From gitlab at gitlab.haskell.org Fri May 1 01:34:53 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 30 Apr 2020 21:34:53 -0400 Subject: [Git][ghc/ghc][master] 3 commits: nonmoving: Clear bitmap after initializing block size Message-ID: <5eab7cbd696d3_6167c5ce1b08227640@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 2aa67611 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - 54dad3cf by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - 99ff8145 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 3 changed files: - rts/sm/GC.c - rts/sm/NonMoving.c - rts/sm/NonMovingSweep.c Changes: ===================================== rts/sm/GC.c ===================================== @@ -738,11 +738,13 @@ GarbageCollect (uint32_t collect_gen, } } // for all generations - // Flush the update remembered set. See Note [Eager update remembered set + // Flush the update remembered sets. See Note [Eager update remembered set // flushing] in NonMovingMark.c if (RtsFlags.GcFlags.useNonmoving) { RELEASE_SM_LOCK; - nonmovingAddUpdRemSetBlocks(&gct->cap->upd_rem_set.queue); + for (n = 0; n < n_capabilities; n++) { + nonmovingAddUpdRemSetBlocks(&capabilities[n]->upd_rem_set.queue); + } ACQUIRE_SM_LOCK; } ===================================== rts/sm/NonMoving.c ===================================== @@ -402,10 +402,10 @@ static void nonmovingInitSegment(struct NonmovingSegment *seg, uint8_t log_block seg->link = NULL; seg->todo_link = NULL; seg->next_free = 0; - nonmovingClearBitmap(seg); bd->nonmoving_segment.log_block_size = log_block_size; bd->nonmoving_segment.next_free_snap = 0; bd->u.scan = nonmovingSegmentGetBlock(seg, 0); + nonmovingClearBitmap(seg); } // Add a segment to the free list. ===================================== rts/sm/NonMovingSweep.c ===================================== @@ -31,12 +31,11 @@ enum SweepResult { GNUC_ATTR_HOT static enum SweepResult nonmovingSweepSegment(struct NonmovingSegment *seg) { + const nonmoving_block_idx blk_cnt = nonmovingSegmentBlockCount(seg); bool found_free = false; bool found_live = false; - for (nonmoving_block_idx i = 0; - i < nonmovingSegmentBlockCount(seg); - ++i) + for (nonmoving_block_idx i = 0; i < blk_cnt; ++i) { if (seg->bitmap[i] == nonmovingMarkEpoch) { found_live = true; View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/014ef4a3d9ee30b8add9118950f1f5007143bd1c...99ff8145044288a8a58c8028516903937ba3935c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/014ef4a3d9ee30b8add9118950f1f5007143bd1c...99ff8145044288a8a58c8028516903937ba3935c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 1 01:35:35 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 30 Apr 2020 21:35:35 -0400 Subject: [Git][ghc/ghc][master] 2 commits: Remove OneShotInfo field of LFReEntrant, document OneShotInfo Message-ID: <5eab7ce772b5a_6167120888bc8229690@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 05b0a9fd by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 Remove OneShotInfo field of LFReEntrant, document OneShotInfo The field is only used in withNewTickyCounterFun and it's easier to directly pass a parameter for one-shot info to withNewTickyCounterFun instead of passing it via LFReEntrant. This also makes !2842 simpler. Other changes: - New Note (by SPJ) [OneShotInfo overview] added. - Arity argument of thunkCode removed as it's always 0. - - - - - a43620c6 by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 GHC.StgToCmm.Ticky: remove a few unused stuff - - - - - 4 changed files: - compiler/GHC/StgToCmm/Bind.hs - compiler/GHC/StgToCmm/Closure.hs - compiler/GHC/StgToCmm/Ticky.hs - compiler/GHC/Types/Basic.hs Changes: ===================================== compiler/GHC/StgToCmm/Bind.hs ===================================== @@ -111,7 +111,7 @@ cgTopRhsClosure dflags rec id ccs upd_flag args body = (_, _, fv_details) = mkVirtHeapOffsets dflags header [] -- Don't drop the non-void args until the closure info has been made ; forkClosureBody (closureCodeBody True id closure_info ccs - (nonVoidIds args) (length args) body fv_details) + args body fv_details) ; return () } @@ -358,8 +358,8 @@ mkRhsClosure dflags bndr cc fvs upd_flag args body -- forkClosureBody: (a) ensure that bindings in here are not seen elsewhere -- (b) ignore Sequel from context; use empty Sequel -- And compile the body - closureCodeBody False bndr closure_info cc (nonVoidIds args) - (length args) body fv_details + closureCodeBody False bndr closure_info cc args + body fv_details -- BUILD THE OBJECT -- ; (use_cc, blame_cc) <- chooseDynCostCentres cc args body @@ -436,8 +436,7 @@ closureCodeBody :: Bool -- whether this is a top-level binding -> Id -- the closure's name -> ClosureInfo -- Lots of information about this closure -> CostCentreStack -- Optional cost centre attached to closure - -> [NonVoid Id] -- incoming args to the closure - -> Int -- arity, including void args + -> [Id] -- incoming args to the closure -> CgStgExpr -> [(NonVoid Id, ByteOff)] -- the closure's free vars -> FCode () @@ -452,31 +451,32 @@ closureCodeBody :: Bool -- whether this is a top-level binding normal form, so there is no need to set up an update frame. -} -closureCodeBody top_lvl bndr cl_info cc _args arity body fv_details - | arity == 0 -- No args i.e. thunk +-- No args i.e. thunk +closureCodeBody top_lvl bndr cl_info cc [] body fv_details = withNewTickyCounterThunk (isStaticClosure cl_info) (closureUpdReqd cl_info) (closureName cl_info) $ emitClosureProcAndInfoTable top_lvl bndr lf_info info_tbl [] $ - \(_, node, _) -> thunkCode cl_info fv_details cc node arity body + \(_, node, _) -> thunkCode cl_info fv_details cc node body where lf_info = closureLFInfo cl_info info_tbl = mkCmmInfo cl_info bndr cc -closureCodeBody top_lvl bndr cl_info cc args arity body fv_details - = -- Note: args may be [], if all args are Void - withNewTickyCounterFun - (closureSingleEntry cl_info) - (closureName cl_info) - args $ do { +closureCodeBody top_lvl bndr cl_info cc args@(arg0:_) body fv_details + = let nv_args = nonVoidIds args + arity = length args + in + -- See Note [OneShotInfo overview] in GHC.Types.Basic. + withNewTickyCounterFun (isOneShotBndr arg0) (closureName cl_info) + nv_args $ do { ; let lf_info = closureLFInfo cl_info info_tbl = mkCmmInfo cl_info bndr cc -- Emit the main entry code - ; emitClosureProcAndInfoTable top_lvl bndr lf_info info_tbl args $ + ; emitClosureProcAndInfoTable top_lvl bndr lf_info info_tbl nv_args $ \(_offset, node, arg_regs) -> do -- Emit slow-entry code (for entering a closure through a PAP) { mkSlowEntryCode bndr cl_info arg_regs @@ -565,15 +565,15 @@ mkSlowEntryCode bndr cl_info arg_regs -- function closure is already in `Node' ----------------------------------------- thunkCode :: ClosureInfo -> [(NonVoid Id, ByteOff)] -> CostCentreStack - -> LocalReg -> Int -> CgStgExpr -> FCode () -thunkCode cl_info fv_details _cc node arity body + -> LocalReg -> CgStgExpr -> FCode () +thunkCode cl_info fv_details _cc node body = do { dflags <- getDynFlags ; let node_points = nodeMustPointToIt dflags (closureLFInfo cl_info) node' = if node_points then Just node else Nothing ; ldvEnterClosure cl_info (CmmLocal node) -- NB: Node always points when profiling -- Heap overflow check - ; entryHeapCheck cl_info node' arity [] $ do + ; entryHeapCheck cl_info node' 0 [] $ do { -- Overwrite with black hole if necessary -- but *after* the heap-overflow check ; tickyEnterThunk cl_info ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -48,7 +48,7 @@ module GHC.StgToCmm.Closure ( -- ** Predicates -- These are really just functions on LambdaFormInfo - closureUpdReqd, closureSingleEntry, + closureUpdReqd, closureReEntrant, closureFunInfo, isToplevClosure, @@ -201,7 +201,6 @@ argPrimRep arg = typePrimRep1 (stgArgType arg) data LambdaFormInfo = LFReEntrant -- Reentrant closure (a function) TopLevelFlag -- True if top level - OneShotInfo !RepArity -- Arity. Invariant: always > 0 !Bool -- True <=> no fvs ArgDescr -- Argument descriptor (should really be in ClosureInfo) @@ -285,8 +284,7 @@ mkLFReEntrant :: TopLevelFlag -- True of top level mkLFReEntrant _ _ [] _ = pprPanic "mkLFReEntrant" empty mkLFReEntrant top fvs args arg_descr - = LFReEntrant top os_info (length args) (null fvs) arg_descr - where os_info = idOneShotInfo (head args) + = LFReEntrant top (length args) (null fvs) arg_descr ------------- mkLFThunk :: Type -> TopLevelFlag -> [Id] -> UpdateFlag -> LambdaFormInfo @@ -335,7 +333,7 @@ mkLFImported id -- the id really does point directly to the constructor | arity > 0 - = LFReEntrant TopLevel noOneShotInfo arity True (panic "arg_descr") + = LFReEntrant TopLevel arity True (panic "arg_descr") | otherwise = mkLFArgument id -- Not sure of exact arity @@ -384,9 +382,9 @@ tagForArity dflags arity lfDynTag :: DynFlags -> LambdaFormInfo -> DynTag -- Return the tag in the low order bits of a variable bound -- to this LambdaForm -lfDynTag dflags (LFCon con) = tagForCon dflags con -lfDynTag dflags (LFReEntrant _ _ arity _ _) = tagForArity dflags arity -lfDynTag _ _other = 0 +lfDynTag dflags (LFCon con) = tagForCon dflags con +lfDynTag dflags (LFReEntrant _ arity _ _) = tagForArity dflags arity +lfDynTag _ _other = 0 ----------------------------------------------------------------------------- @@ -407,11 +405,11 @@ isLFReEntrant _ = False ----------------------------------------------------------------------------- lfClosureType :: LambdaFormInfo -> ClosureTypeInfo -lfClosureType (LFReEntrant _ _ arity _ argd) = Fun arity argd -lfClosureType (LFCon con) = Constr (dataConTagZ con) - (dataConIdentity con) -lfClosureType (LFThunk _ _ _ is_sel _) = thunkClosureType is_sel -lfClosureType _ = panic "lfClosureType" +lfClosureType (LFReEntrant _ arity _ argd) = Fun arity argd +lfClosureType (LFCon con) = Constr (dataConTagZ con) + (dataConIdentity con) +lfClosureType (LFThunk _ _ _ is_sel _) = thunkClosureType is_sel +lfClosureType _ = panic "lfClosureType" thunkClosureType :: StandardFormInfo -> ClosureTypeInfo thunkClosureType (SelectorThunk off) = ThunkSelector off @@ -431,7 +429,7 @@ nodeMustPointToIt :: DynFlags -> LambdaFormInfo -> Bool -- this closure has R1 (the "Node" register) pointing to the -- closure itself --- the "self" argument -nodeMustPointToIt _ (LFReEntrant top _ _ no_fvs _) +nodeMustPointToIt _ (LFReEntrant top _ no_fvs _) = not no_fvs -- Certainly if it has fvs we need to point to it || isNotTopLevel top -- See Note [GC recovery] -- For lex_profiling we also access the cost centre for a @@ -566,7 +564,7 @@ getCallMethod dflags _ id _ n_args v_args _cg_loc -- self-recursive tail calls] in GHC.StgToCmm.Expr for more details = JumpToIt block_id args -getCallMethod dflags name id (LFReEntrant _ _ arity _ _) n_args _v_args _cg_loc +getCallMethod dflags name id (LFReEntrant _ arity _ _) n_args _v_args _cg_loc _self_loop_info | n_args == 0 -- No args at all && not (gopt Opt_SccProfilingOn dflags) @@ -811,11 +809,6 @@ lfUpdatable :: LambdaFormInfo -> Bool lfUpdatable (LFThunk _ _ upd _ _) = upd lfUpdatable _ = False -closureSingleEntry :: ClosureInfo -> Bool -closureSingleEntry (ClosureInfo { closureLFInfo = LFThunk _ _ upd _ _}) = not upd -closureSingleEntry (ClosureInfo { closureLFInfo = LFReEntrant _ OneShotLam _ _ _}) = True -closureSingleEntry _ = False - closureReEntrant :: ClosureInfo -> Bool closureReEntrant (ClosureInfo { closureLFInfo = LFReEntrant {} }) = True closureReEntrant _ = False @@ -824,8 +817,8 @@ closureFunInfo :: ClosureInfo -> Maybe (RepArity, ArgDescr) closureFunInfo (ClosureInfo { closureLFInfo = lf_info }) = lfFunInfo lf_info lfFunInfo :: LambdaFormInfo -> Maybe (RepArity, ArgDescr) -lfFunInfo (LFReEntrant _ _ arity _ arg_desc) = Just (arity, arg_desc) -lfFunInfo _ = Nothing +lfFunInfo (LFReEntrant _ arity _ arg_desc) = Just (arity, arg_desc) +lfFunInfo _ = Nothing funTag :: DynFlags -> ClosureInfo -> DynTag funTag dflags (ClosureInfo { closureLFInfo = lf_info }) @@ -834,9 +827,9 @@ funTag dflags (ClosureInfo { closureLFInfo = lf_info }) isToplevClosure :: ClosureInfo -> Bool isToplevClosure (ClosureInfo { closureLFInfo = lf_info }) = case lf_info of - LFReEntrant TopLevel _ _ _ _ -> True - LFThunk TopLevel _ _ _ _ -> True - _other -> False + LFReEntrant TopLevel _ _ _ -> True + LFThunk TopLevel _ _ _ _ -> True + _other -> False -------------------------------------- -- Label generation ===================================== compiler/GHC/StgToCmm/Ticky.hs ===================================== @@ -82,27 +82,22 @@ module GHC.StgToCmm.Ticky ( tickyHeapCheck, tickyStackCheck, - tickyUnknownCall, tickyDirectCall, + tickyDirectCall, tickyPushUpdateFrame, tickyUpdateFrameOmitted, tickyEnterDynCon, - tickyEnterStaticCon, - tickyEnterViaNode, tickyEnterFun, - tickyEnterThunk, tickyEnterStdThunk, -- dynamic non-value - -- thunks only + tickyEnterThunk, tickyEnterLNE, tickyUpdateBhCaf, - tickyBlackHole, tickyUnboxedTupleReturn, tickyReturnOldCon, tickyReturnNewCon, - tickyKnownCallTooFewArgs, tickyKnownCallExact, tickyKnownCallExtraArgs, - tickySlowCall, tickySlowCallPat, + tickySlowCall ) where import GHC.Prelude @@ -276,10 +271,8 @@ tickyUpdateFrameOmitted = ifTicky $ bumpTickyCounter (fsLit "UPDF_OMITTED_ctr") -- bump of name-specific ticky counter into. On the other hand, we can -- still track allocation their allocation. -tickyEnterDynCon, tickyEnterStaticCon, tickyEnterViaNode :: FCode () -tickyEnterDynCon = ifTicky $ bumpTickyCounter (fsLit "ENT_DYN_CON_ctr") -tickyEnterStaticCon = ifTicky $ bumpTickyCounter (fsLit "ENT_STATIC_CON_ctr") -tickyEnterViaNode = ifTicky $ bumpTickyCounter (fsLit "ENT_VIA_NODE_ctr") +tickyEnterDynCon :: FCode () +tickyEnterDynCon = ifTicky $ bumpTickyCounter (fsLit "ENT_DYN_CON_ctr") tickyEnterThunk :: ClosureInfo -> FCode () tickyEnterThunk cl_info @@ -291,7 +284,7 @@ tickyEnterThunk cl_info registerTickyCtrAtEntryDyn ticky_ctr_lbl bumpTickyEntryCount ticky_ctr_lbl } where - updatable = closureSingleEntry cl_info + updatable = not (closureUpdReqd cl_info) static = isStaticClosure cl_info ctr | static = if updatable then fsLit "ENT_STATIC_THK_SINGLE_ctr" @@ -299,16 +292,6 @@ tickyEnterThunk cl_info | otherwise = if updatable then fsLit "ENT_DYN_THK_SINGLE_ctr" else fsLit "ENT_DYN_THK_MANY_ctr" -tickyEnterStdThunk :: ClosureInfo -> FCode () -tickyEnterStdThunk = tickyEnterThunk - -tickyBlackHole :: Bool{-updatable-} -> FCode () -tickyBlackHole updatable - = ifTicky (bumpTickyCounter ctr) - where - ctr | updatable = (fsLit "UPD_BH_SINGLE_ENTRY_ctr") - | otherwise = (fsLit "UPD_BH_UPDATABLE_ctr") - tickyUpdateBhCaf :: ClosureInfo -> FCode () tickyUpdateBhCaf cl_info = ifTicky (bumpTickyCounter ctr) ===================================== compiler/GHC/Types/Basic.hs ===================================== @@ -243,13 +243,80 @@ instance Outputable Alignment where ************************************************************************ -} +{- +Note [OneShotInfo overview] +~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Lambda-bound Ids (and only lambda-bound Ids) may be decorated with +one-shot info. The idea is that if we see + (\x{one-shot}. e) +it means that this lambda will only be applied once. In particular +that means we can float redexes under the lambda without losing +work. For example, consider + let t = expensive in + (\x{one-shot}. case t of { True -> ...; False -> ... }) + +Because it's a one-shot lambda, we can safely inline t, giving + (\x{one_shot}. case of of + { True -> ...; False -> ... }) + +Moving parts: + +* Usage analysis, performed as part of demand-analysis, finds + out whether functions call their argument once. Consider + f g x = Just (case g x of { ... }) + + Here 'f' is lazy in 'g', but it guarantees to call it no + more than once. So g will get a C1(U) usage demand. + +* Occurrence analysis propagates this usage information + (in the demand signature of a function) to its calls. + Example, given 'f' above + f (\x.e) blah + + Since f's demand signature says it has a C1(U) usage demand on its + first argument, the occurrence analyser sets the \x to be one-shot. + This is done via the occ_one_shots field of OccEnv. + +* Float-in and float-out take account of one-shot-ness + +* Occurrence analysis doesn't set "inside-lam" for occurrences inside + a one-shot lambda + +Other notes + +* A one-shot lambda can use its argument many times. To elaborate + the example above + let t = expensive in + (\x{one-shot}. case t of { True -> x+x; False -> x*x }) + + Here the '\x' is one-shot, which justifies inlining 't', + but x is used many times. That's absolutely fine. + +* It's entirely possible to have + (\x{one-shot}. \y{many-shot}. e) + + For example + let t = expensive + g = \x -> let v = x+t in + \y -> x + v + in map (g 5) xs + + Here the `\x` is a one-shot binder: `g` is applied to one argument + exactly once. And because the `\x` is one-shot, it would be fine to + float that `let t = expensive` binding inside the `\x`. + + But the `\y` is most definitely not one-shot! +-} + -- | If the 'Id' is a lambda-bound variable then it may have lambda-bound -- variable info. Sometimes we know whether the lambda binding this variable --- is a \"one-shot\" lambda; that is, whether it is applied at most once. +-- is a "one-shot" lambda; that is, whether it is applied at most once. -- -- This information may be useful in optimisation, as computations may -- safely be floated inside such a lambda without risk of duplicating -- work. +-- +-- See also Note [OneShotInfo overview] above. data OneShotInfo = NoOneShotInfo -- ^ No information | OneShotLam -- ^ The lambda is applied at most once. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/99ff8145044288a8a58c8028516903937ba3935c...a43620c621563deed76ba6b417e3a7a707c15d23 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/99ff8145044288a8a58c8028516903937ba3935c...a43620c621563deed76ba6b417e3a7a707c15d23 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 1 02:07:01 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 30 Apr 2020 22:07:01 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 11 commits: nonmoving: Clear bitmap after initializing block size Message-ID: <5eab8445929cc_616787c09cc823315d@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 2aa67611 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - 54dad3cf by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - 99ff8145 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 05b0a9fd by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 Remove OneShotInfo field of LFReEntrant, document OneShotInfo The field is only used in withNewTickyCounterFun and it's easier to directly pass a parameter for one-shot info to withNewTickyCounterFun instead of passing it via LFReEntrant. This also makes !2842 simpler. Other changes: - New Note (by SPJ) [OneShotInfo overview] added. - Arity argument of thunkCode removed as it's always 0. - - - - - a43620c6 by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 GHC.StgToCmm.Ticky: remove a few unused stuff - - - - - 5692ef1c by Sylvain Henry at 2020-04-30T22:06:49-04:00 Use platform in Iface Binary - - - - - ba6a55a1 by Sylvain Henry at 2020-04-30T22:06:49-04:00 Refactor PprDebug handling If `-dppr-debug` is set, then PprUser and PprDump styles are silently replaced with PprDebug style. This was done in `mkUserStyle` and `mkDumpStyle` smart constructors. As a consequence they needed a DynFlags parameter. Now we keep the original PprUser and PprDump styles until they are used to create an `SDocContext`. I.e. the substitution is only performed in `initSDocContext`. - - - - - 9e00a194 by Sylvain Henry at 2020-04-30T22:06:49-04:00 Remove PprStyle param of logging actions Use `withPprStyle` instead to apply a specific style to a SDoc. - - - - - ff52d895 by Sylvain Henry at 2020-04-30T22:06:49-04:00 Fully remove PprDebug PprDebug was a pain to deal with consistently as it is implied by `-dppr-debug` but it isn't really a PprStyle. We remove it completely and query the appropriate SDoc flag instead (`sdocPprDebug`) via helpers (`getPprDebug` and its friends). - - - - - 9c9c4621 by Sebastian Graf at 2020-04-30T22:06:50-04:00 PmCheck: Only call checkSingle if we would report warnings - - - - - aa0ebc8c by Sebastian Graf at 2020-04-30T22:06:50-04:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Driver.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/TyCo/Ppr.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Runtime/Debugger.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6e659dece9614de57f99e0322dad399491b620bc...aa0ebc8c1716ed18319c261da192e839f2fe688a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6e659dece9614de57f99e0322dad399491b620bc...aa0ebc8c1716ed18319c261da192e839f2fe688a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 1 08:17:19 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 01 May 2020 04:17:19 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 6 commits: Use platform in Iface Binary Message-ID: <5eabdb0f17445_6167e11371882663d4@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 2cf5d330 by Sylvain Henry at 2020-05-01T04:17:11-04:00 Use platform in Iface Binary - - - - - 48c8d671 by Sylvain Henry at 2020-05-01T04:17:11-04:00 Refactor PprDebug handling If `-dppr-debug` is set, then PprUser and PprDump styles are silently replaced with PprDebug style. This was done in `mkUserStyle` and `mkDumpStyle` smart constructors. As a consequence they needed a DynFlags parameter. Now we keep the original PprUser and PprDump styles until they are used to create an `SDocContext`. I.e. the substitution is only performed in `initSDocContext`. - - - - - 81e5ed90 by Sylvain Henry at 2020-05-01T04:17:11-04:00 Remove PprStyle param of logging actions Use `withPprStyle` instead to apply a specific style to a SDoc. - - - - - 5fadf4c1 by Sylvain Henry at 2020-05-01T04:17:11-04:00 Fully remove PprDebug PprDebug was a pain to deal with consistently as it is implied by `-dppr-debug` but it isn't really a PprStyle. We remove it completely and query the appropriate SDoc flag instead (`sdocPprDebug`) via helpers (`getPprDebug` and its friends). - - - - - 78393245 by Sebastian Graf at 2020-05-01T04:17:11-04:00 PmCheck: Only call checkSingle if we would report warnings - - - - - a6e8bbfd by Sebastian Graf at 2020-05-01T04:17:12-04:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Driver.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/TyCo/Ppr.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Runtime/Debugger.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/aa0ebc8c1716ed18319c261da192e839f2fe688a...a6e8bbfd6161dfca0f5772e84f3f94a6de9c3baf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/aa0ebc8c1716ed18319c261da192e839f2fe688a...a6e8bbfd6161dfca0f5772e84f3f94a6de9c3baf You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 1 08:54:11 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Fri, 01 May 2020 04:54:11 -0400 Subject: [Git][ghc/ghc][wip/osa1/lfinfo] 19 commits: Document backpack fields in DynFlags Message-ID: <5eabe3b349328_61673f81cd4c695c82699e0@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/lfinfo at Glasgow Haskell Compiler / GHC Commits: 2cfc4ab9 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Document backpack fields in DynFlags - - - - - 10a2ba90 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 69562e34 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 9e2c8e0e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - ea717aa4 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 10d15f1e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 8bfb0219 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - 71484b09 by Alexis King at 2020-04-30T01:57:35-04:00 Allow block arguments in arrow control operators Arrow control operators have their own entries in the grammar, so they did not cooperate with BlockArguments. This was just a minor oversight, so this patch adjusts the grammar to add the desired behavior. fixes #18050 - - - - - a48cd2a0 by Alexis King at 2020-04-30T01:57:35-04:00 Allow LambdaCase to be used as a command in proc notation - - - - - f4d3773c by Alexis King at 2020-04-30T01:57:35-04:00 Document BlockArguments/LambdaCase support in arrow notation - - - - - 5bdfdd13 by Simon Peyton Jones at 2020-04-30T01:58:15-04:00 Add tests for #17873 - - - - - 19b701c2 by Simon Peyton Jones at 2020-04-30T07:30:13-04:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - 014ef4a3 by Matthew Pickering at 2020-04-30T07:30:50-04:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 2aa67611 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - 54dad3cf by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - 99ff8145 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 05b0a9fd by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 Remove OneShotInfo field of LFReEntrant, document OneShotInfo The field is only used in withNewTickyCounterFun and it's easier to directly pass a parameter for one-shot info to withNewTickyCounterFun instead of passing it via LFReEntrant. This also makes !2842 simpler. Other changes: - New Note (by SPJ) [OneShotInfo overview] added. - Arity argument of thunkCode removed as it's always 0. - - - - - a43620c6 by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 GHC.StgToCmm.Ticky: remove a few unused stuff - - - - - 96eb36f9 by Ömer Sinan Ağacan at 2020-05-01T11:53:05+03:00 Cross-module LambdaFormInfo passing - Store LambdaFormInfos of exported Ids in interface files - Use them in importing modules This is for optimization purposes: if we know LambdaFormInfo of imported Ids we can generate more efficient calling code, see `getCallMethod`. Exporting (putting them in interface files or in ModDetails) and importing (reading them from interface files) are both optional. We don't assume known LambdaFormInfos anywhere and do not change how we call Ids with unknown LambdaFormInfos. Runtime, allocation, and residency numbers when building Cabal-the-library (commit 0d4ee7ba3). (Log and .hp files are in the MR: !2842) Runtime: | | GHC HEAD | This patch | Diff | |-----|----------|------------|----------------| | -O0 | 0:35.70 | 0:34.75 | -0.95s, -2.66% | | -O1 | 2:25.21 | 2:25.16 | -0.05s, -0.03% | | -O2 | 2:52.89 | 2:51.25 | -1.63s, -0.9% | Allocations: | | GHC HEAD | This patch | Diff | |-----|-----------------|-----------------|----------------------| | -O0 | 54,872,673,008 | 54,917,849,488 | +45,176,480, +0.08% | | -O1 | 227,080,315,016 | 227,584,483,224 | +504,168,208, +0.22% | | -O2 | 266,085,969,832 | 266,710,115,472 | +624,145,640, +0.23% | Max. residency: NOTE: Residency is measured with extra runtime args: `-i0 -h` which effectively turn all GCs into major GCs, and do GC more often. | | GHC HEAD | This patch | Diff | |-----|----------------------------|------------------------------|----------------------| | -O0 | 416,350,080 (894 samples) | 417,733,152 (892 samples) | +1,383,072, +0.33% | | -O1 | 928,484,840 (2101 samples) | 945,624,664 (2098 samples) | +17,139,824, +1.84% | | -O2 | 991,311,896 (2548 samples) | 1,010,647,088 (2536 samples) | +19,335,192, +1.95% | NoFib results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS 0.0% 0.0% +0.0% +0.0% +0.0% CSD 0.0% 0.0% 0.0% +0.0% +0.0% FS 0.0% 0.0% +0.0% +0.0% +0.0% S 0.0% 0.0% +0.0% +0.0% +0.0% VS 0.0% 0.0% +0.0% +0.0% +0.0% VSD 0.0% 0.0% +0.0% +0.0% +0.1% VSM 0.0% 0.0% +0.0% +0.0% +0.0% anna 0.0% 0.0% -0.3% -0.8% -0.0% ansi 0.0% 0.0% -0.0% -0.0% 0.0% atom 0.0% 0.0% -0.0% -0.0% 0.0% awards 0.0% 0.0% -0.1% -0.3% 0.0% banner 0.0% 0.0% -0.0% -0.0% -0.0% bernouilli 0.0% 0.0% -0.0% -0.0% -0.0% binary-trees 0.0% 0.0% -0.0% -0.0% +0.0% boyer 0.0% 0.0% -0.0% -0.0% 0.0% boyer2 0.0% 0.0% -0.0% -0.0% 0.0% bspt 0.0% 0.0% -0.0% -0.2% 0.0% cacheprof 0.0% 0.0% -0.1% -0.4% +0.0% calendar 0.0% 0.0% -0.0% -0.0% 0.0% cichelli 0.0% 0.0% -0.9% -2.4% 0.0% circsim 0.0% 0.0% -0.0% -0.0% 0.0% clausify 0.0% 0.0% -0.1% -0.3% 0.0% comp_lab_zift 0.0% 0.0% -0.0% -0.0% +0.0% compress 0.0% 0.0% -0.0% -0.0% -0.0% compress2 0.0% 0.0% -0.0% -0.0% 0.0% constraints 0.0% 0.0% -0.1% -0.2% -0.0% cryptarithm1 0.0% 0.0% -0.0% -0.0% 0.0% cryptarithm2 0.0% 0.0% -1.4% -4.1% -0.0% cse 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e1 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e2 0.0% 0.0% -0.0% -0.0% -0.0% dom-lt 0.0% 0.0% -0.1% -0.2% 0.0% eliza 0.0% 0.0% -0.5% -1.5% 0.0% event 0.0% 0.0% -0.0% -0.0% -0.0% exact-reals 0.0% 0.0% -0.1% -0.3% +0.0% exp3_8 0.0% 0.0% -0.0% -0.0% -0.0% expert 0.0% 0.0% -0.3% -1.0% -0.0% fannkuch-redux 0.0% 0.0% +0.0% +0.0% +0.0% fasta 0.0% 0.0% -0.0% -0.0% +0.0% fem 0.0% 0.0% -0.0% -0.0% 0.0% fft 0.0% 0.0% -0.0% -0.0% 0.0% fft2 0.0% 0.0% -0.0% -0.0% 0.0% fibheaps 0.0% 0.0% -0.0% -0.0% +0.0% fish 0.0% 0.0% 0.0% -0.0% +0.0% fluid 0.0% 0.0% -0.4% -1.2% +0.0% fulsom 0.0% 0.0% -0.0% -0.0% 0.0% gamteb 0.0% 0.0% -0.1% -0.3% 0.0% gcd 0.0% 0.0% -0.0% -0.0% 0.0% gen_regexps 0.0% 0.0% -0.0% -0.0% -0.0% genfft 0.0% 0.0% -0.0% -0.0% 0.0% gg 0.0% 0.0% -0.0% -0.0% +0.0% grep 0.0% 0.0% -0.0% -0.0% -0.0% hidden 0.0% 0.0% -0.1% -0.4% -0.0% hpg 0.0% 0.0% -0.2% -0.5% +0.0% ida 0.0% 0.0% -0.0% -0.0% +0.0% infer 0.0% 0.0% -0.3% -0.8% -0.0% integer 0.0% 0.0% -0.0% -0.0% +0.0% integrate 0.0% 0.0% -0.0% -0.0% 0.0% k-nucleotide 0.0% 0.0% -0.0% -0.0% +0.0% kahan 0.0% 0.0% -0.0% -0.0% +0.0% knights 0.0% 0.0% -2.2% -5.4% 0.0% lambda 0.0% 0.0% -0.6% -1.8% 0.0% last-piece 0.0% 0.0% -0.0% -0.0% 0.0% lcss 0.0% 0.0% -0.0% -0.1% 0.0% life 0.0% 0.0% -0.0% -0.1% 0.0% lift 0.0% 0.0% -0.2% -0.6% +0.0% linear 0.0% 0.0% -0.0% -0.0% -0.0% listcompr 0.0% 0.0% -0.0% -0.0% 0.0% listcopy 0.0% 0.0% -0.0% -0.0% 0.0% maillist 0.0% 0.0% -0.1% -0.3% +0.0% mandel 0.0% 0.0% -0.0% -0.0% 0.0% mandel2 0.0% 0.0% -0.0% -0.0% -0.0% mate +0.0% 0.0% -0.0% -0.0% -0.0% minimax 0.0% 0.0% -0.2% -1.0% 0.0% mkhprog 0.0% 0.0% -0.1% -0.2% -0.0% multiplier 0.0% 0.0% -0.0% -0.0% -0.0% n-body 0.0% 0.0% -0.0% -0.0% +0.0% nucleic2 0.0% 0.0% -0.1% -0.2% 0.0% para 0.0% 0.0% -0.0% -0.0% -0.0% paraffins 0.0% 0.0% -0.0% -0.0% 0.0% parser 0.0% 0.0% -0.2% -0.7% 0.0% parstof 0.0% 0.0% -0.0% -0.0% +0.0% pic 0.0% 0.0% -0.0% -0.0% 0.0% pidigits 0.0% 0.0% +0.0% +0.0% +0.0% power 0.0% 0.0% -0.2% -0.6% +0.0% pretty 0.0% 0.0% -0.0% -0.0% -0.0% primes 0.0% 0.0% -0.0% -0.0% 0.0% primetest 0.0% 0.0% -0.0% -0.0% -0.0% prolog 0.0% 0.0% -0.3% -1.1% 0.0% puzzle 0.0% 0.0% -0.0% -0.0% 0.0% queens 0.0% 0.0% -0.0% -0.0% +0.0% reptile 0.0% 0.0% -0.0% -0.0% 0.0% reverse-complem 0.0% 0.0% -0.0% -0.0% +0.0% rewrite 0.0% 0.0% -0.7% -2.5% -0.0% rfib 0.0% 0.0% -0.0% -0.0% 0.0% rsa 0.0% 0.0% -0.0% -0.0% 0.0% scc 0.0% 0.0% -0.1% -0.2% -0.0% sched 0.0% 0.0% -0.0% -0.0% -0.0% scs 0.0% 0.0% -1.0% -2.6% +0.0% simple 0.0% 0.0% +0.0% -0.0% +0.0% solid 0.0% 0.0% -0.0% -0.0% 0.0% sorting 0.0% 0.0% -0.6% -1.6% 0.0% spectral-norm 0.0% 0.0% +0.0% 0.0% +0.0% sphere 0.0% 0.0% -0.0% -0.0% -0.0% symalg 0.0% 0.0% -0.0% -0.0% +0.0% tak 0.0% 0.0% -0.0% -0.0% 0.0% transform 0.0% 0.0% -0.0% -0.0% 0.0% treejoin 0.0% 0.0% -0.0% -0.0% 0.0% typecheck 0.0% 0.0% -0.0% -0.0% +0.0% veritas +0.0% 0.0% -0.2% -0.4% +0.0% wang 0.0% 0.0% -0.0% -0.0% 0.0% wave4main 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 0.0% 0.0% -0.0% -0.0% +0.0% x2n1 0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min 0.0% 0.0% -2.2% -5.4% -0.0% Max +0.0% 0.0% +0.0% +0.0% +0.1% Geometric Mean -0.0% -0.0% -0.1% -0.3% +0.0% Metric increases micro benchmarks tracked in #17686: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 Co-authored-by: Andreas Klebinger <klebinger.andreas at gmx.at> - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Config.hs - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Opt/Driver.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/TyCon.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8049753a33c9bd0879b8c11af8ae315b7e1072ba...96eb36f90c372ec20828f8553de217748a7e92f9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8049753a33c9bd0879b8c11af8ae315b7e1072ba...96eb36f90c372ec20828f8553de217748a7e92f9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 1 09:08:24 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Fri, 01 May 2020 05:08:24 -0400 Subject: [Git][ghc/ghc][wip/osa1/lfinfo] Cross-module LambdaFormInfo passing Message-ID: <5eabe708a028f_6167120888bc82707d7@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/lfinfo at Glasgow Haskell Compiler / GHC Commits: ff772455 by Ömer Sinan Ağacan at 2020-05-01T12:08:12+03:00 Cross-module LambdaFormInfo passing - Store LambdaFormInfos of exported Ids in interface files - Use them in importing modules This is for optimization purposes: if we know LambdaFormInfo of imported Ids we can generate more efficient calling code, see `getCallMethod`. Exporting (putting them in interface files or in ModDetails) and importing (reading them from interface files) are both optional. We don't assume known LambdaFormInfos anywhere and do not change how we call Ids with unknown LambdaFormInfos. Runtime, allocation, and residency numbers when building Cabal-the-library (commit 0d4ee7ba3). (Log and .hp files are in the MR: !2842) Runtime: | | GHC HEAD | This patch | Diff | |-----|----------|------------|----------------| | -O0 | 0:35.70 | 0:34.75 | -0.95s, -2.66% | | -O1 | 2:25.21 | 2:25.16 | -0.05s, -0.03% | | -O2 | 2:52.89 | 2:51.25 | -1.63s, -0.9% | Allocations: | | GHC HEAD | This patch | Diff | |-----|-----------------|-----------------|----------------------| | -O0 | 54,872,673,008 | 54,917,849,488 | +45,176,480, +0.08% | | -O1 | 227,080,315,016 | 227,584,483,224 | +504,168,208, +0.22% | | -O2 | 266,085,969,832 | 266,710,115,472 | +624,145,640, +0.23% | Max. residency: NOTE: Residency is measured with extra runtime args: `-i0 -h` which effectively turn all GCs into major GCs, and do GC more often. | | GHC HEAD | This patch | Diff | |-----|----------------------------|------------------------------|----------------------| | -O0 | 416,350,080 (894 samples) | 417,733,152 (892 samples) | +1,383,072, +0.33% | | -O1 | 928,484,840 (2101 samples) | 945,624,664 (2098 samples) | +17,139,824, +1.84% | | -O2 | 991,311,896 (2548 samples) | 1,010,647,088 (2536 samples) | +19,335,192, +1.95% | NoFib results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS 0.0% 0.0% +0.0% +0.0% +0.0% CSD 0.0% 0.0% 0.0% +0.0% +0.0% FS 0.0% 0.0% +0.0% +0.0% +0.0% S 0.0% 0.0% +0.0% +0.0% +0.0% VS 0.0% 0.0% +0.0% +0.0% +0.0% VSD 0.0% 0.0% +0.0% +0.0% +0.1% VSM 0.0% 0.0% +0.0% +0.0% +0.0% anna 0.0% 0.0% -0.3% -0.8% -0.0% ansi 0.0% 0.0% -0.0% -0.0% 0.0% atom 0.0% 0.0% -0.0% -0.0% 0.0% awards 0.0% 0.0% -0.1% -0.3% 0.0% banner 0.0% 0.0% -0.0% -0.0% -0.0% bernouilli 0.0% 0.0% -0.0% -0.0% -0.0% binary-trees 0.0% 0.0% -0.0% -0.0% +0.0% boyer 0.0% 0.0% -0.0% -0.0% 0.0% boyer2 0.0% 0.0% -0.0% -0.0% 0.0% bspt 0.0% 0.0% -0.0% -0.2% 0.0% cacheprof 0.0% 0.0% -0.1% -0.4% +0.0% calendar 0.0% 0.0% -0.0% -0.0% 0.0% cichelli 0.0% 0.0% -0.9% -2.4% 0.0% circsim 0.0% 0.0% -0.0% -0.0% 0.0% clausify 0.0% 0.0% -0.1% -0.3% 0.0% comp_lab_zift 0.0% 0.0% -0.0% -0.0% +0.0% compress 0.0% 0.0% -0.0% -0.0% -0.0% compress2 0.0% 0.0% -0.0% -0.0% 0.0% constraints 0.0% 0.0% -0.1% -0.2% -0.0% cryptarithm1 0.0% 0.0% -0.0% -0.0% 0.0% cryptarithm2 0.0% 0.0% -1.4% -4.1% -0.0% cse 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e1 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e2 0.0% 0.0% -0.0% -0.0% -0.0% dom-lt 0.0% 0.0% -0.1% -0.2% 0.0% eliza 0.0% 0.0% -0.5% -1.5% 0.0% event 0.0% 0.0% -0.0% -0.0% -0.0% exact-reals 0.0% 0.0% -0.1% -0.3% +0.0% exp3_8 0.0% 0.0% -0.0% -0.0% -0.0% expert 0.0% 0.0% -0.3% -1.0% -0.0% fannkuch-redux 0.0% 0.0% +0.0% +0.0% +0.0% fasta 0.0% 0.0% -0.0% -0.0% +0.0% fem 0.0% 0.0% -0.0% -0.0% 0.0% fft 0.0% 0.0% -0.0% -0.0% 0.0% fft2 0.0% 0.0% -0.0% -0.0% 0.0% fibheaps 0.0% 0.0% -0.0% -0.0% +0.0% fish 0.0% 0.0% 0.0% -0.0% +0.0% fluid 0.0% 0.0% -0.4% -1.2% +0.0% fulsom 0.0% 0.0% -0.0% -0.0% 0.0% gamteb 0.0% 0.0% -0.1% -0.3% 0.0% gcd 0.0% 0.0% -0.0% -0.0% 0.0% gen_regexps 0.0% 0.0% -0.0% -0.0% -0.0% genfft 0.0% 0.0% -0.0% -0.0% 0.0% gg 0.0% 0.0% -0.0% -0.0% +0.0% grep 0.0% 0.0% -0.0% -0.0% -0.0% hidden 0.0% 0.0% -0.1% -0.4% -0.0% hpg 0.0% 0.0% -0.2% -0.5% +0.0% ida 0.0% 0.0% -0.0% -0.0% +0.0% infer 0.0% 0.0% -0.3% -0.8% -0.0% integer 0.0% 0.0% -0.0% -0.0% +0.0% integrate 0.0% 0.0% -0.0% -0.0% 0.0% k-nucleotide 0.0% 0.0% -0.0% -0.0% +0.0% kahan 0.0% 0.0% -0.0% -0.0% +0.0% knights 0.0% 0.0% -2.2% -5.4% 0.0% lambda 0.0% 0.0% -0.6% -1.8% 0.0% last-piece 0.0% 0.0% -0.0% -0.0% 0.0% lcss 0.0% 0.0% -0.0% -0.1% 0.0% life 0.0% 0.0% -0.0% -0.1% 0.0% lift 0.0% 0.0% -0.2% -0.6% +0.0% linear 0.0% 0.0% -0.0% -0.0% -0.0% listcompr 0.0% 0.0% -0.0% -0.0% 0.0% listcopy 0.0% 0.0% -0.0% -0.0% 0.0% maillist 0.0% 0.0% -0.1% -0.3% +0.0% mandel 0.0% 0.0% -0.0% -0.0% 0.0% mandel2 0.0% 0.0% -0.0% -0.0% -0.0% mate +0.0% 0.0% -0.0% -0.0% -0.0% minimax 0.0% 0.0% -0.2% -1.0% 0.0% mkhprog 0.0% 0.0% -0.1% -0.2% -0.0% multiplier 0.0% 0.0% -0.0% -0.0% -0.0% n-body 0.0% 0.0% -0.0% -0.0% +0.0% nucleic2 0.0% 0.0% -0.1% -0.2% 0.0% para 0.0% 0.0% -0.0% -0.0% -0.0% paraffins 0.0% 0.0% -0.0% -0.0% 0.0% parser 0.0% 0.0% -0.2% -0.7% 0.0% parstof 0.0% 0.0% -0.0% -0.0% +0.0% pic 0.0% 0.0% -0.0% -0.0% 0.0% pidigits 0.0% 0.0% +0.0% +0.0% +0.0% power 0.0% 0.0% -0.2% -0.6% +0.0% pretty 0.0% 0.0% -0.0% -0.0% -0.0% primes 0.0% 0.0% -0.0% -0.0% 0.0% primetest 0.0% 0.0% -0.0% -0.0% -0.0% prolog 0.0% 0.0% -0.3% -1.1% 0.0% puzzle 0.0% 0.0% -0.0% -0.0% 0.0% queens 0.0% 0.0% -0.0% -0.0% +0.0% reptile 0.0% 0.0% -0.0% -0.0% 0.0% reverse-complem 0.0% 0.0% -0.0% -0.0% +0.0% rewrite 0.0% 0.0% -0.7% -2.5% -0.0% rfib 0.0% 0.0% -0.0% -0.0% 0.0% rsa 0.0% 0.0% -0.0% -0.0% 0.0% scc 0.0% 0.0% -0.1% -0.2% -0.0% sched 0.0% 0.0% -0.0% -0.0% -0.0% scs 0.0% 0.0% -1.0% -2.6% +0.0% simple 0.0% 0.0% +0.0% -0.0% +0.0% solid 0.0% 0.0% -0.0% -0.0% 0.0% sorting 0.0% 0.0% -0.6% -1.6% 0.0% spectral-norm 0.0% 0.0% +0.0% 0.0% +0.0% sphere 0.0% 0.0% -0.0% -0.0% -0.0% symalg 0.0% 0.0% -0.0% -0.0% +0.0% tak 0.0% 0.0% -0.0% -0.0% 0.0% transform 0.0% 0.0% -0.0% -0.0% 0.0% treejoin 0.0% 0.0% -0.0% -0.0% 0.0% typecheck 0.0% 0.0% -0.0% -0.0% +0.0% veritas +0.0% 0.0% -0.2% -0.4% +0.0% wang 0.0% 0.0% -0.0% -0.0% 0.0% wave4main 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 0.0% 0.0% -0.0% -0.0% +0.0% x2n1 0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min 0.0% 0.0% -2.2% -5.4% -0.0% Max +0.0% 0.0% +0.0% +0.0% +0.1% Geometric Mean -0.0% -0.0% -0.1% -0.3% +0.0% Metric increases micro benchmarks tracked in #17686: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 Co-authored-by: Andreas Klebinger <klebinger.andreas at gmx.at> - - - - - 28 changed files: - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Iface/UpdateCafInfos.hs → compiler/GHC/Iface/UpdateIdInfos.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Runtime/Heap/Layout.hs - compiler/GHC/StgToCmm.hs - compiler/GHC/StgToCmm/Closure.hs - + compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/ghc.cabal.in - testsuite/tests/codeGen/should_compile/Makefile - + testsuite/tests/codeGen/should_compile/cg009/A.hs - + testsuite/tests/codeGen/should_compile/cg009/Main.hs - + testsuite/tests/codeGen/should_compile/cg009/Makefile - + testsuite/tests/codeGen/should_compile/cg009/all.T - + testsuite/tests/codeGen/should_compile/cg010/A.hs - + testsuite/tests/codeGen/should_compile/cg010/Main.hs - + testsuite/tests/codeGen/should_compile/cg010/Makefile - + testsuite/tests/codeGen/should_compile/cg010/all.T - + testsuite/tests/codeGen/should_compile/cg010/cg010.stdout - testsuite/tests/simplCore/should_compile/Makefile - testsuite/tests/simplCore/should_compile/T4201.stdout Changes: ===================================== compiler/GHC/CoreToIface.hs ===================================== @@ -34,13 +34,14 @@ module GHC.CoreToIface , toIfaceIdDetails , toIfaceIdInfo , toIfUnfolding - , toIfaceOneShot , toIfaceTickish , toIfaceBind , toIfaceAlt , toIfaceCon , toIfaceApp , toIfaceVar + -- * Other stuff + , toIfaceLFInfo ) where #include "HsVersions.h" @@ -51,6 +52,7 @@ import GHC.Iface.Syntax import GHC.Core.DataCon import GHC.Types.Id import GHC.Types.Id.Info +import GHC.StgToCmm.Types import GHC.Core import GHC.Core.TyCon hiding ( pprPromotionQuote ) import GHC.Core.Coercion.Axiom @@ -616,6 +618,31 @@ toIfaceVar v where name = idName v +--------------------- +toIfaceLFInfo :: Name -> LambdaFormInfo -> IfaceLFInfo +toIfaceLFInfo nm lfi = case lfi of + LFReEntrant top_lvl arity no_fvs _arg_descr -> + -- Exported LFReEntrant closures are top level, and top-level closures + -- don't have free variables + ASSERT2(isTopLevel top_lvl, ppr nm) + ASSERT2(no_fvs, ppr nm) + IfLFReEntrant arity + LFThunk top_lvl no_fvs updatable sfi mb_fun -> + -- Exported LFThunk closures are top level (which don't have free + -- variables) and non-standard (see cgTopRhsClosure) + ASSERT2(isTopLevel top_lvl, ppr nm) + ASSERT2(no_fvs, ppr nm) + ASSERT2(sfi == NonStandardThunk, ppr nm) + IfLFThunk updatable mb_fun + LFCon dc -> + IfLFCon (dataConName dc) + LFUnknown mb_fun -> + IfLFUnknown mb_fun + LFUnlifted -> + IfLFUnlifted + LFLetNoEscape -> + panic "toIfaceLFInfo: LFLetNoEscape" + {- Note [Inlining and hs-boot files] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider this example (#10083, #12789): ===================================== compiler/GHC/Driver/Hooks.hs ===================================== @@ -55,6 +55,7 @@ import GHC.Stg.Syntax import GHC.Data.Stream import GHC.Cmm import GHC.Hs.Extension +import GHC.StgToCmm.Types (ModuleLFInfos) import Data.Maybe @@ -109,7 +110,7 @@ data Hooks = Hooks -> IO (Maybe HValue)) , createIservProcessHook :: Maybe (CreateProcess -> IO ProcessHandle) , stgToCmmHook :: Maybe (DynFlags -> Module -> [TyCon] -> CollectedCCs - -> [CgStgTopBinding] -> HpcInfo -> Stream IO CmmGroup ()) + -> [CgStgTopBinding] -> HpcInfo -> Stream IO CmmGroup ModuleLFInfos) , cmmToRawCmmHook :: forall a . Maybe (DynFlags -> Maybe Module -> Stream IO CmmGroupSRTs a -> IO (Stream IO RawCmmGroup a)) } ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -132,7 +132,6 @@ import qualified GHC.StgToCmm as StgToCmm ( codeGen ) import GHC.Types.CostCentre import GHC.Core.TyCon import GHC.Types.Name -import GHC.Types.Name.Set import GHC.Cmm import GHC.Cmm.Parser ( parseCmmFile ) import GHC.Cmm.Info.Build @@ -147,6 +146,7 @@ import GHC.Tc.Utils.Env import GHC.Builtin.Names import GHC.Driver.Plugins import GHC.Runtime.Loader ( initializePlugins ) +import GHC.StgToCmm.Types (CgInfos (..), ModuleLFInfos) import GHC.Driver.Session import GHC.Utils.Error @@ -175,6 +175,7 @@ import qualified Data.Set as S import Data.Set (Set) import Data.Functor import Control.DeepSeq (force) +import Data.Bifunctor (first) import GHC.Iface.Ext.Ast ( mkHieFile ) import GHC.Iface.Ext.Types ( getAsts, hie_asts, hie_module ) @@ -1385,7 +1386,7 @@ hscWriteIface dflags iface no_change mod_location = do -- | Compile to hard-code. hscGenHardCode :: HscEnv -> CgGuts -> ModLocation -> FilePath - -> IO (FilePath, Maybe FilePath, [(ForeignSrcLang, FilePath)], NameSet) + -> IO (FilePath, Maybe FilePath, [(ForeignSrcLang, FilePath)], CgInfos) -- ^ @Just f@ <=> _stub.c is f hscGenHardCode hsc_env cgguts location output_filename = do let CgGuts{ -- This is the last use of the ModGuts in a compilation. @@ -1444,11 +1445,11 @@ hscGenHardCode hsc_env cgguts location output_filename = do return a rawcmms1 = Stream.mapM dump rawcmms0 - (output_filename, (_stub_h_exists, stub_c_exists), foreign_fps, caf_infos) + (output_filename, (_stub_h_exists, stub_c_exists), foreign_fps, cg_infos) <- {-# SCC "codeOutput" #-} codeOutput dflags this_mod output_filename location foreign_stubs foreign_files dependencies rawcmms1 - return (output_filename, stub_c_exists, foreign_fps, caf_infos) + return (output_filename, stub_c_exists, foreign_fps, cg_infos) hscInteractive :: HscEnv @@ -1542,7 +1543,7 @@ doCodeGen :: HscEnv -> Module -> [TyCon] -> CollectedCCs -> [StgTopBinding] -> HpcInfo - -> IO (Stream IO CmmGroupSRTs NameSet) + -> IO (Stream IO CmmGroupSRTs CgInfos) -- Note we produce a 'Stream' of CmmGroups, so that the -- backend can be run incrementally. Otherwise it generates all -- the C-- up front, which has a significant space cost. @@ -1554,7 +1555,7 @@ doCodeGen hsc_env this_mod data_tycons dumpIfSet_dyn dflags Opt_D_dump_stg_final "Final STG:" FormatSTG (pprGenStgTopBindings stg_binds_w_fvs) - let cmm_stream :: Stream IO CmmGroup () + let cmm_stream :: Stream IO CmmGroup ModuleLFInfos -- See Note [Forcing of stg_binds] cmm_stream = stg_binds_w_fvs `seqList` {-# SCC "StgToCmm" #-} lookupHook stgToCmmHook StgToCmm.codeGen dflags dflags this_mod data_tycons @@ -1573,10 +1574,14 @@ doCodeGen hsc_env this_mod data_tycons ppr_stream1 = Stream.mapM dump1 cmm_stream - pipeline_stream = - {-# SCC "cmmPipeline" #-} - Stream.mapAccumL (cmmPipeline hsc_env) (emptySRT this_mod) ppr_stream1 - <&> (srtMapNonCAFs . moduleSRTMap) + pipeline_stream :: Stream IO CmmGroupSRTs CgInfos + pipeline_stream = do + (non_cafs, lf_infos) <- + {-# SCC "cmmPipeline" #-} + Stream.mapAccumL_ (cmmPipeline hsc_env) (emptySRT this_mod) ppr_stream1 + <&> first (srtMapNonCAFs . moduleSRTMap) + + return CgInfos{ cgNonCafs = non_cafs, cgLFInfos = lf_infos } dump2 a = do unless (null a) $ ===================================== compiler/GHC/Driver/Pipeline.hs ===================================== @@ -70,7 +70,7 @@ import GHC.Settings import GHC.Data.Bag ( unitBag ) import GHC.Data.FastString ( mkFastString ) import GHC.Iface.Make ( mkFullIface ) -import GHC.Iface.UpdateCafInfos ( updateModDetailsCafInfos ) +import GHC.Iface.UpdateIdInfos ( updateModDetailsIdInfos ) import GHC.Utils.Exception as Exception import System.Directory @@ -1178,12 +1178,12 @@ runPhase (HscOut src_flavour mod_name result) _ dflags = do PipeState{hsc_env=hsc_env'} <- getPipeState - (outputFilename, mStub, foreign_files, caf_infos) <- liftIO $ + (outputFilename, mStub, foreign_files, cg_infos) <- liftIO $ hscGenHardCode hsc_env' cgguts mod_location output_fn - final_iface <- liftIO (mkFullIface hsc_env'{hsc_dflags=iface_dflags} partial_iface (Just caf_infos)) - let final_mod_details = {-# SCC updateModDetailsCafInfos #-} - updateModDetailsCafInfos iface_dflags caf_infos mod_details + final_iface <- liftIO (mkFullIface hsc_env'{hsc_dflags=iface_dflags} partial_iface (Just cg_infos)) + let final_mod_details = {-# SCC updateModDetailsIdInfos #-} + updateModDetailsIdInfos iface_dflags cg_infos mod_details setIface final_iface final_mod_details -- See Note [Writing interface files] ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -38,6 +38,7 @@ import GHC.Core.Coercion.Axiom import GHC.Core.ConLike import GHC.Core.DataCon import GHC.Core.Type +import GHC.StgToCmm.Types (CgInfos (..)) import GHC.Tc.Utils.TcType import GHC.Core.InstEnv import GHC.Core.FamInstEnv @@ -98,15 +99,19 @@ mkPartialIface hsc_env mod_details = mkIface_ hsc_env this_mod hsc_src used_th deps rdr_env fix_env warns hpc_info self_trust safe_mode usages doc_hdr decl_docs arg_docs mod_details --- | Fully instantiate a interface --- Adds fingerprints and potentially code generator produced information. -mkFullIface :: HscEnv -> PartialModIface -> Maybe NameSet -> IO ModIface -mkFullIface hsc_env partial_iface mb_non_cafs = do +-- | Fully instantiate an interface. Adds fingerprints and potentially code +-- generator produced information. +-- +-- CgInfos is not available when not generating code (-fno-code), or when not +-- generating interface pragmas (-fomit-interface-pragmas). See also +-- Note [Conveying CAF-info and LFInfo between modules] in GHC.StgToCmm.Types. +mkFullIface :: HscEnv -> PartialModIface -> Maybe CgInfos -> IO ModIface +mkFullIface hsc_env partial_iface mb_cg_infos = do let decls | gopt Opt_OmitInterfacePragmas (hsc_dflags hsc_env) = mi_decls partial_iface | otherwise - = updateDeclCafInfos (mi_decls partial_iface) mb_non_cafs + = updateDecl (mi_decls partial_iface) mb_cg_infos full_iface <- {-# SCC "addFingerprints" #-} @@ -117,15 +122,23 @@ mkFullIface hsc_env partial_iface mb_non_cafs = do return full_iface -updateDeclCafInfos :: [IfaceDecl] -> Maybe NameSet -> [IfaceDecl] -updateDeclCafInfos decls Nothing = decls -updateDeclCafInfos decls (Just non_cafs) = map update_decl decls +updateDecl :: [IfaceDecl] -> Maybe CgInfos -> [IfaceDecl] +updateDecl decls Nothing = decls +updateDecl decls (Just CgInfos{ cgNonCafs = non_cafs, cgLFInfos = lf_infos }) = map update_decl decls where + update_decl (IfaceId nm ty details infos) + | let not_caffy = elemNameSet nm non_cafs + , let mb_lf_info = lookupNameEnv lf_infos nm + , WARN( isNothing mb_lf_info, text "Name without LFInfo:" <+> ppr nm ) True + -- Only allocate a new IfaceId if we're going to update the infos + , isJust mb_lf_info || not_caffy + = IfaceId nm ty details $ + (if not_caffy then (HsNoCafRefs :) else id) + (case mb_lf_info of + Nothing -> infos -- LFInfos not available when building .cmm files + Just lf_info -> HsLFInfo (toIfaceLFInfo nm lf_info) : infos) + update_decl decl - | IfaceId nm ty details infos <- decl - , elemNameSet nm non_cafs - = IfaceId nm ty details (HsNoCafRefs : infos) - | otherwise = decl -- | Make an interface from the results of typechecking only. Useful ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -22,6 +22,8 @@ module GHC.Iface.Syntax ( IfaceAxBranch(..), IfaceTyConParent(..), IfaceCompleteMatch(..), + IfaceLFInfo(..), + IfaceStandardFormInfo(..), -- * Binding names IfaceTopBndr, @@ -30,6 +32,7 @@ module GHC.Iface.Syntax ( -- Misc ifaceDeclImplicitBndrs, visibleIfConDecls, ifaceDeclFingerprints, + tcStandardFormInfo, -- Free Names freeNamesIfDecl, freeNamesIfRule, freeNamesIfFamInst, @@ -67,15 +70,18 @@ import GHC.Utils.Binary import GHC.Data.BooleanFormula ( BooleanFormula, pprBooleanFormula, isTrue ) import GHC.Types.Var( VarBndr(..), binderVar ) import GHC.Core.TyCon ( Role (..), Injectivity(..), tyConBndrVisArgFlag ) -import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, debugIsOn ) +import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, debugIsOn, + seqList ) import GHC.Core.DataCon (SrcStrictness(..), SrcUnpackedness(..)) import GHC.Utils.Lexeme (isLexSym) import GHC.Builtin.Types ( constraintKindTyConName ) -import GHC.Utils.Misc (seqList) +import GHC.StgToCmm.Types import Control.Monad import System.IO.Unsafe import Control.DeepSeq +import Data.Word +import Data.Bits infixl 3 &&& @@ -114,7 +120,8 @@ data IfaceDecl = IfaceId { ifName :: IfaceTopBndr, ifType :: IfaceType, ifIdDetails :: IfaceIdDetails, - ifIdInfo :: IfaceIdInfo } + ifIdInfo :: IfaceIdInfo + } | IfaceData { ifName :: IfaceTopBndr, -- Type constructor ifBinders :: [IfaceTyConBinder], @@ -348,6 +355,7 @@ data IfaceInfoItem IfaceUnfolding -- See Note [Expose recursive functions] | HsNoCafRefs | HsLevity -- Present <=> never levity polymorphic + | HsLFInfo IfaceLFInfo -- NB: Specialisations and rules come in separately and are -- only later attached to the Id. Partial reason: some are orphans. @@ -379,6 +387,77 @@ data IfaceIdDetails | IfRecSelId (Either IfaceTyCon IfaceDecl) Bool | IfDFunId +-- | Iface type for LambdaFormInfo. Fields not relevant for imported Ids are +-- omitted in this type. +data IfaceLFInfo + = IfLFReEntrant !RepArity + | IfLFThunk + !Bool -- True <=> updatable + !Bool -- True <=> might be a function type + | IfLFCon !Name + | IfLFUnknown !Bool + | IfLFUnlifted + +tcStandardFormInfo :: IfaceStandardFormInfo -> StandardFormInfo +tcStandardFormInfo (IfStandardFormInfo w) + | testBit w 0 = NonStandardThunk + | otherwise = con field + where + field = fromIntegral (w `unsafeShiftR` 2) + con + | testBit w 1 = ApThunk + | otherwise = SelectorThunk + +instance Outputable IfaceLFInfo where + ppr (IfLFReEntrant arity) = + text "LFReEntrant" <+> ppr arity + + ppr (IfLFThunk updatable mb_fun) = + text "LFThunk" <+> parens + (text "updatable=" <> ppr updatable <+> + text "might_be_function=" <+> ppr mb_fun) + + ppr (IfLFCon con) = + text "LFCon" <> brackets (ppr con) + + ppr IfLFUnlifted = + text "LFUnlifted" + + ppr (IfLFUnknown fun_flag) = + text "LFUnknown" <+> ppr fun_flag + +newtype IfaceStandardFormInfo = IfStandardFormInfo Word16 + +instance Binary IfaceStandardFormInfo where + put_ bh (IfStandardFormInfo w) = put_ bh (w :: Word16) + get bh = IfStandardFormInfo <$> (get bh :: IO Word16) + +instance Binary IfaceLFInfo where + put_ bh (IfLFReEntrant arity) = do + putByte bh 0 + put_ bh arity + put_ bh (IfLFThunk updatable mb_fun) = do + putByte bh 1 + put_ bh updatable + put_ bh mb_fun + put_ bh (IfLFCon con_name) = do + putByte bh 2 + put_ bh con_name + put_ bh (IfLFUnknown fun_flag) = do + putByte bh 3 + put_ bh fun_flag + put_ bh IfLFUnlifted = + putByte bh 4 + get bh = do + tag <- getByte bh + case tag of + 0 -> IfLFReEntrant <$> get bh + 1 -> IfLFThunk <$> get bh <*> get bh + 2 -> IfLFCon <$> get bh + 3 -> IfLFUnknown <$> get bh + 4 -> pure IfLFUnlifted + _ -> panic "Invalid byte" + {- Note [Versioning of instances] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1393,6 +1472,7 @@ instance Outputable IfaceInfoItem where ppr (HsCpr cpr) = text "CPR:" <+> ppr cpr ppr HsNoCafRefs = text "HasNoCafRefs" ppr HsLevity = text "Never levity-polymorphic" + ppr (HsLFInfo lf_info) = text "LambdaFormInfo:" <+> ppr lf_info instance Outputable IfaceJoinInfo where ppr IfaceNotJoinPoint = empty @@ -1853,7 +1933,7 @@ instance Binary IfaceDecl where get bh = do h <- getByte bh case h of - 0 -> do name <- get bh + 0 -> do name <- get bh ~(ty, details, idinfo) <- lazyGet bh -- See Note [Lazy deserialization of IfaceId] return (IfaceId name ty details idinfo) @@ -2153,6 +2233,8 @@ instance Binary IfaceInfoItem where put_ bh HsNoCafRefs = putByte bh 4 put_ bh HsLevity = putByte bh 5 put_ bh (HsCpr cpr) = putByte bh 6 >> put_ bh cpr + put_ bh (HsLFInfo lf_info) = putByte bh 7 >> put_ bh lf_info + get bh = do h <- getByte bh case h of @@ -2164,7 +2246,8 @@ instance Binary IfaceInfoItem where 3 -> liftM HsInline $ get bh 4 -> return HsNoCafRefs 5 -> return HsLevity - _ -> HsCpr <$> get bh + 6 -> HsCpr <$> get bh + _ -> HsLFInfo <$> get bh instance Binary IfaceUnfolding where put_ bh (IfCoreUnfold s e) = do @@ -2495,6 +2578,7 @@ instance NFData IfaceInfoItem where HsNoCafRefs -> () HsLevity -> () HsCpr cpr -> cpr `seq` () + HsLFInfo lf_info -> lf_info `seq` () -- TODO: seq further? instance NFData IfaceUnfolding where rnf = \case ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -123,6 +123,9 @@ data IfaceOneShot -- See Note [Preserve OneShotInfo] in CoreTicy = IfaceNoOneShot -- and Note [The oneShot function] in GHC.Types.Id.Make | IfaceOneShot +instance Outputable IfaceOneShot where + ppr IfaceNoOneShot = text "NoOneShotInfo" + ppr IfaceOneShot = text "OneShot" {- %************************************************************************ ===================================== compiler/GHC/Iface/UpdateCafInfos.hs → compiler/GHC/Iface/UpdateIdInfos.hs ===================================== @@ -1,38 +1,42 @@ {-# LANGUAGE CPP, BangPatterns, Strict, RecordWildCards #-} -module GHC.Iface.UpdateCafInfos - ( updateModDetailsCafInfos +module GHC.Iface.UpdateIdInfos + ( updateModDetailsIdInfos ) where import GHC.Prelude import GHC.Core +import GHC.Core.InstEnv import GHC.Driver.Session import GHC.Driver.Types +import GHC.StgToCmm.Types (CgInfos (..)) import GHC.Types.Id import GHC.Types.Id.Info -import GHC.Core.InstEnv import GHC.Types.Name.Env import GHC.Types.Name.Set -import GHC.Utils.Misc import GHC.Types.Var +import GHC.Utils.Misc import GHC.Utils.Outputable #include "HsVersions.h" --- | Update CafInfos of all occurences (in rules, unfoldings, class instances) -updateModDetailsCafInfos +-- | Update CafInfos and LFInfos of all occurences (in rules, unfoldings, class +-- instances). +-- +-- See Note [Conveying CAF-info and LFInfo between modules] in +-- GHC.StgToCmm.Types. +updateModDetailsIdInfos :: DynFlags - -> NameSet -- ^ Non-CAFFY names in the module. Names not in this set are CAFFY. + -> CgInfos -> ModDetails -- ^ ModDetails to update -> ModDetails -updateModDetailsCafInfos dflags _ mod_details +updateModDetailsIdInfos dflags _ mod_details | gopt Opt_OmitInterfacePragmas dflags = mod_details -updateModDetailsCafInfos _ non_cafs mod_details = - {- pprTrace "updateModDetailsCafInfos" (text "non_cafs:" <+> ppr non_cafs) $ -} +updateModDetailsIdInfos _ cg_infos mod_details = let ModDetails{ md_types = type_env -- for unfoldings , md_insts = insts @@ -40,11 +44,11 @@ updateModDetailsCafInfos _ non_cafs mod_details = } = mod_details -- type TypeEnv = NameEnv TyThing - ~type_env' = mapNameEnv (updateTyThingCafInfos type_env' non_cafs) type_env + ~type_env' = mapNameEnv (updateTyThingIdInfos type_env' cg_infos) type_env -- Not strict! - !insts' = strictMap (updateInstCafInfos type_env' non_cafs) insts - !rules' = strictMap (updateRuleCafInfos type_env') rules + !insts' = strictMap (updateInstIdInfos type_env' cg_infos) insts + !rules' = strictMap (updateRuleIdInfos type_env') rules in mod_details{ md_types = type_env' , md_insts = insts' @@ -55,28 +59,28 @@ updateModDetailsCafInfos _ non_cafs mod_details = -- Rules -------------------------------------------------------------------------------- -updateRuleCafInfos :: TypeEnv -> CoreRule -> CoreRule -updateRuleCafInfos _ rule at BuiltinRule{} = rule -updateRuleCafInfos type_env Rule{ .. } = Rule { ru_rhs = updateGlobalIds type_env ru_rhs, .. } +updateRuleIdInfos :: TypeEnv -> CoreRule -> CoreRule +updateRuleIdInfos _ rule at BuiltinRule{} = rule +updateRuleIdInfos type_env Rule{ .. } = Rule { ru_rhs = updateGlobalIds type_env ru_rhs, .. } -------------------------------------------------------------------------------- -- Instances -------------------------------------------------------------------------------- -updateInstCafInfos :: TypeEnv -> NameSet -> ClsInst -> ClsInst -updateInstCafInfos type_env non_cafs = - updateClsInstDFun (updateIdUnfolding type_env . updateIdCafInfo non_cafs) +updateInstIdInfos :: TypeEnv -> CgInfos -> ClsInst -> ClsInst +updateInstIdInfos type_env cg_infos = + updateClsInstDFun (updateIdUnfolding type_env . updateIdInfo cg_infos) -------------------------------------------------------------------------------- -- TyThings -------------------------------------------------------------------------------- -updateTyThingCafInfos :: TypeEnv -> NameSet -> TyThing -> TyThing +updateTyThingIdInfos :: TypeEnv -> CgInfos -> TyThing -> TyThing -updateTyThingCafInfos type_env non_cafs (AnId id) = - AnId (updateIdUnfolding type_env (updateIdCafInfo non_cafs id)) +updateTyThingIdInfos type_env cg_infos (AnId id) = + AnId (updateIdUnfolding type_env (updateIdInfo cg_infos id)) -updateTyThingCafInfos _ _ other = other -- AConLike, ATyCon, ACoAxiom +updateTyThingIdInfos _ _ other = other -- AConLike, ATyCon, ACoAxiom -------------------------------------------------------------------------------- -- Unfoldings @@ -95,13 +99,18 @@ updateIdUnfolding type_env id = -- Expressions -------------------------------------------------------------------------------- -updateIdCafInfo :: NameSet -> Id -> Id -updateIdCafInfo non_cafs id - | idName id `elemNameSet` non_cafs - = -- pprTrace "updateIdCafInfo" (text "Marking" <+> ppr id <+> parens (ppr (idName id)) <+> text "as non-CAFFY") $ - id `setIdCafInfo` NoCafRefs - | otherwise - = id +updateIdInfo :: CgInfos -> Id -> Id +updateIdInfo CgInfos{ cgNonCafs = non_cafs, cgLFInfos = lf_infos } id = + let + not_caffy = elemNameSet (idName id) non_cafs + mb_lf_info = lookupNameEnv lf_infos (idName id) + + id1 = if not_caffy then setIdCafInfo id NoCafRefs else id + id2 = case mb_lf_info of + Nothing -> id1 + Just lf_info -> setIdLFInfo id1 lf_info + in + id2 -------------------------------------------------------------------------------- @@ -116,7 +125,7 @@ updateGlobalIds env e = go env e case lookupNameEnv env (varName var) of Nothing -> var Just (AnId id) -> id - Just other -> pprPanic "GHC.Iface.UpdateCafInfos.updateGlobalIds" $ + Just other -> pprPanic "UpdateCafInfos.updateGlobalIds" $ text "Found a non-Id for Id Name" <+> ppr (varName var) $$ nest 4 (text "Id:" <+> ppr var $$ text "TyThing:" <+> ppr other) ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -19,7 +19,8 @@ module GHC.IfaceToCore ( tcIfaceDecl, tcIfaceInst, tcIfaceFamInst, tcIfaceRules, tcIfaceAnnotations, tcIfaceCompleteSigs, tcIfaceExpr, -- Desired by HERMIT (#7683) - tcIfaceGlobal + tcIfaceGlobal, + tcIfaceOneShot ) where #include "HsVersions.h" @@ -30,6 +31,7 @@ import GHC.Builtin.Types.Literals(typeNatCoAxiomRules) import GHC.Iface.Syntax import GHC.Iface.Load import GHC.Iface.Env +import GHC.StgToCmm.Types import GHC.Tc.TyCl.Build import GHC.Tc.Utils.Monad import GHC.Tc.Utils.TcType @@ -1464,8 +1466,7 @@ tcIdInfo ignore_prags toplvl name ty info = do let init_info | if_boot lcl_env = vanillaIdInfo `setUnfoldingInfo` BootUnfolding | otherwise = vanillaIdInfo - let needed = needed_prags info - foldlM tcPrag init_info needed + foldlM tcPrag init_info (needed_prags info) where needed_prags :: [IfaceInfoItem] -> [IfaceInfoItem] needed_prags items @@ -1485,6 +1486,9 @@ tcIdInfo ignore_prags toplvl name ty info = do tcPrag info (HsCpr cpr) = return (info `setCprInfo` cpr) tcPrag info (HsInline prag) = return (info `setInlinePragInfo` prag) tcPrag info HsLevity = return (info `setNeverLevPoly` ty) + tcPrag info (HsLFInfo lf_info) = do + lf_info <- tcLFInfo lf_info + return (info `setLFInfo` lf_info) -- The next two are lazy, so they don't transitively suck stuff in tcPrag info (HsUnfold lb if_unf) @@ -1497,6 +1501,38 @@ tcJoinInfo :: IfaceJoinInfo -> Maybe JoinArity tcJoinInfo (IfaceJoinPoint ar) = Just ar tcJoinInfo IfaceNotJoinPoint = Nothing +tcLFInfo :: IfaceLFInfo -> IfL LambdaFormInfo +tcLFInfo lfi = case lfi of + IfLFReEntrant rep_arity -> + -- LFReEntrant closures in interface files are guaranteed to + -- + -- - Be top-level, as only top-level closures are exported. + -- - Have no free variables, as only non-top-level closures have free + -- variables + -- - Don't have ArgDescrs, as ArgDescr is used when generating code for + -- the closure + -- + -- These invariants are checked when generating LFInfos in toIfaceLFInfo. + return (LFReEntrant TopLevel rep_arity True ArgUnknown) + + IfLFThunk updatable mb_fun -> + -- LFThunk closure in interface files are guaranteed to + -- + -- - Be top-level + -- - No have free variables + -- + -- These invariants are checked when generating LFInfos in toIfaceLFInfo. + return (LFThunk TopLevel True updatable NonStandardThunk mb_fun) + + IfLFUnlifted -> + return LFUnlifted + + IfLFCon con_name -> + LFCon <$!> tcIfaceDataCon con_name + + IfLFUnknown fun_flag -> + return (LFUnknown fun_flag) + tcUnfolding :: TopLevelFlag -> Name -> Type -> IdInfo -> IfaceUnfolding -> IfL Unfolding tcUnfolding toplvl name _ info (IfCoreUnfold stable if_expr) = do { dflags <- getDynFlags @@ -1508,7 +1544,7 @@ tcUnfolding toplvl name _ info (IfCoreUnfold stable if_expr) Just expr -> mkFinalUnfolding dflags unf_src strict_sig expr } where - -- Strictness should occur before unfolding! + -- Strictness should occur before unfolding! strict_sig = strictnessInfo info tcUnfolding toplvl name _ _ (IfCompulsory if_expr) @@ -1583,6 +1619,10 @@ tcPragExpr is_compulsory toplvl name expr -- It's OK to use nonDetEltsUFM here because we immediately forget -- the ordering by creating a set +tcIfaceOneShot :: IfaceOneShot -> OneShotInfo +tcIfaceOneShot IfaceNoOneShot = NoOneShotInfo +tcIfaceOneShot IfaceOneShot = OneShotLam + {- ************************************************************************ * * ===================================== compiler/GHC/Runtime/Heap/Layout.hs ===================================== @@ -51,6 +51,7 @@ import GHC.Driver.Session import GHC.Utils.Outputable import GHC.Platform import GHC.Data.FastString +import GHC.StgToCmm.Types import Data.Word import Data.Bits @@ -64,9 +65,6 @@ import Data.ByteString (ByteString) ************************************************************************ -} --- | Word offset, or word count -type WordOff = Int - -- | Byte offset, or byte count type ByteOff = Int @@ -196,29 +194,6 @@ type ConstrDescription = ByteString -- result of dataConIdentity type FunArity = Int type SelectorOffset = Int -------------------------- --- We represent liveness bitmaps as a Bitmap (whose internal --- representation really is a bitmap). These are pinned onto case return --- vectors to indicate the state of the stack for the garbage collector. --- --- In the compiled program, liveness bitmaps that fit inside a single --- word (StgWord) are stored as a single word, while larger bitmaps are --- stored as a pointer to an array of words. - -type Liveness = [Bool] -- One Bool per word; True <=> non-ptr or dead - -- False <=> ptr - -------------------------- --- An ArgDescr describes the argument pattern of a function - -data ArgDescr - = ArgSpec -- Fits one of the standard patterns - !Int -- RTS type identifier ARG_P, ARG_N, ... - - | ArgGen -- General case - Liveness -- Details about the arguments - - ----------------------------------------------------------------------------- -- Construction @@ -545,10 +520,6 @@ instance Outputable SMRep where ppr (RTSRep ty rep) = text "tag:" <> ppr ty <+> ppr rep -instance Outputable ArgDescr where - ppr (ArgSpec n) = text "ArgSpec" <+> ppr n - ppr (ArgGen ls) = text "ArgGen" <+> ppr ls - pprTypeInfo :: ClosureTypeInfo -> SDoc pprTypeInfo (Constr tag descr) = text "Con" <+> ===================================== compiler/GHC/StgToCmm.hs ===================================== @@ -1,5 +1,6 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-} +{-# LANGUAGE BangPatterns #-} ----------------------------------------------------------------------------- -- @@ -25,6 +26,7 @@ import GHC.StgToCmm.Utils import GHC.StgToCmm.Closure import GHC.StgToCmm.Hpc import GHC.StgToCmm.Ticky +import GHC.StgToCmm.Types (ModuleLFInfos) import GHC.Cmm import GHC.Cmm.Utils @@ -47,6 +49,8 @@ import GHC.Data.Stream import GHC.Types.Basic import GHC.Types.Var.Set ( isEmptyDVarSet ) import GHC.SysTools.FileCleanup +import GHC.Types.Unique.FM +import GHC.Types.Name.Env import GHC.Data.OrdList import GHC.Cmm.Graph @@ -63,7 +67,8 @@ codeGen :: DynFlags -> CollectedCCs -- (Local/global) cost-centres needing declaring/registering. -> [CgStgTopBinding] -- Bindings to convert -> HpcInfo - -> Stream IO CmmGroup () -- Output as a stream, so codegen can + -> Stream IO CmmGroup ModuleLFInfos + -- Output as a stream, so codegen can -- be interleaved with output codeGen dflags this_mod data_tycons @@ -105,6 +110,18 @@ codeGen dflags this_mod data_tycons mapM_ (cg . cgDataCon) (tyConDataCons tycon) ; mapM_ do_tycon data_tycons + + ; cg_id_infos <- cgs_binds <$> liftIO (readIORef cgref) + + ; let extractInfo info = (name, lf) + where + !id = cg_id info + !name = idName id + !lf = cg_lf info + + ; let !generatedInfo = mkNameEnv (Prelude.map extractInfo (eltsUFM cg_id_infos)) + + ; return generatedInfo } --------------------------------------------------------------- ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -70,6 +70,7 @@ import GHC.Stg.Syntax import GHC.Runtime.Heap.Layout import GHC.Cmm import GHC.Cmm.Ppr.Expr() -- For Outputable instances +import GHC.StgToCmm.Types import GHC.Types.CostCentre import GHC.Cmm.BlockId @@ -188,76 +189,6 @@ addArgReps = map (\arg -> let arg' = fromNonVoid arg argPrimRep :: StgArg -> PrimRep argPrimRep arg = typePrimRep1 (stgArgType arg) - ------------------------------------------------------------------------------ --- LambdaFormInfo ------------------------------------------------------------------------------ - --- Information about an identifier, from the code generator's point of --- view. Every identifier is bound to a LambdaFormInfo in the --- environment, which gives the code generator enough info to be able to --- tail call or return that identifier. - -data LambdaFormInfo - = LFReEntrant -- Reentrant closure (a function) - TopLevelFlag -- True if top level - !RepArity -- Arity. Invariant: always > 0 - !Bool -- True <=> no fvs - ArgDescr -- Argument descriptor (should really be in ClosureInfo) - - | LFThunk -- Thunk (zero arity) - TopLevelFlag - !Bool -- True <=> no free vars - !Bool -- True <=> updatable (i.e., *not* single-entry) - StandardFormInfo - !Bool -- True <=> *might* be a function type - - | LFCon -- A saturated constructor application - DataCon -- The constructor - - | LFUnknown -- Used for function arguments and imported things. - -- We know nothing about this closure. - -- Treat like updatable "LFThunk"... - -- Imported things which we *do* know something about use - -- one of the other LF constructors (eg LFReEntrant for - -- known functions) - !Bool -- True <=> *might* be a function type - -- The False case is good when we want to enter it, - -- because then we know the entry code will do - -- For a function, the entry code is the fast entry point - - | LFUnlifted -- A value of unboxed type; - -- always a value, needs evaluation - - | LFLetNoEscape -- See LetNoEscape module for precise description - - -------------------------- --- StandardFormInfo tells whether this thunk has one of --- a small number of standard forms - -data StandardFormInfo - = NonStandardThunk - -- The usual case: not of the standard forms - - | SelectorThunk - -- A SelectorThunk is of form - -- case x of - -- con a1,..,an -> ak - -- and the constructor is from a single-constr type. - WordOff -- 0-origin offset of ak within the "goods" of - -- constructor (Recall that the a1,...,an may be laid - -- out in the heap in a non-obvious order.) - - | ApThunk - -- An ApThunk is of form - -- x1 ... xn - -- The code for the thunk just pushes x2..xn on the stack and enters x1. - -- There are a few of these (for 1 <= n <= MAX_SPEC_AP_SIZE) pre-compiled - -- in the RTS to save space. - RepArity -- Arity, n - - ------------------------------------------------------ -- Building LambdaFormInfo ------------------------------------------------------ @@ -325,18 +256,22 @@ mkApLFInfo id upd_flag arity ------------- mkLFImported :: Id -> LambdaFormInfo -mkLFImported id - | Just con <- isDataConWorkId_maybe id - , isNullaryRepDataCon con - = LFCon con -- An imported nullary constructor - -- We assume that the constructor is evaluated so that - -- the id really does point directly to the constructor - - | arity > 0 - = LFReEntrant TopLevel arity True (panic "arg_descr") - - | otherwise - = mkLFArgument id -- Not sure of exact arity +mkLFImported id = + case idLFInfo_maybe id of + Just lf_info -> + lf_info + Nothing + | Just con <- isDataConWorkId_maybe id + , isNullaryRepDataCon con + -> LFCon con -- An imported nullary constructor + -- We assume that the constructor is evaluated so that + -- the id really does point directly to the constructor + + | arity > 0 + -> LFReEntrant TopLevel arity True ArgUnknown + + | otherwise + -> mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id ===================================== compiler/GHC/StgToCmm/Types.hs ===================================== @@ -0,0 +1,224 @@ +{-# LANGUAGE CPP #-} + +module GHC.StgToCmm.Types + ( CgInfos (..) + , LambdaFormInfo (..) + , ModuleLFInfos + , Liveness + , ArgDescr (..) + , StandardFormInfo (..) + , WordOff + ) where + +#include "HsVersions.h" + +import GHC.Prelude + +import GHC.Types.Basic +import GHC.Core.DataCon +import GHC.Types.Name.Env +import GHC.Types.Name.Set +import GHC.Utils.Outputable + +{- +Note [Conveying CAF-info and LFInfo between modules] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Some information about an Id is generated in the code generator, and is not +available earlier. Namely: + +* CAF info. Code motion in Cmm or earlier phases may move references around so + we compute information about which bits of code refer to which CAF late in the + Cmm pipeline. + +* LambdaFormInfo. This records the details of a closure representation, + including + - the final arity (for functions) + - whether it is a data constructor, and if so its tag + +Collectively we call this CgInfo (see GHC.StgToCmm.Types). + +It's very useful for importing modules to have this information. We can always +make a conservative assumption, but that is bad: e.g. + +* For CAF info, if we know nothing we have to assume it is a CAF which bloats + the SRTs of the importing module. + +- For data constructors, we really like having well-tagged pointers. See #14677, + #16559, #15155, and wiki: commentary/rts/haskell-execution/pointer-tagging + +So we arrange to always serialise this information into the interface file. The +moving parts are: + +* We record the CgInfo in the IdInfo of the Id. + +* GHC.Driver.Pipeline: the call to updateModDetailsIdInfos augments the + ModDetails constructed at the end of the Core pipeline, with with CgInfo + gleaned from the back end. The hard work is done in GHC.Iface.UpdateIdInfos. + +* For ModIface we generate the final ModIface with CgInfo in + GHC.Iface.Make.mkFullIface. + +* We don't absolutely guarantee to serialise the CgInfo: we won't if you have + -fomit-interface-pragmas or -fno-code; and we won't read it in if you have + -fignore-interface-pragmas. (We could revisit this decision.) +-} + +-- | Codegen-generated Id infos, to be passed to downstream via interfaces. +-- +-- This stuff is for optimization purposes only, they're not compulsory. +-- +-- * When CafInfo of an imported Id is not known it's safe to treat it as CAFFY. +-- * When LambdaFormInfo of an imported Id is not known it's safe to treat it as +-- `LFUnknown True` (which just says "it could be anything" and we do slow +-- entry). +-- +-- See also Note [Conveying CAF-info and LFInfo between modules] above. +-- +data CgInfos = CgInfos + { cgNonCafs :: !NameSet + -- ^ Exported Non-CAFFY closures in the current module. Everything else is + -- either not exported of CAFFY. + , cgLFInfos :: !ModuleLFInfos + -- ^ LambdaFormInfos of exported closures in the current module. + } + +-------------------------------------------------------------------------------- +-- LambdaFormInfo +-------------------------------------------------------------------------------- + +-- | Maps names in the current module to their LambdaFormInfos +type ModuleLFInfos = NameEnv LambdaFormInfo + +-- | Information about an identifier, from the code generator's point of view. +-- Every identifier is bound to a LambdaFormInfo in the environment, which gives +-- the code generator enough info to be able to tail call or return that +-- identifier. +data LambdaFormInfo + = LFReEntrant -- Reentrant closure (a function) + !TopLevelFlag -- True if top level + !RepArity -- Arity. Invariant: always > 0 + !Bool -- True <=> no fvs + !ArgDescr -- Argument descriptor (should really be in ClosureInfo) + + | LFThunk -- Thunk (zero arity) + !TopLevelFlag + !Bool -- True <=> no free vars + !Bool -- True <=> updatable (i.e., *not* single-entry) + !StandardFormInfo + !Bool -- True <=> *might* be a function type + + | LFCon -- A saturated constructor application + !DataCon -- The constructor + + | LFUnknown -- Used for function arguments and imported things. + -- We know nothing about this closure. + -- Treat like updatable "LFThunk"... + -- Imported things which we *do* know something about use + -- one of the other LF constructors (eg LFReEntrant for + -- known functions) + !Bool -- True <=> *might* be a function type + -- The False case is good when we want to enter it, + -- because then we know the entry code will do + -- For a function, the entry code is the fast entry point + + | LFUnlifted -- A value of unboxed type; + -- always a value, needs evaluation + + | LFLetNoEscape -- See LetNoEscape module for precise description + +instance Outputable LambdaFormInfo where + ppr (LFReEntrant top rep fvs argdesc) = + text "LFReEntrant" <> brackets + (ppr top <+> ppr rep <+> pprFvs fvs <+> ppr argdesc) + ppr (LFThunk top hasfv updateable sfi m_function) = + text "LFThunk" <> brackets + (ppr top <+> pprFvs hasfv <+> pprUpdateable updateable <+> + ppr sfi <+> pprFuncFlag m_function) + ppr (LFCon con) = + text "LFCon" <> brackets (ppr con) + ppr (LFUnknown m_func) = + text "LFUnknown" <> brackets (pprFuncFlag m_func) + ppr LFUnlifted = + text "LFUnlifted" + ppr LFLetNoEscape = + text "LFLetNoEscape" + +pprFvs :: Bool -> SDoc +pprFvs True = text "no-fvs" +pprFvs False = text "fvs" + +pprFuncFlag :: Bool -> SDoc +pprFuncFlag True = text "mFunc" +pprFuncFlag False = text "value" + +pprUpdateable :: Bool -> SDoc +pprUpdateable True = text "updateable" +pprUpdateable False = text "oneshot" + +-------------------------------------------------------------------------------- + +-- | We represent liveness bitmaps as a Bitmap (whose internal representation +-- really is a bitmap). These are pinned onto case return vectors to indicate +-- the state of the stack for the garbage collector. +-- +-- In the compiled program, liveness bitmaps that fit inside a single word +-- (StgWord) are stored as a single word, while larger bitmaps are stored as a +-- pointer to an array of words. + +type Liveness = [Bool] -- One Bool per word; True <=> non-ptr or dead + -- False <=> ptr + +-------------------------------------------------------------------------------- +-- | An ArgDescr describes the argument pattern of a function + +data ArgDescr + = ArgSpec -- Fits one of the standard patterns + !Int -- RTS type identifier ARG_P, ARG_N, ... + + | ArgGen -- General case + Liveness -- Details about the arguments + + | ArgUnknown -- For imported binds. + -- Invariant: Never Unknown for binds of the module + -- we are compiling. + deriving (Eq) + +instance Outputable ArgDescr where + ppr (ArgSpec n) = text "ArgSpec" <+> ppr n + ppr (ArgGen ls) = text "ArgGen" <+> ppr ls + ppr ArgUnknown = text "ArgUnknown" + +-------------------------------------------------------------------------------- +-- | StandardFormInfo tells whether this thunk has one of a small number of +-- standard forms + +data StandardFormInfo + = NonStandardThunk + -- The usual case: not of the standard forms + + | SelectorThunk + -- A SelectorThunk is of form + -- case x of + -- con a1,..,an -> ak + -- and the constructor is from a single-constr type. + !WordOff -- 0-origin offset of ak within the "goods" of + -- constructor (Recall that the a1,...,an may be laid + -- out in the heap in a non-obvious order.) + + | ApThunk + -- An ApThunk is of form + -- x1 ... xn + -- The code for the thunk just pushes x2..xn on the stack and enters x1. + -- There are a few of these (for 1 <= n <= MAX_SPEC_AP_SIZE) pre-compiled + -- in the RTS to save space. + !RepArity -- Arity, n + deriving (Eq) + +-- | Word offset, or word count +type WordOff = Int + +instance Outputable StandardFormInfo where + ppr NonStandardThunk = text "RegThunk" + ppr (SelectorThunk w) = text "SelThunk:" <> ppr w + ppr (ApThunk n) = text "ApThunk:" <> ppr n ===================================== compiler/GHC/Types/Id.hs ===================================== @@ -92,7 +92,7 @@ module GHC.Types.Id ( idCallArity, idFunRepArity, idUnfolding, realIdUnfolding, idSpecialisation, idCoreRules, idHasRules, - idCafInfo, + idCafInfo, idLFInfo_maybe, idOneShotInfo, idStateHackOneShotInfo, idOccInfo, isNeverLevPolyId, @@ -105,6 +105,7 @@ module GHC.Types.Id ( setIdSpecialisation, setIdCafInfo, setIdOccInfo, zapIdOccInfo, + setIdLFInfo, setIdDemandInfo, setIdStrictness, @@ -731,6 +732,15 @@ idCafInfo id = cafInfo (idInfo id) setIdCafInfo :: Id -> CafInfo -> Id setIdCafInfo id caf_info = modifyIdInfo (`setCafInfo` caf_info) id + --------------------------------- + -- Lambda form info + +idLFInfo_maybe :: Id -> Maybe LambdaFormInfo +idLFInfo_maybe = lfInfo . idInfo + +setIdLFInfo :: Id -> LambdaFormInfo -> Id +setIdLFInfo id lf = modifyIdInfo (`setLFInfo` lf) id + --------------------------------- -- Occurrence INFO idOccInfo :: Id -> OccInfo ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -74,6 +74,10 @@ module GHC.Types.Id.Info ( ppCafInfo, mayHaveCafRefs, cafInfo, setCafInfo, + -- ** The LambdaFormInfo type + LambdaFormInfo(..), + lfInfo, setLFInfo, + -- ** Tick-box Info TickBoxOp(..), TickBoxId, @@ -105,6 +109,8 @@ import GHC.Types.Demand import GHC.Types.Cpr import GHC.Utils.Misc +import GHC.StgToCmm.Types (LambdaFormInfo (..)) + -- infixl so you can say (id `set` a `set` b) infixl 1 `setRuleInfo`, `setArityInfo`, @@ -251,7 +257,7 @@ data IdInfo -- See Note [Specialisations and RULES in IdInfo] unfoldingInfo :: Unfolding, -- ^ The 'Id's unfolding - cafInfo :: CafInfo, + cafInfo :: !CafInfo, -- ^ 'Id' CAF info oneShotInfo :: OneShotInfo, -- ^ Info about a lambda-bound variable, if the 'Id' is one @@ -271,8 +277,9 @@ data IdInfo -- ^ How this is called. This is the number of arguments to which a -- binding can be eta-expanded without losing any sharing. -- n <=> all calls have at least n arguments - levityInfo :: LevityInfo + levityInfo :: LevityInfo, -- ^ when applied, will this Id ever have a levity-polymorphic type? + lfInfo :: !(Maybe LambdaFormInfo) } -- Setters @@ -295,13 +302,18 @@ setUnfoldingInfo info uf setArityInfo :: IdInfo -> ArityInfo -> IdInfo setArityInfo info ar = info { arityInfo = ar } + setCallArityInfo :: IdInfo -> ArityInfo -> IdInfo setCallArityInfo info ar = info { callArityInfo = ar } + setCafInfo :: IdInfo -> CafInfo -> IdInfo -setCafInfo info caf = info { cafInfo = caf } +setCafInfo info caf = info { cafInfo = caf } + +setLFInfo :: IdInfo -> LambdaFormInfo -> IdInfo +setLFInfo info lf = info { lfInfo = Just lf } setOneShotInfo :: IdInfo -> OneShotInfo -> IdInfo -setOneShotInfo info lb = {-lb `seq`-} info { oneShotInfo = lb } +setOneShotInfo info lb = {-lb `seq`-} info { oneShotInfo = lb } setDemandInfo :: IdInfo -> Demand -> IdInfo setDemandInfo info dd = dd `seq` info { demandInfo = dd } @@ -327,7 +339,8 @@ vanillaIdInfo strictnessInfo = nopSig, cprInfo = topCprSig, callArityInfo = unknownArity, - levityInfo = NoLevityInfo + levityInfo = NoLevityInfo, + lfInfo = Nothing } -- | More informative 'IdInfo' we can use when we know the 'Id' has no CAF references ===================================== compiler/ghc.cabal.in ===================================== @@ -228,7 +228,7 @@ Library GHC.Types.SrcLoc GHC.Types.Unique.Supply GHC.Types.Unique - GHC.Iface.UpdateCafInfos + GHC.Iface.UpdateIdInfos GHC.Types.Var GHC.Types.Var.Env GHC.Types.Var.Set @@ -295,6 +295,7 @@ Library GHC.StgToCmm.Ticky GHC.StgToCmm.Utils GHC.StgToCmm.ExtCode + GHC.StgToCmm.Types GHC.Runtime.Heap.Layout GHC.Core.Arity GHC.Core.FVs ===================================== testsuite/tests/codeGen/should_compile/Makefile ===================================== @@ -64,10 +64,10 @@ T17648: # NoCafRefs) to the interface files. '$(TEST_HC)' $(TEST_HC_OPTS) -dno-typeable-binds -O T17648.hs -v0 '$(TEST_HC)' --show-iface T17648.hi | tr -d '\n\r' | \ - grep -F 'f :: T GHC.Types.Int -> () [HasNoCafRefs, Arity' >/dev/null + grep -F 'f :: T GHC.Types.Int -> () [HasNoCafRefs, LambdaFormInfo' >/dev/null # Second compilation with -fcatch-bottoms, f should be CAFFY '$(TEST_HC)' $(TEST_HC_OPTS) -dno-typeable-binds -O \ -fcatch-bottoms T17648.hs -v0 -fforce-recomp '$(TEST_HC)' --show-iface T17648.hi | tr -d '\n\r' | \ - grep -F 'f :: T GHC.Types.Int -> () [Arity: 1, Strictness' >/dev/null + grep -F 'f :: T GHC.Types.Int -> () [LambdaFormInfo' >/dev/null ===================================== testsuite/tests/codeGen/should_compile/cg009/A.hs ===================================== @@ -0,0 +1,5 @@ +module A where + +newtype A = A Int + +val = A 42 ===================================== testsuite/tests/codeGen/should_compile/cg009/Main.hs ===================================== @@ -0,0 +1,7 @@ +module Main where + +import A + +main = return () + +a = val ===================================== testsuite/tests/codeGen/should_compile/cg009/Makefile ===================================== @@ -0,0 +1,9 @@ +TOP=../../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +# Make sure the LFInfo for an exported, but not directly used newtype +# constructors does not trip up the compiler. +cg009: + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O A.hs -fforce-recomp + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O0 Main.hs -fforce-recomp ===================================== testsuite/tests/codeGen/should_compile/cg009/all.T ===================================== @@ -0,0 +1 @@ +test('cg009', [extra_files(['A.hs','Main.hs'])], makefile_test, ['cg009']) ===================================== testsuite/tests/codeGen/should_compile/cg010/A.hs ===================================== @@ -0,0 +1,4 @@ +module A where + +{-# NOINLINE val #-} +val = Just 42 ===================================== testsuite/tests/codeGen/should_compile/cg010/Main.hs ===================================== @@ -0,0 +1,7 @@ +module Main where + +import A + +main = return () + +a = val ===================================== testsuite/tests/codeGen/should_compile/cg010/Makefile ===================================== @@ -0,0 +1,9 @@ +TOP=../../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +# Make sure LFInfo causes the imported reference to val to get tagged. +cg010: + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O A.hs -fforce-recomp + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O Main.hs -fforce-recomp -ddump-cmm -ddump-to-file + grep "A.val_closure+2" Main.dump-cmm ===================================== testsuite/tests/codeGen/should_compile/cg010/all.T ===================================== @@ -0,0 +1 @@ +test('cg010', [extra_files(['A.hs','Main.hs'])], makefile_test, ['cg010']) ===================================== testsuite/tests/codeGen/should_compile/cg010/cg010.stdout ===================================== @@ -0,0 +1 @@ + const A.val_closure+2; ===================================== testsuite/tests/simplCore/should_compile/Makefile ===================================== @@ -107,7 +107,7 @@ T4201: '$(TEST_HC)' $(TEST_HC_OPTS) -c -O T4201.hs '$(TEST_HC)' $(TEST_HC_OPTS) --show-iface T4201.hi > T4201.list # poor man idea about how to replace GNU grep -B2 "Sym" invocation with pure POSIX tools - for i in `grep -n "Sym" T4201.list |cut -d ':' -f -1`; do head -$$i T4201.list | tail -3 ; done + for i in `grep -n "Sym" T4201.list | cut -d ':' -f -1`; do head -$$i T4201.list | tail -4; done $(RM) -f T4201.list # This one looped as a result of bogus specialisation ===================================== testsuite/tests/simplCore/should_compile/T4201.stdout ===================================== @@ -1,3 +1,4 @@ - [HasNoCafRefs, Arity: 1, Strictness: , + [HasNoCafRefs, LambdaFormInfo: LFReEntrant 1, Arity: 1, + Strictness: , Unfolding: InlineRule (0, True, True) bof `cast` (Sym (N:Foo[0]) ->_R _R)] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ff77245509282b1212c343a14c84dc3d0d1291ab -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ff77245509282b1212c343a14c84dc3d0d1291ab You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 1 09:10:36 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Fri, 01 May 2020 05:10:36 -0400 Subject: [Git][ghc/ghc][wip/ww-max-worker-args-old-arity] Make WorkWrap.Lib.isWorkerSmallEnough aware of the old arity Message-ID: <5eabe78c4718b_6167c5ce1b08275460@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/ww-max-worker-args-old-arity at Glasgow Haskell Compiler / GHC Commits: 54c7ea2d by Sebastian Graf at 2020-05-01T11:02:20+02:00 Make WorkWrap.Lib.isWorkerSmallEnough aware of the old arity We should allow a wrapper with up to 82 parameters when the original function had 82 parameters to begin with. I verified that this made no difference on NoFib, but then again it doesn't use huge records... Fixes #18122. - - - - - 6 changed files: - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - docs/users_guide/using-optimisation.rst - + testsuite/tests/stranal/should_compile/T18122.hs - + testsuite/tests/stranal/should_compile/T18122.stderr - testsuite/tests/stranal/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -1997,7 +1997,7 @@ callsToNewPats env fn spec_info@(SI { si_specs = done_specs }) bndr_occs calls -- Remove ones that have too many worker variables small_pats = filterOut too_big non_dups - too_big (vars,_) = not (isWorkerSmallEnough (sc_dflags env) vars) + too_big (vars,args) = not (isWorkerSmallEnough (sc_dflags env) (length args) vars) -- We are about to construct w/w pair in 'spec_one'. -- Omit specialisation leading to high arity workers. -- See Note [Limit w/w arity] in GHC.Core.Opt.WorkWrap.Utils ===================================== compiler/GHC/Core/Opt/WorkWrap/Utils.hs ===================================== @@ -162,7 +162,7 @@ mkWwBodies dflags fam_envs rhs_fvs fun_id demands cpr_info wrapper_body = wrap_fn_args . wrap_fn_cpr . wrap_fn_str . applyToVars work_call_args . Var worker_body = mkLams work_lam_args. work_fn_str . work_fn_cpr . work_fn_args - ; if isWorkerSmallEnough dflags work_args + ; if isWorkerSmallEnough dflags (length demands) work_args && not (too_many_args_for_join_point wrap_args) && ((useful1 && not only_one_void_argument) || useful2) then return (Just (worker_args_dmds, length work_call_args, @@ -203,10 +203,13 @@ mkWwBodies dflags fam_envs rhs_fvs fun_id demands cpr_info = False -- See Note [Limit w/w arity] -isWorkerSmallEnough :: DynFlags -> [Var] -> Bool -isWorkerSmallEnough dflags vars = count isId vars <= maxWorkerArgs dflags +isWorkerSmallEnough :: DynFlags -> Int -> [Var] -> Bool +isWorkerSmallEnough dflags old_n_args vars + = count isId vars <= max old_n_args (maxWorkerArgs dflags) -- We count only Free variables (isId) to skip Type, Kind -- variables which have no runtime representation. + -- Also if the function took 82 arguments before (old_n_args), it's fine if + -- it takes <= 82 arguments afterwards. {- Note [Always do CPR w/w] @@ -227,7 +230,8 @@ Guard against high worker arity as it generates a lot of stack traffic. A simplified example is #11565#comment:6 Current strategy is very simple: don't perform w/w transformation at all -if the result produces a wrapper with arity higher than -fmax-worker-args=. +if the result produces a wrapper with arity higher than -fmax-worker-args +and the number arguments before w/w. It is a bit all or nothing, consider ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -642,14 +642,15 @@ by saying ``-fno-wombat``. Sets the maximal number of iterations for the simplifier. .. ghc-flag:: -fmax-worker-args=⟨n⟩ - :shortdesc: *default: 10.* If a worker has that many arguments, none will - be unpacked anymore. + :shortdesc: *default: 10.* Maximum number of value arguments for a worker. :type: dynamic :category: :default: 10 - If a worker has that many arguments, none will be unpacked anymore. + A function will not be split into worker and wrapper if the number of + value arguments of the resulting worker exceeds both that of the original + function and this setting. .. ghc-flag:: -fno-opt-coercion :shortdesc: Turn off the coercion optimiser ===================================== testsuite/tests/stranal/should_compile/T18122.hs ===================================== @@ -0,0 +1,6 @@ +{-# OPTIONS_GHC -fforce-recomp -O2 -fmax-worker-args=1 #-} +module Lib where + +foo :: (Int, Int) -> Int -> Int +foo (x, y) z = x+z +{-# NOINLINE foo #-} ===================================== testsuite/tests/stranal/should_compile/T18122.stderr ===================================== @@ -0,0 +1,83 @@ + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 35, types: 27, coercions: 0, joins: 0/0} + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Lib.$trModule4 :: GHC.Prim.Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +Lib.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Lib.$trModule3 :: GHC.Types.TrName +[GblId, + Cpr=m1, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +Lib.$trModule3 = GHC.Types.TrNameS Lib.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Lib.$trModule2 :: GHC.Prim.Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +Lib.$trModule2 = "Lib"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Lib.$trModule1 :: GHC.Types.TrName +[GblId, + Cpr=m1, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +Lib.$trModule1 = GHC.Types.TrNameS Lib.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +Lib.$trModule :: GHC.Types.Module +[GblId, + Cpr=m1, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] +Lib.$trModule = GHC.Types.Module Lib.$trModule3 Lib.$trModule1 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Lib.$wfoo [InlPrag=NOINLINE] + :: GHC.Prim.Int# -> GHC.Prim.Int# -> GHC.Prim.Int# +[GblId, Arity=2, Str=, Unf=OtherCon []] +Lib.$wfoo = (GHC.Prim.+#) + +-- RHS size: {terms: 18, types: 14, coercions: 0, joins: 0/0} +foo [InlPrag=NOUSERINLINE[0]] :: (Int, Int) -> Int -> Int +[GblId, + Arity=2, + Str=, + Cpr=m1, + Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, + Guidance=ALWAYS_IF(arity=2,unsat_ok=True,boring_ok=False) + Tmpl= \ (w_sHs [Occ=Once!] :: (Int, Int)) + (w1_sHt [Occ=Once!] :: Int) -> + case w_sHs of { (ww1_sHw [Occ=Once!], _ [Occ=Dead]) -> + case ww1_sHw of { GHC.Types.I# ww4_sHz [Occ=Once] -> + case w1_sHt of { GHC.Types.I# ww6_sHF [Occ=Once] -> + case Lib.$wfoo ww4_sHz ww6_sHF of ww7_sHJ [Occ=Once] { __DEFAULT -> + GHC.Types.I# ww7_sHJ + } + } + } + }}] +foo + = \ (w_sHs :: (Int, Int)) (w1_sHt :: Int) -> + case w_sHs of { (ww1_sHw, ww2_sHB) -> + case ww1_sHw of { GHC.Types.I# ww4_sHz -> + case w1_sHt of { GHC.Types.I# ww6_sHF -> + case Lib.$wfoo ww4_sHz ww6_sHF of ww7_sHJ { __DEFAULT -> + GHC.Types.I# ww7_sHJ + } + } + } + } + + + ===================================== testsuite/tests/stranal/should_compile/all.T ===================================== @@ -51,3 +51,6 @@ test('T17852', [ grep_errmsg(r'\\$wf ::') ], compile, ['-ddump-worker-wrapper - test('T16029', normal, makefile_test, []) test('T10069', [ grep_errmsg(r'(wc1).*Int#$') ], compile, ['-dppr-cols=200 -ddump-simpl']) + +# We just want to find the worker of foo in there: +test('T18122', [ grep_errmsg(r'wfoo =') ], compile, ['-ddump-simpl']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/54c7ea2dfda9fd3f72d9d493b0efdc5ad531bf8b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/54c7ea2dfda9fd3f72d9d493b0efdc5ad531bf8b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 1 11:49:01 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Fri, 01 May 2020 07:49:01 -0400 Subject: [Git][ghc/ghc][wip/osa1/lfinfo] Cross-module LambdaFormInfo passing Message-ID: <5eac0cad257d6_616787c09cc82979a2@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/lfinfo at Glasgow Haskell Compiler / GHC Commits: 38f63fb8 by Ömer Sinan Ağacan at 2020-05-01T14:48:45+03:00 Cross-module LambdaFormInfo passing - Store LambdaFormInfos of exported Ids in interface files - Use them in importing modules This is for optimization purposes: if we know LambdaFormInfo of imported Ids we can generate more efficient calling code, see `getCallMethod`. Exporting (putting them in interface files or in ModDetails) and importing (reading them from interface files) are both optional. We don't assume known LambdaFormInfos anywhere and do not change how we call Ids with unknown LambdaFormInfos. Runtime, allocation, and residency numbers when building Cabal-the-library (commit 0d4ee7ba3). (Log and .hp files are in the MR: !2842) Runtime: | | GHC HEAD | This patch | Diff | |-----|----------|------------|----------------| | -O0 | 0:35.70 | 0:34.75 | -0.95s, -2.66% | | -O1 | 2:25.21 | 2:25.16 | -0.05s, -0.03% | | -O2 | 2:52.89 | 2:51.25 | -1.63s, -0.9% | Allocations: | | GHC HEAD | This patch | Diff | |-----|-----------------|-----------------|----------------------| | -O0 | 54,872,673,008 | 54,917,849,488 | +45,176,480, +0.08% | | -O1 | 227,080,315,016 | 227,584,483,224 | +504,168,208, +0.22% | | -O2 | 266,085,969,832 | 266,710,115,472 | +624,145,640, +0.23% | Max. residency: NOTE: Residency is measured with extra runtime args: `-i0 -h` which effectively turn all GCs into major GCs, and do GC more often. | | GHC HEAD | This patch | Diff | |-----|----------------------------|------------------------------|----------------------| | -O0 | 416,350,080 (894 samples) | 417,733,152 (892 samples) | +1,383,072, +0.33% | | -O1 | 928,484,840 (2101 samples) | 945,624,664 (2098 samples) | +17,139,824, +1.84% | | -O2 | 991,311,896 (2548 samples) | 1,010,647,088 (2536 samples) | +19,335,192, +1.95% | NoFib results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS 0.0% 0.0% +0.0% +0.0% +0.0% CSD 0.0% 0.0% 0.0% +0.0% +0.0% FS 0.0% 0.0% +0.0% +0.0% +0.0% S 0.0% 0.0% +0.0% +0.0% +0.0% VS 0.0% 0.0% +0.0% +0.0% +0.0% VSD 0.0% 0.0% +0.0% +0.0% +0.1% VSM 0.0% 0.0% +0.0% +0.0% +0.0% anna 0.0% 0.0% -0.3% -0.8% -0.0% ansi 0.0% 0.0% -0.0% -0.0% 0.0% atom 0.0% 0.0% -0.0% -0.0% 0.0% awards 0.0% 0.0% -0.1% -0.3% 0.0% banner 0.0% 0.0% -0.0% -0.0% -0.0% bernouilli 0.0% 0.0% -0.0% -0.0% -0.0% binary-trees 0.0% 0.0% -0.0% -0.0% +0.0% boyer 0.0% 0.0% -0.0% -0.0% 0.0% boyer2 0.0% 0.0% -0.0% -0.0% 0.0% bspt 0.0% 0.0% -0.0% -0.2% 0.0% cacheprof 0.0% 0.0% -0.1% -0.4% +0.0% calendar 0.0% 0.0% -0.0% -0.0% 0.0% cichelli 0.0% 0.0% -0.9% -2.4% 0.0% circsim 0.0% 0.0% -0.0% -0.0% 0.0% clausify 0.0% 0.0% -0.1% -0.3% 0.0% comp_lab_zift 0.0% 0.0% -0.0% -0.0% +0.0% compress 0.0% 0.0% -0.0% -0.0% -0.0% compress2 0.0% 0.0% -0.0% -0.0% 0.0% constraints 0.0% 0.0% -0.1% -0.2% -0.0% cryptarithm1 0.0% 0.0% -0.0% -0.0% 0.0% cryptarithm2 0.0% 0.0% -1.4% -4.1% -0.0% cse 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e1 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e2 0.0% 0.0% -0.0% -0.0% -0.0% dom-lt 0.0% 0.0% -0.1% -0.2% 0.0% eliza 0.0% 0.0% -0.5% -1.5% 0.0% event 0.0% 0.0% -0.0% -0.0% -0.0% exact-reals 0.0% 0.0% -0.1% -0.3% +0.0% exp3_8 0.0% 0.0% -0.0% -0.0% -0.0% expert 0.0% 0.0% -0.3% -1.0% -0.0% fannkuch-redux 0.0% 0.0% +0.0% +0.0% +0.0% fasta 0.0% 0.0% -0.0% -0.0% +0.0% fem 0.0% 0.0% -0.0% -0.0% 0.0% fft 0.0% 0.0% -0.0% -0.0% 0.0% fft2 0.0% 0.0% -0.0% -0.0% 0.0% fibheaps 0.0% 0.0% -0.0% -0.0% +0.0% fish 0.0% 0.0% 0.0% -0.0% +0.0% fluid 0.0% 0.0% -0.4% -1.2% +0.0% fulsom 0.0% 0.0% -0.0% -0.0% 0.0% gamteb 0.0% 0.0% -0.1% -0.3% 0.0% gcd 0.0% 0.0% -0.0% -0.0% 0.0% gen_regexps 0.0% 0.0% -0.0% -0.0% -0.0% genfft 0.0% 0.0% -0.0% -0.0% 0.0% gg 0.0% 0.0% -0.0% -0.0% +0.0% grep 0.0% 0.0% -0.0% -0.0% -0.0% hidden 0.0% 0.0% -0.1% -0.4% -0.0% hpg 0.0% 0.0% -0.2% -0.5% +0.0% ida 0.0% 0.0% -0.0% -0.0% +0.0% infer 0.0% 0.0% -0.3% -0.8% -0.0% integer 0.0% 0.0% -0.0% -0.0% +0.0% integrate 0.0% 0.0% -0.0% -0.0% 0.0% k-nucleotide 0.0% 0.0% -0.0% -0.0% +0.0% kahan 0.0% 0.0% -0.0% -0.0% +0.0% knights 0.0% 0.0% -2.2% -5.4% 0.0% lambda 0.0% 0.0% -0.6% -1.8% 0.0% last-piece 0.0% 0.0% -0.0% -0.0% 0.0% lcss 0.0% 0.0% -0.0% -0.1% 0.0% life 0.0% 0.0% -0.0% -0.1% 0.0% lift 0.0% 0.0% -0.2% -0.6% +0.0% linear 0.0% 0.0% -0.0% -0.0% -0.0% listcompr 0.0% 0.0% -0.0% -0.0% 0.0% listcopy 0.0% 0.0% -0.0% -0.0% 0.0% maillist 0.0% 0.0% -0.1% -0.3% +0.0% mandel 0.0% 0.0% -0.0% -0.0% 0.0% mandel2 0.0% 0.0% -0.0% -0.0% -0.0% mate +0.0% 0.0% -0.0% -0.0% -0.0% minimax 0.0% 0.0% -0.2% -1.0% 0.0% mkhprog 0.0% 0.0% -0.1% -0.2% -0.0% multiplier 0.0% 0.0% -0.0% -0.0% -0.0% n-body 0.0% 0.0% -0.0% -0.0% +0.0% nucleic2 0.0% 0.0% -0.1% -0.2% 0.0% para 0.0% 0.0% -0.0% -0.0% -0.0% paraffins 0.0% 0.0% -0.0% -0.0% 0.0% parser 0.0% 0.0% -0.2% -0.7% 0.0% parstof 0.0% 0.0% -0.0% -0.0% +0.0% pic 0.0% 0.0% -0.0% -0.0% 0.0% pidigits 0.0% 0.0% +0.0% +0.0% +0.0% power 0.0% 0.0% -0.2% -0.6% +0.0% pretty 0.0% 0.0% -0.0% -0.0% -0.0% primes 0.0% 0.0% -0.0% -0.0% 0.0% primetest 0.0% 0.0% -0.0% -0.0% -0.0% prolog 0.0% 0.0% -0.3% -1.1% 0.0% puzzle 0.0% 0.0% -0.0% -0.0% 0.0% queens 0.0% 0.0% -0.0% -0.0% +0.0% reptile 0.0% 0.0% -0.0% -0.0% 0.0% reverse-complem 0.0% 0.0% -0.0% -0.0% +0.0% rewrite 0.0% 0.0% -0.7% -2.5% -0.0% rfib 0.0% 0.0% -0.0% -0.0% 0.0% rsa 0.0% 0.0% -0.0% -0.0% 0.0% scc 0.0% 0.0% -0.1% -0.2% -0.0% sched 0.0% 0.0% -0.0% -0.0% -0.0% scs 0.0% 0.0% -1.0% -2.6% +0.0% simple 0.0% 0.0% +0.0% -0.0% +0.0% solid 0.0% 0.0% -0.0% -0.0% 0.0% sorting 0.0% 0.0% -0.6% -1.6% 0.0% spectral-norm 0.0% 0.0% +0.0% 0.0% +0.0% sphere 0.0% 0.0% -0.0% -0.0% -0.0% symalg 0.0% 0.0% -0.0% -0.0% +0.0% tak 0.0% 0.0% -0.0% -0.0% 0.0% transform 0.0% 0.0% -0.0% -0.0% 0.0% treejoin 0.0% 0.0% -0.0% -0.0% 0.0% typecheck 0.0% 0.0% -0.0% -0.0% +0.0% veritas +0.0% 0.0% -0.2% -0.4% +0.0% wang 0.0% 0.0% -0.0% -0.0% 0.0% wave4main 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 0.0% 0.0% -0.0% -0.0% +0.0% x2n1 0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min 0.0% 0.0% -2.2% -5.4% -0.0% Max +0.0% 0.0% +0.0% +0.0% +0.1% Geometric Mean -0.0% -0.0% -0.1% -0.3% +0.0% Metric increases micro benchmarks tracked in #17686: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 Co-authored-by: Andreas Klebinger <klebinger.andreas at gmx.at> - - - - - 28 changed files: - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Iface/UpdateCafInfos.hs → compiler/GHC/Iface/UpdateIdInfos.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Runtime/Heap/Layout.hs - compiler/GHC/StgToCmm.hs - compiler/GHC/StgToCmm/Closure.hs - + compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/ghc.cabal.in - testsuite/tests/codeGen/should_compile/Makefile - + testsuite/tests/codeGen/should_compile/cg009/A.hs - + testsuite/tests/codeGen/should_compile/cg009/Main.hs - + testsuite/tests/codeGen/should_compile/cg009/Makefile - + testsuite/tests/codeGen/should_compile/cg009/all.T - + testsuite/tests/codeGen/should_compile/cg010/A.hs - + testsuite/tests/codeGen/should_compile/cg010/Main.hs - + testsuite/tests/codeGen/should_compile/cg010/Makefile - + testsuite/tests/codeGen/should_compile/cg010/all.T - + testsuite/tests/codeGen/should_compile/cg010/cg010.stdout - testsuite/tests/simplCore/should_compile/Makefile - testsuite/tests/simplCore/should_compile/T4201.stdout Changes: ===================================== compiler/GHC/CoreToIface.hs ===================================== @@ -34,13 +34,14 @@ module GHC.CoreToIface , toIfaceIdDetails , toIfaceIdInfo , toIfUnfolding - , toIfaceOneShot , toIfaceTickish , toIfaceBind , toIfaceAlt , toIfaceCon , toIfaceApp , toIfaceVar + -- * Other stuff + , toIfaceLFInfo ) where #include "HsVersions.h" @@ -51,6 +52,7 @@ import GHC.Iface.Syntax import GHC.Core.DataCon import GHC.Types.Id import GHC.Types.Id.Info +import GHC.StgToCmm.Types import GHC.Core import GHC.Core.TyCon hiding ( pprPromotionQuote ) import GHC.Core.Coercion.Axiom @@ -616,6 +618,34 @@ toIfaceVar v where name = idName v +--------------------- +toIfaceLFInfo :: Name -> LambdaFormInfo -> IfaceLFInfo +toIfaceLFInfo nm lfi = case lfi of + LFReEntrant top_lvl arity no_fvs _arg_descr -> + -- Exported LFReEntrant closures are top level, and top-level closures + -- don't have free variables + ASSERT2(isTopLevel top_lvl, ppr nm) + ASSERT2(no_fvs, ppr nm) + IfLFReEntrant arity + LFThunk top_lvl no_fvs updatable sfi _mb_fun -> + -- Exported LFThunk closures are top level (which don't have free + -- variables), updatable, and non-standard (see cgTopRhsClosure) + ASSERT2(isTopLevel top_lvl, ppr nm) + ASSERT2(no_fvs, ppr nm) + ASSERT2(updatable, ppr nm) + ASSERT2(sfi == NonStandardThunk, ppr nm) + IfLFUnknown + LFCon dc -> + IfLFCon (dataConName dc) + LFUnknown _might_be_function -> + -- The argument can be derived from the type via might_be_a_function so we + -- don't serialize it + IfLFUnknown + LFUnlifted -> + IfLFUnlifted + LFLetNoEscape -> + panic "toIfaceLFInfo: LFLetNoEscape" + {- Note [Inlining and hs-boot files] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider this example (#10083, #12789): ===================================== compiler/GHC/Driver/Hooks.hs ===================================== @@ -55,6 +55,7 @@ import GHC.Stg.Syntax import GHC.Data.Stream import GHC.Cmm import GHC.Hs.Extension +import GHC.StgToCmm.Types (ModuleLFInfos) import Data.Maybe @@ -109,7 +110,7 @@ data Hooks = Hooks -> IO (Maybe HValue)) , createIservProcessHook :: Maybe (CreateProcess -> IO ProcessHandle) , stgToCmmHook :: Maybe (DynFlags -> Module -> [TyCon] -> CollectedCCs - -> [CgStgTopBinding] -> HpcInfo -> Stream IO CmmGroup ()) + -> [CgStgTopBinding] -> HpcInfo -> Stream IO CmmGroup ModuleLFInfos) , cmmToRawCmmHook :: forall a . Maybe (DynFlags -> Maybe Module -> Stream IO CmmGroupSRTs a -> IO (Stream IO RawCmmGroup a)) } ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -132,7 +132,6 @@ import qualified GHC.StgToCmm as StgToCmm ( codeGen ) import GHC.Types.CostCentre import GHC.Core.TyCon import GHC.Types.Name -import GHC.Types.Name.Set import GHC.Cmm import GHC.Cmm.Parser ( parseCmmFile ) import GHC.Cmm.Info.Build @@ -147,6 +146,7 @@ import GHC.Tc.Utils.Env import GHC.Builtin.Names import GHC.Driver.Plugins import GHC.Runtime.Loader ( initializePlugins ) +import GHC.StgToCmm.Types (CgInfos (..), ModuleLFInfos) import GHC.Driver.Session import GHC.Utils.Error @@ -175,6 +175,7 @@ import qualified Data.Set as S import Data.Set (Set) import Data.Functor import Control.DeepSeq (force) +import Data.Bifunctor (first) import GHC.Iface.Ext.Ast ( mkHieFile ) import GHC.Iface.Ext.Types ( getAsts, hie_asts, hie_module ) @@ -1385,7 +1386,7 @@ hscWriteIface dflags iface no_change mod_location = do -- | Compile to hard-code. hscGenHardCode :: HscEnv -> CgGuts -> ModLocation -> FilePath - -> IO (FilePath, Maybe FilePath, [(ForeignSrcLang, FilePath)], NameSet) + -> IO (FilePath, Maybe FilePath, [(ForeignSrcLang, FilePath)], CgInfos) -- ^ @Just f@ <=> _stub.c is f hscGenHardCode hsc_env cgguts location output_filename = do let CgGuts{ -- This is the last use of the ModGuts in a compilation. @@ -1444,11 +1445,11 @@ hscGenHardCode hsc_env cgguts location output_filename = do return a rawcmms1 = Stream.mapM dump rawcmms0 - (output_filename, (_stub_h_exists, stub_c_exists), foreign_fps, caf_infos) + (output_filename, (_stub_h_exists, stub_c_exists), foreign_fps, cg_infos) <- {-# SCC "codeOutput" #-} codeOutput dflags this_mod output_filename location foreign_stubs foreign_files dependencies rawcmms1 - return (output_filename, stub_c_exists, foreign_fps, caf_infos) + return (output_filename, stub_c_exists, foreign_fps, cg_infos) hscInteractive :: HscEnv @@ -1542,7 +1543,7 @@ doCodeGen :: HscEnv -> Module -> [TyCon] -> CollectedCCs -> [StgTopBinding] -> HpcInfo - -> IO (Stream IO CmmGroupSRTs NameSet) + -> IO (Stream IO CmmGroupSRTs CgInfos) -- Note we produce a 'Stream' of CmmGroups, so that the -- backend can be run incrementally. Otherwise it generates all -- the C-- up front, which has a significant space cost. @@ -1554,7 +1555,7 @@ doCodeGen hsc_env this_mod data_tycons dumpIfSet_dyn dflags Opt_D_dump_stg_final "Final STG:" FormatSTG (pprGenStgTopBindings stg_binds_w_fvs) - let cmm_stream :: Stream IO CmmGroup () + let cmm_stream :: Stream IO CmmGroup ModuleLFInfos -- See Note [Forcing of stg_binds] cmm_stream = stg_binds_w_fvs `seqList` {-# SCC "StgToCmm" #-} lookupHook stgToCmmHook StgToCmm.codeGen dflags dflags this_mod data_tycons @@ -1573,10 +1574,14 @@ doCodeGen hsc_env this_mod data_tycons ppr_stream1 = Stream.mapM dump1 cmm_stream - pipeline_stream = - {-# SCC "cmmPipeline" #-} - Stream.mapAccumL (cmmPipeline hsc_env) (emptySRT this_mod) ppr_stream1 - <&> (srtMapNonCAFs . moduleSRTMap) + pipeline_stream :: Stream IO CmmGroupSRTs CgInfos + pipeline_stream = do + (non_cafs, lf_infos) <- + {-# SCC "cmmPipeline" #-} + Stream.mapAccumL_ (cmmPipeline hsc_env) (emptySRT this_mod) ppr_stream1 + <&> first (srtMapNonCAFs . moduleSRTMap) + + return CgInfos{ cgNonCafs = non_cafs, cgLFInfos = lf_infos } dump2 a = do unless (null a) $ ===================================== compiler/GHC/Driver/Pipeline.hs ===================================== @@ -70,7 +70,7 @@ import GHC.Settings import GHC.Data.Bag ( unitBag ) import GHC.Data.FastString ( mkFastString ) import GHC.Iface.Make ( mkFullIface ) -import GHC.Iface.UpdateCafInfos ( updateModDetailsCafInfos ) +import GHC.Iface.UpdateIdInfos ( updateModDetailsIdInfos ) import GHC.Utils.Exception as Exception import System.Directory @@ -1178,12 +1178,12 @@ runPhase (HscOut src_flavour mod_name result) _ dflags = do PipeState{hsc_env=hsc_env'} <- getPipeState - (outputFilename, mStub, foreign_files, caf_infos) <- liftIO $ + (outputFilename, mStub, foreign_files, cg_infos) <- liftIO $ hscGenHardCode hsc_env' cgguts mod_location output_fn - final_iface <- liftIO (mkFullIface hsc_env'{hsc_dflags=iface_dflags} partial_iface (Just caf_infos)) - let final_mod_details = {-# SCC updateModDetailsCafInfos #-} - updateModDetailsCafInfos iface_dflags caf_infos mod_details + final_iface <- liftIO (mkFullIface hsc_env'{hsc_dflags=iface_dflags} partial_iface (Just cg_infos)) + let final_mod_details = {-# SCC updateModDetailsIdInfos #-} + updateModDetailsIdInfos iface_dflags cg_infos mod_details setIface final_iface final_mod_details -- See Note [Writing interface files] ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -38,6 +38,7 @@ import GHC.Core.Coercion.Axiom import GHC.Core.ConLike import GHC.Core.DataCon import GHC.Core.Type +import GHC.StgToCmm.Types (CgInfos (..)) import GHC.Tc.Utils.TcType import GHC.Core.InstEnv import GHC.Core.FamInstEnv @@ -98,15 +99,19 @@ mkPartialIface hsc_env mod_details = mkIface_ hsc_env this_mod hsc_src used_th deps rdr_env fix_env warns hpc_info self_trust safe_mode usages doc_hdr decl_docs arg_docs mod_details --- | Fully instantiate a interface --- Adds fingerprints and potentially code generator produced information. -mkFullIface :: HscEnv -> PartialModIface -> Maybe NameSet -> IO ModIface -mkFullIface hsc_env partial_iface mb_non_cafs = do +-- | Fully instantiate an interface. Adds fingerprints and potentially code +-- generator produced information. +-- +-- CgInfos is not available when not generating code (-fno-code), or when not +-- generating interface pragmas (-fomit-interface-pragmas). See also +-- Note [Conveying CAF-info and LFInfo between modules] in GHC.StgToCmm.Types. +mkFullIface :: HscEnv -> PartialModIface -> Maybe CgInfos -> IO ModIface +mkFullIface hsc_env partial_iface mb_cg_infos = do let decls | gopt Opt_OmitInterfacePragmas (hsc_dflags hsc_env) = mi_decls partial_iface | otherwise - = updateDeclCafInfos (mi_decls partial_iface) mb_non_cafs + = updateDecl (mi_decls partial_iface) mb_cg_infos full_iface <- {-# SCC "addFingerprints" #-} @@ -117,15 +122,23 @@ mkFullIface hsc_env partial_iface mb_non_cafs = do return full_iface -updateDeclCafInfos :: [IfaceDecl] -> Maybe NameSet -> [IfaceDecl] -updateDeclCafInfos decls Nothing = decls -updateDeclCafInfos decls (Just non_cafs) = map update_decl decls +updateDecl :: [IfaceDecl] -> Maybe CgInfos -> [IfaceDecl] +updateDecl decls Nothing = decls +updateDecl decls (Just CgInfos{ cgNonCafs = non_cafs, cgLFInfos = lf_infos }) = map update_decl decls where + update_decl (IfaceId nm ty details infos) + | let not_caffy = elemNameSet nm non_cafs + , let mb_lf_info = lookupNameEnv lf_infos nm + , WARN( isNothing mb_lf_info, text "Name without LFInfo:" <+> ppr nm ) True + -- Only allocate a new IfaceId if we're going to update the infos + , isJust mb_lf_info || not_caffy + = IfaceId nm ty details $ + (if not_caffy then (HsNoCafRefs :) else id) + (case mb_lf_info of + Nothing -> infos -- LFInfos not available when building .cmm files + Just lf_info -> HsLFInfo (toIfaceLFInfo nm lf_info) : infos) + update_decl decl - | IfaceId nm ty details infos <- decl - , elemNameSet nm non_cafs - = IfaceId nm ty details (HsNoCafRefs : infos) - | otherwise = decl -- | Make an interface from the results of typechecking only. Useful ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -22,6 +22,8 @@ module GHC.Iface.Syntax ( IfaceAxBranch(..), IfaceTyConParent(..), IfaceCompleteMatch(..), + IfaceLFInfo(..), + IfaceStandardFormInfo(..), -- * Binding names IfaceTopBndr, @@ -30,6 +32,7 @@ module GHC.Iface.Syntax ( -- Misc ifaceDeclImplicitBndrs, visibleIfConDecls, ifaceDeclFingerprints, + tcStandardFormInfo, -- Free Names freeNamesIfDecl, freeNamesIfRule, freeNamesIfFamInst, @@ -67,15 +70,18 @@ import GHC.Utils.Binary import GHC.Data.BooleanFormula ( BooleanFormula, pprBooleanFormula, isTrue ) import GHC.Types.Var( VarBndr(..), binderVar ) import GHC.Core.TyCon ( Role (..), Injectivity(..), tyConBndrVisArgFlag ) -import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, debugIsOn ) +import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, debugIsOn, + seqList ) import GHC.Core.DataCon (SrcStrictness(..), SrcUnpackedness(..)) import GHC.Utils.Lexeme (isLexSym) import GHC.Builtin.Types ( constraintKindTyConName ) -import GHC.Utils.Misc (seqList) +import GHC.StgToCmm.Types import Control.Monad import System.IO.Unsafe import Control.DeepSeq +import Data.Word +import Data.Bits infixl 3 &&& @@ -114,7 +120,8 @@ data IfaceDecl = IfaceId { ifName :: IfaceTopBndr, ifType :: IfaceType, ifIdDetails :: IfaceIdDetails, - ifIdInfo :: IfaceIdInfo } + ifIdInfo :: IfaceIdInfo + } | IfaceData { ifName :: IfaceTopBndr, -- Type constructor ifBinders :: [IfaceTyConBinder], @@ -348,6 +355,7 @@ data IfaceInfoItem IfaceUnfolding -- See Note [Expose recursive functions] | HsNoCafRefs | HsLevity -- Present <=> never levity polymorphic + | HsLFInfo IfaceLFInfo -- NB: Specialisations and rules come in separately and are -- only later attached to the Id. Partial reason: some are orphans. @@ -379,6 +387,70 @@ data IfaceIdDetails | IfRecSelId (Either IfaceTyCon IfaceDecl) Bool | IfDFunId +-- | Iface type for LambdaFormInfo. Fields not relevant for imported Ids are +-- omitted in this type. +-- +-- Thunks are represented as LFUnknown: top-level thunks are never single-entry, +-- and for updatable thunks LFThunk and LFUnknown calling convention is the +-- same, see GHC.StgToCmm.Closure.getCallMethod. +data IfaceLFInfo + = IfLFReEntrant !RepArity + | IfLFCon !Name + | IfLFUnknown + | IfLFUnlifted + -- Generally, top-level things can't be unlifted, but we have an exception + -- for literal strings -- see Note [Core top-level string literals] in + -- GHC.Core + +tcStandardFormInfo :: IfaceStandardFormInfo -> StandardFormInfo +tcStandardFormInfo (IfStandardFormInfo w) + | testBit w 0 = NonStandardThunk + | otherwise = con field + where + field = fromIntegral (w `unsafeShiftR` 2) + con + | testBit w 1 = ApThunk + | otherwise = SelectorThunk + +instance Outputable IfaceLFInfo where + ppr (IfLFReEntrant arity) = + text "LFReEntrant" <+> ppr arity + + ppr (IfLFCon con) = + text "LFCon" <> brackets (ppr con) + + ppr IfLFUnlifted = + text "LFUnlifted" + + ppr IfLFUnknown = + text "LFUnknown" + +newtype IfaceStandardFormInfo = IfStandardFormInfo Word16 + +instance Binary IfaceStandardFormInfo where + put_ bh (IfStandardFormInfo w) = put_ bh (w :: Word16) + get bh = IfStandardFormInfo <$> (get bh :: IO Word16) + +instance Binary IfaceLFInfo where + put_ bh (IfLFReEntrant arity) = do + putByte bh 0 + put_ bh arity + put_ bh (IfLFCon con_name) = do + putByte bh 1 + put_ bh con_name + put_ bh IfLFUnknown = do + putByte bh 2 + put_ bh IfLFUnlifted = + putByte bh 3 + get bh = do + tag <- getByte bh + case tag of + 0 -> IfLFReEntrant <$> get bh + 1 -> IfLFCon <$> get bh + 2 -> pure IfLFUnknown + 3 -> pure IfLFUnlifted + _ -> panic "Invalid byte" + {- Note [Versioning of instances] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1393,6 +1465,7 @@ instance Outputable IfaceInfoItem where ppr (HsCpr cpr) = text "CPR:" <+> ppr cpr ppr HsNoCafRefs = text "HasNoCafRefs" ppr HsLevity = text "Never levity-polymorphic" + ppr (HsLFInfo lf_info) = text "LambdaFormInfo:" <+> ppr lf_info instance Outputable IfaceJoinInfo where ppr IfaceNotJoinPoint = empty @@ -1853,7 +1926,7 @@ instance Binary IfaceDecl where get bh = do h <- getByte bh case h of - 0 -> do name <- get bh + 0 -> do name <- get bh ~(ty, details, idinfo) <- lazyGet bh -- See Note [Lazy deserialization of IfaceId] return (IfaceId name ty details idinfo) @@ -2153,6 +2226,8 @@ instance Binary IfaceInfoItem where put_ bh HsNoCafRefs = putByte bh 4 put_ bh HsLevity = putByte bh 5 put_ bh (HsCpr cpr) = putByte bh 6 >> put_ bh cpr + put_ bh (HsLFInfo lf_info) = putByte bh 7 >> put_ bh lf_info + get bh = do h <- getByte bh case h of @@ -2164,7 +2239,8 @@ instance Binary IfaceInfoItem where 3 -> liftM HsInline $ get bh 4 -> return HsNoCafRefs 5 -> return HsLevity - _ -> HsCpr <$> get bh + 6 -> HsCpr <$> get bh + _ -> HsLFInfo <$> get bh instance Binary IfaceUnfolding where put_ bh (IfCoreUnfold s e) = do @@ -2495,6 +2571,7 @@ instance NFData IfaceInfoItem where HsNoCafRefs -> () HsLevity -> () HsCpr cpr -> cpr `seq` () + HsLFInfo lf_info -> lf_info `seq` () -- TODO: seq further? instance NFData IfaceUnfolding where rnf = \case ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -123,6 +123,9 @@ data IfaceOneShot -- See Note [Preserve OneShotInfo] in CoreTicy = IfaceNoOneShot -- and Note [The oneShot function] in GHC.Types.Id.Make | IfaceOneShot +instance Outputable IfaceOneShot where + ppr IfaceNoOneShot = text "NoOneShotInfo" + ppr IfaceOneShot = text "OneShot" {- %************************************************************************ ===================================== compiler/GHC/Iface/UpdateCafInfos.hs → compiler/GHC/Iface/UpdateIdInfos.hs ===================================== @@ -1,38 +1,42 @@ {-# LANGUAGE CPP, BangPatterns, Strict, RecordWildCards #-} -module GHC.Iface.UpdateCafInfos - ( updateModDetailsCafInfos +module GHC.Iface.UpdateIdInfos + ( updateModDetailsIdInfos ) where import GHC.Prelude import GHC.Core +import GHC.Core.InstEnv import GHC.Driver.Session import GHC.Driver.Types +import GHC.StgToCmm.Types (CgInfos (..)) import GHC.Types.Id import GHC.Types.Id.Info -import GHC.Core.InstEnv import GHC.Types.Name.Env import GHC.Types.Name.Set -import GHC.Utils.Misc import GHC.Types.Var +import GHC.Utils.Misc import GHC.Utils.Outputable #include "HsVersions.h" --- | Update CafInfos of all occurences (in rules, unfoldings, class instances) -updateModDetailsCafInfos +-- | Update CafInfos and LFInfos of all occurences (in rules, unfoldings, class +-- instances). +-- +-- See Note [Conveying CAF-info and LFInfo between modules] in +-- GHC.StgToCmm.Types. +updateModDetailsIdInfos :: DynFlags - -> NameSet -- ^ Non-CAFFY names in the module. Names not in this set are CAFFY. + -> CgInfos -> ModDetails -- ^ ModDetails to update -> ModDetails -updateModDetailsCafInfos dflags _ mod_details +updateModDetailsIdInfos dflags _ mod_details | gopt Opt_OmitInterfacePragmas dflags = mod_details -updateModDetailsCafInfos _ non_cafs mod_details = - {- pprTrace "updateModDetailsCafInfos" (text "non_cafs:" <+> ppr non_cafs) $ -} +updateModDetailsIdInfos _ cg_infos mod_details = let ModDetails{ md_types = type_env -- for unfoldings , md_insts = insts @@ -40,11 +44,11 @@ updateModDetailsCafInfos _ non_cafs mod_details = } = mod_details -- type TypeEnv = NameEnv TyThing - ~type_env' = mapNameEnv (updateTyThingCafInfos type_env' non_cafs) type_env + ~type_env' = mapNameEnv (updateTyThingIdInfos type_env' cg_infos) type_env -- Not strict! - !insts' = strictMap (updateInstCafInfos type_env' non_cafs) insts - !rules' = strictMap (updateRuleCafInfos type_env') rules + !insts' = strictMap (updateInstIdInfos type_env' cg_infos) insts + !rules' = strictMap (updateRuleIdInfos type_env') rules in mod_details{ md_types = type_env' , md_insts = insts' @@ -55,28 +59,28 @@ updateModDetailsCafInfos _ non_cafs mod_details = -- Rules -------------------------------------------------------------------------------- -updateRuleCafInfos :: TypeEnv -> CoreRule -> CoreRule -updateRuleCafInfos _ rule at BuiltinRule{} = rule -updateRuleCafInfos type_env Rule{ .. } = Rule { ru_rhs = updateGlobalIds type_env ru_rhs, .. } +updateRuleIdInfos :: TypeEnv -> CoreRule -> CoreRule +updateRuleIdInfos _ rule at BuiltinRule{} = rule +updateRuleIdInfos type_env Rule{ .. } = Rule { ru_rhs = updateGlobalIds type_env ru_rhs, .. } -------------------------------------------------------------------------------- -- Instances -------------------------------------------------------------------------------- -updateInstCafInfos :: TypeEnv -> NameSet -> ClsInst -> ClsInst -updateInstCafInfos type_env non_cafs = - updateClsInstDFun (updateIdUnfolding type_env . updateIdCafInfo non_cafs) +updateInstIdInfos :: TypeEnv -> CgInfos -> ClsInst -> ClsInst +updateInstIdInfos type_env cg_infos = + updateClsInstDFun (updateIdUnfolding type_env . updateIdInfo cg_infos) -------------------------------------------------------------------------------- -- TyThings -------------------------------------------------------------------------------- -updateTyThingCafInfos :: TypeEnv -> NameSet -> TyThing -> TyThing +updateTyThingIdInfos :: TypeEnv -> CgInfos -> TyThing -> TyThing -updateTyThingCafInfos type_env non_cafs (AnId id) = - AnId (updateIdUnfolding type_env (updateIdCafInfo non_cafs id)) +updateTyThingIdInfos type_env cg_infos (AnId id) = + AnId (updateIdUnfolding type_env (updateIdInfo cg_infos id)) -updateTyThingCafInfos _ _ other = other -- AConLike, ATyCon, ACoAxiom +updateTyThingIdInfos _ _ other = other -- AConLike, ATyCon, ACoAxiom -------------------------------------------------------------------------------- -- Unfoldings @@ -95,13 +99,18 @@ updateIdUnfolding type_env id = -- Expressions -------------------------------------------------------------------------------- -updateIdCafInfo :: NameSet -> Id -> Id -updateIdCafInfo non_cafs id - | idName id `elemNameSet` non_cafs - = -- pprTrace "updateIdCafInfo" (text "Marking" <+> ppr id <+> parens (ppr (idName id)) <+> text "as non-CAFFY") $ - id `setIdCafInfo` NoCafRefs - | otherwise - = id +updateIdInfo :: CgInfos -> Id -> Id +updateIdInfo CgInfos{ cgNonCafs = non_cafs, cgLFInfos = lf_infos } id = + let + not_caffy = elemNameSet (idName id) non_cafs + mb_lf_info = lookupNameEnv lf_infos (idName id) + + id1 = if not_caffy then setIdCafInfo id NoCafRefs else id + id2 = case mb_lf_info of + Nothing -> id1 + Just lf_info -> setIdLFInfo id1 lf_info + in + id2 -------------------------------------------------------------------------------- @@ -116,7 +125,7 @@ updateGlobalIds env e = go env e case lookupNameEnv env (varName var) of Nothing -> var Just (AnId id) -> id - Just other -> pprPanic "GHC.Iface.UpdateCafInfos.updateGlobalIds" $ + Just other -> pprPanic "UpdateCafInfos.updateGlobalIds" $ text "Found a non-Id for Id Name" <+> ppr (varName var) $$ nest 4 (text "Id:" <+> ppr var $$ text "TyThing:" <+> ppr other) ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -19,7 +19,8 @@ module GHC.IfaceToCore ( tcIfaceDecl, tcIfaceInst, tcIfaceFamInst, tcIfaceRules, tcIfaceAnnotations, tcIfaceCompleteSigs, tcIfaceExpr, -- Desired by HERMIT (#7683) - tcIfaceGlobal + tcIfaceGlobal, + tcIfaceOneShot ) where #include "HsVersions.h" @@ -30,6 +31,8 @@ import GHC.Builtin.Types.Literals(typeNatCoAxiomRules) import GHC.Iface.Syntax import GHC.Iface.Load import GHC.Iface.Env +import GHC.StgToCmm.Types +import GHC.StgToCmm.Closure (might_be_a_function) import GHC.Tc.TyCl.Build import GHC.Tc.Utils.Monad import GHC.Tc.Utils.TcType @@ -1464,8 +1467,7 @@ tcIdInfo ignore_prags toplvl name ty info = do let init_info | if_boot lcl_env = vanillaIdInfo `setUnfoldingInfo` BootUnfolding | otherwise = vanillaIdInfo - let needed = needed_prags info - foldlM tcPrag init_info needed + foldlM tcPrag init_info (needed_prags info) where needed_prags :: [IfaceInfoItem] -> [IfaceInfoItem] needed_prags items @@ -1485,6 +1487,9 @@ tcIdInfo ignore_prags toplvl name ty info = do tcPrag info (HsCpr cpr) = return (info `setCprInfo` cpr) tcPrag info (HsInline prag) = return (info `setInlinePragInfo` prag) tcPrag info HsLevity = return (info `setNeverLevPoly` ty) + tcPrag info (HsLFInfo lf_info) = do + lf_info <- tcLFInfo ty lf_info + return (info `setLFInfo` lf_info) -- The next two are lazy, so they don't transitively suck stuff in tcPrag info (HsUnfold lb if_unf) @@ -1497,6 +1502,29 @@ tcJoinInfo :: IfaceJoinInfo -> Maybe JoinArity tcJoinInfo (IfaceJoinPoint ar) = Just ar tcJoinInfo IfaceNotJoinPoint = Nothing +tcLFInfo :: Type -> IfaceLFInfo -> IfL LambdaFormInfo +tcLFInfo ty lfi = case lfi of + IfLFReEntrant rep_arity -> + -- LFReEntrant closures in interface files are guaranteed to + -- + -- - Be top-level, as only top-level closures are exported. + -- - Have no free variables, as only non-top-level closures have free + -- variables + -- - Don't have ArgDescrs, as ArgDescr is used when generating code for + -- the closure + -- + -- These invariants are checked when generating LFInfos in toIfaceLFInfo. + return (LFReEntrant TopLevel rep_arity True ArgUnknown) + + IfLFUnlifted -> + return LFUnlifted + + IfLFCon con_name -> + LFCon <$!> tcIfaceDataCon con_name + + IfLFUnknown -> + return (LFUnknown (might_be_a_function ty)) + tcUnfolding :: TopLevelFlag -> Name -> Type -> IdInfo -> IfaceUnfolding -> IfL Unfolding tcUnfolding toplvl name _ info (IfCoreUnfold stable if_expr) = do { dflags <- getDynFlags @@ -1508,7 +1536,7 @@ tcUnfolding toplvl name _ info (IfCoreUnfold stable if_expr) Just expr -> mkFinalUnfolding dflags unf_src strict_sig expr } where - -- Strictness should occur before unfolding! + -- Strictness should occur before unfolding! strict_sig = strictnessInfo info tcUnfolding toplvl name _ _ (IfCompulsory if_expr) @@ -1583,6 +1611,10 @@ tcPragExpr is_compulsory toplvl name expr -- It's OK to use nonDetEltsUFM here because we immediately forget -- the ordering by creating a set +tcIfaceOneShot :: IfaceOneShot -> OneShotInfo +tcIfaceOneShot IfaceNoOneShot = NoOneShotInfo +tcIfaceOneShot IfaceOneShot = OneShotLam + {- ************************************************************************ * * ===================================== compiler/GHC/Runtime/Heap/Layout.hs ===================================== @@ -51,6 +51,7 @@ import GHC.Driver.Session import GHC.Utils.Outputable import GHC.Platform import GHC.Data.FastString +import GHC.StgToCmm.Types import Data.Word import Data.Bits @@ -64,9 +65,6 @@ import Data.ByteString (ByteString) ************************************************************************ -} --- | Word offset, or word count -type WordOff = Int - -- | Byte offset, or byte count type ByteOff = Int @@ -196,29 +194,6 @@ type ConstrDescription = ByteString -- result of dataConIdentity type FunArity = Int type SelectorOffset = Int -------------------------- --- We represent liveness bitmaps as a Bitmap (whose internal --- representation really is a bitmap). These are pinned onto case return --- vectors to indicate the state of the stack for the garbage collector. --- --- In the compiled program, liveness bitmaps that fit inside a single --- word (StgWord) are stored as a single word, while larger bitmaps are --- stored as a pointer to an array of words. - -type Liveness = [Bool] -- One Bool per word; True <=> non-ptr or dead - -- False <=> ptr - -------------------------- --- An ArgDescr describes the argument pattern of a function - -data ArgDescr - = ArgSpec -- Fits one of the standard patterns - !Int -- RTS type identifier ARG_P, ARG_N, ... - - | ArgGen -- General case - Liveness -- Details about the arguments - - ----------------------------------------------------------------------------- -- Construction @@ -545,10 +520,6 @@ instance Outputable SMRep where ppr (RTSRep ty rep) = text "tag:" <> ppr ty <+> ppr rep -instance Outputable ArgDescr where - ppr (ArgSpec n) = text "ArgSpec" <+> ppr n - ppr (ArgGen ls) = text "ArgGen" <+> ppr ls - pprTypeInfo :: ClosureTypeInfo -> SDoc pprTypeInfo (Constr tag descr) = text "Con" <+> ===================================== compiler/GHC/StgToCmm.hs ===================================== @@ -1,5 +1,6 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-} +{-# LANGUAGE BangPatterns #-} ----------------------------------------------------------------------------- -- @@ -25,6 +26,7 @@ import GHC.StgToCmm.Utils import GHC.StgToCmm.Closure import GHC.StgToCmm.Hpc import GHC.StgToCmm.Ticky +import GHC.StgToCmm.Types (ModuleLFInfos) import GHC.Cmm import GHC.Cmm.Utils @@ -47,6 +49,8 @@ import GHC.Data.Stream import GHC.Types.Basic import GHC.Types.Var.Set ( isEmptyDVarSet ) import GHC.SysTools.FileCleanup +import GHC.Types.Unique.FM +import GHC.Types.Name.Env import GHC.Data.OrdList import GHC.Cmm.Graph @@ -63,7 +67,8 @@ codeGen :: DynFlags -> CollectedCCs -- (Local/global) cost-centres needing declaring/registering. -> [CgStgTopBinding] -- Bindings to convert -> HpcInfo - -> Stream IO CmmGroup () -- Output as a stream, so codegen can + -> Stream IO CmmGroup ModuleLFInfos + -- Output as a stream, so codegen can -- be interleaved with output codeGen dflags this_mod data_tycons @@ -105,6 +110,18 @@ codeGen dflags this_mod data_tycons mapM_ (cg . cgDataCon) (tyConDataCons tycon) ; mapM_ do_tycon data_tycons + + ; cg_id_infos <- cgs_binds <$> liftIO (readIORef cgref) + + ; let extractInfo info = (name, lf) + where + !id = cg_id info + !name = idName id + !lf = cg_lf info + + ; let !generatedInfo = mkNameEnv (Prelude.map extractInfo (eltsUFM cg_id_infos)) + + ; return generatedInfo } --------------------------------------------------------------- ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -55,6 +55,8 @@ module GHC.StgToCmm.Closure ( blackHoleOnEntry, -- Needs LambdaFormInfo and SMRep isStaticClosure, -- Needs SMPre + might_be_a_function, + -- * InfoTables mkDataConInfoTable, cafBlackHoleInfoTable, @@ -70,6 +72,7 @@ import GHC.Stg.Syntax import GHC.Runtime.Heap.Layout import GHC.Cmm import GHC.Cmm.Ppr.Expr() -- For Outputable instances +import GHC.StgToCmm.Types import GHC.Types.CostCentre import GHC.Cmm.BlockId @@ -188,76 +191,6 @@ addArgReps = map (\arg -> let arg' = fromNonVoid arg argPrimRep :: StgArg -> PrimRep argPrimRep arg = typePrimRep1 (stgArgType arg) - ------------------------------------------------------------------------------ --- LambdaFormInfo ------------------------------------------------------------------------------ - --- Information about an identifier, from the code generator's point of --- view. Every identifier is bound to a LambdaFormInfo in the --- environment, which gives the code generator enough info to be able to --- tail call or return that identifier. - -data LambdaFormInfo - = LFReEntrant -- Reentrant closure (a function) - TopLevelFlag -- True if top level - !RepArity -- Arity. Invariant: always > 0 - !Bool -- True <=> no fvs - ArgDescr -- Argument descriptor (should really be in ClosureInfo) - - | LFThunk -- Thunk (zero arity) - TopLevelFlag - !Bool -- True <=> no free vars - !Bool -- True <=> updatable (i.e., *not* single-entry) - StandardFormInfo - !Bool -- True <=> *might* be a function type - - | LFCon -- A saturated constructor application - DataCon -- The constructor - - | LFUnknown -- Used for function arguments and imported things. - -- We know nothing about this closure. - -- Treat like updatable "LFThunk"... - -- Imported things which we *do* know something about use - -- one of the other LF constructors (eg LFReEntrant for - -- known functions) - !Bool -- True <=> *might* be a function type - -- The False case is good when we want to enter it, - -- because then we know the entry code will do - -- For a function, the entry code is the fast entry point - - | LFUnlifted -- A value of unboxed type; - -- always a value, needs evaluation - - | LFLetNoEscape -- See LetNoEscape module for precise description - - -------------------------- --- StandardFormInfo tells whether this thunk has one of --- a small number of standard forms - -data StandardFormInfo - = NonStandardThunk - -- The usual case: not of the standard forms - - | SelectorThunk - -- A SelectorThunk is of form - -- case x of - -- con a1,..,an -> ak - -- and the constructor is from a single-constr type. - WordOff -- 0-origin offset of ak within the "goods" of - -- constructor (Recall that the a1,...,an may be laid - -- out in the heap in a non-obvious order.) - - | ApThunk - -- An ApThunk is of form - -- x1 ... xn - -- The code for the thunk just pushes x2..xn on the stack and enters x1. - -- There are a few of these (for 1 <= n <= MAX_SPEC_AP_SIZE) pre-compiled - -- in the RTS to save space. - RepArity -- Arity, n - - ------------------------------------------------------ -- Building LambdaFormInfo ------------------------------------------------------ @@ -325,18 +258,22 @@ mkApLFInfo id upd_flag arity ------------- mkLFImported :: Id -> LambdaFormInfo -mkLFImported id - | Just con <- isDataConWorkId_maybe id - , isNullaryRepDataCon con - = LFCon con -- An imported nullary constructor - -- We assume that the constructor is evaluated so that - -- the id really does point directly to the constructor - - | arity > 0 - = LFReEntrant TopLevel arity True (panic "arg_descr") - - | otherwise - = mkLFArgument id -- Not sure of exact arity +mkLFImported id = + case idLFInfo_maybe id of + Just lf_info -> + lf_info + Nothing + | Just con <- isDataConWorkId_maybe id + , isNullaryRepDataCon con + -> LFCon con -- An imported nullary constructor + -- We assume that the constructor is evaluated so that + -- the id really does point directly to the constructor + + | arity > 0 + -> LFReEntrant TopLevel arity True ArgUnknown + + | otherwise + -> mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id ===================================== compiler/GHC/StgToCmm/Types.hs ===================================== @@ -0,0 +1,224 @@ +{-# LANGUAGE CPP #-} + +module GHC.StgToCmm.Types + ( CgInfos (..) + , LambdaFormInfo (..) + , ModuleLFInfos + , Liveness + , ArgDescr (..) + , StandardFormInfo (..) + , WordOff + ) where + +#include "HsVersions.h" + +import GHC.Prelude + +import GHC.Types.Basic +import GHC.Core.DataCon +import GHC.Types.Name.Env +import GHC.Types.Name.Set +import GHC.Utils.Outputable + +{- +Note [Conveying CAF-info and LFInfo between modules] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Some information about an Id is generated in the code generator, and is not +available earlier. Namely: + +* CAF info. Code motion in Cmm or earlier phases may move references around so + we compute information about which bits of code refer to which CAF late in the + Cmm pipeline. + +* LambdaFormInfo. This records the details of a closure representation, + including + - the final arity (for functions) + - whether it is a data constructor, and if so its tag + +Collectively we call this CgInfo (see GHC.StgToCmm.Types). + +It's very useful for importing modules to have this information. We can always +make a conservative assumption, but that is bad: e.g. + +* For CAF info, if we know nothing we have to assume it is a CAF which bloats + the SRTs of the importing module. + +- For data constructors, we really like having well-tagged pointers. See #14677, + #16559, #15155, and wiki: commentary/rts/haskell-execution/pointer-tagging + +So we arrange to always serialise this information into the interface file. The +moving parts are: + +* We record the CgInfo in the IdInfo of the Id. + +* GHC.Driver.Pipeline: the call to updateModDetailsIdInfos augments the + ModDetails constructed at the end of the Core pipeline, with with CgInfo + gleaned from the back end. The hard work is done in GHC.Iface.UpdateIdInfos. + +* For ModIface we generate the final ModIface with CgInfo in + GHC.Iface.Make.mkFullIface. + +* We don't absolutely guarantee to serialise the CgInfo: we won't if you have + -fomit-interface-pragmas or -fno-code; and we won't read it in if you have + -fignore-interface-pragmas. (We could revisit this decision.) +-} + +-- | Codegen-generated Id infos, to be passed to downstream via interfaces. +-- +-- This stuff is for optimization purposes only, they're not compulsory. +-- +-- * When CafInfo of an imported Id is not known it's safe to treat it as CAFFY. +-- * When LambdaFormInfo of an imported Id is not known it's safe to treat it as +-- `LFUnknown True` (which just says "it could be anything" and we do slow +-- entry). +-- +-- See also Note [Conveying CAF-info and LFInfo between modules] above. +-- +data CgInfos = CgInfos + { cgNonCafs :: !NameSet + -- ^ Exported Non-CAFFY closures in the current module. Everything else is + -- either not exported of CAFFY. + , cgLFInfos :: !ModuleLFInfos + -- ^ LambdaFormInfos of exported closures in the current module. + } + +-------------------------------------------------------------------------------- +-- LambdaFormInfo +-------------------------------------------------------------------------------- + +-- | Maps names in the current module to their LambdaFormInfos +type ModuleLFInfos = NameEnv LambdaFormInfo + +-- | Information about an identifier, from the code generator's point of view. +-- Every identifier is bound to a LambdaFormInfo in the environment, which gives +-- the code generator enough info to be able to tail call or return that +-- identifier. +data LambdaFormInfo + = LFReEntrant -- Reentrant closure (a function) + !TopLevelFlag -- True if top level + !RepArity -- Arity. Invariant: always > 0 + !Bool -- True <=> no fvs + !ArgDescr -- Argument descriptor (should really be in ClosureInfo) + + | LFThunk -- Thunk (zero arity) + !TopLevelFlag + !Bool -- True <=> no free vars + !Bool -- True <=> updatable (i.e., *not* single-entry) + !StandardFormInfo + !Bool -- True <=> *might* be a function type + + | LFCon -- A saturated constructor application + !DataCon -- The constructor + + | LFUnknown -- Used for function arguments and imported things. + -- We know nothing about this closure. + -- Treat like updatable "LFThunk"... + -- Imported things which we *do* know something about use + -- one of the other LF constructors (eg LFReEntrant for + -- known functions) + !Bool -- True <=> *might* be a function type + -- The False case is good when we want to enter it, + -- because then we know the entry code will do + -- For a function, the entry code is the fast entry point + + | LFUnlifted -- A value of unboxed type; + -- always a value, needs evaluation + + | LFLetNoEscape -- See LetNoEscape module for precise description + +instance Outputable LambdaFormInfo where + ppr (LFReEntrant top rep fvs argdesc) = + text "LFReEntrant" <> brackets + (ppr top <+> ppr rep <+> pprFvs fvs <+> ppr argdesc) + ppr (LFThunk top hasfv updateable sfi m_function) = + text "LFThunk" <> brackets + (ppr top <+> pprFvs hasfv <+> pprUpdateable updateable <+> + ppr sfi <+> pprFuncFlag m_function) + ppr (LFCon con) = + text "LFCon" <> brackets (ppr con) + ppr (LFUnknown m_func) = + text "LFUnknown" <> brackets (pprFuncFlag m_func) + ppr LFUnlifted = + text "LFUnlifted" + ppr LFLetNoEscape = + text "LFLetNoEscape" + +pprFvs :: Bool -> SDoc +pprFvs True = text "no-fvs" +pprFvs False = text "fvs" + +pprFuncFlag :: Bool -> SDoc +pprFuncFlag True = text "mFunc" +pprFuncFlag False = text "value" + +pprUpdateable :: Bool -> SDoc +pprUpdateable True = text "updateable" +pprUpdateable False = text "oneshot" + +-------------------------------------------------------------------------------- + +-- | We represent liveness bitmaps as a Bitmap (whose internal representation +-- really is a bitmap). These are pinned onto case return vectors to indicate +-- the state of the stack for the garbage collector. +-- +-- In the compiled program, liveness bitmaps that fit inside a single word +-- (StgWord) are stored as a single word, while larger bitmaps are stored as a +-- pointer to an array of words. + +type Liveness = [Bool] -- One Bool per word; True <=> non-ptr or dead + -- False <=> ptr + +-------------------------------------------------------------------------------- +-- | An ArgDescr describes the argument pattern of a function + +data ArgDescr + = ArgSpec -- Fits one of the standard patterns + !Int -- RTS type identifier ARG_P, ARG_N, ... + + | ArgGen -- General case + Liveness -- Details about the arguments + + | ArgUnknown -- For imported binds. + -- Invariant: Never Unknown for binds of the module + -- we are compiling. + deriving (Eq) + +instance Outputable ArgDescr where + ppr (ArgSpec n) = text "ArgSpec" <+> ppr n + ppr (ArgGen ls) = text "ArgGen" <+> ppr ls + ppr ArgUnknown = text "ArgUnknown" + +-------------------------------------------------------------------------------- +-- | StandardFormInfo tells whether this thunk has one of a small number of +-- standard forms + +data StandardFormInfo + = NonStandardThunk + -- The usual case: not of the standard forms + + | SelectorThunk + -- A SelectorThunk is of form + -- case x of + -- con a1,..,an -> ak + -- and the constructor is from a single-constr type. + !WordOff -- 0-origin offset of ak within the "goods" of + -- constructor (Recall that the a1,...,an may be laid + -- out in the heap in a non-obvious order.) + + | ApThunk + -- An ApThunk is of form + -- x1 ... xn + -- The code for the thunk just pushes x2..xn on the stack and enters x1. + -- There are a few of these (for 1 <= n <= MAX_SPEC_AP_SIZE) pre-compiled + -- in the RTS to save space. + !RepArity -- Arity, n + deriving (Eq) + +-- | Word offset, or word count +type WordOff = Int + +instance Outputable StandardFormInfo where + ppr NonStandardThunk = text "RegThunk" + ppr (SelectorThunk w) = text "SelThunk:" <> ppr w + ppr (ApThunk n) = text "ApThunk:" <> ppr n ===================================== compiler/GHC/Types/Id.hs ===================================== @@ -92,7 +92,7 @@ module GHC.Types.Id ( idCallArity, idFunRepArity, idUnfolding, realIdUnfolding, idSpecialisation, idCoreRules, idHasRules, - idCafInfo, + idCafInfo, idLFInfo_maybe, idOneShotInfo, idStateHackOneShotInfo, idOccInfo, isNeverLevPolyId, @@ -105,6 +105,7 @@ module GHC.Types.Id ( setIdSpecialisation, setIdCafInfo, setIdOccInfo, zapIdOccInfo, + setIdLFInfo, setIdDemandInfo, setIdStrictness, @@ -731,6 +732,15 @@ idCafInfo id = cafInfo (idInfo id) setIdCafInfo :: Id -> CafInfo -> Id setIdCafInfo id caf_info = modifyIdInfo (`setCafInfo` caf_info) id + --------------------------------- + -- Lambda form info + +idLFInfo_maybe :: Id -> Maybe LambdaFormInfo +idLFInfo_maybe = lfInfo . idInfo + +setIdLFInfo :: Id -> LambdaFormInfo -> Id +setIdLFInfo id lf = modifyIdInfo (`setLFInfo` lf) id + --------------------------------- -- Occurrence INFO idOccInfo :: Id -> OccInfo ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -74,6 +74,10 @@ module GHC.Types.Id.Info ( ppCafInfo, mayHaveCafRefs, cafInfo, setCafInfo, + -- ** The LambdaFormInfo type + LambdaFormInfo(..), + lfInfo, setLFInfo, + -- ** Tick-box Info TickBoxOp(..), TickBoxId, @@ -105,6 +109,8 @@ import GHC.Types.Demand import GHC.Types.Cpr import GHC.Utils.Misc +import GHC.StgToCmm.Types (LambdaFormInfo (..)) + -- infixl so you can say (id `set` a `set` b) infixl 1 `setRuleInfo`, `setArityInfo`, @@ -251,7 +257,7 @@ data IdInfo -- See Note [Specialisations and RULES in IdInfo] unfoldingInfo :: Unfolding, -- ^ The 'Id's unfolding - cafInfo :: CafInfo, + cafInfo :: !CafInfo, -- ^ 'Id' CAF info oneShotInfo :: OneShotInfo, -- ^ Info about a lambda-bound variable, if the 'Id' is one @@ -271,8 +277,9 @@ data IdInfo -- ^ How this is called. This is the number of arguments to which a -- binding can be eta-expanded without losing any sharing. -- n <=> all calls have at least n arguments - levityInfo :: LevityInfo + levityInfo :: LevityInfo, -- ^ when applied, will this Id ever have a levity-polymorphic type? + lfInfo :: !(Maybe LambdaFormInfo) } -- Setters @@ -295,13 +302,18 @@ setUnfoldingInfo info uf setArityInfo :: IdInfo -> ArityInfo -> IdInfo setArityInfo info ar = info { arityInfo = ar } + setCallArityInfo :: IdInfo -> ArityInfo -> IdInfo setCallArityInfo info ar = info { callArityInfo = ar } + setCafInfo :: IdInfo -> CafInfo -> IdInfo -setCafInfo info caf = info { cafInfo = caf } +setCafInfo info caf = info { cafInfo = caf } + +setLFInfo :: IdInfo -> LambdaFormInfo -> IdInfo +setLFInfo info lf = info { lfInfo = Just lf } setOneShotInfo :: IdInfo -> OneShotInfo -> IdInfo -setOneShotInfo info lb = {-lb `seq`-} info { oneShotInfo = lb } +setOneShotInfo info lb = {-lb `seq`-} info { oneShotInfo = lb } setDemandInfo :: IdInfo -> Demand -> IdInfo setDemandInfo info dd = dd `seq` info { demandInfo = dd } @@ -327,7 +339,8 @@ vanillaIdInfo strictnessInfo = nopSig, cprInfo = topCprSig, callArityInfo = unknownArity, - levityInfo = NoLevityInfo + levityInfo = NoLevityInfo, + lfInfo = Nothing } -- | More informative 'IdInfo' we can use when we know the 'Id' has no CAF references ===================================== compiler/ghc.cabal.in ===================================== @@ -228,7 +228,7 @@ Library GHC.Types.SrcLoc GHC.Types.Unique.Supply GHC.Types.Unique - GHC.Iface.UpdateCafInfos + GHC.Iface.UpdateIdInfos GHC.Types.Var GHC.Types.Var.Env GHC.Types.Var.Set @@ -295,6 +295,7 @@ Library GHC.StgToCmm.Ticky GHC.StgToCmm.Utils GHC.StgToCmm.ExtCode + GHC.StgToCmm.Types GHC.Runtime.Heap.Layout GHC.Core.Arity GHC.Core.FVs ===================================== testsuite/tests/codeGen/should_compile/Makefile ===================================== @@ -64,10 +64,10 @@ T17648: # NoCafRefs) to the interface files. '$(TEST_HC)' $(TEST_HC_OPTS) -dno-typeable-binds -O T17648.hs -v0 '$(TEST_HC)' --show-iface T17648.hi | tr -d '\n\r' | \ - grep -F 'f :: T GHC.Types.Int -> () [HasNoCafRefs, Arity' >/dev/null + grep -F 'f :: T GHC.Types.Int -> () [HasNoCafRefs, LambdaFormInfo' >/dev/null # Second compilation with -fcatch-bottoms, f should be CAFFY '$(TEST_HC)' $(TEST_HC_OPTS) -dno-typeable-binds -O \ -fcatch-bottoms T17648.hs -v0 -fforce-recomp '$(TEST_HC)' --show-iface T17648.hi | tr -d '\n\r' | \ - grep -F 'f :: T GHC.Types.Int -> () [Arity: 1, Strictness' >/dev/null + grep -F 'f :: T GHC.Types.Int -> () [LambdaFormInfo' >/dev/null ===================================== testsuite/tests/codeGen/should_compile/cg009/A.hs ===================================== @@ -0,0 +1,5 @@ +module A where + +newtype A = A Int + +val = A 42 ===================================== testsuite/tests/codeGen/should_compile/cg009/Main.hs ===================================== @@ -0,0 +1,7 @@ +module Main where + +import A + +main = return () + +a = val ===================================== testsuite/tests/codeGen/should_compile/cg009/Makefile ===================================== @@ -0,0 +1,9 @@ +TOP=../../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +# Make sure the LFInfo for an exported, but not directly used newtype +# constructors does not trip up the compiler. +cg009: + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O A.hs -fforce-recomp + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O0 Main.hs -fforce-recomp ===================================== testsuite/tests/codeGen/should_compile/cg009/all.T ===================================== @@ -0,0 +1 @@ +test('cg009', [extra_files(['A.hs','Main.hs'])], makefile_test, ['cg009']) ===================================== testsuite/tests/codeGen/should_compile/cg010/A.hs ===================================== @@ -0,0 +1,4 @@ +module A where + +{-# NOINLINE val #-} +val = Just 42 ===================================== testsuite/tests/codeGen/should_compile/cg010/Main.hs ===================================== @@ -0,0 +1,7 @@ +module Main where + +import A + +main = return () + +a = val ===================================== testsuite/tests/codeGen/should_compile/cg010/Makefile ===================================== @@ -0,0 +1,9 @@ +TOP=../../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +# Make sure LFInfo causes the imported reference to val to get tagged. +cg010: + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O A.hs -fforce-recomp + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O Main.hs -fforce-recomp -ddump-cmm -ddump-to-file + grep "A.val_closure+2" Main.dump-cmm ===================================== testsuite/tests/codeGen/should_compile/cg010/all.T ===================================== @@ -0,0 +1 @@ +test('cg010', [extra_files(['A.hs','Main.hs'])], makefile_test, ['cg010']) ===================================== testsuite/tests/codeGen/should_compile/cg010/cg010.stdout ===================================== @@ -0,0 +1 @@ + const A.val_closure+2; ===================================== testsuite/tests/simplCore/should_compile/Makefile ===================================== @@ -107,7 +107,7 @@ T4201: '$(TEST_HC)' $(TEST_HC_OPTS) -c -O T4201.hs '$(TEST_HC)' $(TEST_HC_OPTS) --show-iface T4201.hi > T4201.list # poor man idea about how to replace GNU grep -B2 "Sym" invocation with pure POSIX tools - for i in `grep -n "Sym" T4201.list |cut -d ':' -f -1`; do head -$$i T4201.list | tail -3 ; done + for i in `grep -n "Sym" T4201.list | cut -d ':' -f -1`; do head -$$i T4201.list | tail -4; done $(RM) -f T4201.list # This one looped as a result of bogus specialisation ===================================== testsuite/tests/simplCore/should_compile/T4201.stdout ===================================== @@ -1,3 +1,4 @@ - [HasNoCafRefs, Arity: 1, Strictness: , + [HasNoCafRefs, LambdaFormInfo: LFReEntrant 1, Arity: 1, + Strictness: , Unfolding: InlineRule (0, True, True) bof `cast` (Sym (N:Foo[0]) ->_R _R)] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/38f63fb80b54c94da4018bcb4ea4029b494d6a03 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/38f63fb80b54c94da4018bcb4ea4029b494d6a03 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 1 11:57:51 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Fri, 01 May 2020 07:57:51 -0400 Subject: [Git][ghc/ghc][wip/osa1/lfinfo] Cross-module LambdaFormInfo passing Message-ID: <5eac0ebfb0249_61673f819b417d1c8301469@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/lfinfo at Glasgow Haskell Compiler / GHC Commits: ab111166 by Ömer Sinan Ağacan at 2020-05-01T14:57:40+03:00 Cross-module LambdaFormInfo passing - Store LambdaFormInfos of exported Ids in interface files - Use them in importing modules This is for optimization purposes: if we know LambdaFormInfo of imported Ids we can generate more efficient calling code, see `getCallMethod`. Exporting (putting them in interface files or in ModDetails) and importing (reading them from interface files) are both optional. We don't assume known LambdaFormInfos anywhere and do not change how we call Ids with unknown LambdaFormInfos. Runtime, allocation, and residency numbers when building Cabal-the-library (commit 0d4ee7ba3). (Log and .hp files are in the MR: !2842) Runtime: | | GHC HEAD | This patch | Diff | |-----|----------|------------|----------------| | -O0 | 0:35.70 | 0:34.75 | -0.95s, -2.66% | | -O1 | 2:25.21 | 2:25.16 | -0.05s, -0.03% | | -O2 | 2:52.89 | 2:51.25 | -1.63s, -0.9% | Allocations: | | GHC HEAD | This patch | Diff | |-----|-----------------|-----------------|----------------------| | -O0 | 54,872,673,008 | 54,917,849,488 | +45,176,480, +0.08% | | -O1 | 227,080,315,016 | 227,584,483,224 | +504,168,208, +0.22% | | -O2 | 266,085,969,832 | 266,710,115,472 | +624,145,640, +0.23% | Max. residency: NOTE: Residency is measured with extra runtime args: `-i0 -h` which effectively turn all GCs into major GCs, and do GC more often. | | GHC HEAD | This patch | Diff | |-----|----------------------------|------------------------------|----------------------| | -O0 | 416,350,080 (894 samples) | 417,733,152 (892 samples) | +1,383,072, +0.33% | | -O1 | 928,484,840 (2101 samples) | 945,624,664 (2098 samples) | +17,139,824, +1.84% | | -O2 | 991,311,896 (2548 samples) | 1,010,647,088 (2536 samples) | +19,335,192, +1.95% | NoFib results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS 0.0% 0.0% +0.0% +0.0% +0.0% CSD 0.0% 0.0% 0.0% +0.0% +0.0% FS 0.0% 0.0% +0.0% +0.0% +0.0% S 0.0% 0.0% +0.0% +0.0% +0.0% VS 0.0% 0.0% +0.0% +0.0% +0.0% VSD 0.0% 0.0% +0.0% +0.0% +0.1% VSM 0.0% 0.0% +0.0% +0.0% +0.0% anna 0.0% 0.0% -0.3% -0.8% -0.0% ansi 0.0% 0.0% -0.0% -0.0% 0.0% atom 0.0% 0.0% -0.0% -0.0% 0.0% awards 0.0% 0.0% -0.1% -0.3% 0.0% banner 0.0% 0.0% -0.0% -0.0% -0.0% bernouilli 0.0% 0.0% -0.0% -0.0% -0.0% binary-trees 0.0% 0.0% -0.0% -0.0% +0.0% boyer 0.0% 0.0% -0.0% -0.0% 0.0% boyer2 0.0% 0.0% -0.0% -0.0% 0.0% bspt 0.0% 0.0% -0.0% -0.2% 0.0% cacheprof 0.0% 0.0% -0.1% -0.4% +0.0% calendar 0.0% 0.0% -0.0% -0.0% 0.0% cichelli 0.0% 0.0% -0.9% -2.4% 0.0% circsim 0.0% 0.0% -0.0% -0.0% 0.0% clausify 0.0% 0.0% -0.1% -0.3% 0.0% comp_lab_zift 0.0% 0.0% -0.0% -0.0% +0.0% compress 0.0% 0.0% -0.0% -0.0% -0.0% compress2 0.0% 0.0% -0.0% -0.0% 0.0% constraints 0.0% 0.0% -0.1% -0.2% -0.0% cryptarithm1 0.0% 0.0% -0.0% -0.0% 0.0% cryptarithm2 0.0% 0.0% -1.4% -4.1% -0.0% cse 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e1 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e2 0.0% 0.0% -0.0% -0.0% -0.0% dom-lt 0.0% 0.0% -0.1% -0.2% 0.0% eliza 0.0% 0.0% -0.5% -1.5% 0.0% event 0.0% 0.0% -0.0% -0.0% -0.0% exact-reals 0.0% 0.0% -0.1% -0.3% +0.0% exp3_8 0.0% 0.0% -0.0% -0.0% -0.0% expert 0.0% 0.0% -0.3% -1.0% -0.0% fannkuch-redux 0.0% 0.0% +0.0% +0.0% +0.0% fasta 0.0% 0.0% -0.0% -0.0% +0.0% fem 0.0% 0.0% -0.0% -0.0% 0.0% fft 0.0% 0.0% -0.0% -0.0% 0.0% fft2 0.0% 0.0% -0.0% -0.0% 0.0% fibheaps 0.0% 0.0% -0.0% -0.0% +0.0% fish 0.0% 0.0% 0.0% -0.0% +0.0% fluid 0.0% 0.0% -0.4% -1.2% +0.0% fulsom 0.0% 0.0% -0.0% -0.0% 0.0% gamteb 0.0% 0.0% -0.1% -0.3% 0.0% gcd 0.0% 0.0% -0.0% -0.0% 0.0% gen_regexps 0.0% 0.0% -0.0% -0.0% -0.0% genfft 0.0% 0.0% -0.0% -0.0% 0.0% gg 0.0% 0.0% -0.0% -0.0% +0.0% grep 0.0% 0.0% -0.0% -0.0% -0.0% hidden 0.0% 0.0% -0.1% -0.4% -0.0% hpg 0.0% 0.0% -0.2% -0.5% +0.0% ida 0.0% 0.0% -0.0% -0.0% +0.0% infer 0.0% 0.0% -0.3% -0.8% -0.0% integer 0.0% 0.0% -0.0% -0.0% +0.0% integrate 0.0% 0.0% -0.0% -0.0% 0.0% k-nucleotide 0.0% 0.0% -0.0% -0.0% +0.0% kahan 0.0% 0.0% -0.0% -0.0% +0.0% knights 0.0% 0.0% -2.2% -5.4% 0.0% lambda 0.0% 0.0% -0.6% -1.8% 0.0% last-piece 0.0% 0.0% -0.0% -0.0% 0.0% lcss 0.0% 0.0% -0.0% -0.1% 0.0% life 0.0% 0.0% -0.0% -0.1% 0.0% lift 0.0% 0.0% -0.2% -0.6% +0.0% linear 0.0% 0.0% -0.0% -0.0% -0.0% listcompr 0.0% 0.0% -0.0% -0.0% 0.0% listcopy 0.0% 0.0% -0.0% -0.0% 0.0% maillist 0.0% 0.0% -0.1% -0.3% +0.0% mandel 0.0% 0.0% -0.0% -0.0% 0.0% mandel2 0.0% 0.0% -0.0% -0.0% -0.0% mate +0.0% 0.0% -0.0% -0.0% -0.0% minimax 0.0% 0.0% -0.2% -1.0% 0.0% mkhprog 0.0% 0.0% -0.1% -0.2% -0.0% multiplier 0.0% 0.0% -0.0% -0.0% -0.0% n-body 0.0% 0.0% -0.0% -0.0% +0.0% nucleic2 0.0% 0.0% -0.1% -0.2% 0.0% para 0.0% 0.0% -0.0% -0.0% -0.0% paraffins 0.0% 0.0% -0.0% -0.0% 0.0% parser 0.0% 0.0% -0.2% -0.7% 0.0% parstof 0.0% 0.0% -0.0% -0.0% +0.0% pic 0.0% 0.0% -0.0% -0.0% 0.0% pidigits 0.0% 0.0% +0.0% +0.0% +0.0% power 0.0% 0.0% -0.2% -0.6% +0.0% pretty 0.0% 0.0% -0.0% -0.0% -0.0% primes 0.0% 0.0% -0.0% -0.0% 0.0% primetest 0.0% 0.0% -0.0% -0.0% -0.0% prolog 0.0% 0.0% -0.3% -1.1% 0.0% puzzle 0.0% 0.0% -0.0% -0.0% 0.0% queens 0.0% 0.0% -0.0% -0.0% +0.0% reptile 0.0% 0.0% -0.0% -0.0% 0.0% reverse-complem 0.0% 0.0% -0.0% -0.0% +0.0% rewrite 0.0% 0.0% -0.7% -2.5% -0.0% rfib 0.0% 0.0% -0.0% -0.0% 0.0% rsa 0.0% 0.0% -0.0% -0.0% 0.0% scc 0.0% 0.0% -0.1% -0.2% -0.0% sched 0.0% 0.0% -0.0% -0.0% -0.0% scs 0.0% 0.0% -1.0% -2.6% +0.0% simple 0.0% 0.0% +0.0% -0.0% +0.0% solid 0.0% 0.0% -0.0% -0.0% 0.0% sorting 0.0% 0.0% -0.6% -1.6% 0.0% spectral-norm 0.0% 0.0% +0.0% 0.0% +0.0% sphere 0.0% 0.0% -0.0% -0.0% -0.0% symalg 0.0% 0.0% -0.0% -0.0% +0.0% tak 0.0% 0.0% -0.0% -0.0% 0.0% transform 0.0% 0.0% -0.0% -0.0% 0.0% treejoin 0.0% 0.0% -0.0% -0.0% 0.0% typecheck 0.0% 0.0% -0.0% -0.0% +0.0% veritas +0.0% 0.0% -0.2% -0.4% +0.0% wang 0.0% 0.0% -0.0% -0.0% 0.0% wave4main 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 0.0% 0.0% -0.0% -0.0% +0.0% x2n1 0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min 0.0% 0.0% -2.2% -5.4% -0.0% Max +0.0% 0.0% +0.0% +0.0% +0.1% Geometric Mean -0.0% -0.0% -0.1% -0.3% +0.0% Metric increases micro benchmarks tracked in #17686: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 Co-authored-by: Andreas Klebinger <klebinger.andreas at gmx.at> - - - - - 28 changed files: - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Iface/UpdateCafInfos.hs → compiler/GHC/Iface/UpdateIdInfos.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Runtime/Heap/Layout.hs - compiler/GHC/StgToCmm.hs - compiler/GHC/StgToCmm/Closure.hs - + compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/ghc.cabal.in - testsuite/tests/codeGen/should_compile/Makefile - + testsuite/tests/codeGen/should_compile/cg009/A.hs - + testsuite/tests/codeGen/should_compile/cg009/Main.hs - + testsuite/tests/codeGen/should_compile/cg009/Makefile - + testsuite/tests/codeGen/should_compile/cg009/all.T - + testsuite/tests/codeGen/should_compile/cg010/A.hs - + testsuite/tests/codeGen/should_compile/cg010/Main.hs - + testsuite/tests/codeGen/should_compile/cg010/Makefile - + testsuite/tests/codeGen/should_compile/cg010/all.T - + testsuite/tests/codeGen/should_compile/cg010/cg010.stdout - testsuite/tests/simplCore/should_compile/Makefile - testsuite/tests/simplCore/should_compile/T4201.stdout Changes: ===================================== compiler/GHC/CoreToIface.hs ===================================== @@ -34,13 +34,14 @@ module GHC.CoreToIface , toIfaceIdDetails , toIfaceIdInfo , toIfUnfolding - , toIfaceOneShot , toIfaceTickish , toIfaceBind , toIfaceAlt , toIfaceCon , toIfaceApp , toIfaceVar + -- * Other stuff + , toIfaceLFInfo ) where #include "HsVersions.h" @@ -51,6 +52,7 @@ import GHC.Iface.Syntax import GHC.Core.DataCon import GHC.Types.Id import GHC.Types.Id.Info +import GHC.StgToCmm.Types import GHC.Core import GHC.Core.TyCon hiding ( pprPromotionQuote ) import GHC.Core.Coercion.Axiom @@ -616,6 +618,34 @@ toIfaceVar v where name = idName v +--------------------- +toIfaceLFInfo :: Name -> LambdaFormInfo -> IfaceLFInfo +toIfaceLFInfo nm lfi = case lfi of + LFReEntrant top_lvl arity no_fvs _arg_descr -> + -- Exported LFReEntrant closures are top level, and top-level closures + -- don't have free variables + ASSERT2(isTopLevel top_lvl, ppr nm) + ASSERT2(no_fvs, ppr nm) + IfLFReEntrant arity + LFThunk top_lvl no_fvs updatable sfi _mb_fun -> + -- Exported LFThunk closures are top level (which don't have free + -- variables), updatable, and non-standard (see cgTopRhsClosure) + ASSERT2(isTopLevel top_lvl, ppr nm) + ASSERT2(no_fvs, ppr nm) + ASSERT2(updatable, ppr nm) + ASSERT2(sfi == NonStandardThunk, ppr nm) + IfLFUnknown + LFCon dc -> + IfLFCon (dataConName dc) + LFUnknown _might_be_function -> + -- The argument can be derived from the type via might_be_a_function so we + -- don't serialize it + IfLFUnknown + LFUnlifted -> + IfLFUnlifted + LFLetNoEscape -> + panic "toIfaceLFInfo: LFLetNoEscape" + {- Note [Inlining and hs-boot files] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider this example (#10083, #12789): ===================================== compiler/GHC/Driver/Hooks.hs ===================================== @@ -55,6 +55,7 @@ import GHC.Stg.Syntax import GHC.Data.Stream import GHC.Cmm import GHC.Hs.Extension +import GHC.StgToCmm.Types (ModuleLFInfos) import Data.Maybe @@ -109,7 +110,7 @@ data Hooks = Hooks -> IO (Maybe HValue)) , createIservProcessHook :: Maybe (CreateProcess -> IO ProcessHandle) , stgToCmmHook :: Maybe (DynFlags -> Module -> [TyCon] -> CollectedCCs - -> [CgStgTopBinding] -> HpcInfo -> Stream IO CmmGroup ()) + -> [CgStgTopBinding] -> HpcInfo -> Stream IO CmmGroup ModuleLFInfos) , cmmToRawCmmHook :: forall a . Maybe (DynFlags -> Maybe Module -> Stream IO CmmGroupSRTs a -> IO (Stream IO RawCmmGroup a)) } ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -132,7 +132,6 @@ import qualified GHC.StgToCmm as StgToCmm ( codeGen ) import GHC.Types.CostCentre import GHC.Core.TyCon import GHC.Types.Name -import GHC.Types.Name.Set import GHC.Cmm import GHC.Cmm.Parser ( parseCmmFile ) import GHC.Cmm.Info.Build @@ -147,6 +146,7 @@ import GHC.Tc.Utils.Env import GHC.Builtin.Names import GHC.Driver.Plugins import GHC.Runtime.Loader ( initializePlugins ) +import GHC.StgToCmm.Types (CgInfos (..), ModuleLFInfos) import GHC.Driver.Session import GHC.Utils.Error @@ -175,6 +175,7 @@ import qualified Data.Set as S import Data.Set (Set) import Data.Functor import Control.DeepSeq (force) +import Data.Bifunctor (first) import GHC.Iface.Ext.Ast ( mkHieFile ) import GHC.Iface.Ext.Types ( getAsts, hie_asts, hie_module ) @@ -1385,7 +1386,7 @@ hscWriteIface dflags iface no_change mod_location = do -- | Compile to hard-code. hscGenHardCode :: HscEnv -> CgGuts -> ModLocation -> FilePath - -> IO (FilePath, Maybe FilePath, [(ForeignSrcLang, FilePath)], NameSet) + -> IO (FilePath, Maybe FilePath, [(ForeignSrcLang, FilePath)], CgInfos) -- ^ @Just f@ <=> _stub.c is f hscGenHardCode hsc_env cgguts location output_filename = do let CgGuts{ -- This is the last use of the ModGuts in a compilation. @@ -1444,11 +1445,11 @@ hscGenHardCode hsc_env cgguts location output_filename = do return a rawcmms1 = Stream.mapM dump rawcmms0 - (output_filename, (_stub_h_exists, stub_c_exists), foreign_fps, caf_infos) + (output_filename, (_stub_h_exists, stub_c_exists), foreign_fps, cg_infos) <- {-# SCC "codeOutput" #-} codeOutput dflags this_mod output_filename location foreign_stubs foreign_files dependencies rawcmms1 - return (output_filename, stub_c_exists, foreign_fps, caf_infos) + return (output_filename, stub_c_exists, foreign_fps, cg_infos) hscInteractive :: HscEnv @@ -1542,7 +1543,7 @@ doCodeGen :: HscEnv -> Module -> [TyCon] -> CollectedCCs -> [StgTopBinding] -> HpcInfo - -> IO (Stream IO CmmGroupSRTs NameSet) + -> IO (Stream IO CmmGroupSRTs CgInfos) -- Note we produce a 'Stream' of CmmGroups, so that the -- backend can be run incrementally. Otherwise it generates all -- the C-- up front, which has a significant space cost. @@ -1554,7 +1555,7 @@ doCodeGen hsc_env this_mod data_tycons dumpIfSet_dyn dflags Opt_D_dump_stg_final "Final STG:" FormatSTG (pprGenStgTopBindings stg_binds_w_fvs) - let cmm_stream :: Stream IO CmmGroup () + let cmm_stream :: Stream IO CmmGroup ModuleLFInfos -- See Note [Forcing of stg_binds] cmm_stream = stg_binds_w_fvs `seqList` {-# SCC "StgToCmm" #-} lookupHook stgToCmmHook StgToCmm.codeGen dflags dflags this_mod data_tycons @@ -1573,10 +1574,14 @@ doCodeGen hsc_env this_mod data_tycons ppr_stream1 = Stream.mapM dump1 cmm_stream - pipeline_stream = - {-# SCC "cmmPipeline" #-} - Stream.mapAccumL (cmmPipeline hsc_env) (emptySRT this_mod) ppr_stream1 - <&> (srtMapNonCAFs . moduleSRTMap) + pipeline_stream :: Stream IO CmmGroupSRTs CgInfos + pipeline_stream = do + (non_cafs, lf_infos) <- + {-# SCC "cmmPipeline" #-} + Stream.mapAccumL_ (cmmPipeline hsc_env) (emptySRT this_mod) ppr_stream1 + <&> first (srtMapNonCAFs . moduleSRTMap) + + return CgInfos{ cgNonCafs = non_cafs, cgLFInfos = lf_infos } dump2 a = do unless (null a) $ ===================================== compiler/GHC/Driver/Pipeline.hs ===================================== @@ -70,7 +70,7 @@ import GHC.Settings import GHC.Data.Bag ( unitBag ) import GHC.Data.FastString ( mkFastString ) import GHC.Iface.Make ( mkFullIface ) -import GHC.Iface.UpdateCafInfos ( updateModDetailsCafInfos ) +import GHC.Iface.UpdateIdInfos ( updateModDetailsIdInfos ) import GHC.Utils.Exception as Exception import System.Directory @@ -1178,12 +1178,12 @@ runPhase (HscOut src_flavour mod_name result) _ dflags = do PipeState{hsc_env=hsc_env'} <- getPipeState - (outputFilename, mStub, foreign_files, caf_infos) <- liftIO $ + (outputFilename, mStub, foreign_files, cg_infos) <- liftIO $ hscGenHardCode hsc_env' cgguts mod_location output_fn - final_iface <- liftIO (mkFullIface hsc_env'{hsc_dflags=iface_dflags} partial_iface (Just caf_infos)) - let final_mod_details = {-# SCC updateModDetailsCafInfos #-} - updateModDetailsCafInfos iface_dflags caf_infos mod_details + final_iface <- liftIO (mkFullIface hsc_env'{hsc_dflags=iface_dflags} partial_iface (Just cg_infos)) + let final_mod_details = {-# SCC updateModDetailsIdInfos #-} + updateModDetailsIdInfos iface_dflags cg_infos mod_details setIface final_iface final_mod_details -- See Note [Writing interface files] ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -38,6 +38,7 @@ import GHC.Core.Coercion.Axiom import GHC.Core.ConLike import GHC.Core.DataCon import GHC.Core.Type +import GHC.StgToCmm.Types (CgInfos (..)) import GHC.Tc.Utils.TcType import GHC.Core.InstEnv import GHC.Core.FamInstEnv @@ -98,15 +99,19 @@ mkPartialIface hsc_env mod_details = mkIface_ hsc_env this_mod hsc_src used_th deps rdr_env fix_env warns hpc_info self_trust safe_mode usages doc_hdr decl_docs arg_docs mod_details --- | Fully instantiate a interface --- Adds fingerprints and potentially code generator produced information. -mkFullIface :: HscEnv -> PartialModIface -> Maybe NameSet -> IO ModIface -mkFullIface hsc_env partial_iface mb_non_cafs = do +-- | Fully instantiate an interface. Adds fingerprints and potentially code +-- generator produced information. +-- +-- CgInfos is not available when not generating code (-fno-code), or when not +-- generating interface pragmas (-fomit-interface-pragmas). See also +-- Note [Conveying CAF-info and LFInfo between modules] in GHC.StgToCmm.Types. +mkFullIface :: HscEnv -> PartialModIface -> Maybe CgInfos -> IO ModIface +mkFullIface hsc_env partial_iface mb_cg_infos = do let decls | gopt Opt_OmitInterfacePragmas (hsc_dflags hsc_env) = mi_decls partial_iface | otherwise - = updateDeclCafInfos (mi_decls partial_iface) mb_non_cafs + = updateDecl (mi_decls partial_iface) mb_cg_infos full_iface <- {-# SCC "addFingerprints" #-} @@ -117,15 +122,23 @@ mkFullIface hsc_env partial_iface mb_non_cafs = do return full_iface -updateDeclCafInfos :: [IfaceDecl] -> Maybe NameSet -> [IfaceDecl] -updateDeclCafInfos decls Nothing = decls -updateDeclCafInfos decls (Just non_cafs) = map update_decl decls +updateDecl :: [IfaceDecl] -> Maybe CgInfos -> [IfaceDecl] +updateDecl decls Nothing = decls +updateDecl decls (Just CgInfos{ cgNonCafs = non_cafs, cgLFInfos = lf_infos }) = map update_decl decls where + update_decl (IfaceId nm ty details infos) + | let not_caffy = elemNameSet nm non_cafs + , let mb_lf_info = lookupNameEnv lf_infos nm + , WARN( isNothing mb_lf_info, text "Name without LFInfo:" <+> ppr nm ) True + -- Only allocate a new IfaceId if we're going to update the infos + , isJust mb_lf_info || not_caffy + = IfaceId nm ty details $ + (if not_caffy then (HsNoCafRefs :) else id) + (case mb_lf_info of + Nothing -> infos -- LFInfos not available when building .cmm files + Just lf_info -> HsLFInfo (toIfaceLFInfo nm lf_info) : infos) + update_decl decl - | IfaceId nm ty details infos <- decl - , elemNameSet nm non_cafs - = IfaceId nm ty details (HsNoCafRefs : infos) - | otherwise = decl -- | Make an interface from the results of typechecking only. Useful ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -22,6 +22,8 @@ module GHC.Iface.Syntax ( IfaceAxBranch(..), IfaceTyConParent(..), IfaceCompleteMatch(..), + IfaceLFInfo(..), + IfaceStandardFormInfo(..), -- * Binding names IfaceTopBndr, @@ -30,6 +32,7 @@ module GHC.Iface.Syntax ( -- Misc ifaceDeclImplicitBndrs, visibleIfConDecls, ifaceDeclFingerprints, + tcStandardFormInfo, -- Free Names freeNamesIfDecl, freeNamesIfRule, freeNamesIfFamInst, @@ -67,15 +70,18 @@ import GHC.Utils.Binary import GHC.Data.BooleanFormula ( BooleanFormula, pprBooleanFormula, isTrue ) import GHC.Types.Var( VarBndr(..), binderVar ) import GHC.Core.TyCon ( Role (..), Injectivity(..), tyConBndrVisArgFlag ) -import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, debugIsOn ) +import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, debugIsOn, + seqList ) import GHC.Core.DataCon (SrcStrictness(..), SrcUnpackedness(..)) import GHC.Utils.Lexeme (isLexSym) import GHC.Builtin.Types ( constraintKindTyConName ) -import GHC.Utils.Misc (seqList) +import GHC.StgToCmm.Types import Control.Monad import System.IO.Unsafe import Control.DeepSeq +import Data.Word +import Data.Bits infixl 3 &&& @@ -114,7 +120,8 @@ data IfaceDecl = IfaceId { ifName :: IfaceTopBndr, ifType :: IfaceType, ifIdDetails :: IfaceIdDetails, - ifIdInfo :: IfaceIdInfo } + ifIdInfo :: IfaceIdInfo + } | IfaceData { ifName :: IfaceTopBndr, -- Type constructor ifBinders :: [IfaceTyConBinder], @@ -348,6 +355,7 @@ data IfaceInfoItem IfaceUnfolding -- See Note [Expose recursive functions] | HsNoCafRefs | HsLevity -- Present <=> never levity polymorphic + | HsLFInfo IfaceLFInfo -- NB: Specialisations and rules come in separately and are -- only later attached to the Id. Partial reason: some are orphans. @@ -379,6 +387,70 @@ data IfaceIdDetails | IfRecSelId (Either IfaceTyCon IfaceDecl) Bool | IfDFunId +-- | Iface type for LambdaFormInfo. Fields not relevant for imported Ids are +-- omitted in this type. +-- +-- Thunks are represented as LFUnknown: top-level thunks are never single-entry, +-- and for updatable thunks LFThunk and LFUnknown calling convention is the +-- same, see GHC.StgToCmm.Closure.getCallMethod. +data IfaceLFInfo + = IfLFReEntrant !RepArity + | IfLFCon !Name + | IfLFUnknown + | IfLFUnlifted + -- Generally, top-level things can't be unlifted, but we have an exception + -- for literal strings -- see Note [Core top-level string literals] in + -- GHC.Core + +tcStandardFormInfo :: IfaceStandardFormInfo -> StandardFormInfo +tcStandardFormInfo (IfStandardFormInfo w) + | testBit w 0 = NonStandardThunk + | otherwise = con field + where + field = fromIntegral (w `unsafeShiftR` 2) + con + | testBit w 1 = ApThunk + | otherwise = SelectorThunk + +instance Outputable IfaceLFInfo where + ppr (IfLFReEntrant arity) = + text "LFReEntrant" <+> ppr arity + + ppr (IfLFCon con) = + text "LFCon" <> brackets (ppr con) + + ppr IfLFUnlifted = + text "LFUnlifted" + + ppr IfLFUnknown = + text "LFUnknown" + +newtype IfaceStandardFormInfo = IfStandardFormInfo Word16 + +instance Binary IfaceStandardFormInfo where + put_ bh (IfStandardFormInfo w) = put_ bh (w :: Word16) + get bh = IfStandardFormInfo <$> (get bh :: IO Word16) + +instance Binary IfaceLFInfo where + put_ bh (IfLFReEntrant arity) = do + putByte bh 0 + put_ bh arity + put_ bh (IfLFCon con_name) = do + putByte bh 1 + put_ bh con_name + put_ bh IfLFUnknown = do + putByte bh 2 + put_ bh IfLFUnlifted = + putByte bh 3 + get bh = do + tag <- getByte bh + case tag of + 0 -> IfLFReEntrant <$> get bh + 1 -> IfLFCon <$> get bh + 2 -> pure IfLFUnknown + 3 -> pure IfLFUnlifted + _ -> panic "Invalid byte" + {- Note [Versioning of instances] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1393,6 +1465,7 @@ instance Outputable IfaceInfoItem where ppr (HsCpr cpr) = text "CPR:" <+> ppr cpr ppr HsNoCafRefs = text "HasNoCafRefs" ppr HsLevity = text "Never levity-polymorphic" + ppr (HsLFInfo lf_info) = text "LambdaFormInfo:" <+> ppr lf_info instance Outputable IfaceJoinInfo where ppr IfaceNotJoinPoint = empty @@ -1853,7 +1926,7 @@ instance Binary IfaceDecl where get bh = do h <- getByte bh case h of - 0 -> do name <- get bh + 0 -> do name <- get bh ~(ty, details, idinfo) <- lazyGet bh -- See Note [Lazy deserialization of IfaceId] return (IfaceId name ty details idinfo) @@ -2153,6 +2226,8 @@ instance Binary IfaceInfoItem where put_ bh HsNoCafRefs = putByte bh 4 put_ bh HsLevity = putByte bh 5 put_ bh (HsCpr cpr) = putByte bh 6 >> put_ bh cpr + put_ bh (HsLFInfo lf_info) = putByte bh 7 >> put_ bh lf_info + get bh = do h <- getByte bh case h of @@ -2164,7 +2239,8 @@ instance Binary IfaceInfoItem where 3 -> liftM HsInline $ get bh 4 -> return HsNoCafRefs 5 -> return HsLevity - _ -> HsCpr <$> get bh + 6 -> HsCpr <$> get bh + _ -> HsLFInfo <$> get bh instance Binary IfaceUnfolding where put_ bh (IfCoreUnfold s e) = do @@ -2495,6 +2571,7 @@ instance NFData IfaceInfoItem where HsNoCafRefs -> () HsLevity -> () HsCpr cpr -> cpr `seq` () + HsLFInfo lf_info -> lf_info `seq` () -- TODO: seq further? instance NFData IfaceUnfolding where rnf = \case ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -123,6 +123,9 @@ data IfaceOneShot -- See Note [Preserve OneShotInfo] in CoreTicy = IfaceNoOneShot -- and Note [The oneShot function] in GHC.Types.Id.Make | IfaceOneShot +instance Outputable IfaceOneShot where + ppr IfaceNoOneShot = text "NoOneShotInfo" + ppr IfaceOneShot = text "OneShot" {- %************************************************************************ ===================================== compiler/GHC/Iface/UpdateCafInfos.hs → compiler/GHC/Iface/UpdateIdInfos.hs ===================================== @@ -1,38 +1,42 @@ {-# LANGUAGE CPP, BangPatterns, Strict, RecordWildCards #-} -module GHC.Iface.UpdateCafInfos - ( updateModDetailsCafInfos +module GHC.Iface.UpdateIdInfos + ( updateModDetailsIdInfos ) where import GHC.Prelude import GHC.Core +import GHC.Core.InstEnv import GHC.Driver.Session import GHC.Driver.Types +import GHC.StgToCmm.Types (CgInfos (..)) import GHC.Types.Id import GHC.Types.Id.Info -import GHC.Core.InstEnv import GHC.Types.Name.Env import GHC.Types.Name.Set -import GHC.Utils.Misc import GHC.Types.Var +import GHC.Utils.Misc import GHC.Utils.Outputable #include "HsVersions.h" --- | Update CafInfos of all occurences (in rules, unfoldings, class instances) -updateModDetailsCafInfos +-- | Update CafInfos and LFInfos of all occurences (in rules, unfoldings, class +-- instances). +-- +-- See Note [Conveying CAF-info and LFInfo between modules] in +-- GHC.StgToCmm.Types. +updateModDetailsIdInfos :: DynFlags - -> NameSet -- ^ Non-CAFFY names in the module. Names not in this set are CAFFY. + -> CgInfos -> ModDetails -- ^ ModDetails to update -> ModDetails -updateModDetailsCafInfos dflags _ mod_details +updateModDetailsIdInfos dflags _ mod_details | gopt Opt_OmitInterfacePragmas dflags = mod_details -updateModDetailsCafInfos _ non_cafs mod_details = - {- pprTrace "updateModDetailsCafInfos" (text "non_cafs:" <+> ppr non_cafs) $ -} +updateModDetailsIdInfos _ cg_infos mod_details = let ModDetails{ md_types = type_env -- for unfoldings , md_insts = insts @@ -40,11 +44,11 @@ updateModDetailsCafInfos _ non_cafs mod_details = } = mod_details -- type TypeEnv = NameEnv TyThing - ~type_env' = mapNameEnv (updateTyThingCafInfos type_env' non_cafs) type_env + ~type_env' = mapNameEnv (updateTyThingIdInfos type_env' cg_infos) type_env -- Not strict! - !insts' = strictMap (updateInstCafInfos type_env' non_cafs) insts - !rules' = strictMap (updateRuleCafInfos type_env') rules + !insts' = strictMap (updateInstIdInfos type_env' cg_infos) insts + !rules' = strictMap (updateRuleIdInfos type_env') rules in mod_details{ md_types = type_env' , md_insts = insts' @@ -55,28 +59,28 @@ updateModDetailsCafInfos _ non_cafs mod_details = -- Rules -------------------------------------------------------------------------------- -updateRuleCafInfos :: TypeEnv -> CoreRule -> CoreRule -updateRuleCafInfos _ rule at BuiltinRule{} = rule -updateRuleCafInfos type_env Rule{ .. } = Rule { ru_rhs = updateGlobalIds type_env ru_rhs, .. } +updateRuleIdInfos :: TypeEnv -> CoreRule -> CoreRule +updateRuleIdInfos _ rule at BuiltinRule{} = rule +updateRuleIdInfos type_env Rule{ .. } = Rule { ru_rhs = updateGlobalIds type_env ru_rhs, .. } -------------------------------------------------------------------------------- -- Instances -------------------------------------------------------------------------------- -updateInstCafInfos :: TypeEnv -> NameSet -> ClsInst -> ClsInst -updateInstCafInfos type_env non_cafs = - updateClsInstDFun (updateIdUnfolding type_env . updateIdCafInfo non_cafs) +updateInstIdInfos :: TypeEnv -> CgInfos -> ClsInst -> ClsInst +updateInstIdInfos type_env cg_infos = + updateClsInstDFun (updateIdUnfolding type_env . updateIdInfo cg_infos) -------------------------------------------------------------------------------- -- TyThings -------------------------------------------------------------------------------- -updateTyThingCafInfos :: TypeEnv -> NameSet -> TyThing -> TyThing +updateTyThingIdInfos :: TypeEnv -> CgInfos -> TyThing -> TyThing -updateTyThingCafInfos type_env non_cafs (AnId id) = - AnId (updateIdUnfolding type_env (updateIdCafInfo non_cafs id)) +updateTyThingIdInfos type_env cg_infos (AnId id) = + AnId (updateIdUnfolding type_env (updateIdInfo cg_infos id)) -updateTyThingCafInfos _ _ other = other -- AConLike, ATyCon, ACoAxiom +updateTyThingIdInfos _ _ other = other -- AConLike, ATyCon, ACoAxiom -------------------------------------------------------------------------------- -- Unfoldings @@ -95,13 +99,18 @@ updateIdUnfolding type_env id = -- Expressions -------------------------------------------------------------------------------- -updateIdCafInfo :: NameSet -> Id -> Id -updateIdCafInfo non_cafs id - | idName id `elemNameSet` non_cafs - = -- pprTrace "updateIdCafInfo" (text "Marking" <+> ppr id <+> parens (ppr (idName id)) <+> text "as non-CAFFY") $ - id `setIdCafInfo` NoCafRefs - | otherwise - = id +updateIdInfo :: CgInfos -> Id -> Id +updateIdInfo CgInfos{ cgNonCafs = non_cafs, cgLFInfos = lf_infos } id = + let + not_caffy = elemNameSet (idName id) non_cafs + mb_lf_info = lookupNameEnv lf_infos (idName id) + + id1 = if not_caffy then setIdCafInfo id NoCafRefs else id + id2 = case mb_lf_info of + Nothing -> id1 + Just lf_info -> setIdLFInfo id1 lf_info + in + id2 -------------------------------------------------------------------------------- @@ -116,7 +125,7 @@ updateGlobalIds env e = go env e case lookupNameEnv env (varName var) of Nothing -> var Just (AnId id) -> id - Just other -> pprPanic "GHC.Iface.UpdateCafInfos.updateGlobalIds" $ + Just other -> pprPanic "UpdateCafInfos.updateGlobalIds" $ text "Found a non-Id for Id Name" <+> ppr (varName var) $$ nest 4 (text "Id:" <+> ppr var $$ text "TyThing:" <+> ppr other) ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -19,7 +19,8 @@ module GHC.IfaceToCore ( tcIfaceDecl, tcIfaceInst, tcIfaceFamInst, tcIfaceRules, tcIfaceAnnotations, tcIfaceCompleteSigs, tcIfaceExpr, -- Desired by HERMIT (#7683) - tcIfaceGlobal + tcIfaceGlobal, + tcIfaceOneShot ) where #include "HsVersions.h" @@ -30,6 +31,8 @@ import GHC.Builtin.Types.Literals(typeNatCoAxiomRules) import GHC.Iface.Syntax import GHC.Iface.Load import GHC.Iface.Env +import GHC.StgToCmm.Types +import GHC.StgToCmm.Closure (might_be_a_function) import GHC.Tc.TyCl.Build import GHC.Tc.Utils.Monad import GHC.Tc.Utils.TcType @@ -1464,8 +1467,7 @@ tcIdInfo ignore_prags toplvl name ty info = do let init_info | if_boot lcl_env = vanillaIdInfo `setUnfoldingInfo` BootUnfolding | otherwise = vanillaIdInfo - let needed = needed_prags info - foldlM tcPrag init_info needed + foldlM tcPrag init_info (needed_prags info) where needed_prags :: [IfaceInfoItem] -> [IfaceInfoItem] needed_prags items @@ -1485,6 +1487,9 @@ tcIdInfo ignore_prags toplvl name ty info = do tcPrag info (HsCpr cpr) = return (info `setCprInfo` cpr) tcPrag info (HsInline prag) = return (info `setInlinePragInfo` prag) tcPrag info HsLevity = return (info `setNeverLevPoly` ty) + tcPrag info (HsLFInfo lf_info) = do + lf_info <- tcLFInfo ty lf_info + return (info `setLFInfo` lf_info) -- The next two are lazy, so they don't transitively suck stuff in tcPrag info (HsUnfold lb if_unf) @@ -1497,6 +1502,29 @@ tcJoinInfo :: IfaceJoinInfo -> Maybe JoinArity tcJoinInfo (IfaceJoinPoint ar) = Just ar tcJoinInfo IfaceNotJoinPoint = Nothing +tcLFInfo :: Type -> IfaceLFInfo -> IfL LambdaFormInfo +tcLFInfo ty lfi = case lfi of + IfLFReEntrant rep_arity -> + -- LFReEntrant closures in interface files are guaranteed to + -- + -- - Be top-level, as only top-level closures are exported. + -- - Have no free variables, as only non-top-level closures have free + -- variables + -- - Don't have ArgDescrs, as ArgDescr is used when generating code for + -- the closure + -- + -- These invariants are checked when generating LFInfos in toIfaceLFInfo. + return (LFReEntrant TopLevel rep_arity True ArgUnknown) + + IfLFUnlifted -> + return LFUnlifted + + IfLFCon con_name -> + LFCon <$!> tcIfaceDataCon con_name + + IfLFUnknown -> + return (LFUnknown (might_be_a_function ty)) + tcUnfolding :: TopLevelFlag -> Name -> Type -> IdInfo -> IfaceUnfolding -> IfL Unfolding tcUnfolding toplvl name _ info (IfCoreUnfold stable if_expr) = do { dflags <- getDynFlags @@ -1508,7 +1536,7 @@ tcUnfolding toplvl name _ info (IfCoreUnfold stable if_expr) Just expr -> mkFinalUnfolding dflags unf_src strict_sig expr } where - -- Strictness should occur before unfolding! + -- Strictness should occur before unfolding! strict_sig = strictnessInfo info tcUnfolding toplvl name _ _ (IfCompulsory if_expr) @@ -1583,6 +1611,10 @@ tcPragExpr is_compulsory toplvl name expr -- It's OK to use nonDetEltsUFM here because we immediately forget -- the ordering by creating a set +tcIfaceOneShot :: IfaceOneShot -> OneShotInfo +tcIfaceOneShot IfaceNoOneShot = NoOneShotInfo +tcIfaceOneShot IfaceOneShot = OneShotLam + {- ************************************************************************ * * ===================================== compiler/GHC/Runtime/Heap/Layout.hs ===================================== @@ -51,6 +51,7 @@ import GHC.Driver.Session import GHC.Utils.Outputable import GHC.Platform import GHC.Data.FastString +import GHC.StgToCmm.Types import Data.Word import Data.Bits @@ -64,9 +65,6 @@ import Data.ByteString (ByteString) ************************************************************************ -} --- | Word offset, or word count -type WordOff = Int - -- | Byte offset, or byte count type ByteOff = Int @@ -196,29 +194,6 @@ type ConstrDescription = ByteString -- result of dataConIdentity type FunArity = Int type SelectorOffset = Int -------------------------- --- We represent liveness bitmaps as a Bitmap (whose internal --- representation really is a bitmap). These are pinned onto case return --- vectors to indicate the state of the stack for the garbage collector. --- --- In the compiled program, liveness bitmaps that fit inside a single --- word (StgWord) are stored as a single word, while larger bitmaps are --- stored as a pointer to an array of words. - -type Liveness = [Bool] -- One Bool per word; True <=> non-ptr or dead - -- False <=> ptr - -------------------------- --- An ArgDescr describes the argument pattern of a function - -data ArgDescr - = ArgSpec -- Fits one of the standard patterns - !Int -- RTS type identifier ARG_P, ARG_N, ... - - | ArgGen -- General case - Liveness -- Details about the arguments - - ----------------------------------------------------------------------------- -- Construction @@ -545,10 +520,6 @@ instance Outputable SMRep where ppr (RTSRep ty rep) = text "tag:" <> ppr ty <+> ppr rep -instance Outputable ArgDescr where - ppr (ArgSpec n) = text "ArgSpec" <+> ppr n - ppr (ArgGen ls) = text "ArgGen" <+> ppr ls - pprTypeInfo :: ClosureTypeInfo -> SDoc pprTypeInfo (Constr tag descr) = text "Con" <+> ===================================== compiler/GHC/StgToCmm.hs ===================================== @@ -1,5 +1,6 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-} +{-# LANGUAGE BangPatterns #-} ----------------------------------------------------------------------------- -- @@ -25,6 +26,7 @@ import GHC.StgToCmm.Utils import GHC.StgToCmm.Closure import GHC.StgToCmm.Hpc import GHC.StgToCmm.Ticky +import GHC.StgToCmm.Types (ModuleLFInfos) import GHC.Cmm import GHC.Cmm.Utils @@ -47,6 +49,8 @@ import GHC.Data.Stream import GHC.Types.Basic import GHC.Types.Var.Set ( isEmptyDVarSet ) import GHC.SysTools.FileCleanup +import GHC.Types.Unique.FM +import GHC.Types.Name.Env import GHC.Data.OrdList import GHC.Cmm.Graph @@ -63,7 +67,8 @@ codeGen :: DynFlags -> CollectedCCs -- (Local/global) cost-centres needing declaring/registering. -> [CgStgTopBinding] -- Bindings to convert -> HpcInfo - -> Stream IO CmmGroup () -- Output as a stream, so codegen can + -> Stream IO CmmGroup ModuleLFInfos + -- Output as a stream, so codegen can -- be interleaved with output codeGen dflags this_mod data_tycons @@ -105,6 +110,19 @@ codeGen dflags this_mod data_tycons mapM_ (cg . cgDataCon) (tyConDataCons tycon) ; mapM_ do_tycon data_tycons + + ; cg_id_infos <- cgs_binds <$> liftIO (readIORef cgref) + + ; let extract_lf_info info = (name, lf) + where + !id = cg_id info + !name = idName id + !lf = cg_lf info + + -- Note [Conveying CAF-info and LFInfo between modules] + ; let !generatedInfo = mkNameEnv (Prelude.map extract_lf_info (eltsUFM cg_id_infos)) + + ; return generatedInfo } --------------------------------------------------------------- ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -55,6 +55,8 @@ module GHC.StgToCmm.Closure ( blackHoleOnEntry, -- Needs LambdaFormInfo and SMRep isStaticClosure, -- Needs SMPre + might_be_a_function, + -- * InfoTables mkDataConInfoTable, cafBlackHoleInfoTable, @@ -70,6 +72,7 @@ import GHC.Stg.Syntax import GHC.Runtime.Heap.Layout import GHC.Cmm import GHC.Cmm.Ppr.Expr() -- For Outputable instances +import GHC.StgToCmm.Types import GHC.Types.CostCentre import GHC.Cmm.BlockId @@ -188,76 +191,6 @@ addArgReps = map (\arg -> let arg' = fromNonVoid arg argPrimRep :: StgArg -> PrimRep argPrimRep arg = typePrimRep1 (stgArgType arg) - ------------------------------------------------------------------------------ --- LambdaFormInfo ------------------------------------------------------------------------------ - --- Information about an identifier, from the code generator's point of --- view. Every identifier is bound to a LambdaFormInfo in the --- environment, which gives the code generator enough info to be able to --- tail call or return that identifier. - -data LambdaFormInfo - = LFReEntrant -- Reentrant closure (a function) - TopLevelFlag -- True if top level - !RepArity -- Arity. Invariant: always > 0 - !Bool -- True <=> no fvs - ArgDescr -- Argument descriptor (should really be in ClosureInfo) - - | LFThunk -- Thunk (zero arity) - TopLevelFlag - !Bool -- True <=> no free vars - !Bool -- True <=> updatable (i.e., *not* single-entry) - StandardFormInfo - !Bool -- True <=> *might* be a function type - - | LFCon -- A saturated constructor application - DataCon -- The constructor - - | LFUnknown -- Used for function arguments and imported things. - -- We know nothing about this closure. - -- Treat like updatable "LFThunk"... - -- Imported things which we *do* know something about use - -- one of the other LF constructors (eg LFReEntrant for - -- known functions) - !Bool -- True <=> *might* be a function type - -- The False case is good when we want to enter it, - -- because then we know the entry code will do - -- For a function, the entry code is the fast entry point - - | LFUnlifted -- A value of unboxed type; - -- always a value, needs evaluation - - | LFLetNoEscape -- See LetNoEscape module for precise description - - -------------------------- --- StandardFormInfo tells whether this thunk has one of --- a small number of standard forms - -data StandardFormInfo - = NonStandardThunk - -- The usual case: not of the standard forms - - | SelectorThunk - -- A SelectorThunk is of form - -- case x of - -- con a1,..,an -> ak - -- and the constructor is from a single-constr type. - WordOff -- 0-origin offset of ak within the "goods" of - -- constructor (Recall that the a1,...,an may be laid - -- out in the heap in a non-obvious order.) - - | ApThunk - -- An ApThunk is of form - -- x1 ... xn - -- The code for the thunk just pushes x2..xn on the stack and enters x1. - -- There are a few of these (for 1 <= n <= MAX_SPEC_AP_SIZE) pre-compiled - -- in the RTS to save space. - RepArity -- Arity, n - - ------------------------------------------------------ -- Building LambdaFormInfo ------------------------------------------------------ @@ -325,18 +258,22 @@ mkApLFInfo id upd_flag arity ------------- mkLFImported :: Id -> LambdaFormInfo -mkLFImported id - | Just con <- isDataConWorkId_maybe id - , isNullaryRepDataCon con - = LFCon con -- An imported nullary constructor - -- We assume that the constructor is evaluated so that - -- the id really does point directly to the constructor - - | arity > 0 - = LFReEntrant TopLevel arity True (panic "arg_descr") - - | otherwise - = mkLFArgument id -- Not sure of exact arity +mkLFImported id = + case idLFInfo_maybe id of + Just lf_info -> + lf_info + Nothing + | Just con <- isDataConWorkId_maybe id + , isNullaryRepDataCon con + -> LFCon con -- An imported nullary constructor + -- We assume that the constructor is evaluated so that + -- the id really does point directly to the constructor + + | arity > 0 + -> LFReEntrant TopLevel arity True ArgUnknown + + | otherwise + -> mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id ===================================== compiler/GHC/StgToCmm/Types.hs ===================================== @@ -0,0 +1,224 @@ +{-# LANGUAGE CPP #-} + +module GHC.StgToCmm.Types + ( CgInfos (..) + , LambdaFormInfo (..) + , ModuleLFInfos + , Liveness + , ArgDescr (..) + , StandardFormInfo (..) + , WordOff + ) where + +#include "HsVersions.h" + +import GHC.Prelude + +import GHC.Types.Basic +import GHC.Core.DataCon +import GHC.Types.Name.Env +import GHC.Types.Name.Set +import GHC.Utils.Outputable + +{- +Note [Conveying CAF-info and LFInfo between modules] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Some information about an Id is generated in the code generator, and is not +available earlier. Namely: + +* CAF info. Code motion in Cmm or earlier phases may move references around so + we compute information about which bits of code refer to which CAF late in the + Cmm pipeline. + +* LambdaFormInfo. This records the details of a closure representation, + including + - the final arity (for functions) + - whether it is a data constructor, and if so its tag + +Collectively we call this CgInfo (see GHC.StgToCmm.Types). + +It's very useful for importing modules to have this information. We can always +make a conservative assumption, but that is bad: e.g. + +* For CAF info, if we know nothing we have to assume it is a CAF which bloats + the SRTs of the importing module. + +- For data constructors, we really like having well-tagged pointers. See #14677, + #16559, #15155, and wiki: commentary/rts/haskell-execution/pointer-tagging + +So we arrange to always serialise this information into the interface file. The +moving parts are: + +* We record the CgInfo in the IdInfo of the Id. + +* GHC.Driver.Pipeline: the call to updateModDetailsIdInfos augments the + ModDetails constructed at the end of the Core pipeline, with with CgInfo + gleaned from the back end. The hard work is done in GHC.Iface.UpdateIdInfos. + +* For ModIface we generate the final ModIface with CgInfo in + GHC.Iface.Make.mkFullIface. + +* We don't absolutely guarantee to serialise the CgInfo: we won't if you have + -fomit-interface-pragmas or -fno-code; and we won't read it in if you have + -fignore-interface-pragmas. (We could revisit this decision.) +-} + +-- | Codegen-generated Id infos, to be passed to downstream via interfaces. +-- +-- This stuff is for optimization purposes only, they're not compulsory. +-- +-- * When CafInfo of an imported Id is not known it's safe to treat it as CAFFY. +-- * When LambdaFormInfo of an imported Id is not known it's safe to treat it as +-- `LFUnknown True` (which just says "it could be anything" and we do slow +-- entry). +-- +-- See also Note [Conveying CAF-info and LFInfo between modules] above. +-- +data CgInfos = CgInfos + { cgNonCafs :: !NameSet + -- ^ Exported Non-CAFFY closures in the current module. Everything else is + -- either not exported of CAFFY. + , cgLFInfos :: !ModuleLFInfos + -- ^ LambdaFormInfos of exported closures in the current module. + } + +-------------------------------------------------------------------------------- +-- LambdaFormInfo +-------------------------------------------------------------------------------- + +-- | Maps names in the current module to their LambdaFormInfos +type ModuleLFInfos = NameEnv LambdaFormInfo + +-- | Information about an identifier, from the code generator's point of view. +-- Every identifier is bound to a LambdaFormInfo in the environment, which gives +-- the code generator enough info to be able to tail call or return that +-- identifier. +data LambdaFormInfo + = LFReEntrant -- Reentrant closure (a function) + !TopLevelFlag -- True if top level + !RepArity -- Arity. Invariant: always > 0 + !Bool -- True <=> no fvs + !ArgDescr -- Argument descriptor (should really be in ClosureInfo) + + | LFThunk -- Thunk (zero arity) + !TopLevelFlag + !Bool -- True <=> no free vars + !Bool -- True <=> updatable (i.e., *not* single-entry) + !StandardFormInfo + !Bool -- True <=> *might* be a function type + + | LFCon -- A saturated constructor application + !DataCon -- The constructor + + | LFUnknown -- Used for function arguments and imported things. + -- We know nothing about this closure. + -- Treat like updatable "LFThunk"... + -- Imported things which we *do* know something about use + -- one of the other LF constructors (eg LFReEntrant for + -- known functions) + !Bool -- True <=> *might* be a function type + -- The False case is good when we want to enter it, + -- because then we know the entry code will do + -- For a function, the entry code is the fast entry point + + | LFUnlifted -- A value of unboxed type; + -- always a value, needs evaluation + + | LFLetNoEscape -- See LetNoEscape module for precise description + +instance Outputable LambdaFormInfo where + ppr (LFReEntrant top rep fvs argdesc) = + text "LFReEntrant" <> brackets + (ppr top <+> ppr rep <+> pprFvs fvs <+> ppr argdesc) + ppr (LFThunk top hasfv updateable sfi m_function) = + text "LFThunk" <> brackets + (ppr top <+> pprFvs hasfv <+> pprUpdateable updateable <+> + ppr sfi <+> pprFuncFlag m_function) + ppr (LFCon con) = + text "LFCon" <> brackets (ppr con) + ppr (LFUnknown m_func) = + text "LFUnknown" <> brackets (pprFuncFlag m_func) + ppr LFUnlifted = + text "LFUnlifted" + ppr LFLetNoEscape = + text "LFLetNoEscape" + +pprFvs :: Bool -> SDoc +pprFvs True = text "no-fvs" +pprFvs False = text "fvs" + +pprFuncFlag :: Bool -> SDoc +pprFuncFlag True = text "mFunc" +pprFuncFlag False = text "value" + +pprUpdateable :: Bool -> SDoc +pprUpdateable True = text "updateable" +pprUpdateable False = text "oneshot" + +-------------------------------------------------------------------------------- + +-- | We represent liveness bitmaps as a Bitmap (whose internal representation +-- really is a bitmap). These are pinned onto case return vectors to indicate +-- the state of the stack for the garbage collector. +-- +-- In the compiled program, liveness bitmaps that fit inside a single word +-- (StgWord) are stored as a single word, while larger bitmaps are stored as a +-- pointer to an array of words. + +type Liveness = [Bool] -- One Bool per word; True <=> non-ptr or dead + -- False <=> ptr + +-------------------------------------------------------------------------------- +-- | An ArgDescr describes the argument pattern of a function + +data ArgDescr + = ArgSpec -- Fits one of the standard patterns + !Int -- RTS type identifier ARG_P, ARG_N, ... + + | ArgGen -- General case + Liveness -- Details about the arguments + + | ArgUnknown -- For imported binds. + -- Invariant: Never Unknown for binds of the module + -- we are compiling. + deriving (Eq) + +instance Outputable ArgDescr where + ppr (ArgSpec n) = text "ArgSpec" <+> ppr n + ppr (ArgGen ls) = text "ArgGen" <+> ppr ls + ppr ArgUnknown = text "ArgUnknown" + +-------------------------------------------------------------------------------- +-- | StandardFormInfo tells whether this thunk has one of a small number of +-- standard forms + +data StandardFormInfo + = NonStandardThunk + -- The usual case: not of the standard forms + + | SelectorThunk + -- A SelectorThunk is of form + -- case x of + -- con a1,..,an -> ak + -- and the constructor is from a single-constr type. + !WordOff -- 0-origin offset of ak within the "goods" of + -- constructor (Recall that the a1,...,an may be laid + -- out in the heap in a non-obvious order.) + + | ApThunk + -- An ApThunk is of form + -- x1 ... xn + -- The code for the thunk just pushes x2..xn on the stack and enters x1. + -- There are a few of these (for 1 <= n <= MAX_SPEC_AP_SIZE) pre-compiled + -- in the RTS to save space. + !RepArity -- Arity, n + deriving (Eq) + +-- | Word offset, or word count +type WordOff = Int + +instance Outputable StandardFormInfo where + ppr NonStandardThunk = text "RegThunk" + ppr (SelectorThunk w) = text "SelThunk:" <> ppr w + ppr (ApThunk n) = text "ApThunk:" <> ppr n ===================================== compiler/GHC/Types/Id.hs ===================================== @@ -92,7 +92,7 @@ module GHC.Types.Id ( idCallArity, idFunRepArity, idUnfolding, realIdUnfolding, idSpecialisation, idCoreRules, idHasRules, - idCafInfo, + idCafInfo, idLFInfo_maybe, idOneShotInfo, idStateHackOneShotInfo, idOccInfo, isNeverLevPolyId, @@ -105,6 +105,7 @@ module GHC.Types.Id ( setIdSpecialisation, setIdCafInfo, setIdOccInfo, zapIdOccInfo, + setIdLFInfo, setIdDemandInfo, setIdStrictness, @@ -731,6 +732,15 @@ idCafInfo id = cafInfo (idInfo id) setIdCafInfo :: Id -> CafInfo -> Id setIdCafInfo id caf_info = modifyIdInfo (`setCafInfo` caf_info) id + --------------------------------- + -- Lambda form info + +idLFInfo_maybe :: Id -> Maybe LambdaFormInfo +idLFInfo_maybe = lfInfo . idInfo + +setIdLFInfo :: Id -> LambdaFormInfo -> Id +setIdLFInfo id lf = modifyIdInfo (`setLFInfo` lf) id + --------------------------------- -- Occurrence INFO idOccInfo :: Id -> OccInfo ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -74,6 +74,10 @@ module GHC.Types.Id.Info ( ppCafInfo, mayHaveCafRefs, cafInfo, setCafInfo, + -- ** The LambdaFormInfo type + LambdaFormInfo(..), + lfInfo, setLFInfo, + -- ** Tick-box Info TickBoxOp(..), TickBoxId, @@ -105,6 +109,8 @@ import GHC.Types.Demand import GHC.Types.Cpr import GHC.Utils.Misc +import GHC.StgToCmm.Types (LambdaFormInfo (..)) + -- infixl so you can say (id `set` a `set` b) infixl 1 `setRuleInfo`, `setArityInfo`, @@ -251,8 +257,10 @@ data IdInfo -- See Note [Specialisations and RULES in IdInfo] unfoldingInfo :: Unfolding, -- ^ The 'Id's unfolding - cafInfo :: CafInfo, + cafInfo :: !CafInfo, -- ^ 'Id' CAF info + -- See Note [Conveying CAF-info and LFInfo between modules] in + -- GHC.StgToCmm.Types. oneShotInfo :: OneShotInfo, -- ^ Info about a lambda-bound variable, if the 'Id' is one inlinePragInfo :: InlinePragma, @@ -271,8 +279,13 @@ data IdInfo -- ^ How this is called. This is the number of arguments to which a -- binding can be eta-expanded without losing any sharing. -- n <=> all calls have at least n arguments - levityInfo :: LevityInfo + levityInfo :: LevityInfo, -- ^ when applied, will this Id ever have a levity-polymorphic type? + lfInfo :: !(Maybe LambdaFormInfo) + -- ^ LambdaFormInfo of the Id. Not necessary, but if we know this we can + -- generate more efficient calling code. See getCallMethod + -- GHC.StgToCmm.Closure and Note [Conveying CAF-info and LFInfo between + -- modules] in GHC.StgToCmm.Types. } -- Setters @@ -295,13 +308,18 @@ setUnfoldingInfo info uf setArityInfo :: IdInfo -> ArityInfo -> IdInfo setArityInfo info ar = info { arityInfo = ar } + setCallArityInfo :: IdInfo -> ArityInfo -> IdInfo setCallArityInfo info ar = info { callArityInfo = ar } + setCafInfo :: IdInfo -> CafInfo -> IdInfo -setCafInfo info caf = info { cafInfo = caf } +setCafInfo info caf = info { cafInfo = caf } + +setLFInfo :: IdInfo -> LambdaFormInfo -> IdInfo +setLFInfo info lf = info { lfInfo = Just lf } setOneShotInfo :: IdInfo -> OneShotInfo -> IdInfo -setOneShotInfo info lb = {-lb `seq`-} info { oneShotInfo = lb } +setOneShotInfo info lb = {-lb `seq`-} info { oneShotInfo = lb } setDemandInfo :: IdInfo -> Demand -> IdInfo setDemandInfo info dd = dd `seq` info { demandInfo = dd } @@ -327,7 +345,8 @@ vanillaIdInfo strictnessInfo = nopSig, cprInfo = topCprSig, callArityInfo = unknownArity, - levityInfo = NoLevityInfo + levityInfo = NoLevityInfo, + lfInfo = Nothing } -- | More informative 'IdInfo' we can use when we know the 'Id' has no CAF references ===================================== compiler/ghc.cabal.in ===================================== @@ -228,7 +228,7 @@ Library GHC.Types.SrcLoc GHC.Types.Unique.Supply GHC.Types.Unique - GHC.Iface.UpdateCafInfos + GHC.Iface.UpdateIdInfos GHC.Types.Var GHC.Types.Var.Env GHC.Types.Var.Set @@ -295,6 +295,7 @@ Library GHC.StgToCmm.Ticky GHC.StgToCmm.Utils GHC.StgToCmm.ExtCode + GHC.StgToCmm.Types GHC.Runtime.Heap.Layout GHC.Core.Arity GHC.Core.FVs ===================================== testsuite/tests/codeGen/should_compile/Makefile ===================================== @@ -64,10 +64,10 @@ T17648: # NoCafRefs) to the interface files. '$(TEST_HC)' $(TEST_HC_OPTS) -dno-typeable-binds -O T17648.hs -v0 '$(TEST_HC)' --show-iface T17648.hi | tr -d '\n\r' | \ - grep -F 'f :: T GHC.Types.Int -> () [HasNoCafRefs, Arity' >/dev/null + grep -F 'f :: T GHC.Types.Int -> () [HasNoCafRefs, LambdaFormInfo' >/dev/null # Second compilation with -fcatch-bottoms, f should be CAFFY '$(TEST_HC)' $(TEST_HC_OPTS) -dno-typeable-binds -O \ -fcatch-bottoms T17648.hs -v0 -fforce-recomp '$(TEST_HC)' --show-iface T17648.hi | tr -d '\n\r' | \ - grep -F 'f :: T GHC.Types.Int -> () [Arity: 1, Strictness' >/dev/null + grep -F 'f :: T GHC.Types.Int -> () [LambdaFormInfo' >/dev/null ===================================== testsuite/tests/codeGen/should_compile/cg009/A.hs ===================================== @@ -0,0 +1,5 @@ +module A where + +newtype A = A Int + +val = A 42 ===================================== testsuite/tests/codeGen/should_compile/cg009/Main.hs ===================================== @@ -0,0 +1,7 @@ +module Main where + +import A + +main = return () + +a = val ===================================== testsuite/tests/codeGen/should_compile/cg009/Makefile ===================================== @@ -0,0 +1,9 @@ +TOP=../../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +# Make sure the LFInfo for an exported, but not directly used newtype +# constructors does not trip up the compiler. +cg009: + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O A.hs -fforce-recomp + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O0 Main.hs -fforce-recomp ===================================== testsuite/tests/codeGen/should_compile/cg009/all.T ===================================== @@ -0,0 +1 @@ +test('cg009', [extra_files(['A.hs','Main.hs'])], makefile_test, ['cg009']) ===================================== testsuite/tests/codeGen/should_compile/cg010/A.hs ===================================== @@ -0,0 +1,4 @@ +module A where + +{-# NOINLINE val #-} +val = Just 42 ===================================== testsuite/tests/codeGen/should_compile/cg010/Main.hs ===================================== @@ -0,0 +1,7 @@ +module Main where + +import A + +main = return () + +a = val ===================================== testsuite/tests/codeGen/should_compile/cg010/Makefile ===================================== @@ -0,0 +1,9 @@ +TOP=../../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +# Make sure LFInfo causes the imported reference to val to get tagged. +cg010: + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O A.hs -fforce-recomp + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O Main.hs -fforce-recomp -ddump-cmm -ddump-to-file + grep "A.val_closure+2" Main.dump-cmm ===================================== testsuite/tests/codeGen/should_compile/cg010/all.T ===================================== @@ -0,0 +1 @@ +test('cg010', [extra_files(['A.hs','Main.hs'])], makefile_test, ['cg010']) ===================================== testsuite/tests/codeGen/should_compile/cg010/cg010.stdout ===================================== @@ -0,0 +1 @@ + const A.val_closure+2; ===================================== testsuite/tests/simplCore/should_compile/Makefile ===================================== @@ -107,7 +107,7 @@ T4201: '$(TEST_HC)' $(TEST_HC_OPTS) -c -O T4201.hs '$(TEST_HC)' $(TEST_HC_OPTS) --show-iface T4201.hi > T4201.list # poor man idea about how to replace GNU grep -B2 "Sym" invocation with pure POSIX tools - for i in `grep -n "Sym" T4201.list |cut -d ':' -f -1`; do head -$$i T4201.list | tail -3 ; done + for i in `grep -n "Sym" T4201.list | cut -d ':' -f -1`; do head -$$i T4201.list | tail -4; done $(RM) -f T4201.list # This one looped as a result of bogus specialisation ===================================== testsuite/tests/simplCore/should_compile/T4201.stdout ===================================== @@ -1,3 +1,4 @@ - [HasNoCafRefs, Arity: 1, Strictness: , + [HasNoCafRefs, LambdaFormInfo: LFReEntrant 1, Arity: 1, + Strictness: , Unfolding: InlineRule (0, True, True) bof `cast` (Sym (N:Foo[0]) ->_R _R)] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ab1111665718e34466f6348175c1afbf34895042 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ab1111665718e34466f6348175c1afbf34895042 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 1 11:58:43 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Fri, 01 May 2020 07:58:43 -0400 Subject: [Git][ghc/ghc][wip/osa1/lfinfo] Cross-module LambdaFormInfo passing Message-ID: <5eac0ef39f1fe_616711ab08a4830213@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/lfinfo at Glasgow Haskell Compiler / GHC Commits: ca6a2571 by Ömer Sinan Ağacan at 2020-05-01T14:58:26+03:00 Cross-module LambdaFormInfo passing - Store LambdaFormInfos of exported Ids in interface files - Use them in importing modules This is for optimization purposes: if we know LambdaFormInfo of imported Ids we can generate more efficient calling code, see `getCallMethod`. Exporting (putting them in interface files or in ModDetails) and importing (reading them from interface files) are both optional. We don't assume known LambdaFormInfos anywhere and do not change how we call Ids with unknown LambdaFormInfos. Runtime, allocation, and residency numbers when building Cabal-the-library (commit 0d4ee7ba3). (Log and .hp files are in the MR: !2842) Runtime: | | GHC HEAD | This patch | Diff | |-----|----------|------------|----------------| | -O0 | 0:35.70 | 0:34.75 | -0.95s, -2.66% | | -O1 | 2:25.21 | 2:25.16 | -0.05s, -0.03% | | -O2 | 2:52.89 | 2:51.25 | -1.63s, -0.9% | Allocations: | | GHC HEAD | This patch | Diff | |-----|-----------------|-----------------|----------------------| | -O0 | 54,872,673,008 | 54,917,849,488 | +45,176,480, +0.08% | | -O1 | 227,080,315,016 | 227,584,483,224 | +504,168,208, +0.22% | | -O2 | 266,085,969,832 | 266,710,115,472 | +624,145,640, +0.23% | Max. residency: NOTE: Residency is measured with extra runtime args: `-i0 -h` which effectively turn all GCs into major GCs, and do GC more often. | | GHC HEAD | This patch | Diff | |-----|----------------------------|------------------------------|----------------------| | -O0 | 416,350,080 (894 samples) | 417,733,152 (892 samples) | +1,383,072, +0.33% | | -O1 | 928,484,840 (2101 samples) | 945,624,664 (2098 samples) | +17,139,824, +1.84% | | -O2 | 991,311,896 (2548 samples) | 1,010,647,088 (2536 samples) | +19,335,192, +1.95% | NoFib results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS 0.0% 0.0% +0.0% +0.0% +0.0% CSD 0.0% 0.0% 0.0% +0.0% +0.0% FS 0.0% 0.0% +0.0% +0.0% +0.0% S 0.0% 0.0% +0.0% +0.0% +0.0% VS 0.0% 0.0% +0.0% +0.0% +0.0% VSD 0.0% 0.0% +0.0% +0.0% +0.1% VSM 0.0% 0.0% +0.0% +0.0% +0.0% anna 0.0% 0.0% -0.3% -0.8% -0.0% ansi 0.0% 0.0% -0.0% -0.0% 0.0% atom 0.0% 0.0% -0.0% -0.0% 0.0% awards 0.0% 0.0% -0.1% -0.3% 0.0% banner 0.0% 0.0% -0.0% -0.0% -0.0% bernouilli 0.0% 0.0% -0.0% -0.0% -0.0% binary-trees 0.0% 0.0% -0.0% -0.0% +0.0% boyer 0.0% 0.0% -0.0% -0.0% 0.0% boyer2 0.0% 0.0% -0.0% -0.0% 0.0% bspt 0.0% 0.0% -0.0% -0.2% 0.0% cacheprof 0.0% 0.0% -0.1% -0.4% +0.0% calendar 0.0% 0.0% -0.0% -0.0% 0.0% cichelli 0.0% 0.0% -0.9% -2.4% 0.0% circsim 0.0% 0.0% -0.0% -0.0% 0.0% clausify 0.0% 0.0% -0.1% -0.3% 0.0% comp_lab_zift 0.0% 0.0% -0.0% -0.0% +0.0% compress 0.0% 0.0% -0.0% -0.0% -0.0% compress2 0.0% 0.0% -0.0% -0.0% 0.0% constraints 0.0% 0.0% -0.1% -0.2% -0.0% cryptarithm1 0.0% 0.0% -0.0% -0.0% 0.0% cryptarithm2 0.0% 0.0% -1.4% -4.1% -0.0% cse 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e1 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e2 0.0% 0.0% -0.0% -0.0% -0.0% dom-lt 0.0% 0.0% -0.1% -0.2% 0.0% eliza 0.0% 0.0% -0.5% -1.5% 0.0% event 0.0% 0.0% -0.0% -0.0% -0.0% exact-reals 0.0% 0.0% -0.1% -0.3% +0.0% exp3_8 0.0% 0.0% -0.0% -0.0% -0.0% expert 0.0% 0.0% -0.3% -1.0% -0.0% fannkuch-redux 0.0% 0.0% +0.0% +0.0% +0.0% fasta 0.0% 0.0% -0.0% -0.0% +0.0% fem 0.0% 0.0% -0.0% -0.0% 0.0% fft 0.0% 0.0% -0.0% -0.0% 0.0% fft2 0.0% 0.0% -0.0% -0.0% 0.0% fibheaps 0.0% 0.0% -0.0% -0.0% +0.0% fish 0.0% 0.0% 0.0% -0.0% +0.0% fluid 0.0% 0.0% -0.4% -1.2% +0.0% fulsom 0.0% 0.0% -0.0% -0.0% 0.0% gamteb 0.0% 0.0% -0.1% -0.3% 0.0% gcd 0.0% 0.0% -0.0% -0.0% 0.0% gen_regexps 0.0% 0.0% -0.0% -0.0% -0.0% genfft 0.0% 0.0% -0.0% -0.0% 0.0% gg 0.0% 0.0% -0.0% -0.0% +0.0% grep 0.0% 0.0% -0.0% -0.0% -0.0% hidden 0.0% 0.0% -0.1% -0.4% -0.0% hpg 0.0% 0.0% -0.2% -0.5% +0.0% ida 0.0% 0.0% -0.0% -0.0% +0.0% infer 0.0% 0.0% -0.3% -0.8% -0.0% integer 0.0% 0.0% -0.0% -0.0% +0.0% integrate 0.0% 0.0% -0.0% -0.0% 0.0% k-nucleotide 0.0% 0.0% -0.0% -0.0% +0.0% kahan 0.0% 0.0% -0.0% -0.0% +0.0% knights 0.0% 0.0% -2.2% -5.4% 0.0% lambda 0.0% 0.0% -0.6% -1.8% 0.0% last-piece 0.0% 0.0% -0.0% -0.0% 0.0% lcss 0.0% 0.0% -0.0% -0.1% 0.0% life 0.0% 0.0% -0.0% -0.1% 0.0% lift 0.0% 0.0% -0.2% -0.6% +0.0% linear 0.0% 0.0% -0.0% -0.0% -0.0% listcompr 0.0% 0.0% -0.0% -0.0% 0.0% listcopy 0.0% 0.0% -0.0% -0.0% 0.0% maillist 0.0% 0.0% -0.1% -0.3% +0.0% mandel 0.0% 0.0% -0.0% -0.0% 0.0% mandel2 0.0% 0.0% -0.0% -0.0% -0.0% mate +0.0% 0.0% -0.0% -0.0% -0.0% minimax 0.0% 0.0% -0.2% -1.0% 0.0% mkhprog 0.0% 0.0% -0.1% -0.2% -0.0% multiplier 0.0% 0.0% -0.0% -0.0% -0.0% n-body 0.0% 0.0% -0.0% -0.0% +0.0% nucleic2 0.0% 0.0% -0.1% -0.2% 0.0% para 0.0% 0.0% -0.0% -0.0% -0.0% paraffins 0.0% 0.0% -0.0% -0.0% 0.0% parser 0.0% 0.0% -0.2% -0.7% 0.0% parstof 0.0% 0.0% -0.0% -0.0% +0.0% pic 0.0% 0.0% -0.0% -0.0% 0.0% pidigits 0.0% 0.0% +0.0% +0.0% +0.0% power 0.0% 0.0% -0.2% -0.6% +0.0% pretty 0.0% 0.0% -0.0% -0.0% -0.0% primes 0.0% 0.0% -0.0% -0.0% 0.0% primetest 0.0% 0.0% -0.0% -0.0% -0.0% prolog 0.0% 0.0% -0.3% -1.1% 0.0% puzzle 0.0% 0.0% -0.0% -0.0% 0.0% queens 0.0% 0.0% -0.0% -0.0% +0.0% reptile 0.0% 0.0% -0.0% -0.0% 0.0% reverse-complem 0.0% 0.0% -0.0% -0.0% +0.0% rewrite 0.0% 0.0% -0.7% -2.5% -0.0% rfib 0.0% 0.0% -0.0% -0.0% 0.0% rsa 0.0% 0.0% -0.0% -0.0% 0.0% scc 0.0% 0.0% -0.1% -0.2% -0.0% sched 0.0% 0.0% -0.0% -0.0% -0.0% scs 0.0% 0.0% -1.0% -2.6% +0.0% simple 0.0% 0.0% +0.0% -0.0% +0.0% solid 0.0% 0.0% -0.0% -0.0% 0.0% sorting 0.0% 0.0% -0.6% -1.6% 0.0% spectral-norm 0.0% 0.0% +0.0% 0.0% +0.0% sphere 0.0% 0.0% -0.0% -0.0% -0.0% symalg 0.0% 0.0% -0.0% -0.0% +0.0% tak 0.0% 0.0% -0.0% -0.0% 0.0% transform 0.0% 0.0% -0.0% -0.0% 0.0% treejoin 0.0% 0.0% -0.0% -0.0% 0.0% typecheck 0.0% 0.0% -0.0% -0.0% +0.0% veritas +0.0% 0.0% -0.2% -0.4% +0.0% wang 0.0% 0.0% -0.0% -0.0% 0.0% wave4main 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 0.0% 0.0% -0.0% -0.0% +0.0% x2n1 0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min 0.0% 0.0% -2.2% -5.4% -0.0% Max +0.0% 0.0% +0.0% +0.0% +0.1% Geometric Mean -0.0% -0.0% -0.1% -0.3% +0.0% Metric increases micro benchmarks tracked in #17686: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 Co-authored-by: Andreas Klebinger <klebinger.andreas at gmx.at> - - - - - 28 changed files: - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Iface/UpdateCafInfos.hs → compiler/GHC/Iface/UpdateIdInfos.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Runtime/Heap/Layout.hs - compiler/GHC/StgToCmm.hs - compiler/GHC/StgToCmm/Closure.hs - + compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/ghc.cabal.in - testsuite/tests/codeGen/should_compile/Makefile - + testsuite/tests/codeGen/should_compile/cg009/A.hs - + testsuite/tests/codeGen/should_compile/cg009/Main.hs - + testsuite/tests/codeGen/should_compile/cg009/Makefile - + testsuite/tests/codeGen/should_compile/cg009/all.T - + testsuite/tests/codeGen/should_compile/cg010/A.hs - + testsuite/tests/codeGen/should_compile/cg010/Main.hs - + testsuite/tests/codeGen/should_compile/cg010/Makefile - + testsuite/tests/codeGen/should_compile/cg010/all.T - + testsuite/tests/codeGen/should_compile/cg010/cg010.stdout - testsuite/tests/simplCore/should_compile/Makefile - testsuite/tests/simplCore/should_compile/T4201.stdout Changes: ===================================== compiler/GHC/CoreToIface.hs ===================================== @@ -34,13 +34,14 @@ module GHC.CoreToIface , toIfaceIdDetails , toIfaceIdInfo , toIfUnfolding - , toIfaceOneShot , toIfaceTickish , toIfaceBind , toIfaceAlt , toIfaceCon , toIfaceApp , toIfaceVar + -- * Other stuff + , toIfaceLFInfo ) where #include "HsVersions.h" @@ -51,6 +52,7 @@ import GHC.Iface.Syntax import GHC.Core.DataCon import GHC.Types.Id import GHC.Types.Id.Info +import GHC.StgToCmm.Types import GHC.Core import GHC.Core.TyCon hiding ( pprPromotionQuote ) import GHC.Core.Coercion.Axiom @@ -616,6 +618,34 @@ toIfaceVar v where name = idName v +--------------------- +toIfaceLFInfo :: Name -> LambdaFormInfo -> IfaceLFInfo +toIfaceLFInfo nm lfi = case lfi of + LFReEntrant top_lvl arity no_fvs _arg_descr -> + -- Exported LFReEntrant closures are top level, and top-level closures + -- don't have free variables + ASSERT2(isTopLevel top_lvl, ppr nm) + ASSERT2(no_fvs, ppr nm) + IfLFReEntrant arity + LFThunk top_lvl no_fvs updatable sfi _mb_fun -> + -- Exported LFThunk closures are top level (which don't have free + -- variables), updatable, and non-standard (see cgTopRhsClosure) + ASSERT2(isTopLevel top_lvl, ppr nm) + ASSERT2(no_fvs, ppr nm) + ASSERT2(updatable, ppr nm) + ASSERT2(sfi == NonStandardThunk, ppr nm) + IfLFUnknown + LFCon dc -> + IfLFCon (dataConName dc) + LFUnknown _might_be_function -> + -- The argument can be derived from the type via might_be_a_function so we + -- don't serialize it + IfLFUnknown + LFUnlifted -> + IfLFUnlifted + LFLetNoEscape -> + panic "toIfaceLFInfo: LFLetNoEscape" + {- Note [Inlining and hs-boot files] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider this example (#10083, #12789): ===================================== compiler/GHC/Driver/Hooks.hs ===================================== @@ -55,6 +55,7 @@ import GHC.Stg.Syntax import GHC.Data.Stream import GHC.Cmm import GHC.Hs.Extension +import GHC.StgToCmm.Types (ModuleLFInfos) import Data.Maybe @@ -109,7 +110,7 @@ data Hooks = Hooks -> IO (Maybe HValue)) , createIservProcessHook :: Maybe (CreateProcess -> IO ProcessHandle) , stgToCmmHook :: Maybe (DynFlags -> Module -> [TyCon] -> CollectedCCs - -> [CgStgTopBinding] -> HpcInfo -> Stream IO CmmGroup ()) + -> [CgStgTopBinding] -> HpcInfo -> Stream IO CmmGroup ModuleLFInfos) , cmmToRawCmmHook :: forall a . Maybe (DynFlags -> Maybe Module -> Stream IO CmmGroupSRTs a -> IO (Stream IO RawCmmGroup a)) } ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -132,7 +132,6 @@ import qualified GHC.StgToCmm as StgToCmm ( codeGen ) import GHC.Types.CostCentre import GHC.Core.TyCon import GHC.Types.Name -import GHC.Types.Name.Set import GHC.Cmm import GHC.Cmm.Parser ( parseCmmFile ) import GHC.Cmm.Info.Build @@ -147,6 +146,7 @@ import GHC.Tc.Utils.Env import GHC.Builtin.Names import GHC.Driver.Plugins import GHC.Runtime.Loader ( initializePlugins ) +import GHC.StgToCmm.Types (CgInfos (..), ModuleLFInfos) import GHC.Driver.Session import GHC.Utils.Error @@ -175,6 +175,7 @@ import qualified Data.Set as S import Data.Set (Set) import Data.Functor import Control.DeepSeq (force) +import Data.Bifunctor (first) import GHC.Iface.Ext.Ast ( mkHieFile ) import GHC.Iface.Ext.Types ( getAsts, hie_asts, hie_module ) @@ -1385,7 +1386,7 @@ hscWriteIface dflags iface no_change mod_location = do -- | Compile to hard-code. hscGenHardCode :: HscEnv -> CgGuts -> ModLocation -> FilePath - -> IO (FilePath, Maybe FilePath, [(ForeignSrcLang, FilePath)], NameSet) + -> IO (FilePath, Maybe FilePath, [(ForeignSrcLang, FilePath)], CgInfos) -- ^ @Just f@ <=> _stub.c is f hscGenHardCode hsc_env cgguts location output_filename = do let CgGuts{ -- This is the last use of the ModGuts in a compilation. @@ -1444,11 +1445,11 @@ hscGenHardCode hsc_env cgguts location output_filename = do return a rawcmms1 = Stream.mapM dump rawcmms0 - (output_filename, (_stub_h_exists, stub_c_exists), foreign_fps, caf_infos) + (output_filename, (_stub_h_exists, stub_c_exists), foreign_fps, cg_infos) <- {-# SCC "codeOutput" #-} codeOutput dflags this_mod output_filename location foreign_stubs foreign_files dependencies rawcmms1 - return (output_filename, stub_c_exists, foreign_fps, caf_infos) + return (output_filename, stub_c_exists, foreign_fps, cg_infos) hscInteractive :: HscEnv @@ -1542,7 +1543,7 @@ doCodeGen :: HscEnv -> Module -> [TyCon] -> CollectedCCs -> [StgTopBinding] -> HpcInfo - -> IO (Stream IO CmmGroupSRTs NameSet) + -> IO (Stream IO CmmGroupSRTs CgInfos) -- Note we produce a 'Stream' of CmmGroups, so that the -- backend can be run incrementally. Otherwise it generates all -- the C-- up front, which has a significant space cost. @@ -1554,7 +1555,7 @@ doCodeGen hsc_env this_mod data_tycons dumpIfSet_dyn dflags Opt_D_dump_stg_final "Final STG:" FormatSTG (pprGenStgTopBindings stg_binds_w_fvs) - let cmm_stream :: Stream IO CmmGroup () + let cmm_stream :: Stream IO CmmGroup ModuleLFInfos -- See Note [Forcing of stg_binds] cmm_stream = stg_binds_w_fvs `seqList` {-# SCC "StgToCmm" #-} lookupHook stgToCmmHook StgToCmm.codeGen dflags dflags this_mod data_tycons @@ -1573,10 +1574,14 @@ doCodeGen hsc_env this_mod data_tycons ppr_stream1 = Stream.mapM dump1 cmm_stream - pipeline_stream = - {-# SCC "cmmPipeline" #-} - Stream.mapAccumL (cmmPipeline hsc_env) (emptySRT this_mod) ppr_stream1 - <&> (srtMapNonCAFs . moduleSRTMap) + pipeline_stream :: Stream IO CmmGroupSRTs CgInfos + pipeline_stream = do + (non_cafs, lf_infos) <- + {-# SCC "cmmPipeline" #-} + Stream.mapAccumL_ (cmmPipeline hsc_env) (emptySRT this_mod) ppr_stream1 + <&> first (srtMapNonCAFs . moduleSRTMap) + + return CgInfos{ cgNonCafs = non_cafs, cgLFInfos = lf_infos } dump2 a = do unless (null a) $ ===================================== compiler/GHC/Driver/Pipeline.hs ===================================== @@ -70,7 +70,7 @@ import GHC.Settings import GHC.Data.Bag ( unitBag ) import GHC.Data.FastString ( mkFastString ) import GHC.Iface.Make ( mkFullIface ) -import GHC.Iface.UpdateCafInfos ( updateModDetailsCafInfos ) +import GHC.Iface.UpdateIdInfos ( updateModDetailsIdInfos ) import GHC.Utils.Exception as Exception import System.Directory @@ -1178,12 +1178,12 @@ runPhase (HscOut src_flavour mod_name result) _ dflags = do PipeState{hsc_env=hsc_env'} <- getPipeState - (outputFilename, mStub, foreign_files, caf_infos) <- liftIO $ + (outputFilename, mStub, foreign_files, cg_infos) <- liftIO $ hscGenHardCode hsc_env' cgguts mod_location output_fn - final_iface <- liftIO (mkFullIface hsc_env'{hsc_dflags=iface_dflags} partial_iface (Just caf_infos)) - let final_mod_details = {-# SCC updateModDetailsCafInfos #-} - updateModDetailsCafInfos iface_dflags caf_infos mod_details + final_iface <- liftIO (mkFullIface hsc_env'{hsc_dflags=iface_dflags} partial_iface (Just cg_infos)) + let final_mod_details = {-# SCC updateModDetailsIdInfos #-} + updateModDetailsIdInfos iface_dflags cg_infos mod_details setIface final_iface final_mod_details -- See Note [Writing interface files] ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -38,6 +38,7 @@ import GHC.Core.Coercion.Axiom import GHC.Core.ConLike import GHC.Core.DataCon import GHC.Core.Type +import GHC.StgToCmm.Types (CgInfos (..)) import GHC.Tc.Utils.TcType import GHC.Core.InstEnv import GHC.Core.FamInstEnv @@ -98,15 +99,19 @@ mkPartialIface hsc_env mod_details = mkIface_ hsc_env this_mod hsc_src used_th deps rdr_env fix_env warns hpc_info self_trust safe_mode usages doc_hdr decl_docs arg_docs mod_details --- | Fully instantiate a interface --- Adds fingerprints and potentially code generator produced information. -mkFullIface :: HscEnv -> PartialModIface -> Maybe NameSet -> IO ModIface -mkFullIface hsc_env partial_iface mb_non_cafs = do +-- | Fully instantiate an interface. Adds fingerprints and potentially code +-- generator produced information. +-- +-- CgInfos is not available when not generating code (-fno-code), or when not +-- generating interface pragmas (-fomit-interface-pragmas). See also +-- Note [Conveying CAF-info and LFInfo between modules] in GHC.StgToCmm.Types. +mkFullIface :: HscEnv -> PartialModIface -> Maybe CgInfos -> IO ModIface +mkFullIface hsc_env partial_iface mb_cg_infos = do let decls | gopt Opt_OmitInterfacePragmas (hsc_dflags hsc_env) = mi_decls partial_iface | otherwise - = updateDeclCafInfos (mi_decls partial_iface) mb_non_cafs + = updateDecl (mi_decls partial_iface) mb_cg_infos full_iface <- {-# SCC "addFingerprints" #-} @@ -117,15 +122,23 @@ mkFullIface hsc_env partial_iface mb_non_cafs = do return full_iface -updateDeclCafInfos :: [IfaceDecl] -> Maybe NameSet -> [IfaceDecl] -updateDeclCafInfos decls Nothing = decls -updateDeclCafInfos decls (Just non_cafs) = map update_decl decls +updateDecl :: [IfaceDecl] -> Maybe CgInfos -> [IfaceDecl] +updateDecl decls Nothing = decls +updateDecl decls (Just CgInfos{ cgNonCafs = non_cafs, cgLFInfos = lf_infos }) = map update_decl decls where + update_decl (IfaceId nm ty details infos) + | let not_caffy = elemNameSet nm non_cafs + , let mb_lf_info = lookupNameEnv lf_infos nm + , WARN( isNothing mb_lf_info, text "Name without LFInfo:" <+> ppr nm ) True + -- Only allocate a new IfaceId if we're going to update the infos + , isJust mb_lf_info || not_caffy + = IfaceId nm ty details $ + (if not_caffy then (HsNoCafRefs :) else id) + (case mb_lf_info of + Nothing -> infos -- LFInfos not available when building .cmm files + Just lf_info -> HsLFInfo (toIfaceLFInfo nm lf_info) : infos) + update_decl decl - | IfaceId nm ty details infos <- decl - , elemNameSet nm non_cafs - = IfaceId nm ty details (HsNoCafRefs : infos) - | otherwise = decl -- | Make an interface from the results of typechecking only. Useful ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -22,6 +22,8 @@ module GHC.Iface.Syntax ( IfaceAxBranch(..), IfaceTyConParent(..), IfaceCompleteMatch(..), + IfaceLFInfo(..), + IfaceStandardFormInfo(..), -- * Binding names IfaceTopBndr, @@ -30,6 +32,7 @@ module GHC.Iface.Syntax ( -- Misc ifaceDeclImplicitBndrs, visibleIfConDecls, ifaceDeclFingerprints, + tcStandardFormInfo, -- Free Names freeNamesIfDecl, freeNamesIfRule, freeNamesIfFamInst, @@ -67,15 +70,18 @@ import GHC.Utils.Binary import GHC.Data.BooleanFormula ( BooleanFormula, pprBooleanFormula, isTrue ) import GHC.Types.Var( VarBndr(..), binderVar ) import GHC.Core.TyCon ( Role (..), Injectivity(..), tyConBndrVisArgFlag ) -import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, debugIsOn ) +import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, debugIsOn, + seqList ) import GHC.Core.DataCon (SrcStrictness(..), SrcUnpackedness(..)) import GHC.Utils.Lexeme (isLexSym) import GHC.Builtin.Types ( constraintKindTyConName ) -import GHC.Utils.Misc (seqList) +import GHC.StgToCmm.Types import Control.Monad import System.IO.Unsafe import Control.DeepSeq +import Data.Word +import Data.Bits infixl 3 &&& @@ -114,7 +120,8 @@ data IfaceDecl = IfaceId { ifName :: IfaceTopBndr, ifType :: IfaceType, ifIdDetails :: IfaceIdDetails, - ifIdInfo :: IfaceIdInfo } + ifIdInfo :: IfaceIdInfo + } | IfaceData { ifName :: IfaceTopBndr, -- Type constructor ifBinders :: [IfaceTyConBinder], @@ -348,6 +355,7 @@ data IfaceInfoItem IfaceUnfolding -- See Note [Expose recursive functions] | HsNoCafRefs | HsLevity -- Present <=> never levity polymorphic + | HsLFInfo IfaceLFInfo -- NB: Specialisations and rules come in separately and are -- only later attached to the Id. Partial reason: some are orphans. @@ -379,6 +387,70 @@ data IfaceIdDetails | IfRecSelId (Either IfaceTyCon IfaceDecl) Bool | IfDFunId +-- | Iface type for LambdaFormInfo. Fields not relevant for imported Ids are +-- omitted in this type. +-- +-- Thunks are represented as LFUnknown: top-level thunks are never single-entry, +-- and for updatable thunks LFThunk and LFUnknown calling convention is the +-- same, see GHC.StgToCmm.Closure.getCallMethod. +data IfaceLFInfo + = IfLFReEntrant !RepArity + | IfLFCon !Name + | IfLFUnknown + | IfLFUnlifted + -- Generally, top-level things can't be unlifted, but we have an exception + -- for literal strings -- see Note [Core top-level string literals] in + -- GHC.Core + +tcStandardFormInfo :: IfaceStandardFormInfo -> StandardFormInfo +tcStandardFormInfo (IfStandardFormInfo w) + | testBit w 0 = NonStandardThunk + | otherwise = con field + where + field = fromIntegral (w `unsafeShiftR` 2) + con + | testBit w 1 = ApThunk + | otherwise = SelectorThunk + +instance Outputable IfaceLFInfo where + ppr (IfLFReEntrant arity) = + text "LFReEntrant" <+> ppr arity + + ppr (IfLFCon con) = + text "LFCon" <> brackets (ppr con) + + ppr IfLFUnlifted = + text "LFUnlifted" + + ppr IfLFUnknown = + text "LFUnknown" + +newtype IfaceStandardFormInfo = IfStandardFormInfo Word16 + +instance Binary IfaceStandardFormInfo where + put_ bh (IfStandardFormInfo w) = put_ bh (w :: Word16) + get bh = IfStandardFormInfo <$> (get bh :: IO Word16) + +instance Binary IfaceLFInfo where + put_ bh (IfLFReEntrant arity) = do + putByte bh 0 + put_ bh arity + put_ bh (IfLFCon con_name) = do + putByte bh 1 + put_ bh con_name + put_ bh IfLFUnknown = do + putByte bh 2 + put_ bh IfLFUnlifted = + putByte bh 3 + get bh = do + tag <- getByte bh + case tag of + 0 -> IfLFReEntrant <$> get bh + 1 -> IfLFCon <$> get bh + 2 -> pure IfLFUnknown + 3 -> pure IfLFUnlifted + _ -> panic "Invalid byte" + {- Note [Versioning of instances] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1393,6 +1465,7 @@ instance Outputable IfaceInfoItem where ppr (HsCpr cpr) = text "CPR:" <+> ppr cpr ppr HsNoCafRefs = text "HasNoCafRefs" ppr HsLevity = text "Never levity-polymorphic" + ppr (HsLFInfo lf_info) = text "LambdaFormInfo:" <+> ppr lf_info instance Outputable IfaceJoinInfo where ppr IfaceNotJoinPoint = empty @@ -1853,7 +1926,7 @@ instance Binary IfaceDecl where get bh = do h <- getByte bh case h of - 0 -> do name <- get bh + 0 -> do name <- get bh ~(ty, details, idinfo) <- lazyGet bh -- See Note [Lazy deserialization of IfaceId] return (IfaceId name ty details idinfo) @@ -2153,6 +2226,8 @@ instance Binary IfaceInfoItem where put_ bh HsNoCafRefs = putByte bh 4 put_ bh HsLevity = putByte bh 5 put_ bh (HsCpr cpr) = putByte bh 6 >> put_ bh cpr + put_ bh (HsLFInfo lf_info) = putByte bh 7 >> put_ bh lf_info + get bh = do h <- getByte bh case h of @@ -2164,7 +2239,8 @@ instance Binary IfaceInfoItem where 3 -> liftM HsInline $ get bh 4 -> return HsNoCafRefs 5 -> return HsLevity - _ -> HsCpr <$> get bh + 6 -> HsCpr <$> get bh + _ -> HsLFInfo <$> get bh instance Binary IfaceUnfolding where put_ bh (IfCoreUnfold s e) = do @@ -2495,6 +2571,7 @@ instance NFData IfaceInfoItem where HsNoCafRefs -> () HsLevity -> () HsCpr cpr -> cpr `seq` () + HsLFInfo lf_info -> lf_info `seq` () -- TODO: seq further? instance NFData IfaceUnfolding where rnf = \case ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -123,6 +123,9 @@ data IfaceOneShot -- See Note [Preserve OneShotInfo] in CoreTicy = IfaceNoOneShot -- and Note [The oneShot function] in GHC.Types.Id.Make | IfaceOneShot +instance Outputable IfaceOneShot where + ppr IfaceNoOneShot = text "NoOneShotInfo" + ppr IfaceOneShot = text "OneShot" {- %************************************************************************ ===================================== compiler/GHC/Iface/UpdateCafInfos.hs → compiler/GHC/Iface/UpdateIdInfos.hs ===================================== @@ -1,38 +1,42 @@ {-# LANGUAGE CPP, BangPatterns, Strict, RecordWildCards #-} -module GHC.Iface.UpdateCafInfos - ( updateModDetailsCafInfos +module GHC.Iface.UpdateIdInfos + ( updateModDetailsIdInfos ) where import GHC.Prelude import GHC.Core +import GHC.Core.InstEnv import GHC.Driver.Session import GHC.Driver.Types +import GHC.StgToCmm.Types (CgInfos (..)) import GHC.Types.Id import GHC.Types.Id.Info -import GHC.Core.InstEnv import GHC.Types.Name.Env import GHC.Types.Name.Set -import GHC.Utils.Misc import GHC.Types.Var +import GHC.Utils.Misc import GHC.Utils.Outputable #include "HsVersions.h" --- | Update CafInfos of all occurences (in rules, unfoldings, class instances) -updateModDetailsCafInfos +-- | Update CafInfos and LFInfos of all occurences (in rules, unfoldings, class +-- instances). +-- +-- See Note [Conveying CAF-info and LFInfo between modules] in +-- GHC.StgToCmm.Types. +updateModDetailsIdInfos :: DynFlags - -> NameSet -- ^ Non-CAFFY names in the module. Names not in this set are CAFFY. + -> CgInfos -> ModDetails -- ^ ModDetails to update -> ModDetails -updateModDetailsCafInfos dflags _ mod_details +updateModDetailsIdInfos dflags _ mod_details | gopt Opt_OmitInterfacePragmas dflags = mod_details -updateModDetailsCafInfos _ non_cafs mod_details = - {- pprTrace "updateModDetailsCafInfos" (text "non_cafs:" <+> ppr non_cafs) $ -} +updateModDetailsIdInfos _ cg_infos mod_details = let ModDetails{ md_types = type_env -- for unfoldings , md_insts = insts @@ -40,11 +44,11 @@ updateModDetailsCafInfos _ non_cafs mod_details = } = mod_details -- type TypeEnv = NameEnv TyThing - ~type_env' = mapNameEnv (updateTyThingCafInfos type_env' non_cafs) type_env + ~type_env' = mapNameEnv (updateTyThingIdInfos type_env' cg_infos) type_env -- Not strict! - !insts' = strictMap (updateInstCafInfos type_env' non_cafs) insts - !rules' = strictMap (updateRuleCafInfos type_env') rules + !insts' = strictMap (updateInstIdInfos type_env' cg_infos) insts + !rules' = strictMap (updateRuleIdInfos type_env') rules in mod_details{ md_types = type_env' , md_insts = insts' @@ -55,28 +59,28 @@ updateModDetailsCafInfos _ non_cafs mod_details = -- Rules -------------------------------------------------------------------------------- -updateRuleCafInfos :: TypeEnv -> CoreRule -> CoreRule -updateRuleCafInfos _ rule at BuiltinRule{} = rule -updateRuleCafInfos type_env Rule{ .. } = Rule { ru_rhs = updateGlobalIds type_env ru_rhs, .. } +updateRuleIdInfos :: TypeEnv -> CoreRule -> CoreRule +updateRuleIdInfos _ rule at BuiltinRule{} = rule +updateRuleIdInfos type_env Rule{ .. } = Rule { ru_rhs = updateGlobalIds type_env ru_rhs, .. } -------------------------------------------------------------------------------- -- Instances -------------------------------------------------------------------------------- -updateInstCafInfos :: TypeEnv -> NameSet -> ClsInst -> ClsInst -updateInstCafInfos type_env non_cafs = - updateClsInstDFun (updateIdUnfolding type_env . updateIdCafInfo non_cafs) +updateInstIdInfos :: TypeEnv -> CgInfos -> ClsInst -> ClsInst +updateInstIdInfos type_env cg_infos = + updateClsInstDFun (updateIdUnfolding type_env . updateIdInfo cg_infos) -------------------------------------------------------------------------------- -- TyThings -------------------------------------------------------------------------------- -updateTyThingCafInfos :: TypeEnv -> NameSet -> TyThing -> TyThing +updateTyThingIdInfos :: TypeEnv -> CgInfos -> TyThing -> TyThing -updateTyThingCafInfos type_env non_cafs (AnId id) = - AnId (updateIdUnfolding type_env (updateIdCafInfo non_cafs id)) +updateTyThingIdInfos type_env cg_infos (AnId id) = + AnId (updateIdUnfolding type_env (updateIdInfo cg_infos id)) -updateTyThingCafInfos _ _ other = other -- AConLike, ATyCon, ACoAxiom +updateTyThingIdInfos _ _ other = other -- AConLike, ATyCon, ACoAxiom -------------------------------------------------------------------------------- -- Unfoldings @@ -95,13 +99,18 @@ updateIdUnfolding type_env id = -- Expressions -------------------------------------------------------------------------------- -updateIdCafInfo :: NameSet -> Id -> Id -updateIdCafInfo non_cafs id - | idName id `elemNameSet` non_cafs - = -- pprTrace "updateIdCafInfo" (text "Marking" <+> ppr id <+> parens (ppr (idName id)) <+> text "as non-CAFFY") $ - id `setIdCafInfo` NoCafRefs - | otherwise - = id +updateIdInfo :: CgInfos -> Id -> Id +updateIdInfo CgInfos{ cgNonCafs = non_cafs, cgLFInfos = lf_infos } id = + let + not_caffy = elemNameSet (idName id) non_cafs + mb_lf_info = lookupNameEnv lf_infos (idName id) + + id1 = if not_caffy then setIdCafInfo id NoCafRefs else id + id2 = case mb_lf_info of + Nothing -> id1 + Just lf_info -> setIdLFInfo id1 lf_info + in + id2 -------------------------------------------------------------------------------- @@ -116,7 +125,7 @@ updateGlobalIds env e = go env e case lookupNameEnv env (varName var) of Nothing -> var Just (AnId id) -> id - Just other -> pprPanic "GHC.Iface.UpdateCafInfos.updateGlobalIds" $ + Just other -> pprPanic "UpdateCafInfos.updateGlobalIds" $ text "Found a non-Id for Id Name" <+> ppr (varName var) $$ nest 4 (text "Id:" <+> ppr var $$ text "TyThing:" <+> ppr other) ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -19,7 +19,8 @@ module GHC.IfaceToCore ( tcIfaceDecl, tcIfaceInst, tcIfaceFamInst, tcIfaceRules, tcIfaceAnnotations, tcIfaceCompleteSigs, tcIfaceExpr, -- Desired by HERMIT (#7683) - tcIfaceGlobal + tcIfaceGlobal, + tcIfaceOneShot ) where #include "HsVersions.h" @@ -30,6 +31,8 @@ import GHC.Builtin.Types.Literals(typeNatCoAxiomRules) import GHC.Iface.Syntax import GHC.Iface.Load import GHC.Iface.Env +import GHC.StgToCmm.Types +import GHC.StgToCmm.Closure (might_be_a_function) import GHC.Tc.TyCl.Build import GHC.Tc.Utils.Monad import GHC.Tc.Utils.TcType @@ -1464,8 +1467,7 @@ tcIdInfo ignore_prags toplvl name ty info = do let init_info | if_boot lcl_env = vanillaIdInfo `setUnfoldingInfo` BootUnfolding | otherwise = vanillaIdInfo - let needed = needed_prags info - foldlM tcPrag init_info needed + foldlM tcPrag init_info (needed_prags info) where needed_prags :: [IfaceInfoItem] -> [IfaceInfoItem] needed_prags items @@ -1485,6 +1487,9 @@ tcIdInfo ignore_prags toplvl name ty info = do tcPrag info (HsCpr cpr) = return (info `setCprInfo` cpr) tcPrag info (HsInline prag) = return (info `setInlinePragInfo` prag) tcPrag info HsLevity = return (info `setNeverLevPoly` ty) + tcPrag info (HsLFInfo lf_info) = do + lf_info <- tcLFInfo ty lf_info + return (info `setLFInfo` lf_info) -- The next two are lazy, so they don't transitively suck stuff in tcPrag info (HsUnfold lb if_unf) @@ -1497,6 +1502,29 @@ tcJoinInfo :: IfaceJoinInfo -> Maybe JoinArity tcJoinInfo (IfaceJoinPoint ar) = Just ar tcJoinInfo IfaceNotJoinPoint = Nothing +tcLFInfo :: Type -> IfaceLFInfo -> IfL LambdaFormInfo +tcLFInfo ty lfi = case lfi of + IfLFReEntrant rep_arity -> + -- LFReEntrant closures in interface files are guaranteed to + -- + -- - Be top-level, as only top-level closures are exported. + -- - Have no free variables, as only non-top-level closures have free + -- variables + -- - Don't have ArgDescrs, as ArgDescr is used when generating code for + -- the closure + -- + -- These invariants are checked when generating LFInfos in toIfaceLFInfo. + return (LFReEntrant TopLevel rep_arity True ArgUnknown) + + IfLFUnlifted -> + return LFUnlifted + + IfLFCon con_name -> + LFCon <$!> tcIfaceDataCon con_name + + IfLFUnknown -> + return (LFUnknown (might_be_a_function ty)) + tcUnfolding :: TopLevelFlag -> Name -> Type -> IdInfo -> IfaceUnfolding -> IfL Unfolding tcUnfolding toplvl name _ info (IfCoreUnfold stable if_expr) = do { dflags <- getDynFlags @@ -1508,7 +1536,7 @@ tcUnfolding toplvl name _ info (IfCoreUnfold stable if_expr) Just expr -> mkFinalUnfolding dflags unf_src strict_sig expr } where - -- Strictness should occur before unfolding! + -- Strictness should occur before unfolding! strict_sig = strictnessInfo info tcUnfolding toplvl name _ _ (IfCompulsory if_expr) @@ -1583,6 +1611,10 @@ tcPragExpr is_compulsory toplvl name expr -- It's OK to use nonDetEltsUFM here because we immediately forget -- the ordering by creating a set +tcIfaceOneShot :: IfaceOneShot -> OneShotInfo +tcIfaceOneShot IfaceNoOneShot = NoOneShotInfo +tcIfaceOneShot IfaceOneShot = OneShotLam + {- ************************************************************************ * * ===================================== compiler/GHC/Runtime/Heap/Layout.hs ===================================== @@ -51,6 +51,7 @@ import GHC.Driver.Session import GHC.Utils.Outputable import GHC.Platform import GHC.Data.FastString +import GHC.StgToCmm.Types import Data.Word import Data.Bits @@ -64,9 +65,6 @@ import Data.ByteString (ByteString) ************************************************************************ -} --- | Word offset, or word count -type WordOff = Int - -- | Byte offset, or byte count type ByteOff = Int @@ -196,29 +194,6 @@ type ConstrDescription = ByteString -- result of dataConIdentity type FunArity = Int type SelectorOffset = Int -------------------------- --- We represent liveness bitmaps as a Bitmap (whose internal --- representation really is a bitmap). These are pinned onto case return --- vectors to indicate the state of the stack for the garbage collector. --- --- In the compiled program, liveness bitmaps that fit inside a single --- word (StgWord) are stored as a single word, while larger bitmaps are --- stored as a pointer to an array of words. - -type Liveness = [Bool] -- One Bool per word; True <=> non-ptr or dead - -- False <=> ptr - -------------------------- --- An ArgDescr describes the argument pattern of a function - -data ArgDescr - = ArgSpec -- Fits one of the standard patterns - !Int -- RTS type identifier ARG_P, ARG_N, ... - - | ArgGen -- General case - Liveness -- Details about the arguments - - ----------------------------------------------------------------------------- -- Construction @@ -545,10 +520,6 @@ instance Outputable SMRep where ppr (RTSRep ty rep) = text "tag:" <> ppr ty <+> ppr rep -instance Outputable ArgDescr where - ppr (ArgSpec n) = text "ArgSpec" <+> ppr n - ppr (ArgGen ls) = text "ArgGen" <+> ppr ls - pprTypeInfo :: ClosureTypeInfo -> SDoc pprTypeInfo (Constr tag descr) = text "Con" <+> ===================================== compiler/GHC/StgToCmm.hs ===================================== @@ -1,5 +1,6 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-} +{-# LANGUAGE BangPatterns #-} ----------------------------------------------------------------------------- -- @@ -25,6 +26,7 @@ import GHC.StgToCmm.Utils import GHC.StgToCmm.Closure import GHC.StgToCmm.Hpc import GHC.StgToCmm.Ticky +import GHC.StgToCmm.Types (ModuleLFInfos) import GHC.Cmm import GHC.Cmm.Utils @@ -47,6 +49,8 @@ import GHC.Data.Stream import GHC.Types.Basic import GHC.Types.Var.Set ( isEmptyDVarSet ) import GHC.SysTools.FileCleanup +import GHC.Types.Unique.FM +import GHC.Types.Name.Env import GHC.Data.OrdList import GHC.Cmm.Graph @@ -63,7 +67,8 @@ codeGen :: DynFlags -> CollectedCCs -- (Local/global) cost-centres needing declaring/registering. -> [CgStgTopBinding] -- Bindings to convert -> HpcInfo - -> Stream IO CmmGroup () -- Output as a stream, so codegen can + -> Stream IO CmmGroup ModuleLFInfos + -- Output as a stream, so codegen can -- be interleaved with output codeGen dflags this_mod data_tycons @@ -105,6 +110,21 @@ codeGen dflags this_mod data_tycons mapM_ (cg . cgDataCon) (tyConDataCons tycon) ; mapM_ do_tycon data_tycons + + ; cg_id_infos <- cgs_binds <$> liftIO (readIORef cgref) + + ; let extract_lf_info info = (name, lf) + where + !id = cg_id info + !name = idName id + !lf = cg_lf info + + -- LambdaFormInfos to be used in importing modules to generate more + -- efficient caling code. See Note [Conveying CAF-info and LFInfo + -- between modules] in GHC.StgToCmm.Types. + ; let !generatedInfo = mkNameEnv (Prelude.map extract_lf_info (eltsUFM cg_id_infos)) + + ; return generatedInfo } --------------------------------------------------------------- ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -55,6 +55,8 @@ module GHC.StgToCmm.Closure ( blackHoleOnEntry, -- Needs LambdaFormInfo and SMRep isStaticClosure, -- Needs SMPre + might_be_a_function, + -- * InfoTables mkDataConInfoTable, cafBlackHoleInfoTable, @@ -70,6 +72,7 @@ import GHC.Stg.Syntax import GHC.Runtime.Heap.Layout import GHC.Cmm import GHC.Cmm.Ppr.Expr() -- For Outputable instances +import GHC.StgToCmm.Types import GHC.Types.CostCentre import GHC.Cmm.BlockId @@ -188,76 +191,6 @@ addArgReps = map (\arg -> let arg' = fromNonVoid arg argPrimRep :: StgArg -> PrimRep argPrimRep arg = typePrimRep1 (stgArgType arg) - ------------------------------------------------------------------------------ --- LambdaFormInfo ------------------------------------------------------------------------------ - --- Information about an identifier, from the code generator's point of --- view. Every identifier is bound to a LambdaFormInfo in the --- environment, which gives the code generator enough info to be able to --- tail call or return that identifier. - -data LambdaFormInfo - = LFReEntrant -- Reentrant closure (a function) - TopLevelFlag -- True if top level - !RepArity -- Arity. Invariant: always > 0 - !Bool -- True <=> no fvs - ArgDescr -- Argument descriptor (should really be in ClosureInfo) - - | LFThunk -- Thunk (zero arity) - TopLevelFlag - !Bool -- True <=> no free vars - !Bool -- True <=> updatable (i.e., *not* single-entry) - StandardFormInfo - !Bool -- True <=> *might* be a function type - - | LFCon -- A saturated constructor application - DataCon -- The constructor - - | LFUnknown -- Used for function arguments and imported things. - -- We know nothing about this closure. - -- Treat like updatable "LFThunk"... - -- Imported things which we *do* know something about use - -- one of the other LF constructors (eg LFReEntrant for - -- known functions) - !Bool -- True <=> *might* be a function type - -- The False case is good when we want to enter it, - -- because then we know the entry code will do - -- For a function, the entry code is the fast entry point - - | LFUnlifted -- A value of unboxed type; - -- always a value, needs evaluation - - | LFLetNoEscape -- See LetNoEscape module for precise description - - -------------------------- --- StandardFormInfo tells whether this thunk has one of --- a small number of standard forms - -data StandardFormInfo - = NonStandardThunk - -- The usual case: not of the standard forms - - | SelectorThunk - -- A SelectorThunk is of form - -- case x of - -- con a1,..,an -> ak - -- and the constructor is from a single-constr type. - WordOff -- 0-origin offset of ak within the "goods" of - -- constructor (Recall that the a1,...,an may be laid - -- out in the heap in a non-obvious order.) - - | ApThunk - -- An ApThunk is of form - -- x1 ... xn - -- The code for the thunk just pushes x2..xn on the stack and enters x1. - -- There are a few of these (for 1 <= n <= MAX_SPEC_AP_SIZE) pre-compiled - -- in the RTS to save space. - RepArity -- Arity, n - - ------------------------------------------------------ -- Building LambdaFormInfo ------------------------------------------------------ @@ -325,18 +258,22 @@ mkApLFInfo id upd_flag arity ------------- mkLFImported :: Id -> LambdaFormInfo -mkLFImported id - | Just con <- isDataConWorkId_maybe id - , isNullaryRepDataCon con - = LFCon con -- An imported nullary constructor - -- We assume that the constructor is evaluated so that - -- the id really does point directly to the constructor - - | arity > 0 - = LFReEntrant TopLevel arity True (panic "arg_descr") - - | otherwise - = mkLFArgument id -- Not sure of exact arity +mkLFImported id = + case idLFInfo_maybe id of + Just lf_info -> + lf_info + Nothing + | Just con <- isDataConWorkId_maybe id + , isNullaryRepDataCon con + -> LFCon con -- An imported nullary constructor + -- We assume that the constructor is evaluated so that + -- the id really does point directly to the constructor + + | arity > 0 + -> LFReEntrant TopLevel arity True ArgUnknown + + | otherwise + -> mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id ===================================== compiler/GHC/StgToCmm/Types.hs ===================================== @@ -0,0 +1,224 @@ +{-# LANGUAGE CPP #-} + +module GHC.StgToCmm.Types + ( CgInfos (..) + , LambdaFormInfo (..) + , ModuleLFInfos + , Liveness + , ArgDescr (..) + , StandardFormInfo (..) + , WordOff + ) where + +#include "HsVersions.h" + +import GHC.Prelude + +import GHC.Types.Basic +import GHC.Core.DataCon +import GHC.Types.Name.Env +import GHC.Types.Name.Set +import GHC.Utils.Outputable + +{- +Note [Conveying CAF-info and LFInfo between modules] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Some information about an Id is generated in the code generator, and is not +available earlier. Namely: + +* CAF info. Code motion in Cmm or earlier phases may move references around so + we compute information about which bits of code refer to which CAF late in the + Cmm pipeline. + +* LambdaFormInfo. This records the details of a closure representation, + including + - the final arity (for functions) + - whether it is a data constructor, and if so its tag + +Collectively we call this CgInfo (see GHC.StgToCmm.Types). + +It's very useful for importing modules to have this information. We can always +make a conservative assumption, but that is bad: e.g. + +* For CAF info, if we know nothing we have to assume it is a CAF which bloats + the SRTs of the importing module. + +- For data constructors, we really like having well-tagged pointers. See #14677, + #16559, #15155, and wiki: commentary/rts/haskell-execution/pointer-tagging + +So we arrange to always serialise this information into the interface file. The +moving parts are: + +* We record the CgInfo in the IdInfo of the Id. + +* GHC.Driver.Pipeline: the call to updateModDetailsIdInfos augments the + ModDetails constructed at the end of the Core pipeline, with with CgInfo + gleaned from the back end. The hard work is done in GHC.Iface.UpdateIdInfos. + +* For ModIface we generate the final ModIface with CgInfo in + GHC.Iface.Make.mkFullIface. + +* We don't absolutely guarantee to serialise the CgInfo: we won't if you have + -fomit-interface-pragmas or -fno-code; and we won't read it in if you have + -fignore-interface-pragmas. (We could revisit this decision.) +-} + +-- | Codegen-generated Id infos, to be passed to downstream via interfaces. +-- +-- This stuff is for optimization purposes only, they're not compulsory. +-- +-- * When CafInfo of an imported Id is not known it's safe to treat it as CAFFY. +-- * When LambdaFormInfo of an imported Id is not known it's safe to treat it as +-- `LFUnknown True` (which just says "it could be anything" and we do slow +-- entry). +-- +-- See also Note [Conveying CAF-info and LFInfo between modules] above. +-- +data CgInfos = CgInfos + { cgNonCafs :: !NameSet + -- ^ Exported Non-CAFFY closures in the current module. Everything else is + -- either not exported of CAFFY. + , cgLFInfos :: !ModuleLFInfos + -- ^ LambdaFormInfos of exported closures in the current module. + } + +-------------------------------------------------------------------------------- +-- LambdaFormInfo +-------------------------------------------------------------------------------- + +-- | Maps names in the current module to their LambdaFormInfos +type ModuleLFInfos = NameEnv LambdaFormInfo + +-- | Information about an identifier, from the code generator's point of view. +-- Every identifier is bound to a LambdaFormInfo in the environment, which gives +-- the code generator enough info to be able to tail call or return that +-- identifier. +data LambdaFormInfo + = LFReEntrant -- Reentrant closure (a function) + !TopLevelFlag -- True if top level + !RepArity -- Arity. Invariant: always > 0 + !Bool -- True <=> no fvs + !ArgDescr -- Argument descriptor (should really be in ClosureInfo) + + | LFThunk -- Thunk (zero arity) + !TopLevelFlag + !Bool -- True <=> no free vars + !Bool -- True <=> updatable (i.e., *not* single-entry) + !StandardFormInfo + !Bool -- True <=> *might* be a function type + + | LFCon -- A saturated constructor application + !DataCon -- The constructor + + | LFUnknown -- Used for function arguments and imported things. + -- We know nothing about this closure. + -- Treat like updatable "LFThunk"... + -- Imported things which we *do* know something about use + -- one of the other LF constructors (eg LFReEntrant for + -- known functions) + !Bool -- True <=> *might* be a function type + -- The False case is good when we want to enter it, + -- because then we know the entry code will do + -- For a function, the entry code is the fast entry point + + | LFUnlifted -- A value of unboxed type; + -- always a value, needs evaluation + + | LFLetNoEscape -- See LetNoEscape module for precise description + +instance Outputable LambdaFormInfo where + ppr (LFReEntrant top rep fvs argdesc) = + text "LFReEntrant" <> brackets + (ppr top <+> ppr rep <+> pprFvs fvs <+> ppr argdesc) + ppr (LFThunk top hasfv updateable sfi m_function) = + text "LFThunk" <> brackets + (ppr top <+> pprFvs hasfv <+> pprUpdateable updateable <+> + ppr sfi <+> pprFuncFlag m_function) + ppr (LFCon con) = + text "LFCon" <> brackets (ppr con) + ppr (LFUnknown m_func) = + text "LFUnknown" <> brackets (pprFuncFlag m_func) + ppr LFUnlifted = + text "LFUnlifted" + ppr LFLetNoEscape = + text "LFLetNoEscape" + +pprFvs :: Bool -> SDoc +pprFvs True = text "no-fvs" +pprFvs False = text "fvs" + +pprFuncFlag :: Bool -> SDoc +pprFuncFlag True = text "mFunc" +pprFuncFlag False = text "value" + +pprUpdateable :: Bool -> SDoc +pprUpdateable True = text "updateable" +pprUpdateable False = text "oneshot" + +-------------------------------------------------------------------------------- + +-- | We represent liveness bitmaps as a Bitmap (whose internal representation +-- really is a bitmap). These are pinned onto case return vectors to indicate +-- the state of the stack for the garbage collector. +-- +-- In the compiled program, liveness bitmaps that fit inside a single word +-- (StgWord) are stored as a single word, while larger bitmaps are stored as a +-- pointer to an array of words. + +type Liveness = [Bool] -- One Bool per word; True <=> non-ptr or dead + -- False <=> ptr + +-------------------------------------------------------------------------------- +-- | An ArgDescr describes the argument pattern of a function + +data ArgDescr + = ArgSpec -- Fits one of the standard patterns + !Int -- RTS type identifier ARG_P, ARG_N, ... + + | ArgGen -- General case + Liveness -- Details about the arguments + + | ArgUnknown -- For imported binds. + -- Invariant: Never Unknown for binds of the module + -- we are compiling. + deriving (Eq) + +instance Outputable ArgDescr where + ppr (ArgSpec n) = text "ArgSpec" <+> ppr n + ppr (ArgGen ls) = text "ArgGen" <+> ppr ls + ppr ArgUnknown = text "ArgUnknown" + +-------------------------------------------------------------------------------- +-- | StandardFormInfo tells whether this thunk has one of a small number of +-- standard forms + +data StandardFormInfo + = NonStandardThunk + -- The usual case: not of the standard forms + + | SelectorThunk + -- A SelectorThunk is of form + -- case x of + -- con a1,..,an -> ak + -- and the constructor is from a single-constr type. + !WordOff -- 0-origin offset of ak within the "goods" of + -- constructor (Recall that the a1,...,an may be laid + -- out in the heap in a non-obvious order.) + + | ApThunk + -- An ApThunk is of form + -- x1 ... xn + -- The code for the thunk just pushes x2..xn on the stack and enters x1. + -- There are a few of these (for 1 <= n <= MAX_SPEC_AP_SIZE) pre-compiled + -- in the RTS to save space. + !RepArity -- Arity, n + deriving (Eq) + +-- | Word offset, or word count +type WordOff = Int + +instance Outputable StandardFormInfo where + ppr NonStandardThunk = text "RegThunk" + ppr (SelectorThunk w) = text "SelThunk:" <> ppr w + ppr (ApThunk n) = text "ApThunk:" <> ppr n ===================================== compiler/GHC/Types/Id.hs ===================================== @@ -92,7 +92,7 @@ module GHC.Types.Id ( idCallArity, idFunRepArity, idUnfolding, realIdUnfolding, idSpecialisation, idCoreRules, idHasRules, - idCafInfo, + idCafInfo, idLFInfo_maybe, idOneShotInfo, idStateHackOneShotInfo, idOccInfo, isNeverLevPolyId, @@ -105,6 +105,7 @@ module GHC.Types.Id ( setIdSpecialisation, setIdCafInfo, setIdOccInfo, zapIdOccInfo, + setIdLFInfo, setIdDemandInfo, setIdStrictness, @@ -731,6 +732,15 @@ idCafInfo id = cafInfo (idInfo id) setIdCafInfo :: Id -> CafInfo -> Id setIdCafInfo id caf_info = modifyIdInfo (`setCafInfo` caf_info) id + --------------------------------- + -- Lambda form info + +idLFInfo_maybe :: Id -> Maybe LambdaFormInfo +idLFInfo_maybe = lfInfo . idInfo + +setIdLFInfo :: Id -> LambdaFormInfo -> Id +setIdLFInfo id lf = modifyIdInfo (`setLFInfo` lf) id + --------------------------------- -- Occurrence INFO idOccInfo :: Id -> OccInfo ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -74,6 +74,10 @@ module GHC.Types.Id.Info ( ppCafInfo, mayHaveCafRefs, cafInfo, setCafInfo, + -- ** The LambdaFormInfo type + LambdaFormInfo(..), + lfInfo, setLFInfo, + -- ** Tick-box Info TickBoxOp(..), TickBoxId, @@ -105,6 +109,8 @@ import GHC.Types.Demand import GHC.Types.Cpr import GHC.Utils.Misc +import GHC.StgToCmm.Types (LambdaFormInfo (..)) + -- infixl so you can say (id `set` a `set` b) infixl 1 `setRuleInfo`, `setArityInfo`, @@ -251,8 +257,10 @@ data IdInfo -- See Note [Specialisations and RULES in IdInfo] unfoldingInfo :: Unfolding, -- ^ The 'Id's unfolding - cafInfo :: CafInfo, + cafInfo :: !CafInfo, -- ^ 'Id' CAF info + -- See Note [Conveying CAF-info and LFInfo between modules] in + -- GHC.StgToCmm.Types. oneShotInfo :: OneShotInfo, -- ^ Info about a lambda-bound variable, if the 'Id' is one inlinePragInfo :: InlinePragma, @@ -271,8 +279,13 @@ data IdInfo -- ^ How this is called. This is the number of arguments to which a -- binding can be eta-expanded without losing any sharing. -- n <=> all calls have at least n arguments - levityInfo :: LevityInfo + levityInfo :: LevityInfo, -- ^ when applied, will this Id ever have a levity-polymorphic type? + lfInfo :: !(Maybe LambdaFormInfo) + -- ^ LambdaFormInfo of the Id. Not necessary, but if we know this we can + -- generate more efficient calling code. See getCallMethod + -- GHC.StgToCmm.Closure and Note [Conveying CAF-info and LFInfo between + -- modules] in GHC.StgToCmm.Types. } -- Setters @@ -295,13 +308,18 @@ setUnfoldingInfo info uf setArityInfo :: IdInfo -> ArityInfo -> IdInfo setArityInfo info ar = info { arityInfo = ar } + setCallArityInfo :: IdInfo -> ArityInfo -> IdInfo setCallArityInfo info ar = info { callArityInfo = ar } + setCafInfo :: IdInfo -> CafInfo -> IdInfo -setCafInfo info caf = info { cafInfo = caf } +setCafInfo info caf = info { cafInfo = caf } + +setLFInfo :: IdInfo -> LambdaFormInfo -> IdInfo +setLFInfo info lf = info { lfInfo = Just lf } setOneShotInfo :: IdInfo -> OneShotInfo -> IdInfo -setOneShotInfo info lb = {-lb `seq`-} info { oneShotInfo = lb } +setOneShotInfo info lb = {-lb `seq`-} info { oneShotInfo = lb } setDemandInfo :: IdInfo -> Demand -> IdInfo setDemandInfo info dd = dd `seq` info { demandInfo = dd } @@ -327,7 +345,8 @@ vanillaIdInfo strictnessInfo = nopSig, cprInfo = topCprSig, callArityInfo = unknownArity, - levityInfo = NoLevityInfo + levityInfo = NoLevityInfo, + lfInfo = Nothing } -- | More informative 'IdInfo' we can use when we know the 'Id' has no CAF references ===================================== compiler/ghc.cabal.in ===================================== @@ -228,7 +228,7 @@ Library GHC.Types.SrcLoc GHC.Types.Unique.Supply GHC.Types.Unique - GHC.Iface.UpdateCafInfos + GHC.Iface.UpdateIdInfos GHC.Types.Var GHC.Types.Var.Env GHC.Types.Var.Set @@ -295,6 +295,7 @@ Library GHC.StgToCmm.Ticky GHC.StgToCmm.Utils GHC.StgToCmm.ExtCode + GHC.StgToCmm.Types GHC.Runtime.Heap.Layout GHC.Core.Arity GHC.Core.FVs ===================================== testsuite/tests/codeGen/should_compile/Makefile ===================================== @@ -64,10 +64,10 @@ T17648: # NoCafRefs) to the interface files. '$(TEST_HC)' $(TEST_HC_OPTS) -dno-typeable-binds -O T17648.hs -v0 '$(TEST_HC)' --show-iface T17648.hi | tr -d '\n\r' | \ - grep -F 'f :: T GHC.Types.Int -> () [HasNoCafRefs, Arity' >/dev/null + grep -F 'f :: T GHC.Types.Int -> () [HasNoCafRefs, LambdaFormInfo' >/dev/null # Second compilation with -fcatch-bottoms, f should be CAFFY '$(TEST_HC)' $(TEST_HC_OPTS) -dno-typeable-binds -O \ -fcatch-bottoms T17648.hs -v0 -fforce-recomp '$(TEST_HC)' --show-iface T17648.hi | tr -d '\n\r' | \ - grep -F 'f :: T GHC.Types.Int -> () [Arity: 1, Strictness' >/dev/null + grep -F 'f :: T GHC.Types.Int -> () [LambdaFormInfo' >/dev/null ===================================== testsuite/tests/codeGen/should_compile/cg009/A.hs ===================================== @@ -0,0 +1,5 @@ +module A where + +newtype A = A Int + +val = A 42 ===================================== testsuite/tests/codeGen/should_compile/cg009/Main.hs ===================================== @@ -0,0 +1,7 @@ +module Main where + +import A + +main = return () + +a = val ===================================== testsuite/tests/codeGen/should_compile/cg009/Makefile ===================================== @@ -0,0 +1,9 @@ +TOP=../../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +# Make sure the LFInfo for an exported, but not directly used newtype +# constructors does not trip up the compiler. +cg009: + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O A.hs -fforce-recomp + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O0 Main.hs -fforce-recomp ===================================== testsuite/tests/codeGen/should_compile/cg009/all.T ===================================== @@ -0,0 +1 @@ +test('cg009', [extra_files(['A.hs','Main.hs'])], makefile_test, ['cg009']) ===================================== testsuite/tests/codeGen/should_compile/cg010/A.hs ===================================== @@ -0,0 +1,4 @@ +module A where + +{-# NOINLINE val #-} +val = Just 42 ===================================== testsuite/tests/codeGen/should_compile/cg010/Main.hs ===================================== @@ -0,0 +1,7 @@ +module Main where + +import A + +main = return () + +a = val ===================================== testsuite/tests/codeGen/should_compile/cg010/Makefile ===================================== @@ -0,0 +1,9 @@ +TOP=../../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +# Make sure LFInfo causes the imported reference to val to get tagged. +cg010: + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O A.hs -fforce-recomp + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O Main.hs -fforce-recomp -ddump-cmm -ddump-to-file + grep "A.val_closure+2" Main.dump-cmm ===================================== testsuite/tests/codeGen/should_compile/cg010/all.T ===================================== @@ -0,0 +1 @@ +test('cg010', [extra_files(['A.hs','Main.hs'])], makefile_test, ['cg010']) ===================================== testsuite/tests/codeGen/should_compile/cg010/cg010.stdout ===================================== @@ -0,0 +1 @@ + const A.val_closure+2; ===================================== testsuite/tests/simplCore/should_compile/Makefile ===================================== @@ -107,7 +107,7 @@ T4201: '$(TEST_HC)' $(TEST_HC_OPTS) -c -O T4201.hs '$(TEST_HC)' $(TEST_HC_OPTS) --show-iface T4201.hi > T4201.list # poor man idea about how to replace GNU grep -B2 "Sym" invocation with pure POSIX tools - for i in `grep -n "Sym" T4201.list |cut -d ':' -f -1`; do head -$$i T4201.list | tail -3 ; done + for i in `grep -n "Sym" T4201.list | cut -d ':' -f -1`; do head -$$i T4201.list | tail -4; done $(RM) -f T4201.list # This one looped as a result of bogus specialisation ===================================== testsuite/tests/simplCore/should_compile/T4201.stdout ===================================== @@ -1,3 +1,4 @@ - [HasNoCafRefs, Arity: 1, Strictness: , + [HasNoCafRefs, LambdaFormInfo: LFReEntrant 1, Arity: 1, + Strictness: , Unfolding: InlineRule (0, True, True) bof `cast` (Sym (N:Foo[0]) ->_R _R)] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ca6a257100570cf610ed048a1afc0ad99ed12682 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ca6a257100570cf610ed048a1afc0ad99ed12682 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 1 12:05:30 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Fri, 01 May 2020 08:05:30 -0400 Subject: [Git][ghc/ghc][wip/osa1/lfinfo] Cross-module LambdaFormInfo passing Message-ID: <5eac108a822dd_616787c09cc8304289@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/lfinfo at Glasgow Haskell Compiler / GHC Commits: 0ba1d26a by Ömer Sinan Ağacan at 2020-05-01T15:05:19+03:00 Cross-module LambdaFormInfo passing - Store LambdaFormInfos of exported Ids in interface files - Use them in importing modules This is for optimization purposes: if we know LambdaFormInfo of imported Ids we can generate more efficient calling code, see `getCallMethod`. Exporting (putting them in interface files or in ModDetails) and importing (reading them from interface files) are both optional. We don't assume known LambdaFormInfos anywhere and do not change how we call Ids with unknown LambdaFormInfos. Runtime, allocation, and residency numbers when building Cabal-the-library (commit 0d4ee7ba3). (Log and .hp files are in the MR: !2842) Runtime: | | GHC HEAD | This patch | Diff | |-----|----------|------------|----------------| | -O0 | 0:35.70 | 0:34.75 | -0.95s, -2.66% | | -O1 | 2:25.21 | 2:25.16 | -0.05s, -0.03% | | -O2 | 2:52.89 | 2:51.25 | -1.63s, -0.9% | Allocations: | | GHC HEAD | This patch | Diff | |-----|-----------------|-----------------|----------------------| | -O0 | 54,872,673,008 | 54,917,849,488 | +45,176,480, +0.08% | | -O1 | 227,080,315,016 | 227,584,483,224 | +504,168,208, +0.22% | | -O2 | 266,085,969,832 | 266,710,115,472 | +624,145,640, +0.23% | Max. residency: NOTE: Residency is measured with extra runtime args: `-i0 -h` which effectively turn all GCs into major GCs, and do GC more often. | | GHC HEAD | This patch | Diff | |-----|----------------------------|------------------------------|----------------------| | -O0 | 416,350,080 (894 samples) | 417,733,152 (892 samples) | +1,383,072, +0.33% | | -O1 | 928,484,840 (2101 samples) | 945,624,664 (2098 samples) | +17,139,824, +1.84% | | -O2 | 991,311,896 (2548 samples) | 1,010,647,088 (2536 samples) | +19,335,192, +1.95% | NoFib results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS 0.0% 0.0% +0.0% +0.0% +0.0% CSD 0.0% 0.0% 0.0% +0.0% +0.0% FS 0.0% 0.0% +0.0% +0.0% +0.0% S 0.0% 0.0% +0.0% +0.0% +0.0% VS 0.0% 0.0% +0.0% +0.0% +0.0% VSD 0.0% 0.0% +0.0% +0.0% +0.1% VSM 0.0% 0.0% +0.0% +0.0% +0.0% anna 0.0% 0.0% -0.3% -0.8% -0.0% ansi 0.0% 0.0% -0.0% -0.0% 0.0% atom 0.0% 0.0% -0.0% -0.0% 0.0% awards 0.0% 0.0% -0.1% -0.3% 0.0% banner 0.0% 0.0% -0.0% -0.0% -0.0% bernouilli 0.0% 0.0% -0.0% -0.0% -0.0% binary-trees 0.0% 0.0% -0.0% -0.0% +0.0% boyer 0.0% 0.0% -0.0% -0.0% 0.0% boyer2 0.0% 0.0% -0.0% -0.0% 0.0% bspt 0.0% 0.0% -0.0% -0.2% 0.0% cacheprof 0.0% 0.0% -0.1% -0.4% +0.0% calendar 0.0% 0.0% -0.0% -0.0% 0.0% cichelli 0.0% 0.0% -0.9% -2.4% 0.0% circsim 0.0% 0.0% -0.0% -0.0% 0.0% clausify 0.0% 0.0% -0.1% -0.3% 0.0% comp_lab_zift 0.0% 0.0% -0.0% -0.0% +0.0% compress 0.0% 0.0% -0.0% -0.0% -0.0% compress2 0.0% 0.0% -0.0% -0.0% 0.0% constraints 0.0% 0.0% -0.1% -0.2% -0.0% cryptarithm1 0.0% 0.0% -0.0% -0.0% 0.0% cryptarithm2 0.0% 0.0% -1.4% -4.1% -0.0% cse 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e1 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e2 0.0% 0.0% -0.0% -0.0% -0.0% dom-lt 0.0% 0.0% -0.1% -0.2% 0.0% eliza 0.0% 0.0% -0.5% -1.5% 0.0% event 0.0% 0.0% -0.0% -0.0% -0.0% exact-reals 0.0% 0.0% -0.1% -0.3% +0.0% exp3_8 0.0% 0.0% -0.0% -0.0% -0.0% expert 0.0% 0.0% -0.3% -1.0% -0.0% fannkuch-redux 0.0% 0.0% +0.0% +0.0% +0.0% fasta 0.0% 0.0% -0.0% -0.0% +0.0% fem 0.0% 0.0% -0.0% -0.0% 0.0% fft 0.0% 0.0% -0.0% -0.0% 0.0% fft2 0.0% 0.0% -0.0% -0.0% 0.0% fibheaps 0.0% 0.0% -0.0% -0.0% +0.0% fish 0.0% 0.0% 0.0% -0.0% +0.0% fluid 0.0% 0.0% -0.4% -1.2% +0.0% fulsom 0.0% 0.0% -0.0% -0.0% 0.0% gamteb 0.0% 0.0% -0.1% -0.3% 0.0% gcd 0.0% 0.0% -0.0% -0.0% 0.0% gen_regexps 0.0% 0.0% -0.0% -0.0% -0.0% genfft 0.0% 0.0% -0.0% -0.0% 0.0% gg 0.0% 0.0% -0.0% -0.0% +0.0% grep 0.0% 0.0% -0.0% -0.0% -0.0% hidden 0.0% 0.0% -0.1% -0.4% -0.0% hpg 0.0% 0.0% -0.2% -0.5% +0.0% ida 0.0% 0.0% -0.0% -0.0% +0.0% infer 0.0% 0.0% -0.3% -0.8% -0.0% integer 0.0% 0.0% -0.0% -0.0% +0.0% integrate 0.0% 0.0% -0.0% -0.0% 0.0% k-nucleotide 0.0% 0.0% -0.0% -0.0% +0.0% kahan 0.0% 0.0% -0.0% -0.0% +0.0% knights 0.0% 0.0% -2.2% -5.4% 0.0% lambda 0.0% 0.0% -0.6% -1.8% 0.0% last-piece 0.0% 0.0% -0.0% -0.0% 0.0% lcss 0.0% 0.0% -0.0% -0.1% 0.0% life 0.0% 0.0% -0.0% -0.1% 0.0% lift 0.0% 0.0% -0.2% -0.6% +0.0% linear 0.0% 0.0% -0.0% -0.0% -0.0% listcompr 0.0% 0.0% -0.0% -0.0% 0.0% listcopy 0.0% 0.0% -0.0% -0.0% 0.0% maillist 0.0% 0.0% -0.1% -0.3% +0.0% mandel 0.0% 0.0% -0.0% -0.0% 0.0% mandel2 0.0% 0.0% -0.0% -0.0% -0.0% mate +0.0% 0.0% -0.0% -0.0% -0.0% minimax 0.0% 0.0% -0.2% -1.0% 0.0% mkhprog 0.0% 0.0% -0.1% -0.2% -0.0% multiplier 0.0% 0.0% -0.0% -0.0% -0.0% n-body 0.0% 0.0% -0.0% -0.0% +0.0% nucleic2 0.0% 0.0% -0.1% -0.2% 0.0% para 0.0% 0.0% -0.0% -0.0% -0.0% paraffins 0.0% 0.0% -0.0% -0.0% 0.0% parser 0.0% 0.0% -0.2% -0.7% 0.0% parstof 0.0% 0.0% -0.0% -0.0% +0.0% pic 0.0% 0.0% -0.0% -0.0% 0.0% pidigits 0.0% 0.0% +0.0% +0.0% +0.0% power 0.0% 0.0% -0.2% -0.6% +0.0% pretty 0.0% 0.0% -0.0% -0.0% -0.0% primes 0.0% 0.0% -0.0% -0.0% 0.0% primetest 0.0% 0.0% -0.0% -0.0% -0.0% prolog 0.0% 0.0% -0.3% -1.1% 0.0% puzzle 0.0% 0.0% -0.0% -0.0% 0.0% queens 0.0% 0.0% -0.0% -0.0% +0.0% reptile 0.0% 0.0% -0.0% -0.0% 0.0% reverse-complem 0.0% 0.0% -0.0% -0.0% +0.0% rewrite 0.0% 0.0% -0.7% -2.5% -0.0% rfib 0.0% 0.0% -0.0% -0.0% 0.0% rsa 0.0% 0.0% -0.0% -0.0% 0.0% scc 0.0% 0.0% -0.1% -0.2% -0.0% sched 0.0% 0.0% -0.0% -0.0% -0.0% scs 0.0% 0.0% -1.0% -2.6% +0.0% simple 0.0% 0.0% +0.0% -0.0% +0.0% solid 0.0% 0.0% -0.0% -0.0% 0.0% sorting 0.0% 0.0% -0.6% -1.6% 0.0% spectral-norm 0.0% 0.0% +0.0% 0.0% +0.0% sphere 0.0% 0.0% -0.0% -0.0% -0.0% symalg 0.0% 0.0% -0.0% -0.0% +0.0% tak 0.0% 0.0% -0.0% -0.0% 0.0% transform 0.0% 0.0% -0.0% -0.0% 0.0% treejoin 0.0% 0.0% -0.0% -0.0% 0.0% typecheck 0.0% 0.0% -0.0% -0.0% +0.0% veritas +0.0% 0.0% -0.2% -0.4% +0.0% wang 0.0% 0.0% -0.0% -0.0% 0.0% wave4main 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 0.0% 0.0% -0.0% -0.0% +0.0% x2n1 0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min 0.0% 0.0% -2.2% -5.4% -0.0% Max +0.0% 0.0% +0.0% +0.0% +0.1% Geometric Mean -0.0% -0.0% -0.1% -0.3% +0.0% Metric increases micro benchmarks tracked in #17686: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 Co-authored-by: Andreas Klebinger <klebinger.andreas at gmx.at> - - - - - 28 changed files: - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Iface/UpdateCafInfos.hs → compiler/GHC/Iface/UpdateIdInfos.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Runtime/Heap/Layout.hs - compiler/GHC/StgToCmm.hs - compiler/GHC/StgToCmm/Closure.hs - + compiler/GHC/StgToCmm/Types.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Info.hs - compiler/ghc.cabal.in - testsuite/tests/codeGen/should_compile/Makefile - + testsuite/tests/codeGen/should_compile/cg009/A.hs - + testsuite/tests/codeGen/should_compile/cg009/Main.hs - + testsuite/tests/codeGen/should_compile/cg009/Makefile - + testsuite/tests/codeGen/should_compile/cg009/all.T - + testsuite/tests/codeGen/should_compile/cg010/A.hs - + testsuite/tests/codeGen/should_compile/cg010/Main.hs - + testsuite/tests/codeGen/should_compile/cg010/Makefile - + testsuite/tests/codeGen/should_compile/cg010/all.T - + testsuite/tests/codeGen/should_compile/cg010/cg010.stdout - testsuite/tests/simplCore/should_compile/Makefile - testsuite/tests/simplCore/should_compile/T4201.stdout Changes: ===================================== compiler/GHC/CoreToIface.hs ===================================== @@ -34,13 +34,14 @@ module GHC.CoreToIface , toIfaceIdDetails , toIfaceIdInfo , toIfUnfolding - , toIfaceOneShot , toIfaceTickish , toIfaceBind , toIfaceAlt , toIfaceCon , toIfaceApp , toIfaceVar + -- * Other stuff + , toIfaceLFInfo ) where #include "HsVersions.h" @@ -51,6 +52,7 @@ import GHC.Iface.Syntax import GHC.Core.DataCon import GHC.Types.Id import GHC.Types.Id.Info +import GHC.StgToCmm.Types import GHC.Core import GHC.Core.TyCon hiding ( pprPromotionQuote ) import GHC.Core.Coercion.Axiom @@ -616,6 +618,34 @@ toIfaceVar v where name = idName v +--------------------- +toIfaceLFInfo :: Name -> LambdaFormInfo -> IfaceLFInfo +toIfaceLFInfo nm lfi = case lfi of + LFReEntrant top_lvl arity no_fvs _arg_descr -> + -- Exported LFReEntrant closures are top level, and top-level closures + -- don't have free variables + ASSERT2(isTopLevel top_lvl, ppr nm) + ASSERT2(no_fvs, ppr nm) + IfLFReEntrant arity + LFThunk top_lvl no_fvs updatable sfi _mb_fun -> + -- Exported LFThunk closures are top level (which don't have free + -- variables), updatable, and non-standard (see cgTopRhsClosure) + ASSERT2(isTopLevel top_lvl, ppr nm) + ASSERT2(no_fvs, ppr nm) + ASSERT2(updatable, ppr nm) + ASSERT2(sfi == NonStandardThunk, ppr nm) + IfLFUnknown + LFCon dc -> + IfLFCon (dataConName dc) + LFUnknown _might_be_function -> + -- The argument can be derived from the type via might_be_a_function so we + -- don't serialize it + IfLFUnknown + LFUnlifted -> + IfLFUnlifted + LFLetNoEscape -> + panic "toIfaceLFInfo: LFLetNoEscape" + {- Note [Inlining and hs-boot files] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider this example (#10083, #12789): ===================================== compiler/GHC/Driver/Hooks.hs ===================================== @@ -55,6 +55,7 @@ import GHC.Stg.Syntax import GHC.Data.Stream import GHC.Cmm import GHC.Hs.Extension +import GHC.StgToCmm.Types (ModuleLFInfos) import Data.Maybe @@ -109,7 +110,7 @@ data Hooks = Hooks -> IO (Maybe HValue)) , createIservProcessHook :: Maybe (CreateProcess -> IO ProcessHandle) , stgToCmmHook :: Maybe (DynFlags -> Module -> [TyCon] -> CollectedCCs - -> [CgStgTopBinding] -> HpcInfo -> Stream IO CmmGroup ()) + -> [CgStgTopBinding] -> HpcInfo -> Stream IO CmmGroup ModuleLFInfos) , cmmToRawCmmHook :: forall a . Maybe (DynFlags -> Maybe Module -> Stream IO CmmGroupSRTs a -> IO (Stream IO RawCmmGroup a)) } ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -132,7 +132,6 @@ import qualified GHC.StgToCmm as StgToCmm ( codeGen ) import GHC.Types.CostCentre import GHC.Core.TyCon import GHC.Types.Name -import GHC.Types.Name.Set import GHC.Cmm import GHC.Cmm.Parser ( parseCmmFile ) import GHC.Cmm.Info.Build @@ -147,6 +146,7 @@ import GHC.Tc.Utils.Env import GHC.Builtin.Names import GHC.Driver.Plugins import GHC.Runtime.Loader ( initializePlugins ) +import GHC.StgToCmm.Types (CgInfos (..), ModuleLFInfos) import GHC.Driver.Session import GHC.Utils.Error @@ -175,6 +175,7 @@ import qualified Data.Set as S import Data.Set (Set) import Data.Functor import Control.DeepSeq (force) +import Data.Bifunctor (first) import GHC.Iface.Ext.Ast ( mkHieFile ) import GHC.Iface.Ext.Types ( getAsts, hie_asts, hie_module ) @@ -1385,7 +1386,7 @@ hscWriteIface dflags iface no_change mod_location = do -- | Compile to hard-code. hscGenHardCode :: HscEnv -> CgGuts -> ModLocation -> FilePath - -> IO (FilePath, Maybe FilePath, [(ForeignSrcLang, FilePath)], NameSet) + -> IO (FilePath, Maybe FilePath, [(ForeignSrcLang, FilePath)], CgInfos) -- ^ @Just f@ <=> _stub.c is f hscGenHardCode hsc_env cgguts location output_filename = do let CgGuts{ -- This is the last use of the ModGuts in a compilation. @@ -1444,11 +1445,11 @@ hscGenHardCode hsc_env cgguts location output_filename = do return a rawcmms1 = Stream.mapM dump rawcmms0 - (output_filename, (_stub_h_exists, stub_c_exists), foreign_fps, caf_infos) + (output_filename, (_stub_h_exists, stub_c_exists), foreign_fps, cg_infos) <- {-# SCC "codeOutput" #-} codeOutput dflags this_mod output_filename location foreign_stubs foreign_files dependencies rawcmms1 - return (output_filename, stub_c_exists, foreign_fps, caf_infos) + return (output_filename, stub_c_exists, foreign_fps, cg_infos) hscInteractive :: HscEnv @@ -1542,7 +1543,7 @@ doCodeGen :: HscEnv -> Module -> [TyCon] -> CollectedCCs -> [StgTopBinding] -> HpcInfo - -> IO (Stream IO CmmGroupSRTs NameSet) + -> IO (Stream IO CmmGroupSRTs CgInfos) -- Note we produce a 'Stream' of CmmGroups, so that the -- backend can be run incrementally. Otherwise it generates all -- the C-- up front, which has a significant space cost. @@ -1554,7 +1555,7 @@ doCodeGen hsc_env this_mod data_tycons dumpIfSet_dyn dflags Opt_D_dump_stg_final "Final STG:" FormatSTG (pprGenStgTopBindings stg_binds_w_fvs) - let cmm_stream :: Stream IO CmmGroup () + let cmm_stream :: Stream IO CmmGroup ModuleLFInfos -- See Note [Forcing of stg_binds] cmm_stream = stg_binds_w_fvs `seqList` {-# SCC "StgToCmm" #-} lookupHook stgToCmmHook StgToCmm.codeGen dflags dflags this_mod data_tycons @@ -1573,10 +1574,14 @@ doCodeGen hsc_env this_mod data_tycons ppr_stream1 = Stream.mapM dump1 cmm_stream - pipeline_stream = - {-# SCC "cmmPipeline" #-} - Stream.mapAccumL (cmmPipeline hsc_env) (emptySRT this_mod) ppr_stream1 - <&> (srtMapNonCAFs . moduleSRTMap) + pipeline_stream :: Stream IO CmmGroupSRTs CgInfos + pipeline_stream = do + (non_cafs, lf_infos) <- + {-# SCC "cmmPipeline" #-} + Stream.mapAccumL_ (cmmPipeline hsc_env) (emptySRT this_mod) ppr_stream1 + <&> first (srtMapNonCAFs . moduleSRTMap) + + return CgInfos{ cgNonCafs = non_cafs, cgLFInfos = lf_infos } dump2 a = do unless (null a) $ ===================================== compiler/GHC/Driver/Pipeline.hs ===================================== @@ -70,7 +70,7 @@ import GHC.Settings import GHC.Data.Bag ( unitBag ) import GHC.Data.FastString ( mkFastString ) import GHC.Iface.Make ( mkFullIface ) -import GHC.Iface.UpdateCafInfos ( updateModDetailsCafInfos ) +import GHC.Iface.UpdateIdInfos ( updateModDetailsIdInfos ) import GHC.Utils.Exception as Exception import System.Directory @@ -1178,12 +1178,12 @@ runPhase (HscOut src_flavour mod_name result) _ dflags = do PipeState{hsc_env=hsc_env'} <- getPipeState - (outputFilename, mStub, foreign_files, caf_infos) <- liftIO $ + (outputFilename, mStub, foreign_files, cg_infos) <- liftIO $ hscGenHardCode hsc_env' cgguts mod_location output_fn - final_iface <- liftIO (mkFullIface hsc_env'{hsc_dflags=iface_dflags} partial_iface (Just caf_infos)) - let final_mod_details = {-# SCC updateModDetailsCafInfos #-} - updateModDetailsCafInfos iface_dflags caf_infos mod_details + final_iface <- liftIO (mkFullIface hsc_env'{hsc_dflags=iface_dflags} partial_iface (Just cg_infos)) + let final_mod_details = {-# SCC updateModDetailsIdInfos #-} + updateModDetailsIdInfos iface_dflags cg_infos mod_details setIface final_iface final_mod_details -- See Note [Writing interface files] ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -38,6 +38,7 @@ import GHC.Core.Coercion.Axiom import GHC.Core.ConLike import GHC.Core.DataCon import GHC.Core.Type +import GHC.StgToCmm.Types (CgInfos (..)) import GHC.Tc.Utils.TcType import GHC.Core.InstEnv import GHC.Core.FamInstEnv @@ -98,15 +99,19 @@ mkPartialIface hsc_env mod_details = mkIface_ hsc_env this_mod hsc_src used_th deps rdr_env fix_env warns hpc_info self_trust safe_mode usages doc_hdr decl_docs arg_docs mod_details --- | Fully instantiate a interface --- Adds fingerprints and potentially code generator produced information. -mkFullIface :: HscEnv -> PartialModIface -> Maybe NameSet -> IO ModIface -mkFullIface hsc_env partial_iface mb_non_cafs = do +-- | Fully instantiate an interface. Adds fingerprints and potentially code +-- generator produced information. +-- +-- CgInfos is not available when not generating code (-fno-code), or when not +-- generating interface pragmas (-fomit-interface-pragmas). See also +-- Note [Conveying CAF-info and LFInfo between modules] in GHC.StgToCmm.Types. +mkFullIface :: HscEnv -> PartialModIface -> Maybe CgInfos -> IO ModIface +mkFullIface hsc_env partial_iface mb_cg_infos = do let decls | gopt Opt_OmitInterfacePragmas (hsc_dflags hsc_env) = mi_decls partial_iface | otherwise - = updateDeclCafInfos (mi_decls partial_iface) mb_non_cafs + = updateDecl (mi_decls partial_iface) mb_cg_infos full_iface <- {-# SCC "addFingerprints" #-} @@ -117,15 +122,23 @@ mkFullIface hsc_env partial_iface mb_non_cafs = do return full_iface -updateDeclCafInfos :: [IfaceDecl] -> Maybe NameSet -> [IfaceDecl] -updateDeclCafInfos decls Nothing = decls -updateDeclCafInfos decls (Just non_cafs) = map update_decl decls +updateDecl :: [IfaceDecl] -> Maybe CgInfos -> [IfaceDecl] +updateDecl decls Nothing = decls +updateDecl decls (Just CgInfos{ cgNonCafs = non_cafs, cgLFInfos = lf_infos }) = map update_decl decls where + update_decl (IfaceId nm ty details infos) + | let not_caffy = elemNameSet nm non_cafs + , let mb_lf_info = lookupNameEnv lf_infos nm + , WARN( isNothing mb_lf_info, text "Name without LFInfo:" <+> ppr nm ) True + -- Only allocate a new IfaceId if we're going to update the infos + , isJust mb_lf_info || not_caffy + = IfaceId nm ty details $ + (if not_caffy then (HsNoCafRefs :) else id) + (case mb_lf_info of + Nothing -> infos -- LFInfos not available when building .cmm files + Just lf_info -> HsLFInfo (toIfaceLFInfo nm lf_info) : infos) + update_decl decl - | IfaceId nm ty details infos <- decl - , elemNameSet nm non_cafs - = IfaceId nm ty details (HsNoCafRefs : infos) - | otherwise = decl -- | Make an interface from the results of typechecking only. Useful ===================================== compiler/GHC/Iface/Syntax.hs ===================================== @@ -22,6 +22,8 @@ module GHC.Iface.Syntax ( IfaceAxBranch(..), IfaceTyConParent(..), IfaceCompleteMatch(..), + IfaceLFInfo(..), + IfaceStandardFormInfo(..), -- * Binding names IfaceTopBndr, @@ -30,6 +32,7 @@ module GHC.Iface.Syntax ( -- Misc ifaceDeclImplicitBndrs, visibleIfConDecls, ifaceDeclFingerprints, + tcStandardFormInfo, -- Free Names freeNamesIfDecl, freeNamesIfRule, freeNamesIfFamInst, @@ -67,15 +70,18 @@ import GHC.Utils.Binary import GHC.Data.BooleanFormula ( BooleanFormula, pprBooleanFormula, isTrue ) import GHC.Types.Var( VarBndr(..), binderVar ) import GHC.Core.TyCon ( Role (..), Injectivity(..), tyConBndrVisArgFlag ) -import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, debugIsOn ) +import GHC.Utils.Misc( dropList, filterByList, notNull, unzipWith, debugIsOn, + seqList ) import GHC.Core.DataCon (SrcStrictness(..), SrcUnpackedness(..)) import GHC.Utils.Lexeme (isLexSym) import GHC.Builtin.Types ( constraintKindTyConName ) -import GHC.Utils.Misc (seqList) +import GHC.StgToCmm.Types import Control.Monad import System.IO.Unsafe import Control.DeepSeq +import Data.Word +import Data.Bits infixl 3 &&& @@ -114,7 +120,8 @@ data IfaceDecl = IfaceId { ifName :: IfaceTopBndr, ifType :: IfaceType, ifIdDetails :: IfaceIdDetails, - ifIdInfo :: IfaceIdInfo } + ifIdInfo :: IfaceIdInfo + } | IfaceData { ifName :: IfaceTopBndr, -- Type constructor ifBinders :: [IfaceTyConBinder], @@ -348,6 +355,7 @@ data IfaceInfoItem IfaceUnfolding -- See Note [Expose recursive functions] | HsNoCafRefs | HsLevity -- Present <=> never levity polymorphic + | HsLFInfo IfaceLFInfo -- NB: Specialisations and rules come in separately and are -- only later attached to the Id. Partial reason: some are orphans. @@ -379,6 +387,70 @@ data IfaceIdDetails | IfRecSelId (Either IfaceTyCon IfaceDecl) Bool | IfDFunId +-- | Iface type for LambdaFormInfo. Fields not relevant for imported Ids are +-- omitted in this type. +-- +-- Thunks are represented as LFUnknown: top-level thunks are never single-entry, +-- and for updatable thunks LFThunk and LFUnknown calling convention is the +-- same, see GHC.StgToCmm.Closure.getCallMethod. +data IfaceLFInfo + = IfLFReEntrant !RepArity + | IfLFCon !Name + | IfLFUnknown + | IfLFUnlifted + -- Generally, top-level things can't be unlifted, but we have an exception + -- for literal strings -- see Note [Core top-level string literals] in + -- GHC.Core + +tcStandardFormInfo :: IfaceStandardFormInfo -> StandardFormInfo +tcStandardFormInfo (IfStandardFormInfo w) + | testBit w 0 = NonStandardThunk + | otherwise = con field + where + field = fromIntegral (w `unsafeShiftR` 2) + con + | testBit w 1 = ApThunk + | otherwise = SelectorThunk + +instance Outputable IfaceLFInfo where + ppr (IfLFReEntrant arity) = + text "LFReEntrant" <+> ppr arity + + ppr (IfLFCon con) = + text "LFCon" <> brackets (ppr con) + + ppr IfLFUnlifted = + text "LFUnlifted" + + ppr IfLFUnknown = + text "LFUnknown" + +newtype IfaceStandardFormInfo = IfStandardFormInfo Word16 + +instance Binary IfaceStandardFormInfo where + put_ bh (IfStandardFormInfo w) = put_ bh (w :: Word16) + get bh = IfStandardFormInfo <$> (get bh :: IO Word16) + +instance Binary IfaceLFInfo where + put_ bh (IfLFReEntrant arity) = do + putByte bh 0 + put_ bh arity + put_ bh (IfLFCon con_name) = do + putByte bh 1 + put_ bh con_name + put_ bh IfLFUnknown = do + putByte bh 2 + put_ bh IfLFUnlifted = + putByte bh 3 + get bh = do + tag <- getByte bh + case tag of + 0 -> IfLFReEntrant <$> get bh + 1 -> IfLFCon <$> get bh + 2 -> pure IfLFUnknown + 3 -> pure IfLFUnlifted + _ -> panic "Invalid byte" + {- Note [Versioning of instances] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1393,6 +1465,7 @@ instance Outputable IfaceInfoItem where ppr (HsCpr cpr) = text "CPR:" <+> ppr cpr ppr HsNoCafRefs = text "HasNoCafRefs" ppr HsLevity = text "Never levity-polymorphic" + ppr (HsLFInfo lf_info) = text "LambdaFormInfo:" <+> ppr lf_info instance Outputable IfaceJoinInfo where ppr IfaceNotJoinPoint = empty @@ -1853,7 +1926,7 @@ instance Binary IfaceDecl where get bh = do h <- getByte bh case h of - 0 -> do name <- get bh + 0 -> do name <- get bh ~(ty, details, idinfo) <- lazyGet bh -- See Note [Lazy deserialization of IfaceId] return (IfaceId name ty details idinfo) @@ -2153,6 +2226,8 @@ instance Binary IfaceInfoItem where put_ bh HsNoCafRefs = putByte bh 4 put_ bh HsLevity = putByte bh 5 put_ bh (HsCpr cpr) = putByte bh 6 >> put_ bh cpr + put_ bh (HsLFInfo lf_info) = putByte bh 7 >> put_ bh lf_info + get bh = do h <- getByte bh case h of @@ -2164,7 +2239,8 @@ instance Binary IfaceInfoItem where 3 -> liftM HsInline $ get bh 4 -> return HsNoCafRefs 5 -> return HsLevity - _ -> HsCpr <$> get bh + 6 -> HsCpr <$> get bh + _ -> HsLFInfo <$> get bh instance Binary IfaceUnfolding where put_ bh (IfCoreUnfold s e) = do @@ -2495,6 +2571,7 @@ instance NFData IfaceInfoItem where HsNoCafRefs -> () HsLevity -> () HsCpr cpr -> cpr `seq` () + HsLFInfo lf_info -> lf_info `seq` () -- TODO: seq further? instance NFData IfaceUnfolding where rnf = \case ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -123,6 +123,9 @@ data IfaceOneShot -- See Note [Preserve OneShotInfo] in CoreTicy = IfaceNoOneShot -- and Note [The oneShot function] in GHC.Types.Id.Make | IfaceOneShot +instance Outputable IfaceOneShot where + ppr IfaceNoOneShot = text "NoOneShotInfo" + ppr IfaceOneShot = text "OneShot" {- %************************************************************************ ===================================== compiler/GHC/Iface/UpdateCafInfos.hs → compiler/GHC/Iface/UpdateIdInfos.hs ===================================== @@ -1,38 +1,42 @@ {-# LANGUAGE CPP, BangPatterns, Strict, RecordWildCards #-} -module GHC.Iface.UpdateCafInfos - ( updateModDetailsCafInfos +module GHC.Iface.UpdateIdInfos + ( updateModDetailsIdInfos ) where import GHC.Prelude import GHC.Core +import GHC.Core.InstEnv import GHC.Driver.Session import GHC.Driver.Types +import GHC.StgToCmm.Types (CgInfos (..)) import GHC.Types.Id import GHC.Types.Id.Info -import GHC.Core.InstEnv import GHC.Types.Name.Env import GHC.Types.Name.Set -import GHC.Utils.Misc import GHC.Types.Var +import GHC.Utils.Misc import GHC.Utils.Outputable #include "HsVersions.h" --- | Update CafInfos of all occurences (in rules, unfoldings, class instances) -updateModDetailsCafInfos +-- | Update CafInfos and LFInfos of all occurences (in rules, unfoldings, class +-- instances). +-- +-- See Note [Conveying CAF-info and LFInfo between modules] in +-- GHC.StgToCmm.Types. +updateModDetailsIdInfos :: DynFlags - -> NameSet -- ^ Non-CAFFY names in the module. Names not in this set are CAFFY. + -> CgInfos -> ModDetails -- ^ ModDetails to update -> ModDetails -updateModDetailsCafInfos dflags _ mod_details +updateModDetailsIdInfos dflags _ mod_details | gopt Opt_OmitInterfacePragmas dflags = mod_details -updateModDetailsCafInfos _ non_cafs mod_details = - {- pprTrace "updateModDetailsCafInfos" (text "non_cafs:" <+> ppr non_cafs) $ -} +updateModDetailsIdInfos _ cg_infos mod_details = let ModDetails{ md_types = type_env -- for unfoldings , md_insts = insts @@ -40,11 +44,11 @@ updateModDetailsCafInfos _ non_cafs mod_details = } = mod_details -- type TypeEnv = NameEnv TyThing - ~type_env' = mapNameEnv (updateTyThingCafInfos type_env' non_cafs) type_env + ~type_env' = mapNameEnv (updateTyThingIdInfos type_env' cg_infos) type_env -- Not strict! - !insts' = strictMap (updateInstCafInfos type_env' non_cafs) insts - !rules' = strictMap (updateRuleCafInfos type_env') rules + !insts' = strictMap (updateInstIdInfos type_env' cg_infos) insts + !rules' = strictMap (updateRuleIdInfos type_env') rules in mod_details{ md_types = type_env' , md_insts = insts' @@ -55,28 +59,28 @@ updateModDetailsCafInfos _ non_cafs mod_details = -- Rules -------------------------------------------------------------------------------- -updateRuleCafInfos :: TypeEnv -> CoreRule -> CoreRule -updateRuleCafInfos _ rule at BuiltinRule{} = rule -updateRuleCafInfos type_env Rule{ .. } = Rule { ru_rhs = updateGlobalIds type_env ru_rhs, .. } +updateRuleIdInfos :: TypeEnv -> CoreRule -> CoreRule +updateRuleIdInfos _ rule at BuiltinRule{} = rule +updateRuleIdInfos type_env Rule{ .. } = Rule { ru_rhs = updateGlobalIds type_env ru_rhs, .. } -------------------------------------------------------------------------------- -- Instances -------------------------------------------------------------------------------- -updateInstCafInfos :: TypeEnv -> NameSet -> ClsInst -> ClsInst -updateInstCafInfos type_env non_cafs = - updateClsInstDFun (updateIdUnfolding type_env . updateIdCafInfo non_cafs) +updateInstIdInfos :: TypeEnv -> CgInfos -> ClsInst -> ClsInst +updateInstIdInfos type_env cg_infos = + updateClsInstDFun (updateIdUnfolding type_env . updateIdInfo cg_infos) -------------------------------------------------------------------------------- -- TyThings -------------------------------------------------------------------------------- -updateTyThingCafInfos :: TypeEnv -> NameSet -> TyThing -> TyThing +updateTyThingIdInfos :: TypeEnv -> CgInfos -> TyThing -> TyThing -updateTyThingCafInfos type_env non_cafs (AnId id) = - AnId (updateIdUnfolding type_env (updateIdCafInfo non_cafs id)) +updateTyThingIdInfos type_env cg_infos (AnId id) = + AnId (updateIdUnfolding type_env (updateIdInfo cg_infos id)) -updateTyThingCafInfos _ _ other = other -- AConLike, ATyCon, ACoAxiom +updateTyThingIdInfos _ _ other = other -- AConLike, ATyCon, ACoAxiom -------------------------------------------------------------------------------- -- Unfoldings @@ -95,13 +99,18 @@ updateIdUnfolding type_env id = -- Expressions -------------------------------------------------------------------------------- -updateIdCafInfo :: NameSet -> Id -> Id -updateIdCafInfo non_cafs id - | idName id `elemNameSet` non_cafs - = -- pprTrace "updateIdCafInfo" (text "Marking" <+> ppr id <+> parens (ppr (idName id)) <+> text "as non-CAFFY") $ - id `setIdCafInfo` NoCafRefs - | otherwise - = id +updateIdInfo :: CgInfos -> Id -> Id +updateIdInfo CgInfos{ cgNonCafs = non_cafs, cgLFInfos = lf_infos } id = + let + not_caffy = elemNameSet (idName id) non_cafs + mb_lf_info = lookupNameEnv lf_infos (idName id) + + id1 = if not_caffy then setIdCafInfo id NoCafRefs else id + id2 = case mb_lf_info of + Nothing -> id1 + Just lf_info -> setIdLFInfo id1 lf_info + in + id2 -------------------------------------------------------------------------------- @@ -116,7 +125,7 @@ updateGlobalIds env e = go env e case lookupNameEnv env (varName var) of Nothing -> var Just (AnId id) -> id - Just other -> pprPanic "GHC.Iface.UpdateCafInfos.updateGlobalIds" $ + Just other -> pprPanic "UpdateCafInfos.updateGlobalIds" $ text "Found a non-Id for Id Name" <+> ppr (varName var) $$ nest 4 (text "Id:" <+> ppr var $$ text "TyThing:" <+> ppr other) ===================================== compiler/GHC/IfaceToCore.hs ===================================== @@ -19,7 +19,8 @@ module GHC.IfaceToCore ( tcIfaceDecl, tcIfaceInst, tcIfaceFamInst, tcIfaceRules, tcIfaceAnnotations, tcIfaceCompleteSigs, tcIfaceExpr, -- Desired by HERMIT (#7683) - tcIfaceGlobal + tcIfaceGlobal, + tcIfaceOneShot ) where #include "HsVersions.h" @@ -30,6 +31,8 @@ import GHC.Builtin.Types.Literals(typeNatCoAxiomRules) import GHC.Iface.Syntax import GHC.Iface.Load import GHC.Iface.Env +import GHC.StgToCmm.Types +import GHC.StgToCmm.Closure (might_be_a_function) import GHC.Tc.TyCl.Build import GHC.Tc.Utils.Monad import GHC.Tc.Utils.TcType @@ -1464,8 +1467,7 @@ tcIdInfo ignore_prags toplvl name ty info = do let init_info | if_boot lcl_env = vanillaIdInfo `setUnfoldingInfo` BootUnfolding | otherwise = vanillaIdInfo - let needed = needed_prags info - foldlM tcPrag init_info needed + foldlM tcPrag init_info (needed_prags info) where needed_prags :: [IfaceInfoItem] -> [IfaceInfoItem] needed_prags items @@ -1485,6 +1487,9 @@ tcIdInfo ignore_prags toplvl name ty info = do tcPrag info (HsCpr cpr) = return (info `setCprInfo` cpr) tcPrag info (HsInline prag) = return (info `setInlinePragInfo` prag) tcPrag info HsLevity = return (info `setNeverLevPoly` ty) + tcPrag info (HsLFInfo lf_info) = do + lf_info <- tcLFInfo ty lf_info + return (info `setLFInfo` lf_info) -- The next two are lazy, so they don't transitively suck stuff in tcPrag info (HsUnfold lb if_unf) @@ -1497,6 +1502,29 @@ tcJoinInfo :: IfaceJoinInfo -> Maybe JoinArity tcJoinInfo (IfaceJoinPoint ar) = Just ar tcJoinInfo IfaceNotJoinPoint = Nothing +tcLFInfo :: Type -> IfaceLFInfo -> IfL LambdaFormInfo +tcLFInfo ty lfi = case lfi of + IfLFReEntrant rep_arity -> + -- LFReEntrant closures in interface files are guaranteed to + -- + -- - Be top-level, as only top-level closures are exported. + -- - Have no free variables, as only non-top-level closures have free + -- variables + -- - Don't have ArgDescrs, as ArgDescr is used when generating code for + -- the closure + -- + -- These invariants are checked when generating LFInfos in toIfaceLFInfo. + return (LFReEntrant TopLevel rep_arity True ArgUnknown) + + IfLFUnlifted -> + return LFUnlifted + + IfLFCon con_name -> + LFCon <$!> tcIfaceDataCon con_name + + IfLFUnknown -> + return (LFUnknown (might_be_a_function ty)) + tcUnfolding :: TopLevelFlag -> Name -> Type -> IdInfo -> IfaceUnfolding -> IfL Unfolding tcUnfolding toplvl name _ info (IfCoreUnfold stable if_expr) = do { dflags <- getDynFlags @@ -1508,7 +1536,7 @@ tcUnfolding toplvl name _ info (IfCoreUnfold stable if_expr) Just expr -> mkFinalUnfolding dflags unf_src strict_sig expr } where - -- Strictness should occur before unfolding! + -- Strictness should occur before unfolding! strict_sig = strictnessInfo info tcUnfolding toplvl name _ _ (IfCompulsory if_expr) @@ -1583,6 +1611,10 @@ tcPragExpr is_compulsory toplvl name expr -- It's OK to use nonDetEltsUFM here because we immediately forget -- the ordering by creating a set +tcIfaceOneShot :: IfaceOneShot -> OneShotInfo +tcIfaceOneShot IfaceNoOneShot = NoOneShotInfo +tcIfaceOneShot IfaceOneShot = OneShotLam + {- ************************************************************************ * * ===================================== compiler/GHC/Runtime/Heap/Layout.hs ===================================== @@ -51,6 +51,7 @@ import GHC.Driver.Session import GHC.Utils.Outputable import GHC.Platform import GHC.Data.FastString +import GHC.StgToCmm.Types import Data.Word import Data.Bits @@ -64,9 +65,6 @@ import Data.ByteString (ByteString) ************************************************************************ -} --- | Word offset, or word count -type WordOff = Int - -- | Byte offset, or byte count type ByteOff = Int @@ -196,29 +194,6 @@ type ConstrDescription = ByteString -- result of dataConIdentity type FunArity = Int type SelectorOffset = Int -------------------------- --- We represent liveness bitmaps as a Bitmap (whose internal --- representation really is a bitmap). These are pinned onto case return --- vectors to indicate the state of the stack for the garbage collector. --- --- In the compiled program, liveness bitmaps that fit inside a single --- word (StgWord) are stored as a single word, while larger bitmaps are --- stored as a pointer to an array of words. - -type Liveness = [Bool] -- One Bool per word; True <=> non-ptr or dead - -- False <=> ptr - -------------------------- --- An ArgDescr describes the argument pattern of a function - -data ArgDescr - = ArgSpec -- Fits one of the standard patterns - !Int -- RTS type identifier ARG_P, ARG_N, ... - - | ArgGen -- General case - Liveness -- Details about the arguments - - ----------------------------------------------------------------------------- -- Construction @@ -545,10 +520,6 @@ instance Outputable SMRep where ppr (RTSRep ty rep) = text "tag:" <> ppr ty <+> ppr rep -instance Outputable ArgDescr where - ppr (ArgSpec n) = text "ArgSpec" <+> ppr n - ppr (ArgGen ls) = text "ArgGen" <+> ppr ls - pprTypeInfo :: ClosureTypeInfo -> SDoc pprTypeInfo (Constr tag descr) = text "Con" <+> ===================================== compiler/GHC/StgToCmm.hs ===================================== @@ -1,5 +1,6 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-} +{-# LANGUAGE BangPatterns #-} ----------------------------------------------------------------------------- -- @@ -25,6 +26,7 @@ import GHC.StgToCmm.Utils import GHC.StgToCmm.Closure import GHC.StgToCmm.Hpc import GHC.StgToCmm.Ticky +import GHC.StgToCmm.Types (ModuleLFInfos) import GHC.Cmm import GHC.Cmm.Utils @@ -47,6 +49,8 @@ import GHC.Data.Stream import GHC.Types.Basic import GHC.Types.Var.Set ( isEmptyDVarSet ) import GHC.SysTools.FileCleanup +import GHC.Types.Unique.FM +import GHC.Types.Name.Env import GHC.Data.OrdList import GHC.Cmm.Graph @@ -63,7 +67,8 @@ codeGen :: DynFlags -> CollectedCCs -- (Local/global) cost-centres needing declaring/registering. -> [CgStgTopBinding] -- Bindings to convert -> HpcInfo - -> Stream IO CmmGroup () -- Output as a stream, so codegen can + -> Stream IO CmmGroup ModuleLFInfos + -- Output as a stream, so codegen can -- be interleaved with output codeGen dflags this_mod data_tycons @@ -105,6 +110,21 @@ codeGen dflags this_mod data_tycons mapM_ (cg . cgDataCon) (tyConDataCons tycon) ; mapM_ do_tycon data_tycons + + ; cg_id_infos <- cgs_binds <$> liftIO (readIORef cgref) + + ; let extract_lf_info info = (name, lf) + where + !id = cg_id info + !name = idName id + !lf = cg_lf info + + -- LambdaFormInfos to be used in importing modules to generate more + -- efficient caling code. See Note [Conveying CAF-info and LFInfo + -- between modules] in GHC.StgToCmm.Types. + ; let !generatedInfo = mkNameEnv (Prelude.map extract_lf_info (eltsUFM cg_id_infos)) + + ; return generatedInfo } --------------------------------------------------------------- ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -55,6 +55,8 @@ module GHC.StgToCmm.Closure ( blackHoleOnEntry, -- Needs LambdaFormInfo and SMRep isStaticClosure, -- Needs SMPre + might_be_a_function, + -- * InfoTables mkDataConInfoTable, cafBlackHoleInfoTable, @@ -70,6 +72,7 @@ import GHC.Stg.Syntax import GHC.Runtime.Heap.Layout import GHC.Cmm import GHC.Cmm.Ppr.Expr() -- For Outputable instances +import GHC.StgToCmm.Types import GHC.Types.CostCentre import GHC.Cmm.BlockId @@ -188,76 +191,6 @@ addArgReps = map (\arg -> let arg' = fromNonVoid arg argPrimRep :: StgArg -> PrimRep argPrimRep arg = typePrimRep1 (stgArgType arg) - ------------------------------------------------------------------------------ --- LambdaFormInfo ------------------------------------------------------------------------------ - --- Information about an identifier, from the code generator's point of --- view. Every identifier is bound to a LambdaFormInfo in the --- environment, which gives the code generator enough info to be able to --- tail call or return that identifier. - -data LambdaFormInfo - = LFReEntrant -- Reentrant closure (a function) - TopLevelFlag -- True if top level - !RepArity -- Arity. Invariant: always > 0 - !Bool -- True <=> no fvs - ArgDescr -- Argument descriptor (should really be in ClosureInfo) - - | LFThunk -- Thunk (zero arity) - TopLevelFlag - !Bool -- True <=> no free vars - !Bool -- True <=> updatable (i.e., *not* single-entry) - StandardFormInfo - !Bool -- True <=> *might* be a function type - - | LFCon -- A saturated constructor application - DataCon -- The constructor - - | LFUnknown -- Used for function arguments and imported things. - -- We know nothing about this closure. - -- Treat like updatable "LFThunk"... - -- Imported things which we *do* know something about use - -- one of the other LF constructors (eg LFReEntrant for - -- known functions) - !Bool -- True <=> *might* be a function type - -- The False case is good when we want to enter it, - -- because then we know the entry code will do - -- For a function, the entry code is the fast entry point - - | LFUnlifted -- A value of unboxed type; - -- always a value, needs evaluation - - | LFLetNoEscape -- See LetNoEscape module for precise description - - -------------------------- --- StandardFormInfo tells whether this thunk has one of --- a small number of standard forms - -data StandardFormInfo - = NonStandardThunk - -- The usual case: not of the standard forms - - | SelectorThunk - -- A SelectorThunk is of form - -- case x of - -- con a1,..,an -> ak - -- and the constructor is from a single-constr type. - WordOff -- 0-origin offset of ak within the "goods" of - -- constructor (Recall that the a1,...,an may be laid - -- out in the heap in a non-obvious order.) - - | ApThunk - -- An ApThunk is of form - -- x1 ... xn - -- The code for the thunk just pushes x2..xn on the stack and enters x1. - -- There are a few of these (for 1 <= n <= MAX_SPEC_AP_SIZE) pre-compiled - -- in the RTS to save space. - RepArity -- Arity, n - - ------------------------------------------------------ -- Building LambdaFormInfo ------------------------------------------------------ @@ -325,18 +258,22 @@ mkApLFInfo id upd_flag arity ------------- mkLFImported :: Id -> LambdaFormInfo -mkLFImported id - | Just con <- isDataConWorkId_maybe id - , isNullaryRepDataCon con - = LFCon con -- An imported nullary constructor - -- We assume that the constructor is evaluated so that - -- the id really does point directly to the constructor - - | arity > 0 - = LFReEntrant TopLevel arity True (panic "arg_descr") - - | otherwise - = mkLFArgument id -- Not sure of exact arity +mkLFImported id = + case idLFInfo_maybe id of + Just lf_info -> + lf_info + Nothing + | Just con <- isDataConWorkId_maybe id + , isNullaryRepDataCon con + -> LFCon con -- An imported nullary constructor + -- We assume that the constructor is evaluated so that + -- the id really does point directly to the constructor + + | arity > 0 + -> LFReEntrant TopLevel arity True ArgUnknown + + | otherwise + -> mkLFArgument id -- Not sure of exact arity where arity = idFunRepArity id ===================================== compiler/GHC/StgToCmm/Types.hs ===================================== @@ -0,0 +1,224 @@ +{-# LANGUAGE CPP #-} + +module GHC.StgToCmm.Types + ( CgInfos (..) + , LambdaFormInfo (..) + , ModuleLFInfos + , Liveness + , ArgDescr (..) + , StandardFormInfo (..) + , WordOff + ) where + +#include "HsVersions.h" + +import GHC.Prelude + +import GHC.Types.Basic +import GHC.Core.DataCon +import GHC.Types.Name.Env +import GHC.Types.Name.Set +import GHC.Utils.Outputable + +{- +Note [Conveying CAF-info and LFInfo between modules] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Some information about an Id is generated in the code generator, and is not +available earlier. Namely: + +* CAF info. Code motion in Cmm or earlier phases may move references around so + we compute information about which bits of code refer to which CAF late in the + Cmm pipeline. + +* LambdaFormInfo. This records the details of a closure representation, + including + - the final arity (for functions) + - whether it is a data constructor, and if so its tag + +Collectively we call this CgInfo (see GHC.StgToCmm.Types). + +It's very useful for importing modules to have this information. We can always +make a conservative assumption, but that is bad: e.g. + +* For CAF info, if we know nothing we have to assume it is a CAF which bloats + the SRTs of the importing module. + +- For data constructors, we really like having well-tagged pointers. See #14677, + #16559, #15155, and wiki: commentary/rts/haskell-execution/pointer-tagging + +So we arrange to always serialise this information into the interface file. The +moving parts are: + +* We record the CgInfo in the IdInfo of the Id. + +* GHC.Driver.Pipeline: the call to updateModDetailsIdInfos augments the + ModDetails constructed at the end of the Core pipeline, with with CgInfo + gleaned from the back end. The hard work is done in GHC.Iface.UpdateIdInfos. + +* For ModIface we generate the final ModIface with CgInfo in + GHC.Iface.Make.mkFullIface. + +* We don't absolutely guarantee to serialise the CgInfo: we won't if you have + -fomit-interface-pragmas or -fno-code; and we won't read it in if you have + -fignore-interface-pragmas. (We could revisit this decision.) +-} + +-- | Codegen-generated Id infos, to be passed to downstream via interfaces. +-- +-- This stuff is for optimization purposes only, they're not compulsory. +-- +-- * When CafInfo of an imported Id is not known it's safe to treat it as CAFFY. +-- * When LambdaFormInfo of an imported Id is not known it's safe to treat it as +-- `LFUnknown True` (which just says "it could be anything" and we do slow +-- entry). +-- +-- See also Note [Conveying CAF-info and LFInfo between modules] above. +-- +data CgInfos = CgInfos + { cgNonCafs :: !NameSet + -- ^ Exported Non-CAFFY closures in the current module. Everything else is + -- either not exported of CAFFY. + , cgLFInfos :: !ModuleLFInfos + -- ^ LambdaFormInfos of exported closures in the current module. + } + +-------------------------------------------------------------------------------- +-- LambdaFormInfo +-------------------------------------------------------------------------------- + +-- | Maps names in the current module to their LambdaFormInfos +type ModuleLFInfos = NameEnv LambdaFormInfo + +-- | Information about an identifier, from the code generator's point of view. +-- Every identifier is bound to a LambdaFormInfo in the environment, which gives +-- the code generator enough info to be able to tail call or return that +-- identifier. +data LambdaFormInfo + = LFReEntrant -- Reentrant closure (a function) + !TopLevelFlag -- True if top level + !RepArity -- Arity. Invariant: always > 0 + !Bool -- True <=> no fvs + !ArgDescr -- Argument descriptor (should really be in ClosureInfo) + + | LFThunk -- Thunk (zero arity) + !TopLevelFlag + !Bool -- True <=> no free vars + !Bool -- True <=> updatable (i.e., *not* single-entry) + !StandardFormInfo + !Bool -- True <=> *might* be a function type + + | LFCon -- A saturated constructor application + !DataCon -- The constructor + + | LFUnknown -- Used for function arguments and imported things. + -- We know nothing about this closure. + -- Treat like updatable "LFThunk"... + -- Imported things which we *do* know something about use + -- one of the other LF constructors (eg LFReEntrant for + -- known functions) + !Bool -- True <=> *might* be a function type + -- The False case is good when we want to enter it, + -- because then we know the entry code will do + -- For a function, the entry code is the fast entry point + + | LFUnlifted -- A value of unboxed type; + -- always a value, needs evaluation + + | LFLetNoEscape -- See LetNoEscape module for precise description + +instance Outputable LambdaFormInfo where + ppr (LFReEntrant top rep fvs argdesc) = + text "LFReEntrant" <> brackets + (ppr top <+> ppr rep <+> pprFvs fvs <+> ppr argdesc) + ppr (LFThunk top hasfv updateable sfi m_function) = + text "LFThunk" <> brackets + (ppr top <+> pprFvs hasfv <+> pprUpdateable updateable <+> + ppr sfi <+> pprFuncFlag m_function) + ppr (LFCon con) = + text "LFCon" <> brackets (ppr con) + ppr (LFUnknown m_func) = + text "LFUnknown" <> brackets (pprFuncFlag m_func) + ppr LFUnlifted = + text "LFUnlifted" + ppr LFLetNoEscape = + text "LFLetNoEscape" + +pprFvs :: Bool -> SDoc +pprFvs True = text "no-fvs" +pprFvs False = text "fvs" + +pprFuncFlag :: Bool -> SDoc +pprFuncFlag True = text "mFunc" +pprFuncFlag False = text "value" + +pprUpdateable :: Bool -> SDoc +pprUpdateable True = text "updateable" +pprUpdateable False = text "oneshot" + +-------------------------------------------------------------------------------- + +-- | We represent liveness bitmaps as a Bitmap (whose internal representation +-- really is a bitmap). These are pinned onto case return vectors to indicate +-- the state of the stack for the garbage collector. +-- +-- In the compiled program, liveness bitmaps that fit inside a single word +-- (StgWord) are stored as a single word, while larger bitmaps are stored as a +-- pointer to an array of words. + +type Liveness = [Bool] -- One Bool per word; True <=> non-ptr or dead + -- False <=> ptr + +-------------------------------------------------------------------------------- +-- | An ArgDescr describes the argument pattern of a function + +data ArgDescr + = ArgSpec -- Fits one of the standard patterns + !Int -- RTS type identifier ARG_P, ARG_N, ... + + | ArgGen -- General case + Liveness -- Details about the arguments + + | ArgUnknown -- For imported binds. + -- Invariant: Never Unknown for binds of the module + -- we are compiling. + deriving (Eq) + +instance Outputable ArgDescr where + ppr (ArgSpec n) = text "ArgSpec" <+> ppr n + ppr (ArgGen ls) = text "ArgGen" <+> ppr ls + ppr ArgUnknown = text "ArgUnknown" + +-------------------------------------------------------------------------------- +-- | StandardFormInfo tells whether this thunk has one of a small number of +-- standard forms + +data StandardFormInfo + = NonStandardThunk + -- The usual case: not of the standard forms + + | SelectorThunk + -- A SelectorThunk is of form + -- case x of + -- con a1,..,an -> ak + -- and the constructor is from a single-constr type. + !WordOff -- 0-origin offset of ak within the "goods" of + -- constructor (Recall that the a1,...,an may be laid + -- out in the heap in a non-obvious order.) + + | ApThunk + -- An ApThunk is of form + -- x1 ... xn + -- The code for the thunk just pushes x2..xn on the stack and enters x1. + -- There are a few of these (for 1 <= n <= MAX_SPEC_AP_SIZE) pre-compiled + -- in the RTS to save space. + !RepArity -- Arity, n + deriving (Eq) + +-- | Word offset, or word count +type WordOff = Int + +instance Outputable StandardFormInfo where + ppr NonStandardThunk = text "RegThunk" + ppr (SelectorThunk w) = text "SelThunk:" <> ppr w + ppr (ApThunk n) = text "ApThunk:" <> ppr n ===================================== compiler/GHC/Types/Id.hs ===================================== @@ -92,7 +92,7 @@ module GHC.Types.Id ( idCallArity, idFunRepArity, idUnfolding, realIdUnfolding, idSpecialisation, idCoreRules, idHasRules, - idCafInfo, + idCafInfo, idLFInfo_maybe, idOneShotInfo, idStateHackOneShotInfo, idOccInfo, isNeverLevPolyId, @@ -105,6 +105,7 @@ module GHC.Types.Id ( setIdSpecialisation, setIdCafInfo, setIdOccInfo, zapIdOccInfo, + setIdLFInfo, setIdDemandInfo, setIdStrictness, @@ -731,6 +732,15 @@ idCafInfo id = cafInfo (idInfo id) setIdCafInfo :: Id -> CafInfo -> Id setIdCafInfo id caf_info = modifyIdInfo (`setCafInfo` caf_info) id + --------------------------------- + -- Lambda form info + +idLFInfo_maybe :: Id -> Maybe LambdaFormInfo +idLFInfo_maybe = lfInfo . idInfo + +setIdLFInfo :: Id -> LambdaFormInfo -> Id +setIdLFInfo id lf = modifyIdInfo (`setLFInfo` lf) id + --------------------------------- -- Occurrence INFO idOccInfo :: Id -> OccInfo ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -74,6 +74,10 @@ module GHC.Types.Id.Info ( ppCafInfo, mayHaveCafRefs, cafInfo, setCafInfo, + -- ** The LambdaFormInfo type + LambdaFormInfo(..), + lfInfo, setLFInfo, + -- ** Tick-box Info TickBoxOp(..), TickBoxId, @@ -105,6 +109,8 @@ import GHC.Types.Demand import GHC.Types.Cpr import GHC.Utils.Misc +import GHC.StgToCmm.Types (LambdaFormInfo (..)) + -- infixl so you can say (id `set` a `set` b) infixl 1 `setRuleInfo`, `setArityInfo`, @@ -251,8 +257,10 @@ data IdInfo -- See Note [Specialisations and RULES in IdInfo] unfoldingInfo :: Unfolding, -- ^ The 'Id's unfolding - cafInfo :: CafInfo, + cafInfo :: !CafInfo, -- ^ 'Id' CAF info + -- See Note [Conveying CAF-info and LFInfo between modules] in + -- GHC.StgToCmm.Types. oneShotInfo :: OneShotInfo, -- ^ Info about a lambda-bound variable, if the 'Id' is one inlinePragInfo :: InlinePragma, @@ -271,8 +279,21 @@ data IdInfo -- ^ How this is called. This is the number of arguments to which a -- binding can be eta-expanded without losing any sharing. -- n <=> all calls have at least n arguments - levityInfo :: LevityInfo + levityInfo :: LevityInfo, -- ^ when applied, will this Id ever have a levity-polymorphic type? + lfInfo :: !(Maybe LambdaFormInfo) + -- ^ LambdaFormInfo of the Id. Not necessary, but if we know this we can + -- generate more efficient calling code. + -- + -- Not available for the Ids in the current module, and when an imported + -- Id doesn't have a LambdaFormInfo in the interface (in which case we + -- generate a conservative LFI based on the Id's type in + -- GHC.StgToCmm.mkLFImported). + -- + -- See also getCallMethod in GHC.StgToCmm.Closure for how LFIs are used + -- when generating calling code, and Note [Conveying CAF-info and LFInfo + -- between modules] in GHC.StgToCmm.Types for how we implement + -- cross-module LFI passing. } -- Setters @@ -295,13 +316,18 @@ setUnfoldingInfo info uf setArityInfo :: IdInfo -> ArityInfo -> IdInfo setArityInfo info ar = info { arityInfo = ar } + setCallArityInfo :: IdInfo -> ArityInfo -> IdInfo setCallArityInfo info ar = info { callArityInfo = ar } + setCafInfo :: IdInfo -> CafInfo -> IdInfo -setCafInfo info caf = info { cafInfo = caf } +setCafInfo info caf = info { cafInfo = caf } + +setLFInfo :: IdInfo -> LambdaFormInfo -> IdInfo +setLFInfo info lf = info { lfInfo = Just lf } setOneShotInfo :: IdInfo -> OneShotInfo -> IdInfo -setOneShotInfo info lb = {-lb `seq`-} info { oneShotInfo = lb } +setOneShotInfo info lb = {-lb `seq`-} info { oneShotInfo = lb } setDemandInfo :: IdInfo -> Demand -> IdInfo setDemandInfo info dd = dd `seq` info { demandInfo = dd } @@ -327,7 +353,8 @@ vanillaIdInfo strictnessInfo = nopSig, cprInfo = topCprSig, callArityInfo = unknownArity, - levityInfo = NoLevityInfo + levityInfo = NoLevityInfo, + lfInfo = Nothing } -- | More informative 'IdInfo' we can use when we know the 'Id' has no CAF references ===================================== compiler/ghc.cabal.in ===================================== @@ -228,7 +228,7 @@ Library GHC.Types.SrcLoc GHC.Types.Unique.Supply GHC.Types.Unique - GHC.Iface.UpdateCafInfos + GHC.Iface.UpdateIdInfos GHC.Types.Var GHC.Types.Var.Env GHC.Types.Var.Set @@ -295,6 +295,7 @@ Library GHC.StgToCmm.Ticky GHC.StgToCmm.Utils GHC.StgToCmm.ExtCode + GHC.StgToCmm.Types GHC.Runtime.Heap.Layout GHC.Core.Arity GHC.Core.FVs ===================================== testsuite/tests/codeGen/should_compile/Makefile ===================================== @@ -64,10 +64,10 @@ T17648: # NoCafRefs) to the interface files. '$(TEST_HC)' $(TEST_HC_OPTS) -dno-typeable-binds -O T17648.hs -v0 '$(TEST_HC)' --show-iface T17648.hi | tr -d '\n\r' | \ - grep -F 'f :: T GHC.Types.Int -> () [HasNoCafRefs, Arity' >/dev/null + grep -F 'f :: T GHC.Types.Int -> () [HasNoCafRefs, LambdaFormInfo' >/dev/null # Second compilation with -fcatch-bottoms, f should be CAFFY '$(TEST_HC)' $(TEST_HC_OPTS) -dno-typeable-binds -O \ -fcatch-bottoms T17648.hs -v0 -fforce-recomp '$(TEST_HC)' --show-iface T17648.hi | tr -d '\n\r' | \ - grep -F 'f :: T GHC.Types.Int -> () [Arity: 1, Strictness' >/dev/null + grep -F 'f :: T GHC.Types.Int -> () [LambdaFormInfo' >/dev/null ===================================== testsuite/tests/codeGen/should_compile/cg009/A.hs ===================================== @@ -0,0 +1,5 @@ +module A where + +newtype A = A Int + +val = A 42 ===================================== testsuite/tests/codeGen/should_compile/cg009/Main.hs ===================================== @@ -0,0 +1,7 @@ +module Main where + +import A + +main = return () + +a = val ===================================== testsuite/tests/codeGen/should_compile/cg009/Makefile ===================================== @@ -0,0 +1,9 @@ +TOP=../../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +# Make sure the LFInfo for an exported, but not directly used newtype +# constructors does not trip up the compiler. +cg009: + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O A.hs -fforce-recomp + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O0 Main.hs -fforce-recomp ===================================== testsuite/tests/codeGen/should_compile/cg009/all.T ===================================== @@ -0,0 +1 @@ +test('cg009', [extra_files(['A.hs','Main.hs'])], makefile_test, ['cg009']) ===================================== testsuite/tests/codeGen/should_compile/cg010/A.hs ===================================== @@ -0,0 +1,4 @@ +module A where + +{-# NOINLINE val #-} +val = Just 42 ===================================== testsuite/tests/codeGen/should_compile/cg010/Main.hs ===================================== @@ -0,0 +1,7 @@ +module Main where + +import A + +main = return () + +a = val ===================================== testsuite/tests/codeGen/should_compile/cg010/Makefile ===================================== @@ -0,0 +1,9 @@ +TOP=../../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +# Make sure LFInfo causes the imported reference to val to get tagged. +cg010: + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O A.hs -fforce-recomp + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O Main.hs -fforce-recomp -ddump-cmm -ddump-to-file + grep "A.val_closure+2" Main.dump-cmm ===================================== testsuite/tests/codeGen/should_compile/cg010/all.T ===================================== @@ -0,0 +1 @@ +test('cg010', [extra_files(['A.hs','Main.hs'])], makefile_test, ['cg010']) ===================================== testsuite/tests/codeGen/should_compile/cg010/cg010.stdout ===================================== @@ -0,0 +1 @@ + const A.val_closure+2; ===================================== testsuite/tests/simplCore/should_compile/Makefile ===================================== @@ -107,7 +107,7 @@ T4201: '$(TEST_HC)' $(TEST_HC_OPTS) -c -O T4201.hs '$(TEST_HC)' $(TEST_HC_OPTS) --show-iface T4201.hi > T4201.list # poor man idea about how to replace GNU grep -B2 "Sym" invocation with pure POSIX tools - for i in `grep -n "Sym" T4201.list |cut -d ':' -f -1`; do head -$$i T4201.list | tail -3 ; done + for i in `grep -n "Sym" T4201.list | cut -d ':' -f -1`; do head -$$i T4201.list | tail -4; done $(RM) -f T4201.list # This one looped as a result of bogus specialisation ===================================== testsuite/tests/simplCore/should_compile/T4201.stdout ===================================== @@ -1,3 +1,4 @@ - [HasNoCafRefs, Arity: 1, Strictness: , + [HasNoCafRefs, LambdaFormInfo: LFReEntrant 1, Arity: 1, + Strictness: , Unfolding: InlineRule (0, True, True) bof `cast` (Sym (N:Foo[0]) ->_R _R)] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0ba1d26ac9da8ff25bf6de590997cb7791d4f764 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0ba1d26ac9da8ff25bf6de590997cb7791d4f764 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 1 13:50:08 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Fri, 01 May 2020 09:50:08 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18120 Message-ID: <5eac29106ece0_6167e5b152c831268@gitlab.haskell.org.mail> Simon Peyton Jones pushed new branch wip/T18120 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18120 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 1 13:52:02 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Fri, 01 May 2020 09:52:02 -0400 Subject: [Git][ghc/ghc][wip/T18120] 21 commits: Define a Quote IO instance Message-ID: <5eac29828eecc_6167c5ce1b083128bf@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T18120 at Glasgow Haskell Compiler / GHC Commits: 4b9764db by Ryan Scott at 2020-04-28T15:40:04-04:00 Define a Quote IO instance Fixes #18103. - - - - - 518a63d4 by Ryan Scott at 2020-04-28T15:40:42-04:00 Make boxed 1-tuples have known keys Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. - - - - - 2cfc4ab9 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Document backpack fields in DynFlags - - - - - 10a2ba90 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 69562e34 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 9e2c8e0e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - ea717aa4 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 10d15f1e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 8bfb0219 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - 71484b09 by Alexis King at 2020-04-30T01:57:35-04:00 Allow block arguments in arrow control operators Arrow control operators have their own entries in the grammar, so they did not cooperate with BlockArguments. This was just a minor oversight, so this patch adjusts the grammar to add the desired behavior. fixes #18050 - - - - - a48cd2a0 by Alexis King at 2020-04-30T01:57:35-04:00 Allow LambdaCase to be used as a command in proc notation - - - - - f4d3773c by Alexis King at 2020-04-30T01:57:35-04:00 Document BlockArguments/LambdaCase support in arrow notation - - - - - 5bdfdd13 by Simon Peyton Jones at 2020-04-30T01:58:15-04:00 Add tests for #17873 - - - - - 19b701c2 by Simon Peyton Jones at 2020-04-30T07:30:13-04:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - 014ef4a3 by Matthew Pickering at 2020-04-30T07:30:50-04:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 2aa67611 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - 54dad3cf by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - 99ff8145 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 05b0a9fd by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 Remove OneShotInfo field of LFReEntrant, document OneShotInfo The field is only used in withNewTickyCounterFun and it's easier to directly pass a parameter for one-shot info to withNewTickyCounterFun instead of passing it via LFReEntrant. This also makes !2842 simpler. Other changes: - New Note (by SPJ) [OneShotInfo overview] added. - Arity argument of thunkCode removed as it's always 0. - - - - - a43620c6 by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 GHC.StgToCmm.Ticky: remove a few unused stuff - - - - - 344ac8b1 by Simon Peyton Jones at 2020-05-01T14:51:59+01:00 Fix specialisation for DFuns When specialising a DFun we must take care to saturate the unfolding. See Note [Specialising DFuns] in Specialise. Fixes #18120 - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Utils.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Config.hs - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/Core.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Opt/Driver.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/SimpleOpt.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/21c654d9097e5c2feafc790b65e595f9f2e2777f...344ac8b1c281595c2bd34afe3817c11539361ffb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/21c654d9097e5c2feafc790b65e595f9f2e2777f...344ac8b1c281595c2bd34afe3817c11539361ffb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 1 14:20:15 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Fri, 01 May 2020 10:20:15 -0400 Subject: [Git][ghc/ghc][wip/T18120] Fix specialisation for DFuns Message-ID: <5eac301f61284_6167c5ce1b0832069f@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T18120 at Glasgow Haskell Compiler / GHC Commits: a47b226c by Simon Peyton Jones at 2020-05-01T15:18:41+01:00 Fix specialisation for DFuns When specialising a DFun we must take care to saturate the unfolding. See Note [Specialising DFuns] in Specialise. Fixes #18120 - - - - - 6 changed files: - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/Tc/Gen/Sig.hs - + testsuite/tests/simplCore/should_compile/T18120.hs - testsuite/tests/simplCore/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Opt/Specialise.hs ===================================== @@ -1362,6 +1362,7 @@ specCalls mb_mod env existing_rules calls_for_me fn rhs inl_prag = idInlinePragma fn inl_act = inlinePragmaActivation inl_prag is_local = isLocalId fn + is_dfun = isDFunId fn -- Figure out whether the function has an INLINE pragma -- See Note [Inline specialisations] @@ -1384,22 +1385,34 @@ specCalls mb_mod env existing_rules calls_for_me fn rhs spec_call :: SpecInfo -- Accumulating parameter -> CallInfo -- Call instance -> SpecM SpecInfo - spec_call spec_acc@(rules_acc, pairs_acc, uds_acc) (CI { ci_key = call_args }) + spec_call spec_acc@(rules_acc, pairs_acc, uds_acc) ci@(CI { ci_key = call_args }) = -- See Note [Specialising Calls] - do { ( useful, rhs_env2, leftover_bndrs + do { let all_call_args | is_dfun = call_args ++ repeat UnspecArg + | otherwise = call_args + -- See Note [Specialising DFuns] + ; ( useful, rhs_env2, leftover_bndrs , rule_bndrs, rule_lhs_args - , spec_bndrs, dx_binds, spec_args) <- specHeader env rhs_bndrs call_args + , spec_bndrs1, dx_binds, spec_args) <- specHeader env rhs_bndrs all_call_args + +-- ; pprTrace "spec_call" (vcat [ text "call info: " <+> ppr ci +-- , text "useful: " <+> ppr useful +-- , text "rule_bndrs:" <+> ppr rule_bndrs +-- , text "lhs_args: " <+> ppr rule_lhs_args +-- , text "spec_bndrs:" <+> ppr spec_bndrs1 +-- , text "spec_args: " <+> ppr spec_args +-- , text "dx_binds: " <+> ppr dx_binds +-- , text "rhs_env2: " <+> ppr (se_subst rhs_env2) +-- , ppr dx_binds ]) $ +-- return () ; dflags <- getDynFlags ; if not useful -- No useful specialisation || already_covered dflags rules_acc rule_lhs_args then return spec_acc - else -- pprTrace "spec_call" (vcat [ ppr _call_info, ppr fn, ppr rhs_dict_ids - -- , text "rhs_env2" <+> ppr (se_subst rhs_env2) - -- , ppr dx_binds ]) $ + else do { -- Run the specialiser on the specialised RHS -- The "1" suffix is before we maybe add the void arg - ; (spec_rhs1, rhs_uds) <- specLam rhs_env2 (spec_bndrs ++ leftover_bndrs) rhs_body + ; (spec_rhs1, rhs_uds) <- specLam rhs_env2 (spec_bndrs1 ++ leftover_bndrs) rhs_body ; let spec_fn_ty1 = exprType spec_rhs1 -- Maybe add a void arg to the specialised function, @@ -1407,14 +1420,13 @@ specCalls mb_mod env existing_rules calls_for_me fn rhs -- See Note [Specialisations Must Be Lifted] -- C.f. GHC.Core.Opt.WorkWrap.Utils.mkWorkerArgs add_void_arg = isUnliftedType spec_fn_ty1 && not (isJoinId fn) - (spec_rhs, spec_fn_ty, rule_rhs_args) - | add_void_arg = ( Lam voidArgId spec_rhs1 - , mkVisFunTy voidPrimTy spec_fn_ty1 - , voidPrimId : spec_bndrs) - | otherwise = (spec_rhs1, spec_fn_ty1, spec_bndrs) - - arity_decr = count isValArg rule_lhs_args - count isId rule_rhs_args - join_arity_decr = length rule_lhs_args - length rule_rhs_args + (spec_bndrs, spec_rhs, spec_fn_ty) + | add_void_arg = ( voidPrimId : spec_bndrs1 + , Lam voidArgId spec_rhs1 + , mkVisFunTy voidPrimTy spec_fn_ty1) + | otherwise = (spec_bndrs1, spec_rhs1, spec_fn_ty1) + + join_arity_decr = length rule_lhs_args - length spec_bndrs spec_join_arity | Just orig_join_arity <- isJoinId_maybe fn = Just (orig_join_arity - join_arity_decr) | otherwise @@ -1449,7 +1461,7 @@ specCalls mb_mod env existing_rules calls_for_me fn rhs (idName fn) rule_bndrs rule_lhs_args - (mkVarApps (Var spec_fn) rule_rhs_args) + (mkVarApps (Var spec_fn) spec_bndrs) spec_rule = case isJoinId_maybe fn of @@ -1472,15 +1484,15 @@ specCalls mb_mod env existing_rules calls_for_me fn rhs = (inl_prag { inl_inline = NoUserInline }, noUnfolding) | otherwise - = (inl_prag, specUnfolding dflags fn spec_bndrs spec_app arity_decr fn_unf) - - spec_app e = e `mkApps` spec_args + = (inl_prag, specUnfolding dflags spec_bndrs (`mkApps` spec_args) + rule_lhs_args fn_unf) -------------------------------------- -- Adding arity information just propagates it a bit faster -- See Note [Arity decrease] in GHC.Core.Opt.Simplify -- Copy InlinePragma information from the parent Id. -- So if f has INLINE[1] so does spec_fn + arity_decr = count isValArg rule_lhs_args - count isId spec_bndrs spec_f_w_arity = spec_fn `setIdArity` max 0 (fn_arity - arity_decr) `setInlinePragma` spec_inl_prag `setIdUnfolding` spec_unf @@ -1498,8 +1510,19 @@ specCalls mb_mod env existing_rules calls_for_me fn rhs , spec_uds `plusUDs` uds_acc ) } } -{- Note [Specialisation Must Preserve Sharing] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [Specialising DFuns] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +DFuns have a special sort of unfolding (DFunUnfolding), and these are +hard to specialise a DFunUnfolding to give another DFunUnfolding +unless the DFun is fully applied (#18120). So, in the case of DFunIds +we simply extend the CallKey with trailing UnspecArgs, so we'll +generate a rule that completely saturates the DFun. + +There is an ASSERT that checks this, in the DFunUnfolding case of +GHC.Core.Unfold.specUnfolding. + +Note [Specialisation Must Preserve Sharing] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider a function: f :: forall a. Eq a => a -> blah @@ -2089,7 +2112,7 @@ isSpecDict _ = False -- -- Specialised function helpers -- , [c, i, x] -- , [dShow1 = $dfShow dShowT2] --- , [T1, T2, dEqT1, dShow1] +-- , [T1, T2, c, i, dEqT1, dShow1] -- ) specHeader :: SpecEnv @@ -2106,12 +2129,13 @@ specHeader -- RULE helpers , [OutBndr] -- Binders for the RULE - , [CoreArg] -- Args for the LHS of the rule + , [OutExpr] -- Args for the LHS of the rule -- Specialised function helpers , [OutBndr] -- Binders for $sf , [DictBind] -- Auxiliary dictionary bindings , [OutExpr] -- Specialised arguments for unfolding + -- Same length as "args for LHS of rule" ) -- We want to specialise on type 'T1', and so we must construct a substitution ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -173,47 +173,47 @@ mkInlinableUnfolding dflags expr where expr' = simpleOptExpr dflags expr -specUnfolding :: DynFlags -> Id -> [Var] -> (CoreExpr -> CoreExpr) -> Arity +specUnfolding :: DynFlags + -> [Var] -> (CoreExpr -> CoreExpr) + -> [CoreArg] -- LHS arguments in the RULE -> Unfolding -> Unfolding -- See Note [Specialising unfoldings] --- specUnfolding spec_bndrs spec_app arity_decrease unf --- = \spec_bndrs. spec_app( unf ) +-- specUnfolding spec_bndrs spec_args unf +-- = \spec_bndrs. unf spec_args -- -specUnfolding dflags fn spec_bndrs spec_app arity_decrease +specUnfolding dflags spec_bndrs spec_app rule_lhs_args df@(DFunUnfolding { df_bndrs = old_bndrs, df_con = con, df_args = args }) - = ASSERT2( arity_decrease == count isId old_bndrs - count isId spec_bndrs - , ppr df $$ ppr spec_bndrs $$ ppr (spec_app (Var fn)) $$ ppr arity_decrease ) + = ASSERT2( rule_lhs_args `equalLength` old_bndrs + , ppr df $$ ppr rule_lhs_args ) + -- For this ASSERT see Note [DFunUnfoldings] in GHC.Core.Opt.Specialise mkDFunUnfolding spec_bndrs con (map spec_arg args) - -- There is a hard-to-check assumption here that the spec_app has - -- enough applications to exactly saturate the old_bndrs -- For DFunUnfoldings we transform - -- \old_bndrs. MkD ... + -- \obs. MkD ... -- to - -- \new_bndrs. MkD (spec_app(\old_bndrs. )) ... ditto - -- The ASSERT checks the value part of that + -- \sbs. MkD ((\obs. ) spec_args) ... ditto where - spec_arg arg = simpleOptExpr dflags (spec_app (mkLams old_bndrs arg)) + spec_arg arg = simpleOptExpr dflags $ + spec_app (mkLams old_bndrs arg) -- The beta-redexes created by spec_app will be -- simplified away by simplOptExpr -specUnfolding dflags _ spec_bndrs spec_app arity_decrease +specUnfolding dflags spec_bndrs spec_app rule_lhs_args (CoreUnfolding { uf_src = src, uf_tmpl = tmpl , uf_is_top = top_lvl , uf_guidance = old_guidance }) | isStableSource src -- See Note [Specialising unfoldings] - , UnfWhen { ug_arity = old_arity - , ug_unsat_ok = unsat_ok - , ug_boring_ok = boring_ok } <- old_guidance - = let guidance = UnfWhen { ug_arity = old_arity - arity_decrease - , ug_unsat_ok = unsat_ok - , ug_boring_ok = boring_ok } - new_tmpl = simpleOptExpr dflags (mkLams spec_bndrs (spec_app tmpl)) - -- The beta-redexes created by spec_app will be - -- simplified away by simplOptExpr + , UnfWhen { ug_arity = old_arity } <- old_guidance + = mkCoreUnfolding src top_lvl new_tmpl + (old_guidance { ug_arity = old_arity - arity_decrease }) + where + new_tmpl = simpleOptExpr dflags $ + mkLams spec_bndrs $ + spec_app tmpl -- The beta-redexes created by spec_app + -- will besimplified away by simplOptExpr + arity_decrease = count isValArg rule_lhs_args - count isId spec_bndrs - in mkCoreUnfolding src top_lvl new_tmpl guidance -specUnfolding _ _ _ _ _ _ = noUnfolding +specUnfolding _ _ _ _ _ = noUnfolding {- Note [Specialising unfoldings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/HsToCore/Binds.hs ===================================== @@ -694,20 +694,19 @@ dsSpec mb_poly_rhs (L loc (SpecPrag poly_id spec_co spec_inl)) dflags <- getDynFlags ; case decomposeRuleLhs dflags spec_bndrs ds_lhs of { Left msg -> do { warnDs NoReason msg; return Nothing } ; - Right (rule_bndrs, _fn, args) -> do + Right (rule_bndrs, _fn, rule_lhs_args) -> do { this_mod <- getModule ; let fn_unf = realIdUnfolding poly_id - spec_unf = specUnfolding dflags poly_id spec_bndrs core_app arity_decrease fn_unf + spec_unf = specUnfolding dflags spec_bndrs core_app rule_lhs_args fn_unf spec_id = mkLocalId spec_name spec_ty `setInlinePragma` inl_prag `setIdUnfolding` spec_unf - arity_decrease = count isValArg args - count isId spec_bndrs ; rule <- dsMkUserRule this_mod is_local_id (mkFastString ("SPEC " ++ showPpr dflags poly_name)) rule_act poly_name - rule_bndrs args + rule_bndrs rule_lhs_args (mkVarApps (Var spec_id) spec_bndrs) ; let spec_rhs = mkLams spec_bndrs (core_app poly_rhs) ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -634,7 +634,6 @@ to connect the two, something like This wrapper is put in the TcSpecPrag, in the ABExport record of the AbsBinds. - f :: (Eq a, Ix b) => a -> b -> Bool {-# SPECIALISE f :: (Ix p, Ix q) => Int -> (p,q) -> Bool #-} f = @@ -662,8 +661,6 @@ Note that * The RHS of f_spec, has a *copy* of 'binds', so that it can fully specialise it. - - From the TcSpecPrag, in GHC.HsToCore.Binds we generate a binding for f_spec and a RULE: f_spec :: Int -> b -> Int @@ -702,14 +699,14 @@ Some wrinkles So we simply do this: - Generate a constraint to check that the specialised type (after - skolemiseation) is equal to the instantiated function type. + skolemisation) is equal to the instantiated function type. - But *discard* the evidence (coercion) for that constraint, so that we ultimately generate the simpler code f_spec :: Int -> F Int f_spec = Int dNumInt RULE: forall d. f Int d = f_spec - You can see this discarding happening in + You can see this discarding happening in tcSpecPrag 3. Note that the HsWrapper can transform *any* function with the right type prefix ===================================== testsuite/tests/simplCore/should_compile/T18120.hs ===================================== @@ -0,0 +1,34 @@ +{-# LANGUAGE ConstraintKinds #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeOperators #-} +{-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE UndecidableSuperClasses #-} +module Bug where + +import Data.Kind + +type family + AllF (c :: k -> Constraint) (xs :: [k]) :: Constraint where + AllF _c '[] = () + AllF c (x ': xs) = (c x, All c xs) + +class (AllF c xs, SListI xs) => All (c :: k -> Constraint) (xs :: [k]) where +instance All c '[] where +instance (c x, All c xs) => All c (x ': xs) where + +class Top x +instance Top x + +type SListI = All Top + +class All SListI (Code a) => Generic (a :: Type) where + type Code a :: [[Type]] + +data T = MkT Int +instance Generic T where + type Code T = '[ '[Int] ] ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -318,3 +318,4 @@ test('T17966', test('T17810', normal, multimod_compile, ['T17810', '-fspecialise-aggressively -dcore-lint -O -v0']) test('T18013', normal, multimod_compile, ['T18013', '-v0 -O']) test('T18098', normal, compile, ['-dcore-lint -O2']) +test('T18120', normal, compile, ['-dcore-lint -O']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a47b226c654d0125596f5f0c90b4958128aa558c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a47b226c654d0125596f5f0c90b4958128aa558c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 1 14:29:06 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Fri, 01 May 2020 10:29:06 -0400 Subject: [Git][ghc/ghc][wip/T18120] Fix specialisation for DFuns Message-ID: <5eac32329f306_61673f81cd9bfa6c832535d@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T18120 at Glasgow Haskell Compiler / GHC Commits: 7e77aca9 by Simon Peyton Jones at 2020-05-01T15:28:40+01:00 Fix specialisation for DFuns When specialising a DFun we must take care to saturate the unfolding. See Note [Specialising DFuns] in Specialise. Fixes #18120 - - - - - 6 changed files: - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/Tc/Gen/Sig.hs - + testsuite/tests/simplCore/should_compile/T18120.hs - testsuite/tests/simplCore/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Opt/Specialise.hs ===================================== @@ -1362,6 +1362,7 @@ specCalls mb_mod env existing_rules calls_for_me fn rhs inl_prag = idInlinePragma fn inl_act = inlinePragmaActivation inl_prag is_local = isLocalId fn + is_dfun = isDFunId fn -- Figure out whether the function has an INLINE pragma -- See Note [Inline specialisations] @@ -1384,22 +1385,34 @@ specCalls mb_mod env existing_rules calls_for_me fn rhs spec_call :: SpecInfo -- Accumulating parameter -> CallInfo -- Call instance -> SpecM SpecInfo - spec_call spec_acc@(rules_acc, pairs_acc, uds_acc) (CI { ci_key = call_args }) + spec_call spec_acc@(rules_acc, pairs_acc, uds_acc) _ci@(CI { ci_key = call_args }) = -- See Note [Specialising Calls] - do { ( useful, rhs_env2, leftover_bndrs + do { let all_call_args | is_dfun = call_args ++ repeat UnspecArg + | otherwise = call_args + -- See Note [Specialising DFuns] + ; ( useful, rhs_env2, leftover_bndrs , rule_bndrs, rule_lhs_args - , spec_bndrs, dx_binds, spec_args) <- specHeader env rhs_bndrs call_args + , spec_bndrs1, dx_binds, spec_args) <- specHeader env rhs_bndrs all_call_args + +-- ; pprTrace "spec_call" (vcat [ text "call info: " <+> ppr _ci +-- , text "useful: " <+> ppr useful +-- , text "rule_bndrs:" <+> ppr rule_bndrs +-- , text "lhs_args: " <+> ppr rule_lhs_args +-- , text "spec_bndrs:" <+> ppr spec_bndrs1 +-- , text "spec_args: " <+> ppr spec_args +-- , text "dx_binds: " <+> ppr dx_binds +-- , text "rhs_env2: " <+> ppr (se_subst rhs_env2) +-- , ppr dx_binds ]) $ +-- return () ; dflags <- getDynFlags ; if not useful -- No useful specialisation || already_covered dflags rules_acc rule_lhs_args then return spec_acc - else -- pprTrace "spec_call" (vcat [ ppr _call_info, ppr fn, ppr rhs_dict_ids - -- , text "rhs_env2" <+> ppr (se_subst rhs_env2) - -- , ppr dx_binds ]) $ + else do { -- Run the specialiser on the specialised RHS -- The "1" suffix is before we maybe add the void arg - ; (spec_rhs1, rhs_uds) <- specLam rhs_env2 (spec_bndrs ++ leftover_bndrs) rhs_body + ; (spec_rhs1, rhs_uds) <- specLam rhs_env2 (spec_bndrs1 ++ leftover_bndrs) rhs_body ; let spec_fn_ty1 = exprType spec_rhs1 -- Maybe add a void arg to the specialised function, @@ -1407,14 +1420,13 @@ specCalls mb_mod env existing_rules calls_for_me fn rhs -- See Note [Specialisations Must Be Lifted] -- C.f. GHC.Core.Opt.WorkWrap.Utils.mkWorkerArgs add_void_arg = isUnliftedType spec_fn_ty1 && not (isJoinId fn) - (spec_rhs, spec_fn_ty, rule_rhs_args) - | add_void_arg = ( Lam voidArgId spec_rhs1 - , mkVisFunTy voidPrimTy spec_fn_ty1 - , voidPrimId : spec_bndrs) - | otherwise = (spec_rhs1, spec_fn_ty1, spec_bndrs) - - arity_decr = count isValArg rule_lhs_args - count isId rule_rhs_args - join_arity_decr = length rule_lhs_args - length rule_rhs_args + (spec_bndrs, spec_rhs, spec_fn_ty) + | add_void_arg = ( voidPrimId : spec_bndrs1 + , Lam voidArgId spec_rhs1 + , mkVisFunTy voidPrimTy spec_fn_ty1) + | otherwise = (spec_bndrs1, spec_rhs1, spec_fn_ty1) + + join_arity_decr = length rule_lhs_args - length spec_bndrs spec_join_arity | Just orig_join_arity <- isJoinId_maybe fn = Just (orig_join_arity - join_arity_decr) | otherwise @@ -1449,7 +1461,7 @@ specCalls mb_mod env existing_rules calls_for_me fn rhs (idName fn) rule_bndrs rule_lhs_args - (mkVarApps (Var spec_fn) rule_rhs_args) + (mkVarApps (Var spec_fn) spec_bndrs) spec_rule = case isJoinId_maybe fn of @@ -1472,15 +1484,15 @@ specCalls mb_mod env existing_rules calls_for_me fn rhs = (inl_prag { inl_inline = NoUserInline }, noUnfolding) | otherwise - = (inl_prag, specUnfolding dflags fn spec_bndrs spec_app arity_decr fn_unf) - - spec_app e = e `mkApps` spec_args + = (inl_prag, specUnfolding dflags spec_bndrs (`mkApps` spec_args) + rule_lhs_args fn_unf) -------------------------------------- -- Adding arity information just propagates it a bit faster -- See Note [Arity decrease] in GHC.Core.Opt.Simplify -- Copy InlinePragma information from the parent Id. -- So if f has INLINE[1] so does spec_fn + arity_decr = count isValArg rule_lhs_args - count isId spec_bndrs spec_f_w_arity = spec_fn `setIdArity` max 0 (fn_arity - arity_decr) `setInlinePragma` spec_inl_prag `setIdUnfolding` spec_unf @@ -1498,8 +1510,19 @@ specCalls mb_mod env existing_rules calls_for_me fn rhs , spec_uds `plusUDs` uds_acc ) } } -{- Note [Specialisation Must Preserve Sharing] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [Specialising DFuns] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +DFuns have a special sort of unfolding (DFunUnfolding), and these are +hard to specialise a DFunUnfolding to give another DFunUnfolding +unless the DFun is fully applied (#18120). So, in the case of DFunIds +we simply extend the CallKey with trailing UnspecArgs, so we'll +generate a rule that completely saturates the DFun. + +There is an ASSERT that checks this, in the DFunUnfolding case of +GHC.Core.Unfold.specUnfolding. + +Note [Specialisation Must Preserve Sharing] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider a function: f :: forall a. Eq a => a -> blah @@ -2089,7 +2112,7 @@ isSpecDict _ = False -- -- Specialised function helpers -- , [c, i, x] -- , [dShow1 = $dfShow dShowT2] --- , [T1, T2, dEqT1, dShow1] +-- , [T1, T2, c, i, dEqT1, dShow1] -- ) specHeader :: SpecEnv @@ -2106,12 +2129,13 @@ specHeader -- RULE helpers , [OutBndr] -- Binders for the RULE - , [CoreArg] -- Args for the LHS of the rule + , [OutExpr] -- Args for the LHS of the rule -- Specialised function helpers , [OutBndr] -- Binders for $sf , [DictBind] -- Auxiliary dictionary bindings , [OutExpr] -- Specialised arguments for unfolding + -- Same length as "args for LHS of rule" ) -- We want to specialise on type 'T1', and so we must construct a substitution ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -173,47 +173,47 @@ mkInlinableUnfolding dflags expr where expr' = simpleOptExpr dflags expr -specUnfolding :: DynFlags -> Id -> [Var] -> (CoreExpr -> CoreExpr) -> Arity +specUnfolding :: DynFlags + -> [Var] -> (CoreExpr -> CoreExpr) + -> [CoreArg] -- LHS arguments in the RULE -> Unfolding -> Unfolding -- See Note [Specialising unfoldings] --- specUnfolding spec_bndrs spec_app arity_decrease unf --- = \spec_bndrs. spec_app( unf ) +-- specUnfolding spec_bndrs spec_args unf +-- = \spec_bndrs. unf spec_args -- -specUnfolding dflags fn spec_bndrs spec_app arity_decrease +specUnfolding dflags spec_bndrs spec_app rule_lhs_args df@(DFunUnfolding { df_bndrs = old_bndrs, df_con = con, df_args = args }) - = ASSERT2( arity_decrease == count isId old_bndrs - count isId spec_bndrs - , ppr df $$ ppr spec_bndrs $$ ppr (spec_app (Var fn)) $$ ppr arity_decrease ) + = ASSERT2( rule_lhs_args `equalLength` old_bndrs + , ppr df $$ ppr rule_lhs_args ) + -- For this ASSERT see Note [DFunUnfoldings] in GHC.Core.Opt.Specialise mkDFunUnfolding spec_bndrs con (map spec_arg args) - -- There is a hard-to-check assumption here that the spec_app has - -- enough applications to exactly saturate the old_bndrs -- For DFunUnfoldings we transform - -- \old_bndrs. MkD ... + -- \obs. MkD ... -- to - -- \new_bndrs. MkD (spec_app(\old_bndrs. )) ... ditto - -- The ASSERT checks the value part of that + -- \sbs. MkD ((\obs. ) spec_args) ... ditto where - spec_arg arg = simpleOptExpr dflags (spec_app (mkLams old_bndrs arg)) + spec_arg arg = simpleOptExpr dflags $ + spec_app (mkLams old_bndrs arg) -- The beta-redexes created by spec_app will be -- simplified away by simplOptExpr -specUnfolding dflags _ spec_bndrs spec_app arity_decrease +specUnfolding dflags spec_bndrs spec_app rule_lhs_args (CoreUnfolding { uf_src = src, uf_tmpl = tmpl , uf_is_top = top_lvl , uf_guidance = old_guidance }) | isStableSource src -- See Note [Specialising unfoldings] - , UnfWhen { ug_arity = old_arity - , ug_unsat_ok = unsat_ok - , ug_boring_ok = boring_ok } <- old_guidance - = let guidance = UnfWhen { ug_arity = old_arity - arity_decrease - , ug_unsat_ok = unsat_ok - , ug_boring_ok = boring_ok } - new_tmpl = simpleOptExpr dflags (mkLams spec_bndrs (spec_app tmpl)) - -- The beta-redexes created by spec_app will be - -- simplified away by simplOptExpr + , UnfWhen { ug_arity = old_arity } <- old_guidance + = mkCoreUnfolding src top_lvl new_tmpl + (old_guidance { ug_arity = old_arity - arity_decrease }) + where + new_tmpl = simpleOptExpr dflags $ + mkLams spec_bndrs $ + spec_app tmpl -- The beta-redexes created by spec_app + -- will besimplified away by simplOptExpr + arity_decrease = count isValArg rule_lhs_args - count isId spec_bndrs - in mkCoreUnfolding src top_lvl new_tmpl guidance -specUnfolding _ _ _ _ _ _ = noUnfolding +specUnfolding _ _ _ _ _ = noUnfolding {- Note [Specialising unfoldings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/HsToCore/Binds.hs ===================================== @@ -694,20 +694,19 @@ dsSpec mb_poly_rhs (L loc (SpecPrag poly_id spec_co spec_inl)) dflags <- getDynFlags ; case decomposeRuleLhs dflags spec_bndrs ds_lhs of { Left msg -> do { warnDs NoReason msg; return Nothing } ; - Right (rule_bndrs, _fn, args) -> do + Right (rule_bndrs, _fn, rule_lhs_args) -> do { this_mod <- getModule ; let fn_unf = realIdUnfolding poly_id - spec_unf = specUnfolding dflags poly_id spec_bndrs core_app arity_decrease fn_unf + spec_unf = specUnfolding dflags spec_bndrs core_app rule_lhs_args fn_unf spec_id = mkLocalId spec_name spec_ty `setInlinePragma` inl_prag `setIdUnfolding` spec_unf - arity_decrease = count isValArg args - count isId spec_bndrs ; rule <- dsMkUserRule this_mod is_local_id (mkFastString ("SPEC " ++ showPpr dflags poly_name)) rule_act poly_name - rule_bndrs args + rule_bndrs rule_lhs_args (mkVarApps (Var spec_id) spec_bndrs) ; let spec_rhs = mkLams spec_bndrs (core_app poly_rhs) ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -634,7 +634,6 @@ to connect the two, something like This wrapper is put in the TcSpecPrag, in the ABExport record of the AbsBinds. - f :: (Eq a, Ix b) => a -> b -> Bool {-# SPECIALISE f :: (Ix p, Ix q) => Int -> (p,q) -> Bool #-} f = @@ -662,8 +661,6 @@ Note that * The RHS of f_spec, has a *copy* of 'binds', so that it can fully specialise it. - - From the TcSpecPrag, in GHC.HsToCore.Binds we generate a binding for f_spec and a RULE: f_spec :: Int -> b -> Int @@ -702,14 +699,14 @@ Some wrinkles So we simply do this: - Generate a constraint to check that the specialised type (after - skolemiseation) is equal to the instantiated function type. + skolemisation) is equal to the instantiated function type. - But *discard* the evidence (coercion) for that constraint, so that we ultimately generate the simpler code f_spec :: Int -> F Int f_spec = Int dNumInt RULE: forall d. f Int d = f_spec - You can see this discarding happening in + You can see this discarding happening in tcSpecPrag 3. Note that the HsWrapper can transform *any* function with the right type prefix ===================================== testsuite/tests/simplCore/should_compile/T18120.hs ===================================== @@ -0,0 +1,34 @@ +{-# LANGUAGE ConstraintKinds #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeOperators #-} +{-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE UndecidableSuperClasses #-} +module Bug where + +import Data.Kind + +type family + AllF (c :: k -> Constraint) (xs :: [k]) :: Constraint where + AllF _c '[] = () + AllF c (x ': xs) = (c x, All c xs) + +class (AllF c xs, SListI xs) => All (c :: k -> Constraint) (xs :: [k]) where +instance All c '[] where +instance (c x, All c xs) => All c (x ': xs) where + +class Top x +instance Top x + +type SListI = All Top + +class All SListI (Code a) => Generic (a :: Type) where + type Code a :: [[Type]] + +data T = MkT Int +instance Generic T where + type Code T = '[ '[Int] ] ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -318,3 +318,4 @@ test('T17966', test('T17810', normal, multimod_compile, ['T17810', '-fspecialise-aggressively -dcore-lint -O -v0']) test('T18013', normal, multimod_compile, ['T18013', '-v0 -O']) test('T18098', normal, compile, ['-dcore-lint -O2']) +test('T18120', normal, compile, ['-dcore-lint -O']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7e77aca97127a65b574417a0fb25d18e8ddc4b1e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7e77aca97127a65b574417a0fb25d18e8ddc4b1e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 1 14:37:48 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 01 May 2020 10:37:48 -0400 Subject: [Git][ghc/ghc][master] 4 commits: Use platform in Iface Binary Message-ID: <5eac343c4ae8c_61673f81cd4c695c832951b@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 780de9e1 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Use platform in Iface Binary - - - - - f8386c7b by Sylvain Henry at 2020-05-01T10:37:39-04:00 Refactor PprDebug handling If `-dppr-debug` is set, then PprUser and PprDump styles are silently replaced with PprDebug style. This was done in `mkUserStyle` and `mkDumpStyle` smart constructors. As a consequence they needed a DynFlags parameter. Now we keep the original PprUser and PprDump styles until they are used to create an `SDocContext`. I.e. the substitution is only performed in `initSDocContext`. - - - - - b3df9e78 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Remove PprStyle param of logging actions Use `withPprStyle` instead to apply a specific style to a SDoc. - - - - - de9fc995 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Fully remove PprDebug PprDebug was a pain to deal with consistently as it is implied by `-dppr-debug` but it isn't really a PprStyle. We remove it completely and query the appropriate SDoc flag instead (`sdocPprDebug`) via helpers (`getPprDebug` and its friends). - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Driver.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/TyCo/Ppr.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Runtime/Debugger.hs - compiler/GHC/Runtime/Linker.hs - compiler/GHC/Stg/Lint.hs - compiler/GHC/SysTools/ExtraObj.hs - compiler/GHC/SysTools/Process.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a43620c621563deed76ba6b417e3a7a707c15d23...de9fc995c2170bc34600ee3fc80393c67cfecad1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a43620c621563deed76ba6b417e3a7a707c15d23...de9fc995c2170bc34600ee3fc80393c67cfecad1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 1 14:38:26 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 01 May 2020 10:38:26 -0400 Subject: [Git][ghc/ghc][master] 2 commits: PmCheck: Only call checkSingle if we would report warnings Message-ID: <5eac3462e9a9_61673f81cd4c695c8331288@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 8b51fcbd by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Only call checkSingle if we would report warnings - - - - - fd7ea0fe by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 7 changed files: - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/Tc/Types/Evidence.hs - + testsuite/tests/pmcheck/should_compile/T18049.hs - testsuite/tests/pmcheck/should_compile/all.T Changes: ===================================== compiler/GHC/HsToCore/Binds.hs ===================================== @@ -33,7 +33,7 @@ import {-# SOURCE #-} GHC.HsToCore.Match ( matchWrapper ) import GHC.HsToCore.Monad import GHC.HsToCore.GuardedRHSs import GHC.HsToCore.Utils -import GHC.HsToCore.PmCheck ( needToRunPmCheck, addTyCsDs, checkGuardMatches ) +import GHC.HsToCore.PmCheck ( addTyCsDs, checkGuardMatches ) import GHC.Hs -- lots of things import GHC.Core -- lots of things @@ -145,12 +145,20 @@ dsHsBind dflags (VarBind { var_id = var else [] ; return (force_var, [core_bind]) } -dsHsBind dflags b@(FunBind { fun_id = L _ fun +dsHsBind dflags b@(FunBind { fun_id = L loc fun , fun_matches = matches , fun_ext = co_fn , fun_tick = tick }) - = do { (args, body) <- matchWrapper - (mkPrefixFunRhs (noLoc $ idName fun)) + = do { (args, body) <- addTyCsDs FromSource (hsWrapDictBinders co_fn) $ + -- FromSource might not be accurate (we don't have any + -- origin annotations for things in this module), but at + -- worst we do superfluous calls to the pattern match + -- oracle. + -- addTyCsDs: Add type evidence to the refinement type + -- predicate of the coverage checker + -- See Note [Type and Term Equality Propagation] in PmCheck + matchWrapper + (mkPrefixFunRhs (L loc (idName fun))) Nothing matches ; core_wrap <- dsHsWrapper co_fn ; let body' = mkOptTickBox tick body @@ -189,15 +197,7 @@ dsHsBind dflags (AbsBinds { abs_tvs = tyvars, abs_ev_vars = dicts , abs_exports = exports , abs_ev_binds = ev_binds , abs_binds = binds, abs_sig = has_sig }) - = do { ds_binds <- applyWhen (needToRunPmCheck dflags FromSource) - -- FromSource might not be accurate, but at worst - -- we do superfluous calls to the pattern match - -- oracle. - -- addTyCsDs: push type constraints deeper - -- for inner pattern match check - -- See Check, Note [Type and Term Equality Propagation] - (addTyCsDs (listToBag dicts)) - (dsLHsBinds binds) + = do { ds_binds <- addTyCsDs FromSource (listToBag dicts) (dsLHsBinds binds) ; ds_ev_binds <- dsTcEvBinds_s ev_binds @@ -206,7 +206,6 @@ dsHsBind dflags (AbsBinds { abs_tvs = tyvars, abs_ev_vars = dicts dsHsBind _ (PatSynBind{}) = panic "dsHsBind: PatSynBind" - ----------------------- dsAbsBinds :: DynFlags -> [TyVar] -> [EvVar] -> [ABExport GhcTc] ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -32,7 +32,7 @@ import GHC.HsToCore.ListComp import GHC.HsToCore.Utils import GHC.HsToCore.Arrows import GHC.HsToCore.Monad -import GHC.HsToCore.PmCheck ( checkGuardMatches ) +import GHC.HsToCore.PmCheck ( addTyCsDs, checkGuardMatches ) import GHC.Types.Name import GHC.Types.Name.Env import GHC.Core.FamInstEnv( topNormaliseType ) @@ -280,7 +280,8 @@ dsExpr hswrap@(XExpr (HsWrap co_fn e)) HsConLikeOut _ (RealDataCon dc) -> return $ varToCoreExpr (dataConWrapId dc) XExpr (HsWrap _ _) -> pprPanic "dsExpr: HsWrap inside HsWrap" (ppr hswrap) HsPar _ _ -> pprPanic "dsExpr: HsPar inside HsWrap" (ppr hswrap) - _ -> dsExpr e + _ -> addTyCsDs FromSource (hsWrapDictBinders co_fn) $ + dsExpr e -- See Note [Detecting forced eta expansion] ; wrap' <- dsHsWrapper co_fn ; dflags <- getDynFlags ===================================== compiler/GHC/HsToCore/Match.hs ===================================== @@ -859,8 +859,10 @@ matchSinglePatVar var ctx pat ty match_result do { dflags <- getDynFlags ; locn <- getSrcSpanDs - -- Pattern match check warnings - ; checkSingle dflags (DsMatchContext ctx locn) var (unLoc pat) + -- Pattern match check warnings + ; if isMatchContextPmChecked dflags FromSource ctx + then checkSingle dflags (DsMatchContext ctx locn) var (unLoc pat) + else pure () ; let eqn_info = EqnInfo { eqn_pats = [unLoc (decideBangHood dflags pat)] , eqn_orig = FromSource ===================================== compiler/GHC/HsToCore/PmCheck.hs ===================================== @@ -14,7 +14,7 @@ Pattern Matching Coverage Checking. module GHC.HsToCore.PmCheck ( -- Checking and printing checkSingle, checkMatches, checkGuardMatches, - needToRunPmCheck, isMatchContextPmChecked, + isMatchContextPmChecked, -- See Note [Type and Term Equality Propagation] addTyCsDs, addScrutTmCs @@ -45,7 +45,7 @@ import GHC.Core.DataCon import GHC.Core.TyCon import GHC.Types.Var (EvVar) import GHC.Core.Coercion -import GHC.Tc.Types.Evidence ( HsWrapper(..), isIdHsWrapper ) +import GHC.Tc.Types.Evidence (HsWrapper(..), isIdHsWrapper) import GHC.Tc.Utils.TcType (evVarPred) import {-# SOURCE #-} GHC.HsToCore.Expr (dsExpr, dsLExpr, dsSyntaxExpr) import {-# SOURCE #-} GHC.HsToCore.Binds (dsHsWrapper) @@ -53,6 +53,7 @@ import GHC.HsToCore.Utils (selectMatchVar) import GHC.HsToCore.Match.Literal (dsLit, dsOverLit) import GHC.HsToCore.Monad import GHC.Data.Bag +import GHC.Data.IOEnv (unsafeInterleaveM) import GHC.Data.OrdList import GHC.Core.TyCo.Rep import GHC.Core.Type @@ -1033,20 +1034,30 @@ Functions `addScrutTmCs' is responsible for generating these constraints. -} +-- | Locally update 'dsl_deltas' with the given action, but defer evaluation +-- with 'unsafeInterleaveM' in order not to do unnecessary work. locallyExtendPmDelta :: (Deltas -> DsM Deltas) -> DsM a -> DsM a -locallyExtendPmDelta ext k = getPmDeltas >>= ext >>= \deltas -> do - inh <- isInhabited deltas - -- If adding a constraint would lead to a contradiction, don't add it. - -- See @Note [Recovering from unsatisfiable pattern-matching constraints]@ - -- for why this is done. - if inh - then updPmDeltas deltas k - else k - --- | Add in-scope type constraints -addTyCsDs :: Bag EvVar -> DsM a -> DsM a -addTyCsDs ev_vars = - locallyExtendPmDelta (\deltas -> addPmCtsDeltas deltas (PmTyCt . evVarPred <$> ev_vars)) +locallyExtendPmDelta ext k = do + deltas <- getPmDeltas + deltas' <- unsafeInterleaveM $ do + deltas' <- ext deltas + inh <- isInhabited deltas' + -- If adding a constraint would lead to a contradiction, don't add it. + -- See @Note [Recovering from unsatisfiable pattern-matching constraints]@ + -- for why this is done. + if inh + then pure deltas' + else pure deltas + updPmDeltas deltas' k + +-- | Add in-scope type constraints if the coverage checker might run and then +-- run the given action. +addTyCsDs :: Origin -> Bag EvVar -> DsM a -> DsM a +addTyCsDs origin ev_vars m = do + dflags <- getDynFlags + applyWhen (needToRunPmCheck dflags origin) + (locallyExtendPmDelta (\deltas -> addPmCtsDeltas deltas (PmTyCt . evVarPred <$> ev_vars))) + m -- | Add equalities for the scrutinee to the local 'DsM' environment when -- checking a case expression: ===================================== compiler/GHC/Tc/Types/Evidence.hs ===================================== @@ -10,7 +10,7 @@ module GHC.Tc.Types.Evidence ( (<.>), mkWpTyApps, mkWpEvApps, mkWpEvVarApps, mkWpTyLams, mkWpLams, mkWpLet, mkWpCastN, mkWpCastR, collectHsWrapBinders, mkWpFun, idHsWrapper, isIdHsWrapper, isErasableHsWrapper, - pprHsWrapper, + pprHsWrapper, hsWrapDictBinders, -- * Evidence bindings TcEvBinds(..), EvBindsVar(..), @@ -370,6 +370,27 @@ isErasableHsWrapper = go go WpTyApp{} = True go WpLet{} = False +hsWrapDictBinders :: HsWrapper -> Bag DictId +-- ^ Identifies the /lambda-bound/ dictionaries of an 'HsWrapper'. This is used +-- (only) to allow the pattern-match overlap checker to know what Given +-- dictionaries are in scope. +-- +-- We specifically do not collect dictionaries bound in a 'WpLet'. These are +-- either superclasses of lambda-bound ones, or (extremely numerous) results of +-- binding Wanted dictionaries. We definitely don't want all those cluttering +-- up the Given dictionaries for pattern-match overlap checking! +hsWrapDictBinders wrap = go wrap + where + go (WpEvLam dict_id) = unitBag dict_id + go (w1 `WpCompose` w2) = go w1 `unionBags` go w2 + go (WpFun _ w _ _) = go w + go WpHole = emptyBag + go (WpCast {}) = emptyBag + go (WpEvApp {}) = emptyBag + go (WpTyLam {}) = emptyBag + go (WpTyApp {}) = emptyBag + go (WpLet {}) = emptyBag + collectHsWrapBinders :: HsWrapper -> ([Var], HsWrapper) -- Collect the outer lambda binders of a HsWrapper, -- stopping as soon as you get to a non-lambda binder ===================================== testsuite/tests/pmcheck/should_compile/T18049.hs ===================================== @@ -0,0 +1,29 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE RankNTypes #-} +{-# OPTIONS_GHC -Wincomplete-patterns -fforce-recomp #-} +module Bug where + +import Data.Kind + +data SBool :: Bool -> Type where + SFalse :: SBool False + STrue :: SBool True + +f :: SBool b + -> (b ~ True => SBool b -> r) + -> (b ~ False => SBool b -> r) + -> r +f x t f = + case x of + SFalse -> f x + STrue -> t x + +g :: forall b. SBool b -> () +g x = f x + (\x' -> + case x' of + -- SFalse -> () + STrue -> ()) + (\_ -> ()) ===================================== testsuite/tests/pmcheck/should_compile/all.T ===================================== @@ -118,6 +118,8 @@ test('T17977', collect_compiler_stats('bytes allocated',10), compile, ['-fwarn-incomplete-patterns -fwarn-overlapping-patterns']) test('T17977b', collect_compiler_stats('bytes allocated',10), compile, ['-fwarn-incomplete-patterns -fwarn-overlapping-patterns']) +test('T18049', normal, compile, + ['-fwarn-incomplete-patterns -fwarn-overlapping-patterns']) # Other tests test('pmc001', [], compile, View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/de9fc995c2170bc34600ee3fc80393c67cfecad1...fd7ea0fee92a60f9658254cc4fe3abdb4ff299b1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/de9fc995c2170bc34600ee3fc80393c67cfecad1...fd7ea0fee92a60f9658254cc4fe3abdb4ff299b1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 1 15:01:59 2020 From: gitlab at gitlab.haskell.org (Richard Eisenberg) Date: Fri, 01 May 2020 11:01:59 -0400 Subject: [Git][ghc/ghc][wip/hole-refactor] Refactor hole constraints. Message-ID: <5eac39e72e937_6167e5b152c8337918@gitlab.haskell.org.mail> Richard Eisenberg pushed to branch wip/hole-refactor at Glasgow Haskell Compiler / GHC Commits: d9aa8f2c by Richard Eisenberg at 2020-05-01T16:01:25+01:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. - - - - - 18 changed files: - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Errors/Hole.hs-boot - compiler/GHC/Tc/Errors/Hole/FitTypes.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Rule.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/Solver/Canonical.hs - compiler/GHC/Tc/Solver/Flatten.hs - compiler/GHC/Tc/Solver/Interact.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Types/Constraint.hs - compiler/GHC/Tc/Types/Origin.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Tc/Utils/TcMType.hs Changes: ===================================== compiler/GHC/HsToCore/PmCheck/Oracle.hs ===================================== @@ -438,7 +438,7 @@ then newtypes. (b) dcs is the list of newtype constructors "skipped", every time we normalise a newtype to its core representation, we keep track of the source data - constructor. For convenienve, we also track the type we unwrap and the + constructor. For convenience, we also track the type we unwrap and the type of its field. Example: @Down 42@ => @[(Down @Int, Down, Int)] (c) core_ty is the rewritten type. That is, pmTopNormaliseType env ty_cs ty = Just (src_ty, dcs, core_ty) ===================================== compiler/GHC/Tc/Errors.hs ===================================== @@ -285,8 +285,8 @@ important :: SDoc -> Report important doc = mempty { report_important = [doc] } -- | Put a doc into the relevant bindings block. -relevant_bindings :: SDoc -> Report -relevant_bindings doc = mempty { report_relevant_bindings = [doc] } +mk_relevant_bindings :: SDoc -> Report +mk_relevant_bindings doc = mempty { report_relevant_bindings = [doc] } -- | Put a doc into the valid hole fits block. valid_hole_fits :: SDoc -> Report @@ -524,16 +524,28 @@ This only matters in instance declarations.. -} reportWanteds :: ReportErrCtxt -> TcLevel -> WantedConstraints -> TcM () -reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) +reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics + , wc_holes = holes }) = do { traceTc "reportWanteds" (vcat [ text "Simples =" <+> ppr simples , text "Suppress =" <+> ppr (cec_suppress ctxt)]) ; traceTc "rw2" (ppr tidy_cts) - -- First deal with things that are utterly wrong + -- First, deal with any out-of-scope errors: + ; let (out_of_scope, other_holes) = partition isOutOfScopeHole tidy_holes + -- don't suppress out-of-scope errors + ctxt_for_scope_errs = ctxt { cec_suppress = False } + ; (_, no_out_of_scope) <- askNoErrs $ + reportHoles tidy_cts ctxt_for_scope_errs out_of_scope + + -- Next, deal with things that are utterly wrong -- Like Int ~ Bool (incl nullary TyCons) -- or Int ~ t a (AppTy on one side) -- These /ones/ are not suppressed by the incoming context - ; let ctxt_for_insols = ctxt { cec_suppress = False } + -- (but will be by out-of-scope errors) + ; let ctxt_for_insols = ctxt { cec_suppress = not no_out_of_scope } + ; reportHoles tidy_cts ctxt_for_insols other_holes + -- holes never suppress + ; (ctxt1, cts1) <- tryReporters ctxt_for_insols report1 tidy_cts -- Now all the other constraints. We suppress errors here if @@ -554,7 +566,8 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) -- if there's a *given* insoluble here (= inaccessible code) where env = cec_tidy ctxt - tidy_cts = bagToList (mapBag (tidyCt env) simples) + tidy_cts = bagToList (mapBag (tidyCt env) simples) + tidy_holes = bagToList (mapBag (tidyHole env) holes) -- report1: ones that should *not* be suppressed by -- an insoluble somewhere else in the tree @@ -562,9 +575,7 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) -- (see GHC.Tc.Utils.insolubleCt) is caught here, otherwise -- we might suppress its error message, and proceed on past -- type checking to get a Lint error later - report1 = [ ("Out of scope", unblocked is_out_of_scope, True, mkHoleReporter tidy_cts) - , ("Holes", unblocked is_hole, False, mkHoleReporter tidy_cts) - , ("custom_error", unblocked is_user_type_error, True, mkUserTypeErrorReporter) + report1 = [ ("custom_error", unblocked is_user_type_error, True, mkUserTypeErrorReporter) , given_eq_spec , ("insoluble2", unblocked utterly_wrong, True, mkGroupReporter mkEqErr) @@ -593,8 +604,7 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) unblocked checker ct pred = checker ct pred -- rigid_nom_eq, rigid_nom_tv_eq, - is_hole, is_dict, - is_equality, is_ip, is_irred :: Ct -> Pred -> Bool + is_dict, is_equality, is_ip, is_irred :: Ct -> Pred -> Bool is_given_eq ct pred | EqPred {} <- pred = arisesFromGivens ct @@ -617,9 +627,6 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) non_tv_eq _ (EqPred NomEq ty1 _) = not (isTyVarTy ty1) non_tv_eq _ _ = False - is_out_of_scope ct _ = isOutOfScopeCt ct - is_hole ct _ = isHoleCt ct - is_user_type_error ct _ = isUserTypeErrorCt ct is_homo_equality _ (EqPred _ ty1 ty2) = tcTypeKind ty1 `tcEqType` tcTypeKind ty2 @@ -705,12 +712,12 @@ mkSkolReporter ctxt cts | eq_lhs_type ct1 ct2 = True | otherwise = False -mkHoleReporter :: [Ct] -> Reporter --- Reports errors one at a time -mkHoleReporter tidy_simples ctxt - = mapM_ $ \ct -> do { err <- mkHoleError tidy_simples ctxt ct - ; maybeReportHoleError ctxt ct err - ; maybeAddDeferredHoleBinding ctxt err ct } +reportHoles :: [Ct] -- other (tidied) constraints + -> ReportErrCtxt -> [Hole] -> TcM () +reportHoles tidy_cts ctxt + = mapM_ $ \hole -> do { err <- mkHoleError tidy_cts ctxt hole + ; maybeReportHoleError ctxt hole err + ; maybeAddDeferredHoleBinding ctxt err hole } mkUserTypeErrorReporter :: Reporter mkUserTypeErrorReporter ctxt @@ -742,7 +749,7 @@ mkGivenErrorReporter ctxt cts inaccessible_msg = hang (text "Inaccessible code in") 2 (ppr (ic_info implic)) report = important inaccessible_msg `mappend` - relevant_bindings binds_msg + mk_relevant_bindings binds_msg ; err <- mkEqErr_help dflags ctxt report ct' Nothing ty1 ty2 @@ -843,15 +850,27 @@ suppressGroup mk_err ctxt cts ; traceTc "Suppressing errors for" (ppr cts) ; mapM_ (addDeferredBinding ctxt err) cts } -maybeReportHoleError :: ReportErrCtxt -> Ct -> ErrMsg -> TcM () +maybeReportHoleError :: ReportErrCtxt -> Hole -> ErrMsg -> TcM () +maybeReportHoleError ctxt hole err + | isOutOfScopeHole hole + -- Always report an error for out-of-scope variables + -- Unless -fdefer-out-of-scope-variables is on, + -- in which case the messages are discarded. + -- See #12170, #12406 + = -- If deferring, report a warning only if -Wout-of-scope-variables is on + case cec_out_of_scope_holes ctxt of + HoleError -> reportError err + HoleWarn -> + reportWarning (Reason Opt_WarnDeferredOutOfScopeVariables) err + HoleDefer -> return () + -- Unlike maybeReportError, these "hole" errors are -- /not/ suppressed by cec_suppress. We want to see them! -maybeReportHoleError ctxt ct err +maybeReportHoleError ctxt (Hole { hole_sort = TypeHole }) err -- When -XPartialTypeSignatures is on, warnings (instead of errors) are -- generated for holes in partial type signatures. -- Unless -fwarn-partial-type-signatures is not on, -- in which case the messages are discarded. - | isTypeHoleCt ct = -- For partial type signatures, generate warnings only, and do that -- only if -fwarn-partial-type-signatures is on case cec_type_holes ctxt of @@ -859,22 +878,12 @@ maybeReportHoleError ctxt ct err HoleWarn -> reportWarning (Reason Opt_WarnPartialTypeSignatures) err HoleDefer -> return () - -- Always report an error for out-of-scope variables - -- Unless -fdefer-out-of-scope-variables is on, - -- in which case the messages are discarded. - -- See #12170, #12406 - | isOutOfScopeCt ct - = -- If deferring, report a warning only if -Wout-of-scope-variables is on - case cec_out_of_scope_holes ctxt of - HoleError -> reportError err - HoleWarn -> - reportWarning (Reason Opt_WarnDeferredOutOfScopeVariables) err - HoleDefer -> return () - +maybeReportHoleError ctxt hole@(Hole { hole_sort = ExprHole _ }) err -- Otherwise this is a typed hole in an expression, - -- but not for an out-of-scope variable - | otherwise + -- but not for an out-of-scope variable (because that goes through a + -- different function) = -- If deferring, report a warning only if -Wtyped-holes is on + ASSERT( not (isOutOfScopeHole hole) ) case cec_expr_holes ctxt of HoleError -> reportError err HoleWarn -> reportWarning (Reason Opt_WarnTypedHoles) err @@ -899,10 +908,7 @@ addDeferredBinding ctxt err ct , CtWanted { ctev_pred = pred, ctev_dest = dest } <- ctEvidence ct -- Only add deferred bindings for Wanted constraints = do { dflags <- getDynFlags - ; let err_msg = pprLocErrMsg err - err_fs = mkFastString $ showSDoc dflags $ - err_msg $$ text "(deferred type error)" - err_tm = evDelayedError pred err_fs + ; let err_tm = mkErrorTerm dflags pred err ev_binds_var = cec_binds ctxt ; case dest of @@ -917,11 +923,27 @@ addDeferredBinding ctxt err ct | otherwise -- Do not set any evidence for Given/Derived = return () -maybeAddDeferredHoleBinding :: ReportErrCtxt -> ErrMsg -> Ct -> TcM () -maybeAddDeferredHoleBinding ctxt err ct - | isExprHoleCt ct - = addDeferredBinding ctxt err ct -- Only add bindings for holes in expressions - | otherwise -- not for holes in partial type signatures +mkErrorTerm :: DynFlags -> Type -- of the error term + -> ErrMsg -> EvTerm +mkErrorTerm dflags ty err = evDelayedError ty err_fs + where + err_msg = pprLocErrMsg err + err_fs = mkFastString $ showSDoc dflags $ + err_msg $$ text "(deferred type error)" + +maybeAddDeferredHoleBinding :: ReportErrCtxt -> ErrMsg -> Hole -> TcM () +maybeAddDeferredHoleBinding ctxt err (Hole { hole_ty = hole_ty + , hole_sort = ExprHole ev_id }) +-- Only add bindings for holes in expressions +-- not for holes in partial type signatures +-- cf. addDeferredBinding + | deferringAnyBindings ctxt + = do { dflags <- getDynFlags + ; let err_tm = mkErrorTerm dflags hole_ty err + ; addTcEvBind (cec_binds ctxt) $ mkWantedEvBind ev_id err_tm } + | otherwise + = return () +maybeAddDeferredHoleBinding _ _ (Hole { hole_sort = TypeHole }) = return () tryReporters :: ReportErrCtxt -> [ReporterSpec] -> [Ct] -> TcM (ReportErrCtxt, [Ct]) @@ -961,7 +983,6 @@ tryReporter ctxt (str, keep_me, suppress_after, reporter) cts where (yeses, nos) = partition (\ct -> keep_me ct (classifyPredType (ctPred ct))) cts - pprArising :: CtOrigin -> SDoc -- Used for the main, top-level error message -- We've done special processing for TypeEq, KindEq, Given @@ -1104,15 +1125,16 @@ mkIrredErr ctxt cts ; let orig = ctOrigin ct1 msg = couldNotDeduce (getUserGivens ctxt) (map ctPred cts, orig) ; mkErrorMsgFromCt ctxt ct1 $ - important msg `mappend` relevant_bindings binds_msg } + important msg `mappend` mk_relevant_bindings binds_msg } where (ct1:_) = cts ---------------- -mkHoleError :: [Ct] -> ReportErrCtxt -> Ct -> TcM ErrMsg -mkHoleError tidy_simples ctxt ct@(CHoleCan { cc_occ = occ, cc_hole = hole_sort }) - | isOutOfScopeCt ct -- Out of scope variables, like 'a', where 'a' isn't bound - -- Suggest possible in-scope variables in the message +mkHoleError :: [Ct] -> ReportErrCtxt -> Hole -> TcM ErrMsg +mkHoleError _tidy_simples _ctxt hole@(Hole { hole_occ = occ + , hole_ty = hole_ty + , hole_loc = ct_loc }) + | isOutOfScopeHole hole = do { dflags <- getDynFlags ; rdr_env <- getGlobalRdrEnv ; imp_info <- getImports @@ -1122,48 +1144,52 @@ mkHoleError tidy_simples ctxt ct@(CHoleCan { cc_occ = occ, cc_hole = hole_sort } errDoc [out_of_scope_msg] [] [unknownNameSuggestions dflags hpt curr_mod rdr_env (tcl_rdr lcl_env) imp_info (mkRdrUnqual occ)] } + where + herald | isDataOcc occ = text "Data constructor not in scope:" + | otherwise = text "Variable not in scope:" - | otherwise -- Explicit holes, like "_" or "_f" - = do { (ctxt, binds_msg, ct) <- relevantBindings False ctxt ct + out_of_scope_msg -- Print v :: ty only if the type has structure + | boring_type = hang herald 2 (ppr occ) + | otherwise = hang herald 2 (pp_occ_with_type occ hole_ty) + + lcl_env = ctLocEnv ct_loc + boring_type = isTyVarTy hole_ty + + -- general case: not an out-of-scope error +mkHoleError tidy_simples ctxt hole@(Hole { hole_occ = occ + , hole_ty = hole_ty + , hole_sort = sort + , hole_loc = ct_loc }) + = do { (ctxt, binds_msg) + <- relevant_bindings False ctxt lcl_env (tyCoVarsOfType hole_ty) -- The 'False' means "don't filter the bindings"; see Trac #8191 ; show_hole_constraints <- goptM Opt_ShowHoleConstraints ; let constraints_msg - | isExprHoleCt ct, show_hole_constraints + | ExprHole _ <- sort, show_hole_constraints = givenConstraintsMsg ctxt | otherwise = empty ; show_valid_hole_fits <- goptM Opt_ShowValidHoleFits ; (ctxt, sub_msg) <- if show_valid_hole_fits - then validHoleFits ctxt tidy_simples ct + then validHoleFits ctxt tidy_simples hole else return (ctxt, empty) - ; mkErrorMsgFromCt ctxt ct $ + ; mkErrorReport ctxt lcl_env $ important hole_msg `mappend` - relevant_bindings (binds_msg $$ constraints_msg) `mappend` + mk_relevant_bindings (binds_msg $$ constraints_msg) `mappend` valid_hole_fits sub_msg } where - ct_loc = ctLoc ct lcl_env = ctLocEnv ct_loc - hole_ty = ctEvPred (ctEvidence ct) hole_kind = tcTypeKind hole_ty tyvars = tyCoVarsOfTypeList hole_ty - boring_type = isTyVarTy hole_ty - - out_of_scope_msg -- Print v :: ty only if the type has structure - | boring_type = hang herald 2 (ppr occ) - | otherwise = hang herald 2 pp_with_type - pp_with_type = hang (pprPrefixOcc occ) 2 (dcolon <+> pprType hole_ty) - herald | isDataOcc occ = text "Data constructor not in scope:" - | otherwise = text "Variable not in scope:" - - hole_msg = case hole_sort of - ExprHole -> vcat [ hang (text "Found hole:") - 2 pp_with_type - , tyvars_msg, expr_hole_hint ] + hole_msg = case sort of + ExprHole _ -> vcat [ hang (text "Found hole:") + 2 (pp_occ_with_type occ hole_ty) + , tyvars_msg, expr_hole_hint ] TypeHole -> vcat [ hang (text "Found type wildcard" <+> quotes (ppr occ)) 2 (text "standing for" <+> quotes pp_hole_type_with_kind) , tyvars_msg, type_hole_hint ] @@ -1207,21 +1233,22 @@ mkHoleError tidy_simples ctxt ct@(CHoleCan { cc_occ = occ, cc_hole = hole_sort } = ppWhenOption sdocPrintExplicitCoercions $ quotes (ppr tv) <+> text "is a coercion variable" -mkHoleError _ _ ct = pprPanic "mkHoleError" (ppr ct) +pp_occ_with_type :: OccName -> Type -> SDoc +pp_occ_with_type occ hole_ty = hang (pprPrefixOcc occ) 2 (dcolon <+> pprType hole_ty) -- We unwrap the ReportErrCtxt here, to avoid introducing a loop in module -- imports validHoleFits :: ReportErrCtxt -- The context we're in, i.e. the -- implications and the tidy environment -> [Ct] -- Unsolved simple constraints - -> Ct -- The hole constraint. + -> Hole -- The hole -> TcM (ReportErrCtxt, SDoc) -- We return the new context -- with a possibly updated -- tidy environment, and -- the message. validHoleFits ctxt@(CEC {cec_encl = implics - , cec_tidy = lcl_env}) simps ct - = do { (tidy_env, msg) <- findValidHoleFits lcl_env implics simps ct + , cec_tidy = lcl_env}) simps hole + = do { (tidy_env, msg) <- findValidHoleFits lcl_env implics simps hole ; return (ctxt {cec_tidy = tidy_env}, msg) } -- See Note [Constraints include ...] @@ -1255,7 +1282,7 @@ mkIPErr ctxt cts = couldNotDeduce givens (preds, orig) ; mkErrorMsgFromCt ctxt ct1 $ - important msg `mappend` relevant_bindings binds_msg } + important msg `mappend` mk_relevant_bindings binds_msg } where (ct1:_) = cts @@ -1337,7 +1364,7 @@ mkEqErr1 ctxt ct -- Wanted or derived; ; dflags <- getDynFlags ; traceTc "mkEqErr1" (ppr ct $$ pprCtOrigin (ctOrigin ct) $$ ppr keep_going) ; let report = mconcat [important wanted_msg, important coercible_msg, - relevant_bindings binds_msg] + mk_relevant_bindings binds_msg] ; if keep_going then mkEqErr_help dflags ctxt report ct is_oriented ty1 ty2 else mkErrorMsgFromCt ctxt ct report } @@ -1513,7 +1540,7 @@ mkTyVarEqErr' dflags ctxt report ct oriented tv1 ty2 filter isTyVar $ fvVarList $ tyCoFVsOfType ty1 `unionFV` tyCoFVsOfType ty2 - extra3 = relevant_bindings $ + extra3 = mk_relevant_bindings $ ppWhen (not (null interesting_tyvars)) $ hang (text "Type variable kinds:") 2 $ vcat (map (tyvar_binding . tidyTyCoVarOcc (cec_tidy ctxt)) @@ -2819,27 +2846,45 @@ relevantBindings :: Bool -- True <=> filter by tyvar; False <=> no filtering -> TcM (ReportErrCtxt, SDoc, Ct) -- Also returns the zonked and tidied CtOrigin of the constraint relevantBindings want_filtering ctxt ct - = do { dflags <- getDynFlags + = do { traceTc "relevantBindings" (ppr ct) ; (env1, tidy_orig) <- zonkTidyOrigin (cec_tidy ctxt) (ctLocOrigin loc) - ; let ct_tvs = tyCoVarsOfCt ct `unionVarSet` extra_tvs -- For *kind* errors, report the relevant bindings of the -- enclosing *type* equality, because that's more useful for the programmer - extra_tvs = case tidy_orig of + ; let extra_tvs = case tidy_orig of KindEqOrigin t1 m_t2 _ _ -> tyCoVarsOfTypes $ t1 : maybeToList m_t2 _ -> emptyVarSet - ; traceTc "relevantBindings" $ - vcat [ ppr ct - , pprCtOrigin (ctLocOrigin loc) - , ppr ct_tvs + ct_fvs = tyCoVarsOfCt ct `unionVarSet` extra_tvs + + -- Put a zonked, tidied CtOrigin into the Ct + loc' = setCtLocOrigin loc tidy_orig + ct' = setCtLoc ct loc' + ctxt1 = ctxt { cec_tidy = env1 } + + ; (ctxt2, doc) <- relevant_bindings want_filtering ctxt1 lcl_env ct_fvs + ; return (ctxt2, doc, ct') } + where + loc = ctLoc ct + lcl_env = ctLocEnv loc + +-- slightly more general version, to work also with holes +relevant_bindings :: Bool + -> ReportErrCtxt + -> TcLclEnv + -> TyCoVarSet + -> TcM (ReportErrCtxt, SDoc) +relevant_bindings want_filtering ctxt lcl_env ct_tvs + = do { dflags <- getDynFlags + ; traceTc "relevant_bindings" $ + vcat [ ppr ct_tvs , pprWithCommas id [ ppr id <+> dcolon <+> ppr (idType id) | TcIdBndr id _ <- tcl_bndrs lcl_env ] , pprWithCommas id [ ppr id | TcIdBndr_ExpType id _ _ <- tcl_bndrs lcl_env ] ] ; (tidy_env', docs, discards) - <- go dflags env1 ct_tvs (maxRelevantBinds dflags) + <- go dflags (cec_tidy ctxt) (maxRelevantBinds dflags) emptyVarSet [] False (removeBindingShadowing $ tcl_bndrs lcl_env) -- tcl_bndrs has the innermost bindings first, @@ -2849,17 +2894,10 @@ relevantBindings want_filtering ctxt ct hang (text "Relevant bindings include") 2 (vcat docs $$ ppWhen discards discardMsg) - -- Put a zonked, tidied CtOrigin into the Ct - loc' = setCtLocOrigin loc tidy_orig - ct' = setCtLoc ct loc' ctxt' = ctxt { cec_tidy = tidy_env' } - ; return (ctxt', doc, ct') } + ; return (ctxt', doc) } where - ev = ctEvidence ct - loc = ctEvLoc ev - lcl_env = ctLocEnv loc - run_out :: Maybe Int -> Bool run_out Nothing = False run_out (Just n) = n <= 0 @@ -2868,14 +2906,14 @@ relevantBindings want_filtering ctxt ct dec_max = fmap (\n -> n - 1) - go :: DynFlags -> TidyEnv -> TcTyVarSet -> Maybe Int -> TcTyVarSet -> [SDoc] + go :: DynFlags -> TidyEnv -> Maybe Int -> TcTyVarSet -> [SDoc] -> Bool -- True <=> some filtered out due to lack of fuel -> [TcBinder] -> TcM (TidyEnv, [SDoc], Bool) -- The bool says if we filtered any out -- because of lack of fuel - go _ tidy_env _ _ _ docs discards [] + go _ tidy_env _ _ docs discards [] = return (tidy_env, reverse docs, discards) - go dflags tidy_env ct_tvs n_left tvs_seen docs discards (tc_bndr : tc_bndrs) + go dflags tidy_env n_left tvs_seen docs discards (tc_bndr : tc_bndrs) = case tc_bndr of TcTvBndr {} -> discard_it TcIdBndr id top_lvl -> go2 (idName id) (idType id) top_lvl @@ -2891,7 +2929,7 @@ relevantBindings want_filtering ctxt ct Nothing -> discard_it -- No info; discard } where - discard_it = go dflags tidy_env ct_tvs n_left tvs_seen docs + discard_it = go dflags tidy_env n_left tvs_seen docs discards tc_bndrs go2 id_name id_type top_lvl = do { (tidy_env', tidy_ty) <- zonkTidyTcType tidy_env id_type @@ -2916,12 +2954,12 @@ relevantBindings want_filtering ctxt ct else if run_out n_left && id_tvs `subVarSet` tvs_seen -- We've run out of n_left fuel and this binding only -- mentions already-seen type variables, so discard it - then go dflags tidy_env ct_tvs n_left tvs_seen docs + then go dflags tidy_env n_left tvs_seen docs True -- Record that we have now discarded something tc_bndrs -- Keep this binding, decrement fuel - else go dflags tidy_env' ct_tvs (dec_max n_left) new_seen + else go dflags tidy_env' (dec_max n_left) new_seen (doc:docs) discards tc_bndrs } ===================================== compiler/GHC/Tc/Errors/Hole.hs ===================================== @@ -2,17 +2,9 @@ {-# LANGUAGE ExistentialQuantification #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} module GHC.Tc.Errors.Hole - ( findValidHoleFits, tcFilterHoleFits - , tcCheckHoleFit, tcSubsumes - , withoutUnification - , fromPureHFPlugin - -- Re-exports for convenience - , hfIsLcl - , pprHoleFit, debugHoleFitDispConfig + ( findValidHoleFits -- Re-exported from GHC.Tc.Errors.Hole.FitTypes - , TypedHole (..), HoleFit (..), HoleFitCandidate (..) - , CandPlugin, FitPlugin , HoleFitPlugin (..), HoleFitPluginR (..) ) where @@ -121,7 +113,7 @@ The hole in `f` would generate the message: Valid hole fits are found by checking top level identifiers and local bindings in scope for whether their type can be instantiated to the the type of the hole. Additionally, we also need to check whether all relevant constraints are solved -by choosing an identifier of that type as well, see Note [Relevant Constraints] +by choosing an identifier of that type as well, see Note [Relevant constraints] Since checking for subsumption results in the side-effect of type variables being unified by the simplifier, we need to take care to restore them after @@ -143,9 +135,13 @@ that the quantified type variables would take if that fit is used, like If -XTypeApplications is enabled, this can even be copied verbatim as a replacement for the hole. - -Note [Nested implications] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Checking hole fits] +~~~~~~~~~~~~~~~~~~~~~~~~~ +If we have a hole of type hole_ty, we want to know whether a variable +of type ty is a valid fit for the whole. This is a subsumption check: +we wish to know whether ty <: hole_ty. But, of course, the check +must take into account any givens and relevant constraints. +(See also Note [Relevant constraints]). For the simplifier to be able to use any givens present in the enclosing implications to solve relevant constraints, we nest the wanted subsumption @@ -156,10 +152,7 @@ As an example, let's look at the following code: f :: Show a => a -> String f x = show _ -The hole will result in the hole constraint: - - [WD] __a1ph {0}:: a0_a1pd[tau:2] (CHoleCan: ExprHole(_)) - +Suppose the hole is assigned type a0_a1pd[tau:2]. Here the nested implications are just one level deep, namely: [Implic { @@ -170,36 +163,25 @@ Here the nested implications are just one level deep, namely: Given = $dShow_a1pc :: Show a_a1pa[sk:2] Wanted = WC {wc_simple = - [WD] __a1ph {0}:: a_a1pd[tau:2] (CHoleCan: ExprHole(_)) - [WD] $dShow_a1pe {0}:: Show a_a1pd[tau:2] (CDictCan(psc))} + [WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CDictCan(psc))} Binds = EvBindsVar Needed inner = [] Needed outer = [] the type signature for: f :: forall a. Show a => a -> String }] -As we can see, the givens say that the information about the skolem -`a_a1pa[sk:2]` fulfills the Show constraint. - -The simples are: +As we can see, the givens say that the skolem +`a_a1pa[sk:2]` fulfills the Show constraint, and that we must prove +the [W] Show a0_a1pd[tau:2] constraint -- that is, whatever fills the +hole must have a Show instance. - [[WD] __a1ph {0}:: a0_a1pd[tau:2] (CHoleCan: ExprHole(_)), - [WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CNonCanonical)] - -I.e. the hole `a0_a1pd[tau:2]` and the constraint that the type of the hole must -fulfill `Show a0_a1pd[tau:2])`. - -So when we run the check, we need to make sure that the - - [WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CNonCanonical) - -Constraint gets solved. When we now check for whether `x :: a0_a1pd[tau:2]` fits -the hole in `tcCheckHoleFit`, the call to `tcSubType` will end up writing the -meta type variable `a0_a1pd[tau:2] := a_a1pa[sk:2]`. By wrapping the wanted -constraints needed by tcSubType_NC and the relevant constraints (see -Note [Relevant Constraints] for more details) in the nested implications, we -can pass the information in the givens along to the simplifier. For our example, -we end up needing to check whether the following constraints are soluble. +When we now check whether `x :: a_a1pa[sk:2]` fits the hole in +`tcCheckHoleFit`, the call to `tcSubType` will end up unifying the meta type +variable `a0_a1pd[tau:2] := a_a1pa[sk:2]`. By wrapping the wanted constraints +needed by tcSubType_NC and the relevant constraints (see Note [Relevant +Constraints] for more details) in the nested implications, we can pass the +information in the givens along to the simplifier. For our example, we end up +needing to check whether the following constraints are soluble. WC {wc_impl = Implic { @@ -223,10 +205,12 @@ with a final WC of WC {}, confirming x :: a0_a1pd[tau:2] as a match. To avoid side-effects on the nested implications, we create a new EvBindsVar so that any changes to the ev binds during a check remains localised to that check. - +In addition, we call withoutUnification to reset any unified metavariables; this +call is actually done outside tcCheckHoleFit so that the results can be formatted +for the user before resetting variables. Note [Valid refinement hole fits include ...] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When the `-frefinement-level-hole-fits=N` flag is given, we additionally look for "valid refinement hole fits"", i.e. valid hole fits with up to N additional holes in them. @@ -337,10 +321,8 @@ In the free monad example above, this is demonstrated with be applied to an expression of type `a -> Free f b` in order to match. If -XScopedTypeVariables is enabled, this hole fit can even be copied verbatim. - -Note [Relevant Constraints] -~~~~~~~~~~~~~~~~~~~ - +Note [Relevant constraints] +~~~~~~~~~~~~~~~~~~~~~~~~~~~ As highlighted by #14273, we need to check any relevant constraints as well as checking for subsumption. Relevant constraints are the simple constraints whose free unification variables are mentioned in the type of the hole. @@ -351,10 +333,9 @@ as is the case in f :: String f = show _ -Where the simples will be : +Here, the hole is given type a0_a1kv[tau:1]. Then, the emitted constraint is: - [[WD] __a1kz {0}:: a0_a1kv[tau:1] (CHoleCan: ExprHole(_)), - [WD] $dShow_a1kw {0}:: Show a0_a1kv[tau:1] (CNonCanonical)] + [WD] $dShow_a1kw {0}:: Show a0_a1kv[tau:1] (CNonCanonical) However, when there are multiple holes, we need to be more careful. As an example, Let's take a look at the following code: @@ -362,29 +343,24 @@ example, Let's take a look at the following code: f :: Show a => a -> String f x = show (_b (show _a)) -Here there are two holes, `_a` and `_b`, and the simple constraints passed to +Here there are two holes, `_a` and `_b`. Suppose _a :: a0_a1pd[tau:2] and +_b :: a1_a1po[tau:2]. Then, the simple constraints passed to findValidHoleFits are: - [[WD] _a_a1pi {0}:: String - -> a0_a1pd[tau:2] (CHoleCan: ExprHole(_b)), - [WD] _b_a1ps {0}:: a1_a1po[tau:2] (CHoleCan: ExprHole(_a)), - [WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CNonCanonical), + [[WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CNonCanonical), [WD] $dShow_a1pp {0}:: Show a1_a1po[tau:2] (CNonCanonical)] - -Here we have the two hole constraints for `_a` and `_b`, but also additional -constraints that these holes must fulfill. When we are looking for a match for -the hole `_a`, we filter the simple constraints to the "Relevant constraints", -by throwing out all hole constraints and any constraints which do not mention -a variable mentioned in the type of the hole. For hole `_a`, we will then -only require that the `$dShow_a1pp` constraint is solved, since that is -the only non-hole constraint that mentions any free type variables mentioned in -the hole constraint for `_a`, namely `a_a1pd[tau:2]` , and similarly for the -hole `_b` we only require that the `$dShow_a1pe` constraint is solved. +When we are looking for a match for the hole `_a`, we filter the simple +constraints to the "Relevant constraints", by throwing out any constraints +which do not mention a variable mentioned in the type of the hole. For hole +`_a`, we will then only require that the `$dShow_a1pe` constraint is solved, +since that is the only constraint that mentions any free type variables +mentioned in the hole constraint for `_a`, namely `a_a1pd[tau:2]`, and +similarly for the hole `_b` we only require that the `$dShow_a1pe` constraint +is solved. Note [Leaking errors] -~~~~~~~~~~~~~~~~~~~ - +~~~~~~~~~~~~~~~~~~~~~ When considering candidates, GHC believes that we're checking for validity in actual source. However, As evidenced by #15321, #15007 and #15202, this can cause bewildering error messages. The solution here is simple: if a candidate @@ -393,17 +369,12 @@ is discarded. -} - data HoleFitDispConfig = HFDC { showWrap :: Bool , showWrapVars :: Bool , showType :: Bool , showProv :: Bool , showMatches :: Bool } -debugHoleFitDispConfig :: HoleFitDispConfig -debugHoleFitDispConfig = HFDC True True True False False - - -- We read the various -no-show-*-of-hole-fits flags -- and set the display config accordingly. getHoleFitDispConfig :: TcM HoleFitDispConfig @@ -516,13 +487,12 @@ pprHoleFit (HFDC sWrp sWrpVars sTy sProv sMs) (HoleFit {..}) = GreHFCand gre -> pprNameProvenance gre _ -> text "bound at" <+> ppr (getSrcLoc name) -getLocalBindings :: TidyEnv -> Ct -> TcM [Id] -getLocalBindings tidy_orig ct - = do { (env1, _) <- zonkTidyOrigin tidy_orig (ctLocOrigin loc) +getLocalBindings :: TidyEnv -> CtLoc -> TcM [Id] +getLocalBindings tidy_orig ct_loc + = do { (env1, _) <- zonkTidyOrigin tidy_orig (ctLocOrigin ct_loc) ; go env1 [] (removeBindingShadowing $ tcl_bndrs lcl_env) } where - loc = ctEvLoc (ctEvidence ct) - lcl_env = ctLocEnv loc + lcl_env = ctLocEnv ct_loc go :: TidyEnv -> [Id] -> [TcBinder] -> TcM [Id] go _ sofar [] = return (reverse sofar) @@ -542,11 +512,13 @@ findValidHoleFits :: TidyEnv -- ^ The tidy_env for zonking -> [Ct] -- ^ The unsolved simple constraints in the implication for -- the hole. - -> Ct -- ^ The hole constraint itself + -> Hole -> TcM (TidyEnv, SDoc) -findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = +findValidHoleFits tidy_env implics simples h@(Hole { hole_sort = ExprHole _ + , hole_loc = ct_loc + , hole_ty = hole_ty }) = do { rdr_env <- getGlobalRdrEnv - ; lclBinds <- getLocalBindings tidy_env ct + ; lclBinds <- getLocalBindings tidy_env ct_loc ; maxVSubs <- maxValidHoleFits <$> getDynFlags ; hfdc <- getHoleFitDispConfig ; sortingAlg <- getSortingAlg @@ -554,7 +526,9 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = ; hfPlugs <- tcg_hf_plugins <$> getGblEnv ; let findVLimit = if sortingAlg > NoSorting then Nothing else maxVSubs refLevel = refLevelHoleFits dflags - hole = TyH (listToBag relevantCts) implics (Just ct) + hole = TypedHole { th_relevant_cts = listToBag relevantCts + , th_implics = implics + , th_hole = Just h } (candidatePlugins, fitPlugins) = unzip $ map (\p-> ((candPlugin p) hole, (fitPlugin p) hole)) hfPlugs ; traceTc "findingValidHoleFitsFor { " $ ppr hole @@ -625,11 +599,9 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = where -- We extract the type, the tcLevel and the types free variables -- from from the constraint. - hole_ty :: TcPredType - hole_ty = ctPred ct hole_fvs :: FV hole_fvs = tyCoFVsOfType hole_ty - hole_lvl = ctLocLevel $ ctEvLoc $ ctEvidence ct + hole_lvl = ctLocLevel ct_loc -- BuiltInSyntax names like (:) and [] builtIns :: [Name] @@ -668,7 +640,7 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = <*> sortByGraph (sort gblFits) where (lclFits, gblFits) = span hfIsLcl subs - -- See Note [Relevant Constraints] + -- See Note [Relevant constraints] relevantCts :: [Ct] relevantCts = if isEmptyVarSet (fvVarSet hole_fvs) then [] else filter isRelevant simples @@ -684,7 +656,6 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = -- trying to find hole fits for many holes at once. isRelevant ct = not (isEmptyVarSet (ctFreeVarSet ct)) && anyFVMentioned ct - && not (isHoleCt ct) -- We zonk the hole fits so that the output aligns with the rest -- of the typed hole error message output. @@ -761,7 +732,7 @@ tcFilterHoleFits :: Maybe Int -- ^ We return whether or not we stopped due to hitting the limit -- and the fits we found. tcFilterHoleFits (Just 0) _ _ _ = return (False, []) -- Stop right away on 0 -tcFilterHoleFits limit (TyH {..}) ht@(hole_ty, _) candidates = +tcFilterHoleFits limit typed_hole@(TypedHole {..}) ht@(hole_ty, _) candidates = do { traceTc "checkingFitsFor {" $ ppr hole_ty ; (discards, subs) <- go [] emptyVarSet limit ht candidates ; traceTc "checkingFitsFor }" empty @@ -895,8 +866,7 @@ tcFilterHoleFits limit (TyH {..}) ht@(hole_ty, _) candidates = else return Nothing } else return Nothing } where fvs = mkFVs ref_vars `unionFV` hole_fvs `unionFV` tyCoFVsOfType ty - hole = TyH tyHRelevantCts tyHImplics Nothing - + hole = typed_hole { th_hole = Nothing } subsDiscardMsg :: SDoc subsDiscardMsg = @@ -925,7 +895,8 @@ withoutUnification free_vars action = -- Reset any mutated free variables ; mapM_ restore flexis ; return result } - where restore = flip writeTcRef Flexi . metaTyVarRef + where restore tv = do { traceTc "withoutUnification: restore flexi" (ppr tv) + ; writeTcRef (metaTyVarRef tv) Flexi } fuvs = fvVarList free_vars -- | Reports whether first type (ty_a) subsumes the second type (ty_b), @@ -933,14 +904,14 @@ withoutUnification free_vars action = -- ty_a, i.e. `tcSubsumes a b == True` if b is a subtype of a. tcSubsumes :: TcSigmaType -> TcSigmaType -> TcM Bool tcSubsumes ty_a ty_b = fst <$> tcCheckHoleFit dummyHole ty_a ty_b - where dummyHole = TyH emptyBag [] Nothing + where dummyHole = TypedHole { th_relevant_cts = emptyBag + , th_implics = [] + , th_hole = Nothing } -- | A tcSubsumes which takes into account relevant constraints, to fix trac -- #14273. This makes sure that when checking whether a type fits the hole, -- the type has to be subsumed by type of the hole as well as fulfill all -- constraints on the type of the hole. --- Note: The simplifier may perform unification, so make sure to restore any --- free type variables to avoid side-effects. tcCheckHoleFit :: TypedHole -- ^ The hole to check against -> TcSigmaType -- ^ The type to check against (possibly modified, e.g. refined) @@ -949,56 +920,48 @@ tcCheckHoleFit :: TypedHole -- ^ The hole to check against -- ^ Whether it was a match, and the wrapper from hole_ty to ty. tcCheckHoleFit _ hole_ty ty | hole_ty `eqType` ty = return (True, idHsWrapper) -tcCheckHoleFit (TyH {..}) hole_ty ty = discardErrs $ +tcCheckHoleFit (TypedHole {..}) hole_ty ty = discardErrs $ do { -- We wrap the subtype constraint in the implications to pass along the -- givens, and so we must ensure that any nested implications and skolems -- end up with the correct level. The implications are ordered so that -- the innermost (the one with the highest level) is first, so it -- suffices to get the level of the first one (or the current level, if -- there are no implications involved). - innermost_lvl <- case tyHImplics of + innermost_lvl <- case th_implics of [] -> getTcLevel -- imp is the innermost implication (imp:_) -> return (ic_tclvl imp) - ; (wrp, wanted) <- setTcLevel innermost_lvl $ captureConstraints $ - tcSubType_NC ExprSigCtxt ty hole_ty + ; (wrap, wanted) <- setTcLevel innermost_lvl $ captureConstraints $ + tcSubType_NC ExprSigCtxt ty hole_ty ; traceTc "Checking hole fit {" empty ; traceTc "wanteds are: " $ ppr wanted - ; if isEmptyWC wanted && isEmptyBag tyHRelevantCts - then traceTc "}" empty >> return (True, wrp) + ; if isEmptyWC wanted && isEmptyBag th_relevant_cts + then do { traceTc "}" empty + ; return (True, wrap) } else do { fresh_binds <- newTcEvBinds -- The relevant constraints may contain HoleDests, so we must -- take care to clone them as well (to avoid #15370). - ; cloned_relevants <- mapBagM cloneWanted tyHRelevantCts + ; cloned_relevants <- mapBagM cloneWanted th_relevant_cts -- We wrap the WC in the nested implications, see - -- Note [Nested Implications] - ; let outermost_first = reverse tyHImplics - setWC = setWCAndBinds fresh_binds + -- Note [Checking hole fits] + ; let outermost_first = reverse th_implics -- We add the cloned relevants to the wanteds generated by - -- the call to tcSubType_NC, see Note [Relevant Constraints] + -- the call to tcSubType_NC, see Note [Relevant constraints] -- There's no need to clone the wanteds, because they are -- freshly generated by `tcSubtype_NC`. w_rel_cts = addSimples wanted cloned_relevants - w_givens = foldr setWC w_rel_cts outermost_first - ; traceTc "w_givens are: " $ ppr w_givens - ; rem <- runTcSDeriveds $ simpl_top w_givens + final_wc = foldr (setWCAndBinds fresh_binds) w_rel_cts outermost_first + ; traceTc "final_wc is: " $ ppr final_wc + ; rem <- runTcSDeriveds $ simpl_top final_wc -- We don't want any insoluble or simple constraints left, but -- solved implications are ok (and necessary for e.g. undefined) ; traceTc "rems was:" $ ppr rem ; traceTc "}" empty - ; return (isSolvedWC rem, wrp) } } + ; return (isSolvedWC rem, wrap) } } where setWCAndBinds :: EvBindsVar -- Fresh ev binds var. -> Implication -- The implication to put WC in. -> WantedConstraints -- The WC constraints to put implic. -> WantedConstraints -- The new constraints. setWCAndBinds binds imp wc - = WC { wc_simple = emptyBag - , wc_impl = unitBag $ imp { ic_wanted = wc , ic_binds = binds } } - --- | Maps a plugin that needs no state to one with an empty one. -fromPureHFPlugin :: HoleFitPlugin -> HoleFitPluginR -fromPureHFPlugin plug = - HoleFitPluginR { hfPluginInit = newTcRef () - , hfPluginRun = const plug - , hfPluginStop = const $ return () } + = mkImplicWC $ unitBag $ imp { ic_wanted = wc , ic_binds = binds } ===================================== compiler/GHC/Tc/Errors/Hole.hs-boot ===================================== @@ -5,9 +5,9 @@ module GHC.Tc.Errors.Hole where import GHC.Tc.Types ( TcM ) -import GHC.Tc.Types.Constraint ( Ct, Implication ) +import GHC.Tc.Types.Constraint ( Ct, Hole, Implication ) import GHC.Utils.Outputable ( SDoc ) import GHC.Types.Var.Env ( TidyEnv ) -findValidHoleFits :: TidyEnv -> [Implication] -> [Ct] -> Ct +findValidHoleFits :: TidyEnv -> [Implication] -> [Ct] -> Hole -> TcM (TidyEnv, SDoc) ===================================== compiler/GHC/Tc/Errors/Hole/FitTypes.hs ===================================== @@ -21,20 +21,21 @@ import GHC.Types.Name import Data.Function ( on ) -data TypedHole = TyH { tyHRelevantCts :: Cts - -- ^ Any relevant Cts to the hole - , tyHImplics :: [Implication] - -- ^ The nested implications of the hole with the - -- innermost implication first. - , tyHCt :: Maybe Ct - -- ^ The hole constraint itself, if available. - } +data TypedHole = TypedHole { th_relevant_cts :: Cts + -- ^ Any relevant Cts to the hole + , th_implics :: [Implication] + -- ^ The nested implications of the hole with the + -- innermost implication first. + , th_hole :: Maybe Hole + -- ^ The hole itself, if available. Only for debugging. + } instance Outputable TypedHole where - ppr (TyH rels implics ct) + ppr (TypedHole { th_relevant_cts = rels + , th_implics = implics + , th_hole = hole }) = hang (text "TypedHole") 2 - (ppr rels $+$ ppr implics $+$ ppr ct) - + (ppr rels $+$ ppr implics $+$ ppr hole) -- | HoleFitCandidates are passed to hole fit plugins and then -- checked whether they fit a given typed-hole. @@ -51,9 +52,6 @@ pprHoleFitCand (IdHFCand cid) = text "Id HFC: " <> ppr cid pprHoleFitCand (NameHFCand cname) = text "Name HFC: " <> ppr cname pprHoleFitCand (GreHFCand cgre) = text "Gre HFC: " <> ppr cgre - - - instance NamedThing HoleFitCandidate where getName hfc = case hfc of IdHFCand cid -> idName cid ===================================== compiler/GHC/Tc/Gen/Expr.hs ===================================== @@ -36,7 +36,6 @@ import {-# SOURCE #-} GHC.Tc.Gen.Splice( tcSpliceExpr, tcTypedBracket, tcUntyp import GHC.Builtin.Names.TH( liftStringName, liftName ) import GHC.Hs -import GHC.Tc.Types.Constraint ( HoleSort(..) ) import GHC.Tc.Utils.Zonk import GHC.Tc.Utils.Monad import GHC.Tc.Utils.Unify @@ -1408,22 +1407,21 @@ Suppose 'wurble' is not in scope, and we have Then the renamer will make (HsUnboundVar "wurble) for 'wurble', and the typechecker will typecheck it with tcUnboundId, giving it -a type 'alpha', and emitting a deferred CHoleCan constraint, to -be reported later. +a type 'alpha', and emitting a deferred Hole, to be reported later. But then comes the visible type application. If we do nothing, we'll generate an immediate failure (in tc_app_err), saying that a function of type 'alpha' can't be applied to Bool. That's insane! And indeed users complain bitterly (#13834, #17150.) -The right error is the CHoleCan, which has /already/ been emitted by +The right error is the Hole, which has /already/ been emitted by tcUnboundId. It later reports 'wurble' as out of scope, and tries to give its type. Fortunately in tcArgs we still have access to the function, so we can check if it is a HsUnboundVar. We use this info to simply skip over any visible type arguments. We've already inferred the type of the -function, so we'll /already/ have emitted a CHoleCan constraint; +function, so we'll /already/ have emitted a Hole; failing preserves that constraint. We do /not/ want to fail altogether in this case (via failM) becuase @@ -1900,14 +1898,13 @@ tcUnboundId :: HsExpr GhcRn -> OccName -> ExpRhoType -> TcM (HsExpr GhcTc) -- Others might simply be variables that accidentally have no binding site -- -- We turn all of them into HsVar, since HsUnboundVar can't contain an --- Id; and indeed the evidence for the CHoleCan does bind it, so it's +-- Id; and indeed the evidence for the ExprHole does bind it, so it's -- not unbound any more! tcUnboundId rn_expr occ res_ty = do { ty <- newOpenFlexiTyVarTy -- Allow Int# etc (#12531) ; name <- newSysName occ ; let ev = mkLocalId name ty - ; can <- newHoleCt ExprHole ev ty - ; emitInsoluble can + ; emitNewExprHole occ ev ty ; tcWrapResultO (UnboundOccurrenceOf occ) rn_expr (HsVar noExtField (noLoc ev)) ty res_ty } ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -419,7 +419,7 @@ tcHsTypeApp wc_ty kind ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A HsWildCardBndrs's hswc_ext now only includes /named/ wildcards, so any unnamed wildcards stay unchanged in hswc_body. When called in -tcHsTypeApp, tcCheckLHsType will call emitAnonWildCardHoleConstraint +tcHsTypeApp, tcCheckLHsType will call emitAnonTypeHole on these anonymous wildcards. However, this would trigger error/warning when an anonymous wildcard is passed in as a visible type argument, which we do not want because users should be able to write @@ -891,7 +891,7 @@ tcAnonWildCardOcc wc exp_kind ; warning <- woptM Opt_WarnPartialTypeSignatures ; unless (part_tysig && not warning) $ - emitAnonWildCardHoleConstraint wc_tv + emitAnonTypeHole wc_tv -- Why the 'unless' guard? -- See Note [Wildcards in visible kind application] @@ -911,11 +911,11 @@ x = MkT So we should allow '@_' without emitting any hole constraints, and regardless of whether PartialTypeSignatures is enabled or not. But how would the typechecker know which '_' is being used in VKA and which is not when it -calls emitNamedWildCardHoleConstraints in tcHsPartialSigType on all HsWildCardBndrs? +calls emitNamedTypeHole in tcHsPartialSigType on all HsWildCardBndrs? The solution then is to neither rename nor include unnamed wildcards in HsWildCardBndrs, but instead give every anonymous wildcard a fresh wild tyvar in tcAnonWildCardOcc. And whenever we see a '@', we automatically turn on PartialTypeSignatures and -turn off hole constraint warnings, and do not call emitAnonWildCardHoleConstraint +turn off hole constraint warnings, and do not call emitAnonTypeHole under these conditions. See related Note [Wildcards in visible type application] here and Note [The wildcard story for types] in GHC.Hs.Types @@ -3192,7 +3192,7 @@ tcHsPartialSigType ctxt sig_ty -- Spit out the wildcards (including the extra-constraints one) -- as "hole" constraints, so that they'll be reported if necessary -- See Note [Extra-constraint holes in partial type signatures] - ; emitNamedWildCardHoleConstraints wcs + ; mapM_ emitNamedTypeHole wcs -- Zonk, so that any nested foralls can "see" their occurrences -- See Note [Checking partial type signatures], in @@ -3365,7 +3365,7 @@ tcHsPatSigType ctxt sig_ty do { sig_ty <- tcHsOpenType hs_ty ; return (wcs, sig_ty) } - ; emitNamedWildCardHoleConstraints wcs + ; mapM_ emitNamedTypeHole wcs -- sig_ty might have tyvars that are at a higher TcLevel (if hs_ty -- contains a forall). Promote these. ===================================== compiler/GHC/Tc/Gen/Rule.hs ===================================== @@ -462,7 +462,7 @@ getRuleQuantCts wc float_wc :: TcTyCoVarSet -> WantedConstraints -> (Cts, WantedConstraints) float_wc skol_tvs (WC { wc_simple = simples, wc_impl = implics }) = ( simple_yes `andCts` implic_yes - , WC { wc_simple = simple_no, wc_impl = implics_no }) + , emptyWC { wc_simple = simple_no, wc_impl = implics_no }) where (simple_yes, simple_no) = partitionBag (rule_quant_ct skol_tvs) simples (implic_yes, implics_no) = mapAccumBagL (float_implic skol_tvs) @@ -480,8 +480,6 @@ getRuleQuantCts wc | EqPred _ t1 t2 <- classifyPredType (ctPred ct) , not (ok_eq t1 t2) = False -- Note [RULE quantification over equalities] - | isHoleCt ct - = False -- Don't quantify over type holes, obviously | otherwise = tyCoVarsOfCt ct `disjointVarSet` skol_tvs ===================================== compiler/GHC/Tc/Module.hs ===================================== @@ -2589,7 +2589,7 @@ tcRnType hsc_env flexi normalise rdr_type -- kindGeneralize, below solveEqualities $ tcNamedWildCardBinders wcs $ \ wcs' -> - do { emitNamedWildCardHoleConstraints wcs' + do { mapM_ emitNamedTypeHole wcs' ; tcLHsTypeUnsaturated rn_type } -- Do kind generalisation; see Note [Kind-generalise in tcRnType] ===================================== compiler/GHC/Tc/Solver.hs ===================================== @@ -31,7 +31,7 @@ import GHC.Prelude import GHC.Data.Bag import GHC.Core.Class ( Class, classKey, classTyCon ) import GHC.Driver.Session -import GHC.Types.Id ( idType, mkLocalId ) +import GHC.Types.Id ( idType ) import GHC.Tc.Utils.Instantiate import GHC.Data.List.SetOps import GHC.Types.Name @@ -42,6 +42,7 @@ import GHC.Tc.Errors import GHC.Tc.Types.Evidence import GHC.Tc.Solver.Interact import GHC.Tc.Solver.Canonical ( makeSuperClasses, solveCallStack ) +import GHC.Tc.Solver.Flatten ( flattenType ) import GHC.Tc.Utils.TcMType as TcM import GHC.Tc.Utils.Monad as TcM import GHC.Tc.Solver.Monad as TcS @@ -145,8 +146,7 @@ simplifyTop wanteds ; saved_msg <- TcM.readTcRef errs_var ; TcM.writeTcRef errs_var emptyMessages - ; warnAllUnsolved $ WC { wc_simple = unsafe_ol - , wc_impl = emptyBag } + ; warnAllUnsolved $ emptyWC { wc_simple = unsafe_ol } ; whyUnsafe <- fst <$> TcM.readTcRef errs_var ; TcM.writeTcRef errs_var saved_msg @@ -638,27 +638,15 @@ tcNormalise :: Bag EvVar -> Type -> TcM Type tcNormalise given_ids ty = do { lcl_env <- TcM.getLclEnv ; let given_loc = mkGivenLoc topTcLevel UnkSkol lcl_env - ; wanted_ct <- mk_wanted_ct + ; norm_loc <- getCtLocM PatCheckOrigin Nothing ; (res, _ev_binds) <- runTcS $ do { traceTcS "tcNormalise {" (ppr given_ids) ; let given_cts = mkGivens given_loc (bagToList given_ids) ; solveSimpleGivens given_cts - ; wcs <- solveSimpleWanteds (unitBag wanted_ct) - -- It's an invariant that this wc_simple will always be - -- a singleton Ct, since that's what we fed in as input. - ; let ty' = case bagToList (wc_simple wcs) of - (ct:_) -> ctEvPred (ctEvidence ct) - cts -> pprPanic "tcNormalise" (ppr cts) + ; ty' <- flattenType norm_loc ty ; traceTcS "tcNormalise }" (ppr ty') ; pure ty' } ; return res } - where - mk_wanted_ct :: TcM Ct - mk_wanted_ct = do - let occ = mkVarOcc "$tcNorm" - name <- newSysName occ - let ev = mkLocalId name ty - newHoleCt ExprHole ev ty {- Note [Superclasses and satisfiability] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -696,11 +684,8 @@ if some local equalities are solved for. See "Wrinkle: Local equalities" in Note [Type normalisation] in Check. To accomplish its stated goal, tcNormalise first feeds the local constraints -into solveSimpleGivens, then stuffs the argument type in a CHoleCan, and feeds -that singleton Ct into solveSimpleWanteds, which reduces the type in the -CHoleCan as much as possible with respect to the local given constraints. When -solveSimpleWanteds is finished, we dig out the type from the CHoleCan and -return that. +into solveSimpleGivens, then uses flattenType to simplify the desired type +with respect to the givens. *********************************************************************************** * * @@ -889,8 +874,8 @@ mkResidualConstraints rhs_tclvl ev_binds_var , ic_no_eqs = False , ic_info = skol_info } - ; return (WC { wc_simple = outer_simple - , wc_impl = implics })} + ; return (emptyWC { wc_simple = outer_simple + , wc_impl = implics })} where full_theta = map idType full_theta_vars skol_info = InferSkol [ (name, mkSigmaTy [] full_theta ty) @@ -1516,7 +1501,7 @@ solveWantedsAndDrop wanted solveWanteds :: WantedConstraints -> TcS WantedConstraints -- so that the inert set doesn't mindlessly propagate. -- NB: wc_simples may be wanted /or/ derived now -solveWanteds wc@(WC { wc_simple = simples, wc_impl = implics }) +solveWanteds wc@(WC { wc_simple = simples, wc_impl = implics, wc_holes = holes }) = do { cur_lvl <- TcS.getTcLevel ; traceTcS "solveWanteds {" $ vcat [ text "Level =" <+> ppr cur_lvl @@ -1530,9 +1515,12 @@ solveWanteds wc@(WC { wc_simple = simples, wc_impl = implics }) implics `unionBags` wc_impl wc1 ; dflags <- getDynFlags - ; final_wc <- simpl_loop 0 (solverIterations dflags) floated_eqs + ; solved_wc <- simpl_loop 0 (solverIterations dflags) floated_eqs (wc1 { wc_impl = implics2 }) + ; holes' <- simplifyHoles holes + ; let final_wc = solved_wc { wc_holes = holes' } + ; ev_binds_var <- getTcEvBindsVar ; bb <- TcS.getTcEvBindsMap ev_binds_var ; traceTcS "solveWanteds }" $ @@ -1779,12 +1767,13 @@ setImplicationStatus implic@(Implic { ic_status = status then Nothing else Just final_implic } where - WC { wc_simple = simples, wc_impl = implics } = wc + WC { wc_simple = simples, wc_impl = implics, wc_holes = holes } = wc pruned_simples = dropDerivedSimples simples pruned_implics = filterBag keep_me implics pruned_wc = WC { wc_simple = pruned_simples - , wc_impl = pruned_implics } + , wc_impl = pruned_implics + , wc_holes = holes } -- do not prune holes; these should be reported keep_me :: Implication -> Bool keep_me ic @@ -1898,6 +1887,14 @@ neededEvVars implic@(Implic { ic_given = givens | is_given = needs -- Add the rhs vars of the Wanted bindings only | otherwise = evVarsOfTerm rhs `unionVarSet` needs +------------------------------------------------- +simplifyHoles :: Bag Hole -> TcS (Bag Hole) +simplifyHoles = mapBagM simpl_hole + where + simpl_hole :: Hole -> TcS Hole + simpl_hole h@(Hole { hole_ty = ty, hole_loc = loc }) + = do { ty' <- flattenType loc ty + ; return (h { hole_ty = ty' }) } {- Note [Delete dead Given evidence bindings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2143,7 +2140,6 @@ approximateWC float_past_equalities wc is_floatable skol_tvs ct | isGivenCt ct = False - | isHoleCt ct = False | insolubleEqCt ct = False | otherwise = tyCoVarsOfCt ct `disjointVarSet` skol_tvs ===================================== compiler/GHC/Tc/Solver/Canonical.hs ===================================== @@ -34,7 +34,6 @@ import GHC.Tc.Instance.Family ( tcTopNormaliseNewTypeTF_maybe ) import GHC.Types.Var import GHC.Types.Var.Env( mkInScopeSet ) import GHC.Types.Var.Set( delVarSetList ) -import GHC.Types.Name.Occurrence ( OccName ) import GHC.Utils.Outputable import GHC.Driver.Session( DynFlags ) import GHC.Types.Name.Set @@ -67,8 +66,7 @@ Canonicalization converts a simple constraint to a canonical form. It is unary (i.e. treats individual constraints one at a time). Constraints originating from user-written code come into being as -CNonCanonicals (except for CHoleCans, arising from holes). We know nothing -about these constraints. So, first: +CNonCanonicals. We know nothing about these constraints. So, first: Classify CNonCanoncal constraints, depending on whether they are equalities, class predicates, or other. @@ -137,9 +135,6 @@ canonicalize (CFunEqCan { cc_ev = ev = {-# SCC "canEqLeafFunEq" #-} canCFunEqCan ev fn xis1 fsk -canonicalize (CHoleCan { cc_ev = ev, cc_occ = occ, cc_hole = hole }) - = canHole ev occ hole - {- ************************************************************************ * * @@ -718,17 +713,6 @@ canIrred status ev _ -> continueWith $ mkIrredCt status new_ev } } -canHole :: CtEvidence -> OccName -> HoleSort -> TcS (StopOrContinue Ct) -canHole ev occ hole_sort - = do { let pred = ctEvPred ev - ; (xi,co) <- flatten FM_SubstOnly ev pred -- co :: xi ~ pred - ; rewriteEvidence ev xi co `andWhenContinue` \ new_ev -> - do { updInertIrreds (`snocCts` (CHoleCan { cc_ev = new_ev - , cc_occ = occ - , cc_hole = hole_sort })) - ; stopWith new_ev "Emit insoluble hole" } } - - {- ********************************************************************* * * * Quantified predicates @@ -1401,6 +1385,7 @@ can_eq_app ev s1 t1 s2 t2 | CtDerived {} <- ev = do { unifyDeriveds loc [Nominal, Nominal] [s1, t1] [s2, t2] ; stopWith ev "Decomposed [D] AppTy" } + | CtWanted { ctev_dest = dest } <- ev = do { co_s <- unifyWanted loc Nominal s1 s2 ; let arg_loc ===================================== compiler/GHC/Tc/Solver/Flatten.hs ===================================== @@ -5,7 +5,7 @@ module GHC.Tc.Solver.Flatten( FlattenMode(..), flatten, flattenKind, flattenArgsNom, - rewriteTyVar, + rewriteTyVar, flattenType, unflattenWanteds ) where @@ -825,6 +825,20 @@ flattenArgsNom ev tc tys ; traceTcS "flatten }" (vcat (map ppr tys')) ; return (tys', cos, kind_co) } +-- | Flatten a type w.r.t. nominal equality. This is useful to rewrite +-- a type w.r.t. any givens. It does not do type-family reduction. This +-- will never emit new constraints. Call this when the inert set contains +-- only givens. +flattenType :: CtLoc -> TcType -> TcS TcType +flattenType loc ty + -- More info about FM_SubstOnly in Note [Holes] in GHC.Tc.Types.Constraint + = do { (xi, _) <- runFlatten FM_SubstOnly loc Given NomEq $ + flatten_one ty + -- use Given flavor so that it is rewritten + -- only w.r.t. Givens, never Wanteds/Deriveds + -- (Shouldn't matter, if only Givens are present + -- anyway) + ; return xi } {- ********************************************************************* * * ===================================== compiler/GHC/Tc/Solver/Interact.hs ===================================== @@ -195,7 +195,7 @@ solve_simple_wanteds :: WantedConstraints -> TcS (Int, WantedConstraints) -- Try solving these constraints -- Affects the unification state (of course) but not the inert set -- The result is not necessarily zonked -solve_simple_wanteds (WC { wc_simple = simples1, wc_impl = implics1 }) +solve_simple_wanteds (WC { wc_simple = simples1, wc_impl = implics1, wc_holes = holes }) = nestTcS $ do { solveSimples simples1 ; (implics2, tv_eqs, fun_eqs, others) <- getUnsolvedInerts @@ -204,7 +204,8 @@ solve_simple_wanteds (WC { wc_simple = simples1, wc_impl = implics1 }) -- See Note [Unflatten after solving the simple wanteds] ; return ( unif_count , WC { wc_simple = others `andCts` unflattened_eqs - , wc_impl = implics1 `unionBags` implics2 }) } + , wc_impl = implics1 `unionBags` implics2 + , wc_holes = holes }) } {- Note [The solveSimpleWanteds loop] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -264,7 +265,7 @@ runTcPluginsGiven -- 'solveSimpleWanteds' should feed the updated wanteds back into the -- main solver. runTcPluginsWanted :: WantedConstraints -> TcS (Bool, WantedConstraints) -runTcPluginsWanted wc@(WC { wc_simple = simples1, wc_impl = implics1 }) +runTcPluginsWanted wc@(WC { wc_simple = simples1 }) | isEmptyBag simples1 = return (False, wc) | otherwise @@ -285,11 +286,10 @@ runTcPluginsWanted wc@(WC { wc_simple = simples1, wc_impl = implics1 }) ; mapM_ setEv solved_wanted ; return ( notNull (pluginNewCts p) - , WC { wc_simple = listToBag new_wanted `andCts` + , wc { wc_simple = listToBag new_wanted `andCts` listToBag unsolved_wanted `andCts` listToBag unsolved_derived `andCts` - listToBag insols - , wc_impl = implics1 } ) } } + listToBag insols } ) } } where setEv :: (EvTerm,Ct) -> TcS () setEv (ev,ct) = case ctEvidence ct of @@ -494,7 +494,6 @@ interactWithInertsStage wi CIrredCan {} -> interactIrred ics wi CDictCan {} -> interactDict ics wi _ -> pprPanic "interactWithInerts" (ppr wi) } - -- CHoleCan are put straight into inert_frozen, so never get here -- CNonCanonical have been canonicalised data InteractResult ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -198,7 +198,7 @@ import GHC.Types.Unique.Set Note [WorkList priorities] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -A WorkList contains canonical and non-canonical items (of all flavors). +A WorkList contains canonical and non-canonical items (of all flavours). Notice that each Ct now has a simplification depth. We may consider using this depth for prioritization as well in the future. @@ -1653,8 +1653,7 @@ add_item ics item@(CDictCan { cc_ev = ev, cc_class = cls, cc_tyargs = tys }) add_item _ item = pprPanic "upd_inert set: can't happen! Inserting " $ - ppr item -- Can't be CNonCanonical, CHoleCan, - -- because they only land in inert_irreds + ppr item -- Can't be CNonCanonical because they only land in inert_irreds bumpUnsolvedCount :: CtEvidence -> Int -> Int bumpUnsolvedCount ev n | isWanted ev = n+1 @@ -1896,10 +1895,6 @@ be decomposed. Otherwise we end up with a "Can't match [Int] ~ [[Int]]" which is true, but a bit confusing because the outer type constructors match. -Similarly, if we have a CHoleCan, we'd like to rewrite it with any -Givens, to give as informative an error messasge as possible -(#12468, #11325). - Hence: * In the main simplifier loops in GHC.Tc.Solver (solveWanteds, simpl_loop), we feed the insolubles in solveSimpleWanteds, @@ -2352,8 +2347,6 @@ removeInertCt is ct = CQuantCan {} -> panic "removeInertCt: CQuantCan" CIrredCan {} -> panic "removeInertCt: CIrredEvCan" CNonCanonical {} -> panic "removeInertCt: CNonCanonical" - CHoleCan {} -> panic "removeInertCt: CHoleCan" - lookupFlatCache :: TyCon -> [Type] -> TcS (Maybe (TcCoercion, TcType, CtFlavour)) lookupFlatCache fam_tc tys ===================================== compiler/GHC/Tc/Types/Constraint.hs ===================================== @@ -14,8 +14,7 @@ module GHC.Tc.Types.Constraint ( isEmptyCts, isCTyEqCan, isCFunEqCan, isPendingScDict, superClassesMightHelp, getPendingWantedScs, isCDictCan_Maybe, isCFunEqCan_maybe, - isCNonCanonical, isWantedCt, isDerivedCt, - isGivenCt, isHoleCt, isOutOfScopeCt, isExprHoleCt, isTypeHoleCt, + isCNonCanonical, isWantedCt, isDerivedCt, isGivenCt, isUserTypeErrorCt, getUserTypeErrorMsg, ctEvidence, ctLoc, setCtLoc, ctPred, ctFlavour, ctEqRel, ctOrigin, ctEvId, mkTcEqPredLikeEv, @@ -26,9 +25,11 @@ module GHC.Tc.Types.Constraint ( tyCoVarsOfCt, tyCoVarsOfCts, tyCoVarsOfCtList, tyCoVarsOfCtsList, + Hole(..), HoleSort(..), isOutOfScopeHole, + WantedConstraints(..), insolubleWC, emptyWC, isEmptyWC, isSolvedWC, andWC, unionsWC, mkSimpleWC, mkImplicWC, - addInsols, insolublesOnly, addSimples, addImplics, + addInsols, insolublesOnly, addSimples, addImplics, addHole, tyCoVarsOfWC, dropDerivedWC, dropDerivedSimples, tyCoVarsOfWCList, insolubleCt, insolubleEqCt, isDroppableCt, insolubleImplic, @@ -62,9 +63,6 @@ module GHC.Tc.Types.Constraint ( pprEvVarTheta, pprEvVars, pprEvVarWithType, - -- holes - HoleSort(..), - ) where @@ -202,14 +200,6 @@ data Ct cc_ev :: CtEvidence } - | CHoleCan { -- See Note [Hole constraints] - -- Treated as an "insoluble" constraint - -- See Note [Insoluble constraints] - cc_ev :: CtEvidence, - cc_occ :: OccName, -- The name of this hole - cc_hole :: HoleSort -- The sort of this hole (expr, type, ...) - } - | CQuantCan QCInst -- A quantified constraint -- NB: I expect to make more of the cases in Ct -- look like this, with the payload in an @@ -230,13 +220,47 @@ instance Outputable QCInst where ppr (QCI { qci_ev = ev }) = ppr ev ------------ +-- | A hole stores the information needed to report diagnostics +-- about holes in terms (unbound identifiers or underscores) or +-- in types (also called wildcards, as used in partial type +-- signatures). See Note [Holes]. +data Hole + = Hole { hole_sort :: HoleSort -- ^ What flavour of hole is this? + , hole_occ :: OccName -- ^ The name of this hole + , hole_ty :: TcType -- ^ Type to be printed to the user + -- For expression holes: type of expr + -- For type holes: the missing type + , hole_loc :: CtLoc -- ^ Where hole was written + } + -- For the hole_loc, we usually only want the TcLclEnv stored within. + -- Except when we flatten, where we need a whole location. And this + -- might get reported to the user if reducing type families in a + -- hole type loops. + + -- | Used to indicate which sort of hole we have. -data HoleSort = ExprHole +data HoleSort = ExprHole Id -- ^ Either an out-of-scope variable or a "true" hole in an - -- expression (TypedHoles) + -- expression (TypedHoles). + -- The 'Id' is where to store "evidence": this evidence + -- will be an erroring expression for -fdefer-type-errors. | TypeHole -- ^ A hole in a type (PartialTypeSignatures) +instance Outputable Hole where + ppr (Hole { hole_sort = ExprHole id + , hole_occ = occ + , hole_ty = ty }) + = parens $ (braces $ ppr occ <> colon <> ppr id) <+> dcolon <+> ppr ty + ppr (Hole { hole_sort = TypeHole + , hole_occ = occ + , hole_ty = ty }) + = braces $ ppr occ <> colon <> ppr ty + +instance Outputable HoleSort where + ppr (ExprHole id) = text "ExprHole:" <> ppr id + ppr TypeHole = text "TypeHole" + ------------ -- | Used to indicate extra information about why a CIrredCan is irreducible data CtIrredStatus @@ -252,20 +276,8 @@ instance Outputable CtIrredStatus where ppr BlockedCIS = text "(blocked)" ppr OtherCIS = text "(soluble)" -{- Note [Hole constraints] -~~~~~~~~~~~~~~~~~~~~~~~~~~ -CHoleCan constraints are used for two kinds of holes, -distinguished by cc_hole: - - * For holes in expressions - e.g. f x = g _ x - - * For holes in type signatures - e.g. f :: _ -> _ - f x = [x,True] - -Note [CIrredCan constraints] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [CIrredCan constraints] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CIrredCan constraints are used for constraints that are "stuck" - we can't solve them (yet) - we can't use them to solve other constraints @@ -350,6 +362,40 @@ unenforced). The almost-function-free property is checked by isAlmostFunctionFree in GHC.Tc.Utils.TcType. The flattener (in GHC.Tc.Solver.Flatten) produces types that are almost function-free. +Note [Holes] +~~~~~~~~~~~~ +This Note explains how GHC tracks *holes*. + +A hole represents one of two conditions: + - A missing bit of an expression. Example: foo x = x + _ + - A missing bit of a type. Example: bar :: Int -> _ + +What these have in common is that both cause GHC to emit a diagnostic to the +user describing the bit that is left out. + +When a hole is encountered, a new entry of type Hole is added to the ambient +WantedConstraints. The type (hole_ty) of the hole is then simplified during +solving (with respect to any Givens in surrounding implications). It is +reported with all the other errors in GHC.Tc.Errors. No type family reduction +is done on hole types; this is purely because we think it will produce +better error messages not to reduce type families. This is why the +GHC.Tc.Solver.Flatten.flattenType function uses FM_SubstOnly. + +For expression holes, the user has the option of deferring errors until runtime +with -fdefer-type-errors. In this case, the hole actually has evidence: this +evidence is an erroring expression that prints an error and crashes at runtime. +The ExprHole variant of holes stores the Id that will be bound to this evidence; +during constraint generation, this Id was inserted into the expression output +by the type checker. + +You might think that the type of the stored Id is the same as the type of the +hole. However, because the hole type (hole_ty) is rewritten with respect to +givens, this might not be the case. That is, the hole_ty is always (~) to the +type of the Id, but they might not be `eqType`. We need the type of the generated +evidence to match what is expected in the context of the hole, and so we must +store these types separately. + +Type-level holes have no evidence at all. -} mkNonCanonical :: CtEvidence -> Ct @@ -419,7 +465,6 @@ instance Outputable Ct where | pend_sc -> text "CDictCan(psc)" | otherwise -> text "CDictCan" CIrredCan { cc_status = status } -> text "CIrredCan" <> ppr status - CHoleCan { cc_occ = occ } -> text "CHoleCan:" <+> ppr occ CQuantCan (QCI { qci_pend_sc = pend_sc }) | pend_sc -> text "CQuantCan(psc)" | otherwise -> text "CQuantCan" @@ -552,7 +597,6 @@ isDroppableCt ct keep_deriv = case ct of - CHoleCan {} -> True CIrredCan { cc_status = InsolubleCIS } -> keep_eq True _ -> keep_eq False @@ -676,26 +720,6 @@ isCNonCanonical :: Ct -> Bool isCNonCanonical (CNonCanonical {}) = True isCNonCanonical _ = False -isHoleCt:: Ct -> Bool -isHoleCt (CHoleCan {}) = True -isHoleCt _ = False - -isOutOfScopeCt :: Ct -> Bool --- A Hole that does not have a leading underscore is --- simply an out-of-scope variable, and we treat that --- a bit differently when it comes to error reporting -isOutOfScopeCt (CHoleCan { cc_occ = occ }) = not (startsWithUnderscore occ) -isOutOfScopeCt _ = False - -isExprHoleCt :: Ct -> Bool -isExprHoleCt (CHoleCan { cc_hole = ExprHole }) = True -isExprHoleCt _ = False - -isTypeHoleCt :: Ct -> Bool -isTypeHoleCt (CHoleCan { cc_hole = TypeHole }) = True -isTypeHoleCt _ = False - - {- Note [Custom type errors in constraints] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -884,24 +908,25 @@ v%************************************************************************ data WantedConstraints = WC { wc_simple :: Cts -- Unsolved constraints, all wanted , wc_impl :: Bag Implication + , wc_holes :: Bag Hole } emptyWC :: WantedConstraints -emptyWC = WC { wc_simple = emptyBag, wc_impl = emptyBag } +emptyWC = WC { wc_simple = emptyBag + , wc_impl = emptyBag + , wc_holes = emptyBag } mkSimpleWC :: [CtEvidence] -> WantedConstraints mkSimpleWC cts - = WC { wc_simple = listToBag (map mkNonCanonical cts) - , wc_impl = emptyBag } + = emptyWC { wc_simple = listToBag (map mkNonCanonical cts) } mkImplicWC :: Bag Implication -> WantedConstraints mkImplicWC implic - = WC { wc_simple = emptyBag, wc_impl = implic } + = emptyWC { wc_impl = implic } isEmptyWC :: WantedConstraints -> Bool -isEmptyWC (WC { wc_simple = f, wc_impl = i }) - = isEmptyBag f && isEmptyBag i - +isEmptyWC (WC { wc_simple = f, wc_impl = i, wc_holes = holes }) + = isEmptyBag f && isEmptyBag i && isEmptyBag holes -- | Checks whether a the given wanted constraints are solved, i.e. -- that there are no simple constraints left and all the implications @@ -911,10 +936,11 @@ isSolvedWC WC {wc_simple = wc_simple, wc_impl = wc_impl} = isEmptyBag wc_simple && allBag (isSolvedStatus . ic_status) wc_impl andWC :: WantedConstraints -> WantedConstraints -> WantedConstraints -andWC (WC { wc_simple = f1, wc_impl = i1 }) - (WC { wc_simple = f2, wc_impl = i2 }) +andWC (WC { wc_simple = f1, wc_impl = i1, wc_holes = h1 }) + (WC { wc_simple = f2, wc_impl = i2, wc_holes = h2 }) = WC { wc_simple = f1 `unionBags` f2 - , wc_impl = i1 `unionBags` i2 } + , wc_impl = i1 `unionBags` i2 + , wc_holes = h1 `unionBags` h2 } unionsWC :: [WantedConstraints] -> WantedConstraints unionsWC = foldr andWC emptyWC @@ -931,11 +957,16 @@ addInsols :: WantedConstraints -> Bag Ct -> WantedConstraints addInsols wc cts = wc { wc_simple = wc_simple wc `unionBags` cts } +addHole :: WantedConstraints -> Hole -> WantedConstraints +addHole wc hole + = wc { wc_holes = hole `consBag` wc_holes wc } + insolublesOnly :: WantedConstraints -> WantedConstraints -- Keep only the definitely-insoluble constraints -insolublesOnly (WC { wc_simple = simples, wc_impl = implics }) +insolublesOnly (WC { wc_simple = simples, wc_impl = implics, wc_holes = holes }) = WC { wc_simple = filterBag insolubleCt simples - , wc_impl = mapBag implic_insols_only implics } + , wc_impl = mapBag implic_insols_only implics + , wc_holes = filterBag isOutOfScopeHole holes } where implic_insols_only implic = implic { ic_wanted = insolublesOnly (ic_wanted implic) } @@ -953,9 +984,10 @@ insolubleImplic :: Implication -> Bool insolubleImplic ic = isInsolubleStatus (ic_status ic) insolubleWC :: WantedConstraints -> Bool -insolubleWC (WC { wc_impl = implics, wc_simple = simples }) +insolubleWC (WC { wc_impl = implics, wc_simple = simples, wc_holes = holes }) = anyBag insolubleCt simples || anyBag insolubleImplic implics + || anyBag isOutOfScopeHole holes -- See Note [Insoluble holes] insolubleCt :: Ct -> Bool -- Definitely insoluble, in particular /excluding/ type-hole constraints @@ -963,7 +995,6 @@ insolubleCt :: Ct -> Bool -- b) that is insoluble -- c) and does not arise from a Given insolubleCt ct - | isHoleCt ct = isOutOfScopeCt ct -- See Note [Insoluble holes] | not (insolubleEqCt ct) = False | arisesFromGivens ct = False -- See Note [Given insolubles] | otherwise = True @@ -986,6 +1017,11 @@ insolubleEqCt :: Ct -> Bool insolubleEqCt (CIrredCan { cc_status = InsolubleCIS }) = True insolubleEqCt _ = False +-- | Does this hole represent an "out of scope" error? +-- See Note [Insoluble holes] +isOutOfScopeHole :: Hole -> Bool +isOutOfScopeHole (Hole { hole_occ = occ }) = not (startsWithUnderscore occ) + instance Outputable WantedConstraints where ppr (WC {wc_simple = s, wc_impl = i}) = text "WC" <+> braces (vcat @@ -1035,7 +1071,7 @@ Hole constraints that ARE NOT treated as truly insoluble: a) type holes, arising from PartialTypeSignatures, b) "true" expression holes arising from TypedHoles -An "expression hole" or "type hole" constraint isn't really an error +An "expression hole" or "type hole" isn't really an error at all; it's a report saying "_ :: Int" here. But an out-of-scope variable masquerading as expression holes IS treated as truly insoluble, so that it trumps other errors during error reporting. @@ -1512,10 +1548,6 @@ ctFlavourRole (CTyEqCan { cc_ev = ev, cc_eq_rel = eq_rel }) = (ctEvFlavour ev, eq_rel) ctFlavourRole (CFunEqCan { cc_ev = ev }) = (ctEvFlavour ev, NomEq) -ctFlavourRole (CHoleCan { cc_ev = ev }) - = (ctEvFlavour ev, NomEq) -- NomEq: CHoleCans can be rewritten by - -- by nominal equalities but empahatically - -- not by representational equalities ctFlavourRole ct = ctEvFlavourRole (ctEvidence ct) ===================================== compiler/GHC/Tc/Types/Origin.hs ===================================== @@ -427,7 +427,9 @@ data CtOrigin -- We only need a CtOrigin on the first, because the location -- is pinned on the entire error message - | HoleOrigin + | ExprHoleOrigin OccName -- from an expression hole + | TypeHoleOrigin OccName -- from a type hole (partial type signature) + | PatCheckOrigin -- normalisation of a type during pattern-match checking | UnboundOccurrenceOf OccName | ListOrigin -- An overloaded list | BracketOrigin -- An overloaded quotation bracket @@ -640,7 +642,9 @@ pprCtO MCompOrigin = text "a statement in a monad comprehension" pprCtO ProcOrigin = text "a proc expression" pprCtO (TypeEqOrigin t1 t2 _ _)= text "a type equality" <+> sep [ppr t1, char '~', ppr t2] pprCtO AnnOrigin = text "an annotation" -pprCtO HoleOrigin = text "a use of" <+> quotes (text "_") +pprCtO (ExprHoleOrigin occ) = text "a use of" <+> quotes (ppr occ) +pprCtO (TypeHoleOrigin occ) = text "a use of wildcard" <+> quotes (ppr occ) +pprCtO PatCheckOrigin = text "a pattern-match completeness check" pprCtO ListOrigin = text "an overloaded list" pprCtO StaticOrigin = text "a static form" pprCtO BracketOrigin = text "a quotation bracket" ===================================== compiler/GHC/Tc/Utils/Monad.hs ===================================== @@ -98,14 +98,14 @@ module GHC.Tc.Utils.Monad( chooseUniqueOccTc, getConstraintVar, setConstraintVar, emitConstraints, emitStaticConstraints, emitSimple, emitSimples, - emitImplication, emitImplications, emitInsoluble, + emitImplication, emitImplications, emitInsoluble, emitHole, discardConstraints, captureConstraints, tryCaptureConstraints, pushLevelAndCaptureConstraints, pushTcLevelM_, pushTcLevelM, pushTcLevelsM, getTcLevel, setTcLevel, isTouchableTcM, getLclTypeEnv, setLclTypeEnv, traceTcConstraints, - emitNamedWildCardHoleConstraints, emitAnonWildCardHoleConstraint, + emitNamedTypeHole, emitAnonTypeHole, -- * Template Haskell context recordThUse, recordThSpliceUse, @@ -1569,12 +1569,11 @@ emitInsoluble ct ; lie_var <- getConstraintVar ; updTcRef lie_var (`addInsols` unitBag ct) } -emitInsolubles :: Cts -> TcM () -emitInsolubles cts - | isEmptyBag cts = return () - | otherwise = do { traceTc "emitInsolubles" (ppr cts) - ; lie_var <- getConstraintVar - ; updTcRef lie_var (`addInsols` cts) } +emitHole :: Hole -> TcM () +emitHole hole + = do { traceTc "emitHole" (ppr hole) + ; lie_var <- getConstraintVar + ; updTcRef lie_var (`addHole` hole) } -- | Throw out any constraints emitted by the thing_inside discardConstraints :: TcM a -> TcM a @@ -1644,34 +1643,28 @@ traceTcConstraints msg hang (text (msg ++ ": LIE:")) 2 (ppr lie) } -emitAnonWildCardHoleConstraint :: TcTyVar -> TcM () -emitAnonWildCardHoleConstraint tv - = do { ct_loc <- getCtLocM HoleOrigin Nothing - ; emitInsolubles $ unitBag $ - CHoleCan { cc_ev = CtDerived { ctev_pred = mkTyVarTy tv - , ctev_loc = ct_loc } - , cc_occ = mkTyVarOcc "_" - , cc_hole = TypeHole } } - -emitNamedWildCardHoleConstraints :: [(Name, TcTyVar)] -> TcM () -emitNamedWildCardHoleConstraints wcs - = do { ct_loc <- getCtLocM HoleOrigin Nothing - ; emitInsolubles $ listToBag $ - map (do_one ct_loc) wcs } +emitAnonTypeHole :: TcTyVar -> TcM () +emitAnonTypeHole tv + = do { ct_loc <- getCtLocM (TypeHoleOrigin occ) Nothing + ; let hole = Hole { hole_sort = TypeHole + , hole_occ = occ + , hole_ty = mkTyVarTy tv + , hole_loc = ct_loc } + ; emitHole hole } + where + occ = mkTyVarOcc "_" + +emitNamedTypeHole :: (Name, TcTyVar) -> TcM () +emitNamedTypeHole (name, tv) + = do { ct_loc <- setSrcSpan (nameSrcSpan name) $ + getCtLocM (TypeHoleOrigin occ) Nothing + ; let hole = Hole { hole_sort = TypeHole + , hole_occ = occ + , hole_ty = mkTyVarTy tv + , hole_loc = ct_loc } + ; emitHole hole } where - do_one :: CtLoc -> (Name, TcTyVar) -> Ct - do_one ct_loc (name, tv) - = CHoleCan { cc_ev = CtDerived { ctev_pred = mkTyVarTy tv - , ctev_loc = ct_loc' } - , cc_occ = occName name - , cc_hole = TypeHole } - where - real_span = case nameSrcSpan name of - RealSrcSpan span _ -> span - UnhelpfulSpan str -> pprPanic "emitNamedWildCardHoleConstraints" - (ppr name <+> quotes (ftext str)) - -- Wildcards are defined locally, and so have RealSrcSpans - ct_loc' = setCtLocSpan ct_loc real_span + occ = nameOccName name {- Note [Constraints and errors] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Tc/Utils/TcMType.hs ===================================== @@ -41,10 +41,11 @@ module GHC.Tc.Utils.TcMType ( -------------------------------- -- Creating new evidence variables newEvVar, newEvVars, newDict, - newWanted, newWanteds, newHoleCt, cloneWanted, cloneWC, + newWanted, newWanteds, cloneWanted, cloneWC, emitWanted, emitWantedEq, emitWantedEvVar, emitWantedEvVars, emitDerivedEqs, newTcEvBinds, newNoTcEvBinds, addTcEvBind, + emitNewExprHole, newCoercionHole, fillCoercionHole, isFilledCoercionHole, unpackCoercionHole, unpackCoercionHole_maybe, @@ -67,7 +68,7 @@ module GHC.Tc.Utils.TcMType ( -------------------------------- -- Zonking and tidying zonkTidyTcType, zonkTidyTcTypes, zonkTidyOrigin, - tidyEvVar, tidyCt, tidySkolemInfo, + tidyEvVar, tidyCt, tidyHole, tidySkolemInfo, zonkTcTyVar, zonkTcTyVars, zonkTcTyVarToTyVar, zonkTyVarTyVarPairs, zonkTyCoVarsAndFV, zonkTcTypeAndFV, zonkDTyCoVarSetAndFV, @@ -193,17 +194,6 @@ newWanted orig t_or_k pty newWanteds :: CtOrigin -> ThetaType -> TcM [CtEvidence] newWanteds orig = mapM (newWanted orig Nothing) --- | Create a new 'CHoleCan' 'Ct'. -newHoleCt :: HoleSort -> Id -> Type -> TcM Ct -newHoleCt hole ev ty = do - loc <- getCtLocM HoleOrigin Nothing - pure $ CHoleCan { cc_ev = CtWanted { ctev_pred = ty - , ctev_dest = EvVarDest ev - , ctev_nosh = WDeriv - , ctev_loc = loc } - , cc_occ = getOccName ev - , cc_hole = hole } - ---------------------------------------------- -- Cloning constraints ---------------------------------------------- @@ -286,6 +276,18 @@ emitWantedEvVar origin ty emitWantedEvVars :: CtOrigin -> [TcPredType] -> TcM [EvVar] emitWantedEvVars orig = mapM (emitWantedEvVar orig) +-- | Emit a new wanted expression hole +emitNewExprHole :: OccName -- of the hole + -> Id -- of the evidence + -> Type -> TcM () +emitNewExprHole occ ev_id ty + = do { loc <- getCtLocM (ExprHoleOrigin occ) (Just TypeLevel) + ; let hole = Hole { hole_sort = ExprHole ev_id + , hole_occ = getOccName ev_id + , hole_ty = ty + , hole_loc = loc } + ; emitHole hole } + newDict :: Class -> [TcType] -> TcM DictId newDict cls tys = do { name <- newSysName (mkDictOcc (getOccName cls)) @@ -2002,21 +2004,28 @@ zonkWC :: WantedConstraints -> TcM WantedConstraints zonkWC wc = zonkWCRec wc zonkWCRec :: WantedConstraints -> TcM WantedConstraints -zonkWCRec (WC { wc_simple = simple, wc_impl = implic }) +zonkWCRec (WC { wc_simple = simple, wc_impl = implic, wc_holes = holes }) = do { simple' <- zonkSimples simple ; implic' <- mapBagM zonkImplication implic - ; return (WC { wc_simple = simple', wc_impl = implic' }) } + ; holes' <- mapBagM zonkHole holes + ; return (WC { wc_simple = simple', wc_impl = implic', wc_holes = holes' }) } zonkSimples :: Cts -> TcM Cts zonkSimples cts = do { cts' <- mapBagM zonkCt cts ; traceTc "zonkSimples done:" (ppr cts') ; return cts' } +zonkHole :: Hole -> TcM Hole +zonkHole hole@(Hole { hole_ty = ty }) + = do { ty' <- zonkTcType ty + ; return (hole { hole_ty = ty' }) } + -- No need to zonk the Id in any ExprHole because we never look at it + -- until after the final zonk and desugaring + {- Note [zonkCt behaviour] ~~~~~~~~~~~~~~~~~~~~~~~~~~ zonkCt tries to maintain the canonical form of a Ct. For example, - a CDictCan should stay a CDictCan; - - a CHoleCan should stay a CHoleCan - a CIrredCan should stay a CIrredCan with its cc_status flag intact Why?, for example: @@ -2026,8 +2035,6 @@ Why?, for example: don't preserve a canonical form, @expandSuperClasses@ fails to expand superclasses. This is what happened in #11525. -- For CHoleCan, once we forget that it's a hole, we can never recover that info. - - For CIrredCan we want to see if a constraint is insoluble with insolubleWC On the other hand, we change CTyEqCan to CNonCanonical, because of all of @@ -2046,10 +2053,6 @@ creates e.g. a CDictCan where the cc_tyars are /not/ function free. zonkCt :: Ct -> TcM Ct -- See Note [zonkCt behaviour] -zonkCt ct@(CHoleCan { cc_ev = ev }) - = do { ev' <- zonkCtEvidence ev - ; return $ ct { cc_ev = ev' } } - zonkCt ct@(CDictCan { cc_ev = ev, cc_tyargs = args }) = do { ev' <- zonkCtEvidence ev ; args' <- mapM zonkTcType args @@ -2262,17 +2265,15 @@ zonkTidyOrigin env orig = return (env, orig) tidyCt :: TidyEnv -> Ct -> Ct -- Used only in error reporting tidyCt env ct - = ct { cc_ev = tidy_ev env (ctEvidence ct) } + = ct { cc_ev = tidy_ev (ctEvidence ct) } where - tidy_ev :: TidyEnv -> CtEvidence -> CtEvidence + tidy_ev :: CtEvidence -> CtEvidence -- NB: we do not tidy the ctev_evar field because we don't -- show it in error messages - tidy_ev env ctev@(CtGiven { ctev_pred = pred }) - = ctev { ctev_pred = tidyType env pred } - tidy_ev env ctev@(CtWanted { ctev_pred = pred }) - = ctev { ctev_pred = tidyType env pred } - tidy_ev env ctev@(CtDerived { ctev_pred = pred }) - = ctev { ctev_pred = tidyType env pred } + tidy_ev ctev = ctev { ctev_pred = tidyType env (ctev_pred ctev) } + +tidyHole :: TidyEnv -> Hole -> Hole +tidyHole env h@(Hole { hole_ty = ty }) = h { hole_ty = tidyType env ty } ---------------- tidyEvVar :: TidyEnv -> EvVar -> EvVar View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d9aa8f2cb731b2efb957bf46a7174b19de74cd7f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d9aa8f2cb731b2efb957bf46a7174b19de74cd7f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 1 15:15:54 2020 From: gitlab at gitlab.haskell.org (Richard Eisenberg) Date: Fri, 01 May 2020 11:15:54 -0400 Subject: [Git][ghc/ghc][wip/hole-refactor] Refactor hole constraints. Message-ID: <5eac3d2a4a6c3_61673f819b417d1c8342382@gitlab.haskell.org.mail> Richard Eisenberg pushed to branch wip/hole-refactor at Glasgow Haskell Compiler / GHC Commits: 626f10b9 by Richard Eisenberg at 2020-05-01T16:15:32+01:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. - - - - - 18 changed files: - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Errors/Hole.hs-boot - compiler/GHC/Tc/Errors/Hole/FitTypes.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Rule.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/Solver/Canonical.hs - compiler/GHC/Tc/Solver/Flatten.hs - compiler/GHC/Tc/Solver/Interact.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Types/Constraint.hs - compiler/GHC/Tc/Types/Origin.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Tc/Utils/TcMType.hs Changes: ===================================== compiler/GHC/HsToCore/PmCheck/Oracle.hs ===================================== @@ -438,7 +438,7 @@ then newtypes. (b) dcs is the list of newtype constructors "skipped", every time we normalise a newtype to its core representation, we keep track of the source data - constructor. For convenienve, we also track the type we unwrap and the + constructor. For convenience, we also track the type we unwrap and the type of its field. Example: @Down 42@ => @[(Down @Int, Down, Int)] (c) core_ty is the rewritten type. That is, pmTopNormaliseType env ty_cs ty = Just (src_ty, dcs, core_ty) ===================================== compiler/GHC/Tc/Errors.hs ===================================== @@ -285,8 +285,8 @@ important :: SDoc -> Report important doc = mempty { report_important = [doc] } -- | Put a doc into the relevant bindings block. -relevant_bindings :: SDoc -> Report -relevant_bindings doc = mempty { report_relevant_bindings = [doc] } +mk_relevant_bindings :: SDoc -> Report +mk_relevant_bindings doc = mempty { report_relevant_bindings = [doc] } -- | Put a doc into the valid hole fits block. valid_hole_fits :: SDoc -> Report @@ -524,16 +524,28 @@ This only matters in instance declarations.. -} reportWanteds :: ReportErrCtxt -> TcLevel -> WantedConstraints -> TcM () -reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) +reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics + , wc_holes = holes }) = do { traceTc "reportWanteds" (vcat [ text "Simples =" <+> ppr simples , text "Suppress =" <+> ppr (cec_suppress ctxt)]) ; traceTc "rw2" (ppr tidy_cts) - -- First deal with things that are utterly wrong + -- First, deal with any out-of-scope errors: + ; let (out_of_scope, other_holes) = partition isOutOfScopeHole tidy_holes + -- don't suppress out-of-scope errors + ctxt_for_scope_errs = ctxt { cec_suppress = False } + ; (_, no_out_of_scope) <- askNoErrs $ + reportHoles tidy_cts ctxt_for_scope_errs out_of_scope + + -- Next, deal with things that are utterly wrong -- Like Int ~ Bool (incl nullary TyCons) -- or Int ~ t a (AppTy on one side) -- These /ones/ are not suppressed by the incoming context - ; let ctxt_for_insols = ctxt { cec_suppress = False } + -- (but will be by out-of-scope errors) + ; let ctxt_for_insols = ctxt { cec_suppress = not no_out_of_scope } + ; reportHoles tidy_cts ctxt_for_insols other_holes + -- holes never suppress + ; (ctxt1, cts1) <- tryReporters ctxt_for_insols report1 tidy_cts -- Now all the other constraints. We suppress errors here if @@ -554,7 +566,8 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) -- if there's a *given* insoluble here (= inaccessible code) where env = cec_tidy ctxt - tidy_cts = bagToList (mapBag (tidyCt env) simples) + tidy_cts = bagToList (mapBag (tidyCt env) simples) + tidy_holes = bagToList (mapBag (tidyHole env) holes) -- report1: ones that should *not* be suppressed by -- an insoluble somewhere else in the tree @@ -562,9 +575,7 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) -- (see GHC.Tc.Utils.insolubleCt) is caught here, otherwise -- we might suppress its error message, and proceed on past -- type checking to get a Lint error later - report1 = [ ("Out of scope", unblocked is_out_of_scope, True, mkHoleReporter tidy_cts) - , ("Holes", unblocked is_hole, False, mkHoleReporter tidy_cts) - , ("custom_error", unblocked is_user_type_error, True, mkUserTypeErrorReporter) + report1 = [ ("custom_error", unblocked is_user_type_error, True, mkUserTypeErrorReporter) , given_eq_spec , ("insoluble2", unblocked utterly_wrong, True, mkGroupReporter mkEqErr) @@ -593,8 +604,7 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) unblocked checker ct pred = checker ct pred -- rigid_nom_eq, rigid_nom_tv_eq, - is_hole, is_dict, - is_equality, is_ip, is_irred :: Ct -> Pred -> Bool + is_dict, is_equality, is_ip, is_irred :: Ct -> Pred -> Bool is_given_eq ct pred | EqPred {} <- pred = arisesFromGivens ct @@ -617,9 +627,6 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) non_tv_eq _ (EqPred NomEq ty1 _) = not (isTyVarTy ty1) non_tv_eq _ _ = False - is_out_of_scope ct _ = isOutOfScopeCt ct - is_hole ct _ = isHoleCt ct - is_user_type_error ct _ = isUserTypeErrorCt ct is_homo_equality _ (EqPred _ ty1 ty2) = tcTypeKind ty1 `tcEqType` tcTypeKind ty2 @@ -705,12 +712,12 @@ mkSkolReporter ctxt cts | eq_lhs_type ct1 ct2 = True | otherwise = False -mkHoleReporter :: [Ct] -> Reporter --- Reports errors one at a time -mkHoleReporter tidy_simples ctxt - = mapM_ $ \ct -> do { err <- mkHoleError tidy_simples ctxt ct - ; maybeReportHoleError ctxt ct err - ; maybeAddDeferredHoleBinding ctxt err ct } +reportHoles :: [Ct] -- other (tidied) constraints + -> ReportErrCtxt -> [Hole] -> TcM () +reportHoles tidy_cts ctxt + = mapM_ $ \hole -> do { err <- mkHoleError tidy_cts ctxt hole + ; maybeReportHoleError ctxt hole err + ; maybeAddDeferredHoleBinding ctxt err hole } mkUserTypeErrorReporter :: Reporter mkUserTypeErrorReporter ctxt @@ -742,7 +749,7 @@ mkGivenErrorReporter ctxt cts inaccessible_msg = hang (text "Inaccessible code in") 2 (ppr (ic_info implic)) report = important inaccessible_msg `mappend` - relevant_bindings binds_msg + mk_relevant_bindings binds_msg ; err <- mkEqErr_help dflags ctxt report ct' Nothing ty1 ty2 @@ -843,15 +850,27 @@ suppressGroup mk_err ctxt cts ; traceTc "Suppressing errors for" (ppr cts) ; mapM_ (addDeferredBinding ctxt err) cts } -maybeReportHoleError :: ReportErrCtxt -> Ct -> ErrMsg -> TcM () +maybeReportHoleError :: ReportErrCtxt -> Hole -> ErrMsg -> TcM () +maybeReportHoleError ctxt hole err + | isOutOfScopeHole hole + -- Always report an error for out-of-scope variables + -- Unless -fdefer-out-of-scope-variables is on, + -- in which case the messages are discarded. + -- See #12170, #12406 + = -- If deferring, report a warning only if -Wout-of-scope-variables is on + case cec_out_of_scope_holes ctxt of + HoleError -> reportError err + HoleWarn -> + reportWarning (Reason Opt_WarnDeferredOutOfScopeVariables) err + HoleDefer -> return () + -- Unlike maybeReportError, these "hole" errors are -- /not/ suppressed by cec_suppress. We want to see them! -maybeReportHoleError ctxt ct err +maybeReportHoleError ctxt (Hole { hole_sort = TypeHole }) err -- When -XPartialTypeSignatures is on, warnings (instead of errors) are -- generated for holes in partial type signatures. -- Unless -fwarn-partial-type-signatures is not on, -- in which case the messages are discarded. - | isTypeHoleCt ct = -- For partial type signatures, generate warnings only, and do that -- only if -fwarn-partial-type-signatures is on case cec_type_holes ctxt of @@ -859,22 +878,12 @@ maybeReportHoleError ctxt ct err HoleWarn -> reportWarning (Reason Opt_WarnPartialTypeSignatures) err HoleDefer -> return () - -- Always report an error for out-of-scope variables - -- Unless -fdefer-out-of-scope-variables is on, - -- in which case the messages are discarded. - -- See #12170, #12406 - | isOutOfScopeCt ct - = -- If deferring, report a warning only if -Wout-of-scope-variables is on - case cec_out_of_scope_holes ctxt of - HoleError -> reportError err - HoleWarn -> - reportWarning (Reason Opt_WarnDeferredOutOfScopeVariables) err - HoleDefer -> return () - +maybeReportHoleError ctxt hole@(Hole { hole_sort = ExprHole _ }) err -- Otherwise this is a typed hole in an expression, - -- but not for an out-of-scope variable - | otherwise + -- but not for an out-of-scope variable (because that goes through a + -- different function) = -- If deferring, report a warning only if -Wtyped-holes is on + ASSERT( not (isOutOfScopeHole hole) ) case cec_expr_holes ctxt of HoleError -> reportError err HoleWarn -> reportWarning (Reason Opt_WarnTypedHoles) err @@ -899,10 +908,7 @@ addDeferredBinding ctxt err ct , CtWanted { ctev_pred = pred, ctev_dest = dest } <- ctEvidence ct -- Only add deferred bindings for Wanted constraints = do { dflags <- getDynFlags - ; let err_msg = pprLocErrMsg err - err_fs = mkFastString $ showSDoc dflags $ - err_msg $$ text "(deferred type error)" - err_tm = evDelayedError pred err_fs + ; let err_tm = mkErrorTerm dflags pred err ev_binds_var = cec_binds ctxt ; case dest of @@ -917,11 +923,27 @@ addDeferredBinding ctxt err ct | otherwise -- Do not set any evidence for Given/Derived = return () -maybeAddDeferredHoleBinding :: ReportErrCtxt -> ErrMsg -> Ct -> TcM () -maybeAddDeferredHoleBinding ctxt err ct - | isExprHoleCt ct - = addDeferredBinding ctxt err ct -- Only add bindings for holes in expressions - | otherwise -- not for holes in partial type signatures +mkErrorTerm :: DynFlags -> Type -- of the error term + -> ErrMsg -> EvTerm +mkErrorTerm dflags ty err = evDelayedError ty err_fs + where + err_msg = pprLocErrMsg err + err_fs = mkFastString $ showSDoc dflags $ + err_msg $$ text "(deferred type error)" + +maybeAddDeferredHoleBinding :: ReportErrCtxt -> ErrMsg -> Hole -> TcM () +maybeAddDeferredHoleBinding ctxt err (Hole { hole_ty = hole_ty + , hole_sort = ExprHole ev_id }) +-- Only add bindings for holes in expressions +-- not for holes in partial type signatures +-- cf. addDeferredBinding + | deferringAnyBindings ctxt + = do { dflags <- getDynFlags + ; let err_tm = mkErrorTerm dflags hole_ty err + ; addTcEvBind (cec_binds ctxt) $ mkWantedEvBind ev_id err_tm } + | otherwise + = return () +maybeAddDeferredHoleBinding _ _ (Hole { hole_sort = TypeHole }) = return () tryReporters :: ReportErrCtxt -> [ReporterSpec] -> [Ct] -> TcM (ReportErrCtxt, [Ct]) @@ -961,7 +983,6 @@ tryReporter ctxt (str, keep_me, suppress_after, reporter) cts where (yeses, nos) = partition (\ct -> keep_me ct (classifyPredType (ctPred ct))) cts - pprArising :: CtOrigin -> SDoc -- Used for the main, top-level error message -- We've done special processing for TypeEq, KindEq, Given @@ -1104,15 +1125,16 @@ mkIrredErr ctxt cts ; let orig = ctOrigin ct1 msg = couldNotDeduce (getUserGivens ctxt) (map ctPred cts, orig) ; mkErrorMsgFromCt ctxt ct1 $ - important msg `mappend` relevant_bindings binds_msg } + important msg `mappend` mk_relevant_bindings binds_msg } where (ct1:_) = cts ---------------- -mkHoleError :: [Ct] -> ReportErrCtxt -> Ct -> TcM ErrMsg -mkHoleError tidy_simples ctxt ct@(CHoleCan { cc_occ = occ, cc_hole = hole_sort }) - | isOutOfScopeCt ct -- Out of scope variables, like 'a', where 'a' isn't bound - -- Suggest possible in-scope variables in the message +mkHoleError :: [Ct] -> ReportErrCtxt -> Hole -> TcM ErrMsg +mkHoleError _tidy_simples _ctxt hole@(Hole { hole_occ = occ + , hole_ty = hole_ty + , hole_loc = ct_loc }) + | isOutOfScopeHole hole = do { dflags <- getDynFlags ; rdr_env <- getGlobalRdrEnv ; imp_info <- getImports @@ -1122,48 +1144,52 @@ mkHoleError tidy_simples ctxt ct@(CHoleCan { cc_occ = occ, cc_hole = hole_sort } errDoc [out_of_scope_msg] [] [unknownNameSuggestions dflags hpt curr_mod rdr_env (tcl_rdr lcl_env) imp_info (mkRdrUnqual occ)] } + where + herald | isDataOcc occ = text "Data constructor not in scope:" + | otherwise = text "Variable not in scope:" - | otherwise -- Explicit holes, like "_" or "_f" - = do { (ctxt, binds_msg, ct) <- relevantBindings False ctxt ct + out_of_scope_msg -- Print v :: ty only if the type has structure + | boring_type = hang herald 2 (ppr occ) + | otherwise = hang herald 2 (pp_occ_with_type occ hole_ty) + + lcl_env = ctLocEnv ct_loc + boring_type = isTyVarTy hole_ty + + -- general case: not an out-of-scope error +mkHoleError tidy_simples ctxt hole@(Hole { hole_occ = occ + , hole_ty = hole_ty + , hole_sort = sort + , hole_loc = ct_loc }) + = do { (ctxt, binds_msg) + <- relevant_bindings False ctxt lcl_env (tyCoVarsOfType hole_ty) -- The 'False' means "don't filter the bindings"; see Trac #8191 ; show_hole_constraints <- goptM Opt_ShowHoleConstraints ; let constraints_msg - | isExprHoleCt ct, show_hole_constraints + | ExprHole _ <- sort, show_hole_constraints = givenConstraintsMsg ctxt | otherwise = empty ; show_valid_hole_fits <- goptM Opt_ShowValidHoleFits ; (ctxt, sub_msg) <- if show_valid_hole_fits - then validHoleFits ctxt tidy_simples ct + then validHoleFits ctxt tidy_simples hole else return (ctxt, empty) - ; mkErrorMsgFromCt ctxt ct $ + ; mkErrorReport ctxt lcl_env $ important hole_msg `mappend` - relevant_bindings (binds_msg $$ constraints_msg) `mappend` + mk_relevant_bindings (binds_msg $$ constraints_msg) `mappend` valid_hole_fits sub_msg } where - ct_loc = ctLoc ct lcl_env = ctLocEnv ct_loc - hole_ty = ctEvPred (ctEvidence ct) hole_kind = tcTypeKind hole_ty tyvars = tyCoVarsOfTypeList hole_ty - boring_type = isTyVarTy hole_ty - - out_of_scope_msg -- Print v :: ty only if the type has structure - | boring_type = hang herald 2 (ppr occ) - | otherwise = hang herald 2 pp_with_type - pp_with_type = hang (pprPrefixOcc occ) 2 (dcolon <+> pprType hole_ty) - herald | isDataOcc occ = text "Data constructor not in scope:" - | otherwise = text "Variable not in scope:" - - hole_msg = case hole_sort of - ExprHole -> vcat [ hang (text "Found hole:") - 2 pp_with_type - , tyvars_msg, expr_hole_hint ] + hole_msg = case sort of + ExprHole _ -> vcat [ hang (text "Found hole:") + 2 (pp_occ_with_type occ hole_ty) + , tyvars_msg, expr_hole_hint ] TypeHole -> vcat [ hang (text "Found type wildcard" <+> quotes (ppr occ)) 2 (text "standing for" <+> quotes pp_hole_type_with_kind) , tyvars_msg, type_hole_hint ] @@ -1207,21 +1233,22 @@ mkHoleError tidy_simples ctxt ct@(CHoleCan { cc_occ = occ, cc_hole = hole_sort } = ppWhenOption sdocPrintExplicitCoercions $ quotes (ppr tv) <+> text "is a coercion variable" -mkHoleError _ _ ct = pprPanic "mkHoleError" (ppr ct) +pp_occ_with_type :: OccName -> Type -> SDoc +pp_occ_with_type occ hole_ty = hang (pprPrefixOcc occ) 2 (dcolon <+> pprType hole_ty) -- We unwrap the ReportErrCtxt here, to avoid introducing a loop in module -- imports validHoleFits :: ReportErrCtxt -- The context we're in, i.e. the -- implications and the tidy environment -> [Ct] -- Unsolved simple constraints - -> Ct -- The hole constraint. + -> Hole -- The hole -> TcM (ReportErrCtxt, SDoc) -- We return the new context -- with a possibly updated -- tidy environment, and -- the message. validHoleFits ctxt@(CEC {cec_encl = implics - , cec_tidy = lcl_env}) simps ct - = do { (tidy_env, msg) <- findValidHoleFits lcl_env implics simps ct + , cec_tidy = lcl_env}) simps hole + = do { (tidy_env, msg) <- findValidHoleFits lcl_env implics simps hole ; return (ctxt {cec_tidy = tidy_env}, msg) } -- See Note [Constraints include ...] @@ -1255,7 +1282,7 @@ mkIPErr ctxt cts = couldNotDeduce givens (preds, orig) ; mkErrorMsgFromCt ctxt ct1 $ - important msg `mappend` relevant_bindings binds_msg } + important msg `mappend` mk_relevant_bindings binds_msg } where (ct1:_) = cts @@ -1337,7 +1364,7 @@ mkEqErr1 ctxt ct -- Wanted or derived; ; dflags <- getDynFlags ; traceTc "mkEqErr1" (ppr ct $$ pprCtOrigin (ctOrigin ct) $$ ppr keep_going) ; let report = mconcat [important wanted_msg, important coercible_msg, - relevant_bindings binds_msg] + mk_relevant_bindings binds_msg] ; if keep_going then mkEqErr_help dflags ctxt report ct is_oriented ty1 ty2 else mkErrorMsgFromCt ctxt ct report } @@ -1513,7 +1540,7 @@ mkTyVarEqErr' dflags ctxt report ct oriented tv1 ty2 filter isTyVar $ fvVarList $ tyCoFVsOfType ty1 `unionFV` tyCoFVsOfType ty2 - extra3 = relevant_bindings $ + extra3 = mk_relevant_bindings $ ppWhen (not (null interesting_tyvars)) $ hang (text "Type variable kinds:") 2 $ vcat (map (tyvar_binding . tidyTyCoVarOcc (cec_tidy ctxt)) @@ -2819,27 +2846,45 @@ relevantBindings :: Bool -- True <=> filter by tyvar; False <=> no filtering -> TcM (ReportErrCtxt, SDoc, Ct) -- Also returns the zonked and tidied CtOrigin of the constraint relevantBindings want_filtering ctxt ct - = do { dflags <- getDynFlags + = do { traceTc "relevantBindings" (ppr ct) ; (env1, tidy_orig) <- zonkTidyOrigin (cec_tidy ctxt) (ctLocOrigin loc) - ; let ct_tvs = tyCoVarsOfCt ct `unionVarSet` extra_tvs -- For *kind* errors, report the relevant bindings of the -- enclosing *type* equality, because that's more useful for the programmer - extra_tvs = case tidy_orig of + ; let extra_tvs = case tidy_orig of KindEqOrigin t1 m_t2 _ _ -> tyCoVarsOfTypes $ t1 : maybeToList m_t2 _ -> emptyVarSet - ; traceTc "relevantBindings" $ - vcat [ ppr ct - , pprCtOrigin (ctLocOrigin loc) - , ppr ct_tvs + ct_fvs = tyCoVarsOfCt ct `unionVarSet` extra_tvs + + -- Put a zonked, tidied CtOrigin into the Ct + loc' = setCtLocOrigin loc tidy_orig + ct' = setCtLoc ct loc' + ctxt1 = ctxt { cec_tidy = env1 } + + ; (ctxt2, doc) <- relevant_bindings want_filtering ctxt1 lcl_env ct_fvs + ; return (ctxt2, doc, ct') } + where + loc = ctLoc ct + lcl_env = ctLocEnv loc + +-- slightly more general version, to work also with holes +relevant_bindings :: Bool + -> ReportErrCtxt + -> TcLclEnv + -> TyCoVarSet + -> TcM (ReportErrCtxt, SDoc) +relevant_bindings want_filtering ctxt lcl_env ct_tvs + = do { dflags <- getDynFlags + ; traceTc "relevant_bindings" $ + vcat [ ppr ct_tvs , pprWithCommas id [ ppr id <+> dcolon <+> ppr (idType id) | TcIdBndr id _ <- tcl_bndrs lcl_env ] , pprWithCommas id [ ppr id | TcIdBndr_ExpType id _ _ <- tcl_bndrs lcl_env ] ] ; (tidy_env', docs, discards) - <- go dflags env1 ct_tvs (maxRelevantBinds dflags) + <- go dflags (cec_tidy ctxt) (maxRelevantBinds dflags) emptyVarSet [] False (removeBindingShadowing $ tcl_bndrs lcl_env) -- tcl_bndrs has the innermost bindings first, @@ -2849,17 +2894,10 @@ relevantBindings want_filtering ctxt ct hang (text "Relevant bindings include") 2 (vcat docs $$ ppWhen discards discardMsg) - -- Put a zonked, tidied CtOrigin into the Ct - loc' = setCtLocOrigin loc tidy_orig - ct' = setCtLoc ct loc' ctxt' = ctxt { cec_tidy = tidy_env' } - ; return (ctxt', doc, ct') } + ; return (ctxt', doc) } where - ev = ctEvidence ct - loc = ctEvLoc ev - lcl_env = ctLocEnv loc - run_out :: Maybe Int -> Bool run_out Nothing = False run_out (Just n) = n <= 0 @@ -2868,14 +2906,14 @@ relevantBindings want_filtering ctxt ct dec_max = fmap (\n -> n - 1) - go :: DynFlags -> TidyEnv -> TcTyVarSet -> Maybe Int -> TcTyVarSet -> [SDoc] + go :: DynFlags -> TidyEnv -> Maybe Int -> TcTyVarSet -> [SDoc] -> Bool -- True <=> some filtered out due to lack of fuel -> [TcBinder] -> TcM (TidyEnv, [SDoc], Bool) -- The bool says if we filtered any out -- because of lack of fuel - go _ tidy_env _ _ _ docs discards [] + go _ tidy_env _ _ docs discards [] = return (tidy_env, reverse docs, discards) - go dflags tidy_env ct_tvs n_left tvs_seen docs discards (tc_bndr : tc_bndrs) + go dflags tidy_env n_left tvs_seen docs discards (tc_bndr : tc_bndrs) = case tc_bndr of TcTvBndr {} -> discard_it TcIdBndr id top_lvl -> go2 (idName id) (idType id) top_lvl @@ -2891,7 +2929,7 @@ relevantBindings want_filtering ctxt ct Nothing -> discard_it -- No info; discard } where - discard_it = go dflags tidy_env ct_tvs n_left tvs_seen docs + discard_it = go dflags tidy_env n_left tvs_seen docs discards tc_bndrs go2 id_name id_type top_lvl = do { (tidy_env', tidy_ty) <- zonkTidyTcType tidy_env id_type @@ -2916,12 +2954,12 @@ relevantBindings want_filtering ctxt ct else if run_out n_left && id_tvs `subVarSet` tvs_seen -- We've run out of n_left fuel and this binding only -- mentions already-seen type variables, so discard it - then go dflags tidy_env ct_tvs n_left tvs_seen docs + then go dflags tidy_env n_left tvs_seen docs True -- Record that we have now discarded something tc_bndrs -- Keep this binding, decrement fuel - else go dflags tidy_env' ct_tvs (dec_max n_left) new_seen + else go dflags tidy_env' (dec_max n_left) new_seen (doc:docs) discards tc_bndrs } ===================================== compiler/GHC/Tc/Errors/Hole.hs ===================================== @@ -2,17 +2,9 @@ {-# LANGUAGE ExistentialQuantification #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} module GHC.Tc.Errors.Hole - ( findValidHoleFits, tcFilterHoleFits - , tcCheckHoleFit, tcSubsumes - , withoutUnification - , fromPureHFPlugin - -- Re-exports for convenience - , hfIsLcl - , pprHoleFit, debugHoleFitDispConfig + ( findValidHoleFits -- Re-exported from GHC.Tc.Errors.Hole.FitTypes - , TypedHole (..), HoleFit (..), HoleFitCandidate (..) - , CandPlugin, FitPlugin , HoleFitPlugin (..), HoleFitPluginR (..) ) where @@ -121,7 +113,7 @@ The hole in `f` would generate the message: Valid hole fits are found by checking top level identifiers and local bindings in scope for whether their type can be instantiated to the the type of the hole. Additionally, we also need to check whether all relevant constraints are solved -by choosing an identifier of that type as well, see Note [Relevant Constraints] +by choosing an identifier of that type as well, see Note [Relevant constraints] Since checking for subsumption results in the side-effect of type variables being unified by the simplifier, we need to take care to restore them after @@ -143,9 +135,13 @@ that the quantified type variables would take if that fit is used, like If -XTypeApplications is enabled, this can even be copied verbatim as a replacement for the hole. - -Note [Nested implications] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Checking hole fits] +~~~~~~~~~~~~~~~~~~~~~~~~~ +If we have a hole of type hole_ty, we want to know whether a variable +of type ty is a valid fit for the whole. This is a subsumption check: +we wish to know whether ty <: hole_ty. But, of course, the check +must take into account any givens and relevant constraints. +(See also Note [Relevant constraints]). For the simplifier to be able to use any givens present in the enclosing implications to solve relevant constraints, we nest the wanted subsumption @@ -156,10 +152,7 @@ As an example, let's look at the following code: f :: Show a => a -> String f x = show _ -The hole will result in the hole constraint: - - [WD] __a1ph {0}:: a0_a1pd[tau:2] (CHoleCan: ExprHole(_)) - +Suppose the hole is assigned type a0_a1pd[tau:2]. Here the nested implications are just one level deep, namely: [Implic { @@ -170,36 +163,25 @@ Here the nested implications are just one level deep, namely: Given = $dShow_a1pc :: Show a_a1pa[sk:2] Wanted = WC {wc_simple = - [WD] __a1ph {0}:: a_a1pd[tau:2] (CHoleCan: ExprHole(_)) - [WD] $dShow_a1pe {0}:: Show a_a1pd[tau:2] (CDictCan(psc))} + [WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CDictCan(psc))} Binds = EvBindsVar Needed inner = [] Needed outer = [] the type signature for: f :: forall a. Show a => a -> String }] -As we can see, the givens say that the information about the skolem -`a_a1pa[sk:2]` fulfills the Show constraint. - -The simples are: +As we can see, the givens say that the skolem +`a_a1pa[sk:2]` fulfills the Show constraint, and that we must prove +the [W] Show a0_a1pd[tau:2] constraint -- that is, whatever fills the +hole must have a Show instance. - [[WD] __a1ph {0}:: a0_a1pd[tau:2] (CHoleCan: ExprHole(_)), - [WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CNonCanonical)] - -I.e. the hole `a0_a1pd[tau:2]` and the constraint that the type of the hole must -fulfill `Show a0_a1pd[tau:2])`. - -So when we run the check, we need to make sure that the - - [WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CNonCanonical) - -Constraint gets solved. When we now check for whether `x :: a0_a1pd[tau:2]` fits -the hole in `tcCheckHoleFit`, the call to `tcSubType` will end up writing the -meta type variable `a0_a1pd[tau:2] := a_a1pa[sk:2]`. By wrapping the wanted -constraints needed by tcSubType_NC and the relevant constraints (see -Note [Relevant Constraints] for more details) in the nested implications, we -can pass the information in the givens along to the simplifier. For our example, -we end up needing to check whether the following constraints are soluble. +When we now check whether `x :: a_a1pa[sk:2]` fits the hole in +`tcCheckHoleFit`, the call to `tcSubType` will end up unifying the meta type +variable `a0_a1pd[tau:2] := a_a1pa[sk:2]`. By wrapping the wanted constraints +needed by tcSubType_NC and the relevant constraints (see Note [Relevant +Constraints] for more details) in the nested implications, we can pass the +information in the givens along to the simplifier. For our example, we end up +needing to check whether the following constraints are soluble. WC {wc_impl = Implic { @@ -223,10 +205,12 @@ with a final WC of WC {}, confirming x :: a0_a1pd[tau:2] as a match. To avoid side-effects on the nested implications, we create a new EvBindsVar so that any changes to the ev binds during a check remains localised to that check. - +In addition, we call withoutUnification to reset any unified metavariables; this +call is actually done outside tcCheckHoleFit so that the results can be formatted +for the user before resetting variables. Note [Valid refinement hole fits include ...] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When the `-frefinement-level-hole-fits=N` flag is given, we additionally look for "valid refinement hole fits"", i.e. valid hole fits with up to N additional holes in them. @@ -337,10 +321,8 @@ In the free monad example above, this is demonstrated with be applied to an expression of type `a -> Free f b` in order to match. If -XScopedTypeVariables is enabled, this hole fit can even be copied verbatim. - -Note [Relevant Constraints] -~~~~~~~~~~~~~~~~~~~ - +Note [Relevant constraints] +~~~~~~~~~~~~~~~~~~~~~~~~~~~ As highlighted by #14273, we need to check any relevant constraints as well as checking for subsumption. Relevant constraints are the simple constraints whose free unification variables are mentioned in the type of the hole. @@ -351,10 +333,9 @@ as is the case in f :: String f = show _ -Where the simples will be : +Here, the hole is given type a0_a1kv[tau:1]. Then, the emitted constraint is: - [[WD] __a1kz {0}:: a0_a1kv[tau:1] (CHoleCan: ExprHole(_)), - [WD] $dShow_a1kw {0}:: Show a0_a1kv[tau:1] (CNonCanonical)] + [WD] $dShow_a1kw {0}:: Show a0_a1kv[tau:1] (CNonCanonical) However, when there are multiple holes, we need to be more careful. As an example, Let's take a look at the following code: @@ -362,29 +343,24 @@ example, Let's take a look at the following code: f :: Show a => a -> String f x = show (_b (show _a)) -Here there are two holes, `_a` and `_b`, and the simple constraints passed to +Here there are two holes, `_a` and `_b`. Suppose _a :: a0_a1pd[tau:2] and +_b :: a1_a1po[tau:2]. Then, the simple constraints passed to findValidHoleFits are: - [[WD] _a_a1pi {0}:: String - -> a0_a1pd[tau:2] (CHoleCan: ExprHole(_b)), - [WD] _b_a1ps {0}:: a1_a1po[tau:2] (CHoleCan: ExprHole(_a)), - [WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CNonCanonical), + [[WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CNonCanonical), [WD] $dShow_a1pp {0}:: Show a1_a1po[tau:2] (CNonCanonical)] - -Here we have the two hole constraints for `_a` and `_b`, but also additional -constraints that these holes must fulfill. When we are looking for a match for -the hole `_a`, we filter the simple constraints to the "Relevant constraints", -by throwing out all hole constraints and any constraints which do not mention -a variable mentioned in the type of the hole. For hole `_a`, we will then -only require that the `$dShow_a1pp` constraint is solved, since that is -the only non-hole constraint that mentions any free type variables mentioned in -the hole constraint for `_a`, namely `a_a1pd[tau:2]` , and similarly for the -hole `_b` we only require that the `$dShow_a1pe` constraint is solved. +When we are looking for a match for the hole `_a`, we filter the simple +constraints to the "Relevant constraints", by throwing out any constraints +which do not mention a variable mentioned in the type of the hole. For hole +`_a`, we will then only require that the `$dShow_a1pe` constraint is solved, +since that is the only constraint that mentions any free type variables +mentioned in the hole constraint for `_a`, namely `a_a1pd[tau:2]`, and +similarly for the hole `_b` we only require that the `$dShow_a1pe` constraint +is solved. Note [Leaking errors] -~~~~~~~~~~~~~~~~~~~ - +~~~~~~~~~~~~~~~~~~~~~ When considering candidates, GHC believes that we're checking for validity in actual source. However, As evidenced by #15321, #15007 and #15202, this can cause bewildering error messages. The solution here is simple: if a candidate @@ -393,17 +369,12 @@ is discarded. -} - data HoleFitDispConfig = HFDC { showWrap :: Bool , showWrapVars :: Bool , showType :: Bool , showProv :: Bool , showMatches :: Bool } -debugHoleFitDispConfig :: HoleFitDispConfig -debugHoleFitDispConfig = HFDC True True True False False - - -- We read the various -no-show-*-of-hole-fits flags -- and set the display config accordingly. getHoleFitDispConfig :: TcM HoleFitDispConfig @@ -516,13 +487,12 @@ pprHoleFit (HFDC sWrp sWrpVars sTy sProv sMs) (HoleFit {..}) = GreHFCand gre -> pprNameProvenance gre _ -> text "bound at" <+> ppr (getSrcLoc name) -getLocalBindings :: TidyEnv -> Ct -> TcM [Id] -getLocalBindings tidy_orig ct - = do { (env1, _) <- zonkTidyOrigin tidy_orig (ctLocOrigin loc) +getLocalBindings :: TidyEnv -> CtLoc -> TcM [Id] +getLocalBindings tidy_orig ct_loc + = do { (env1, _) <- zonkTidyOrigin tidy_orig (ctLocOrigin ct_loc) ; go env1 [] (removeBindingShadowing $ tcl_bndrs lcl_env) } where - loc = ctEvLoc (ctEvidence ct) - lcl_env = ctLocEnv loc + lcl_env = ctLocEnv ct_loc go :: TidyEnv -> [Id] -> [TcBinder] -> TcM [Id] go _ sofar [] = return (reverse sofar) @@ -542,11 +512,13 @@ findValidHoleFits :: TidyEnv -- ^ The tidy_env for zonking -> [Ct] -- ^ The unsolved simple constraints in the implication for -- the hole. - -> Ct -- ^ The hole constraint itself + -> Hole -> TcM (TidyEnv, SDoc) -findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = +findValidHoleFits tidy_env implics simples h@(Hole { hole_sort = ExprHole _ + , hole_loc = ct_loc + , hole_ty = hole_ty }) = do { rdr_env <- getGlobalRdrEnv - ; lclBinds <- getLocalBindings tidy_env ct + ; lclBinds <- getLocalBindings tidy_env ct_loc ; maxVSubs <- maxValidHoleFits <$> getDynFlags ; hfdc <- getHoleFitDispConfig ; sortingAlg <- getSortingAlg @@ -554,7 +526,9 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = ; hfPlugs <- tcg_hf_plugins <$> getGblEnv ; let findVLimit = if sortingAlg > NoSorting then Nothing else maxVSubs refLevel = refLevelHoleFits dflags - hole = TyH (listToBag relevantCts) implics (Just ct) + hole = TypedHole { th_relevant_cts = listToBag relevantCts + , th_implics = implics + , th_hole = Just h } (candidatePlugins, fitPlugins) = unzip $ map (\p-> ((candPlugin p) hole, (fitPlugin p) hole)) hfPlugs ; traceTc "findingValidHoleFitsFor { " $ ppr hole @@ -625,11 +599,9 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = where -- We extract the type, the tcLevel and the types free variables -- from from the constraint. - hole_ty :: TcPredType - hole_ty = ctPred ct hole_fvs :: FV hole_fvs = tyCoFVsOfType hole_ty - hole_lvl = ctLocLevel $ ctEvLoc $ ctEvidence ct + hole_lvl = ctLocLevel ct_loc -- BuiltInSyntax names like (:) and [] builtIns :: [Name] @@ -668,7 +640,7 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = <*> sortByGraph (sort gblFits) where (lclFits, gblFits) = span hfIsLcl subs - -- See Note [Relevant Constraints] + -- See Note [Relevant constraints] relevantCts :: [Ct] relevantCts = if isEmptyVarSet (fvVarSet hole_fvs) then [] else filter isRelevant simples @@ -684,7 +656,6 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = -- trying to find hole fits for many holes at once. isRelevant ct = not (isEmptyVarSet (ctFreeVarSet ct)) && anyFVMentioned ct - && not (isHoleCt ct) -- We zonk the hole fits so that the output aligns with the rest -- of the typed hole error message output. @@ -761,7 +732,7 @@ tcFilterHoleFits :: Maybe Int -- ^ We return whether or not we stopped due to hitting the limit -- and the fits we found. tcFilterHoleFits (Just 0) _ _ _ = return (False, []) -- Stop right away on 0 -tcFilterHoleFits limit (TyH {..}) ht@(hole_ty, _) candidates = +tcFilterHoleFits limit typed_hole ht@(hole_ty, _) candidates = do { traceTc "checkingFitsFor {" $ ppr hole_ty ; (discards, subs) <- go [] emptyVarSet limit ht candidates ; traceTc "checkingFitsFor }" empty @@ -895,8 +866,7 @@ tcFilterHoleFits limit (TyH {..}) ht@(hole_ty, _) candidates = else return Nothing } else return Nothing } where fvs = mkFVs ref_vars `unionFV` hole_fvs `unionFV` tyCoFVsOfType ty - hole = TyH tyHRelevantCts tyHImplics Nothing - + hole = typed_hole { th_hole = Nothing } subsDiscardMsg :: SDoc subsDiscardMsg = @@ -925,7 +895,8 @@ withoutUnification free_vars action = -- Reset any mutated free variables ; mapM_ restore flexis ; return result } - where restore = flip writeTcRef Flexi . metaTyVarRef + where restore tv = do { traceTc "withoutUnification: restore flexi" (ppr tv) + ; writeTcRef (metaTyVarRef tv) Flexi } fuvs = fvVarList free_vars -- | Reports whether first type (ty_a) subsumes the second type (ty_b), @@ -933,14 +904,14 @@ withoutUnification free_vars action = -- ty_a, i.e. `tcSubsumes a b == True` if b is a subtype of a. tcSubsumes :: TcSigmaType -> TcSigmaType -> TcM Bool tcSubsumes ty_a ty_b = fst <$> tcCheckHoleFit dummyHole ty_a ty_b - where dummyHole = TyH emptyBag [] Nothing + where dummyHole = TypedHole { th_relevant_cts = emptyBag + , th_implics = [] + , th_hole = Nothing } -- | A tcSubsumes which takes into account relevant constraints, to fix trac -- #14273. This makes sure that when checking whether a type fits the hole, -- the type has to be subsumed by type of the hole as well as fulfill all -- constraints on the type of the hole. --- Note: The simplifier may perform unification, so make sure to restore any --- free type variables to avoid side-effects. tcCheckHoleFit :: TypedHole -- ^ The hole to check against -> TcSigmaType -- ^ The type to check against (possibly modified, e.g. refined) @@ -949,56 +920,48 @@ tcCheckHoleFit :: TypedHole -- ^ The hole to check against -- ^ Whether it was a match, and the wrapper from hole_ty to ty. tcCheckHoleFit _ hole_ty ty | hole_ty `eqType` ty = return (True, idHsWrapper) -tcCheckHoleFit (TyH {..}) hole_ty ty = discardErrs $ +tcCheckHoleFit (TypedHole {..}) hole_ty ty = discardErrs $ do { -- We wrap the subtype constraint in the implications to pass along the -- givens, and so we must ensure that any nested implications and skolems -- end up with the correct level. The implications are ordered so that -- the innermost (the one with the highest level) is first, so it -- suffices to get the level of the first one (or the current level, if -- there are no implications involved). - innermost_lvl <- case tyHImplics of + innermost_lvl <- case th_implics of [] -> getTcLevel -- imp is the innermost implication (imp:_) -> return (ic_tclvl imp) - ; (wrp, wanted) <- setTcLevel innermost_lvl $ captureConstraints $ - tcSubType_NC ExprSigCtxt ty hole_ty + ; (wrap, wanted) <- setTcLevel innermost_lvl $ captureConstraints $ + tcSubType_NC ExprSigCtxt ty hole_ty ; traceTc "Checking hole fit {" empty ; traceTc "wanteds are: " $ ppr wanted - ; if isEmptyWC wanted && isEmptyBag tyHRelevantCts - then traceTc "}" empty >> return (True, wrp) + ; if isEmptyWC wanted && isEmptyBag th_relevant_cts + then do { traceTc "}" empty + ; return (True, wrap) } else do { fresh_binds <- newTcEvBinds -- The relevant constraints may contain HoleDests, so we must -- take care to clone them as well (to avoid #15370). - ; cloned_relevants <- mapBagM cloneWanted tyHRelevantCts + ; cloned_relevants <- mapBagM cloneWanted th_relevant_cts -- We wrap the WC in the nested implications, see - -- Note [Nested Implications] - ; let outermost_first = reverse tyHImplics - setWC = setWCAndBinds fresh_binds + -- Note [Checking hole fits] + ; let outermost_first = reverse th_implics -- We add the cloned relevants to the wanteds generated by - -- the call to tcSubType_NC, see Note [Relevant Constraints] + -- the call to tcSubType_NC, see Note [Relevant constraints] -- There's no need to clone the wanteds, because they are -- freshly generated by `tcSubtype_NC`. w_rel_cts = addSimples wanted cloned_relevants - w_givens = foldr setWC w_rel_cts outermost_first - ; traceTc "w_givens are: " $ ppr w_givens - ; rem <- runTcSDeriveds $ simpl_top w_givens + final_wc = foldr (setWCAndBinds fresh_binds) w_rel_cts outermost_first + ; traceTc "final_wc is: " $ ppr final_wc + ; rem <- runTcSDeriveds $ simpl_top final_wc -- We don't want any insoluble or simple constraints left, but -- solved implications are ok (and necessary for e.g. undefined) ; traceTc "rems was:" $ ppr rem ; traceTc "}" empty - ; return (isSolvedWC rem, wrp) } } + ; return (isSolvedWC rem, wrap) } } where setWCAndBinds :: EvBindsVar -- Fresh ev binds var. -> Implication -- The implication to put WC in. -> WantedConstraints -- The WC constraints to put implic. -> WantedConstraints -- The new constraints. setWCAndBinds binds imp wc - = WC { wc_simple = emptyBag - , wc_impl = unitBag $ imp { ic_wanted = wc , ic_binds = binds } } - --- | Maps a plugin that needs no state to one with an empty one. -fromPureHFPlugin :: HoleFitPlugin -> HoleFitPluginR -fromPureHFPlugin plug = - HoleFitPluginR { hfPluginInit = newTcRef () - , hfPluginRun = const plug - , hfPluginStop = const $ return () } + = mkImplicWC $ unitBag $ imp { ic_wanted = wc , ic_binds = binds } ===================================== compiler/GHC/Tc/Errors/Hole.hs-boot ===================================== @@ -5,9 +5,9 @@ module GHC.Tc.Errors.Hole where import GHC.Tc.Types ( TcM ) -import GHC.Tc.Types.Constraint ( Ct, Implication ) +import GHC.Tc.Types.Constraint ( Ct, Hole, Implication ) import GHC.Utils.Outputable ( SDoc ) import GHC.Types.Var.Env ( TidyEnv ) -findValidHoleFits :: TidyEnv -> [Implication] -> [Ct] -> Ct +findValidHoleFits :: TidyEnv -> [Implication] -> [Ct] -> Hole -> TcM (TidyEnv, SDoc) ===================================== compiler/GHC/Tc/Errors/Hole/FitTypes.hs ===================================== @@ -21,20 +21,21 @@ import GHC.Types.Name import Data.Function ( on ) -data TypedHole = TyH { tyHRelevantCts :: Cts - -- ^ Any relevant Cts to the hole - , tyHImplics :: [Implication] - -- ^ The nested implications of the hole with the - -- innermost implication first. - , tyHCt :: Maybe Ct - -- ^ The hole constraint itself, if available. - } +data TypedHole = TypedHole { th_relevant_cts :: Cts + -- ^ Any relevant Cts to the hole + , th_implics :: [Implication] + -- ^ The nested implications of the hole with the + -- innermost implication first. + , th_hole :: Maybe Hole + -- ^ The hole itself, if available. Only for debugging. + } instance Outputable TypedHole where - ppr (TyH rels implics ct) + ppr (TypedHole { th_relevant_cts = rels + , th_implics = implics + , th_hole = hole }) = hang (text "TypedHole") 2 - (ppr rels $+$ ppr implics $+$ ppr ct) - + (ppr rels $+$ ppr implics $+$ ppr hole) -- | HoleFitCandidates are passed to hole fit plugins and then -- checked whether they fit a given typed-hole. @@ -51,9 +52,6 @@ pprHoleFitCand (IdHFCand cid) = text "Id HFC: " <> ppr cid pprHoleFitCand (NameHFCand cname) = text "Name HFC: " <> ppr cname pprHoleFitCand (GreHFCand cgre) = text "Gre HFC: " <> ppr cgre - - - instance NamedThing HoleFitCandidate where getName hfc = case hfc of IdHFCand cid -> idName cid ===================================== compiler/GHC/Tc/Gen/Expr.hs ===================================== @@ -36,7 +36,6 @@ import {-# SOURCE #-} GHC.Tc.Gen.Splice( tcSpliceExpr, tcTypedBracket, tcUntyp import GHC.Builtin.Names.TH( liftStringName, liftName ) import GHC.Hs -import GHC.Tc.Types.Constraint ( HoleSort(..) ) import GHC.Tc.Utils.Zonk import GHC.Tc.Utils.Monad import GHC.Tc.Utils.Unify @@ -1408,22 +1407,21 @@ Suppose 'wurble' is not in scope, and we have Then the renamer will make (HsUnboundVar "wurble) for 'wurble', and the typechecker will typecheck it with tcUnboundId, giving it -a type 'alpha', and emitting a deferred CHoleCan constraint, to -be reported later. +a type 'alpha', and emitting a deferred Hole, to be reported later. But then comes the visible type application. If we do nothing, we'll generate an immediate failure (in tc_app_err), saying that a function of type 'alpha' can't be applied to Bool. That's insane! And indeed users complain bitterly (#13834, #17150.) -The right error is the CHoleCan, which has /already/ been emitted by +The right error is the Hole, which has /already/ been emitted by tcUnboundId. It later reports 'wurble' as out of scope, and tries to give its type. Fortunately in tcArgs we still have access to the function, so we can check if it is a HsUnboundVar. We use this info to simply skip over any visible type arguments. We've already inferred the type of the -function, so we'll /already/ have emitted a CHoleCan constraint; +function, so we'll /already/ have emitted a Hole; failing preserves that constraint. We do /not/ want to fail altogether in this case (via failM) becuase @@ -1900,14 +1898,13 @@ tcUnboundId :: HsExpr GhcRn -> OccName -> ExpRhoType -> TcM (HsExpr GhcTc) -- Others might simply be variables that accidentally have no binding site -- -- We turn all of them into HsVar, since HsUnboundVar can't contain an --- Id; and indeed the evidence for the CHoleCan does bind it, so it's +-- Id; and indeed the evidence for the ExprHole does bind it, so it's -- not unbound any more! tcUnboundId rn_expr occ res_ty = do { ty <- newOpenFlexiTyVarTy -- Allow Int# etc (#12531) ; name <- newSysName occ ; let ev = mkLocalId name ty - ; can <- newHoleCt ExprHole ev ty - ; emitInsoluble can + ; emitNewExprHole occ ev ty ; tcWrapResultO (UnboundOccurrenceOf occ) rn_expr (HsVar noExtField (noLoc ev)) ty res_ty } ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -419,7 +419,7 @@ tcHsTypeApp wc_ty kind ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A HsWildCardBndrs's hswc_ext now only includes /named/ wildcards, so any unnamed wildcards stay unchanged in hswc_body. When called in -tcHsTypeApp, tcCheckLHsType will call emitAnonWildCardHoleConstraint +tcHsTypeApp, tcCheckLHsType will call emitAnonTypeHole on these anonymous wildcards. However, this would trigger error/warning when an anonymous wildcard is passed in as a visible type argument, which we do not want because users should be able to write @@ -891,7 +891,7 @@ tcAnonWildCardOcc wc exp_kind ; warning <- woptM Opt_WarnPartialTypeSignatures ; unless (part_tysig && not warning) $ - emitAnonWildCardHoleConstraint wc_tv + emitAnonTypeHole wc_tv -- Why the 'unless' guard? -- See Note [Wildcards in visible kind application] @@ -911,11 +911,11 @@ x = MkT So we should allow '@_' without emitting any hole constraints, and regardless of whether PartialTypeSignatures is enabled or not. But how would the typechecker know which '_' is being used in VKA and which is not when it -calls emitNamedWildCardHoleConstraints in tcHsPartialSigType on all HsWildCardBndrs? +calls emitNamedTypeHole in tcHsPartialSigType on all HsWildCardBndrs? The solution then is to neither rename nor include unnamed wildcards in HsWildCardBndrs, but instead give every anonymous wildcard a fresh wild tyvar in tcAnonWildCardOcc. And whenever we see a '@', we automatically turn on PartialTypeSignatures and -turn off hole constraint warnings, and do not call emitAnonWildCardHoleConstraint +turn off hole constraint warnings, and do not call emitAnonTypeHole under these conditions. See related Note [Wildcards in visible type application] here and Note [The wildcard story for types] in GHC.Hs.Types @@ -3192,7 +3192,7 @@ tcHsPartialSigType ctxt sig_ty -- Spit out the wildcards (including the extra-constraints one) -- as "hole" constraints, so that they'll be reported if necessary -- See Note [Extra-constraint holes in partial type signatures] - ; emitNamedWildCardHoleConstraints wcs + ; mapM_ emitNamedTypeHole wcs -- Zonk, so that any nested foralls can "see" their occurrences -- See Note [Checking partial type signatures], in @@ -3365,7 +3365,7 @@ tcHsPatSigType ctxt sig_ty do { sig_ty <- tcHsOpenType hs_ty ; return (wcs, sig_ty) } - ; emitNamedWildCardHoleConstraints wcs + ; mapM_ emitNamedTypeHole wcs -- sig_ty might have tyvars that are at a higher TcLevel (if hs_ty -- contains a forall). Promote these. ===================================== compiler/GHC/Tc/Gen/Rule.hs ===================================== @@ -462,7 +462,7 @@ getRuleQuantCts wc float_wc :: TcTyCoVarSet -> WantedConstraints -> (Cts, WantedConstraints) float_wc skol_tvs (WC { wc_simple = simples, wc_impl = implics }) = ( simple_yes `andCts` implic_yes - , WC { wc_simple = simple_no, wc_impl = implics_no }) + , emptyWC { wc_simple = simple_no, wc_impl = implics_no }) where (simple_yes, simple_no) = partitionBag (rule_quant_ct skol_tvs) simples (implic_yes, implics_no) = mapAccumBagL (float_implic skol_tvs) @@ -480,8 +480,6 @@ getRuleQuantCts wc | EqPred _ t1 t2 <- classifyPredType (ctPred ct) , not (ok_eq t1 t2) = False -- Note [RULE quantification over equalities] - | isHoleCt ct - = False -- Don't quantify over type holes, obviously | otherwise = tyCoVarsOfCt ct `disjointVarSet` skol_tvs ===================================== compiler/GHC/Tc/Module.hs ===================================== @@ -2589,7 +2589,7 @@ tcRnType hsc_env flexi normalise rdr_type -- kindGeneralize, below solveEqualities $ tcNamedWildCardBinders wcs $ \ wcs' -> - do { emitNamedWildCardHoleConstraints wcs' + do { mapM_ emitNamedTypeHole wcs' ; tcLHsTypeUnsaturated rn_type } -- Do kind generalisation; see Note [Kind-generalise in tcRnType] ===================================== compiler/GHC/Tc/Solver.hs ===================================== @@ -31,7 +31,7 @@ import GHC.Prelude import GHC.Data.Bag import GHC.Core.Class ( Class, classKey, classTyCon ) import GHC.Driver.Session -import GHC.Types.Id ( idType, mkLocalId ) +import GHC.Types.Id ( idType ) import GHC.Tc.Utils.Instantiate import GHC.Data.List.SetOps import GHC.Types.Name @@ -42,6 +42,7 @@ import GHC.Tc.Errors import GHC.Tc.Types.Evidence import GHC.Tc.Solver.Interact import GHC.Tc.Solver.Canonical ( makeSuperClasses, solveCallStack ) +import GHC.Tc.Solver.Flatten ( flattenType ) import GHC.Tc.Utils.TcMType as TcM import GHC.Tc.Utils.Monad as TcM import GHC.Tc.Solver.Monad as TcS @@ -145,8 +146,7 @@ simplifyTop wanteds ; saved_msg <- TcM.readTcRef errs_var ; TcM.writeTcRef errs_var emptyMessages - ; warnAllUnsolved $ WC { wc_simple = unsafe_ol - , wc_impl = emptyBag } + ; warnAllUnsolved $ emptyWC { wc_simple = unsafe_ol } ; whyUnsafe <- fst <$> TcM.readTcRef errs_var ; TcM.writeTcRef errs_var saved_msg @@ -638,27 +638,15 @@ tcNormalise :: Bag EvVar -> Type -> TcM Type tcNormalise given_ids ty = do { lcl_env <- TcM.getLclEnv ; let given_loc = mkGivenLoc topTcLevel UnkSkol lcl_env - ; wanted_ct <- mk_wanted_ct + ; norm_loc <- getCtLocM PatCheckOrigin Nothing ; (res, _ev_binds) <- runTcS $ do { traceTcS "tcNormalise {" (ppr given_ids) ; let given_cts = mkGivens given_loc (bagToList given_ids) ; solveSimpleGivens given_cts - ; wcs <- solveSimpleWanteds (unitBag wanted_ct) - -- It's an invariant that this wc_simple will always be - -- a singleton Ct, since that's what we fed in as input. - ; let ty' = case bagToList (wc_simple wcs) of - (ct:_) -> ctEvPred (ctEvidence ct) - cts -> pprPanic "tcNormalise" (ppr cts) + ; ty' <- flattenType norm_loc ty ; traceTcS "tcNormalise }" (ppr ty') ; pure ty' } ; return res } - where - mk_wanted_ct :: TcM Ct - mk_wanted_ct = do - let occ = mkVarOcc "$tcNorm" - name <- newSysName occ - let ev = mkLocalId name ty - newHoleCt ExprHole ev ty {- Note [Superclasses and satisfiability] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -696,11 +684,8 @@ if some local equalities are solved for. See "Wrinkle: Local equalities" in Note [Type normalisation] in Check. To accomplish its stated goal, tcNormalise first feeds the local constraints -into solveSimpleGivens, then stuffs the argument type in a CHoleCan, and feeds -that singleton Ct into solveSimpleWanteds, which reduces the type in the -CHoleCan as much as possible with respect to the local given constraints. When -solveSimpleWanteds is finished, we dig out the type from the CHoleCan and -return that. +into solveSimpleGivens, then uses flattenType to simplify the desired type +with respect to the givens. *********************************************************************************** * * @@ -889,8 +874,8 @@ mkResidualConstraints rhs_tclvl ev_binds_var , ic_no_eqs = False , ic_info = skol_info } - ; return (WC { wc_simple = outer_simple - , wc_impl = implics })} + ; return (emptyWC { wc_simple = outer_simple + , wc_impl = implics })} where full_theta = map idType full_theta_vars skol_info = InferSkol [ (name, mkSigmaTy [] full_theta ty) @@ -1516,7 +1501,7 @@ solveWantedsAndDrop wanted solveWanteds :: WantedConstraints -> TcS WantedConstraints -- so that the inert set doesn't mindlessly propagate. -- NB: wc_simples may be wanted /or/ derived now -solveWanteds wc@(WC { wc_simple = simples, wc_impl = implics }) +solveWanteds wc@(WC { wc_simple = simples, wc_impl = implics, wc_holes = holes }) = do { cur_lvl <- TcS.getTcLevel ; traceTcS "solveWanteds {" $ vcat [ text "Level =" <+> ppr cur_lvl @@ -1530,9 +1515,12 @@ solveWanteds wc@(WC { wc_simple = simples, wc_impl = implics }) implics `unionBags` wc_impl wc1 ; dflags <- getDynFlags - ; final_wc <- simpl_loop 0 (solverIterations dflags) floated_eqs + ; solved_wc <- simpl_loop 0 (solverIterations dflags) floated_eqs (wc1 { wc_impl = implics2 }) + ; holes' <- simplifyHoles holes + ; let final_wc = solved_wc { wc_holes = holes' } + ; ev_binds_var <- getTcEvBindsVar ; bb <- TcS.getTcEvBindsMap ev_binds_var ; traceTcS "solveWanteds }" $ @@ -1779,12 +1767,13 @@ setImplicationStatus implic@(Implic { ic_status = status then Nothing else Just final_implic } where - WC { wc_simple = simples, wc_impl = implics } = wc + WC { wc_simple = simples, wc_impl = implics, wc_holes = holes } = wc pruned_simples = dropDerivedSimples simples pruned_implics = filterBag keep_me implics pruned_wc = WC { wc_simple = pruned_simples - , wc_impl = pruned_implics } + , wc_impl = pruned_implics + , wc_holes = holes } -- do not prune holes; these should be reported keep_me :: Implication -> Bool keep_me ic @@ -1898,6 +1887,14 @@ neededEvVars implic@(Implic { ic_given = givens | is_given = needs -- Add the rhs vars of the Wanted bindings only | otherwise = evVarsOfTerm rhs `unionVarSet` needs +------------------------------------------------- +simplifyHoles :: Bag Hole -> TcS (Bag Hole) +simplifyHoles = mapBagM simpl_hole + where + simpl_hole :: Hole -> TcS Hole + simpl_hole h@(Hole { hole_ty = ty, hole_loc = loc }) + = do { ty' <- flattenType loc ty + ; return (h { hole_ty = ty' }) } {- Note [Delete dead Given evidence bindings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2143,7 +2140,6 @@ approximateWC float_past_equalities wc is_floatable skol_tvs ct | isGivenCt ct = False - | isHoleCt ct = False | insolubleEqCt ct = False | otherwise = tyCoVarsOfCt ct `disjointVarSet` skol_tvs ===================================== compiler/GHC/Tc/Solver/Canonical.hs ===================================== @@ -34,7 +34,6 @@ import GHC.Tc.Instance.Family ( tcTopNormaliseNewTypeTF_maybe ) import GHC.Types.Var import GHC.Types.Var.Env( mkInScopeSet ) import GHC.Types.Var.Set( delVarSetList ) -import GHC.Types.Name.Occurrence ( OccName ) import GHC.Utils.Outputable import GHC.Driver.Session( DynFlags ) import GHC.Types.Name.Set @@ -67,8 +66,7 @@ Canonicalization converts a simple constraint to a canonical form. It is unary (i.e. treats individual constraints one at a time). Constraints originating from user-written code come into being as -CNonCanonicals (except for CHoleCans, arising from holes). We know nothing -about these constraints. So, first: +CNonCanonicals. We know nothing about these constraints. So, first: Classify CNonCanoncal constraints, depending on whether they are equalities, class predicates, or other. @@ -137,9 +135,6 @@ canonicalize (CFunEqCan { cc_ev = ev = {-# SCC "canEqLeafFunEq" #-} canCFunEqCan ev fn xis1 fsk -canonicalize (CHoleCan { cc_ev = ev, cc_occ = occ, cc_hole = hole }) - = canHole ev occ hole - {- ************************************************************************ * * @@ -718,17 +713,6 @@ canIrred status ev _ -> continueWith $ mkIrredCt status new_ev } } -canHole :: CtEvidence -> OccName -> HoleSort -> TcS (StopOrContinue Ct) -canHole ev occ hole_sort - = do { let pred = ctEvPred ev - ; (xi,co) <- flatten FM_SubstOnly ev pred -- co :: xi ~ pred - ; rewriteEvidence ev xi co `andWhenContinue` \ new_ev -> - do { updInertIrreds (`snocCts` (CHoleCan { cc_ev = new_ev - , cc_occ = occ - , cc_hole = hole_sort })) - ; stopWith new_ev "Emit insoluble hole" } } - - {- ********************************************************************* * * * Quantified predicates @@ -1401,6 +1385,7 @@ can_eq_app ev s1 t1 s2 t2 | CtDerived {} <- ev = do { unifyDeriveds loc [Nominal, Nominal] [s1, t1] [s2, t2] ; stopWith ev "Decomposed [D] AppTy" } + | CtWanted { ctev_dest = dest } <- ev = do { co_s <- unifyWanted loc Nominal s1 s2 ; let arg_loc ===================================== compiler/GHC/Tc/Solver/Flatten.hs ===================================== @@ -5,7 +5,7 @@ module GHC.Tc.Solver.Flatten( FlattenMode(..), flatten, flattenKind, flattenArgsNom, - rewriteTyVar, + rewriteTyVar, flattenType, unflattenWanteds ) where @@ -825,6 +825,20 @@ flattenArgsNom ev tc tys ; traceTcS "flatten }" (vcat (map ppr tys')) ; return (tys', cos, kind_co) } +-- | Flatten a type w.r.t. nominal equality. This is useful to rewrite +-- a type w.r.t. any givens. It does not do type-family reduction. This +-- will never emit new constraints. Call this when the inert set contains +-- only givens. +flattenType :: CtLoc -> TcType -> TcS TcType +flattenType loc ty + -- More info about FM_SubstOnly in Note [Holes] in GHC.Tc.Types.Constraint + = do { (xi, _) <- runFlatten FM_SubstOnly loc Given NomEq $ + flatten_one ty + -- use Given flavor so that it is rewritten + -- only w.r.t. Givens, never Wanteds/Deriveds + -- (Shouldn't matter, if only Givens are present + -- anyway) + ; return xi } {- ********************************************************************* * * ===================================== compiler/GHC/Tc/Solver/Interact.hs ===================================== @@ -195,7 +195,7 @@ solve_simple_wanteds :: WantedConstraints -> TcS (Int, WantedConstraints) -- Try solving these constraints -- Affects the unification state (of course) but not the inert set -- The result is not necessarily zonked -solve_simple_wanteds (WC { wc_simple = simples1, wc_impl = implics1 }) +solve_simple_wanteds (WC { wc_simple = simples1, wc_impl = implics1, wc_holes = holes }) = nestTcS $ do { solveSimples simples1 ; (implics2, tv_eqs, fun_eqs, others) <- getUnsolvedInerts @@ -204,7 +204,8 @@ solve_simple_wanteds (WC { wc_simple = simples1, wc_impl = implics1 }) -- See Note [Unflatten after solving the simple wanteds] ; return ( unif_count , WC { wc_simple = others `andCts` unflattened_eqs - , wc_impl = implics1 `unionBags` implics2 }) } + , wc_impl = implics1 `unionBags` implics2 + , wc_holes = holes }) } {- Note [The solveSimpleWanteds loop] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -264,7 +265,7 @@ runTcPluginsGiven -- 'solveSimpleWanteds' should feed the updated wanteds back into the -- main solver. runTcPluginsWanted :: WantedConstraints -> TcS (Bool, WantedConstraints) -runTcPluginsWanted wc@(WC { wc_simple = simples1, wc_impl = implics1 }) +runTcPluginsWanted wc@(WC { wc_simple = simples1 }) | isEmptyBag simples1 = return (False, wc) | otherwise @@ -285,11 +286,10 @@ runTcPluginsWanted wc@(WC { wc_simple = simples1, wc_impl = implics1 }) ; mapM_ setEv solved_wanted ; return ( notNull (pluginNewCts p) - , WC { wc_simple = listToBag new_wanted `andCts` + , wc { wc_simple = listToBag new_wanted `andCts` listToBag unsolved_wanted `andCts` listToBag unsolved_derived `andCts` - listToBag insols - , wc_impl = implics1 } ) } } + listToBag insols } ) } } where setEv :: (EvTerm,Ct) -> TcS () setEv (ev,ct) = case ctEvidence ct of @@ -494,7 +494,6 @@ interactWithInertsStage wi CIrredCan {} -> interactIrred ics wi CDictCan {} -> interactDict ics wi _ -> pprPanic "interactWithInerts" (ppr wi) } - -- CHoleCan are put straight into inert_frozen, so never get here -- CNonCanonical have been canonicalised data InteractResult ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -198,7 +198,7 @@ import GHC.Types.Unique.Set Note [WorkList priorities] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -A WorkList contains canonical and non-canonical items (of all flavors). +A WorkList contains canonical and non-canonical items (of all flavours). Notice that each Ct now has a simplification depth. We may consider using this depth for prioritization as well in the future. @@ -1653,8 +1653,7 @@ add_item ics item@(CDictCan { cc_ev = ev, cc_class = cls, cc_tyargs = tys }) add_item _ item = pprPanic "upd_inert set: can't happen! Inserting " $ - ppr item -- Can't be CNonCanonical, CHoleCan, - -- because they only land in inert_irreds + ppr item -- Can't be CNonCanonical because they only land in inert_irreds bumpUnsolvedCount :: CtEvidence -> Int -> Int bumpUnsolvedCount ev n | isWanted ev = n+1 @@ -1896,10 +1895,6 @@ be decomposed. Otherwise we end up with a "Can't match [Int] ~ [[Int]]" which is true, but a bit confusing because the outer type constructors match. -Similarly, if we have a CHoleCan, we'd like to rewrite it with any -Givens, to give as informative an error messasge as possible -(#12468, #11325). - Hence: * In the main simplifier loops in GHC.Tc.Solver (solveWanteds, simpl_loop), we feed the insolubles in solveSimpleWanteds, @@ -2352,8 +2347,6 @@ removeInertCt is ct = CQuantCan {} -> panic "removeInertCt: CQuantCan" CIrredCan {} -> panic "removeInertCt: CIrredEvCan" CNonCanonical {} -> panic "removeInertCt: CNonCanonical" - CHoleCan {} -> panic "removeInertCt: CHoleCan" - lookupFlatCache :: TyCon -> [Type] -> TcS (Maybe (TcCoercion, TcType, CtFlavour)) lookupFlatCache fam_tc tys ===================================== compiler/GHC/Tc/Types/Constraint.hs ===================================== @@ -14,8 +14,7 @@ module GHC.Tc.Types.Constraint ( isEmptyCts, isCTyEqCan, isCFunEqCan, isPendingScDict, superClassesMightHelp, getPendingWantedScs, isCDictCan_Maybe, isCFunEqCan_maybe, - isCNonCanonical, isWantedCt, isDerivedCt, - isGivenCt, isHoleCt, isOutOfScopeCt, isExprHoleCt, isTypeHoleCt, + isCNonCanonical, isWantedCt, isDerivedCt, isGivenCt, isUserTypeErrorCt, getUserTypeErrorMsg, ctEvidence, ctLoc, setCtLoc, ctPred, ctFlavour, ctEqRel, ctOrigin, ctEvId, mkTcEqPredLikeEv, @@ -26,9 +25,11 @@ module GHC.Tc.Types.Constraint ( tyCoVarsOfCt, tyCoVarsOfCts, tyCoVarsOfCtList, tyCoVarsOfCtsList, + Hole(..), HoleSort(..), isOutOfScopeHole, + WantedConstraints(..), insolubleWC, emptyWC, isEmptyWC, isSolvedWC, andWC, unionsWC, mkSimpleWC, mkImplicWC, - addInsols, insolublesOnly, addSimples, addImplics, + addInsols, insolublesOnly, addSimples, addImplics, addHole, tyCoVarsOfWC, dropDerivedWC, dropDerivedSimples, tyCoVarsOfWCList, insolubleCt, insolubleEqCt, isDroppableCt, insolubleImplic, @@ -62,9 +63,6 @@ module GHC.Tc.Types.Constraint ( pprEvVarTheta, pprEvVars, pprEvVarWithType, - -- holes - HoleSort(..), - ) where @@ -202,14 +200,6 @@ data Ct cc_ev :: CtEvidence } - | CHoleCan { -- See Note [Hole constraints] - -- Treated as an "insoluble" constraint - -- See Note [Insoluble constraints] - cc_ev :: CtEvidence, - cc_occ :: OccName, -- The name of this hole - cc_hole :: HoleSort -- The sort of this hole (expr, type, ...) - } - | CQuantCan QCInst -- A quantified constraint -- NB: I expect to make more of the cases in Ct -- look like this, with the payload in an @@ -230,13 +220,47 @@ instance Outputable QCInst where ppr (QCI { qci_ev = ev }) = ppr ev ------------ +-- | A hole stores the information needed to report diagnostics +-- about holes in terms (unbound identifiers or underscores) or +-- in types (also called wildcards, as used in partial type +-- signatures). See Note [Holes]. +data Hole + = Hole { hole_sort :: HoleSort -- ^ What flavour of hole is this? + , hole_occ :: OccName -- ^ The name of this hole + , hole_ty :: TcType -- ^ Type to be printed to the user + -- For expression holes: type of expr + -- For type holes: the missing type + , hole_loc :: CtLoc -- ^ Where hole was written + } + -- For the hole_loc, we usually only want the TcLclEnv stored within. + -- Except when we flatten, where we need a whole location. And this + -- might get reported to the user if reducing type families in a + -- hole type loops. + + -- | Used to indicate which sort of hole we have. -data HoleSort = ExprHole +data HoleSort = ExprHole Id -- ^ Either an out-of-scope variable or a "true" hole in an - -- expression (TypedHoles) + -- expression (TypedHoles). + -- The 'Id' is where to store "evidence": this evidence + -- will be an erroring expression for -fdefer-type-errors. | TypeHole -- ^ A hole in a type (PartialTypeSignatures) +instance Outputable Hole where + ppr (Hole { hole_sort = ExprHole id + , hole_occ = occ + , hole_ty = ty }) + = parens $ (braces $ ppr occ <> colon <> ppr id) <+> dcolon <+> ppr ty + ppr (Hole { hole_sort = TypeHole + , hole_occ = occ + , hole_ty = ty }) + = braces $ ppr occ <> colon <> ppr ty + +instance Outputable HoleSort where + ppr (ExprHole id) = text "ExprHole:" <> ppr id + ppr TypeHole = text "TypeHole" + ------------ -- | Used to indicate extra information about why a CIrredCan is irreducible data CtIrredStatus @@ -252,20 +276,8 @@ instance Outputable CtIrredStatus where ppr BlockedCIS = text "(blocked)" ppr OtherCIS = text "(soluble)" -{- Note [Hole constraints] -~~~~~~~~~~~~~~~~~~~~~~~~~~ -CHoleCan constraints are used for two kinds of holes, -distinguished by cc_hole: - - * For holes in expressions - e.g. f x = g _ x - - * For holes in type signatures - e.g. f :: _ -> _ - f x = [x,True] - -Note [CIrredCan constraints] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [CIrredCan constraints] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CIrredCan constraints are used for constraints that are "stuck" - we can't solve them (yet) - we can't use them to solve other constraints @@ -350,6 +362,40 @@ unenforced). The almost-function-free property is checked by isAlmostFunctionFree in GHC.Tc.Utils.TcType. The flattener (in GHC.Tc.Solver.Flatten) produces types that are almost function-free. +Note [Holes] +~~~~~~~~~~~~ +This Note explains how GHC tracks *holes*. + +A hole represents one of two conditions: + - A missing bit of an expression. Example: foo x = x + _ + - A missing bit of a type. Example: bar :: Int -> _ + +What these have in common is that both cause GHC to emit a diagnostic to the +user describing the bit that is left out. + +When a hole is encountered, a new entry of type Hole is added to the ambient +WantedConstraints. The type (hole_ty) of the hole is then simplified during +solving (with respect to any Givens in surrounding implications). It is +reported with all the other errors in GHC.Tc.Errors. No type family reduction +is done on hole types; this is purely because we think it will produce +better error messages not to reduce type families. This is why the +GHC.Tc.Solver.Flatten.flattenType function uses FM_SubstOnly. + +For expression holes, the user has the option of deferring errors until runtime +with -fdefer-type-errors. In this case, the hole actually has evidence: this +evidence is an erroring expression that prints an error and crashes at runtime. +The ExprHole variant of holes stores the Id that will be bound to this evidence; +during constraint generation, this Id was inserted into the expression output +by the type checker. + +You might think that the type of the stored Id is the same as the type of the +hole. However, because the hole type (hole_ty) is rewritten with respect to +givens, this might not be the case. That is, the hole_ty is always (~) to the +type of the Id, but they might not be `eqType`. We need the type of the generated +evidence to match what is expected in the context of the hole, and so we must +store these types separately. + +Type-level holes have no evidence at all. -} mkNonCanonical :: CtEvidence -> Ct @@ -419,7 +465,6 @@ instance Outputable Ct where | pend_sc -> text "CDictCan(psc)" | otherwise -> text "CDictCan" CIrredCan { cc_status = status } -> text "CIrredCan" <> ppr status - CHoleCan { cc_occ = occ } -> text "CHoleCan:" <+> ppr occ CQuantCan (QCI { qci_pend_sc = pend_sc }) | pend_sc -> text "CQuantCan(psc)" | otherwise -> text "CQuantCan" @@ -552,7 +597,6 @@ isDroppableCt ct keep_deriv = case ct of - CHoleCan {} -> True CIrredCan { cc_status = InsolubleCIS } -> keep_eq True _ -> keep_eq False @@ -676,26 +720,6 @@ isCNonCanonical :: Ct -> Bool isCNonCanonical (CNonCanonical {}) = True isCNonCanonical _ = False -isHoleCt:: Ct -> Bool -isHoleCt (CHoleCan {}) = True -isHoleCt _ = False - -isOutOfScopeCt :: Ct -> Bool --- A Hole that does not have a leading underscore is --- simply an out-of-scope variable, and we treat that --- a bit differently when it comes to error reporting -isOutOfScopeCt (CHoleCan { cc_occ = occ }) = not (startsWithUnderscore occ) -isOutOfScopeCt _ = False - -isExprHoleCt :: Ct -> Bool -isExprHoleCt (CHoleCan { cc_hole = ExprHole }) = True -isExprHoleCt _ = False - -isTypeHoleCt :: Ct -> Bool -isTypeHoleCt (CHoleCan { cc_hole = TypeHole }) = True -isTypeHoleCt _ = False - - {- Note [Custom type errors in constraints] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -884,24 +908,25 @@ v%************************************************************************ data WantedConstraints = WC { wc_simple :: Cts -- Unsolved constraints, all wanted , wc_impl :: Bag Implication + , wc_holes :: Bag Hole } emptyWC :: WantedConstraints -emptyWC = WC { wc_simple = emptyBag, wc_impl = emptyBag } +emptyWC = WC { wc_simple = emptyBag + , wc_impl = emptyBag + , wc_holes = emptyBag } mkSimpleWC :: [CtEvidence] -> WantedConstraints mkSimpleWC cts - = WC { wc_simple = listToBag (map mkNonCanonical cts) - , wc_impl = emptyBag } + = emptyWC { wc_simple = listToBag (map mkNonCanonical cts) } mkImplicWC :: Bag Implication -> WantedConstraints mkImplicWC implic - = WC { wc_simple = emptyBag, wc_impl = implic } + = emptyWC { wc_impl = implic } isEmptyWC :: WantedConstraints -> Bool -isEmptyWC (WC { wc_simple = f, wc_impl = i }) - = isEmptyBag f && isEmptyBag i - +isEmptyWC (WC { wc_simple = f, wc_impl = i, wc_holes = holes }) + = isEmptyBag f && isEmptyBag i && isEmptyBag holes -- | Checks whether a the given wanted constraints are solved, i.e. -- that there are no simple constraints left and all the implications @@ -911,10 +936,11 @@ isSolvedWC WC {wc_simple = wc_simple, wc_impl = wc_impl} = isEmptyBag wc_simple && allBag (isSolvedStatus . ic_status) wc_impl andWC :: WantedConstraints -> WantedConstraints -> WantedConstraints -andWC (WC { wc_simple = f1, wc_impl = i1 }) - (WC { wc_simple = f2, wc_impl = i2 }) +andWC (WC { wc_simple = f1, wc_impl = i1, wc_holes = h1 }) + (WC { wc_simple = f2, wc_impl = i2, wc_holes = h2 }) = WC { wc_simple = f1 `unionBags` f2 - , wc_impl = i1 `unionBags` i2 } + , wc_impl = i1 `unionBags` i2 + , wc_holes = h1 `unionBags` h2 } unionsWC :: [WantedConstraints] -> WantedConstraints unionsWC = foldr andWC emptyWC @@ -931,11 +957,16 @@ addInsols :: WantedConstraints -> Bag Ct -> WantedConstraints addInsols wc cts = wc { wc_simple = wc_simple wc `unionBags` cts } +addHole :: WantedConstraints -> Hole -> WantedConstraints +addHole wc hole + = wc { wc_holes = hole `consBag` wc_holes wc } + insolublesOnly :: WantedConstraints -> WantedConstraints -- Keep only the definitely-insoluble constraints -insolublesOnly (WC { wc_simple = simples, wc_impl = implics }) +insolublesOnly (WC { wc_simple = simples, wc_impl = implics, wc_holes = holes }) = WC { wc_simple = filterBag insolubleCt simples - , wc_impl = mapBag implic_insols_only implics } + , wc_impl = mapBag implic_insols_only implics + , wc_holes = filterBag isOutOfScopeHole holes } where implic_insols_only implic = implic { ic_wanted = insolublesOnly (ic_wanted implic) } @@ -953,9 +984,10 @@ insolubleImplic :: Implication -> Bool insolubleImplic ic = isInsolubleStatus (ic_status ic) insolubleWC :: WantedConstraints -> Bool -insolubleWC (WC { wc_impl = implics, wc_simple = simples }) +insolubleWC (WC { wc_impl = implics, wc_simple = simples, wc_holes = holes }) = anyBag insolubleCt simples || anyBag insolubleImplic implics + || anyBag isOutOfScopeHole holes -- See Note [Insoluble holes] insolubleCt :: Ct -> Bool -- Definitely insoluble, in particular /excluding/ type-hole constraints @@ -963,7 +995,6 @@ insolubleCt :: Ct -> Bool -- b) that is insoluble -- c) and does not arise from a Given insolubleCt ct - | isHoleCt ct = isOutOfScopeCt ct -- See Note [Insoluble holes] | not (insolubleEqCt ct) = False | arisesFromGivens ct = False -- See Note [Given insolubles] | otherwise = True @@ -986,6 +1017,11 @@ insolubleEqCt :: Ct -> Bool insolubleEqCt (CIrredCan { cc_status = InsolubleCIS }) = True insolubleEqCt _ = False +-- | Does this hole represent an "out of scope" error? +-- See Note [Insoluble holes] +isOutOfScopeHole :: Hole -> Bool +isOutOfScopeHole (Hole { hole_occ = occ }) = not (startsWithUnderscore occ) + instance Outputable WantedConstraints where ppr (WC {wc_simple = s, wc_impl = i}) = text "WC" <+> braces (vcat @@ -1035,7 +1071,7 @@ Hole constraints that ARE NOT treated as truly insoluble: a) type holes, arising from PartialTypeSignatures, b) "true" expression holes arising from TypedHoles -An "expression hole" or "type hole" constraint isn't really an error +An "expression hole" or "type hole" isn't really an error at all; it's a report saying "_ :: Int" here. But an out-of-scope variable masquerading as expression holes IS treated as truly insoluble, so that it trumps other errors during error reporting. @@ -1512,10 +1548,6 @@ ctFlavourRole (CTyEqCan { cc_ev = ev, cc_eq_rel = eq_rel }) = (ctEvFlavour ev, eq_rel) ctFlavourRole (CFunEqCan { cc_ev = ev }) = (ctEvFlavour ev, NomEq) -ctFlavourRole (CHoleCan { cc_ev = ev }) - = (ctEvFlavour ev, NomEq) -- NomEq: CHoleCans can be rewritten by - -- by nominal equalities but empahatically - -- not by representational equalities ctFlavourRole ct = ctEvFlavourRole (ctEvidence ct) ===================================== compiler/GHC/Tc/Types/Origin.hs ===================================== @@ -427,7 +427,9 @@ data CtOrigin -- We only need a CtOrigin on the first, because the location -- is pinned on the entire error message - | HoleOrigin + | ExprHoleOrigin OccName -- from an expression hole + | TypeHoleOrigin OccName -- from a type hole (partial type signature) + | PatCheckOrigin -- normalisation of a type during pattern-match checking | UnboundOccurrenceOf OccName | ListOrigin -- An overloaded list | BracketOrigin -- An overloaded quotation bracket @@ -640,7 +642,9 @@ pprCtO MCompOrigin = text "a statement in a monad comprehension" pprCtO ProcOrigin = text "a proc expression" pprCtO (TypeEqOrigin t1 t2 _ _)= text "a type equality" <+> sep [ppr t1, char '~', ppr t2] pprCtO AnnOrigin = text "an annotation" -pprCtO HoleOrigin = text "a use of" <+> quotes (text "_") +pprCtO (ExprHoleOrigin occ) = text "a use of" <+> quotes (ppr occ) +pprCtO (TypeHoleOrigin occ) = text "a use of wildcard" <+> quotes (ppr occ) +pprCtO PatCheckOrigin = text "a pattern-match completeness check" pprCtO ListOrigin = text "an overloaded list" pprCtO StaticOrigin = text "a static form" pprCtO BracketOrigin = text "a quotation bracket" ===================================== compiler/GHC/Tc/Utils/Monad.hs ===================================== @@ -98,14 +98,14 @@ module GHC.Tc.Utils.Monad( chooseUniqueOccTc, getConstraintVar, setConstraintVar, emitConstraints, emitStaticConstraints, emitSimple, emitSimples, - emitImplication, emitImplications, emitInsoluble, + emitImplication, emitImplications, emitInsoluble, emitHole, discardConstraints, captureConstraints, tryCaptureConstraints, pushLevelAndCaptureConstraints, pushTcLevelM_, pushTcLevelM, pushTcLevelsM, getTcLevel, setTcLevel, isTouchableTcM, getLclTypeEnv, setLclTypeEnv, traceTcConstraints, - emitNamedWildCardHoleConstraints, emitAnonWildCardHoleConstraint, + emitNamedTypeHole, emitAnonTypeHole, -- * Template Haskell context recordThUse, recordThSpliceUse, @@ -1569,12 +1569,11 @@ emitInsoluble ct ; lie_var <- getConstraintVar ; updTcRef lie_var (`addInsols` unitBag ct) } -emitInsolubles :: Cts -> TcM () -emitInsolubles cts - | isEmptyBag cts = return () - | otherwise = do { traceTc "emitInsolubles" (ppr cts) - ; lie_var <- getConstraintVar - ; updTcRef lie_var (`addInsols` cts) } +emitHole :: Hole -> TcM () +emitHole hole + = do { traceTc "emitHole" (ppr hole) + ; lie_var <- getConstraintVar + ; updTcRef lie_var (`addHole` hole) } -- | Throw out any constraints emitted by the thing_inside discardConstraints :: TcM a -> TcM a @@ -1644,34 +1643,28 @@ traceTcConstraints msg hang (text (msg ++ ": LIE:")) 2 (ppr lie) } -emitAnonWildCardHoleConstraint :: TcTyVar -> TcM () -emitAnonWildCardHoleConstraint tv - = do { ct_loc <- getCtLocM HoleOrigin Nothing - ; emitInsolubles $ unitBag $ - CHoleCan { cc_ev = CtDerived { ctev_pred = mkTyVarTy tv - , ctev_loc = ct_loc } - , cc_occ = mkTyVarOcc "_" - , cc_hole = TypeHole } } - -emitNamedWildCardHoleConstraints :: [(Name, TcTyVar)] -> TcM () -emitNamedWildCardHoleConstraints wcs - = do { ct_loc <- getCtLocM HoleOrigin Nothing - ; emitInsolubles $ listToBag $ - map (do_one ct_loc) wcs } +emitAnonTypeHole :: TcTyVar -> TcM () +emitAnonTypeHole tv + = do { ct_loc <- getCtLocM (TypeHoleOrigin occ) Nothing + ; let hole = Hole { hole_sort = TypeHole + , hole_occ = occ + , hole_ty = mkTyVarTy tv + , hole_loc = ct_loc } + ; emitHole hole } + where + occ = mkTyVarOcc "_" + +emitNamedTypeHole :: (Name, TcTyVar) -> TcM () +emitNamedTypeHole (name, tv) + = do { ct_loc <- setSrcSpan (nameSrcSpan name) $ + getCtLocM (TypeHoleOrigin occ) Nothing + ; let hole = Hole { hole_sort = TypeHole + , hole_occ = occ + , hole_ty = mkTyVarTy tv + , hole_loc = ct_loc } + ; emitHole hole } where - do_one :: CtLoc -> (Name, TcTyVar) -> Ct - do_one ct_loc (name, tv) - = CHoleCan { cc_ev = CtDerived { ctev_pred = mkTyVarTy tv - , ctev_loc = ct_loc' } - , cc_occ = occName name - , cc_hole = TypeHole } - where - real_span = case nameSrcSpan name of - RealSrcSpan span _ -> span - UnhelpfulSpan str -> pprPanic "emitNamedWildCardHoleConstraints" - (ppr name <+> quotes (ftext str)) - -- Wildcards are defined locally, and so have RealSrcSpans - ct_loc' = setCtLocSpan ct_loc real_span + occ = nameOccName name {- Note [Constraints and errors] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Tc/Utils/TcMType.hs ===================================== @@ -41,10 +41,11 @@ module GHC.Tc.Utils.TcMType ( -------------------------------- -- Creating new evidence variables newEvVar, newEvVars, newDict, - newWanted, newWanteds, newHoleCt, cloneWanted, cloneWC, + newWanted, newWanteds, cloneWanted, cloneWC, emitWanted, emitWantedEq, emitWantedEvVar, emitWantedEvVars, emitDerivedEqs, newTcEvBinds, newNoTcEvBinds, addTcEvBind, + emitNewExprHole, newCoercionHole, fillCoercionHole, isFilledCoercionHole, unpackCoercionHole, unpackCoercionHole_maybe, @@ -67,7 +68,7 @@ module GHC.Tc.Utils.TcMType ( -------------------------------- -- Zonking and tidying zonkTidyTcType, zonkTidyTcTypes, zonkTidyOrigin, - tidyEvVar, tidyCt, tidySkolemInfo, + tidyEvVar, tidyCt, tidyHole, tidySkolemInfo, zonkTcTyVar, zonkTcTyVars, zonkTcTyVarToTyVar, zonkTyVarTyVarPairs, zonkTyCoVarsAndFV, zonkTcTypeAndFV, zonkDTyCoVarSetAndFV, @@ -193,17 +194,6 @@ newWanted orig t_or_k pty newWanteds :: CtOrigin -> ThetaType -> TcM [CtEvidence] newWanteds orig = mapM (newWanted orig Nothing) --- | Create a new 'CHoleCan' 'Ct'. -newHoleCt :: HoleSort -> Id -> Type -> TcM Ct -newHoleCt hole ev ty = do - loc <- getCtLocM HoleOrigin Nothing - pure $ CHoleCan { cc_ev = CtWanted { ctev_pred = ty - , ctev_dest = EvVarDest ev - , ctev_nosh = WDeriv - , ctev_loc = loc } - , cc_occ = getOccName ev - , cc_hole = hole } - ---------------------------------------------- -- Cloning constraints ---------------------------------------------- @@ -286,6 +276,18 @@ emitWantedEvVar origin ty emitWantedEvVars :: CtOrigin -> [TcPredType] -> TcM [EvVar] emitWantedEvVars orig = mapM (emitWantedEvVar orig) +-- | Emit a new wanted expression hole +emitNewExprHole :: OccName -- of the hole + -> Id -- of the evidence + -> Type -> TcM () +emitNewExprHole occ ev_id ty + = do { loc <- getCtLocM (ExprHoleOrigin occ) (Just TypeLevel) + ; let hole = Hole { hole_sort = ExprHole ev_id + , hole_occ = getOccName ev_id + , hole_ty = ty + , hole_loc = loc } + ; emitHole hole } + newDict :: Class -> [TcType] -> TcM DictId newDict cls tys = do { name <- newSysName (mkDictOcc (getOccName cls)) @@ -2002,21 +2004,28 @@ zonkWC :: WantedConstraints -> TcM WantedConstraints zonkWC wc = zonkWCRec wc zonkWCRec :: WantedConstraints -> TcM WantedConstraints -zonkWCRec (WC { wc_simple = simple, wc_impl = implic }) +zonkWCRec (WC { wc_simple = simple, wc_impl = implic, wc_holes = holes }) = do { simple' <- zonkSimples simple ; implic' <- mapBagM zonkImplication implic - ; return (WC { wc_simple = simple', wc_impl = implic' }) } + ; holes' <- mapBagM zonkHole holes + ; return (WC { wc_simple = simple', wc_impl = implic', wc_holes = holes' }) } zonkSimples :: Cts -> TcM Cts zonkSimples cts = do { cts' <- mapBagM zonkCt cts ; traceTc "zonkSimples done:" (ppr cts') ; return cts' } +zonkHole :: Hole -> TcM Hole +zonkHole hole@(Hole { hole_ty = ty }) + = do { ty' <- zonkTcType ty + ; return (hole { hole_ty = ty' }) } + -- No need to zonk the Id in any ExprHole because we never look at it + -- until after the final zonk and desugaring + {- Note [zonkCt behaviour] ~~~~~~~~~~~~~~~~~~~~~~~~~~ zonkCt tries to maintain the canonical form of a Ct. For example, - a CDictCan should stay a CDictCan; - - a CHoleCan should stay a CHoleCan - a CIrredCan should stay a CIrredCan with its cc_status flag intact Why?, for example: @@ -2026,8 +2035,6 @@ Why?, for example: don't preserve a canonical form, @expandSuperClasses@ fails to expand superclasses. This is what happened in #11525. -- For CHoleCan, once we forget that it's a hole, we can never recover that info. - - For CIrredCan we want to see if a constraint is insoluble with insolubleWC On the other hand, we change CTyEqCan to CNonCanonical, because of all of @@ -2046,10 +2053,6 @@ creates e.g. a CDictCan where the cc_tyars are /not/ function free. zonkCt :: Ct -> TcM Ct -- See Note [zonkCt behaviour] -zonkCt ct@(CHoleCan { cc_ev = ev }) - = do { ev' <- zonkCtEvidence ev - ; return $ ct { cc_ev = ev' } } - zonkCt ct@(CDictCan { cc_ev = ev, cc_tyargs = args }) = do { ev' <- zonkCtEvidence ev ; args' <- mapM zonkTcType args @@ -2262,17 +2265,15 @@ zonkTidyOrigin env orig = return (env, orig) tidyCt :: TidyEnv -> Ct -> Ct -- Used only in error reporting tidyCt env ct - = ct { cc_ev = tidy_ev env (ctEvidence ct) } + = ct { cc_ev = tidy_ev (ctEvidence ct) } where - tidy_ev :: TidyEnv -> CtEvidence -> CtEvidence + tidy_ev :: CtEvidence -> CtEvidence -- NB: we do not tidy the ctev_evar field because we don't -- show it in error messages - tidy_ev env ctev@(CtGiven { ctev_pred = pred }) - = ctev { ctev_pred = tidyType env pred } - tidy_ev env ctev@(CtWanted { ctev_pred = pred }) - = ctev { ctev_pred = tidyType env pred } - tidy_ev env ctev@(CtDerived { ctev_pred = pred }) - = ctev { ctev_pred = tidyType env pred } + tidy_ev ctev = ctev { ctev_pred = tidyType env (ctev_pred ctev) } + +tidyHole :: TidyEnv -> Hole -> Hole +tidyHole env h@(Hole { hole_ty = ty }) = h { hole_ty = tidyType env ty } ---------------- tidyEvVar :: TidyEnv -> EvVar -> EvVar View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/626f10b9f8122a3e04caefaac7bf105d546406fb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/626f10b9f8122a3e04caefaac7bf105d546406fb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 1 15:20:04 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Fri, 01 May 2020 11:20:04 -0400 Subject: [Git][ghc/ghc][wip/T17775] 30 commits: Define a Quote IO instance Message-ID: <5eac3e248e3e2_61673f81cd9bfa6c83428a4@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: 4b9764db by Ryan Scott at 2020-04-28T15:40:04-04:00 Define a Quote IO instance Fixes #18103. - - - - - 518a63d4 by Ryan Scott at 2020-04-28T15:40:42-04:00 Make boxed 1-tuples have known keys Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. - - - - - 2cfc4ab9 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Document backpack fields in DynFlags - - - - - 10a2ba90 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 69562e34 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 9e2c8e0e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - ea717aa4 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 10d15f1e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 8bfb0219 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - 71484b09 by Alexis King at 2020-04-30T01:57:35-04:00 Allow block arguments in arrow control operators Arrow control operators have their own entries in the grammar, so they did not cooperate with BlockArguments. This was just a minor oversight, so this patch adjusts the grammar to add the desired behavior. fixes #18050 - - - - - a48cd2a0 by Alexis King at 2020-04-30T01:57:35-04:00 Allow LambdaCase to be used as a command in proc notation - - - - - f4d3773c by Alexis King at 2020-04-30T01:57:35-04:00 Document BlockArguments/LambdaCase support in arrow notation - - - - - 5bdfdd13 by Simon Peyton Jones at 2020-04-30T01:58:15-04:00 Add tests for #17873 - - - - - 19b701c2 by Simon Peyton Jones at 2020-04-30T07:30:13-04:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - 014ef4a3 by Matthew Pickering at 2020-04-30T07:30:50-04:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 2aa67611 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - 54dad3cf by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - 99ff8145 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 05b0a9fd by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 Remove OneShotInfo field of LFReEntrant, document OneShotInfo The field is only used in withNewTickyCounterFun and it's easier to directly pass a parameter for one-shot info to withNewTickyCounterFun instead of passing it via LFReEntrant. This also makes !2842 simpler. Other changes: - New Note (by SPJ) [OneShotInfo overview] added. - Arity argument of thunkCode removed as it's always 0. - - - - - a43620c6 by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 GHC.StgToCmm.Ticky: remove a few unused stuff - - - - - 780de9e1 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Use platform in Iface Binary - - - - - f8386c7b by Sylvain Henry at 2020-05-01T10:37:39-04:00 Refactor PprDebug handling If `-dppr-debug` is set, then PprUser and PprDump styles are silently replaced with PprDebug style. This was done in `mkUserStyle` and `mkDumpStyle` smart constructors. As a consequence they needed a DynFlags parameter. Now we keep the original PprUser and PprDump styles until they are used to create an `SDocContext`. I.e. the substitution is only performed in `initSDocContext`. - - - - - b3df9e78 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Remove PprStyle param of logging actions Use `withPprStyle` instead to apply a specific style to a SDoc. - - - - - de9fc995 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Fully remove PprDebug PprDebug was a pain to deal with consistently as it is implied by `-dppr-debug` but it isn't really a PprStyle. We remove it completely and query the appropriate SDoc flag instead (`sdocPprDebug`) via helpers (`getPprDebug` and its friends). - - - - - 8b51fcbd by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Only call checkSingle if we would report warnings - - - - - fd7ea0fe by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 4baf35b1 by Simon Peyton Jones at 2020-05-01T16:18:38+01:00 Simple subsumption This patch simplifies GHC to use simple subsumption. Ticket #17775 Implements GHC proposal #287 https://github.com/ghc-proposals/ghc-proposals/blob/master/ proposals/0287-simplify-subsumption.rst All the motivation is described there; I will not repeat it here. The implementation payload: * tcSubType and friends become noticably simpler, because it no longer uses eta-expansion when checking subsumption. * No deeplyInstantiate or deeplySkolemise That in turn means that some tests fail, by design; they can all be fixed by eta expansion. There is a list of such changes below. Implementing the patch led me into a variety of sticky corners, so the patch includes several othe changes, some quite significant: * I made String wired-in, so that "foo" :: String rather than "foo" :: [Char] This improves error messages, and fixes #15679 * isTauTy: was replying True for (Show a => a ->a), which is utterly bogus. Fixed. * The pattern match checker relies on knowing about in-scope equality constraints, andd adds them to the desugarer's environment using addTyCsDs. But the co_fn in a FunBind was missed, and for some reason simple-subsumption ends up with dictionaries there. So I added a call to addTyCsDs. This is really part of #18049. * I moved the ic_telescope field out of Implication and into ForAllSkol instead. This is a nice win; just expresses the code much better. * There was a bug in GHC.Tc.TyCl.Instance.tcDataFamInstHeader. We called checkDataKindSig inside tc_kind_sig, /before/ solveEqualities and zonking. Obviously wrong, easily fixed. * solveLocalEqualitiesX: there was a whole mess in here, around failing fast enough. I discovered a bad latent bug where we could successfully kind-check a type signature, and use it, but have unsolved constraints that could fill in coercion holes in that signature -- aargh. It's all explained in Note [Failure in local type signatures] in GHC.Tc.Solver. Much better now. * I fixed a serious bug in anonymous type holes. IN f :: Int -> (forall a. a -> _) -> Int that "_" should be a unification variable at the /outer/ level; it cannot be instantiated to 'a'. This was plain wrong. New fields mode_lvl and mode_holes in TcTyMode, and auxiliary data type GHC.Tc.Gen.HsType.HoleMode. This fixes #16292, but makes no progress towards the more ambitious #16082 * I got sucked into an enormous refactoring of the reporting of equality errors in GHC.Tc.Errors, especially in mkEqErr1 mkTyVarEqErr misMatchMsg misMatchMsgOrCND In particular, the very tricky mkExpectedActualMsg function is gone. It took me a full day. But the result is far easier to understand. (Still not easy!) This led to various minor improvements in error output, and an enormous number of test-case error wibbles. One particular point: for occurs-check errors I now just say Can't match 'a' against '[a]' rather than using the intimidating language of "occurs check". * Pretty-printing AbsBinds Tests review * Eta expansions T11305: one eta expansion T12082: one eta expansion (undefined) T13585a: one eta expansion T3102: one eta expansion T3692: two eta expansions (tricky) T2239: two eta expansions T16473: one eta determ004: two eta expansions (undefined) annfail06: two eta (undefined) T17923: four eta expansions (a strange program indeed!) tcrun035: one eta expansion * Ambiguity check at higher rank. Now that we have simple subsumption, a type like f :: (forall a. Eq a => Int) -> Int is no longer ambiguous, because we could write g :: (forall a. Eq a => Int) -> Int g = f and it'd typecheck just fine. But f's type is a bit suspicious, and we might want to consider making the ambiguity check do a check on each sub-term. Meanwhile, these tests are accepted, whereas they were previously rejected as ambiguous: T7220a T15438 T10503 T9222 * Some more interesting error message wibbles T13381: Fine: one error (Int ~ Exp Int) rather than two (Int ~ Exp Int, Exp Int ~ Int) T9834: Small change in error (improvement) T10619: Improved T2414: Small change, due to order of unification, fine T2534: A very simple case in which a change of unification order means we get tow unsolved constraints instead of one tc211: bizarre impredicative tests; just accept this for now - - - - - 2d3f029d by Simon Peyton Jones at 2020-05-01T16:19:29+01:00 Wibbles Especially make major improvement to hsWrapDictBinders - - - - - 4117c6a9 by Simon Peyton Jones at 2020-05-01T16:19:30+01:00 Wibbles esp to tcPolyCheck - - - - - 905faac4 by Simon Peyton Jones at 2020-05-01T16:19:31+01:00 Wibbles - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Utils.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Config.hs - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Driver.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/SpecConstr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a4249525036262c9ecf52cbcdd9ad70304c53d57...905faac4cb90be07cc8c28630cc5b88fa2f23541 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a4249525036262c9ecf52cbcdd9ad70304c53d57...905faac4cb90be07cc8c28630cc5b88fa2f23541 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 1 15:25:19 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Fri, 01 May 2020 11:25:19 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18121 Message-ID: <5eac3f5f1c9ab_616711ab08a48344065@gitlab.haskell.org.mail> Simon Peyton Jones pushed new branch wip/T18121 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18121 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 1 16:39:09 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Fri, 01 May 2020 12:39:09 -0400 Subject: [Git][ghc/ghc][wip/T17775] Wibbles Message-ID: <5eac50ade963b_6167c5ce1b083614f4@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: b4d28d52 by Simon Peyton Jones at 2020-05-01T17:38:45+01:00 Wibbles - - - - - 1 changed file: - compiler/GHC/Tc/Solver.hs Changes: ===================================== compiler/GHC/Tc/Solver.hs ===================================== @@ -2531,13 +2531,15 @@ floatEqualities skols given_ids ev_binds_var no_given_eqs is_float_eq_candidate ct | pred <- ctPred ct , EqPred NomEq ty1 ty2 <- classifyPredType pred - , Just tv1 <- tcGetTyVar_maybe ty1 - , isMetaTyVar tv1 - , not (isTyVarTyVar tv1) || isTyVarTy ty2 - = True + = float_eq ty1 ty2 || float_eq ty2 ty1 | otherwise = False + float_eq ty1 ty2 + = case getTyVar_maybe ty1 of + Just tv1 -> isMetaTyVar tv1 + && (not (isTyVarTyVar tv1) || isTyVarTy ty2) + Nothing -> False {- Note [Float equalities from under a skolem binding] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2568,15 +2570,17 @@ Which equalities should we float? We want to float ones where there is a decent chance that floating outwards will allow unification to happen. In particular, float out equalities that are: -* Of form (alpha ~# ty), where +* Of form (alpha ~# ty) or (ty ~# alpha), where * alpha is a meta-tyvar. * And 'alpha' is not a TyVarTv with 'ty' being a non-tyvar. In that case, floating out won't help either, and it may affect grouping of error messages. - NB: we will never have (skol ~ alpha), with the meta-tyvar on - the right. See Note [Unification variables on the left] - in GHC.Tc.Utils.Unify + NB: generally we won't see (ty ~ alpha), with alpha on the right because + of Note [Unification variables on the left] in GHC.Tc.Utils.Unify. + But if we start with (F tys ~ alpha), it will orient as (fmv ~ alpha), + and unflatten back to (F tys ~ alpha). So we must look for alpha on + the right too. Example T4494. * Nominal. No point in floating (alpha ~R# ty), because we do not unify representational equalities even if alpha is touchable. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b4d28d52e62db37a11f58a4c035d5414c4ed9209 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b4d28d52e62db37a11f58a4c035d5414c4ed9209 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 1 17:27:46 2020 From: gitlab at gitlab.haskell.org (Vladislav Zavialov) Date: Fri, 01 May 2020 13:27:46 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/t18123 Message-ID: <5eac5c1298b0c_6167e5b152c8369580@gitlab.haskell.org.mail> Vladislav Zavialov pushed new branch wip/t18123 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/t18123 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 1 17:31:36 2020 From: gitlab at gitlab.haskell.org (Vladislav Zavialov) Date: Fri, 01 May 2020 13:31:36 -0400 Subject: [Git][ghc/ghc][wip/t18123] 12 commits: nonmoving: Clear bitmap after initializing block size Message-ID: <5eac5cf817ce9_6167c5ce1b083711f0@gitlab.haskell.org.mail> Vladislav Zavialov pushed to branch wip/t18123 at Glasgow Haskell Compiler / GHC Commits: 2aa67611 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - 54dad3cf by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - 99ff8145 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 05b0a9fd by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 Remove OneShotInfo field of LFReEntrant, document OneShotInfo The field is only used in withNewTickyCounterFun and it's easier to directly pass a parameter for one-shot info to withNewTickyCounterFun instead of passing it via LFReEntrant. This also makes !2842 simpler. Other changes: - New Note (by SPJ) [OneShotInfo overview] added. - Arity argument of thunkCode removed as it's always 0. - - - - - a43620c6 by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 GHC.StgToCmm.Ticky: remove a few unused stuff - - - - - 780de9e1 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Use platform in Iface Binary - - - - - f8386c7b by Sylvain Henry at 2020-05-01T10:37:39-04:00 Refactor PprDebug handling If `-dppr-debug` is set, then PprUser and PprDump styles are silently replaced with PprDebug style. This was done in `mkUserStyle` and `mkDumpStyle` smart constructors. As a consequence they needed a DynFlags parameter. Now we keep the original PprUser and PprDump styles until they are used to create an `SDocContext`. I.e. the substitution is only performed in `initSDocContext`. - - - - - b3df9e78 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Remove PprStyle param of logging actions Use `withPprStyle` instead to apply a specific style to a SDoc. - - - - - de9fc995 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Fully remove PprDebug PprDebug was a pain to deal with consistently as it is implied by `-dppr-debug` but it isn't really a PprStyle. We remove it completely and query the appropriate SDoc flag instead (`sdocPprDebug`) via helpers (`getPprDebug` and its friends). - - - - - 8b51fcbd by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Only call checkSingle if we would report warnings - - - - - fd7ea0fe by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 611d3111 by Vladislav Zavialov at 2020-05-01T20:31:16+03:00 Add Semigroup/Monoid for Q (#18123) - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Driver.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/TyCo/Ppr.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Runtime/Debugger.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d002d9aefdf381e8f8184e2ab60f1a5532574c8a...611d3111708142bfe42283a14d1017cbae70592d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d002d9aefdf381e8f8184e2ab60f1a5532574c8a...611d3111708142bfe42283a14d1017cbae70592d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 1 18:12:43 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Fri, 01 May 2020 14:12:43 -0400 Subject: [Git][ghc/ghc][wip/osa1/lfinfo] 7 commits: Use platform in Iface Binary Message-ID: <5eac669b13c8e_616711ab08a483758cf@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/lfinfo at Glasgow Haskell Compiler / GHC Commits: 780de9e1 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Use platform in Iface Binary - - - - - f8386c7b by Sylvain Henry at 2020-05-01T10:37:39-04:00 Refactor PprDebug handling If `-dppr-debug` is set, then PprUser and PprDump styles are silently replaced with PprDebug style. This was done in `mkUserStyle` and `mkDumpStyle` smart constructors. As a consequence they needed a DynFlags parameter. Now we keep the original PprUser and PprDump styles until they are used to create an `SDocContext`. I.e. the substitution is only performed in `initSDocContext`. - - - - - b3df9e78 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Remove PprStyle param of logging actions Use `withPprStyle` instead to apply a specific style to a SDoc. - - - - - de9fc995 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Fully remove PprDebug PprDebug was a pain to deal with consistently as it is implied by `-dppr-debug` but it isn't really a PprStyle. We remove it completely and query the appropriate SDoc flag instead (`sdocPprDebug`) via helpers (`getPprDebug` and its friends). - - - - - 8b51fcbd by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Only call checkSingle if we would report warnings - - - - - fd7ea0fe by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 0340b080 by Ömer Sinan Ağacan at 2020-05-01T21:12:19+03:00 Cross-module LambdaFormInfo passing - Store LambdaFormInfos of exported Ids in interface files - Use them in importing modules This is for optimization purposes: if we know LambdaFormInfo of imported Ids we can generate more efficient calling code, see `getCallMethod`. Exporting (putting them in interface files or in ModDetails) and importing (reading them from interface files) are both optional. We don't assume known LambdaFormInfos anywhere and do not change how we call Ids with unknown LambdaFormInfos. Runtime, allocation, and residency numbers when building Cabal-the-library (commit 0d4ee7ba3). (Log and .hp files are in the MR: !2842) Runtime: | | GHC HEAD | This patch | Diff | |-----|----------|------------|----------------| | -O0 | 0:35.70 | 0:34.75 | -0.95s, -2.66% | | -O1 | 2:25.21 | 2:25.16 | -0.05s, -0.03% | | -O2 | 2:52.89 | 2:51.25 | -1.63s, -0.9% | Allocations: | | GHC HEAD | This patch | Diff | |-----|-----------------|-----------------|----------------------| | -O0 | 54,872,673,008 | 54,917,849,488 | +45,176,480, +0.08% | | -O1 | 227,080,315,016 | 227,584,483,224 | +504,168,208, +0.22% | | -O2 | 266,085,969,832 | 266,710,115,472 | +624,145,640, +0.23% | Max. residency: NOTE: Residency is measured with extra runtime args: `-i0 -h` which effectively turn all GCs into major GCs, and do GC more often. | | GHC HEAD | This patch | Diff | |-----|----------------------------|------------------------------|----------------------| | -O0 | 416,350,080 (894 samples) | 417,733,152 (892 samples) | +1,383,072, +0.33% | | -O1 | 928,484,840 (2101 samples) | 945,624,664 (2098 samples) | +17,139,824, +1.84% | | -O2 | 991,311,896 (2548 samples) | 1,010,647,088 (2536 samples) | +19,335,192, +1.95% | NoFib results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS 0.0% 0.0% +0.0% +0.0% +0.0% CSD 0.0% 0.0% 0.0% +0.0% +0.0% FS 0.0% 0.0% +0.0% +0.0% +0.0% S 0.0% 0.0% +0.0% +0.0% +0.0% VS 0.0% 0.0% +0.0% +0.0% +0.0% VSD 0.0% 0.0% +0.0% +0.0% +0.1% VSM 0.0% 0.0% +0.0% +0.0% +0.0% anna 0.0% 0.0% -0.3% -0.8% -0.0% ansi 0.0% 0.0% -0.0% -0.0% 0.0% atom 0.0% 0.0% -0.0% -0.0% 0.0% awards 0.0% 0.0% -0.1% -0.3% 0.0% banner 0.0% 0.0% -0.0% -0.0% -0.0% bernouilli 0.0% 0.0% -0.0% -0.0% -0.0% binary-trees 0.0% 0.0% -0.0% -0.0% +0.0% boyer 0.0% 0.0% -0.0% -0.0% 0.0% boyer2 0.0% 0.0% -0.0% -0.0% 0.0% bspt 0.0% 0.0% -0.0% -0.2% 0.0% cacheprof 0.0% 0.0% -0.1% -0.4% +0.0% calendar 0.0% 0.0% -0.0% -0.0% 0.0% cichelli 0.0% 0.0% -0.9% -2.4% 0.0% circsim 0.0% 0.0% -0.0% -0.0% 0.0% clausify 0.0% 0.0% -0.1% -0.3% 0.0% comp_lab_zift 0.0% 0.0% -0.0% -0.0% +0.0% compress 0.0% 0.0% -0.0% -0.0% -0.0% compress2 0.0% 0.0% -0.0% -0.0% 0.0% constraints 0.0% 0.0% -0.1% -0.2% -0.0% cryptarithm1 0.0% 0.0% -0.0% -0.0% 0.0% cryptarithm2 0.0% 0.0% -1.4% -4.1% -0.0% cse 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e1 0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e2 0.0% 0.0% -0.0% -0.0% -0.0% dom-lt 0.0% 0.0% -0.1% -0.2% 0.0% eliza 0.0% 0.0% -0.5% -1.5% 0.0% event 0.0% 0.0% -0.0% -0.0% -0.0% exact-reals 0.0% 0.0% -0.1% -0.3% +0.0% exp3_8 0.0% 0.0% -0.0% -0.0% -0.0% expert 0.0% 0.0% -0.3% -1.0% -0.0% fannkuch-redux 0.0% 0.0% +0.0% +0.0% +0.0% fasta 0.0% 0.0% -0.0% -0.0% +0.0% fem 0.0% 0.0% -0.0% -0.0% 0.0% fft 0.0% 0.0% -0.0% -0.0% 0.0% fft2 0.0% 0.0% -0.0% -0.0% 0.0% fibheaps 0.0% 0.0% -0.0% -0.0% +0.0% fish 0.0% 0.0% 0.0% -0.0% +0.0% fluid 0.0% 0.0% -0.4% -1.2% +0.0% fulsom 0.0% 0.0% -0.0% -0.0% 0.0% gamteb 0.0% 0.0% -0.1% -0.3% 0.0% gcd 0.0% 0.0% -0.0% -0.0% 0.0% gen_regexps 0.0% 0.0% -0.0% -0.0% -0.0% genfft 0.0% 0.0% -0.0% -0.0% 0.0% gg 0.0% 0.0% -0.0% -0.0% +0.0% grep 0.0% 0.0% -0.0% -0.0% -0.0% hidden 0.0% 0.0% -0.1% -0.4% -0.0% hpg 0.0% 0.0% -0.2% -0.5% +0.0% ida 0.0% 0.0% -0.0% -0.0% +0.0% infer 0.0% 0.0% -0.3% -0.8% -0.0% integer 0.0% 0.0% -0.0% -0.0% +0.0% integrate 0.0% 0.0% -0.0% -0.0% 0.0% k-nucleotide 0.0% 0.0% -0.0% -0.0% +0.0% kahan 0.0% 0.0% -0.0% -0.0% +0.0% knights 0.0% 0.0% -2.2% -5.4% 0.0% lambda 0.0% 0.0% -0.6% -1.8% 0.0% last-piece 0.0% 0.0% -0.0% -0.0% 0.0% lcss 0.0% 0.0% -0.0% -0.1% 0.0% life 0.0% 0.0% -0.0% -0.1% 0.0% lift 0.0% 0.0% -0.2% -0.6% +0.0% linear 0.0% 0.0% -0.0% -0.0% -0.0% listcompr 0.0% 0.0% -0.0% -0.0% 0.0% listcopy 0.0% 0.0% -0.0% -0.0% 0.0% maillist 0.0% 0.0% -0.1% -0.3% +0.0% mandel 0.0% 0.0% -0.0% -0.0% 0.0% mandel2 0.0% 0.0% -0.0% -0.0% -0.0% mate +0.0% 0.0% -0.0% -0.0% -0.0% minimax 0.0% 0.0% -0.2% -1.0% 0.0% mkhprog 0.0% 0.0% -0.1% -0.2% -0.0% multiplier 0.0% 0.0% -0.0% -0.0% -0.0% n-body 0.0% 0.0% -0.0% -0.0% +0.0% nucleic2 0.0% 0.0% -0.1% -0.2% 0.0% para 0.0% 0.0% -0.0% -0.0% -0.0% paraffins 0.0% 0.0% -0.0% -0.0% 0.0% parser 0.0% 0.0% -0.2% -0.7% 0.0% parstof 0.0% 0.0% -0.0% -0.0% +0.0% pic 0.0% 0.0% -0.0% -0.0% 0.0% pidigits 0.0% 0.0% +0.0% +0.0% +0.0% power 0.0% 0.0% -0.2% -0.6% +0.0% pretty 0.0% 0.0% -0.0% -0.0% -0.0% primes 0.0% 0.0% -0.0% -0.0% 0.0% primetest 0.0% 0.0% -0.0% -0.0% -0.0% prolog 0.0% 0.0% -0.3% -1.1% 0.0% puzzle 0.0% 0.0% -0.0% -0.0% 0.0% queens 0.0% 0.0% -0.0% -0.0% +0.0% reptile 0.0% 0.0% -0.0% -0.0% 0.0% reverse-complem 0.0% 0.0% -0.0% -0.0% +0.0% rewrite 0.0% 0.0% -0.7% -2.5% -0.0% rfib 0.0% 0.0% -0.0% -0.0% 0.0% rsa 0.0% 0.0% -0.0% -0.0% 0.0% scc 0.0% 0.0% -0.1% -0.2% -0.0% sched 0.0% 0.0% -0.0% -0.0% -0.0% scs 0.0% 0.0% -1.0% -2.6% +0.0% simple 0.0% 0.0% +0.0% -0.0% +0.0% solid 0.0% 0.0% -0.0% -0.0% 0.0% sorting 0.0% 0.0% -0.6% -1.6% 0.0% spectral-norm 0.0% 0.0% +0.0% 0.0% +0.0% sphere 0.0% 0.0% -0.0% -0.0% -0.0% symalg 0.0% 0.0% -0.0% -0.0% +0.0% tak 0.0% 0.0% -0.0% -0.0% 0.0% transform 0.0% 0.0% -0.0% -0.0% 0.0% treejoin 0.0% 0.0% -0.0% -0.0% 0.0% typecheck 0.0% 0.0% -0.0% -0.0% +0.0% veritas +0.0% 0.0% -0.2% -0.4% +0.0% wang 0.0% 0.0% -0.0% -0.0% 0.0% wave4main 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 0.0% 0.0% -0.0% -0.0% +0.0% x2n1 0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min 0.0% 0.0% -2.2% -5.4% -0.0% Max +0.0% 0.0% +0.0% +0.0% +0.1% Geometric Mean -0.0% -0.0% -0.1% -0.3% +0.0% Metric increases micro benchmarks tracked in #17686: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 Co-authored-by: Andreas Klebinger <klebinger.andreas at gmx.at> - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Driver.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/TyCo/Ppr.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Load.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0ba1d26ac9da8ff25bf6de590997cb7791d4f764...0340b080e58e9119050d8b3b6ae344406b1a0cdc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0ba1d26ac9da8ff25bf6de590997cb7791d4f764...0340b080e58e9119050d8b3b6ae344406b1a0cdc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 2 16:23:40 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Sat, 02 May 2020 12:23:40 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T16758 Message-ID: <5ead9e8c7787d_61673f81cd4c695c8418142@gitlab.haskell.org.mail> Ryan Scott pushed new branch wip/T16758 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T16758 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 2 16:39:08 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Sat, 02 May 2020 12:39:08 -0400 Subject: [Git][ghc/ghc][wip/T16758] Unmark T16758 as expect_broken Message-ID: <5eada22c391d2_6167e5b152c8424628@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T16758 at Glasgow Haskell Compiler / GHC Commits: 648e5207 by Ryan Scott at 2020-05-02T12:37:29-04:00 Unmark T16758 as expect_broken Commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70 fixes #16758. Accordingly, this patch removes the `expect_broken` label from the `T16758` test case, moves it from `should_compile` to `should_fail` (as it should produce an error message), and checks in the expected stderr. - - - - - 4 changed files: - testsuite/tests/saks/should_compile/all.T - testsuite/tests/saks/should_compile/T16758.hs → testsuite/tests/saks/should_fail/T16758.hs - + testsuite/tests/saks/should_fail/T16758.stderr - testsuite/tests/saks/should_fail/all.T Changes: ===================================== testsuite/tests/saks/should_compile/all.T ===================================== @@ -34,7 +34,6 @@ test('T16723', normal, compile, ['']) test('T16724', extra_files(['T16724.hs']), ghci_script, ['T16724.script']) test('T16726', normal, compile, ['']) test('T16731', normal, compile, ['']) -test('T16758', expect_broken(16758), compile, ['']) test('T16721', normal, ghci_script, ['T16721.script']) test('T16756a', normal, compile, ['']) ===================================== testsuite/tests/saks/should_compile/T16758.hs → testsuite/tests/saks/should_fail/T16758.hs ===================================== ===================================== testsuite/tests/saks/should_fail/T16758.stderr ===================================== @@ -0,0 +1,8 @@ + +T16758.hs:14:8: error: + • Couldn't match expected kind ‘Int’ with actual kind ‘a’ + ‘a’ is a rigid type variable bound by + the class declaration for ‘C’ + at T16758.hs:12:19 + • In the type signature: f :: C a => a -> Int + In the class declaration for ‘C’ ===================================== testsuite/tests/saks/should_fail/all.T ===================================== @@ -30,3 +30,4 @@ test('T16727b', normal, compile_fail, ['']) test('T16725', normal, compile_fail, ['']) test('T16826', normal, compile_fail, ['']) test('T16756b', normal, compile_fail, ['']) +test('T16758', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/648e5207ba549b25d2cf846e301e0b9b3b3f8cfa -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/648e5207ba549b25d2cf846e301e0b9b3b3f8cfa You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 2 19:15:19 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Sat, 02 May 2020 15:15:19 -0400 Subject: [Git][ghc/ghc][wip/T16758] Add regression tests for #16244, #16245, #16758 Message-ID: <5eadc6c7cafdb_61673f81cc913ba084488e@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T16758 at Glasgow Haskell Compiler / GHC Commits: 01dd8c76 by Ryan Scott at 2020-05-02T15:12:12-04:00 Add regression tests for #16244, #16245, #16758 Commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70 ended up fixing quite a few bugs: * This commit fixes #16244 completely. A regression test has been added. * This commit fixes one program from #16245. (The program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211369 still panics, and the program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211400 still loops infinitely.) A regression test has been added for this program. * This commit fixes #16758. Accordingly, this patch removes the `expect_broken` label from the `T16758` test case, moves it from `should_compile` to `should_fail` (as it should produce an error message), and checks in the expected stderr. - - - - - 9 changed files: - + testsuite/tests/polykinds/T16244.hs - + testsuite/tests/polykinds/T16244.stderr - + testsuite/tests/polykinds/T16245.hs - + testsuite/tests/polykinds/T16245.stderr - testsuite/tests/polykinds/all.T - testsuite/tests/saks/should_compile/all.T - testsuite/tests/saks/should_compile/T16758.hs → testsuite/tests/saks/should_fail/T16758.hs - + testsuite/tests/saks/should_fail/T16758.stderr - testsuite/tests/saks/should_fail/all.T Changes: ===================================== testsuite/tests/polykinds/T16244.hs ===================================== @@ -0,0 +1,11 @@ +{-# LANGUAGE ConstraintKinds #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE PolyKinds #-} +module T16244 where + +import Data.Kind + +type Const a b = a +type SameKind (a :: k) (b :: k) = (() :: Constraint) +class SameKind a b => C (k :: Const Type a) (b :: k) ===================================== testsuite/tests/polykinds/T16244.stderr ===================================== @@ -0,0 +1,11 @@ + +T16244.hs:11:18: error: + • Couldn't match kind ‘k1’ with ‘k’ + ‘k1’ is a rigid type variable bound by + the class declaration for ‘C’ + at T16244.hs:11:26 + ‘k’ is a rigid type variable bound by + the class declaration for ‘C’ + at T16244.hs:11:1-52 + • In the second argument of ‘SameKind’, namely ‘b’ + In the class declaration for ‘C’ ===================================== testsuite/tests/polykinds/T16245.hs ===================================== @@ -0,0 +1,11 @@ +{-# LANGUAGE ConstraintKinds #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE QuantifiedConstraints #-} +module T16245 where + +import Data.Kind + +type Const a b = a +type SameKind (a :: k) (b :: k) = (() :: Constraint) +class (forall (b :: k). SameKind a b) => C (k :: Const Type a) ===================================== testsuite/tests/polykinds/T16245.stderr ===================================== @@ -0,0 +1,11 @@ + +T16245.hs:11:36: error: + • Couldn't match kind ‘k1’ with ‘k’ + ‘k1’ is a rigid type variable bound by + the class declaration for ‘C’ + at T16245.hs:11:45 + ‘k’ is a rigid type variable bound by + the class declaration for ‘C’ + at T16245.hs:11:1-62 + • In the second argument of ‘SameKind’, namely ‘b’ + In the class declaration for ‘C’ ===================================== testsuite/tests/polykinds/all.T ===================================== @@ -211,6 +211,8 @@ test('T16247a', normal, compile_fail, ['']) test('KindVarOrder', normal, ghci_script, ['KindVarOrder.script']) test('T16221', normal, compile, ['']) test('T16221a', normal, compile_fail, ['']) +test('T16244', normal, compile_fail, ['']) +test('T16245', normal, compile_fail, ['']) test('T16342', normal, compile, ['']) test('T16263', normal, compile_fail, ['']) test('T16902', normal, compile_fail, ['']) ===================================== testsuite/tests/saks/should_compile/all.T ===================================== @@ -34,7 +34,6 @@ test('T16723', normal, compile, ['']) test('T16724', extra_files(['T16724.hs']), ghci_script, ['T16724.script']) test('T16726', normal, compile, ['']) test('T16731', normal, compile, ['']) -test('T16758', expect_broken(16758), compile, ['']) test('T16721', normal, ghci_script, ['T16721.script']) test('T16756a', normal, compile, ['']) ===================================== testsuite/tests/saks/should_compile/T16758.hs → testsuite/tests/saks/should_fail/T16758.hs ===================================== ===================================== testsuite/tests/saks/should_fail/T16758.stderr ===================================== @@ -0,0 +1,8 @@ + +T16758.hs:14:8: error: + • Couldn't match expected kind ‘Int’ with actual kind ‘a’ + ‘a’ is a rigid type variable bound by + the class declaration for ‘C’ + at T16758.hs:12:19 + • In the type signature: f :: C a => a -> Int + In the class declaration for ‘C’ ===================================== testsuite/tests/saks/should_fail/all.T ===================================== @@ -30,3 +30,4 @@ test('T16727b', normal, compile_fail, ['']) test('T16725', normal, compile_fail, ['']) test('T16826', normal, compile_fail, ['']) test('T16756b', normal, compile_fail, ['']) +test('T16758', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/01dd8c760a2662400e9d1d9f6fd41f320b90721b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/01dd8c760a2662400e9d1d9f6fd41f320b90721b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 2 20:40:17 2020 From: gitlab at gitlab.haskell.org (Richard Eisenberg) Date: Sat, 02 May 2020 16:40:17 -0400 Subject: [Git][ghc/ghc][wip/hole-refactor] Refactor hole constraints. Message-ID: <5eaddab14d3ce_6167c5ce1b0845779a@gitlab.haskell.org.mail> Richard Eisenberg pushed to branch wip/hole-refactor at Glasgow Haskell Compiler / GHC Commits: 57d2bba3 by Richard Eisenberg at 2020-05-01T16:37:38+00:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. - - - - - 18 changed files: - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Errors/Hole.hs-boot - compiler/GHC/Tc/Errors/Hole/FitTypes.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Rule.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/Solver/Canonical.hs - compiler/GHC/Tc/Solver/Flatten.hs - compiler/GHC/Tc/Solver/Interact.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Types/Constraint.hs - compiler/GHC/Tc/Types/Origin.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Tc/Utils/TcMType.hs Changes: ===================================== compiler/GHC/HsToCore/PmCheck/Oracle.hs ===================================== @@ -438,7 +438,7 @@ then newtypes. (b) dcs is the list of newtype constructors "skipped", every time we normalise a newtype to its core representation, we keep track of the source data - constructor. For convenienve, we also track the type we unwrap and the + constructor. For convenience, we also track the type we unwrap and the type of its field. Example: @Down 42@ => @[(Down @Int, Down, Int)] (c) core_ty is the rewritten type. That is, pmTopNormaliseType env ty_cs ty = Just (src_ty, dcs, core_ty) ===================================== compiler/GHC/Tc/Errors.hs ===================================== @@ -285,8 +285,8 @@ important :: SDoc -> Report important doc = mempty { report_important = [doc] } -- | Put a doc into the relevant bindings block. -relevant_bindings :: SDoc -> Report -relevant_bindings doc = mempty { report_relevant_bindings = [doc] } +mk_relevant_bindings :: SDoc -> Report +mk_relevant_bindings doc = mempty { report_relevant_bindings = [doc] } -- | Put a doc into the valid hole fits block. valid_hole_fits :: SDoc -> Report @@ -524,16 +524,29 @@ This only matters in instance declarations.. -} reportWanteds :: ReportErrCtxt -> TcLevel -> WantedConstraints -> TcM () -reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) +reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics + , wc_holes = holes }) = do { traceTc "reportWanteds" (vcat [ text "Simples =" <+> ppr simples - , text "Suppress =" <+> ppr (cec_suppress ctxt)]) - ; traceTc "rw2" (ppr tidy_cts) - - -- First deal with things that are utterly wrong + , text "Suppress =" <+> ppr (cec_suppress ctxt) + , text "tidy_cts =" <+> ppr tidy_cts + , text "tidy_holes = " <+> ppr tidy_holes ]) + + -- First, deal with any out-of-scope errors: + ; let (out_of_scope, other_holes) = partition isOutOfScopeHole tidy_holes + -- don't suppress out-of-scope errors + ctxt_for_scope_errs = ctxt { cec_suppress = False } + ; (_, no_out_of_scope) <- askNoErrs $ + reportHoles tidy_cts ctxt_for_scope_errs out_of_scope + + -- Next, deal with things that are utterly wrong -- Like Int ~ Bool (incl nullary TyCons) -- or Int ~ t a (AppTy on one side) -- These /ones/ are not suppressed by the incoming context - ; let ctxt_for_insols = ctxt { cec_suppress = False } + -- (but will be by out-of-scope errors) + ; let ctxt_for_insols = ctxt { cec_suppress = not no_out_of_scope } + ; reportHoles tidy_cts ctxt_for_insols other_holes + -- holes never suppress + ; (ctxt1, cts1) <- tryReporters ctxt_for_insols report1 tidy_cts -- Now all the other constraints. We suppress errors here if @@ -554,7 +567,8 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) -- if there's a *given* insoluble here (= inaccessible code) where env = cec_tidy ctxt - tidy_cts = bagToList (mapBag (tidyCt env) simples) + tidy_cts = bagToList (mapBag (tidyCt env) simples) + tidy_holes = bagToList (mapBag (tidyHole env) holes) -- report1: ones that should *not* be suppressed by -- an insoluble somewhere else in the tree @@ -562,9 +576,7 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) -- (see GHC.Tc.Utils.insolubleCt) is caught here, otherwise -- we might suppress its error message, and proceed on past -- type checking to get a Lint error later - report1 = [ ("Out of scope", unblocked is_out_of_scope, True, mkHoleReporter tidy_cts) - , ("Holes", unblocked is_hole, False, mkHoleReporter tidy_cts) - , ("custom_error", unblocked is_user_type_error, True, mkUserTypeErrorReporter) + report1 = [ ("custom_error", unblocked is_user_type_error, True, mkUserTypeErrorReporter) , given_eq_spec , ("insoluble2", unblocked utterly_wrong, True, mkGroupReporter mkEqErr) @@ -593,8 +605,7 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) unblocked checker ct pred = checker ct pred -- rigid_nom_eq, rigid_nom_tv_eq, - is_hole, is_dict, - is_equality, is_ip, is_irred :: Ct -> Pred -> Bool + is_dict, is_equality, is_ip, is_irred :: Ct -> Pred -> Bool is_given_eq ct pred | EqPred {} <- pred = arisesFromGivens ct @@ -617,9 +628,6 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) non_tv_eq _ (EqPred NomEq ty1 _) = not (isTyVarTy ty1) non_tv_eq _ _ = False - is_out_of_scope ct _ = isOutOfScopeCt ct - is_hole ct _ = isHoleCt ct - is_user_type_error ct _ = isUserTypeErrorCt ct is_homo_equality _ (EqPred _ ty1 ty2) = tcTypeKind ty1 `tcEqType` tcTypeKind ty2 @@ -705,12 +713,12 @@ mkSkolReporter ctxt cts | eq_lhs_type ct1 ct2 = True | otherwise = False -mkHoleReporter :: [Ct] -> Reporter --- Reports errors one at a time -mkHoleReporter tidy_simples ctxt - = mapM_ $ \ct -> do { err <- mkHoleError tidy_simples ctxt ct - ; maybeReportHoleError ctxt ct err - ; maybeAddDeferredHoleBinding ctxt err ct } +reportHoles :: [Ct] -- other (tidied) constraints + -> ReportErrCtxt -> [Hole] -> TcM () +reportHoles tidy_cts ctxt + = mapM_ $ \hole -> do { err <- mkHoleError tidy_cts ctxt hole + ; maybeReportHoleError ctxt hole err + ; maybeAddDeferredHoleBinding ctxt err hole } mkUserTypeErrorReporter :: Reporter mkUserTypeErrorReporter ctxt @@ -742,7 +750,7 @@ mkGivenErrorReporter ctxt cts inaccessible_msg = hang (text "Inaccessible code in") 2 (ppr (ic_info implic)) report = important inaccessible_msg `mappend` - relevant_bindings binds_msg + mk_relevant_bindings binds_msg ; err <- mkEqErr_help dflags ctxt report ct' Nothing ty1 ty2 @@ -843,15 +851,27 @@ suppressGroup mk_err ctxt cts ; traceTc "Suppressing errors for" (ppr cts) ; mapM_ (addDeferredBinding ctxt err) cts } -maybeReportHoleError :: ReportErrCtxt -> Ct -> ErrMsg -> TcM () +maybeReportHoleError :: ReportErrCtxt -> Hole -> ErrMsg -> TcM () +maybeReportHoleError ctxt hole err + | isOutOfScopeHole hole + -- Always report an error for out-of-scope variables + -- Unless -fdefer-out-of-scope-variables is on, + -- in which case the messages are discarded. + -- See #12170, #12406 + = -- If deferring, report a warning only if -Wout-of-scope-variables is on + case cec_out_of_scope_holes ctxt of + HoleError -> reportError err + HoleWarn -> + reportWarning (Reason Opt_WarnDeferredOutOfScopeVariables) err + HoleDefer -> return () + -- Unlike maybeReportError, these "hole" errors are -- /not/ suppressed by cec_suppress. We want to see them! -maybeReportHoleError ctxt ct err +maybeReportHoleError ctxt (Hole { hole_sort = TypeHole }) err -- When -XPartialTypeSignatures is on, warnings (instead of errors) are -- generated for holes in partial type signatures. -- Unless -fwarn-partial-type-signatures is not on, -- in which case the messages are discarded. - | isTypeHoleCt ct = -- For partial type signatures, generate warnings only, and do that -- only if -fwarn-partial-type-signatures is on case cec_type_holes ctxt of @@ -859,22 +879,12 @@ maybeReportHoleError ctxt ct err HoleWarn -> reportWarning (Reason Opt_WarnPartialTypeSignatures) err HoleDefer -> return () - -- Always report an error for out-of-scope variables - -- Unless -fdefer-out-of-scope-variables is on, - -- in which case the messages are discarded. - -- See #12170, #12406 - | isOutOfScopeCt ct - = -- If deferring, report a warning only if -Wout-of-scope-variables is on - case cec_out_of_scope_holes ctxt of - HoleError -> reportError err - HoleWarn -> - reportWarning (Reason Opt_WarnDeferredOutOfScopeVariables) err - HoleDefer -> return () - +maybeReportHoleError ctxt hole@(Hole { hole_sort = ExprHole _ }) err -- Otherwise this is a typed hole in an expression, - -- but not for an out-of-scope variable - | otherwise + -- but not for an out-of-scope variable (because that goes through a + -- different function) = -- If deferring, report a warning only if -Wtyped-holes is on + ASSERT( not (isOutOfScopeHole hole) ) case cec_expr_holes ctxt of HoleError -> reportError err HoleWarn -> reportWarning (Reason Opt_WarnTypedHoles) err @@ -899,10 +909,7 @@ addDeferredBinding ctxt err ct , CtWanted { ctev_pred = pred, ctev_dest = dest } <- ctEvidence ct -- Only add deferred bindings for Wanted constraints = do { dflags <- getDynFlags - ; let err_msg = pprLocErrMsg err - err_fs = mkFastString $ showSDoc dflags $ - err_msg $$ text "(deferred type error)" - err_tm = evDelayedError pred err_fs + ; let err_tm = mkErrorTerm dflags pred err ev_binds_var = cec_binds ctxt ; case dest of @@ -917,11 +924,27 @@ addDeferredBinding ctxt err ct | otherwise -- Do not set any evidence for Given/Derived = return () -maybeAddDeferredHoleBinding :: ReportErrCtxt -> ErrMsg -> Ct -> TcM () -maybeAddDeferredHoleBinding ctxt err ct - | isExprHoleCt ct - = addDeferredBinding ctxt err ct -- Only add bindings for holes in expressions - | otherwise -- not for holes in partial type signatures +mkErrorTerm :: DynFlags -> Type -- of the error term + -> ErrMsg -> EvTerm +mkErrorTerm dflags ty err = evDelayedError ty err_fs + where + err_msg = pprLocErrMsg err + err_fs = mkFastString $ showSDoc dflags $ + err_msg $$ text "(deferred type error)" +maybeAddDeferredHoleBinding :: ReportErrCtxt -> ErrMsg -> Hole -> TcM () +maybeAddDeferredHoleBinding ctxt err (Hole { hole_sort = ExprHole ev_id }) +-- Only add bindings for holes in expressions +-- not for holes in partial type signatures +-- cf. addDeferredBinding + | deferringAnyBindings ctxt + = do { dflags <- getDynFlags + ; let err_tm = mkErrorTerm dflags (idType ev_id) err + -- NB: idType ev_id, not hole_ty. hole_ty might be rewritten. + -- See Note [Holes] in GHC.Tc.Types.Constraint + ; addTcEvBind (cec_binds ctxt) $ mkWantedEvBind ev_id err_tm } + | otherwise + = return () +maybeAddDeferredHoleBinding _ _ (Hole { hole_sort = TypeHole }) = return () tryReporters :: ReportErrCtxt -> [ReporterSpec] -> [Ct] -> TcM (ReportErrCtxt, [Ct]) @@ -961,7 +984,6 @@ tryReporter ctxt (str, keep_me, suppress_after, reporter) cts where (yeses, nos) = partition (\ct -> keep_me ct (classifyPredType (ctPred ct))) cts - pprArising :: CtOrigin -> SDoc -- Used for the main, top-level error message -- We've done special processing for TypeEq, KindEq, Given @@ -1104,15 +1126,16 @@ mkIrredErr ctxt cts ; let orig = ctOrigin ct1 msg = couldNotDeduce (getUserGivens ctxt) (map ctPred cts, orig) ; mkErrorMsgFromCt ctxt ct1 $ - important msg `mappend` relevant_bindings binds_msg } + important msg `mappend` mk_relevant_bindings binds_msg } where (ct1:_) = cts ---------------- -mkHoleError :: [Ct] -> ReportErrCtxt -> Ct -> TcM ErrMsg -mkHoleError tidy_simples ctxt ct@(CHoleCan { cc_occ = occ, cc_hole = hole_sort }) - | isOutOfScopeCt ct -- Out of scope variables, like 'a', where 'a' isn't bound - -- Suggest possible in-scope variables in the message +mkHoleError :: [Ct] -> ReportErrCtxt -> Hole -> TcM ErrMsg +mkHoleError _tidy_simples _ctxt hole@(Hole { hole_occ = occ + , hole_ty = hole_ty + , hole_loc = ct_loc }) + | isOutOfScopeHole hole = do { dflags <- getDynFlags ; rdr_env <- getGlobalRdrEnv ; imp_info <- getImports @@ -1122,48 +1145,52 @@ mkHoleError tidy_simples ctxt ct@(CHoleCan { cc_occ = occ, cc_hole = hole_sort } errDoc [out_of_scope_msg] [] [unknownNameSuggestions dflags hpt curr_mod rdr_env (tcl_rdr lcl_env) imp_info (mkRdrUnqual occ)] } + where + herald | isDataOcc occ = text "Data constructor not in scope:" + | otherwise = text "Variable not in scope:" - | otherwise -- Explicit holes, like "_" or "_f" - = do { (ctxt, binds_msg, ct) <- relevantBindings False ctxt ct + out_of_scope_msg -- Print v :: ty only if the type has structure + | boring_type = hang herald 2 (ppr occ) + | otherwise = hang herald 2 (pp_occ_with_type occ hole_ty) + + lcl_env = ctLocEnv ct_loc + boring_type = isTyVarTy hole_ty + + -- general case: not an out-of-scope error +mkHoleError tidy_simples ctxt hole@(Hole { hole_occ = occ + , hole_ty = hole_ty + , hole_sort = sort + , hole_loc = ct_loc }) + = do { (ctxt, binds_msg) + <- relevant_bindings False ctxt lcl_env (tyCoVarsOfType hole_ty) -- The 'False' means "don't filter the bindings"; see Trac #8191 ; show_hole_constraints <- goptM Opt_ShowHoleConstraints ; let constraints_msg - | isExprHoleCt ct, show_hole_constraints + | ExprHole _ <- sort, show_hole_constraints = givenConstraintsMsg ctxt | otherwise = empty ; show_valid_hole_fits <- goptM Opt_ShowValidHoleFits ; (ctxt, sub_msg) <- if show_valid_hole_fits - then validHoleFits ctxt tidy_simples ct + then validHoleFits ctxt tidy_simples hole else return (ctxt, empty) - ; mkErrorMsgFromCt ctxt ct $ + ; mkErrorReport ctxt lcl_env $ important hole_msg `mappend` - relevant_bindings (binds_msg $$ constraints_msg) `mappend` + mk_relevant_bindings (binds_msg $$ constraints_msg) `mappend` valid_hole_fits sub_msg } where - ct_loc = ctLoc ct lcl_env = ctLocEnv ct_loc - hole_ty = ctEvPred (ctEvidence ct) hole_kind = tcTypeKind hole_ty tyvars = tyCoVarsOfTypeList hole_ty - boring_type = isTyVarTy hole_ty - - out_of_scope_msg -- Print v :: ty only if the type has structure - | boring_type = hang herald 2 (ppr occ) - | otherwise = hang herald 2 pp_with_type - pp_with_type = hang (pprPrefixOcc occ) 2 (dcolon <+> pprType hole_ty) - herald | isDataOcc occ = text "Data constructor not in scope:" - | otherwise = text "Variable not in scope:" - - hole_msg = case hole_sort of - ExprHole -> vcat [ hang (text "Found hole:") - 2 pp_with_type - , tyvars_msg, expr_hole_hint ] + hole_msg = case sort of + ExprHole _ -> vcat [ hang (text "Found hole:") + 2 (pp_occ_with_type occ hole_ty) + , tyvars_msg, expr_hole_hint ] TypeHole -> vcat [ hang (text "Found type wildcard" <+> quotes (ppr occ)) 2 (text "standing for" <+> quotes pp_hole_type_with_kind) , tyvars_msg, type_hole_hint ] @@ -1207,21 +1234,22 @@ mkHoleError tidy_simples ctxt ct@(CHoleCan { cc_occ = occ, cc_hole = hole_sort } = ppWhenOption sdocPrintExplicitCoercions $ quotes (ppr tv) <+> text "is a coercion variable" -mkHoleError _ _ ct = pprPanic "mkHoleError" (ppr ct) +pp_occ_with_type :: OccName -> Type -> SDoc +pp_occ_with_type occ hole_ty = hang (pprPrefixOcc occ) 2 (dcolon <+> pprType hole_ty) -- We unwrap the ReportErrCtxt here, to avoid introducing a loop in module -- imports validHoleFits :: ReportErrCtxt -- The context we're in, i.e. the -- implications and the tidy environment -> [Ct] -- Unsolved simple constraints - -> Ct -- The hole constraint. + -> Hole -- The hole -> TcM (ReportErrCtxt, SDoc) -- We return the new context -- with a possibly updated -- tidy environment, and -- the message. validHoleFits ctxt@(CEC {cec_encl = implics - , cec_tidy = lcl_env}) simps ct - = do { (tidy_env, msg) <- findValidHoleFits lcl_env implics simps ct + , cec_tidy = lcl_env}) simps hole + = do { (tidy_env, msg) <- findValidHoleFits lcl_env implics simps hole ; return (ctxt {cec_tidy = tidy_env}, msg) } -- See Note [Constraints include ...] @@ -1255,7 +1283,7 @@ mkIPErr ctxt cts = couldNotDeduce givens (preds, orig) ; mkErrorMsgFromCt ctxt ct1 $ - important msg `mappend` relevant_bindings binds_msg } + important msg `mappend` mk_relevant_bindings binds_msg } where (ct1:_) = cts @@ -1337,7 +1365,7 @@ mkEqErr1 ctxt ct -- Wanted or derived; ; dflags <- getDynFlags ; traceTc "mkEqErr1" (ppr ct $$ pprCtOrigin (ctOrigin ct) $$ ppr keep_going) ; let report = mconcat [important wanted_msg, important coercible_msg, - relevant_bindings binds_msg] + mk_relevant_bindings binds_msg] ; if keep_going then mkEqErr_help dflags ctxt report ct is_oriented ty1 ty2 else mkErrorMsgFromCt ctxt ct report } @@ -1513,7 +1541,7 @@ mkTyVarEqErr' dflags ctxt report ct oriented tv1 ty2 filter isTyVar $ fvVarList $ tyCoFVsOfType ty1 `unionFV` tyCoFVsOfType ty2 - extra3 = relevant_bindings $ + extra3 = mk_relevant_bindings $ ppWhen (not (null interesting_tyvars)) $ hang (text "Type variable kinds:") 2 $ vcat (map (tyvar_binding . tidyTyCoVarOcc (cec_tidy ctxt)) @@ -2819,27 +2847,45 @@ relevantBindings :: Bool -- True <=> filter by tyvar; False <=> no filtering -> TcM (ReportErrCtxt, SDoc, Ct) -- Also returns the zonked and tidied CtOrigin of the constraint relevantBindings want_filtering ctxt ct - = do { dflags <- getDynFlags + = do { traceTc "relevantBindings" (ppr ct) ; (env1, tidy_orig) <- zonkTidyOrigin (cec_tidy ctxt) (ctLocOrigin loc) - ; let ct_tvs = tyCoVarsOfCt ct `unionVarSet` extra_tvs -- For *kind* errors, report the relevant bindings of the -- enclosing *type* equality, because that's more useful for the programmer - extra_tvs = case tidy_orig of + ; let extra_tvs = case tidy_orig of KindEqOrigin t1 m_t2 _ _ -> tyCoVarsOfTypes $ t1 : maybeToList m_t2 _ -> emptyVarSet - ; traceTc "relevantBindings" $ - vcat [ ppr ct - , pprCtOrigin (ctLocOrigin loc) - , ppr ct_tvs + ct_fvs = tyCoVarsOfCt ct `unionVarSet` extra_tvs + + -- Put a zonked, tidied CtOrigin into the Ct + loc' = setCtLocOrigin loc tidy_orig + ct' = setCtLoc ct loc' + ctxt1 = ctxt { cec_tidy = env1 } + + ; (ctxt2, doc) <- relevant_bindings want_filtering ctxt1 lcl_env ct_fvs + ; return (ctxt2, doc, ct') } + where + loc = ctLoc ct + lcl_env = ctLocEnv loc + +-- slightly more general version, to work also with holes +relevant_bindings :: Bool + -> ReportErrCtxt + -> TcLclEnv + -> TyCoVarSet + -> TcM (ReportErrCtxt, SDoc) +relevant_bindings want_filtering ctxt lcl_env ct_tvs + = do { dflags <- getDynFlags + ; traceTc "relevant_bindings" $ + vcat [ ppr ct_tvs , pprWithCommas id [ ppr id <+> dcolon <+> ppr (idType id) | TcIdBndr id _ <- tcl_bndrs lcl_env ] , pprWithCommas id [ ppr id | TcIdBndr_ExpType id _ _ <- tcl_bndrs lcl_env ] ] ; (tidy_env', docs, discards) - <- go dflags env1 ct_tvs (maxRelevantBinds dflags) + <- go dflags (cec_tidy ctxt) (maxRelevantBinds dflags) emptyVarSet [] False (removeBindingShadowing $ tcl_bndrs lcl_env) -- tcl_bndrs has the innermost bindings first, @@ -2849,17 +2895,10 @@ relevantBindings want_filtering ctxt ct hang (text "Relevant bindings include") 2 (vcat docs $$ ppWhen discards discardMsg) - -- Put a zonked, tidied CtOrigin into the Ct - loc' = setCtLocOrigin loc tidy_orig - ct' = setCtLoc ct loc' ctxt' = ctxt { cec_tidy = tidy_env' } - ; return (ctxt', doc, ct') } + ; return (ctxt', doc) } where - ev = ctEvidence ct - loc = ctEvLoc ev - lcl_env = ctLocEnv loc - run_out :: Maybe Int -> Bool run_out Nothing = False run_out (Just n) = n <= 0 @@ -2868,14 +2907,14 @@ relevantBindings want_filtering ctxt ct dec_max = fmap (\n -> n - 1) - go :: DynFlags -> TidyEnv -> TcTyVarSet -> Maybe Int -> TcTyVarSet -> [SDoc] + go :: DynFlags -> TidyEnv -> Maybe Int -> TcTyVarSet -> [SDoc] -> Bool -- True <=> some filtered out due to lack of fuel -> [TcBinder] -> TcM (TidyEnv, [SDoc], Bool) -- The bool says if we filtered any out -- because of lack of fuel - go _ tidy_env _ _ _ docs discards [] + go _ tidy_env _ _ docs discards [] = return (tidy_env, reverse docs, discards) - go dflags tidy_env ct_tvs n_left tvs_seen docs discards (tc_bndr : tc_bndrs) + go dflags tidy_env n_left tvs_seen docs discards (tc_bndr : tc_bndrs) = case tc_bndr of TcTvBndr {} -> discard_it TcIdBndr id top_lvl -> go2 (idName id) (idType id) top_lvl @@ -2891,7 +2930,7 @@ relevantBindings want_filtering ctxt ct Nothing -> discard_it -- No info; discard } where - discard_it = go dflags tidy_env ct_tvs n_left tvs_seen docs + discard_it = go dflags tidy_env n_left tvs_seen docs discards tc_bndrs go2 id_name id_type top_lvl = do { (tidy_env', tidy_ty) <- zonkTidyTcType tidy_env id_type @@ -2916,12 +2955,12 @@ relevantBindings want_filtering ctxt ct else if run_out n_left && id_tvs `subVarSet` tvs_seen -- We've run out of n_left fuel and this binding only -- mentions already-seen type variables, so discard it - then go dflags tidy_env ct_tvs n_left tvs_seen docs + then go dflags tidy_env n_left tvs_seen docs True -- Record that we have now discarded something tc_bndrs -- Keep this binding, decrement fuel - else go dflags tidy_env' ct_tvs (dec_max n_left) new_seen + else go dflags tidy_env' (dec_max n_left) new_seen (doc:docs) discards tc_bndrs } ===================================== compiler/GHC/Tc/Errors/Hole.hs ===================================== @@ -2,17 +2,9 @@ {-# LANGUAGE ExistentialQuantification #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} module GHC.Tc.Errors.Hole - ( findValidHoleFits, tcFilterHoleFits - , tcCheckHoleFit, tcSubsumes - , withoutUnification - , fromPureHFPlugin - -- Re-exports for convenience - , hfIsLcl - , pprHoleFit, debugHoleFitDispConfig + ( findValidHoleFits -- Re-exported from GHC.Tc.Errors.Hole.FitTypes - , TypedHole (..), HoleFit (..), HoleFitCandidate (..) - , CandPlugin, FitPlugin , HoleFitPlugin (..), HoleFitPluginR (..) ) where @@ -121,7 +113,7 @@ The hole in `f` would generate the message: Valid hole fits are found by checking top level identifiers and local bindings in scope for whether their type can be instantiated to the the type of the hole. Additionally, we also need to check whether all relevant constraints are solved -by choosing an identifier of that type as well, see Note [Relevant Constraints] +by choosing an identifier of that type as well, see Note [Relevant constraints] Since checking for subsumption results in the side-effect of type variables being unified by the simplifier, we need to take care to restore them after @@ -143,9 +135,13 @@ that the quantified type variables would take if that fit is used, like If -XTypeApplications is enabled, this can even be copied verbatim as a replacement for the hole. - -Note [Nested implications] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Checking hole fits] +~~~~~~~~~~~~~~~~~~~~~~~~~ +If we have a hole of type hole_ty, we want to know whether a variable +of type ty is a valid fit for the whole. This is a subsumption check: +we wish to know whether ty <: hole_ty. But, of course, the check +must take into account any givens and relevant constraints. +(See also Note [Relevant constraints]). For the simplifier to be able to use any givens present in the enclosing implications to solve relevant constraints, we nest the wanted subsumption @@ -156,10 +152,7 @@ As an example, let's look at the following code: f :: Show a => a -> String f x = show _ -The hole will result in the hole constraint: - - [WD] __a1ph {0}:: a0_a1pd[tau:2] (CHoleCan: ExprHole(_)) - +Suppose the hole is assigned type a0_a1pd[tau:2]. Here the nested implications are just one level deep, namely: [Implic { @@ -170,36 +163,25 @@ Here the nested implications are just one level deep, namely: Given = $dShow_a1pc :: Show a_a1pa[sk:2] Wanted = WC {wc_simple = - [WD] __a1ph {0}:: a_a1pd[tau:2] (CHoleCan: ExprHole(_)) - [WD] $dShow_a1pe {0}:: Show a_a1pd[tau:2] (CDictCan(psc))} + [WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CDictCan(psc))} Binds = EvBindsVar Needed inner = [] Needed outer = [] the type signature for: f :: forall a. Show a => a -> String }] -As we can see, the givens say that the information about the skolem -`a_a1pa[sk:2]` fulfills the Show constraint. - -The simples are: +As we can see, the givens say that the skolem +`a_a1pa[sk:2]` fulfills the Show constraint, and that we must prove +the [W] Show a0_a1pd[tau:2] constraint -- that is, whatever fills the +hole must have a Show instance. - [[WD] __a1ph {0}:: a0_a1pd[tau:2] (CHoleCan: ExprHole(_)), - [WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CNonCanonical)] - -I.e. the hole `a0_a1pd[tau:2]` and the constraint that the type of the hole must -fulfill `Show a0_a1pd[tau:2])`. - -So when we run the check, we need to make sure that the - - [WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CNonCanonical) - -Constraint gets solved. When we now check for whether `x :: a0_a1pd[tau:2]` fits -the hole in `tcCheckHoleFit`, the call to `tcSubType` will end up writing the -meta type variable `a0_a1pd[tau:2] := a_a1pa[sk:2]`. By wrapping the wanted -constraints needed by tcSubType_NC and the relevant constraints (see -Note [Relevant Constraints] for more details) in the nested implications, we -can pass the information in the givens along to the simplifier. For our example, -we end up needing to check whether the following constraints are soluble. +When we now check whether `x :: a_a1pa[sk:2]` fits the hole in +`tcCheckHoleFit`, the call to `tcSubType` will end up unifying the meta type +variable `a0_a1pd[tau:2] := a_a1pa[sk:2]`. By wrapping the wanted constraints +needed by tcSubType_NC and the relevant constraints (see Note [Relevant +Constraints] for more details) in the nested implications, we can pass the +information in the givens along to the simplifier. For our example, we end up +needing to check whether the following constraints are soluble. WC {wc_impl = Implic { @@ -223,10 +205,12 @@ with a final WC of WC {}, confirming x :: a0_a1pd[tau:2] as a match. To avoid side-effects on the nested implications, we create a new EvBindsVar so that any changes to the ev binds during a check remains localised to that check. - +In addition, we call withoutUnification to reset any unified metavariables; this +call is actually done outside tcCheckHoleFit so that the results can be formatted +for the user before resetting variables. Note [Valid refinement hole fits include ...] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When the `-frefinement-level-hole-fits=N` flag is given, we additionally look for "valid refinement hole fits"", i.e. valid hole fits with up to N additional holes in them. @@ -337,10 +321,8 @@ In the free monad example above, this is demonstrated with be applied to an expression of type `a -> Free f b` in order to match. If -XScopedTypeVariables is enabled, this hole fit can even be copied verbatim. - -Note [Relevant Constraints] -~~~~~~~~~~~~~~~~~~~ - +Note [Relevant constraints] +~~~~~~~~~~~~~~~~~~~~~~~~~~~ As highlighted by #14273, we need to check any relevant constraints as well as checking for subsumption. Relevant constraints are the simple constraints whose free unification variables are mentioned in the type of the hole. @@ -351,10 +333,9 @@ as is the case in f :: String f = show _ -Where the simples will be : +Here, the hole is given type a0_a1kv[tau:1]. Then, the emitted constraint is: - [[WD] __a1kz {0}:: a0_a1kv[tau:1] (CHoleCan: ExprHole(_)), - [WD] $dShow_a1kw {0}:: Show a0_a1kv[tau:1] (CNonCanonical)] + [WD] $dShow_a1kw {0}:: Show a0_a1kv[tau:1] (CNonCanonical) However, when there are multiple holes, we need to be more careful. As an example, Let's take a look at the following code: @@ -362,29 +343,24 @@ example, Let's take a look at the following code: f :: Show a => a -> String f x = show (_b (show _a)) -Here there are two holes, `_a` and `_b`, and the simple constraints passed to +Here there are two holes, `_a` and `_b`. Suppose _a :: a0_a1pd[tau:2] and +_b :: a1_a1po[tau:2]. Then, the simple constraints passed to findValidHoleFits are: - [[WD] _a_a1pi {0}:: String - -> a0_a1pd[tau:2] (CHoleCan: ExprHole(_b)), - [WD] _b_a1ps {0}:: a1_a1po[tau:2] (CHoleCan: ExprHole(_a)), - [WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CNonCanonical), + [[WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CNonCanonical), [WD] $dShow_a1pp {0}:: Show a1_a1po[tau:2] (CNonCanonical)] - -Here we have the two hole constraints for `_a` and `_b`, but also additional -constraints that these holes must fulfill. When we are looking for a match for -the hole `_a`, we filter the simple constraints to the "Relevant constraints", -by throwing out all hole constraints and any constraints which do not mention -a variable mentioned in the type of the hole. For hole `_a`, we will then -only require that the `$dShow_a1pp` constraint is solved, since that is -the only non-hole constraint that mentions any free type variables mentioned in -the hole constraint for `_a`, namely `a_a1pd[tau:2]` , and similarly for the -hole `_b` we only require that the `$dShow_a1pe` constraint is solved. +When we are looking for a match for the hole `_a`, we filter the simple +constraints to the "Relevant constraints", by throwing out any constraints +which do not mention a variable mentioned in the type of the hole. For hole +`_a`, we will then only require that the `$dShow_a1pe` constraint is solved, +since that is the only constraint that mentions any free type variables +mentioned in the hole constraint for `_a`, namely `a_a1pd[tau:2]`, and +similarly for the hole `_b` we only require that the `$dShow_a1pe` constraint +is solved. Note [Leaking errors] -~~~~~~~~~~~~~~~~~~~ - +~~~~~~~~~~~~~~~~~~~~~ When considering candidates, GHC believes that we're checking for validity in actual source. However, As evidenced by #15321, #15007 and #15202, this can cause bewildering error messages. The solution here is simple: if a candidate @@ -393,17 +369,12 @@ is discarded. -} - data HoleFitDispConfig = HFDC { showWrap :: Bool , showWrapVars :: Bool , showType :: Bool , showProv :: Bool , showMatches :: Bool } -debugHoleFitDispConfig :: HoleFitDispConfig -debugHoleFitDispConfig = HFDC True True True False False - - -- We read the various -no-show-*-of-hole-fits flags -- and set the display config accordingly. getHoleFitDispConfig :: TcM HoleFitDispConfig @@ -516,13 +487,12 @@ pprHoleFit (HFDC sWrp sWrpVars sTy sProv sMs) (HoleFit {..}) = GreHFCand gre -> pprNameProvenance gre _ -> text "bound at" <+> ppr (getSrcLoc name) -getLocalBindings :: TidyEnv -> Ct -> TcM [Id] -getLocalBindings tidy_orig ct - = do { (env1, _) <- zonkTidyOrigin tidy_orig (ctLocOrigin loc) +getLocalBindings :: TidyEnv -> CtLoc -> TcM [Id] +getLocalBindings tidy_orig ct_loc + = do { (env1, _) <- zonkTidyOrigin tidy_orig (ctLocOrigin ct_loc) ; go env1 [] (removeBindingShadowing $ tcl_bndrs lcl_env) } where - loc = ctEvLoc (ctEvidence ct) - lcl_env = ctLocEnv loc + lcl_env = ctLocEnv ct_loc go :: TidyEnv -> [Id] -> [TcBinder] -> TcM [Id] go _ sofar [] = return (reverse sofar) @@ -542,11 +512,13 @@ findValidHoleFits :: TidyEnv -- ^ The tidy_env for zonking -> [Ct] -- ^ The unsolved simple constraints in the implication for -- the hole. - -> Ct -- ^ The hole constraint itself + -> Hole -> TcM (TidyEnv, SDoc) -findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = +findValidHoleFits tidy_env implics simples h@(Hole { hole_sort = ExprHole _ + , hole_loc = ct_loc + , hole_ty = hole_ty }) = do { rdr_env <- getGlobalRdrEnv - ; lclBinds <- getLocalBindings tidy_env ct + ; lclBinds <- getLocalBindings tidy_env ct_loc ; maxVSubs <- maxValidHoleFits <$> getDynFlags ; hfdc <- getHoleFitDispConfig ; sortingAlg <- getSortingAlg @@ -554,7 +526,9 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = ; hfPlugs <- tcg_hf_plugins <$> getGblEnv ; let findVLimit = if sortingAlg > NoSorting then Nothing else maxVSubs refLevel = refLevelHoleFits dflags - hole = TyH (listToBag relevantCts) implics (Just ct) + hole = TypedHole { th_relevant_cts = listToBag relevantCts + , th_implics = implics + , th_hole = Just h } (candidatePlugins, fitPlugins) = unzip $ map (\p-> ((candPlugin p) hole, (fitPlugin p) hole)) hfPlugs ; traceTc "findingValidHoleFitsFor { " $ ppr hole @@ -625,11 +599,9 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = where -- We extract the type, the tcLevel and the types free variables -- from from the constraint. - hole_ty :: TcPredType - hole_ty = ctPred ct hole_fvs :: FV hole_fvs = tyCoFVsOfType hole_ty - hole_lvl = ctLocLevel $ ctEvLoc $ ctEvidence ct + hole_lvl = ctLocLevel ct_loc -- BuiltInSyntax names like (:) and [] builtIns :: [Name] @@ -668,7 +640,7 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = <*> sortByGraph (sort gblFits) where (lclFits, gblFits) = span hfIsLcl subs - -- See Note [Relevant Constraints] + -- See Note [Relevant constraints] relevantCts :: [Ct] relevantCts = if isEmptyVarSet (fvVarSet hole_fvs) then [] else filter isRelevant simples @@ -684,7 +656,6 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = -- trying to find hole fits for many holes at once. isRelevant ct = not (isEmptyVarSet (ctFreeVarSet ct)) && anyFVMentioned ct - && not (isHoleCt ct) -- We zonk the hole fits so that the output aligns with the rest -- of the typed hole error message output. @@ -761,7 +732,7 @@ tcFilterHoleFits :: Maybe Int -- ^ We return whether or not we stopped due to hitting the limit -- and the fits we found. tcFilterHoleFits (Just 0) _ _ _ = return (False, []) -- Stop right away on 0 -tcFilterHoleFits limit (TyH {..}) ht@(hole_ty, _) candidates = +tcFilterHoleFits limit typed_hole ht@(hole_ty, _) candidates = do { traceTc "checkingFitsFor {" $ ppr hole_ty ; (discards, subs) <- go [] emptyVarSet limit ht candidates ; traceTc "checkingFitsFor }" empty @@ -895,8 +866,7 @@ tcFilterHoleFits limit (TyH {..}) ht@(hole_ty, _) candidates = else return Nothing } else return Nothing } where fvs = mkFVs ref_vars `unionFV` hole_fvs `unionFV` tyCoFVsOfType ty - hole = TyH tyHRelevantCts tyHImplics Nothing - + hole = typed_hole { th_hole = Nothing } subsDiscardMsg :: SDoc subsDiscardMsg = @@ -925,7 +895,8 @@ withoutUnification free_vars action = -- Reset any mutated free variables ; mapM_ restore flexis ; return result } - where restore = flip writeTcRef Flexi . metaTyVarRef + where restore tv = do { traceTc "withoutUnification: restore flexi" (ppr tv) + ; writeTcRef (metaTyVarRef tv) Flexi } fuvs = fvVarList free_vars -- | Reports whether first type (ty_a) subsumes the second type (ty_b), @@ -933,14 +904,14 @@ withoutUnification free_vars action = -- ty_a, i.e. `tcSubsumes a b == True` if b is a subtype of a. tcSubsumes :: TcSigmaType -> TcSigmaType -> TcM Bool tcSubsumes ty_a ty_b = fst <$> tcCheckHoleFit dummyHole ty_a ty_b - where dummyHole = TyH emptyBag [] Nothing + where dummyHole = TypedHole { th_relevant_cts = emptyBag + , th_implics = [] + , th_hole = Nothing } -- | A tcSubsumes which takes into account relevant constraints, to fix trac -- #14273. This makes sure that when checking whether a type fits the hole, -- the type has to be subsumed by type of the hole as well as fulfill all -- constraints on the type of the hole. --- Note: The simplifier may perform unification, so make sure to restore any --- free type variables to avoid side-effects. tcCheckHoleFit :: TypedHole -- ^ The hole to check against -> TcSigmaType -- ^ The type to check against (possibly modified, e.g. refined) @@ -949,56 +920,48 @@ tcCheckHoleFit :: TypedHole -- ^ The hole to check against -- ^ Whether it was a match, and the wrapper from hole_ty to ty. tcCheckHoleFit _ hole_ty ty | hole_ty `eqType` ty = return (True, idHsWrapper) -tcCheckHoleFit (TyH {..}) hole_ty ty = discardErrs $ +tcCheckHoleFit (TypedHole {..}) hole_ty ty = discardErrs $ do { -- We wrap the subtype constraint in the implications to pass along the -- givens, and so we must ensure that any nested implications and skolems -- end up with the correct level. The implications are ordered so that -- the innermost (the one with the highest level) is first, so it -- suffices to get the level of the first one (or the current level, if -- there are no implications involved). - innermost_lvl <- case tyHImplics of + innermost_lvl <- case th_implics of [] -> getTcLevel -- imp is the innermost implication (imp:_) -> return (ic_tclvl imp) - ; (wrp, wanted) <- setTcLevel innermost_lvl $ captureConstraints $ - tcSubType_NC ExprSigCtxt ty hole_ty + ; (wrap, wanted) <- setTcLevel innermost_lvl $ captureConstraints $ + tcSubType_NC ExprSigCtxt ty hole_ty ; traceTc "Checking hole fit {" empty ; traceTc "wanteds are: " $ ppr wanted - ; if isEmptyWC wanted && isEmptyBag tyHRelevantCts - then traceTc "}" empty >> return (True, wrp) + ; if isEmptyWC wanted && isEmptyBag th_relevant_cts + then do { traceTc "}" empty + ; return (True, wrap) } else do { fresh_binds <- newTcEvBinds -- The relevant constraints may contain HoleDests, so we must -- take care to clone them as well (to avoid #15370). - ; cloned_relevants <- mapBagM cloneWanted tyHRelevantCts + ; cloned_relevants <- mapBagM cloneWanted th_relevant_cts -- We wrap the WC in the nested implications, see - -- Note [Nested Implications] - ; let outermost_first = reverse tyHImplics - setWC = setWCAndBinds fresh_binds + -- Note [Checking hole fits] + ; let outermost_first = reverse th_implics -- We add the cloned relevants to the wanteds generated by - -- the call to tcSubType_NC, see Note [Relevant Constraints] + -- the call to tcSubType_NC, see Note [Relevant constraints] -- There's no need to clone the wanteds, because they are -- freshly generated by `tcSubtype_NC`. w_rel_cts = addSimples wanted cloned_relevants - w_givens = foldr setWC w_rel_cts outermost_first - ; traceTc "w_givens are: " $ ppr w_givens - ; rem <- runTcSDeriveds $ simpl_top w_givens + final_wc = foldr (setWCAndBinds fresh_binds) w_rel_cts outermost_first + ; traceTc "final_wc is: " $ ppr final_wc + ; rem <- runTcSDeriveds $ simpl_top final_wc -- We don't want any insoluble or simple constraints left, but -- solved implications are ok (and necessary for e.g. undefined) ; traceTc "rems was:" $ ppr rem ; traceTc "}" empty - ; return (isSolvedWC rem, wrp) } } + ; return (isSolvedWC rem, wrap) } } where setWCAndBinds :: EvBindsVar -- Fresh ev binds var. -> Implication -- The implication to put WC in. -> WantedConstraints -- The WC constraints to put implic. -> WantedConstraints -- The new constraints. setWCAndBinds binds imp wc - = WC { wc_simple = emptyBag - , wc_impl = unitBag $ imp { ic_wanted = wc , ic_binds = binds } } - --- | Maps a plugin that needs no state to one with an empty one. -fromPureHFPlugin :: HoleFitPlugin -> HoleFitPluginR -fromPureHFPlugin plug = - HoleFitPluginR { hfPluginInit = newTcRef () - , hfPluginRun = const plug - , hfPluginStop = const $ return () } + = mkImplicWC $ unitBag $ imp { ic_wanted = wc , ic_binds = binds } ===================================== compiler/GHC/Tc/Errors/Hole.hs-boot ===================================== @@ -5,9 +5,9 @@ module GHC.Tc.Errors.Hole where import GHC.Tc.Types ( TcM ) -import GHC.Tc.Types.Constraint ( Ct, Implication ) +import GHC.Tc.Types.Constraint ( Ct, Hole, Implication ) import GHC.Utils.Outputable ( SDoc ) import GHC.Types.Var.Env ( TidyEnv ) -findValidHoleFits :: TidyEnv -> [Implication] -> [Ct] -> Ct +findValidHoleFits :: TidyEnv -> [Implication] -> [Ct] -> Hole -> TcM (TidyEnv, SDoc) ===================================== compiler/GHC/Tc/Errors/Hole/FitTypes.hs ===================================== @@ -21,20 +21,21 @@ import GHC.Types.Name import Data.Function ( on ) -data TypedHole = TyH { tyHRelevantCts :: Cts - -- ^ Any relevant Cts to the hole - , tyHImplics :: [Implication] - -- ^ The nested implications of the hole with the - -- innermost implication first. - , tyHCt :: Maybe Ct - -- ^ The hole constraint itself, if available. - } +data TypedHole = TypedHole { th_relevant_cts :: Cts + -- ^ Any relevant Cts to the hole + , th_implics :: [Implication] + -- ^ The nested implications of the hole with the + -- innermost implication first. + , th_hole :: Maybe Hole + -- ^ The hole itself, if available. Only for debugging. + } instance Outputable TypedHole where - ppr (TyH rels implics ct) + ppr (TypedHole { th_relevant_cts = rels + , th_implics = implics + , th_hole = hole }) = hang (text "TypedHole") 2 - (ppr rels $+$ ppr implics $+$ ppr ct) - + (ppr rels $+$ ppr implics $+$ ppr hole) -- | HoleFitCandidates are passed to hole fit plugins and then -- checked whether they fit a given typed-hole. @@ -51,9 +52,6 @@ pprHoleFitCand (IdHFCand cid) = text "Id HFC: " <> ppr cid pprHoleFitCand (NameHFCand cname) = text "Name HFC: " <> ppr cname pprHoleFitCand (GreHFCand cgre) = text "Gre HFC: " <> ppr cgre - - - instance NamedThing HoleFitCandidate where getName hfc = case hfc of IdHFCand cid -> idName cid ===================================== compiler/GHC/Tc/Gen/Expr.hs ===================================== @@ -36,7 +36,6 @@ import {-# SOURCE #-} GHC.Tc.Gen.Splice( tcSpliceExpr, tcTypedBracket, tcUntyp import GHC.Builtin.Names.TH( liftStringName, liftName ) import GHC.Hs -import GHC.Tc.Types.Constraint ( HoleSort(..) ) import GHC.Tc.Utils.Zonk import GHC.Tc.Utils.Monad import GHC.Tc.Utils.Unify @@ -1408,22 +1407,21 @@ Suppose 'wurble' is not in scope, and we have Then the renamer will make (HsUnboundVar "wurble) for 'wurble', and the typechecker will typecheck it with tcUnboundId, giving it -a type 'alpha', and emitting a deferred CHoleCan constraint, to -be reported later. +a type 'alpha', and emitting a deferred Hole, to be reported later. But then comes the visible type application. If we do nothing, we'll generate an immediate failure (in tc_app_err), saying that a function of type 'alpha' can't be applied to Bool. That's insane! And indeed users complain bitterly (#13834, #17150.) -The right error is the CHoleCan, which has /already/ been emitted by +The right error is the Hole, which has /already/ been emitted by tcUnboundId. It later reports 'wurble' as out of scope, and tries to give its type. Fortunately in tcArgs we still have access to the function, so we can check if it is a HsUnboundVar. We use this info to simply skip over any visible type arguments. We've already inferred the type of the -function, so we'll /already/ have emitted a CHoleCan constraint; +function, so we'll /already/ have emitted a Hole; failing preserves that constraint. We do /not/ want to fail altogether in this case (via failM) becuase @@ -1900,14 +1898,13 @@ tcUnboundId :: HsExpr GhcRn -> OccName -> ExpRhoType -> TcM (HsExpr GhcTc) -- Others might simply be variables that accidentally have no binding site -- -- We turn all of them into HsVar, since HsUnboundVar can't contain an --- Id; and indeed the evidence for the CHoleCan does bind it, so it's +-- Id; and indeed the evidence for the ExprHole does bind it, so it's -- not unbound any more! tcUnboundId rn_expr occ res_ty = do { ty <- newOpenFlexiTyVarTy -- Allow Int# etc (#12531) ; name <- newSysName occ ; let ev = mkLocalId name ty - ; can <- newHoleCt ExprHole ev ty - ; emitInsoluble can + ; emitNewExprHole occ ev ty ; tcWrapResultO (UnboundOccurrenceOf occ) rn_expr (HsVar noExtField (noLoc ev)) ty res_ty } ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -419,7 +419,7 @@ tcHsTypeApp wc_ty kind ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A HsWildCardBndrs's hswc_ext now only includes /named/ wildcards, so any unnamed wildcards stay unchanged in hswc_body. When called in -tcHsTypeApp, tcCheckLHsType will call emitAnonWildCardHoleConstraint +tcHsTypeApp, tcCheckLHsType will call emitAnonTypeHole on these anonymous wildcards. However, this would trigger error/warning when an anonymous wildcard is passed in as a visible type argument, which we do not want because users should be able to write @@ -891,7 +891,7 @@ tcAnonWildCardOcc wc exp_kind ; warning <- woptM Opt_WarnPartialTypeSignatures ; unless (part_tysig && not warning) $ - emitAnonWildCardHoleConstraint wc_tv + emitAnonTypeHole wc_tv -- Why the 'unless' guard? -- See Note [Wildcards in visible kind application] @@ -911,11 +911,11 @@ x = MkT So we should allow '@_' without emitting any hole constraints, and regardless of whether PartialTypeSignatures is enabled or not. But how would the typechecker know which '_' is being used in VKA and which is not when it -calls emitNamedWildCardHoleConstraints in tcHsPartialSigType on all HsWildCardBndrs? +calls emitNamedTypeHole in tcHsPartialSigType on all HsWildCardBndrs? The solution then is to neither rename nor include unnamed wildcards in HsWildCardBndrs, but instead give every anonymous wildcard a fresh wild tyvar in tcAnonWildCardOcc. And whenever we see a '@', we automatically turn on PartialTypeSignatures and -turn off hole constraint warnings, and do not call emitAnonWildCardHoleConstraint +turn off hole constraint warnings, and do not call emitAnonTypeHole under these conditions. See related Note [Wildcards in visible type application] here and Note [The wildcard story for types] in GHC.Hs.Types @@ -3192,7 +3192,7 @@ tcHsPartialSigType ctxt sig_ty -- Spit out the wildcards (including the extra-constraints one) -- as "hole" constraints, so that they'll be reported if necessary -- See Note [Extra-constraint holes in partial type signatures] - ; emitNamedWildCardHoleConstraints wcs + ; mapM_ emitNamedTypeHole wcs -- Zonk, so that any nested foralls can "see" their occurrences -- See Note [Checking partial type signatures], in @@ -3365,7 +3365,7 @@ tcHsPatSigType ctxt sig_ty do { sig_ty <- tcHsOpenType hs_ty ; return (wcs, sig_ty) } - ; emitNamedWildCardHoleConstraints wcs + ; mapM_ emitNamedTypeHole wcs -- sig_ty might have tyvars that are at a higher TcLevel (if hs_ty -- contains a forall). Promote these. ===================================== compiler/GHC/Tc/Gen/Rule.hs ===================================== @@ -460,9 +460,9 @@ getRuleQuantCts wc = float_wc emptyVarSet wc where float_wc :: TcTyCoVarSet -> WantedConstraints -> (Cts, WantedConstraints) - float_wc skol_tvs (WC { wc_simple = simples, wc_impl = implics }) + float_wc skol_tvs (WC { wc_simple = simples, wc_impl = implics, wc_holes = holes }) = ( simple_yes `andCts` implic_yes - , WC { wc_simple = simple_no, wc_impl = implics_no }) + , emptyWC { wc_simple = simple_no, wc_impl = implics_no, wc_holes = holes }) where (simple_yes, simple_no) = partitionBag (rule_quant_ct skol_tvs) simples (implic_yes, implics_no) = mapAccumBagL (float_implic skol_tvs) @@ -480,8 +480,6 @@ getRuleQuantCts wc | EqPred _ t1 t2 <- classifyPredType (ctPred ct) , not (ok_eq t1 t2) = False -- Note [RULE quantification over equalities] - | isHoleCt ct - = False -- Don't quantify over type holes, obviously | otherwise = tyCoVarsOfCt ct `disjointVarSet` skol_tvs ===================================== compiler/GHC/Tc/Module.hs ===================================== @@ -2589,7 +2589,7 @@ tcRnType hsc_env flexi normalise rdr_type -- kindGeneralize, below solveEqualities $ tcNamedWildCardBinders wcs $ \ wcs' -> - do { emitNamedWildCardHoleConstraints wcs' + do { mapM_ emitNamedTypeHole wcs' ; tcLHsTypeUnsaturated rn_type } -- Do kind generalisation; see Note [Kind-generalise in tcRnType] ===================================== compiler/GHC/Tc/Solver.hs ===================================== @@ -31,7 +31,7 @@ import GHC.Prelude import GHC.Data.Bag import GHC.Core.Class ( Class, classKey, classTyCon ) import GHC.Driver.Session -import GHC.Types.Id ( idType, mkLocalId ) +import GHC.Types.Id ( idType ) import GHC.Tc.Utils.Instantiate import GHC.Data.List.SetOps import GHC.Types.Name @@ -42,6 +42,7 @@ import GHC.Tc.Errors import GHC.Tc.Types.Evidence import GHC.Tc.Solver.Interact import GHC.Tc.Solver.Canonical ( makeSuperClasses, solveCallStack ) +import GHC.Tc.Solver.Flatten ( flattenType ) import GHC.Tc.Utils.TcMType as TcM import GHC.Tc.Utils.Monad as TcM import GHC.Tc.Solver.Monad as TcS @@ -145,8 +146,7 @@ simplifyTop wanteds ; saved_msg <- TcM.readTcRef errs_var ; TcM.writeTcRef errs_var emptyMessages - ; warnAllUnsolved $ WC { wc_simple = unsafe_ol - , wc_impl = emptyBag } + ; warnAllUnsolved $ emptyWC { wc_simple = unsafe_ol } ; whyUnsafe <- fst <$> TcM.readTcRef errs_var ; TcM.writeTcRef errs_var saved_msg @@ -638,27 +638,15 @@ tcNormalise :: Bag EvVar -> Type -> TcM Type tcNormalise given_ids ty = do { lcl_env <- TcM.getLclEnv ; let given_loc = mkGivenLoc topTcLevel UnkSkol lcl_env - ; wanted_ct <- mk_wanted_ct + ; norm_loc <- getCtLocM PatCheckOrigin Nothing ; (res, _ev_binds) <- runTcS $ do { traceTcS "tcNormalise {" (ppr given_ids) ; let given_cts = mkGivens given_loc (bagToList given_ids) ; solveSimpleGivens given_cts - ; wcs <- solveSimpleWanteds (unitBag wanted_ct) - -- It's an invariant that this wc_simple will always be - -- a singleton Ct, since that's what we fed in as input. - ; let ty' = case bagToList (wc_simple wcs) of - (ct:_) -> ctEvPred (ctEvidence ct) - cts -> pprPanic "tcNormalise" (ppr cts) + ; ty' <- flattenType norm_loc ty ; traceTcS "tcNormalise }" (ppr ty') ; pure ty' } ; return res } - where - mk_wanted_ct :: TcM Ct - mk_wanted_ct = do - let occ = mkVarOcc "$tcNorm" - name <- newSysName occ - let ev = mkLocalId name ty - newHoleCt ExprHole ev ty {- Note [Superclasses and satisfiability] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -696,11 +684,8 @@ if some local equalities are solved for. See "Wrinkle: Local equalities" in Note [Type normalisation] in Check. To accomplish its stated goal, tcNormalise first feeds the local constraints -into solveSimpleGivens, then stuffs the argument type in a CHoleCan, and feeds -that singleton Ct into solveSimpleWanteds, which reduces the type in the -CHoleCan as much as possible with respect to the local given constraints. When -solveSimpleWanteds is finished, we dig out the type from the CHoleCan and -return that. +into solveSimpleGivens, then uses flattenType to simplify the desired type +with respect to the givens. *********************************************************************************** * * @@ -889,8 +874,8 @@ mkResidualConstraints rhs_tclvl ev_binds_var , ic_no_eqs = False , ic_info = skol_info } - ; return (WC { wc_simple = outer_simple - , wc_impl = implics })} + ; return (emptyWC { wc_simple = outer_simple + , wc_impl = implics })} where full_theta = map idType full_theta_vars skol_info = InferSkol [ (name, mkSigmaTy [] full_theta ty) @@ -1516,7 +1501,7 @@ solveWantedsAndDrop wanted solveWanteds :: WantedConstraints -> TcS WantedConstraints -- so that the inert set doesn't mindlessly propagate. -- NB: wc_simples may be wanted /or/ derived now -solveWanteds wc@(WC { wc_simple = simples, wc_impl = implics }) +solveWanteds wc@(WC { wc_simple = simples, wc_impl = implics, wc_holes = holes }) = do { cur_lvl <- TcS.getTcLevel ; traceTcS "solveWanteds {" $ vcat [ text "Level =" <+> ppr cur_lvl @@ -1530,9 +1515,12 @@ solveWanteds wc@(WC { wc_simple = simples, wc_impl = implics }) implics `unionBags` wc_impl wc1 ; dflags <- getDynFlags - ; final_wc <- simpl_loop 0 (solverIterations dflags) floated_eqs + ; solved_wc <- simpl_loop 0 (solverIterations dflags) floated_eqs (wc1 { wc_impl = implics2 }) + ; holes' <- simplifyHoles holes + ; let final_wc = solved_wc { wc_holes = holes' } + ; ev_binds_var <- getTcEvBindsVar ; bb <- TcS.getTcEvBindsMap ev_binds_var ; traceTcS "solveWanteds }" $ @@ -1779,12 +1767,13 @@ setImplicationStatus implic@(Implic { ic_status = status then Nothing else Just final_implic } where - WC { wc_simple = simples, wc_impl = implics } = wc + WC { wc_simple = simples, wc_impl = implics, wc_holes = holes } = wc pruned_simples = dropDerivedSimples simples pruned_implics = filterBag keep_me implics pruned_wc = WC { wc_simple = pruned_simples - , wc_impl = pruned_implics } + , wc_impl = pruned_implics + , wc_holes = holes } -- do not prune holes; these should be reported keep_me :: Implication -> Bool keep_me ic @@ -1898,6 +1887,14 @@ neededEvVars implic@(Implic { ic_given = givens | is_given = needs -- Add the rhs vars of the Wanted bindings only | otherwise = evVarsOfTerm rhs `unionVarSet` needs +------------------------------------------------- +simplifyHoles :: Bag Hole -> TcS (Bag Hole) +simplifyHoles = mapBagM simpl_hole + where + simpl_hole :: Hole -> TcS Hole + simpl_hole h@(Hole { hole_ty = ty, hole_loc = loc }) + = do { ty' <- flattenType loc ty + ; return (h { hole_ty = ty' }) } {- Note [Delete dead Given evidence bindings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2143,7 +2140,6 @@ approximateWC float_past_equalities wc is_floatable skol_tvs ct | isGivenCt ct = False - | isHoleCt ct = False | insolubleEqCt ct = False | otherwise = tyCoVarsOfCt ct `disjointVarSet` skol_tvs ===================================== compiler/GHC/Tc/Solver/Canonical.hs ===================================== @@ -34,7 +34,6 @@ import GHC.Tc.Instance.Family ( tcTopNormaliseNewTypeTF_maybe ) import GHC.Types.Var import GHC.Types.Var.Env( mkInScopeSet ) import GHC.Types.Var.Set( delVarSetList ) -import GHC.Types.Name.Occurrence ( OccName ) import GHC.Utils.Outputable import GHC.Driver.Session( DynFlags ) import GHC.Types.Name.Set @@ -67,8 +66,7 @@ Canonicalization converts a simple constraint to a canonical form. It is unary (i.e. treats individual constraints one at a time). Constraints originating from user-written code come into being as -CNonCanonicals (except for CHoleCans, arising from holes). We know nothing -about these constraints. So, first: +CNonCanonicals. We know nothing about these constraints. So, first: Classify CNonCanoncal constraints, depending on whether they are equalities, class predicates, or other. @@ -137,9 +135,6 @@ canonicalize (CFunEqCan { cc_ev = ev = {-# SCC "canEqLeafFunEq" #-} canCFunEqCan ev fn xis1 fsk -canonicalize (CHoleCan { cc_ev = ev, cc_occ = occ, cc_hole = hole }) - = canHole ev occ hole - {- ************************************************************************ * * @@ -718,17 +713,6 @@ canIrred status ev _ -> continueWith $ mkIrredCt status new_ev } } -canHole :: CtEvidence -> OccName -> HoleSort -> TcS (StopOrContinue Ct) -canHole ev occ hole_sort - = do { let pred = ctEvPred ev - ; (xi,co) <- flatten FM_SubstOnly ev pred -- co :: xi ~ pred - ; rewriteEvidence ev xi co `andWhenContinue` \ new_ev -> - do { updInertIrreds (`snocCts` (CHoleCan { cc_ev = new_ev - , cc_occ = occ - , cc_hole = hole_sort })) - ; stopWith new_ev "Emit insoluble hole" } } - - {- ********************************************************************* * * * Quantified predicates @@ -1401,6 +1385,7 @@ can_eq_app ev s1 t1 s2 t2 | CtDerived {} <- ev = do { unifyDeriveds loc [Nominal, Nominal] [s1, t1] [s2, t2] ; stopWith ev "Decomposed [D] AppTy" } + | CtWanted { ctev_dest = dest } <- ev = do { co_s <- unifyWanted loc Nominal s1 s2 ; let arg_loc ===================================== compiler/GHC/Tc/Solver/Flatten.hs ===================================== @@ -5,7 +5,7 @@ module GHC.Tc.Solver.Flatten( FlattenMode(..), flatten, flattenKind, flattenArgsNom, - rewriteTyVar, + rewriteTyVar, flattenType, unflattenWanteds ) where @@ -825,6 +825,20 @@ flattenArgsNom ev tc tys ; traceTcS "flatten }" (vcat (map ppr tys')) ; return (tys', cos, kind_co) } +-- | Flatten a type w.r.t. nominal equality. This is useful to rewrite +-- a type w.r.t. any givens. It does not do type-family reduction. This +-- will never emit new constraints. Call this when the inert set contains +-- only givens. +flattenType :: CtLoc -> TcType -> TcS TcType +flattenType loc ty + -- More info about FM_SubstOnly in Note [Holes] in GHC.Tc.Types.Constraint + = do { (xi, _) <- runFlatten FM_SubstOnly loc Given NomEq $ + flatten_one ty + -- use Given flavor so that it is rewritten + -- only w.r.t. Givens, never Wanteds/Deriveds + -- (Shouldn't matter, if only Givens are present + -- anyway) + ; return xi } {- ********************************************************************* * * ===================================== compiler/GHC/Tc/Solver/Interact.hs ===================================== @@ -195,7 +195,7 @@ solve_simple_wanteds :: WantedConstraints -> TcS (Int, WantedConstraints) -- Try solving these constraints -- Affects the unification state (of course) but not the inert set -- The result is not necessarily zonked -solve_simple_wanteds (WC { wc_simple = simples1, wc_impl = implics1 }) +solve_simple_wanteds (WC { wc_simple = simples1, wc_impl = implics1, wc_holes = holes }) = nestTcS $ do { solveSimples simples1 ; (implics2, tv_eqs, fun_eqs, others) <- getUnsolvedInerts @@ -204,7 +204,8 @@ solve_simple_wanteds (WC { wc_simple = simples1, wc_impl = implics1 }) -- See Note [Unflatten after solving the simple wanteds] ; return ( unif_count , WC { wc_simple = others `andCts` unflattened_eqs - , wc_impl = implics1 `unionBags` implics2 }) } + , wc_impl = implics1 `unionBags` implics2 + , wc_holes = holes }) } {- Note [The solveSimpleWanteds loop] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -264,7 +265,7 @@ runTcPluginsGiven -- 'solveSimpleWanteds' should feed the updated wanteds back into the -- main solver. runTcPluginsWanted :: WantedConstraints -> TcS (Bool, WantedConstraints) -runTcPluginsWanted wc@(WC { wc_simple = simples1, wc_impl = implics1 }) +runTcPluginsWanted wc@(WC { wc_simple = simples1 }) | isEmptyBag simples1 = return (False, wc) | otherwise @@ -285,11 +286,10 @@ runTcPluginsWanted wc@(WC { wc_simple = simples1, wc_impl = implics1 }) ; mapM_ setEv solved_wanted ; return ( notNull (pluginNewCts p) - , WC { wc_simple = listToBag new_wanted `andCts` + , wc { wc_simple = listToBag new_wanted `andCts` listToBag unsolved_wanted `andCts` listToBag unsolved_derived `andCts` - listToBag insols - , wc_impl = implics1 } ) } } + listToBag insols } ) } } where setEv :: (EvTerm,Ct) -> TcS () setEv (ev,ct) = case ctEvidence ct of @@ -494,7 +494,6 @@ interactWithInertsStage wi CIrredCan {} -> interactIrred ics wi CDictCan {} -> interactDict ics wi _ -> pprPanic "interactWithInerts" (ppr wi) } - -- CHoleCan are put straight into inert_frozen, so never get here -- CNonCanonical have been canonicalised data InteractResult ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -198,7 +198,7 @@ import GHC.Types.Unique.Set Note [WorkList priorities] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -A WorkList contains canonical and non-canonical items (of all flavors). +A WorkList contains canonical and non-canonical items (of all flavours). Notice that each Ct now has a simplification depth. We may consider using this depth for prioritization as well in the future. @@ -1653,8 +1653,7 @@ add_item ics item@(CDictCan { cc_ev = ev, cc_class = cls, cc_tyargs = tys }) add_item _ item = pprPanic "upd_inert set: can't happen! Inserting " $ - ppr item -- Can't be CNonCanonical, CHoleCan, - -- because they only land in inert_irreds + ppr item -- Can't be CNonCanonical because they only land in inert_irreds bumpUnsolvedCount :: CtEvidence -> Int -> Int bumpUnsolvedCount ev n | isWanted ev = n+1 @@ -1896,10 +1895,6 @@ be decomposed. Otherwise we end up with a "Can't match [Int] ~ [[Int]]" which is true, but a bit confusing because the outer type constructors match. -Similarly, if we have a CHoleCan, we'd like to rewrite it with any -Givens, to give as informative an error messasge as possible -(#12468, #11325). - Hence: * In the main simplifier loops in GHC.Tc.Solver (solveWanteds, simpl_loop), we feed the insolubles in solveSimpleWanteds, @@ -2352,8 +2347,6 @@ removeInertCt is ct = CQuantCan {} -> panic "removeInertCt: CQuantCan" CIrredCan {} -> panic "removeInertCt: CIrredEvCan" CNonCanonical {} -> panic "removeInertCt: CNonCanonical" - CHoleCan {} -> panic "removeInertCt: CHoleCan" - lookupFlatCache :: TyCon -> [Type] -> TcS (Maybe (TcCoercion, TcType, CtFlavour)) lookupFlatCache fam_tc tys ===================================== compiler/GHC/Tc/Types/Constraint.hs ===================================== @@ -14,8 +14,7 @@ module GHC.Tc.Types.Constraint ( isEmptyCts, isCTyEqCan, isCFunEqCan, isPendingScDict, superClassesMightHelp, getPendingWantedScs, isCDictCan_Maybe, isCFunEqCan_maybe, - isCNonCanonical, isWantedCt, isDerivedCt, - isGivenCt, isHoleCt, isOutOfScopeCt, isExprHoleCt, isTypeHoleCt, + isCNonCanonical, isWantedCt, isDerivedCt, isGivenCt, isUserTypeErrorCt, getUserTypeErrorMsg, ctEvidence, ctLoc, setCtLoc, ctPred, ctFlavour, ctEqRel, ctOrigin, ctEvId, mkTcEqPredLikeEv, @@ -26,9 +25,11 @@ module GHC.Tc.Types.Constraint ( tyCoVarsOfCt, tyCoVarsOfCts, tyCoVarsOfCtList, tyCoVarsOfCtsList, + Hole(..), HoleSort(..), isOutOfScopeHole, + WantedConstraints(..), insolubleWC, emptyWC, isEmptyWC, isSolvedWC, andWC, unionsWC, mkSimpleWC, mkImplicWC, - addInsols, insolublesOnly, addSimples, addImplics, + addInsols, insolublesOnly, addSimples, addImplics, addHole, tyCoVarsOfWC, dropDerivedWC, dropDerivedSimples, tyCoVarsOfWCList, insolubleCt, insolubleEqCt, isDroppableCt, insolubleImplic, @@ -62,9 +63,6 @@ module GHC.Tc.Types.Constraint ( pprEvVarTheta, pprEvVars, pprEvVarWithType, - -- holes - HoleSort(..), - ) where @@ -202,14 +200,6 @@ data Ct cc_ev :: CtEvidence } - | CHoleCan { -- See Note [Hole constraints] - -- Treated as an "insoluble" constraint - -- See Note [Insoluble constraints] - cc_ev :: CtEvidence, - cc_occ :: OccName, -- The name of this hole - cc_hole :: HoleSort -- The sort of this hole (expr, type, ...) - } - | CQuantCan QCInst -- A quantified constraint -- NB: I expect to make more of the cases in Ct -- look like this, with the payload in an @@ -230,13 +220,47 @@ instance Outputable QCInst where ppr (QCI { qci_ev = ev }) = ppr ev ------------ +-- | A hole stores the information needed to report diagnostics +-- about holes in terms (unbound identifiers or underscores) or +-- in types (also called wildcards, as used in partial type +-- signatures). See Note [Holes]. +data Hole + = Hole { hole_sort :: HoleSort -- ^ What flavour of hole is this? + , hole_occ :: OccName -- ^ The name of this hole + , hole_ty :: TcType -- ^ Type to be printed to the user + -- For expression holes: type of expr + -- For type holes: the missing type + , hole_loc :: CtLoc -- ^ Where hole was written + } + -- For the hole_loc, we usually only want the TcLclEnv stored within. + -- Except when we flatten, where we need a whole location. And this + -- might get reported to the user if reducing type families in a + -- hole type loops. + + -- | Used to indicate which sort of hole we have. -data HoleSort = ExprHole +data HoleSort = ExprHole Id -- ^ Either an out-of-scope variable or a "true" hole in an - -- expression (TypedHoles) + -- expression (TypedHoles). + -- The 'Id' is where to store "evidence": this evidence + -- will be an erroring expression for -fdefer-type-errors. | TypeHole -- ^ A hole in a type (PartialTypeSignatures) +instance Outputable Hole where + ppr (Hole { hole_sort = ExprHole id + , hole_occ = occ + , hole_ty = ty }) + = parens $ (braces $ ppr occ <> colon <> ppr id) <+> dcolon <+> ppr ty + ppr (Hole { hole_sort = TypeHole + , hole_occ = occ + , hole_ty = ty }) + = braces $ ppr occ <> colon <> ppr ty + +instance Outputable HoleSort where + ppr (ExprHole id) = text "ExprHole:" <> ppr id + ppr TypeHole = text "TypeHole" + ------------ -- | Used to indicate extra information about why a CIrredCan is irreducible data CtIrredStatus @@ -252,20 +276,8 @@ instance Outputable CtIrredStatus where ppr BlockedCIS = text "(blocked)" ppr OtherCIS = text "(soluble)" -{- Note [Hole constraints] -~~~~~~~~~~~~~~~~~~~~~~~~~~ -CHoleCan constraints are used for two kinds of holes, -distinguished by cc_hole: - - * For holes in expressions - e.g. f x = g _ x - - * For holes in type signatures - e.g. f :: _ -> _ - f x = [x,True] - -Note [CIrredCan constraints] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [CIrredCan constraints] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CIrredCan constraints are used for constraints that are "stuck" - we can't solve them (yet) - we can't use them to solve other constraints @@ -350,6 +362,40 @@ unenforced). The almost-function-free property is checked by isAlmostFunctionFree in GHC.Tc.Utils.TcType. The flattener (in GHC.Tc.Solver.Flatten) produces types that are almost function-free. +Note [Holes] +~~~~~~~~~~~~ +This Note explains how GHC tracks *holes*. + +A hole represents one of two conditions: + - A missing bit of an expression. Example: foo x = x + _ + - A missing bit of a type. Example: bar :: Int -> _ + +What these have in common is that both cause GHC to emit a diagnostic to the +user describing the bit that is left out. + +When a hole is encountered, a new entry of type Hole is added to the ambient +WantedConstraints. The type (hole_ty) of the hole is then simplified during +solving (with respect to any Givens in surrounding implications). It is +reported with all the other errors in GHC.Tc.Errors. No type family reduction +is done on hole types; this is purely because we think it will produce +better error messages not to reduce type families. This is why the +GHC.Tc.Solver.Flatten.flattenType function uses FM_SubstOnly. + +For expression holes, the user has the option of deferring errors until runtime +with -fdefer-type-errors. In this case, the hole actually has evidence: this +evidence is an erroring expression that prints an error and crashes at runtime. +The ExprHole variant of holes stores the Id that will be bound to this evidence; +during constraint generation, this Id was inserted into the expression output +by the type checker. + +You might think that the type of the stored Id is the same as the type of the +hole. However, because the hole type (hole_ty) is rewritten with respect to +givens, this might not be the case. That is, the hole_ty is always (~) to the +type of the Id, but they might not be `eqType`. We need the type of the generated +evidence to match what is expected in the context of the hole, and so we must +store these types separately. + +Type-level holes have no evidence at all. -} mkNonCanonical :: CtEvidence -> Ct @@ -419,7 +465,6 @@ instance Outputable Ct where | pend_sc -> text "CDictCan(psc)" | otherwise -> text "CDictCan" CIrredCan { cc_status = status } -> text "CIrredCan" <> ppr status - CHoleCan { cc_occ = occ } -> text "CHoleCan:" <+> ppr occ CQuantCan (QCI { qci_pend_sc = pend_sc }) | pend_sc -> text "CQuantCan(psc)" | otherwise -> text "CQuantCan" @@ -482,9 +527,10 @@ tyCoVarsOfWCList = fvVarList . tyCoFVsOfWC -- computation. See Note [Deterministic FV] in GHC.Utils.FV. tyCoFVsOfWC :: WantedConstraints -> FV -- Only called on *zonked* things, hence no need to worry about flatten-skolems -tyCoFVsOfWC (WC { wc_simple = simple, wc_impl = implic }) +tyCoFVsOfWC (WC { wc_simple = simple, wc_impl = implic, wc_holes = holes }) = tyCoFVsOfCts simple `unionFV` - tyCoFVsOfBag tyCoFVsOfImplic implic + tyCoFVsOfBag tyCoFVsOfImplic implic `unionFV` + tyCoFVsOfBag tyCoFVsOfHole holes -- | Returns free variables of Implication as a composable FV computation. -- See Note [Deterministic FV] in GHC.Utils.FV. @@ -500,6 +546,9 @@ tyCoFVsOfImplic (Implic { ic_skols = skols tyCoFVsVarBndrs givens $ tyCoFVsOfWC wanted +tyCoFVsOfHole :: Hole -> FV +tyCoFVsOfHole (Hole { hole_ty = ty }) = tyCoFVsOfType ty + tyCoFVsOfBag :: (a -> FV) -> Bag a -> FV tyCoFVsOfBag tvs_of = foldr (unionFV . tvs_of) emptyFV @@ -552,7 +601,6 @@ isDroppableCt ct keep_deriv = case ct of - CHoleCan {} -> True CIrredCan { cc_status = InsolubleCIS } -> keep_eq True _ -> keep_eq False @@ -676,26 +724,6 @@ isCNonCanonical :: Ct -> Bool isCNonCanonical (CNonCanonical {}) = True isCNonCanonical _ = False -isHoleCt:: Ct -> Bool -isHoleCt (CHoleCan {}) = True -isHoleCt _ = False - -isOutOfScopeCt :: Ct -> Bool --- A Hole that does not have a leading underscore is --- simply an out-of-scope variable, and we treat that --- a bit differently when it comes to error reporting -isOutOfScopeCt (CHoleCan { cc_occ = occ }) = not (startsWithUnderscore occ) -isOutOfScopeCt _ = False - -isExprHoleCt :: Ct -> Bool -isExprHoleCt (CHoleCan { cc_hole = ExprHole }) = True -isExprHoleCt _ = False - -isTypeHoleCt :: Ct -> Bool -isTypeHoleCt (CHoleCan { cc_hole = TypeHole }) = True -isTypeHoleCt _ = False - - {- Note [Custom type errors in constraints] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -884,37 +912,39 @@ v%************************************************************************ data WantedConstraints = WC { wc_simple :: Cts -- Unsolved constraints, all wanted , wc_impl :: Bag Implication + , wc_holes :: Bag Hole } emptyWC :: WantedConstraints -emptyWC = WC { wc_simple = emptyBag, wc_impl = emptyBag } +emptyWC = WC { wc_simple = emptyBag + , wc_impl = emptyBag + , wc_holes = emptyBag } mkSimpleWC :: [CtEvidence] -> WantedConstraints mkSimpleWC cts - = WC { wc_simple = listToBag (map mkNonCanonical cts) - , wc_impl = emptyBag } + = emptyWC { wc_simple = listToBag (map mkNonCanonical cts) } mkImplicWC :: Bag Implication -> WantedConstraints mkImplicWC implic - = WC { wc_simple = emptyBag, wc_impl = implic } + = emptyWC { wc_impl = implic } isEmptyWC :: WantedConstraints -> Bool -isEmptyWC (WC { wc_simple = f, wc_impl = i }) - = isEmptyBag f && isEmptyBag i - +isEmptyWC (WC { wc_simple = f, wc_impl = i, wc_holes = holes }) + = isEmptyBag f && isEmptyBag i && isEmptyBag holes -- | Checks whether a the given wanted constraints are solved, i.e. -- that there are no simple constraints left and all the implications -- are solved. isSolvedWC :: WantedConstraints -> Bool -isSolvedWC WC {wc_simple = wc_simple, wc_impl = wc_impl} = - isEmptyBag wc_simple && allBag (isSolvedStatus . ic_status) wc_impl +isSolvedWC WC {wc_simple = wc_simple, wc_impl = wc_impl, wc_holes = holes} = + isEmptyBag wc_simple && allBag (isSolvedStatus . ic_status) wc_impl && isEmptyBag holes andWC :: WantedConstraints -> WantedConstraints -> WantedConstraints -andWC (WC { wc_simple = f1, wc_impl = i1 }) - (WC { wc_simple = f2, wc_impl = i2 }) +andWC (WC { wc_simple = f1, wc_impl = i1, wc_holes = h1 }) + (WC { wc_simple = f2, wc_impl = i2, wc_holes = h2 }) = WC { wc_simple = f1 `unionBags` f2 - , wc_impl = i1 `unionBags` i2 } + , wc_impl = i1 `unionBags` i2 + , wc_holes = h1 `unionBags` h2 } unionsWC :: [WantedConstraints] -> WantedConstraints unionsWC = foldr andWC emptyWC @@ -931,11 +961,16 @@ addInsols :: WantedConstraints -> Bag Ct -> WantedConstraints addInsols wc cts = wc { wc_simple = wc_simple wc `unionBags` cts } +addHole :: WantedConstraints -> Hole -> WantedConstraints +addHole wc hole + = wc { wc_holes = hole `consBag` wc_holes wc } + insolublesOnly :: WantedConstraints -> WantedConstraints -- Keep only the definitely-insoluble constraints -insolublesOnly (WC { wc_simple = simples, wc_impl = implics }) +insolublesOnly (WC { wc_simple = simples, wc_impl = implics, wc_holes = holes }) = WC { wc_simple = filterBag insolubleCt simples - , wc_impl = mapBag implic_insols_only implics } + , wc_impl = mapBag implic_insols_only implics + , wc_holes = filterBag isOutOfScopeHole holes } where implic_insols_only implic = implic { ic_wanted = insolublesOnly (ic_wanted implic) } @@ -953,9 +988,10 @@ insolubleImplic :: Implication -> Bool insolubleImplic ic = isInsolubleStatus (ic_status ic) insolubleWC :: WantedConstraints -> Bool -insolubleWC (WC { wc_impl = implics, wc_simple = simples }) +insolubleWC (WC { wc_impl = implics, wc_simple = simples, wc_holes = holes }) = anyBag insolubleCt simples || anyBag insolubleImplic implics + || anyBag isOutOfScopeHole holes -- See Note [Insoluble holes] insolubleCt :: Ct -> Bool -- Definitely insoluble, in particular /excluding/ type-hole constraints @@ -963,7 +999,6 @@ insolubleCt :: Ct -> Bool -- b) that is insoluble -- c) and does not arise from a Given insolubleCt ct - | isHoleCt ct = isOutOfScopeCt ct -- See Note [Insoluble holes] | not (insolubleEqCt ct) = False | arisesFromGivens ct = False -- See Note [Given insolubles] | otherwise = True @@ -986,11 +1021,17 @@ insolubleEqCt :: Ct -> Bool insolubleEqCt (CIrredCan { cc_status = InsolubleCIS }) = True insolubleEqCt _ = False +-- | Does this hole represent an "out of scope" error? +-- See Note [Insoluble holes] +isOutOfScopeHole :: Hole -> Bool +isOutOfScopeHole (Hole { hole_occ = occ }) = not (startsWithUnderscore occ) + instance Outputable WantedConstraints where - ppr (WC {wc_simple = s, wc_impl = i}) + ppr (WC {wc_simple = s, wc_impl = i, wc_holes = h}) = text "WC" <+> braces (vcat [ ppr_bag (text "wc_simple") s - , ppr_bag (text "wc_impl") i ]) + , ppr_bag (text "wc_impl") i + , ppr_bag (text "wc_holes") h ]) ppr_bag :: Outputable a => SDoc -> Bag a -> SDoc ppr_bag doc bag @@ -1035,7 +1076,7 @@ Hole constraints that ARE NOT treated as truly insoluble: a) type holes, arising from PartialTypeSignatures, b) "true" expression holes arising from TypedHoles -An "expression hole" or "type hole" constraint isn't really an error +An "expression hole" or "type hole" isn't really an error at all; it's a report saying "_ :: Int" here. But an out-of-scope variable masquerading as expression holes IS treated as truly insoluble, so that it trumps other errors during error reporting. @@ -1512,10 +1553,6 @@ ctFlavourRole (CTyEqCan { cc_ev = ev, cc_eq_rel = eq_rel }) = (ctEvFlavour ev, eq_rel) ctFlavourRole (CFunEqCan { cc_ev = ev }) = (ctEvFlavour ev, NomEq) -ctFlavourRole (CHoleCan { cc_ev = ev }) - = (ctEvFlavour ev, NomEq) -- NomEq: CHoleCans can be rewritten by - -- by nominal equalities but empahatically - -- not by representational equalities ctFlavourRole ct = ctEvFlavourRole (ctEvidence ct) ===================================== compiler/GHC/Tc/Types/Origin.hs ===================================== @@ -427,7 +427,9 @@ data CtOrigin -- We only need a CtOrigin on the first, because the location -- is pinned on the entire error message - | HoleOrigin + | ExprHoleOrigin OccName -- from an expression hole + | TypeHoleOrigin OccName -- from a type hole (partial type signature) + | PatCheckOrigin -- normalisation of a type during pattern-match checking | UnboundOccurrenceOf OccName | ListOrigin -- An overloaded list | BracketOrigin -- An overloaded quotation bracket @@ -640,7 +642,9 @@ pprCtO MCompOrigin = text "a statement in a monad comprehension" pprCtO ProcOrigin = text "a proc expression" pprCtO (TypeEqOrigin t1 t2 _ _)= text "a type equality" <+> sep [ppr t1, char '~', ppr t2] pprCtO AnnOrigin = text "an annotation" -pprCtO HoleOrigin = text "a use of" <+> quotes (text "_") +pprCtO (ExprHoleOrigin occ) = text "a use of" <+> quotes (ppr occ) +pprCtO (TypeHoleOrigin occ) = text "a use of wildcard" <+> quotes (ppr occ) +pprCtO PatCheckOrigin = text "a pattern-match completeness check" pprCtO ListOrigin = text "an overloaded list" pprCtO StaticOrigin = text "a static form" pprCtO BracketOrigin = text "a quotation bracket" ===================================== compiler/GHC/Tc/Utils/Monad.hs ===================================== @@ -98,14 +98,14 @@ module GHC.Tc.Utils.Monad( chooseUniqueOccTc, getConstraintVar, setConstraintVar, emitConstraints, emitStaticConstraints, emitSimple, emitSimples, - emitImplication, emitImplications, emitInsoluble, + emitImplication, emitImplications, emitInsoluble, emitHole, discardConstraints, captureConstraints, tryCaptureConstraints, pushLevelAndCaptureConstraints, pushTcLevelM_, pushTcLevelM, pushTcLevelsM, getTcLevel, setTcLevel, isTouchableTcM, getLclTypeEnv, setLclTypeEnv, traceTcConstraints, - emitNamedWildCardHoleConstraints, emitAnonWildCardHoleConstraint, + emitNamedTypeHole, emitAnonTypeHole, -- * Template Haskell context recordThUse, recordThSpliceUse, @@ -1569,12 +1569,11 @@ emitInsoluble ct ; lie_var <- getConstraintVar ; updTcRef lie_var (`addInsols` unitBag ct) } -emitInsolubles :: Cts -> TcM () -emitInsolubles cts - | isEmptyBag cts = return () - | otherwise = do { traceTc "emitInsolubles" (ppr cts) - ; lie_var <- getConstraintVar - ; updTcRef lie_var (`addInsols` cts) } +emitHole :: Hole -> TcM () +emitHole hole + = do { traceTc "emitHole" (ppr hole) + ; lie_var <- getConstraintVar + ; updTcRef lie_var (`addHole` hole) } -- | Throw out any constraints emitted by the thing_inside discardConstraints :: TcM a -> TcM a @@ -1644,34 +1643,28 @@ traceTcConstraints msg hang (text (msg ++ ": LIE:")) 2 (ppr lie) } -emitAnonWildCardHoleConstraint :: TcTyVar -> TcM () -emitAnonWildCardHoleConstraint tv - = do { ct_loc <- getCtLocM HoleOrigin Nothing - ; emitInsolubles $ unitBag $ - CHoleCan { cc_ev = CtDerived { ctev_pred = mkTyVarTy tv - , ctev_loc = ct_loc } - , cc_occ = mkTyVarOcc "_" - , cc_hole = TypeHole } } - -emitNamedWildCardHoleConstraints :: [(Name, TcTyVar)] -> TcM () -emitNamedWildCardHoleConstraints wcs - = do { ct_loc <- getCtLocM HoleOrigin Nothing - ; emitInsolubles $ listToBag $ - map (do_one ct_loc) wcs } +emitAnonTypeHole :: TcTyVar -> TcM () +emitAnonTypeHole tv + = do { ct_loc <- getCtLocM (TypeHoleOrigin occ) Nothing + ; let hole = Hole { hole_sort = TypeHole + , hole_occ = occ + , hole_ty = mkTyVarTy tv + , hole_loc = ct_loc } + ; emitHole hole } + where + occ = mkTyVarOcc "_" + +emitNamedTypeHole :: (Name, TcTyVar) -> TcM () +emitNamedTypeHole (name, tv) + = do { ct_loc <- setSrcSpan (nameSrcSpan name) $ + getCtLocM (TypeHoleOrigin occ) Nothing + ; let hole = Hole { hole_sort = TypeHole + , hole_occ = occ + , hole_ty = mkTyVarTy tv + , hole_loc = ct_loc } + ; emitHole hole } where - do_one :: CtLoc -> (Name, TcTyVar) -> Ct - do_one ct_loc (name, tv) - = CHoleCan { cc_ev = CtDerived { ctev_pred = mkTyVarTy tv - , ctev_loc = ct_loc' } - , cc_occ = occName name - , cc_hole = TypeHole } - where - real_span = case nameSrcSpan name of - RealSrcSpan span _ -> span - UnhelpfulSpan str -> pprPanic "emitNamedWildCardHoleConstraints" - (ppr name <+> quotes (ftext str)) - -- Wildcards are defined locally, and so have RealSrcSpans - ct_loc' = setCtLocSpan ct_loc real_span + occ = nameOccName name {- Note [Constraints and errors] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Tc/Utils/TcMType.hs ===================================== @@ -41,10 +41,11 @@ module GHC.Tc.Utils.TcMType ( -------------------------------- -- Creating new evidence variables newEvVar, newEvVars, newDict, - newWanted, newWanteds, newHoleCt, cloneWanted, cloneWC, + newWanted, newWanteds, cloneWanted, cloneWC, emitWanted, emitWantedEq, emitWantedEvVar, emitWantedEvVars, emitDerivedEqs, newTcEvBinds, newNoTcEvBinds, addTcEvBind, + emitNewExprHole, newCoercionHole, fillCoercionHole, isFilledCoercionHole, unpackCoercionHole, unpackCoercionHole_maybe, @@ -67,7 +68,7 @@ module GHC.Tc.Utils.TcMType ( -------------------------------- -- Zonking and tidying zonkTidyTcType, zonkTidyTcTypes, zonkTidyOrigin, - tidyEvVar, tidyCt, tidySkolemInfo, + tidyEvVar, tidyCt, tidyHole, tidySkolemInfo, zonkTcTyVar, zonkTcTyVars, zonkTcTyVarToTyVar, zonkTyVarTyVarPairs, zonkTyCoVarsAndFV, zonkTcTypeAndFV, zonkDTyCoVarSetAndFV, @@ -193,17 +194,6 @@ newWanted orig t_or_k pty newWanteds :: CtOrigin -> ThetaType -> TcM [CtEvidence] newWanteds orig = mapM (newWanted orig Nothing) --- | Create a new 'CHoleCan' 'Ct'. -newHoleCt :: HoleSort -> Id -> Type -> TcM Ct -newHoleCt hole ev ty = do - loc <- getCtLocM HoleOrigin Nothing - pure $ CHoleCan { cc_ev = CtWanted { ctev_pred = ty - , ctev_dest = EvVarDest ev - , ctev_nosh = WDeriv - , ctev_loc = loc } - , cc_occ = getOccName ev - , cc_hole = hole } - ---------------------------------------------- -- Cloning constraints ---------------------------------------------- @@ -286,6 +276,18 @@ emitWantedEvVar origin ty emitWantedEvVars :: CtOrigin -> [TcPredType] -> TcM [EvVar] emitWantedEvVars orig = mapM (emitWantedEvVar orig) +-- | Emit a new wanted expression hole +emitNewExprHole :: OccName -- of the hole + -> Id -- of the evidence + -> Type -> TcM () +emitNewExprHole occ ev_id ty + = do { loc <- getCtLocM (ExprHoleOrigin occ) (Just TypeLevel) + ; let hole = Hole { hole_sort = ExprHole ev_id + , hole_occ = getOccName ev_id + , hole_ty = ty + , hole_loc = loc } + ; emitHole hole } + newDict :: Class -> [TcType] -> TcM DictId newDict cls tys = do { name <- newSysName (mkDictOcc (getOccName cls)) @@ -2002,21 +2004,28 @@ zonkWC :: WantedConstraints -> TcM WantedConstraints zonkWC wc = zonkWCRec wc zonkWCRec :: WantedConstraints -> TcM WantedConstraints -zonkWCRec (WC { wc_simple = simple, wc_impl = implic }) +zonkWCRec (WC { wc_simple = simple, wc_impl = implic, wc_holes = holes }) = do { simple' <- zonkSimples simple ; implic' <- mapBagM zonkImplication implic - ; return (WC { wc_simple = simple', wc_impl = implic' }) } + ; holes' <- mapBagM zonkHole holes + ; return (WC { wc_simple = simple', wc_impl = implic', wc_holes = holes' }) } zonkSimples :: Cts -> TcM Cts zonkSimples cts = do { cts' <- mapBagM zonkCt cts ; traceTc "zonkSimples done:" (ppr cts') ; return cts' } +zonkHole :: Hole -> TcM Hole +zonkHole hole@(Hole { hole_ty = ty }) + = do { ty' <- zonkTcType ty + ; return (hole { hole_ty = ty' }) } + -- No need to zonk the Id in any ExprHole because we never look at it + -- until after the final zonk and desugaring + {- Note [zonkCt behaviour] ~~~~~~~~~~~~~~~~~~~~~~~~~~ zonkCt tries to maintain the canonical form of a Ct. For example, - a CDictCan should stay a CDictCan; - - a CHoleCan should stay a CHoleCan - a CIrredCan should stay a CIrredCan with its cc_status flag intact Why?, for example: @@ -2026,8 +2035,6 @@ Why?, for example: don't preserve a canonical form, @expandSuperClasses@ fails to expand superclasses. This is what happened in #11525. -- For CHoleCan, once we forget that it's a hole, we can never recover that info. - - For CIrredCan we want to see if a constraint is insoluble with insolubleWC On the other hand, we change CTyEqCan to CNonCanonical, because of all of @@ -2046,10 +2053,6 @@ creates e.g. a CDictCan where the cc_tyars are /not/ function free. zonkCt :: Ct -> TcM Ct -- See Note [zonkCt behaviour] -zonkCt ct@(CHoleCan { cc_ev = ev }) - = do { ev' <- zonkCtEvidence ev - ; return $ ct { cc_ev = ev' } } - zonkCt ct@(CDictCan { cc_ev = ev, cc_tyargs = args }) = do { ev' <- zonkCtEvidence ev ; args' <- mapM zonkTcType args @@ -2262,17 +2265,15 @@ zonkTidyOrigin env orig = return (env, orig) tidyCt :: TidyEnv -> Ct -> Ct -- Used only in error reporting tidyCt env ct - = ct { cc_ev = tidy_ev env (ctEvidence ct) } + = ct { cc_ev = tidy_ev (ctEvidence ct) } where - tidy_ev :: TidyEnv -> CtEvidence -> CtEvidence + tidy_ev :: CtEvidence -> CtEvidence -- NB: we do not tidy the ctev_evar field because we don't -- show it in error messages - tidy_ev env ctev@(CtGiven { ctev_pred = pred }) - = ctev { ctev_pred = tidyType env pred } - tidy_ev env ctev@(CtWanted { ctev_pred = pred }) - = ctev { ctev_pred = tidyType env pred } - tidy_ev env ctev@(CtDerived { ctev_pred = pred }) - = ctev { ctev_pred = tidyType env pred } + tidy_ev ctev = ctev { ctev_pred = tidyType env (ctev_pred ctev) } + +tidyHole :: TidyEnv -> Hole -> Hole +tidyHole env h@(Hole { hole_ty = ty }) = h { hole_ty = tidyType env ty } ---------------- tidyEvVar :: TidyEnv -> EvVar -> EvVar View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/57d2bba3908770d5ff94bb1a39585acfd7b7f82c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/57d2bba3908770d5ff94bb1a39585acfd7b7f82c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 2 22:16:27 2020 From: gitlab at gitlab.haskell.org (Richard Eisenberg) Date: Sat, 02 May 2020 18:16:27 -0400 Subject: [Git][ghc/ghc][wip/T17674] 548 commits: improve docs for HeaderInfo.getImports Message-ID: <5eadf13b5cb2e_61673f81cd4c695c8461270@gitlab.haskell.org.mail> Richard Eisenberg pushed to branch wip/T17674 at Glasgow Haskell Compiler / GHC Commits: 49f83a0d by Adam Sandberg Eriksson at 2020-01-12T21:28:09-05:00 improve docs for HeaderInfo.getImports [skip ci] - - - - - 9129210f by Matthew Pickering at 2020-01-12T21:28:47-05:00 Overloaded Quotation Brackets (#246) This patch implements overloaded quotation brackets which generalise the desugaring of all quotation forms in terms of a new minimal interface. The main change is that a quotation, for example, [e| 5 |], will now have type `Quote m => m Exp` rather than `Q Exp`. The `Quote` typeclass contains a single method for generating new names which is used when desugaring binding structures. The return type of functions from the `Lift` type class, `lift` and `liftTyped` have been restricted to `forall m . Quote m => m Exp` rather than returning a result in a Q monad. More details about the feature can be read in the GHC proposal. https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0246-overloaded-bracket.rst - - - - - 350e2b78 by Richard Eisenberg at 2020-01-12T21:29:27-05:00 Don't zap to Any; error instead This changes GHC's treatment of so-called Naughty Quantification Candidates to issue errors, instead of zapping to Any. Close #16775. No new test cases, because existing ones cover this well. - - - - - 0b5ddc7f by Brian Wignall at 2020-01-12T21:30:08-05:00 Fix more typos, via an improved Levenshtein-style corrector - - - - - f732dbec by Ben Gamari at 2020-01-12T21:30:49-05:00 gitlab-ci: Retain bindists used by head.hackage for longer Previously we would keep them for two weeks. However, on the stable branches two weeks can easily elapse with no pushes. - - - - - c8636da5 by Sylvain Henry at 2020-01-12T21:31:30-05:00 Fix LANG=C for readelf invocation in T14999 The test fails when used with LANG=fr_FR.UTF-8 - - - - - 077a88de by Jean-Baptiste Mazon at 2020-01-12T21:32:08-05:00 users-guide/debug-info: typo “behivior” - - - - - 61916c5d by Simon Peyton Jones at 2020-01-12T21:32:44-05:00 Add comments about TH levels - - - - - 1fd766ca by Simon Peyton Jones at 2020-01-12T21:32:44-05:00 Comments about constraint floating - - - - - de01427e by Simon Peyton Jones at 2020-01-12T21:32:45-05:00 Minor refactor around quantified constraints This patch clarifies a dark corner of quantified constraints. * See Note [Yukky eq_sel for a HoleDest] in TcSMonad * Minor refactor, breaking out new function TcInteract.doTopReactEqPred - - - - - 30be3bf1 by Simon Peyton Jones at 2020-01-12T21:32:45-05:00 Comments in TcHsType - - - - - c5977d4d by Sebastian Graf at 2020-01-16T05:58:58-05:00 Better documentation for mkEtaWW [skip ci] So that hopefully I understand it faster next time. Also got rid of the confusing `orig_expr`, which makes the call site in `etaExpand` look out of sync with the passed `n` (which is not the original `n`). - - - - - 22c0bdc3 by John Ericson at 2020-01-16T05:59:37-05:00 Handle TagToEnum in the same big case as the other primops Before, it was a panic because it was handled above. But there must have been an error in my reasoning (another caller?) because #17442 reported the panic was hit. But, rather than figuring out what happened, I can just make it impossible by construction. By adding just a bit more bureaucracy in the return types, I can handle TagToEnum in the same case as all the others, so the big case is is now total, and the panic is removed. Fixes #17442 - - - - - ee5d63f4 by John Ericson at 2020-01-16T05:59:37-05:00 Get rid of OpDest `OpDest` was basically a defunctionalization. Just turn the code that cased on it into those functions, and call them directly. - - - - - 1ff55226 by John Ericson at 2020-01-16T06:00:16-05:00 Remove special case case of bool during STG -> C-- Allow removing the no longer needed cgPrimOp, getting rid of a small a small layer violation too. Change which made the special case no longer needed was #6135 / 6579a6c73082387f82b994305011f011d9d8382b, which dates back to 2013, making me feel better. - - - - - f416fe64 by Adam Wespiser at 2020-01-16T06:00:53-05:00 replace dead html link (fixes #17661) - - - - - f6bf2ce8 by Sebastian Graf at 2020-01-16T06:01:32-05:00 Revert "`exprOkForSpeculation` for Note [IO hack in the demand analyser]" This reverts commit ce64b397777408731c6dd3f5c55ea8415f9f565b on the grounds of the regression it would introduce in a couple of packages. Fixes #17653. Also undoes a slight metric increase in #13701 introduced by that commit that we didn't see prior to !1983. Metric Decrease: T13701 - - - - - a71323ff by Ben Gamari at 2020-01-17T08:43:16-05:00 gitlab-ci: Don't FORCE_SYMLINKS on Windows Not all runners have symlink permissions enabled. - - - - - 0499e3bc by Ömer Sinan Ağacan at 2020-01-20T15:31:33-05:00 Fix +RTS -Z flag documentation Stack squeezing is done on context switch, not on GC or stack overflow. Fix the documentation. Fixes #17685 [ci skip] - - - - - a661df91 by Ömer Sinan Ağacan at 2020-01-20T15:32:13-05:00 Document Stg.FVs module Fixes #17662 [ci skip] - - - - - db24e480 by Ben Gamari at 2020-01-20T15:32:52-05:00 llvmGen: Don't trash STG registers Fixes #13904. - - - - - f3d7fdb3 by Ben Gamari at 2020-01-20T15:32:52-05:00 llvmGen: Fix typo in readnone attribute - - - - - 442751c6 by Ben Gamari at 2020-01-20T15:32:52-05:00 llvmGen: Add lower-expect to the -O0 optimisation set @kavon says that this will improve block layout for stack checks. - - - - - e90ecc93 by Ben Gamari at 2020-01-20T15:32:52-05:00 llvmGen: Fix #14251 Fixes the calling convention for functions passing raw SSE-register values by adding padding as needed to get the values in the right registers. This problem cropped up when some args were unused an dropped from the live list. This folds together 2e23e1c7de01c92b038e55ce53d11bf9db993dd4 and 73273be476a8cc6c13368660b042b3b0614fd928 previously from @kavon. Metric Increase: T12707 ManyConstructors - - - - - 66e511a4 by Ben Gamari at 2020-01-20T15:33:28-05:00 testsuite: Preserve more information in framework failures Namely print the entire exception in hopes that this will help track down #17649. - - - - - b62b8cea by Ömer Sinan Ağacan at 2020-01-20T15:34:06-05:00 Remove deprecated -smp flag It was deprecated in 2012 with 46258b40 - - - - - 0c04a86a by Ben Gamari at 2020-01-20T15:34:43-05:00 gitlab-ci: Reenable submodule linter - - - - - 2bfabd22 by Ben Gamari at 2020-01-20T15:34:43-05:00 gitlab-ci: Allow submodule cleaning to fail on Windows Currently CI is inexplicably failing with ``` $ git submodule foreach git clean -xdf fatal: not a git repository: libffi-tarballs/../.git/modules/libffi-tarballs ``` I have no idea how this working tree got into such a state but we do need to fail more gracefully when it happens. Consequently, we allow the cleaning step to fail. - - - - - 14bced99 by Xavier Denis at 2020-01-20T15:35:21-05:00 Put the docs for :instances in alphabetical position - - - - - 7e0bb82b by Ben Gamari at 2020-01-20T15:35:57-05:00 Add missing Note [Improvement from Ground Wanteds] Closes #17659. - - - - - 17e43a7c by Ben Gamari at 2020-01-20T15:36:32-05:00 unregisterised: Fix declaration for stg_NO_FINALIZER Previously it had a redundant _entry suffix. We never noticed this previously presumably because we never generated references to it (however hard to believe this may be). However, it did start failing in !1304. - - - - - 3dae006f by PHO at 2020-01-20T15:37:08-05:00 Avoid ./configure failure on NetBSD - - - - - 738e2912 by Ben Gamari at 2020-01-24T13:42:56-05:00 testsuite: Widen acceptance window of T1969 I have seen >20% fluctuations in this number, leading to spurious failures. - - - - - ad4eb7a7 by Gabor Greif at 2020-01-25T05:19:07-05:00 Document the fact, that openFileBlocking can consume an OS thread indefinitely. Also state that a deadlock can happen with the non-threaded runtime. [ci skip] - - - - - be910728 by Sebastian Graf at 2020-01-25T05:19:46-05:00 `-ddump-str-signatures` dumps Text, not STG [skip ci] - - - - - 0e57d8a1 by Ömer Sinan Ağacan at 2020-01-25T05:20:27-05:00 Fix chaining tagged and untagged ptrs in compacting GC Currently compacting GC has the invariant that in a chain all fields are tagged the same. However this does not really hold: root pointers are not tagged, so when we thread a root we initialize a chain without a tag. When the pointed objects is evaluated and we have more pointers to it from the heap, we then add *tagged* fields to the chain (because pointers to it from the heap are tagged), ending up chaining fields with different tags (pointers from roots are NOT tagged, pointers from heap are). This breaks the invariant and as a result compacting GC turns tagged pointers into non-tagged. This later causes problem in the generated code where we do reads assuming that the pointer is aligned, e.g. 0x7(%rax) -- assumes that pointer is tagged 1 which causes misaligned reads. This caused #17088. We fix this using the "pointer tagging for large families" patch (#14373, !1742): - With the pointer tagging patch the GC can know what the tagged pointer to a CONSTR should be (previously we'd need to know the family size -- large families are always tagged 1, small families are tagged depending on the constructor). - Since we now know what the tags should be we no longer need to store the pointer tag in the info table pointers when forming chains in the compacting GC. As a result we no longer need to tag pointers in chains with 1/2 depending on whether the field points to an info table pointer, or to another field: an info table pointer is always tagged 0, everything else in the chain is tagged 1. The lost tags in pointers can be retrieved by looking at the info table. Finally, instead of using tag 1 for fields and tag 0 for info table pointers, we use two different tags for fields: - 1 for fields that have untagged pointers - 2 for fields that have tagged pointers When unchaining we then look at the pointer to a field, and depending on its tag we either leave a tagged pointer or an untagged pointer in the field. This allows chaining untagged and tagged fields together in compacting GC. Fixes #17088 Nofib results ------------- Binaries are smaller because of smaller `Compact.c` code. make mode=fast EXTRA_RUNTEST_OPTS="-cachegrind" EXTRA_HC_OPTS="-with-rtsopts=-c" NoFibRuns=1 -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS -0.3% 0.0% +0.0% +0.0% +0.0% CSD -0.3% 0.0% +0.0% +0.0% +0.0% FS -0.3% 0.0% +0.0% -0.0% -0.0% S -0.3% 0.0% +5.4% +0.8% +3.9% VS -0.3% 0.0% +0.0% -0.0% -0.0% VSD -0.3% 0.0% -0.0% -0.0% -0.2% VSM -0.3% 0.0% +0.0% +0.0% +0.0% anna -0.1% 0.0% +0.0% +0.0% +0.0% ansi -0.3% 0.0% +0.1% +0.0% +0.0% atom -0.2% 0.0% +0.0% +0.0% +0.0% awards -0.2% 0.0% +0.0% 0.0% -0.0% banner -0.3% 0.0% +0.0% +0.0% +0.0% bernouilli -0.3% 0.0% +0.1% +0.0% +0.0% binary-trees -0.2% 0.0% +0.0% 0.0% +0.0% boyer -0.3% 0.0% +0.2% +0.0% +0.0% boyer2 -0.2% 0.0% +0.2% +0.1% +0.0% bspt -0.2% 0.0% +0.0% +0.0% +0.0% cacheprof -0.2% 0.0% +0.0% +0.0% +0.0% calendar -0.3% 0.0% +0.0% +0.0% +0.0% cichelli -0.3% 0.0% +1.1% +0.2% +0.5% circsim -0.2% 0.0% +0.0% -0.0% -0.0% clausify -0.3% 0.0% +0.0% -0.0% -0.0% comp_lab_zift -0.2% 0.0% +0.0% +0.0% +0.0% compress -0.3% 0.0% +0.0% +0.0% +0.0% compress2 -0.3% 0.0% +0.0% -0.0% -0.0% constraints -0.3% 0.0% +0.2% +0.1% +0.1% cryptarithm1 -0.3% 0.0% +0.0% -0.0% 0.0% cryptarithm2 -0.3% 0.0% +0.0% +0.0% +0.0% cse -0.3% 0.0% +0.0% +0.0% +0.0% digits-of-e1 -0.3% 0.0% +0.0% +0.0% +0.0% digits-of-e2 -0.3% 0.0% +0.0% +0.0% -0.0% dom-lt -0.2% 0.0% +0.0% +0.0% +0.0% eliza -0.2% 0.0% +0.0% +0.0% +0.0% event -0.3% 0.0% +0.1% +0.0% -0.0% exact-reals -0.2% 0.0% +0.0% +0.0% +0.0% exp3_8 -0.3% 0.0% +0.0% +0.0% +0.0% expert -0.2% 0.0% +0.0% +0.0% +0.0% fannkuch-redux -0.3% 0.0% -0.0% -0.0% -0.0% fasta -0.3% 0.0% +0.0% +0.0% +0.0% fem -0.2% 0.0% +0.1% +0.0% +0.0% fft -0.2% 0.0% +0.0% -0.0% -0.0% fft2 -0.2% 0.0% +0.0% -0.0% +0.0% fibheaps -0.3% 0.0% +0.0% -0.0% -0.0% fish -0.3% 0.0% +0.0% +0.0% +0.0% fluid -0.2% 0.0% +0.4% +0.1% +0.1% fulsom -0.2% 0.0% +0.0% +0.0% +0.0% gamteb -0.2% 0.0% +0.1% +0.0% +0.0% gcd -0.3% 0.0% +0.0% +0.0% +0.0% gen_regexps -0.3% 0.0% +0.0% -0.0% -0.0% genfft -0.3% 0.0% +0.0% +0.0% +0.0% gg -0.2% 0.0% +0.7% +0.3% +0.2% grep -0.2% 0.0% +0.0% +0.0% +0.0% hidden -0.2% 0.0% +0.0% +0.0% +0.0% hpg -0.2% 0.0% +0.1% +0.0% +0.0% ida -0.3% 0.0% +0.0% +0.0% +0.0% infer -0.2% 0.0% +0.0% -0.0% -0.0% integer -0.3% 0.0% +0.0% +0.0% +0.0% integrate -0.2% 0.0% +0.0% +0.0% +0.0% k-nucleotide -0.2% 0.0% +0.0% +0.0% -0.0% kahan -0.3% 0.0% -0.0% -0.0% -0.0% knights -0.3% 0.0% +0.0% -0.0% -0.0% lambda -0.3% 0.0% +0.0% -0.0% -0.0% last-piece -0.3% 0.0% +0.0% +0.0% +0.0% lcss -0.3% 0.0% +0.0% +0.0% 0.0% life -0.3% 0.0% +0.0% -0.0% -0.0% lift -0.2% 0.0% +0.0% +0.0% +0.0% linear -0.2% 0.0% +0.0% +0.0% +0.0% listcompr -0.3% 0.0% +0.0% +0.0% +0.0% listcopy -0.3% 0.0% +0.0% +0.0% +0.0% maillist -0.3% 0.0% +0.0% -0.0% -0.0% mandel -0.2% 0.0% +0.0% +0.0% +0.0% mandel2 -0.3% 0.0% +0.0% +0.0% +0.0% mate -0.2% 0.0% +0.0% +0.0% +0.0% minimax -0.3% 0.0% +0.0% +0.0% +0.0% mkhprog -0.2% 0.0% +0.0% +0.0% +0.0% multiplier -0.3% 0.0% +0.0% -0.0% -0.0% n-body -0.2% 0.0% -0.0% -0.0% -0.0% nucleic2 -0.2% 0.0% +0.0% +0.0% +0.0% para -0.2% 0.0% +0.0% -0.0% -0.0% paraffins -0.3% 0.0% +0.0% -0.0% -0.0% parser -0.2% 0.0% +0.0% +0.0% +0.0% parstof -0.2% 0.0% +0.8% +0.2% +0.2% pic -0.2% 0.0% +0.1% -0.1% -0.1% pidigits -0.3% 0.0% +0.0% +0.0% +0.0% power -0.2% 0.0% +0.0% -0.0% -0.0% pretty -0.3% 0.0% -0.0% -0.0% -0.1% primes -0.3% 0.0% +0.0% +0.0% -0.0% primetest -0.2% 0.0% +0.0% -0.0% -0.0% prolog -0.3% 0.0% +0.0% -0.0% -0.0% puzzle -0.3% 0.0% +0.0% +0.0% +0.0% queens -0.3% 0.0% +0.0% +0.0% +0.0% reptile -0.2% 0.0% +0.2% +0.1% +0.0% reverse-complem -0.3% 0.0% +0.0% +0.0% +0.0% rewrite -0.3% 0.0% +0.0% -0.0% -0.0% rfib -0.2% 0.0% +0.0% +0.0% -0.0% rsa -0.2% 0.0% +0.0% +0.0% +0.0% scc -0.3% 0.0% -0.0% -0.0% -0.1% sched -0.3% 0.0% +0.0% +0.0% +0.0% scs -0.2% 0.0% +0.1% +0.0% +0.0% simple -0.2% 0.0% +3.4% +1.0% +1.8% solid -0.2% 0.0% +0.0% +0.0% +0.0% sorting -0.3% 0.0% +0.0% +0.0% +0.0% spectral-norm -0.2% 0.0% -0.0% -0.0% -0.0% sphere -0.2% 0.0% +0.0% +0.0% +0.0% symalg -0.2% 0.0% +0.0% +0.0% +0.0% tak -0.3% 0.0% +0.0% +0.0% -0.0% transform -0.2% 0.0% +0.2% +0.1% +0.1% treejoin -0.3% 0.0% +0.2% -0.0% -0.1% typecheck -0.3% 0.0% +0.0% +0.0% +0.0% veritas -0.1% 0.0% +0.0% +0.0% +0.0% wang -0.2% 0.0% +0.0% -0.0% -0.0% wave4main -0.3% 0.0% +0.0% -0.0% -0.0% wheel-sieve1 -0.3% 0.0% +0.0% -0.0% -0.0% wheel-sieve2 -0.3% 0.0% +0.0% -0.0% -0.0% x2n1 -0.3% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min -0.3% 0.0% -0.0% -0.1% -0.2% Max -0.1% 0.0% +5.4% +1.0% +3.9% Geometric Mean -0.3% -0.0% +0.1% +0.0% +0.1% -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- circsim -0.2% 0.0% +1.6% +0.4% +0.7% constraints -0.3% 0.0% +4.3% +1.5% +2.3% fibheaps -0.3% 0.0% +3.5% +1.2% +1.3% fulsom -0.2% 0.0% +3.6% +1.2% +1.8% gc_bench -0.3% 0.0% +4.1% +1.3% +2.3% hash -0.3% 0.0% +6.6% +2.2% +3.6% lcss -0.3% 0.0% +0.7% +0.2% +0.7% mutstore1 -0.3% 0.0% +4.8% +1.4% +2.8% mutstore2 -0.3% 0.0% +3.4% +1.0% +1.7% power -0.2% 0.0% +2.7% +0.6% +1.9% spellcheck -0.3% 0.0% +1.1% +0.4% +0.4% -------------------------------------------------------------------------------- Min -0.3% 0.0% +0.7% +0.2% +0.4% Max -0.2% 0.0% +6.6% +2.2% +3.6% Geometric Mean -0.3% +0.0% +3.3% +1.0% +1.8% Metric changes -------------- While it sounds ridiculous, this change causes increased allocations in the following tests. We concluded that this change can't cause a difference in allocations and decided to land this patch. Fluctuations in "bytes allocated" metric is tracked in #17686. Metric Increase: Naperian T10547 T12150 T12234 T12425 T13035 T5837 T6048 - - - - - 8038cbd9 by Sebastian Graf at 2020-01-25T05:21:05-05:00 PmCheck: Formulate as translation between Clause Trees We used to check `GrdVec`s arising from multiple clauses and guards in isolation. That resulted in a split between `pmCheck` and `pmCheckGuards`, the implementations of which were similar, but subtly different in detail. Also the throttling mechanism described in `Note [Countering exponential blowup]` ultimately got quite complicated because it had to cater for both checking functions. This patch realises that pattern match checking doesn't just consider single guarded RHSs, but that it's always a whole set of clauses, each of which can have multiple guarded RHSs in turn. We do so by translating a list of `Match`es to a `GrdTree`: ```haskell data GrdTree = Rhs !RhsInfo | Guard !PmGrd !GrdTree -- captures lef-to-right match semantics | Sequence !GrdTree !GrdTree -- captures top-to-bottom match semantics | Empty -- For -XEmptyCase, neutral element of Sequence ``` Then we have a function `checkGrdTree` that matches a given `GrdTree` against an incoming set of values, represented by `Deltas`: ```haskell checkGrdTree :: GrdTree -> Deltas -> CheckResult ... ``` Throttling is isolated to the `Sequence` case and becomes as easy as one would expect: When the union of uncovered values becomes too big, just return the original incoming `Deltas` instead (which is always a superset of the union, thus a sound approximation). The returned `CheckResult` contains two things: 1. The set of values that were not covered by any of the clauses, for exhaustivity warnings. 2. The `AnnotatedTree` that enriches the syntactic structure of the input program with divergence and inaccessibility information. This is `AnnotatedTree`: ```haskell data AnnotatedTree = AccessibleRhs !RhsInfo | InaccessibleRhs !RhsInfo | MayDiverge !AnnotatedTree | SequenceAnn !AnnotatedTree !AnnotatedTree | EmptyAnn ``` Crucially, `MayDiverge` asserts that the tree may force diverging values, so not all of its wrapped clauses can be redundant. While the set of uncovered values can be used to generate the missing equations for warning messages, redundant and proper inaccessible equations can be extracted from `AnnotatedTree` by `redundantAndInaccessibleRhss`. For this to work properly, the interface to the Oracle had to change. There's only `addPmCts` now, which takes a bag of `PmCt`s. There's a whole bunch of `PmCt` variants to replace the different oracle functions from before. The new `AnnotatedTree` structure allows for more accurate warning reporting (as evidenced by a number of changes spread throughout GHC's code base), thus we fix #17465. Fixes #17646 on the go. Metric Decrease: T11822 T9233 PmSeriesS haddock.compiler - - - - - 86966d48 by Sebastian Graf at 2020-01-25T05:21:05-05:00 PmCheck: Properly handle constructor-bound type variables In https://gitlab.haskell.org/ghc/ghc/merge_requests/2192#note_246551 Simon convinced me that ignoring type variables existentially bound by data constructors have to be the same way as value binders. Sadly I couldn't think of a regression test, but I'm confident that this change strictly improves on the status quo. - - - - - c3fde723 by Ryan Scott at 2020-01-25T05:21:40-05:00 Handle local fixity declarations in DsMeta properly `DsMeta.rep_sig` used to skip over `FixSig` entirely, which had the effect of causing local fixity declarations to be dropped when quoted in Template Haskell. But there is no good reason for this state of affairs, as the code in `DsMeta.repFixD` (which handles top-level fixity declarations) handles local fixity declarations just fine. This patch factors out the necessary parts of `repFixD` so that they can be used in `rep_sig` as well. There was one minor complication: the fixity signatures for class methods in each `HsGroup` were stored both in `FixSig`s _and_ the list of `LFixitySig`s for top-level fixity signatures, so I needed to take action to prevent fixity signatures for class methods being converted to `Dec`s twice. I tweaked `RnSource.add` to avoid putting these fixity signatures in two places and added `Note [Top-level fixity signatures in an HsGroup]` in `GHC.Hs.Decls` to explain the new design. Fixes #17608. Bumps the Haddock submodule. - - - - - 6e2d9ee2 by Sylvain Henry at 2020-01-25T05:22:20-05:00 Module hierarchy: Cmm (cf #13009) - - - - - 8b726534 by PHO at 2020-01-25T05:23:01-05:00 Fix rts allocateExec() on NetBSD Similar to SELinux, NetBSD "PaX mprotect" prohibits marking a page mapping both writable and executable at the same time. Use libffi which knows how to work around it. - - - - - 6eb566a0 by Xavier Denis at 2020-01-25T05:23:39-05:00 Add ghc-in-ghci for stack based builds - - - - - b1a32170 by Xavier Denis at 2020-01-25T05:23:39-05:00 Create ghci.cabal.sh - - - - - 0a5e4f5f by Sylvain Henry at 2020-01-25T05:24:19-05:00 Split glasgow_exts into several files (#17316) - - - - - b3e5c678 by Ben Gamari at 2020-01-25T05:24:57-05:00 hadrian: Throw error on duplicate-named flavours Throw an error if the user requests a flavour for which there is more than one match. Fixes #17156. - - - - - 0940b59a by Ryan Scott at 2020-01-25T08:15:05-05:00 Do not bring visible foralls into scope in hsScopedTvs Previously, `hsScopedTvs` (and its cousin `hsWcScopedTvs`) pretended that visible dependent quantification could not possibly happen at the term level, and cemented that assumption with an `ASSERT`: ```hs hsScopedTvs (HsForAllTy { hst_fvf = vis_flag, ... }) = ASSERT( vis_flag == ForallInvis ) ... ``` It turns out that this assumption is wrong. You can end up tripping this `ASSERT` if you stick it to the man and write a type for a term that uses visible dependent quantification anyway, like in this example: ```hs {-# LANGUAGE ScopedTypeVariables #-} x :: forall a -> a -> a x = x ``` That won't typecheck, but that's not the point. Before the typechecker has a chance to reject this, the renamer will try to use `hsScopedTvs` to bring `a` into scope over the body of `x`, since `a` is quantified by a `forall`. This, in turn, causes the `ASSERT` to fail. Bummer. Instead of walking on this dangerous ground, this patch makes GHC adopt a more hardline stance by pattern-matching directly on `ForallInvis` in `hsScopedTvs`: ```hs hsScopedTvs (HsForAllTy { hst_fvf = ForallInvis, ... }) = ... ``` Now `a` will not be brought over the body of `x` at all (which is how it should be), there's no chance of the `ASSERT` failing anymore (as it's gone), and best of all, the behavior of `hsScopedTvs` does not change. Everyone wins! Fixes #17687. - - - - - 1132602f by Ryan Scott at 2020-01-27T10:03:42-05:00 Use splitLHs{ForAll,Sigma}TyInvis throughout the codebase Richard points out in #17688 that we use `splitLHsForAllTy` and `splitLHsSigmaTy` in places that we ought to be using the corresponding `-Invis` variants instead, identifying two bugs that are caused by this oversight: * Certain TH-quoted type signatures, such as those that appear in quoted `SPECIALISE` pragmas, silently turn visible `forall`s into invisible `forall`s. * When quoted, the type `forall a -> (a ~ a) => a` will turn into `forall a -> a` due to a bug in `DsMeta.repForall` that drops contexts that follow visible `forall`s. These are both ultimately caused by the fact that `splitLHsForAllTy` and `splitLHsSigmaTy` split apart visible `forall`s in addition to invisible ones. This patch cleans things up: * We now use `splitLHsForAllTyInvis` and `splitLHsSigmaTyInvis` throughout the codebase. Relatedly, the `splitLHsForAllTy` and `splitLHsSigmaTy` have been removed, as they are easy to misuse. * `DsMeta.repForall` now only handles invisible `forall`s to reduce the chance for confusion with visible `forall`s, which need to be handled differently. I also renamed it from `repForall` to `repForallT` to emphasize that its distinguishing characteristic is the fact that it desugars down to `L.H.TH.Syntax.ForallT`. Fixes #17688. - - - - - 97d0b0a3 by Matthew Pickering at 2020-01-27T10:04:19-05:00 Make Block.h compile with c++ compilers - - - - - 4bada77d by Tom Ellis at 2020-01-27T12:30:46-05:00 Disable two warnings for files that trigger them incomplete-uni-patterns and incomplete-record-updates will be in -Wall at a future date, so prepare for that by disabling those warnings on files that trigger them. - - - - - 0188404a by Tom Ellis at 2020-01-27T12:30:46-05:00 Add two warnings to stage 2 build - - - - - acae02c1 by Tom Ellis at 2020-01-27T12:30:46-05:00 Add two warnings to Hadrian - - - - - bf38a20e by Sylvain Henry at 2020-01-31T02:46:15-05:00 Call `interpretPackageEnv` from `setSessionDynFlags` interpretPackageEnv modifies the flags by reading the dreaded package environments. It is much less surprising to call it from `setSessionDynFlags` instead of reading package environments as a side-effect of `initPackages`. - - - - - 29c701c1 by Sylvain Henry at 2020-01-31T02:46:15-05:00 Refactor package related code The package terminology is a bit of a mess. Cabal packages contain components. Instances of these components when built with some flags/options/dependencies are called units. Units are registered into package databases and their metadata are called PackageConfig. GHC only knows about package databases containing units. It is a sad mismatch not fixed by this patch (we would have to rename parameters such as `package-id <unit-id>` which would affect users). This patch however fixes the following internal names: - Renames PackageConfig into UnitInfo. - Rename systemPackageConfig into globalPackageDatabase[Path] - Rename PkgConfXX into PkgDbXX - Rename pkgIdMap into unitIdMap - Rename ModuleToPkgDbAll into ModuleNameProvidersMap - Rename lookupPackage into lookupUnit - Add comments on DynFlags package related fields It also introduces a new `PackageDatabase` datatype instead of explicitly passing the following tuple: `(FilePath,[PackageConfig])`. The `pkgDatabase` field in `DynFlags` now contains the unit info for each unit of each package database exactly as they have been read from disk. Previously the command-line flag `-distrust-all-packages` would modify these unit info. Now this flag only affects the "dynamic" consolidated package state found in `pkgState` field. It makes sense because `initPackages` could be called first with this `distrust-all-packages` flag set and then again (using ghc-api) without and it should work (package databases are not read again from disk when `initPackages` is called the second time). Bump haddock submodule - - - - - 942c7148 by Ben Gamari at 2020-01-31T02:46:54-05:00 rename: Eliminate usage of mkVarOccUnique Replacing it with `newSysName`. Fixes #17061. - - - - - 41117d71 by Ben Gamari at 2020-01-31T02:47:31-05:00 base: Use one-shot kqueue on macOS The underlying reason requiring that one-shot usage be disabled (#13903) has been fixed. Closes #15768. - - - - - 01b15b83 by Ben Gamari at 2020-01-31T02:48:08-05:00 testsuite: Don't crash on encoding failure in print If the user doesn't use a Unicode locale then the testsuite driver would previously throw framework failures due to encoding failures. We now rather use the `replace` error-handling strategy. - - - - - c846618a by Ömer Sinan Ağacan at 2020-01-31T12:21:10+03:00 Do CafInfo/SRT analysis in Cmm This patch removes all CafInfo predictions and various hacks to preserve predicted CafInfos from the compiler and assigns final CafInfos to interface Ids after code generation. SRT analysis is extended to support static data, and Cmm generator is modified to allow generating static_link fields after SRT analysis. This also fixes `-fcatch-bottoms`, which introduces error calls in case expressions in CorePrep, which runs *after* CoreTidy (which is where we decide on CafInfos) and turns previously non-CAFFY things into CAFFY. Fixes #17648 Fixes #9718 Evaluation ========== NoFib ----- Boot with: `make boot mode=fast` Run: `make mode=fast EXTRA_RUNTEST_OPTS="-cachegrind" NoFibRuns=1` -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS -0.0% 0.0% -0.0% -0.0% -0.0% CSD -0.0% 0.0% -0.0% -0.0% -0.0% FS -0.0% 0.0% -0.0% -0.0% -0.0% S -0.0% 0.0% -0.0% -0.0% -0.0% VS -0.0% 0.0% -0.0% -0.0% -0.0% VSD -0.0% 0.0% -0.0% -0.0% -0.5% VSM -0.0% 0.0% -0.0% -0.0% -0.0% anna -0.1% 0.0% -0.0% -0.0% -0.0% ansi -0.0% 0.0% -0.0% -0.0% -0.0% atom -0.0% 0.0% -0.0% -0.0% -0.0% awards -0.0% 0.0% -0.0% -0.0% -0.0% banner -0.0% 0.0% -0.0% -0.0% -0.0% bernouilli -0.0% 0.0% -0.0% -0.0% -0.0% binary-trees -0.0% 0.0% -0.0% -0.0% -0.0% boyer -0.0% 0.0% -0.0% -0.0% -0.0% boyer2 -0.0% 0.0% -0.0% -0.0% -0.0% bspt -0.0% 0.0% -0.0% -0.0% -0.0% cacheprof -0.0% 0.0% -0.0% -0.0% -0.0% calendar -0.0% 0.0% -0.0% -0.0% -0.0% cichelli -0.0% 0.0% -0.0% -0.0% -0.0% circsim -0.0% 0.0% -0.0% -0.0% -0.0% clausify -0.0% 0.0% -0.0% -0.0% -0.0% comp_lab_zift -0.0% 0.0% -0.0% -0.0% -0.0% compress -0.0% 0.0% -0.0% -0.0% -0.0% compress2 -0.0% 0.0% -0.0% -0.0% -0.0% constraints -0.0% 0.0% -0.0% -0.0% -0.0% cryptarithm1 -0.0% 0.0% -0.0% -0.0% -0.0% cryptarithm2 -0.0% 0.0% -0.0% -0.0% -0.0% cse -0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e1 -0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e2 -0.0% 0.0% -0.0% -0.0% -0.0% dom-lt -0.0% 0.0% -0.0% -0.0% -0.0% eliza -0.0% 0.0% -0.0% -0.0% -0.0% event -0.0% 0.0% -0.0% -0.0% -0.0% exact-reals -0.0% 0.0% -0.0% -0.0% -0.0% exp3_8 -0.0% 0.0% -0.0% -0.0% -0.0% expert -0.0% 0.0% -0.0% -0.0% -0.0% fannkuch-redux -0.0% 0.0% -0.0% -0.0% -0.0% fasta -0.0% 0.0% -0.0% -0.0% -0.0% fem -0.0% 0.0% -0.0% -0.0% -0.0% fft -0.0% 0.0% -0.0% -0.0% -0.0% fft2 -0.0% 0.0% -0.0% -0.0% -0.0% fibheaps -0.0% 0.0% -0.0% -0.0% -0.0% fish -0.0% 0.0% -0.0% -0.0% -0.0% fluid -0.1% 0.0% -0.0% -0.0% -0.0% fulsom -0.0% 0.0% -0.0% -0.0% -0.0% gamteb -0.0% 0.0% -0.0% -0.0% -0.0% gcd -0.0% 0.0% -0.0% -0.0% -0.0% gen_regexps -0.0% 0.0% -0.0% -0.0% -0.0% genfft -0.0% 0.0% -0.0% -0.0% -0.0% gg -0.0% 0.0% -0.0% -0.0% -0.0% grep -0.0% 0.0% -0.0% -0.0% -0.0% hidden -0.0% 0.0% -0.0% -0.0% -0.0% hpg -0.1% 0.0% -0.0% -0.0% -0.0% ida -0.0% 0.0% -0.0% -0.0% -0.0% infer -0.0% 0.0% -0.0% -0.0% -0.0% integer -0.0% 0.0% -0.0% -0.0% -0.0% integrate -0.0% 0.0% -0.0% -0.0% -0.0% k-nucleotide -0.0% 0.0% -0.0% -0.0% -0.0% kahan -0.0% 0.0% -0.0% -0.0% -0.0% knights -0.0% 0.0% -0.0% -0.0% -0.0% lambda -0.0% 0.0% -0.0% -0.0% -0.0% last-piece -0.0% 0.0% -0.0% -0.0% -0.0% lcss -0.0% 0.0% -0.0% -0.0% -0.0% life -0.0% 0.0% -0.0% -0.0% -0.0% lift -0.0% 0.0% -0.0% -0.0% -0.0% linear -0.1% 0.0% -0.0% -0.0% -0.0% listcompr -0.0% 0.0% -0.0% -0.0% -0.0% listcopy -0.0% 0.0% -0.0% -0.0% -0.0% maillist -0.0% 0.0% -0.0% -0.0% -0.0% mandel -0.0% 0.0% -0.0% -0.0% -0.0% mandel2 -0.0% 0.0% -0.0% -0.0% -0.0% mate -0.0% 0.0% -0.0% -0.0% -0.0% minimax -0.0% 0.0% -0.0% -0.0% -0.0% mkhprog -0.0% 0.0% -0.0% -0.0% -0.0% multiplier -0.0% 0.0% -0.0% -0.0% -0.0% n-body -0.0% 0.0% -0.0% -0.0% -0.0% nucleic2 -0.0% 0.0% -0.0% -0.0% -0.0% para -0.0% 0.0% -0.0% -0.0% -0.0% paraffins -0.0% 0.0% -0.0% -0.0% -0.0% parser -0.1% 0.0% -0.0% -0.0% -0.0% parstof -0.1% 0.0% -0.0% -0.0% -0.0% pic -0.0% 0.0% -0.0% -0.0% -0.0% pidigits -0.0% 0.0% -0.0% -0.0% -0.0% power -0.0% 0.0% -0.0% -0.0% -0.0% pretty -0.0% 0.0% -0.3% -0.4% -0.4% primes -0.0% 0.0% -0.0% -0.0% -0.0% primetest -0.0% 0.0% -0.0% -0.0% -0.0% prolog -0.0% 0.0% -0.0% -0.0% -0.0% puzzle -0.0% 0.0% -0.0% -0.0% -0.0% queens -0.0% 0.0% -0.0% -0.0% -0.0% reptile -0.0% 0.0% -0.0% -0.0% -0.0% reverse-complem -0.0% 0.0% -0.0% -0.0% -0.0% rewrite -0.0% 0.0% -0.0% -0.0% -0.0% rfib -0.0% 0.0% -0.0% -0.0% -0.0% rsa -0.0% 0.0% -0.0% -0.0% -0.0% scc -0.0% 0.0% -0.3% -0.5% -0.4% sched -0.0% 0.0% -0.0% -0.0% -0.0% scs -0.0% 0.0% -0.0% -0.0% -0.0% simple -0.1% 0.0% -0.0% -0.0% -0.0% solid -0.0% 0.0% -0.0% -0.0% -0.0% sorting -0.0% 0.0% -0.0% -0.0% -0.0% spectral-norm -0.0% 0.0% -0.0% -0.0% -0.0% sphere -0.0% 0.0% -0.0% -0.0% -0.0% symalg -0.0% 0.0% -0.0% -0.0% -0.0% tak -0.0% 0.0% -0.0% -0.0% -0.0% transform -0.0% 0.0% -0.0% -0.0% -0.0% treejoin -0.0% 0.0% -0.0% -0.0% -0.0% typecheck -0.0% 0.0% -0.0% -0.0% -0.0% veritas -0.0% 0.0% -0.0% -0.0% -0.0% wang -0.0% 0.0% -0.0% -0.0% -0.0% wave4main -0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 -0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 -0.0% 0.0% -0.0% -0.0% -0.0% x2n1 -0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min -0.1% 0.0% -0.3% -0.5% -0.5% Max -0.0% 0.0% -0.0% -0.0% -0.0% Geometric Mean -0.0% -0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- circsim -0.1% 0.0% -0.0% -0.0% -0.0% constraints -0.0% 0.0% -0.0% -0.0% -0.0% fibheaps -0.0% 0.0% -0.0% -0.0% -0.0% gc_bench -0.0% 0.0% -0.0% -0.0% -0.0% hash -0.0% 0.0% -0.0% -0.0% -0.0% lcss -0.0% 0.0% -0.0% -0.0% -0.0% power -0.0% 0.0% -0.0% -0.0% -0.0% spellcheck -0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min -0.1% 0.0% -0.0% -0.0% -0.0% Max -0.0% 0.0% -0.0% -0.0% -0.0% Geometric Mean -0.0% +0.0% -0.0% -0.0% -0.0% Manual inspection of programs in testsuite/tests/programs --------------------------------------------------------- I built these programs with a bunch of dump flags and `-O` and compared STG, Cmm, and Asm dumps and file sizes. (Below the numbers in parenthesis show number of modules in the program) These programs have identical compiler (same .hi and .o sizes, STG, and Cmm and Asm dumps): - Queens (1), andre_monad (1), cholewo-eval (2), cvh_unboxing (3), andy_cherry (7), fun_insts (1), hs-boot (4), fast2haskell (2), jl_defaults (1), jq_readsPrec (1), jules_xref (1), jtod_circint (4), jules_xref2 (1), lennart_range (1), lex (1), life_space_leak (1), bargon-mangler-bug (7), record_upd (1), rittri (1), sanders_array (1), strict_anns (1), thurston-module-arith (2), okeefe_neural (1), joao-circular (6), 10queens (1) Programs with different compiler outputs: - jl_defaults (1): For some reason GHC HEAD marks a lot of top-level `[Int]` closures as CAFFY for no reason. With this patch we no longer make them CAFFY and generate less SRT entries. For some reason Main.o is slightly larger with this patch (1.3%) and the executable sizes are the same. (I'd expect both to be smaller) - launchbury (1): Same as jl_defaults: top-level `[Int]` closures marked as CAFFY for no reason. Similarly `Main.o` is 1.4% larger but the executable sizes are the same. - galois_raytrace (13): Differences are in the Parse module. There are a lot, but some of the changes are caused by the fact that for some reason (I think a bug) GHC HEAD marks the dictionary for `Functor Identity` as CAFFY. Parse.o is 0.4% larger, the executable size is the same. - north_array: We now generate less SRT entries because some of array primops used in this program like `NewArrayOp` get eliminated during Stg-to-Cmm and turn some CAFFY things into non-CAFFY. Main.o gets 24% larger (9224 bytes from 9000 bytes), executable sizes are the same. - seward-space-leak: Difference in this program is better shown by this smaller example: module Lib where data CDS = Case [CDS] [(Int, CDS)] | Call CDS CDS instance Eq CDS where Case sels1 rets1 == Case sels2 rets2 = sels1 == sels2 && rets1 == rets2 Call a1 b1 == Call a2 b2 = a1 == a2 && b1 == b2 _ == _ = False In this program GHC HEAD builds a new SRT for the recursive group of `(==)`, `(/=)` and the dictionary closure. Then `/=` points to `==` in its SRT field, and `==` uses the SRT object as its SRT. With this patch we use the closure for `/=` as the SRT and add `==` there. Then `/=` gets an empty SRT field and `==` points to `/=` in its SRT field. This change looks fine to me. Main.o gets 0.07% larger, executable sizes are identical. head.hackage ------------ head.hackage's CI script builds 428 packages from Hackage using this patch with no failures. Compiler performance -------------------- The compiler perf tests report that the compiler allocates slightly more (worst case observed so far is 4%). However most programs in the test suite are small, single file programs. To benchmark compiler performance on something more realistic I build Cabal (the library, 236 modules) with different optimisation levels. For the "max residency" row I run GHC with `+RTS -s -A100k -i0 -h` for more accurate numbers. Other rows are generated with just `-s`. (This is because `-i0` causes running GC much more frequently and as a result "bytes copied" gets inflated by more than 25x in some cases) * -O0 | | GHC HEAD | This MR | Diff | | --------------- | -------------- | -------------- | ------ | | Bytes allocated | 54,413,350,872 | 54,701,099,464 | +0.52% | | Bytes copied | 4,926,037,184 | 4,990,638,760 | +1.31% | | Max residency | 421,225,624 | 424,324,264 | +0.73% | * -O1 | | GHC HEAD | This MR | Diff | | --------------- | --------------- | --------------- | ------ | | Bytes allocated | 245,849,209,992 | 246,562,088,672 | +0.28% | | Bytes copied | 26,943,452,560 | 27,089,972,296 | +0.54% | | Max residency | 982,643,440 | 991,663,432 | +0.91% | * -O2 | | GHC HEAD | This MR | Diff | | --------------- | --------------- | --------------- | ------ | | Bytes allocated | 291,044,511,408 | 291,863,910,912 | +0.28% | | Bytes copied | 37,044,237,616 | 36,121,690,472 | -2.49% | | Max residency | 1,071,600,328 | 1,086,396,256 | +1.38% | Extra compiler allocations -------------------------- Runtime allocations of programs are as reported above (NoFib section). The compiler now allocates more than before. Main source of allocation in this patch compared to base commit is the new SRT algorithm (GHC.Cmm.Info.Build). Below is some of the extra work we do with this patch, numbers generated by profiled stage 2 compiler when building a pathological case (the test 'ManyConstructors') with '-O2': - We now sort the final STG for a module, which means traversing the entire program, generating free variable set for each top-level binding, doing SCC analysis, and re-ordering the program. In ManyConstructors this step allocates 97,889,952 bytes. - We now do SRT analysis on static data, which in a program like ManyConstructors causes analysing 10,000 bindings that we would previously just skip. This step allocates 70,898,352 bytes. - We now maintain an SRT map for the entire module as we compile Cmm groups: data ModuleSRTInfo = ModuleSRTInfo { ... , moduleSRTMap :: SRTMap } (SRTMap is just a strict Map from the 'containers' library) This map gets an entry for most bindings in a module (exceptions are THUNKs and CAFFY static functions). For ManyConstructors this map gets 50015 entries. - Once we're done with code generation we generate a NameSet from SRTMap for the non-CAFFY names in the current module. This set gets the same number of entries as the SRTMap. - Finally we update CafInfos in ModDetails for the non-CAFFY Ids, using the NameSet generated in the previous step. This usually does the least amount of allocation among the work listed here. Only place with this patch where we do less work in the CAF analysis in the tidying pass (CoreTidy). However that doesn't save us much, as the pass still needs to traverse the whole program and update IdInfos for other reasons. Only thing we don't here do is the `hasCafRefs` pass over the RHS of bindings, which is a stateless pass that returns a boolean value, so it doesn't allocate much. (Metric changes blow are all increased allocations) Metric changes -------------- Metric Increase: ManyAlternatives ManyConstructors T13035 T14683 T1969 T9961 - - - - - 2a87a565 by Andreas Klebinger at 2020-01-31T12:21:10+03:00 A few optimizations in STG and Cmm parts: (Guided by the profiler output) - Add a few bang patterns, INLINABLE annotations, and a seqList in a few places in Cmm and STG parts. - Do not add external variables as dependencies in STG dependency analysis (GHC.Stg.DepAnal). - - - - - bef704b6 by Simon Peyton Jones at 2020-02-01T02:28:45-05:00 Improve skolemisation This patch avoids skolemiseUnboundMetaTyVar making up a fresh Name when it doesn't need to. See Note [Skolemising and identity] Improves error messsages for partial type signatures. - - - - - cd110423 by Simon Peyton Jones at 2020-02-01T02:28:45-05:00 Improve pretty-printing for TyConBinders In particular, show their kinds. - - - - - 913287a0 by Simon Peyton Jones at 2020-02-01T02:28:45-05:00 Fix scoping of TyCon binders in TcTyClsDecls This patch fixes #17566 by refactoring the way we decide the final identity of the tyvars in the TyCons of a possibly-recursive nest of type and class decls, possibly with associated types. It's all laid out in Note [Swizzling the tyvars before generaliseTcTyCon] Main changes: * We have to generalise each decl (with its associated types) all at once: TcTyClsDecls.generaliseTyClDecl * The main new work is done in TcTyClsDecls.swizzleTcTyConBndrs * The mysterious TcHsSyn.zonkRecTyVarBndrs dies altogether Other smaller things: * A little refactoring, moving bindTyClTyVars from tcTyClDecl1 to tcDataDefn, tcSynRhs, etc. Clearer, reduces the number of parameters * Reduce the amount of swizzling required. Specifically, bindExplicitTKBndrs_Q_Tv doesn't need to clone a new Name for the TyVarTv, and not cloning means that in the vasly common case, swizzleTyConBndrs is a no-op In detail: Rename newTyVarTyVar --> cloneTyVarTyVar Add newTyVarTyTyVar that doesn't clone Use the non-cloning newTyVarTyVar in bindExplicitTKBndrs_Q_Tv Rename newFlexiKindedTyVarTyVar --> cloneFlexiKindedTyVarTyVar * Define new utility function and use it HsDecls.familyDeclName :: FamilyDecl (GhcPass p) -> IdP (GhcPass p) Updates haddock submodule. - - - - - 58ed6c4a by Ben Gamari at 2020-02-01T02:29:23-05:00 rts/M32Alloc: Don't attempt to unmap non-existent pages The m32 allocator's `pages` list may contain NULLs in the case that the page was flushed. Some `munmap` implementations (e.g. FreeBSD's) don't like it if we pass them NULL. Don't do that. - - - - - 859db7d6 by Ömer Sinan Ağacan at 2020-02-01T14:18:49+03:00 Improve/fix -fcatch-bottoms documentation Old documentation suggests that -fcatch-bottoms only adds a default alternative to bottoming case expression, but that's not true. We use a very simplistic "is exhaustive" check and add default alternatives to any case expression that does not cover all constructors of the type. In case of GADTs this simple check assumes all constructors should be covered, even the ones ruled out by the type of the scrutinee. Update the documentation to reflect this. (Originally noticed in #17648) [ci skip] - - - - - 54dfa94a by John Ericson at 2020-02-03T21:14:24-05:00 Fix docs for FrontendResult Other variant was removed in ac1a379363618a6f2f17fff65ce9129164b6ef30 but docs were no changed. - - - - - 5e63d9c0 by John Ericson at 2020-02-03T21:15:02-05:00 Refactor HscMain.finish I found the old control flow a bit hard to follow; I rewrote it to first decide whether to desugar, and then use that choice when computing whether to simplify / what sort of interface file to write. I hope eventually we will always write post-tc interface files, which will make the logic of this function even simpler, and continue the thrust of this refactor. - - - - - e580e5b8 by Stefan Schulze Frielinghaus at 2020-02-04T09:29:00-05:00 Do not build StgCRunAsm.S for unregisterised builds For unregisterised builds StgRun/StgReturn are implemented via a mini interpreter in StgCRun.c and therefore would collide with the implementations in StgCRunAsm.S. - - - - - e3b0bd97 by Stefan Schulze Frielinghaus at 2020-02-04T09:29:00-05:00 fixup! fixup! Do not build StgCRunAsm.S for unregisterised builds - - - - - eb629fab by John Ericson at 2020-02-04T09:29:38-05:00 Delete some superfluous helper functions in HscMain The driver code is some of the nastiest in GHC, and I am worried about being able to untangle all the tech debt. In `HscMain` we have a number of helpers which are either not-used or little used. I delete them so we can reduce cognative load, distilling the essential complexity away from the cruft. - - - - - c90eca55 by Sebastian Graf at 2020-02-05T09:21:29-05:00 PmCheck: Record type constraints arising from existentials in `PmCoreCt`s In #17703 (a follow-up of !2192), we established that contrary to my belief, type constraints arising from existentials in code like ```hs data Ex where Ex :: a -> Ex f _ | let x = Ex @Int 15 = case x of Ex -> ... ``` are in fact useful. This commit makes a number of refactorings and improvements to comments, but fundamentally changes `addCoreCt.core_expr` to record the type constraint `a ~ Int` in addition to `x ~ Ex @a y` and `y ~ 15`. Fixes #17703. - - - - - 6d3b5d57 by Ömer Sinan Ağacan at 2020-02-05T09:22:10-05:00 testlib: Extend existing *_opts in extra_*_opts Previously we'd override the existing {run,hc} opts in extra_{run,hc}_opts, which caused flakiness in T1969, see #17712. extra_{run,hc}_opts now extends {run,hc} opts, instead of overriding. Also we shrank the allocation area for T1969 in order to increase residency sampling frequency. Fixes #17712 - - - - - 9c89a48d by Ömer Sinan Ağacan at 2020-02-05T09:22:52-05:00 Remove CafInfo-related code from STG lambda lift pass After c846618ae0 we don't have accurate CafInfos for Ids in the current module and we're free to introduce new CAFFY or non-CAFFY bindings or change CafInfos of existing binders; so no we no longer need to maintain CafInfos in Core or STG passes. - - - - - 70ddb8bf by Ryan Scott at 2020-02-05T09:23:30-05:00 Add regression test for #17773 - - - - - e8004e5d by Ben Gamari at 2020-02-05T13:55:19-05:00 gitlab-ci: Allow Windows builds to fail again Due to T7702 and the process issues described in #17777. - - - - - 29b72c00 by Ben Gamari at 2020-02-06T11:55:41-05:00 VarSet: Introduce nonDetFoldVarSet - - - - - c4e6b35d by Ben Gamari at 2020-02-06T11:55:41-05:00 Move closeOverKinds and friends to TyCoFVs - - - - - ed2f0e5c by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Reform the free variable finders for types This patch delivers on (much of) #17509. * Introduces the shallow vs deep free variable distinction * Introduce TyCoRep.foldType, foldType :: Monoid a => TyCoFolder env a -> env -> Type -> a and use it in the free variable finders. * Substitution in TyCoSubst * ASSERTs are on for checkValidSubst * checkValidSubst uses shallowTyCoVarsOfTypes etc Quite a few things still to do * We could use foldType in lots of other places * We could use mapType for substitution. (Check that we get good code!) * Some (but not yet all) clients of substitution can now save time by using shallowTyCoVarsOfTypes * All calls to tyCoVarsOfTypes should be inspected; most of them should be shallow. Maybe. * Currently shallowTyCoVarsOfTypes still returns unification variables, but not CoVarHoles. Reason: we need to return unification variables in some of the calls in TcSimplify, eg when promoting. * We should do the same thing for tyCoFVsOfTypes, which is currently unchanged. * tyCoFVsOfTypes returns CoVarHoles, because of the use in TcSimplify.mkResidualConstraints. See Note [Emitting the residual implication in simplifyInfer] * #17509 talks about "relevant" variables too. - - - - - 01a1f4fb by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Use foldTyCo for noFreeVarsOfType - - - - - 0e59afd6 by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Simplify closeOverKinds - - - - - 9ca5c88e by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Use foldTyCo for coVarsOfType - - - - - 5541b87c by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Use foldTyCo for exactTyCoVarsOfType This entailed * Adding a tcf_view field to TyCoFolder * Moving exactTyCoVarsOtType to TcType. It properly belongs there, since only the typechecker calls this function. But it also means that we can "see" and inline tcView. Metric Decrease: T14683 - - - - - 7c122851 by Simon Peyton Jones at 2020-02-06T11:56:02-05:00 Comments only - - - - - 588acb99 by Adam Sandberg Eriksson at 2020-02-08T10:15:38-05:00 slightly better named cost-centres for simple pattern bindings #17006 ``` main = do print $ g [1..100] a where g xs x = map (`mod` x) xs a :: Int = 324 ``` The above program previously attributed the cost of computing 324 to a cost centre named `(...)`, with this change the cost is attributed to `a` instead. This change only affects simple pattern bindings (decorated variables: type signatures, parens, ~ annotations and ! annotations). - - - - - 309f8cfd by Richard Eisenberg at 2020-02-08T10:16:33-05:00 Remove unnecessary parentheses - - - - - 7755ffc2 by Richard Eisenberg at 2020-02-08T10:16:33-05:00 Introduce IsPass; refactor wrappers. There are two main payloads of this patch: 1. This introduces IsPass, which allows e.g. printing code to ask what pass it is running in (Renamed vs Typechecked) and thus print extension fields. See Note [IsPass] in Hs.Extension 2. This moves the HsWrap constructor into an extension field, where it rightly belongs. This is done for HsExpr and HsCmd, but not for HsPat, which is left as an exercise for the reader. There is also some refactoring around SyntaxExprs, but this is really just incidental. This patch subsumes !1721 (sorry @chreekat). Along the way, there is a bit of refactoring in GHC.Hs.Extension, including the removal of NameOrRdrName in favor of NoGhcTc. This meant that we had no real need for GHC.Hs.PlaceHolder, so I got rid of it. Updates haddock submodule. ------------------------- Metric Decrease: haddock.compiler ------------------------- - - - - - 7d452be4 by Dylan Yudaken at 2020-02-08T10:17:17-05:00 Fix hs_try_putmvar losing track of running cap If hs_try_putmvar was called through an unsafe import, it would lose track of the running cap causing a deadlock - - - - - c2e301ae by Ben Gamari at 2020-02-08T10:17:55-05:00 compiler: Qualify imports of Data.List - - - - - aede171a by Ben Gamari at 2020-02-08T10:17:55-05:00 testsuite: Fix -Wcompat-unqualified-imports issues - - - - - 4435a8e0 by Ben Gamari at 2020-02-08T10:17:55-05:00 Introduce -Wcompat-unqualified-imports This implements the warning proposed in option (B) of the Data.List.singleton CLC [discussion][]. This warning, which is included in `-Wcompat` is intended to help users identify imports of modules that will change incompatibly in future GHC releases. This currently only includes `Data.List` due to the expected specialisation and addition of `Data.List.singleton`. Fixes #17244. [discussion]: https://groups.google.com/d/msg/haskell-core-libraries/q3zHLmzBa5E/PmlAs_kYAQAJ - - - - - 28b5349a by Ben Gamari at 2020-02-08T10:17:55-05:00 Bump stm and process submodules - - - - - 7d04b9f2 by Ben Gamari at 2020-02-08T10:18:31-05:00 hadrian: Allow override of Cabal configuration in hadrian.settings Fixes #17612 by adding a `cabal.configure.opts` key for `hadrian.settings`. - - - - - 88bf81aa by Andreas Klebinger at 2020-02-08T10:19:10-05:00 Optimize unpackCString# to allocate less. unpackCString# is a recursive function which for each iteration returns a Cons cell containing the current Char, and a thunk for unpacking the rest of the string. In this patch we change from storing addr + offset inside this thunk to storing only the addr, simply incrementing the address on each iteration. This saves one word of allocation per unpacked character. For a program like "main = print "<largishString>" this amounts to 2-3% fewer % in bytes allocated. I also removed the now redundant local unpack definitions. This removes one call per unpack operation. - - - - - bec76733 by Ben Gamari at 2020-02-08T10:19:57-05:00 Fix GhcThreaded setting This adopts a patch from NetBSD's packaging fixing the `GhcThreaded` option of the make build system. In addition we introduce a `ghcThreaded` option in hadrian's `Flavour` type. Also fix Hadrian's treatment of the `Use Threaded` entry in `settings`. Previously it would incorrectly claim `Use Threaded = True` if we were building the `threaded` runtime way. However, this is inconsistent with the `make` build system, which defines it to be whether the `ghc` executable is linked against the threaded runtime. Fixes #17692. - - - - - 545cf1e1 by Ben Gamari at 2020-02-08T10:20:37-05:00 hadrian: Depend upon libray dependencies when configuring packages This will hopefully fix #17631. - - - - - 047d3d75 by Ben Gamari at 2020-02-08T10:21:16-05:00 testsuite: Add test for #15316 This is the full testcase for T15316. - - - - - 768e5866 by Julien Debon at 2020-02-08T10:22:07-05:00 doc(Data.List): Add some examples to Data.List - - - - - 3900cb83 by Julien Debon at 2020-02-08T10:22:07-05:00 Apply suggestion to libraries/base/GHC/List.hs - - - - - bd666766 by Ben Gamari at 2020-02-08T10:22:45-05:00 users-guide: Clarify that bundled patsyns were introduced in GHC 8.0 Closes #17094. - - - - - 95741ea1 by Pepe Iborra at 2020-02-08T10:23:23-05:00 Update to hie-bios 0.3.2 style program cradle - - - - - fb5c1912 by Sylvain Henry at 2020-02-08T10:24:07-05:00 Remove redundant case This alternative is redundant and triggers no warning when building with 8.6.5 - - - - - 5d83d948 by Matthew Pickering at 2020-02-08T10:24:43-05:00 Add mkHieFileWithSource which doesn't read the source file from disk cc/ @pepeiborra - - - - - dfdae56d by Andreas Klebinger at 2020-02-08T10:25:20-05:00 Rename ghcAssert to stgAssert in hp2ps/Main.h. This fixes #17763 - - - - - 658f7ac6 by Ben Gamari at 2020-02-08T10:26:00-05:00 includes: Avoid using single-line comments in HsFFI.h While single-line comments are supported by C99, dtrace on SmartOS apparently doesn't support them yet. - - - - - c95920a6 by Ömer Sinan Ağacan at 2020-02-08T10:26:42-05:00 Import qualified Prelude in parser This is in preparation of backwards-incompatible changes in happy. See https://github.com/simonmar/happy/issues/166 - - - - - b6dc319a by Ömer Sinan Ağacan at 2020-02-08T10:27:23-05:00 Add regression test for #12760 The bug seems to be fixed in the meantime, make sure it stays fixed. Closes #12760 - - - - - b3857b62 by Ben Gamari at 2020-02-08T10:28:03-05:00 base: Drop out-of-date comment The comment in GHC.Base claimed that ($) couldn't be used in that module as it was wired-in. However, this is no longer true; ($) is merely known key and is defined in Haskell (with a RuntimeRep-polymorphic type) in GHC.Base. The one piece of magic that ($) retains is that it a special typing rule to allow type inference with higher-rank types (e.g. `runST $ blah`; see Note [Typing rule for ($)] in TcExpr). - - - - - 1183ae94 by Daniel Gröber at 2020-02-08T10:29:00-05:00 rts: Fix Arena blocks accounting for MBlock sized allocations When requesting more than BLOCKS_PER_MBLOCK blocks allocGroup can return a different number of blocks than requested. Here we use the number of requested blocks, however arenaFree will subtract the actual number of blocks we got from arena_blocks (possibly) resulting in a negative value and triggering ASSERT(arena_blocks >= 0). - - - - - 97d59db5 by Daniel Gröber at 2020-02-08T10:29:48-05:00 rts: Fix need_prealloc being reset when retainer profiling is on - - - - - 1f630025 by Krzysztof Gogolewski at 2020-02-09T02:52:27-05:00 Add a test for #15712 - - - - - 2ac784ab by Ben Gamari at 2020-02-09T02:53:05-05:00 hadrian: Add --test-metrics argument Allowing the test metric output to be captured to a file, a la the METRIC_FILE environment variable of the make build system. - - - - - f432d8c6 by Ben Gamari at 2020-02-09T02:53:05-05:00 hadrian: Fix --test-summary argument This appears to be a cut-and-paste error. - - - - - a906595f by Arnaud Spiwack at 2020-02-09T02:53:50-05:00 Fix an outdated note link This link appears to have been forgotten in 0dad81ca5fd1f63bf8a3b6ad09787559e8bd05c0 . - - - - - 3ae83da1 by Alp Mestanogullari at 2020-02-09T02:54:28-05:00 hadrian: Windows fixes (bindists, CI) This commit implements a few Windows-specific fixes which get us from a CI job that can't even get as far as starting the testsuite driver, to a state where we can run the entire testssuite (but have test failures to fix). - Don't forget about a potential extension for the haddock program, when preparing the bindist. - Build the timeout program, used by the testsuite driver on Windows in place of the Python script used elsewhere, using the boot compiler. We could alternatively build it with the compiler that we're going to test but this would be a lot more tedious to write. - Implement a wrapper-script less installation procedure for Windows, in `hadrian/bindist/Makefile. - Make dependencies a bit more accurate in the aforementioned Makefile. - Update Windows/Hadrian CI job accordingly. This patch fixes #17486. - - - - - 82f9be8c by Roland Senn at 2020-02-09T02:55:06-05:00 Fix #14628: Panic (No skolem Info) in GHCi This patch implements the [sugggestion from Simon (PJ)](https://gitlab.haskell.org/ghc/ghc/issues/14628#note_146559): - Make `TcErrors.getSkolemInfo` return a `SkolemInfo` rather than an `Implication`. - If `getSkolemInfo` gets `RuntimeUnk`s, just return a new data constructor in `SkolemInfo`, called `RuntimeUnkSkol`. - In `TcErrors.pprSkols` print something sensible for a `RuntimeUnkSkol`. The `getSkolemInfo` function paniced while formating suggestions to add type annotations (subfunction `suggestAddSig`) to a *"Couldn't match type ‘x’ with ‘y’"* error message. The `getSkolemInfo` function didn't find any Implication value and paniced. With this patch the `getSkolemInfo` function does no longer panic, if it finds `RuntimeUnkSkol`s. As the panic occured while processing an error message, we don't need to implement any new error message! - - - - - b2e18e26 by Andreas Klebinger at 2020-02-09T02:55:46-05:00 Fix -ddump-stg-final. Once again make sure this dumps the STG used for codegen. - - - - - 414e2f62 by Sylvain Henry at 2020-02-09T02:56:26-05:00 Force -fPIC for intree GMP (fix #17799) Configure intree GMP with `--with-pic` instead of patching it. Moreover the correct patching was only done for x86_64/darwin (see #17799). - - - - - f0fd72ee by Sebastian Graf at 2020-02-09T17:22:38-05:00 8.10 Release notes for improvements to the pattern-match checker [skip ci] A little late to the game, but better late than never. - - - - - 00dc0f7e by Ömer Sinan Ağacan at 2020-02-09T17:23:17-05:00 Add regression test for #13142 Closes #13142 - - - - - f3e737bb by Sebastian Graf at 2020-02-10T20:04:09-05:00 Fix long distance info for record updates For record updates where the `record_expr` is a variable, as in #17783: ```hs data PartialRec = No | Yes { a :: Int, b :: Bool } update No = No update r@(Yes {}) = r { b = False } ``` We should make use of long distance info in `-Wincomplete-record-updates` checking. But the call to `matchWrapper` in the `RecUpd` case didn't specify a scrutinee expression, which would correspond to the `record_expr` `r` here. That is fixed now. Fixes #17783. - - - - - 5670881d by Tamar Christina at 2020-02-10T20:05:04-05:00 Fs: Fix UNC remapping code. - - - - - 375b3c45 by Oleg Grenrus at 2020-02-11T05:07:30-05:00 Add singleton to Data.OldList - - - - - de32beff by Richard Eisenberg at 2020-02-11T05:08:10-05:00 Do not create nested quantified constraints Previously, we would accidentally make constraints like forall a. C a => forall b. D b => E a b c as we traversed superclasses. No longer! This patch also expands Note [Eagerly expand given superclasses] to work over quantified constraints; necessary for T16502b. Close #17202 and #16502. test cases: typecheck/should_compile/T{17202,16502{,b}} - - - - - e319570e by Ben Gamari at 2020-02-11T05:08:47-05:00 rts: Use nanosleep instead of usleep usleep was removed in POSIX.1-2008. - - - - - b75e7486 by Ben Gamari at 2020-02-11T05:09:24-05:00 rts: Remove incorrect assertions around MSG_THROWTO messages Previously we would assert that threads which are sending a `MSG_THROWTO` message must have their blocking status be blocked on the message. In the usual case of a thread throwing to another thread this is guaranteed by `stg_killThreadzh`. However, `throwToSelf`, used by the GC to kill threads which ran out of heap, failed to guarantee this. Noted while debugging #17785. - - - - - aba51b65 by Sylvain Henry at 2020-02-11T05:10:04-05:00 Add arithmetic exception primops (#14664) - - - - - b157399f by Ben Gamari at 2020-02-11T05:10:40-05:00 configure: Don't assume Gnu linker on Solaris Compl Yue noticed that the linker was dumping the link map on SmartOS. This is because Smartos uses the Solaris linker, which uses the `-64` flag, not `-m64` like Gnu ld, to indicate that it should link for 64-bits. Fix the configure script to handle the Solaris linker correctly. - - - - - d8d73d77 by Simon Peyton Jones at 2020-02-11T05:11:18-05:00 Notes only: telescopes This documentation-only patch fixes #17793 - - - - - 58a4ddef by Alp Mestanogullari at 2020-02-11T05:12:17-05:00 hadrian: build (and ship) iserv on Windows - - - - - 82023524 by Matthew Pickering at 2020-02-11T18:04:17-05:00 TemplateHaskellQuotes: Allow nested splices There is no issue with nested splices as they do not require any compile time code execution. All execution is delayed until the top-level splice. - - - - - 50e24edd by Ömer Sinan Ağacan at 2020-02-11T18:04:57-05:00 Remove Hadrian's copy of (Data.Functor.<&>) The function was added to base with base-4.11 (GHC 8.4) - - - - - f82a2f90 by Sylvain Henry at 2020-02-12T01:56:46-05:00 Document GMP build [skip ci] - - - - - da7f7479 by Sylvain Henry at 2020-02-12T01:57:27-05:00 Module hierarchy: ByteCode and Runtime (cf #13009) Update haddock submodule - - - - - 04f51297 by Ömer Sinan Ağacan at 2020-02-12T01:58:11-05:00 Fix naming of tests for #12923 - - - - - 31fc3321 by Ömer Sinan Ağacan at 2020-02-12T01:58:11-05:00 Add regression test for #12926 Closes #12926 - - - - - f0c0ee7d by Krzysztof Gogolewski at 2020-02-12T01:58:51-05:00 Fix order of arguments in specializer (#17801) See https://gitlab.haskell.org/ghc/ghc/issues/17801#note_253330 No regression test, as it's hard to trigger. - - - - - 059c3c9d by Sebastian Graf at 2020-02-12T11:00:58+01:00 Separate CPR analysis from the Demand analyser The reasons for that can be found in the wiki: https://gitlab.haskell.org/ghc/ghc/wikis/nested-cpr/split-off-cpr We now run CPR after demand analysis (except for after the final demand analysis run just before code gen). CPR got its own dump flags (`-ddump-cpr-anal`, `-ddump-cpr-signatures`), but not its own flag to activate/deactivate. It will run with `-fstrictness`/`-fworker-wrapper`. As explained on the wiki page, this step is necessary for a sane Nested CPR analysis. And it has quite positive impact on compiler performance: Metric Decrease: T9233 T9675 T9961 T15263 - - - - - f5ffd8d9 by Ben Gamari at 2020-02-12T17:22:37-05:00 base: Expose GHC.Unicode.unicodeVersion This exposes a Data.Version.Version representing the version of the Unicode database used by `base`. This should clear up some confusion I have seen in tickets regarding with which Unicode versions a given GHC can be expected to work. While in town I also regenerated (but did not update) the Unicode database with database 12.0.0. Strangely, the file cited in the README no longer existed. Consequently, I used https://www.unicode.org/Public/12.0.0/ucd/UnicodeData.txt and was slightly surprised to find that there were a few changes. - - - - - 6c2585e0 by Ben Gamari at 2020-02-12T17:22:37-05:00 base: Update Unicode database to 12.1.0 Using `curl https://www.unicode.org/Public/12.1.0/ucd/UnicodeData.txt | libraries/base/cbits/ubconfc 12.1.0`. - - - - - df084681 by Krzysztof Gogolewski at 2020-02-12T23:58:52+01:00 Always display inferred variables using braces We now always show "forall {a}. T" for inferred variables, previously this was controlled by -fprint-explicit-foralls. This implements part 1 of https://github.com/ghc-proposals/ghc-proposals/pull/179. Part of GHC ticket #16320. Furthermore, when printing a levity restriction error, we now display the HsWrap of the expression. This lets users see the full elaboration with -fprint-typechecker-elaboration (see also #17670) - - - - - 16d643cf by Sylvain Henry at 2020-02-13T09:16:04-05:00 Remove -ddump-srts flag This flag is deemed not useful. - - - - - fa28ae95 by Sylvain Henry at 2020-02-13T09:16:04-05:00 Fix flag documentation (#17826) - - - - - 1bfd8259 by Sylvain Henry at 2020-02-13T09:16:43-05:00 Ensure that Hadrian is built correctly before using it When Hadrian failed to build, the script would pick a previously built Hadrian (if available) instead of failing. - - - - - cd6e786a by Ömer Sinan Ağacan at 2020-02-14T05:29:56-05:00 Add test for #17648 - - - - - 9f2c3677 by Sylvain Henry at 2020-02-14T05:30:39-05:00 GMP expects the Target platform as --host parameter - - - - - aa6086fd by Oleg Grenrus at 2020-02-14T05:31:16-05:00 Add explicit LANGUAGE Safe to template-haskell (cherry picked from commit a5e0f376821ca882880b03b07b451aa574e289ec) - - - - - af6a0c36 by Ben Gamari at 2020-02-14T05:31:53-05:00 hadrian: Add execution and target architecture to stage-compilation figure - - - - - cf739945 by Sylvain Henry at 2020-02-14T05:32:37-05:00 Module hierarchy: HsToCore (cf #13009) - - - - - 719db318 by Simon Peyton Jones at 2020-02-14T05:33:16-05:00 De-duplicate overlapping Notes Documentation only. Fixes #17827 - - - - - 7550417a by Sylvain Henry at 2020-02-14T05:33:56-05:00 Hadrian: drop Sphinx flag checking for PDF documentation (#17825) It seems that Sphinx produces the ghc-flags.txt in doc/users_guide/_build rather than pdfRoot. We could copy ghc-flags.txt into pdfRoot (like happens naturally in the HTML case) but the benefit is pretty small. Let's just only check the HTML case. - - - - - 813842f4 by Ben Gamari at 2020-02-14T10:16:36-05:00 make: Be more selective in building windows-extra-src tarball - - - - - 0725f4bb by Ben Gamari at 2020-02-14T10:16:36-05:00 Rework handling of win32 toolchain tarballs - - - - - 565ce7ae by Ben Gamari at 2020-02-14T10:16:36-05:00 gitlab-ci: Consolidate CI logic This moves nearly all of the CI logic to .gitlab/ci.sh. This improves things in a number of ways: * it's harder for inconsistencies to arise between architectures * it's easier to share logic between architectures * on Windows, it's easier to ensure that all CI steps are executed from within a properly initialized mingw session. While in town I also add a FreeBSD build job and update the Windows job to use the gitlab-runner PowerShell executor, since cmd.exe will be deprecated soon (fixing #17699). - - - - - 9cbace74 by Ben Gamari at 2020-02-14T10:16:36-05:00 gitlab-ci: Deduplicate nightly job configuration - - - - - 6e837144 by Ben Gamari at 2020-02-14T10:16:36-05:00 integer-gmp: Fix unused command-line argument -L is only needed during linking. - - - - - e5ee07ab by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Don't ask sed to operate in-place on symlinks Some sed implementations (e.g. FreeBSD) refuse to operate in-place on symlinks. - - - - - 71e5e68f by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Disable tests that assume name of libstdc++ on FreeBSD - - - - - 7b2da0f4 by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Mark T6132 as broken on FreeBSD - - - - - 8ef7a15a by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite/T16930: Don't rely on gnu grep specific --include In BSD grep this flag only affects directory recursion. - - - - - 6060003e by Ben Gamari at 2020-02-14T10:16:36-05:00 Pass -Wno-unused-command-line-arguments during link on FreeBSD FreeBSD cc throws a warning if we pass -pthread without actually using any pthread symbols. - - - - - 97497bae by Ben Gamari at 2020-02-14T10:16:36-05:00 base: Always clamp reads/writes to 2GB in length Previously we did this only on Darwin due to #17414. However, even on other platforms >2GB writes are on shaky ground. POSIX explicitly says that the result is implementation-specified and Linux will write at most 0x7ffff000, even on 64-bit platforms. Moreover, getting the sign of the syscall result correct is tricky, as demonstrated by the fact that T17414 currently fails on FreeBSD. For simplicity we now just uniformly clamp to 0x7ffff000 on all platforms. - - - - - 49be2a3f by Ben Gamari at 2020-02-14T10:16:36-05:00 configure: Fix sphinx version test The check for the "v" prefix is redundant. - - - - - f7f7a556 by Ben Gamari at 2020-02-14T10:16:37-05:00 users-guide: Fix unknown link targets - - - - - a204102c by Ben Gamari at 2020-02-14T10:16:37-05:00 docs/compare-flags: Don't use python f-strings - - - - - 92e15a37 by Ben Gamari at 2020-02-14T10:16:37-05:00 gitlab-ci: Fix various shellcheck warnings - - - - - 459f7c6e by Ben Gamari at 2020-02-14T10:16:37-05:00 hadrian: Drop empty arguments from target list Fixes #17748. - - - - - c06df28d by Ben Gamari at 2020-02-14T10:16:37-05:00 users-guide: Fix "invalid file" failure I have no idea how this worked previously. Different Python version? - - - - - 3fe8444f by Ben Gamari at 2020-02-14T10:16:59-05:00 testsuite: Mark T7702 as fragile on Windows Due to #16799. There was previously an attempt to mark it as broken but the `opsys` name was incorrect. - - - - - fe02f781 by Ben Gamari at 2020-02-14T10:16:59-05:00 testsuite: Assert the opsys names are known Previously opsys would take any string. This meant it was very easy for a typo to silently render the predicate ineffective. Fix this by checking the given operating system name against a list of known values. - - - - - 149e2a3a by Ben Gamari at 2020-02-14T10:16:59-05:00 compare-flags: Don't rely on encoding flag of subprocess.check_output Apparently it isn't supported by some slightly older Python versions. - - - - - 798d59f6 by Ben Gamari at 2020-02-14T10:16:59-05:00 rts: Add more debug output to failed path in onIOComplete This will help track down #17035. - - - - - e35f3f98 by Ben Gamari at 2020-02-14T10:16:59-05:00 gitlab-ci: Allow i386 Windows builds to fail again Due to the resistance of #17736 to resolution. - - - - - 261a3cf8 by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Build integer-simple job in the validate flavour - - - - - b613a961 by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Always use mingw64 python on Windows - - - - - 1bc8c8cd by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Allow Windows build to fail due to #17777 The fact that `exec` isn't POSIX compliant means that things can break in arbitrarily bad ways. Sometimes things happen to work correctly but sadly this isn't always the case. - - - - - ac63020d by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Drop unnecessary GHC_VERSION check - - - - - 6926f369 by Ben Gamari at 2020-02-14T10:17:00-05:00 Bump process submodule Folds in the second part of Phyx's Windows process exit fixes [1], hopefully finally resolving issue #17480. [1] https://github.com/haskell/process/pull/160 - - - - - 584eee71 by Tamar Christina at 2020-02-14T10:17:00-05:00 SysTools: Use "process job" when spawning processes on Windows GHC should make calls using process jobs when calling out to GCC and LD. The reason is these use the exec () family of posix functions. Window's process model doesn't allow replacement of processes so this is emulated by creating a new process and immediately exiting the old one. Because of this when using normal Windows wait functions you would return even without the child process having finished. In this case if you are depending on data from the child you will enter a race condition. The usual fix for this is to use process jobs and wait for the termination of all children that have ever been spawn by the process you called. But also waiting for the freeing of all resources. - - - - - ecabfa28 by Tamar Christina at 2020-02-14T10:17:00-05:00 Revert "compiler: Disable atomic renaming on Windows" The original reason this was disabled should be fixed by the previous commit. This reverts commit 1c1b63d63efe8b0f789aa7d5b87cfac3edd213eb. - - - - - 06d60c66 by Ben Gamari at 2020-02-14T10:17:00-05:00 Bump Cabal submodule - - - - - 8cabb384 by Ben Gamari at 2020-02-14T10:17:00-05:00 compare-flags: Fix output - - - - - 8cf646d3 by Ben Gamari at 2020-02-14T10:17:00-05:00 users-guide: Document -ddump-srts - - - - - 932307a5 by Ben Gamari at 2020-02-14T10:17:00-05:00 users-guide: Fix broken reference - - - - - e77818de by Ben Gamari at 2020-02-15T09:26:55-05:00 Accept performance changes These manifested in the integer-simple job. Metric Decrease: T12227 T5549 T14936 T4830 Conversions T5237 T8766 T4801 T10359 Metric Increase: T12234 T6048 T3294 T14683 T3064 T9872b T9872c T783 T5837 T10678 T14697 T5631 T9203 T13719 T12707 T13056 T9630 T10547 T9872d T1969 WWRec T10370 T5321FD haddock.Cabal T5642 T9872a T15263 T12425 MultiLayerModules T5205 T9233 T13379 haddock.base T9020 T13035 T12150 T9961 - - - - - 785008c1 by Ben Gamari at 2020-02-15T09:30:13-05:00 testsuite: Sort test names in expected change output - - - - - 9e851472 by Ömer Sinan Ağacan at 2020-02-16T10:38:41+03:00 Revert "users-guide: Document -ddump-srts" This reverts commit 8cf646d36b02b8ea1c289cb52781c9171853b514. The flag was removed by 16d643cf. [ci skip] - - - - - 9792c816 by Ben Gamari at 2020-02-16T09:47:08-05:00 testsuite: Probe whether symlinks are usable on Windows Closes #17706. - - - - - ee1e5342 by Vladislav Zavialov at 2020-02-16T09:47:44-05:00 Fix the "unused terminals: 2" warning in Parser.y - - - - - b4a8ce52 by Roland Senn at 2020-02-18T20:14:42-05:00 If a :reload finds syntax errors in the module graph, remove the loaded modules. (Fixes #17549) The processing in `compiler/main/GhcMake.hs` computes the ModuleGraph. If it finds errors in the module header or in the import specifications, then the new module graph is incomplete and should not be used. The code before #17549 just reported the errors and left the old ModuleGraph in place. The new code of this MR replaces the old ModuleGraph with an empty one. - - - - - d7029cc0 by Sylvain Henry at 2020-02-18T20:15:30-05:00 Hadrian: refactor GMP in-tree build support (#17756) * Hadrian doesn't use integer-gmp/config.mk file anymore to determine if building GMP in-tree is required. "config.mk" is created by Cabal when the integer-gmp package is configured and this file is still untracked by Hadrian. This led to a tricky configure "race" because "config.mk" is built by the "setup-config" rule, but this rule is also used to find dependencies, in particular the "ghc-gmp.h" header, but the creation of this file was depending (without being tracked) on "config.mk". Now Hadrian only builds in-tree GMP if `--with-intree-gmp` is passed to the top-level configure script. * in-tree GMP isn't built once for all in a fixed stage (Stage1) anymore. It is built per stage which is required if we build a cross-compiler * switching between in-tree and external GMP is now supported without having to clean the build directory first. * "wrappers.c" now includes "ghc-gmp.h" instead of "ghc.h". It helps ensuring that the build system generates "ghc-gmp.h". * build in-tree GMP in "<root>/stageN/gmp/gmpbuild" and produce useful artefacts (libgmp.a, gmp.h, objs/*.o) in "<root>/stageN/gmp" - - - - - 40d917fb by Vladislav Zavialov at 2020-02-18T20:16:07-05:00 Remove the MonadFail P instance There were two issues with this instance: * its existence meant that a pattern match failure in the P monad would produce a user-visible parse error, but the error message would not be helpful to the user * due to the MFP migration strategy, we had to use CPP in Lexer.x, and that created issues for #17750 Updates haddock submodule. - - - - - 5a1ce45d by Joshua Price at 2020-02-18T20:16:47-05:00 Fix unboxed tuple size limit (#17837) - - - - - 192caf58 by Vladislav Zavialov at 2020-02-18T20:17:24-05:00 Fix testsuite driver output (#17847) - - - - - 1500f089 by Sylvain Henry at 2020-02-18T20:18:12-05:00 Modules: Llvm (#13009) - - - - - d53e81c0 by Niklas Hambüchen at 2020-02-20T10:36:22-05:00 8.10 Release notes for atomic .o writes [skip ci] - - - - - 19680ee5 by Niklas Hambüchen at 2020-02-20T10:37:53-05:00 8.10 Release notes for --disable-delayed-os-memory-return [skip ci] - - - - - 74ad75e8 by Simon Peyton Jones at 2020-02-20T21:17:57-05:00 Re-implement unsafe coercions in terms of unsafe equality proofs (Commit message written by Omer, most of the code is written by Simon and Richard) See Note [Implementing unsafeCoerce] for how unsafe equality proofs and the new unsafeCoerce# are implemented. New notes added: - [Checking for levity polymorphism] in CoreLint.hs - [Implementing unsafeCoerce] in base/Unsafe/Coerce.hs - [Patching magic definitions] in Desugar.hs - [Wiring in unsafeCoerce#] in Desugar.hs Only breaking change in this patch is unsafeCoerce# is not exported from GHC.Exts, instead of GHC.Prim. Fixes #17443 Fixes #16893 NoFib ----- -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS -0.1% 0.0% -0.0% -0.0% -0.0% CSD -0.1% 0.0% -0.0% -0.0% -0.0% FS -0.1% 0.0% -0.0% -0.0% -0.0% S -0.1% 0.0% -0.0% -0.0% -0.0% VS -0.1% 0.0% -0.0% -0.0% -0.0% VSD -0.1% 0.0% -0.0% -0.0% -0.1% VSM -0.1% 0.0% -0.0% -0.0% -0.0% anna -0.0% 0.0% -0.0% -0.0% -0.0% ansi -0.1% 0.0% -0.0% -0.0% -0.0% atom -0.1% 0.0% -0.0% -0.0% -0.0% awards -0.1% 0.0% -0.0% -0.0% -0.0% banner -0.1% 0.0% -0.0% -0.0% -0.0% bernouilli -0.1% 0.0% -0.0% -0.0% -0.0% binary-trees -0.1% 0.0% -0.0% -0.0% -0.0% boyer -0.1% 0.0% -0.0% -0.0% -0.0% boyer2 -0.1% 0.0% -0.0% -0.0% -0.0% bspt -0.1% 0.0% -0.0% -0.0% -0.0% cacheprof -0.1% 0.0% -0.0% -0.0% -0.0% calendar -0.1% 0.0% -0.0% -0.0% -0.0% cichelli -0.1% 0.0% -0.0% -0.0% -0.0% circsim -0.1% 0.0% -0.0% -0.0% -0.0% clausify -0.1% 0.0% -0.0% -0.0% -0.0% comp_lab_zift -0.1% 0.0% -0.0% -0.0% -0.0% compress -0.1% 0.0% -0.0% -0.0% -0.0% compress2 -0.1% 0.0% -0.0% -0.0% -0.0% constraints -0.1% 0.0% -0.0% -0.0% -0.0% cryptarithm1 -0.1% 0.0% -0.0% -0.0% -0.0% cryptarithm2 -0.1% 0.0% -0.0% -0.0% -0.0% cse -0.1% 0.0% -0.0% -0.0% -0.0% digits-of-e1 -0.1% 0.0% -0.0% -0.0% -0.0% digits-of-e2 -0.1% 0.0% -0.0% -0.0% -0.0% dom-lt -0.1% 0.0% -0.0% -0.0% -0.0% eliza -0.1% 0.0% -0.0% -0.0% -0.0% event -0.1% 0.0% -0.0% -0.0% -0.0% exact-reals -0.1% 0.0% -0.0% -0.0% -0.0% exp3_8 -0.1% 0.0% -0.0% -0.0% -0.0% expert -0.1% 0.0% -0.0% -0.0% -0.0% fannkuch-redux -0.1% 0.0% -0.0% -0.0% -0.0% fasta -0.1% 0.0% -0.5% -0.3% -0.4% fem -0.1% 0.0% -0.0% -0.0% -0.0% fft -0.1% 0.0% -0.0% -0.0% -0.0% fft2 -0.1% 0.0% -0.0% -0.0% -0.0% fibheaps -0.1% 0.0% -0.0% -0.0% -0.0% fish -0.1% 0.0% -0.0% -0.0% -0.0% fluid -0.1% 0.0% -0.0% -0.0% -0.0% fulsom -0.1% 0.0% +0.0% +0.0% +0.0% gamteb -0.1% 0.0% -0.0% -0.0% -0.0% gcd -0.1% 0.0% -0.0% -0.0% -0.0% gen_regexps -0.1% 0.0% -0.0% -0.0% -0.0% genfft -0.1% 0.0% -0.0% -0.0% -0.0% gg -0.1% 0.0% -0.0% -0.0% -0.0% grep -0.1% 0.0% -0.0% -0.0% -0.0% hidden -0.1% 0.0% -0.0% -0.0% -0.0% hpg -0.1% 0.0% -0.0% -0.0% -0.0% ida -0.1% 0.0% -0.0% -0.0% -0.0% infer -0.1% 0.0% -0.0% -0.0% -0.0% integer -0.1% 0.0% -0.0% -0.0% -0.0% integrate -0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide -0.1% 0.0% -0.0% -0.0% -0.0% kahan -0.1% 0.0% -0.0% -0.0% -0.0% knights -0.1% 0.0% -0.0% -0.0% -0.0% lambda -0.1% 0.0% -0.0% -0.0% -0.0% last-piece -0.1% 0.0% -0.0% -0.0% -0.0% lcss -0.1% 0.0% -0.0% -0.0% -0.0% life -0.1% 0.0% -0.0% -0.0% -0.0% lift -0.1% 0.0% -0.0% -0.0% -0.0% linear -0.1% 0.0% -0.0% -0.0% -0.0% listcompr -0.1% 0.0% -0.0% -0.0% -0.0% listcopy -0.1% 0.0% -0.0% -0.0% -0.0% maillist -0.1% 0.0% -0.0% -0.0% -0.0% mandel -0.1% 0.0% -0.0% -0.0% -0.0% mandel2 -0.1% 0.0% -0.0% -0.0% -0.0% mate -0.1% 0.0% -0.0% -0.0% -0.0% minimax -0.1% 0.0% -0.0% -0.0% -0.0% mkhprog -0.1% 0.0% -0.0% -0.0% -0.0% multiplier -0.1% 0.0% -0.0% -0.0% -0.0% n-body -0.1% 0.0% -0.0% -0.0% -0.0% nucleic2 -0.1% 0.0% -0.0% -0.0% -0.0% para -0.1% 0.0% -0.0% -0.0% -0.0% paraffins -0.1% 0.0% -0.0% -0.0% -0.0% parser -0.1% 0.0% -0.0% -0.0% -0.0% parstof -0.1% 0.0% -0.0% -0.0% -0.0% pic -0.1% 0.0% -0.0% -0.0% -0.0% pidigits -0.1% 0.0% -0.0% -0.0% -0.0% power -0.1% 0.0% -0.0% -0.0% -0.0% pretty -0.1% 0.0% -0.1% -0.1% -0.1% primes -0.1% 0.0% -0.0% -0.0% -0.0% primetest -0.1% 0.0% -0.0% -0.0% -0.0% prolog -0.1% 0.0% -0.0% -0.0% -0.0% puzzle -0.1% 0.0% -0.0% -0.0% -0.0% queens -0.1% 0.0% -0.0% -0.0% -0.0% reptile -0.1% 0.0% -0.0% -0.0% -0.0% reverse-complem -0.1% 0.0% -0.0% -0.0% -0.0% rewrite -0.1% 0.0% -0.0% -0.0% -0.0% rfib -0.1% 0.0% -0.0% -0.0% -0.0% rsa -0.1% 0.0% -0.0% -0.0% -0.0% scc -0.1% 0.0% -0.1% -0.1% -0.1% sched -0.1% 0.0% -0.0% -0.0% -0.0% scs -0.1% 0.0% -0.0% -0.0% -0.0% simple -0.1% 0.0% -0.0% -0.0% -0.0% solid -0.1% 0.0% -0.0% -0.0% -0.0% sorting -0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm -0.1% 0.0% -0.0% -0.0% -0.0% sphere -0.1% 0.0% -0.0% -0.0% -0.0% symalg -0.1% 0.0% -0.0% -0.0% -0.0% tak -0.1% 0.0% -0.0% -0.0% -0.0% transform -0.1% 0.0% -0.0% -0.0% -0.0% treejoin -0.1% 0.0% -0.0% -0.0% -0.0% typecheck -0.1% 0.0% -0.0% -0.0% -0.0% veritas -0.0% 0.0% -0.0% -0.0% -0.0% wang -0.1% 0.0% -0.0% -0.0% -0.0% wave4main -0.1% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 -0.1% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 -0.1% 0.0% -0.0% -0.0% -0.0% x2n1 -0.1% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min -0.1% 0.0% -0.5% -0.3% -0.4% Max -0.0% 0.0% +0.0% +0.0% +0.0% Geometric Mean -0.1% -0.0% -0.0% -0.0% -0.0% Test changes ------------ - break006 is marked as broken, see #17833 - The compiler allocates less when building T14683 (an unsafeCoerce#- heavy happy-generated code) on 64-platforms. Allocates more on 32-bit platforms. - Rest of the increases are tiny amounts (still enough to pass the threshold) in micro-benchmarks. I briefly looked at each one in a profiling build: most of the increased allocations seem to be because of random changes in the generated code. Metric Decrease: T14683 Metric Increase: T12150 T12234 T12425 T13035 T14683 T5837 T6048 Co-Authored-By: Richard Eisenberg <rae at cs.brynmawr.edu> Co-Authored-By: Ömer Sinan Ağacan <omeragacan at gmail.com> - - - - - 6880d6aa by Sylvain Henry at 2020-02-20T21:18:48-05:00 Disentangle DynFlags and SDoc Remove several uses of `sdocWithDynFlags`. The remaining ones are mostly CodeGen related (e.g. depend on target platform constants) and will be fixed separately. Metric Decrease: T12425 T9961 WWRec T1969 T14683 - - - - - 70a90110 by Julien Debon at 2020-02-20T21:19:27-05:00 doc(List): Add examples to GHC.List * Add examples * Cleanup documentation * Clarify merge process and Marge bot - - - - - c8439fc7 by Peter Trommler at 2020-02-20T21:20:05-05:00 Fix testsuite on powerpc64le Remove expect broken on recomp tests, #11260 was closed by !2264 and #11323 most likely by !2264 as well. GHCi scripts tests work on GHCi but not the external interpreter, adjust test configuration accordingly. Fixes unexpected passes. Mark test requiring DWARF expect fail on powerpc64[le] for #11261. - - - - - 65b7256a by Ömer Sinan Ağacan at 2020-02-20T21:20:45-05:00 Use concatMap(M) instead of `concat . map` and the monadic variant - - - - - 8b76d457 by Roland Senn at 2020-02-20T21:21:28-05:00 Fix #17832: Weird handling of exports named main in 8.10-rc1 Switching from `lookupGlobalOccRn_maybe` to `lookupInfoOccRn` to check whether a `main` function is in scope. Unfortunately `lookupGlobalOccRn_maybe` complains if there are multiple `main` functions in scope. - - - - - 466e1ad5 by Krzysztof Gogolewski at 2020-02-20T21:22:11-05:00 Use TTG for HsSplicedT constructor The constructor HsSplicedT occurs only in the GhcTc pass. This enforces this fact statically via TTG. - - - - - 4e622fca by Alexis King at 2020-02-20T21:22:49-05:00 Normalize types when dropping absent arguments from workers fixes #17852 - - - - - a533e547 by Adam Sandberg Eriksson at 2020-02-20T21:23:31-05:00 Mention users guide and release notes in merge request template - - - - - 05251b17 by Ben Gamari at 2020-02-20T21:24:08-05:00 gitlab-ci: Fix typo in BIN_DIST_PREP_TAR_COMP variable name - - - - - f44c7e67 by Ben Gamari at 2020-02-20T21:24:46-05:00 gitlab-ci: Avoid duplicating ~/.cabal contents with every build Previously our attempt to cache the cabal store would `cp cabal-cache ~/.cabal`. However, if the latter already existed this meant that we would end up with ~/.cabal/cabal-cache. Not only would this not help caching but it would exponentially grow the size of ~/.cabal. Not good! - - - - - c5ec9965 by Ben Gamari at 2020-02-20T21:56:13-05:00 GHC.Hs.Extension: Use Type instead of * - - - - - 89cb4cc4 by Ben Gamari at 2020-02-20T21:56:13-05:00 Use Type instead of * in GHC - - - - - 04eb0d6c by Ben Gamari at 2020-02-20T21:56:13-05:00 Enable -Wstar-is-type in -Wall As noted in [proposal 0143][proposal] this is supposed to happen in 8.12. Also fix an incorrect claim in the users guide that -Wstar-is-type is enabled by default. [proposal]: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0143-remove-star-kind.rst - - - - - 6de966f1 by Andreas Klebinger at 2020-02-20T21:56:15-05:00 Fix #17724 by having occAnal preserve used bindings. It sometimes happened that occAnal would remove bindings as dead code by relying on bindings to be in dependency order. The fix was contributed by SPJ. - - - - - abd7f962 by Ben Gamari at 2020-02-20T21:56:15-05:00 users-guide: Mention dependency on `exceptions` in release notes Fixes #17845. - - - - - 58175379 by Sylvain Henry at 2020-02-20T21:56:20-05:00 Hadrian: minor GMP refactoring Somehow I forgot to totally remove `gmpContext` in d7029cc09edc052c2f97effe33233c53340fcce0. This patch fixes it and adds some additional comments. - - - - - 33fa8d94 by Ryan Scott at 2020-02-20T21:56:21-05:00 Generalize liftData to work over any Quote (#17857) The Overloaded Quotations proposal generalized the type of `lift` to work over any `Quote`, but not the type of `liftData`, leading to #17857. Thankfully, generalizing `liftData` is extremely straightforward. Fixes #17857. - - - - - 3cea6795 by Sylvain Henry at 2020-02-20T21:56:23-05:00 Make: fix sdist target (#17848) - - - - - e2cce997 by Sylvain Henry at 2020-02-20T21:56:23-05:00 Hadrian: fix source-dist target (#17849) - - - - - 0a4c89b2 by Matthew Pickering at 2020-02-21T20:44:45-05:00 Special case `mkTyConApp liftedTypeKind []` We really need to make sure that these are shared because otherwise GHC will allocate thousands of identical `TyConApp` nodes. See #17292 ------------------------- Metric Decrease: haddock.Cabal T14683 ------------------------- - - - - - 0482f58a by Matthew Pickering at 2020-02-21T20:45:21-05:00 TH: wrapGenSyns, don't split the element type too much The invariant which allowed the pervious method of splitting the type of the body to find the type of the elements didn't work in the new overloaded quotation world as the type can be something like `WriterT () m a` rather than `Q a` like before. Fixes #17839 - - - - - be7068a6 by Vladislav Zavialov at 2020-02-21T20:45:59-05:00 Parser API annotations: RealSrcLoc During parsing, GHC collects lexical information about AST nodes and stores it in a map. It is needed to faithfully restore original source code, e.g. compare these expressions: a = b a = b The position of the equality sign is not recorded in the AST, so it must be stored elsewhere. This system is described in Note [Api annotations]. Before this patch, the mapping was represented by: Map (SrcSpan, AnnKeywordId) SrcSpan After this patch, the mapping is represented by: Map (RealSrcSpan, AnnKeywordId) RealSrcSpan The motivation behind this change is to avoid using the Ord SrcSpan instance (required by Map here), as it interferes with #17632 (see the discussion there). SrcSpan is isomorphic to Either String RealSrcSpan, but we shouldn't use those strings as Map keys. Those strings are intended as hints to the user, e.g. "<interactive>" or "<compiler-generated code>", so they are not a valid way to identify nodes in the source code. - - - - - 240f5bf6 by Sylvain Henry at 2020-02-21T20:46:40-05:00 Modules: Driver (#13009) submodule updates: nofib, haddock - - - - - 9d094111 by Sylvain Henry at 2020-02-21T20:47:19-05:00 Hadrian: `docs` rule needs `configure` (#17840) - - - - - 1674353a by Ben Gamari at 2020-02-23T17:31:19-05:00 fs: Port fixes from ghc-jailbreak repository * Override rename, unlink, and remove * Factor out wchar conversion - - - - - 853210f2 by Adam Sandberg Ericsson at 2020-02-23T17:32:03-05:00 show gcc linker options in configure summary - - - - - 2831544a by Adam Sandberg Ericsson at 2020-02-23T17:32:44-05:00 hadrian: docs depend on stage1 ghc - - - - - 1d9df9e0 by Adam Sandberg Ericsson at 2020-02-23T17:33:23-05:00 ci: after 5ce63d52fed the linux bindist for doc-tarball has changed name - - - - - 26e8fff3 by Vladislav Zavialov at 2020-02-24T02:05:30-05:00 Remove Ord SrcLoc, Ord SrcSpan Before this patch, GHC relied on Ord SrcSpan to identify source elements, by using SrcSpan as Map keys: blackList :: Map SrcSpan () -- compiler/GHC/HsToCore/Coverage.hs instanceMap :: Map SrcSpan Name -- compiler/GHC/HsToCore/Docs.hs Firstly, this design is not valid in presence of UnhelpfulSpan, as it distinguishes between UnhelpfulSpan "X" and UnhelpfulSpan "Y", but those strings are messages for the user, unfit to serve as identifiers for source elements. Secondly, this design made it hard to extend SrcSpan with additional data. Recall that the definition of SrcSpan is: data SrcSpan = RealSrcSpan !RealSrcSpan | UnhelpfulSpan !FastString Say we want to extend the RealSrcSpan constructor with additional information: data SrcSpan = RealSrcSpan !RealSrcSpan !AdditionalInformation | UnhelpfulSpan !FastString getAdditionalInformation :: SrcSpan -> AdditionalInformation getAdditionalInformation (RealSrcSpan _ a) = a Now, in order for Map SrcSpan to keep working correctly, we must *ignore* additional information when comparing SrcSpan values: instance Ord SrcSpan where compare (RealSrcSpan r1 _) (RealSrcSpan r2 _) = compare r1 r2 ... However, this would violate an important law: a == b therefore f a == f b Ignoring AdditionalInformation in comparisons would mean that with f=getAdditionalInformation, the law above does not hold. A more robust design is to avoid Ord SrcSpan altogether, which is what this patch implements. The mappings are changed to use RealSrcSpan instead: blackList :: Set RealSrcSpan -- compiler/GHC/HsToCore/Coverage.hs instanceMap :: Map RealSrcSpan Name -- compiler/GHC/HsToCore/Docs.hs All SrcSpan comparisons are now done with explicit comparison strategies: SrcLoc.leftmost_smallest SrcLoc.leftmost_largest SrcLoc.rightmost_smallest These strategies are not subject to the law mentioned above and can easily discard both the string stored in UnhelpfulSpan and AdditionalInformation. Updates haddock submodule. - - - - - 5aa6c188 by Ben Gamari at 2020-02-24T02:06:09-05:00 users-guide: Shuffle text - - - - - e3f17413 by Ben Gamari at 2020-02-24T02:06:09-05:00 users-guide: Drop old release notes - - - - - 84dd9610 by Ben Gamari at 2020-02-24T02:06:09-05:00 Bump directory submodule to 1.3.6.0 - - - - - e295a024 by Stefan Pavikevik at 2020-02-24T20:53:44-05:00 check for safe arguments, raising error when invalid (fix #17720) - - - - - 354e2787 by Krzysztof Gogolewski at 2020-02-24T20:54:35-05:00 Comments, small refactor * Remove outdated Note [HsForAllTy tyvar binders] and [Context quantification]. Since the wildcard refactor 1e041b7382, HsForAllTy no longer has an flag controlling explicity. The field `hsq_implicit` is gone too. The current situation is covered by Note [HsType binders] which is already linked from LHsQTyVars. * Small refactor in CoreLint, extracting common code to a function * Remove "not so sure about WpFun" in TcEvidence, per Richard's comment https://gitlab.haskell.org/ghc/ghc/merge_requests/852#note_223226 * Use mkIfThenElse in Foreign/Call, as it does exactly what we need. - - - - - 1b1067d1 by Sylvain Henry at 2020-02-24T20:55:25-05:00 Modules: CmmToAsm (#13009) - - - - - 621468f6 by Alexis King at 2020-02-26T15:08:09-05:00 Treat coercions as arguments for floating and inlining This reverts commit 8924224ecfa065ebc67b96a90d01cf9d2edd0e77 and fixes #17787. - - - - - def486c9 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Allow libnuma library path to be specified - - - - - ed03d4e7 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Refactor gmp arguments Move the gmp configuration to its own binding. - - - - - 09b88384 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Tell Cabal about integer-gmp library location - - - - - 161e08c5 by Krzysztof Gogolewski at 2020-02-26T15:09:30-05:00 Remove dead code * FailablePattern can no longer be created since ab51bee40c82 Therefore, Opt_WarnMissingMonadFailInstances has no effect anymore. * XWrap is no longer used, it was moved to an extension field - - - - - e0d09db3 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Use 8.8.3 to bootstrap on Windows This should fix #17861. - - - - - 972bcf3a by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Fix symlink test Needs to `write` bytes, not str. - - - - - 273e60de by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Add shell subcommand for debugging within CI environment - - - - - 43b13ed3 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Fix colors on Darwin Darwin sh doesn't support \e. - - - - - 217546a7 by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Flush stdout buffers in InitEventLogging Otherwise we are sensitive to libc's buffering strategy. Similar to the issue fixed in 543dfaab166c81f46ac4af76918ce32190aaab22. - - - - - c7d4fa55 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Add run_hadrian subcommand I've ruined two trees already by failing to pass --flavour to hadrian. Let's factor this out so it can be reused during troubleshooting. - - - - - 7dc54873 by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Allow tests to be marked as broken on the command line This allows us to work-around distribution-specific breakage easily. - - - - - 25e2458e by Ben Gamari at 2020-02-26T15:10:09-05:00 hadrian: Add --broken-test flag This exposes the flag of the same name supported by the testsuite driver. - - - - - 55769996 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Mark some tests as broken on Alpine - - - - - 9ee7f87d by Ben Gamari at 2020-02-26T15:10:09-05:00 SysTools: Don't use process jobs if they are broken - - - - - bfaa3961 by Ben Gamari at 2020-02-26T15:10:09-05:00 Bump hsc2hs submodule Fixes name of C compiler. - - - - - b2b49a0a by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Make hasMetricsFile RHS more descriptive - - - - - 817f93ea by Sylvain Henry at 2020-02-26T15:10:58-05:00 Modules: Core (#13009) Update haddock submodule - - - - - 74311e10 by Sebastian Graf at 2020-02-27T16:22:45-05:00 PmCheck: Implement Long-distance information with Covered sets Consider ```hs data T = A | B | C f :: T -> Int f A = 1 f x = case x of A -> 2 B -> 3 C -> 4 ``` Clearly, the RHS returning 2 is redundant. But we don't currently see that, because our approximation to the covered set of the inner case expression just picks up the positive information from surrounding pattern matches. It lacks the context sensivity that `x` can't be `A` anymore! Therefore, we adopt the conceptually and practically superior approach of reusing the covered set of a particular GRHS from an outer pattern match. In this case, we begin checking the `case` expression with the covered set of `f`s second clause, which encodes the information that `x` can't be `A` anymore. After this MR, we will successfully warn about the RHS returning 2 being redundant. Perhaps surprisingly, this was a great simplification to the code of both the coverage checker and the desugarer. Found a redundant case alternative in `unix` submodule, so we have to bump it with a fix. Metric Decrease: T12227 - - - - - 59c023ba by Adam Sandberg Ericsson at 2020-02-27T16:23:25-05:00 configure: correctly generate LIBRARY_template_haskell_VERSION - - - - - 9be82389 by Krzysztof Gogolewski at 2020-02-28T02:35:35-05:00 boot: Remove remote origin check Previously, we used relative paths in submodules. When cloning from GitHub, they had to be manually tweaked. Since a76b233d we use absolute paths, so this workaround can be removed. - - - - - f4b6b594 by Ben Gamari at 2020-02-28T02:36:12-05:00 nonmoving: Fix marking in compact regions Previously we were tracing the object we were asked to mark, even if it lives in a compact region. However, there is no need to do this; we need only to mark the region itself as live. I have seen a segfault due to this due to the concurrent mark seeing a an object in the process of being compacted by the mutator. - - - - - f97d1fb6 by Alp Mestanogullari at 2020-02-28T02:36:59-05:00 base: use an explicit import list in System.Environment.ExecutablePath This was making -Werror builds fail on Windows (at least with Hadrian). - - - - - 66f5d6d6 by Simon Peyton Jones at 2020-02-28T22:03:23-05:00 Improve error handling for VTA + deferred type errors This fixes #17792 See Note [VTA for out-of-scope functions] in TcExpr - - - - - 37f12603 by Ilias Tsitsimpis at 2020-02-28T22:04:04-05:00 llvm-targets: Add arm-unknown-linux-gnueabi Add arm-unknown-linux-gnueabi, which is used by Debian's ARM EABI port (armel), as an LLVM target. - - - - - 327b29e1 by Vladislav Zavialov at 2020-02-29T05:06:31-05:00 Monotonic locations (#17632) When GHC is parsing a file generated by a tool, e.g. by the C preprocessor, the tool may insert #line pragmas to adjust the locations reported to the user. As the result, the locations recorded in RealSrcLoc are not monotonic. Elements that appear later in the StringBuffer are not guaranteed to have a higher line/column number. In fact, there are no guarantees whatsoever, as #line pragmas can arbitrarily modify locations. This lack of guarantees makes ideas such as #17544 infeasible. This patch adds an additional bit of information to every SrcLoc: newtype BufPos = BufPos { bufPos :: Int } A BufPos represents the location in the StringBuffer, unaffected by any pragmas. Updates haddock submodule. Metric Increase: haddock.Cabal haddock.base haddock.compiler MultiLayerModules Naperian parsing001 T12150 - - - - - 99d2de86 by Ben Gamari at 2020-02-29T05:07:10-05:00 plugins: Ensure that loadInterface plugins can see annotations loadInterface replaces the `mi_decls`, `mi_insts`, `mi_fam_insts`, `mi_rules`, `mi_anns` fields of ModIface with `undefined` before inserting the interface into the EPS. However, we still want to give loadInterface plugins access to these fields. Consequently, we want to pass the unmodified `ModIface` the plugin. - - - - - a999ee96 by Xavier Denis at 2020-02-29T05:07:50-05:00 Rename ghci.sh and build.sh to ghci and build respectively Convert hadrian buildscripts to unsuffixed, dashed form final cleanups - - - - - b5fb58fd by Ömer Sinan Ağacan at 2020-02-29T05:08:36-05:00 Document and refactor a few things around bitmap scavenging - Added a few comments in StgPAP - Added a few comments and assertions in scavenge_small_bitmap and walk_large_bitmap - Did tiny refactor in GHC.Data.Bitmap: added some comments, deleted dead code, used PlatformWordSize type. - - - - - 18757cab by Sylvain Henry at 2020-02-29T05:09:25-05:00 Refactor runtime interpreter code In #14335 we want to be able to use both the internal interpreter (for the plugins) and the external interpreter (for TH and GHCi) at the same time. This patch performs some preliminary refactoring: the `hsc_interp` field of HscEnv replaces `hsc_iserv` and is now used to indicate which interpreter (internal, external) to use to execute TH and GHCi. Opt_ExternalInterpreter flag and iserv options in DynFlags are now queried only when we set the session DynFlags. It should help making GHC multi-target in the future by selecting an interpreter according to the selected target. - - - - - b86a6395 by Adam Sandberg Ericsson at 2020-02-29T05:10:06-05:00 docs: correct relative links to haddocks from users guide (fixes #17866) - - - - - 0f55df7f by Adam Sandberg Ericsson at 2020-02-29T05:10:06-05:00 docs: correct link to th haddocks from users guide - - - - - 252e5117 by Jean-Baptiste Mazon at 2020-02-29T05:10:46-05:00 rts: enforce POSIX numeric locale for heap profiles - - - - - 34c7d230 by Sylvain Henry at 2020-02-29T05:11:27-05:00 Fix Hadrian's ``--configure`` (fix #17883) - - - - - 04d30137 by Ömer Sinan Ağacan at 2020-02-29T05:12:06-05:00 Simplify IfaceIdInfo type IfaceIdInfo type is confusing: there's practically no difference between `NoInfo` and `HasInfo []`. The comments say NoInfo is used when -fomit-interface-pragmas is enabled, but we don't need to distinguish `NoInfo` from `HasInfo []` in when reading the interface so the distinction is not important. This patch simplifies the type by removing NoInfo. When we have no info we use an empty list. With this change we no longer read the info list lazily when reading an IfaceInfoItem, but when reading an IfaceId the ifIdInfo field is read lazily, so I doubt this is going to be a problem. - - - - - 3979485b by Roland Senn at 2020-02-29T17:36:59+01:00 Show breakpoint locations of breakpoints which were ignored during :force (#2950) GHCi is split up into 2 major parts: The user-interface (UI) and the byte-code interpreter. With `-fexternal-interpreter` they even run in different processes. Communication between the UI and the Interpreter (called `iserv`) is done using messages over a pipe. This is called `Remote GHCI` and explained in the Note [Remote GHCi] in `compiler/ghci/GHCi.hs`. To process a `:force` command the UI sends a `Seq` message to the `iserv` process. Then `iserv` does the effective evaluation of the value. When during this process a breakpoint is hit, the `iserv` process has no additional information to enhance the `Ignoring breakpoint` output with the breakpoint location. To be able to print additional breakpoint information, there are 2 possible implementation choices: 1. Store the needed information in the `iserv` process. 2. Print the `Ignoring breakpoint` from the UI process. For option 1 we need to store the breakpoint info redundantely in 2 places and this is bad. Therfore option 2 was implemented in this MR: - The user enters a `force` command - The UI sends a `Seq` message to the `iserv` process. - If processing of the `Seq` message hits a breakpoint, the `iserv` process returns control to the UI process. - The UI looks up the source location of the breakpoint, and prints the enhanced `Ignoring breakpoint` output. - The UI sends a `ResumeSeq` message to the `iserv` process, to continue forcing. - - - - - 3cf7303b by Krzysztof Gogolewski at 2020-03-02T01:18:33-05:00 Remove dead code * The names in PrelName and THNames are no longer used since TH merged types and kinds, Typeable is kind-polymorphic, .net support was removed * unqualQuasiQuote no longer used since 6f8ff0bbad3b9fa3 - - - - - dbea7e9d by Ilias Tsitsimpis at 2020-03-02T01:19:12-05:00 Do not define hs_atomic{read,write}64() on non-64bit Do not define hs_atomicread64() and hs_atomicwrite64() on machines where WORD_SIZE_IN_BITS is less than 64, just like we do with the rest of the atomic functions which work on 64-bit values. Without this, compilation fails on MIPSel and PowerPC with the following error: /usr/bin/ld: /<<PKGBUILDDIR>>/libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.3_p.a(atomic.p_o): in function `hs_atomicread64': atomic.c:(.text.hs_atomicread64+0x8): undefined reference to `__sync_add_and_fetch_8' /usr/bin/ld: /<<PKGBUILDDIR>>/libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.3_p.a(atomic.p_o): in function `hs_atomicwrite64': atomic.c:(.text.hs_atomicwrite64+0x38): undefined reference to `__sync_bool_compare_and_swap_8' Fixes #17886. - - - - - 7c0c76fb by Roland Senn at 2020-03-02T17:13:55-05:00 Set `ImpredicativeTypes` during :print command. (#14828) If ImpredicativeTypes is not enabled, then `:print <term>` will fail if the type of <term> has nested `forall`s or `=>`s. This is because the GHCi debugger's internals will attempt to unify a metavariable with the type of <term> and then display the result, but if the type has nested `forall`s or `=>`s, then unification will fail. As a result, `:print` will bail out and the unhelpful result will be `<term> = (_t1::t1)` (where `t1` is a metavariable). Beware: <term> can have nested `forall`s even if its definition doesn't use RankNTypes! Here is an example from #14828: class Functor f where fmap :: (a -> b) -> f a -> f b Somewhat surprisingly, `:print fmap` considers the type of fmap to have nested foralls. This is because the GHCi debugger sees the type `fmap :: forall f. Functor f => forall a b. (a -> b) -> f a -> f b`. We could envision deeply instantiating this type to get the type `forall f a b. Functor f => (a -> b) -> f a -> f b`, but this trick wouldn't work for higher-rank types. Instead, we adopt a simpler fix: enable `ImpredicativeTypes` when using `:print` and friends in the GHCi debugger. This is allows metavariables to unify with types that have nested (or higher-rank) `forall`s/`=>`s, which makes `:print fmap` display as `fmap = (_t1::forall a b. Functor f => (a -> b) -> f a -> f b)`, as expected. Although ImpredicativeTypes is a somewhat unpredictable from a type inference perspective, there is no danger in using it in the GHCi debugger, since all of the terms that the GHCi debugger deals with have already been typechecked. - - - - - 2a2f51d7 by Sylvain Henry at 2020-03-02T17:14:38-05:00 Use configure script to detect that we should use in-tree GMP on Windows - - - - - 8c663c2c by Andreas Klebinger at 2020-03-04T16:12:14+01:00 Be explicit about how stack usage of mvar primops are covered. This fixes #17893 [skip-ci] - - - - - cedd6f30 by Ben Gamari at 2020-03-05T14:53:12-05:00 rts: Add getCurrentThreadCPUTime helper - - - - - ace618cd by Ben Gamari at 2020-03-05T14:53:12-05:00 nonmoving-gc: Track time usage of nonmoving marking - - - - - 022b5ad5 by Ben Gamari at 2020-03-05T14:53:12-05:00 Stats: Add sync pauses to +RTS -S output - - - - - 06763234 by Ben Gamari at 2020-03-05T14:53:12-05:00 rts: Report nonmoving collector statistics in machine-readable output - - - - - 70d2b995 by Ben Gamari at 2020-03-09T06:10:52-04:00 nonmoving: Fix collection of sparks Previously sparks living in the non-moving heap would be promptly GC'd by the minor collector since pruneSparkQueue uses the BF_EVACUATED flag, which non-moving heap blocks do not have set. Fix this by implementing proper support in pruneSparkQueue for determining reachability in the non-moving heap. The story is told in Note [Spark management in the nonmoving heap]. - - - - - 9668781a by Ben Gamari at 2020-03-09T06:11:30-04:00 gitlab-ci: Disable Sphinx documentation in Alpine build - - - - - 8eb2c263 by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 Fix Windows breakage by not touching locales on Windows - - - - - b8dab057 by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 rts: ensure C numerics in heap profiles using Windows locales if needed - - - - - 7d95260f by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 rts: refactor and comment profile locales - - - - - 5b627813 by Ryan Scott at 2020-03-09T16:34:14-04:00 Use InstanceSigs in GND/DerivingVia-generated code (#17899) Aside from making the generated code easier to read when `-ddump-deriv` is enabled, this makes the error message in `T15073` substantially simpler (see the updated `T15073` expected stderr). Fixes #17899. - - - - - 70b50778 by Ben Gamari at 2020-03-10T02:05:42-04:00 SysTools: Ensure that error parser can handle absolute paths on Windows This fixes #17786, where the error parser fails to correctly handle the drive name in absolute Windows paths. Unfortunately I couldn't find a satisfactory way to test this. - - - - - 85b861d8 by Ben Gamari at 2020-03-10T02:05:42-04:00 testsuite: Add test for #17786 This isn't pretty but it's perhaps better than nothing. - - - - - ee2c50cb by Sylvain Henry at 2020-03-10T02:06:33-04:00 Hadrian: track missing configure results - - - - - ca8f51d4 by Ömer Sinan Ağacan at 2020-03-10T02:07:22-04:00 Add regression test for T17904 Closes #17904 - - - - - 5fa9cb82 by Richard Eisenberg at 2020-03-10T12:29:46-04:00 anyRewritableTyVar now looks in RuntimeReps Previously, anyRewritableTyVar looked only at the arg and res of `arg -> res`, but their RuntimeReps are also subject to rewriting. Easy to fix. Test case: typecheck/should_compile/T17024 Fixes #17024. - - - - - 5ba01d83 by Ben Price at 2020-03-10T12:30:27-04:00 Clarify a Lint message When developing a plugin I had a shadowing problem, where I generated code app = \f{v r7B} x{v r7B} -> f{v r7B} x{v r7B} This is obviously wrong, since the occurrence of `f` to the right of the arrow refers to the `x` binder (they share a Unique). However, it is rather confusing when Lint reports Mismatch in type between binder and occurrence Var: x{v rB7} since it is printing the binder, rather than the occurrence. It is rather easy to read this as claiming there is something wrong with the `x` occurrence! We change the report to explicitly print both the binder and the occurrence variables. - - - - - 7b2c827b by Simon Peyton Jones at 2020-03-10T12:31:15-04:00 Comments only Clarify code added in #17852 and MR !2724 - - - - - 3300eeac by Krzysztof Gogolewski at 2020-03-10T12:31:54-04:00 Misc cleanup - Remove Note [Existentials in shift_con_pat]. The function shift_con_pat has been removed 15 years ago in 23f40f0e9be6d4. - Remove kcLookupTcTyCon - it's the same as tcLookupTcTyCon - Remove ASSERT in tyConAppArgN. It's already done by getNth, and it's the only reason getNth exists. - Remove unused function nextRole - - - - - abf5736b by Krzysztof Gogolewski at 2020-03-10T18:05:01+01:00 Typos in comments [skip ci] - - - - - bb586f89 by Ben Gamari at 2020-03-11T00:14:59-04:00 rts: Prefer darwin-specific getCurrentThreadCPUTime macOS Catalina now supports a non-POSIX-compliant version of clock_gettime which cannot use the clock_gettime codepath. Fixes #17906. - - - - - 20800b9a by Sylvain Henry at 2020-03-11T08:17:19-04:00 Split GHC.Iface.Utils module * GHC.Iface.Recomp: recompilation avoidance stuff * GHC.Iface.Make: mkIface* Moved `writeIfaceFile` into GHC.Iface.Load alongside `readIface` and renamed it `writeIface` for consistency. - - - - - 1daa2029 by Greg Steuck at 2020-03-11T08:17:56-04:00 Fixed a minor typo in codegen.rst - - - - - 0bc23338 by Ryan Scott at 2020-03-11T08:18:32-04:00 Re-quantify when generalising over rewrite rule types Previously, `tcRules` would check for naughty quantification candidates (see `Note [Naughty quantification candidates]` in `TcMType`) when generalising over the type of a rewrite rule. This caused sensible-looking rewrite rules (like those in #17710) to be rejected. A more permissing (and easier-to-implement) approach is to do what is described in `Note [Generalising in tcTyFamInstEqnGuts]` in `TcTyClsDecls`: just re-quantify all the type variable binders, regardless of the order in which the user specified them. After all, the notion of type variable specificity has no real meaning in rewrite rules, since one cannot "visibly apply" a rewrite rule. I have written up this wisdom in `Note [Re-quantify type variables in rules]` in `TcRules`. As a result of this patch, compiling the `ExplicitForAllRules1` test case now generates one fewer warning than it used to. As far as I can tell, this is benign, since the thing that the disappearing warning talked about was also mentioned in an entirely separate warning. Fixes #17710. - - - - - 336eac7e by Ben Gamari at 2020-03-11T08:19:08-04:00 testsuite: Mark ghci056 and ghcilink004 as fragile in unreg As noted in #17018. Also fix fragile declaration of T13786, which only runs in the normal way. - - - - - c61b9b02 by Simon Peyton Jones at 2020-03-11T08:19:44-04:00 Deepen call stack for isIn I see quite a few warnings like: WARNING: file compiler/utils/Util.hs, line 593 Over-long elem in unionLists But the call stack is uninformative. Better to add HasDebugCallStack to isIn. Ditto isn'tIn. - - - - - 3aa9b35f by Ömer Sinan Ağacan at 2020-03-11T08:20:27-04:00 Zero any slop after compaction in compacting GC In copying GC, with the relevant debug flags enabled, we release the old blocks after a GC, and the block allocator zeroes the space before releasing a block. This effectively zeros the old heap. In compacting GC we reuse the blocks and previously we didn't zero the unused space in a compacting generation after compaction. With this patch we zero the slop between the free pointer and the end of the block when we're done with compaction and when switching to a new block (because the current block doesn't have enough space for the next object we're shifting). - - - - - 8e6febce by Sylvain Henry at 2020-03-11T20:33:37-04:00 Refactor GHC.Driver.Session (Ways and Flags) * extract flags and ways into their own modules (with some renaming) * remove one SOURCE import of GHC.Driver.Session from GHC.Driver.Phases * when GHC uses dynamic linking (WayDyn), `interpWays` was only reporting WayDyn even if the host was profiled (WayProf). Now it returns both as expected (might fix #16803). * `mkBuildTag :: [Way] -> String` wasn't reporting a canonical tag for differently ordered lists. Now we sort and nub the list to fix this. - - - - - bc41e471 by Sylvain Henry at 2020-03-11T20:33:37-04:00 Refactor interpreterDynamic and interpreterProfiled * `interpreterDynamic` and `interpreterProfiled` now take `Interp` parameters instead of DynFlags * slight refactoring of `ExternalInterp` so that we can read the iserv configuration (which is pure) without reading an MVar. - - - - - a6989971 by Sylvain Henry at 2020-03-11T20:33:37-04:00 Use a Set to represent Ways Should make `member` queries faster and avoid messing up with missing `nubSort`. Metric Increase: hie002 - - - - - cb93a1a4 by Ryan Scott at 2020-03-11T20:34:14-04:00 Make DeriveFunctor-generated code require fewer beta reductions Issue #17880 demonstrates that `DeriveFunctor`-generated code is surprisingly fragile when rank-_n_ types are involved. The culprit is that `$fmap` (the algorithm used to generate `fmap` implementations) was too keen on applying arguments with rank-_n_ types to lambdas, which fail to typecheck more often than not. In this patch, I change `$fmap` (both the specification and the implementation) to produce code that avoids creating as many lambdas, avoiding problems when rank-_n_ field types arise. See the comments titled "Functor instances" in `TcGenFunctor` for a more detailed description. Not only does this fix #17880, but it also ensures that the code that `DeriveFunctor` generates will continue to work after simplified subsumption is implemented (see #17775). What is truly amazing is that #17880 is actually a regression (introduced in GHC 7.6.3) caused by commit 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e, the fix #7436. Prior to that commit, the version of `$fmap` that was used was almost identical to the one used in this patch! Why did that commit change `$fmap` then? It was to avoid severe performance issues that would arise for recursive `fmap` implementations, such as in the example below: ```hs data List a = Nil | Cons a (List a) deriving Functor -- ===> instance Functor List where fmap f Nil = Nil fmap f (Cons x xs) = Cons (f x) (fmap (\y -> f y) xs) ``` The fact that `\y -> f y` was eta expanded caused significant performance overheads. Commit 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e fixed this performance issue, but it went too far. As a result, this patch partially reverts 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e. To ensure that the performance issues pre-#7436 do not resurface, I have taken some precautionary measures: * I have added a special case to `$fmap` for situations where the last type variable in an application of some type occurs directly. If this special case fires, we avoid creating a lambda expression. This ensures that we generate `fmap f (Cons x xs) = Cons (f x) (fmap f xs)` in the derived `Functor List` instance above. For more details, see `Note [Avoid unnecessary eta expansion in derived fmap implementations]` in `TcGenFunctor`. * I have added a `T7436b` test case to ensure that the performance of this derived `Functor List`-style code does not regress. When implementing this, I discovered that `$replace`, the algorithm which generates implementations of `(<$)`, has a special case that is very similar to the `$fmap` special case described above. `$replace` marked this special case with a custom `Replacer` data type, which was a bit overkill. In order to use the same machinery for both `Functor` methods, I ripped out `Replacer` and instead implemented a simple way to detect the special case. See the updated commentary in `Note [Deriving <$]` for more details. - - - - - 1f9db3e7 by Kirill Elagin at 2020-03-12T09:45:51-04:00 pretty-printer: Properly parenthesise LastStmt After ApplicatveDo strips the last `return` during renaming, the pretty printer has to restore it. However, if the return was followed by `$`, the dollar was stripped too and not restored. For example, the last stamement in: ``` foo = do x <- ... ... return $ f x ``` would be printed as: ``` return f x ``` This commit preserved the dolar, so it becomes: ``` return $ f x ``` - - - - - 5cb93af7 by Kirill Elagin at 2020-03-12T09:45:51-04:00 pretty-printer: Do not print ApplicativeDo join * Do not print `join` in ApplictiveStmt, unless ppr-debug * Print parens around multiple parallel binds When ApplicativeDo is enabled, the renamer analyses the statements of a `do` block and in certain cases marks them as needing to be rewritten using `join`. For example, if you have: ``` foo = do a <- e1 b <- e2 doSomething a b ``` it will be desugared into: ``` foo = join (doSomething <$> e1 <*> e2) ``` After renaming but before desugaring the expression is stored essentially as: ``` foo = do [will need join] (a <- e1 | b <- e2) [no return] doSomething a b ``` Before this change, the pretty printer would print a call to `join`, even though it is not needed at this stage at all. The expression will be actually rewritten into one using join only at desugaring, at which point a literal call to join will be inserted. - - - - - 3a259092 by Simon Peyton Jones at 2020-03-12T09:46:29-04:00 Expose compulsory unfoldings always The unsafeCoerce# patch requires that unsafeCoerce# has a compulsory unfolding that is always available. So we have to be careful to expose compulsory unfoldings unconditionally and consistently. We didn't get this quite right: #17871. This patch fixes it. No real surprises here. See Note [Always expose compulsory unfoldings] in GHC.Iface.Tidy - - - - - 6a65b8c2 by Alp Mestanogullari at 2020-03-13T02:29:20-04:00 hadrian: improve dependency tracking for the check-* programs The code in Rules.Register responsible for finding all the build artifacts that Cabal installs when registering a library (static/shared libs, .hi files, ...) was looking in the wrong place. This patch fixes that logic and makes sure we gather all those artifacts in a list to declare that the rule for a given `.conf` file, our proxy for "Hadrian, please install this package in the package db for this stage", also produces those artifacts under the said package database. We also were completely missing some logic to declare that the check-* programs have dependencies besides their source code, at least when testing an in-tree compiler. Finally, this patch also removes redundant packages from 'testsuitePackages', since they should already be covered by the stage<N>Packages lists from Settings.Default. With this patch, after a complete build and freezing stage 1, a change to `compiler/parser/Parser.y` results in rebuilding the ghc lib, reinstalling it, and rebuilding the few programs that depend on it, _including_ `check-ppr` and `check-api-annotations` (therefore fixing #17273). - - - - - 44fad4a9 by Sylvain Henry at 2020-03-13T02:30:22-04:00 Rename isDllName I wanted to fix the dangling comment in `isDllName` ("This is the cause of #", #8696 is already mentioned earlier). I took the opportunity to change the function name to better reflect what it does. - - - - - 2f292db8 by Paavo at 2020-03-13T02:31:03-04:00 Update documentation for closureSize - - - - - f124ff0d by Ben Gamari at 2020-03-13T02:31:40-04:00 gitlab-ci: Rework triggering of release builds Use a push option instead of tagging. - - - - - 7f25557a by Ben Gamari at 2020-03-13T10:38:09-04:00 gitlab-ci: Distinguish integer-simple test envs Previously two integer-simple jobs declared the same test environment. One (the nightly job) was built in the perf way, the other in the validate way. Consequently they had appreciably different performance characteristics, causing in the nightly job to spuriously fail with performance changes. - - - - - c12a2ec5 by Simon Peyton Jones at 2020-03-14T05:25:30-04:00 Fix Lint Ticket #17590 pointed out a bug in the way the linter dealt with type lets, exposed by the new uniqAway story. The fix is described in Note [Linting type lets]. I ended up putting the in-scope Ids in a different env field, le_ids, rather than (as before) sneaking them into the TCvSubst. Surprisingly tiresome, but done. Metric Decrease: hie002 - - - - - b989845e by Sylvain Henry at 2020-03-14T05:26:11-04:00 Hadrian: fix absolute buildroot support (#17822) Shake's "**" wildcard doesn't match absolute root. We must use "//" instead. - - - - - 4f117135 by Sylvain Henry at 2020-03-14T05:26:49-04:00 Make: refactor GMP rules Document and use simpler rules for the ghc-gmp.h header. - - - - - 7432b327 by Sylvain Henry at 2020-03-14T05:27:28-04:00 Use correct option name (-opti) (fix #17314) s/pgmo/opti - - - - - 8f7dd571 by Judah Jacobson at 2020-03-14T05:28:07-04:00 Allow overriding LD_STAGE0 and AR_STAGE0 in the configure script. Previously it was possible to override the stage0 C compiler via `CC_STAGE0`, but you couldn't override `ld` or `ar` in stage0. This change allows overriding them by setting `LD_STAGE0` or `AR_STAGE0`, respectively. Our team uses this feature internally to take more control of our GHC build and make it run more hermetically. - - - - - 7c3e39a9 by Judah Jacobson at 2020-03-14T05:28:07-04:00 Use AC_ARG_VAR for LD_STAGE0 and AR_STAGE0. - - - - - 20d4d676 by Ben Gamari at 2020-03-14T05:28:43-04:00 nonmoving: Don't traverse filled segment list in pause The non-moving collector would previously walk the entire filled segment list during the preparatory pause. However, this is far more work than is strictly necessary. We can rather get away with merely collecting the allocators' filled segment list heads and process the lists themselves during the concurrent phase. This can significantly reduce the maximum gen1 GC pause time in programs with high rates of long-lived allocations. - - - - - fdfa2d01 by Ben Gamari at 2020-03-14T05:29:18-04:00 nonmoving: Remove redundant bitmap clearing nonmovingSweep already clears the bitmap in the sweep loop. There is no reason to do so a second time. - - - - - 2f8c7767 by Simon Peyton Jones at 2020-03-14T05:29:55-04:00 Simple refactor of cheapEqExpr No change in functionality. Just seems tidier (and signficantly more efficient) to deal with ticks directly than to call stripTicksTopE. - - - - - 88f7a762 by Simon Peyton Jones at 2020-03-14T05:29:55-04:00 Improve CSE.combineAlts This patch improves the way that CSE combines identical alternatives. See #17901. I'm still not happy about the duplication between CSE.combineAlts and GHC.Core.Utils.combineIdenticalAlts; see the Notes with those functions. But this patch is a step forward. Metric Decrease: T12425 T5642 - - - - - 8b95ddd3 by Ben Gamari at 2020-03-14T05:30:31-04:00 gitlab-ci: Add integer-simple release build for Windows Closes #16144. - - - - - e3c374cc by Simon Peyton Jones at 2020-03-14T05:31:07-04:00 Wrap an implication around class-sig kind errors Ticket #17841 showed that we can get a kind error in a class signature, but lack an enclosing implication that binds its skolems. This patch * Adds the wrapping implication: the new call to checkTvConstraints in tcClassDecl1 * Simplifies the API to checkTvConstraints, which was not otherwise called at all. * Simplifies TcErrors.report_unsolved by *not* initialising the TidyEnv from the typechecker lexical envt. It's enough to do so from the free vars of the unsolved constraints; and we get silly renamings if we add variables twice: once from the lexical scope and once from the implication constraint. - - - - - 73133a3b by Simon Peyton Jones at 2020-03-14T05:31:07-04:00 Refactoring in TcSMonad This patch is just refactoring: no change in behaviour. I removed the rather complicated checkConstraintsTcS checkTvConstraintsTcS in favour of simpler functions emitImplicationTcS emitTvImplicationTcS pushLevelNoWorkList The last of these is a little strange, but overall it's much better I think. - - - - - 93c88c26 by Ben Gamari at 2020-03-14T05:31:42-04:00 base: Make `open` calls interruptible As noted in #17912, `open` system calls were `safe` rather than `interruptible`. Consequently, the program could not be interrupted with SIGINT if stuck in a slow open operation. Fix this by marking `c_safe_open` as interruptible. - - - - - bee4cdad by Vladislav Zavialov at 2020-03-14T05:32:18-04:00 Remove second tcLookupTcTyCon in tcDataDefn Before this patch, tcDataDefn used to call tcLookupTcTyCon twice in a row: 1. in bindTyClTyVars itself 2. in the continuation passed to it Now bindTyClTyVars passes the TcTyCon to the continuation, making the second lookup unnecessary. - - - - - 3f116d35 by Cale Gibbard at 2020-03-14T19:34:42-04:00 Enable stage1 build of haddock The submodule has already been bumped to contain the fix. - - - - - 49e9d739 by Ömer Sinan Ağacan at 2020-03-14T19:35:24-04:00 rts: Fix printClosure when printing fwd ptrs - - - - - 1de3ab4a by Krzysztof Gogolewski at 2020-03-14T19:36:04-04:00 Remove unused field var_inline (#17915) - - - - - d30aeb4b by Krzysztof Gogolewski at 2020-03-15T03:57:41-04:00 Document restriction on SCC pragma syntax Currently, the names of cost centres must be quoted or be lowercase identifiers. Fixes #17916. - - - - - b4774598 by Brian Foley at 2020-03-15T03:58:18-04:00 Remove some dead code >From the notes.ghc.drop list found using weeder in #17713 - - - - - dd6ffe6b by Viktor Dukhovni at 2020-03-15T03:58:55-04:00 Note platform-specific Foreign.C.Types in context Also fix the markup in the general note at the top of the module. Haddock (usability trade-off), does not support multi-line emphasised text. - - - - - 2e82465f by Sylvain Henry at 2020-03-15T10:57:10-04:00 Refactor CmmToAsm (disentangle DynFlags) This patch disentangles a bit more DynFlags from the native code generator (CmmToAsm). In more details: - add a new NCGConfig datatype in GHC.CmmToAsm.Config which contains the configuration of a native code generation session - explicitly pass NCGConfig/Platform arguments when necessary - as a consequence `sdocWithPlatform` is gone and there are only a few `sdocWithDynFlags` left - remove the use of `unsafeGlobalDynFlags` from GHC.CmmToAsm.CFG - remove `sdocDebugLevel` (now we pass the debug level via NCGConfig) There are still some places where DynFlags is used, especially because of pretty-printing (CLabel), because of Cmm helpers (such as `cmmExprType`) and because of `Outputable` instance for the instructions. These are left for future refactoring as this patch is already big. - - - - - c35c545d by Judah Jacobson at 2020-03-15T10:57:48-04:00 Add a -no-haddock flag. This flag undoes the effect of a previous "-haddock" flag. Having both flags makes it easier for build systems to enable Haddock parsing in a set of global flags, but then disable it locally for specific targets (e.g., third-party packages whose comments don't pass the validation in the latest GHC). I added the flag to expected-undocumented-flags.txt since `-haddock` was alreadyin that list. - - - - - cfcc3c9a by Ömer Sinan Ağacan at 2020-03-15T10:58:27-04:00 Fix global_link of TSOs for threads reachable via dead weaks Fixes #17785 Here's how the problem occurs: - In generation 0 we have a TSO that is finished (i.e. it has no more work to do or it is killed). - The TSO only becomes reachable after collectDeadWeakPtrs(). - After collectDeadWeakPtrs() we switch to WeakDone phase where we don't move TSOs to different lists anymore (like the next gen's thread list or the resurrected_threads list). - So the TSO will never be moved to a generation's thread list, but it will be promoted to generation 1. - Generation 1 collected via mark-compact, and because the TSO is reachable it is marked, and its `global_link` field, which is bogus at this point (because the TSO is not in a list), will be threaded. - Chaos ensues. In other words, when these conditions hold: - A TSO is reachable only after collectDeadWeakPtrs() - It's finished (what_next is ThreadComplete or ThreadKilled) - It's retained by mark-compact collector (moving collector doesn't evacuate the global_list field) We end up doing random mutations on the heap because the TSO's global_list field is not valid, but it still looks like a heap pointer so we thread it during compacting GC. The fix is simple: when we traverse old_threads lists to resurrect unreachable threads the threads that won't be resurrected currently stays on the old_threads lists. Those threads will never be visited again by MarkWeak so we now reset the global_list fields. This way compacting GC does not thread pointers to nowhere. Testing ------- The reproducer in #17785 is quite large and hard to build, because of the dependencies, so I'm not adding a regression test. In my testing the reproducer would take a less than 5 seconds to run, and once in every ~5 runs would fail with a segfault or an assertion error. In other cases it also fails with a test failure. Because the tests never fail with the bug fix, assuming the code is correct, this also means that this bug can sometimes lead to incorrect runtime results. After the fix I was able to run the reproducer repeatedly for about an hour, with no runtime crashes or test failures. To run the reproducer clone the git repo: $ git clone https://github.com/osa1/streamly --branch ghc-segfault Then clone primitive and atomic-primops from their git repos and point to the clones in cabal.project.local. The project should then be buildable using GHC HEAD. Run the executable `properties` with `+RTS -c -DZ`. In addition to the reproducer above I run the test suite using: $ make slowtest EXTRA_HC_OPTS="-debug -with-rtsopts=-DS \ -with-rtsopts=-c +RTS -c -RTS" SKIPWAY='nonmoving nonmoving_thr' This enables compacting GC always in both GHC when building the test programs and when running the test programs, and also enables sanity checking when running the test programs. These set of flags are not compatible for all tests so there are some failures, but I got the same set of failures with this patch compared to GHC HEAD. - - - - - 818b3c38 by Lysxia at 2020-03-16T23:52:42-04:00 base: add strict IO functions: readFile', getContents', hGetContents' - - - - - 18a346a4 by Sylvain Henry at 2020-03-16T23:53:24-04:00 Modules: Core (#13009) Update submodule: haddock - - - - - 92327e3a by Ömer Sinan Ağacan at 2020-03-16T23:54:04-04:00 Update sanity checking for TSOs: - Remove an invalid assumption about GC checking what_next field. The GC doesn't care about what_next at all, if a TSO is reachable then all its pointers are followed (other than global_tso, which is only followed by compacting GC). - Remove checkSTACK in checkTSO: TSO stacks will be visited in checkHeapChain, or checkLargeObjects etc. - Add an assertion in checkTSO to check that the global_link field is sane. - Did some refactor to remove forward decls in checkGlobalTSOList and added braces around single-statement if statements. - - - - - e1aa4052 by PHO at 2020-03-17T07:36:09-04:00 Don't use non-portable operator "==" in configure.ac The test operator "==" is a Bash extension and produces a wrong result if /bin/sh is not Bash. - - - - - 89f034dd by Maximilian Tagher at 2020-03-17T07:36:48-04:00 Document the units of -ddump-timings Right now, in the output of -ddump-timings to a file, you can't tell what the units are: ``` CodeGen [TemplateTestImports]: alloc=22454880 time=14.597 ``` I believe bytes/milliseconds are the correct units, but confirmation would be appreciated. I'm basing it off of this snippet from `withTiming'`: ``` when (verbosity dflags >= 2 && prtimings == PrintTimings) $ liftIO $ logInfo dflags (defaultUserStyle dflags) (text "!!!" <+> what <> colon <+> text "finished in" <+> doublePrec 2 time <+> text "milliseconds" <> comma <+> text "allocated" <+> doublePrec 3 (realToFrac alloc / 1024 / 1024) <+> text "megabytes") ``` which implies time is in milliseconds, and allocations in bytes (which divided by 1024 would be KB, and again would be MB) - - - - - beffa147 by Simon Peyton Jones at 2020-03-17T07:37:25-04:00 Implement mapTyCo like foldTyCo This patch makes mapType use the successful idiom described in TyCoRep Note [Specialising foldType] I have not yet changed any functions to use mapType, though there may be some suitable candidates. This patch should be a no-op in terms of functionality but, because it inlines the mapper itself, I'm hoping that there may be some modest perf improvements. Metric Decrease: T5631 T5642 T3064 T9020 T14683 hie002 haddock.Cabal haddock.base haddock.compiler - - - - - 5800ebfe by Ömer Sinan Ağacan at 2020-03-17T07:38:08-04:00 Don't update ModDetails with CafInfos when opts are disabled This is consistent with the interface file behavior where we omit HsNoCafRefs annotations with -fomit-interface-pragmas (implied by -O0). ModDetails and ModIface are just different representations of the same thing, so they really need to be in sync. This patch does the right thing and does not need too much explanation, but here's an example of a problem not doing this causes in !2842: -- MyInteger.hs module MyInteger ( MyInteger (MyInteger) , ToMyInteger (toMyInteger) ) where newtype MyInteger = MyInteger Integer class ToMyInteger a where toMyInteger :: a -> MyInteger instance ToMyInteger Integer where toMyInteger = MyInteger {- . succ -} -- Main.hs module Main ( main ) where import MyInteger (MyInteger (MyInteger), toMyInteger) main :: IO () main = do let (MyInteger i) = (id . toMyInteger) (41 :: Integer) print i If I build this with -O0, without this fix, we generate a ModDetails with accurate LFInfo for toMyInteger (MyInteger.$fToMyIntegerInteger) which says that it's a LFReEntrant with arity 1. This means in the use site (Main) we tag the value: R3 = MyInteger.$fToMyIntegerInteger_closure + 1; R2 = GHC.Base.id_closure; R1 = GHC.Base.._closure; Sp = Sp - 16; call stg_ap_ppp_fast(R4, R3, R2, R1) args: 24, res: 0, upd: 24; Now we change the definition by uncommenting the `succ` part and it becomes a thunk: MyInteger.$fToMyIntegerInteger [InlPrag=INLINE (sat-args=0)] :: MyInteger.ToMyInteger GHC.Integer.Type.Integer [GblId[DFunId(nt)]] = {} \u [] $ctoMyInteger_rEA; and its LFInfo is now LFThunk. This change in LFInfo makes a difference in the use site: we can no longer tag it. But becuase the interface fingerprint does not change (because ModIface does not change) we don't rebuild Main and tag the thunk. (1.2% increase in allocations when building T12545 on armv7 because we generate more code without CafInfos) Metric Increase: T12545 - - - - - 5b632dad by Paavo at 2020-03-17T07:38:48-04:00 Add example for Data.Semigroup.diff - - - - - 4d85d68b by Paavo at 2020-03-17T07:38:48-04:00 Clean up - - - - - 75168d07 by Paavo at 2020-03-17T07:38:48-04:00 Make example collapsible - - - - - 53ff2cd0 by Richard Eisenberg at 2020-03-17T13:46:57+00:00 Fix #17021 by checking more return kinds All the details are in new Note [Datatype return kinds] in TcTyClsDecls. Test case: typecheck/should_fail/T17021{,b} typecheck/should_compile/T17021a Updates haddock submodule - - - - - 528df8ec by Sylvain Henry at 2020-03-18T10:06:43-04:00 Modules: Core operations (#13009) - - - - - 4e8a71c1 by Richard Eisenberg at 2020-03-18T10:07:19-04:00 Add release note about fix to #16502. We thought we needed to update the manual, but the fix for #16502 actually brings the implementation in line with the manual. So we just alert users of how to update their code. - - - - - 5cbf9934 by Andreas Klebinger at 2020-03-19T00:39:27-04:00 Update "GHC differences to the FFI Chapter" in user guide. The old entry had a heavy focus on how things had been. Which is not what I generally look for in a user guide. I also added a small section on behaviour of nested safe ffi calls. [skip-ci] - - - - - b03fd3bc by Sebastian Graf at 2020-03-19T00:40:06-04:00 PmCheck: Use ConLikeSet to model negative info In #17911, Simon recognised many warnings stemming from over-long list unions while coverage checking Cabal's `LicenseId` module. This patch introduces a new `PmAltConSet` type which uses a `UniqDSet` instead of an association list for `ConLike`s. For `PmLit`s, it will still use an assocation list, though, because a similar map data structure would entail a lot of busy work. Fixes #17911. - - - - - 64f20756 by Sylvain Henry at 2020-03-19T12:16:49-04:00 Refactoring: use Platform instead of DynFlags when possible Metric Decrease: ManyConstructors T12707 T13035 T1969 - - - - - cb1785d9 by Ömer Sinan Ağacan at 2020-03-19T12:16:54-04:00 FastString: fix eager reading of string ptr in hashStr This read causes NULL dereferencing when len is 0. Fixes #17909 In the reproducer in #17909 this bug is triggered as follows: - SimplOpt.dealWithStringLiteral is called with a single-char string ("=" in #17909) - tailFS gets called on the FastString of the single-char string. - tailFS checks the length of the string, which is 1, and calls mkFastStringByteString on the tail of the ByteString, which is an empty ByteString as the original ByteString has only one char. - ByteString's unsafeUseAsCStringLen returns (NULL, 0) for the empty ByteString, which is passed to mkFastStringWith. - mkFastStringWith gets hash of the NULL pointer via hashStr, which fails on empty strings because of this bug. - - - - - 73a7383e by Richard Eisenberg at 2020-03-20T20:42:56-04:00 Simplify treatment of heterogeneous equality Previously, if we had a [W] (a :: k1) ~ (rhs :: k2), we would spit out a [D] k1 ~ k2 and part the W as irreducible, hoping for a unification. But we needn't do this. Instead, we now spit out a [W] co :: k2 ~ k1 and then use co to cast the rhs of the original Wanted. This means that we retain the connection between the spat-out constraint and the original. The problem with this new approach is that we cannot use the casted equality for substitution; it's too like wanteds-rewriting- wanteds. So, we forbid CTyEqCans that mention coercion holes. All the details are in Note [Equalities with incompatible kinds] in TcCanonical. There are a few knock-on effects, documented where they occur. While debugging an error in this patch, Simon and I ran into infelicities in how patterns and matches are printed; we made small improvements. This patch includes mitigations for #17828, which causes spurious pattern-match warnings. When #17828 is fixed, these lines should be removed. - - - - - faa36e5b by Sylvain Henry at 2020-03-20T20:43:41-04:00 Hadrian: ignore in-tree GMP objects with ``--lint`` - - - - - 9a96ff6b by Richard Eisenberg at 2020-03-20T20:44:17-04:00 Update core spec to reflect changes to Core. Key changes: * Adds a new rule for forall-coercions over coercion variables, which was implemented but conspicuously missing from the spec. * Adds treatment for FunCo. * Adds treatment for ForAllTy over coercion variables. * Improves commentary (including restoring a Note lost in 03d4852658e1b7407abb4da84b1b03bfa6f6db3b) in the source. No changes to running code. - - - - - 7e0451c6 by Sergej Jaskiewicz at 2020-03-20T20:44:55-04:00 Fix event message in withTiming' This typo caused generating 'end' events without the corresponding 'begin' events. - - - - - 1542a626 by Ben Gamari at 2020-03-22T22:37:47-04:00 fs.h: Add missing declarations on Windows - - - - - 3bcf2ccd by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump process submodule Avoids redundant case alternative warning. - - - - - 3b363ef9 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Normalize slashes in ghc-api annotations output Enable `normalise_slashes` on `annotations`, `listcomps`, and `parseTree` to fix Windows failures. - - - - - 25fc9429 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - 7f58ec6d by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Fix TOP of T17786 - - - - - aadcd909 by GHC GitLab CI at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - dc1eb10d by GHC GitLab CI at 2020-03-22T22:37:47-04:00 hadrian: Fix executable extension passed to testsuite driver - - - - - 58f62e2c by GHC GitLab CI at 2020-03-22T22:37:47-04:00 gitlab-ci: Require that Windows-hadrian job passes - - - - - 8dd2415d by Ben Gamari at 2020-03-22T22:37:47-04:00 hadrian: Eliminate redundant .exe from GHC path Previously we were invoking: bash -c "c:/GitLabRunner/builds/eEQrxK4p/0/ghc/ghc/toolchain/bin/ghc.exe.exe testsuite/mk/ghc-config.hs -o _build/test/bin/ghc-config.exe" - - - - - 373621f6 by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump hsc2hs submodule - - - - - abc02b40 by Hécate at 2020-03-22T22:38:33-04:00 Annotate the non-total function in Data.Foldable as such - - - - - 19f12557 by Josef Svenningsson at 2020-03-23T14:05:33-04:00 Fix ApplicativeDo regression #17835 A previous fix for #15344 made sure that monadic 'fail' is used properly when translating ApplicativeDo. However, it didn't properly account for when a 'fail' will be inserted which resulted in some programs failing with a type error. - - - - - 2643ba46 by Paavo at 2020-03-24T08:31:32-04:00 Add example and doc for Arg (Fixes #17153) - - - - - 703221f4 by Roland Senn at 2020-03-25T14:45:04-04:00 Use export list of Main module in function TcRnDriver.hs:check_main (Fix #16453) - Provide the export list of the `Main` module as parameter to the `compiler/typecheck/TcRnDriver.hs:check_main` function. - Instead of `lookupOccRn_maybe` call the function `lookupInfoOccRn`. It returns the list `mains_all` of all the main functions in scope. - Select from this list `mains_all` all `main` functions that are in the export list of the `Main` module. - If this new list contains exactly one single `main` function, then typechecking continues. - Otherwise issue an appropriate error message. - - - - - 3e27205a by Sebastian Graf at 2020-03-25T14:45:40-04:00 Remove -fkill-absence and -fkill-one-shot flags They seem to be a benchmarking vestige of the Cardinality paper and probably shouldn't have been merged to HEAD in the first place. - - - - - 262e42aa by Peter Trommler at 2020-03-25T22:41:39-04:00 Do not panic on linker errors - - - - - 0de03cd7 by Sylvain Henry at 2020-03-25T22:42:02-04:00 DynFlags refactoring III Use Platform instead of DynFlags when possible: * `tARGET_MIN_INT` et al. replaced with `platformMinInt` et al. * no more DynFlags in PreRules: added a new `RuleOpts` datatype * don't use `wORD_SIZE` in the compiler * make `wordAlignment` use `Platform` * make `dOUBLE_SIZE` a constant Metric Decrease: T13035 T1969 - - - - - 7a04920b by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: fix a typo in liftA doc This change removes an extra '|' that should not be rendered in the liftA documentation. Tracking: #17929 - - - - - 1c5a15f7 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add Control.Applicative optional example This change adds an optional example. Tracking: #17929 - - - - - 6d172e63 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add markup around Except - - - - - eb2162c8 by John Ericson at 2020-03-26T12:37:08-04:00 Remove unused `ghciTablesNextToCode` from compiler proper - - - - - f51efc4b by Joachim Breitner at 2020-03-26T12:37:09-04:00 Prepare to use run-time tablesNextToCode in compiler exclusively Factor out CPP as much as possible to prepare for runtime determinattion. Progress towards #15548 - - - - - 1c446220 by Joachim Breitner at 2020-03-26T12:37:09-04:00 Use run-time tablesNextToCode in compiler exclusively (#15548) Summary: - There is no more use of the TABLES_NEXT_TO_CODE CPP macro in `compiler/`. GHCI_TABLES_NEXT_TO_CODE is also removed entirely. The field within `PlatformMisc` within `DynFlags` is used instead. - The field is still not exposed as a CLI flag. We might consider some way to ensure the right RTS / libraries are used before doing that. Original reviewers: Original subscribers: TerrorJack, rwbarton, carter Original Differential Revision: https://phabricator.haskell.org/D5082 - - - - - 1941ef4f by Sylvain Henry at 2020-03-29T17:28:51-04:00 Modules: Types (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - 1c7c6f1a by Sylvain Henry at 2020-03-29T17:28:51-04:00 Remove GHC.Types.Unique.Map module This module isn't used anywhere in GHC. - - - - - f1a6c73d by Sylvain Henry at 2020-03-29T17:28:51-04:00 Merge GHC.Types.CostCentre.Init into GHC.Driver.CodeOutput - - - - - 54250f2d by Simon Peyton Jones at 2020-03-29T17:29:30-04:00 Demand analysis: simplify the demand for a RHS Ticket #17932 showed that we were using a stupid demand for the RHS of a let-binding, when the result is a product. This was the result of a "fix" in 2013, which (happily) turns out to no longer be necessary. So I just deleted the code, which simplifies the demand analyser, and fixes #17932. That in turn uncovered that the anticipation of worker/wrapper in CPR analysis was inaccurate, hence the logic that decides whether to unbox an argument in WW was extracted into a function `wantToUnbox`, now consulted by CPR analysis. I tried nofib, and got 0.0% perf changes. All this came up when messing about with !2873 (ticket #17917), but is idependent of it. Unfortunately, this patch regresses #4267 and realised that it is now blocked on #16335. - - - - - 03060b2f by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 on Windows Fixes line ending normalization issue. - - - - - 1f7995ba by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 Fix missing quoting and expected exit code. - - - - - ef9c608e by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Mark T12971 as broken on Windows Due to #17945. - - - - - e54500c1 by Sylvain Henry at 2020-03-29T17:30:47-04:00 Store ComponentId details As far as GHC is concerned, installed package components ("units") are identified by an opaque ComponentId string provided by Cabal. But we don't want to display it to users (as it contains a hash) so GHC queries the database to retrieve some infos about the original source package (name, version, component name). This patch caches these infos in the ComponentId itself so that we don't need to provide DynFlags (which contains installed package informations) to print a ComponentId. In the future we want GHC to support several independent package states (e.g. for plugins and for target code), hence we need to avoid implicitly querying a single global package state. - - - - - 7e7cb714 by Marius Bakke at 2020-03-29T17:31:27-04:00 testsuite: Remove test that dlopens a PIE object. glibc 2.30 disallowed dlopening PIE objects, so just remove the test. Fixes #17952. - - - - - 6c8f80d8 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Correct haddocks for testBit in Data.Bits It conflated the nth bit with the bit at offset n. Now we instead give the definition in terms of `bit and `.&.` on top of clearer phrasing. - - - - - c916f190 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Apply suggestion to libraries/base/Data/Bits.hs - - - - - 64bf7f51 by Ben Gamari at 2020-03-29T17:32:41-04:00 gitlab-ci: Add FreeBSD release job - - - - - a0d8e92e by Ryan Scott at 2020-03-29T17:33:20-04:00 Run checkNewDataCon before constraint-solving newtype constructors Within `checkValidDataCon`, we used to run `checkValidType` on the argument types of a newtype constructor before running `checkNewDataCon`, which ensures that the user does not attempt non-sensical things such as newtypes with multiple arguments or constraints. This works out in most situations, but this falls over on a corner case revealed in #17955: ```hs newtype T = Coercible () T => T () ``` `checkValidType`, among other things, peforms an ambiguity check on the context of a data constructor, and that it turn invokes the constraint solver. It turns out that there is a special case in the constraint solver for representational equalities (read: `Coercible` constraints) that causes newtypes to be unwrapped (see `Note [Unwrap newtypes first]` in `TcCanonical`). This special case does not know how to cope with an ill formed newtype like `T`, so it ends up panicking. The solution is surprisingly simple: just invoke `checkNewDataCon` before `checkValidType` to ensure that the illicit newtype constructor context is detected before the constraint solver can run amok with it. Fixes #17955. - - - - - 45eb9d8c by Krzysztof Gogolewski at 2020-03-29T17:33:59-04:00 Minor cleanup - Simplify mkBuildExpr, the function newTyVars was called only on a one-element list. - TTG: use noExtCon in more places. This is more future-proof. - In zonkExpr, panic instead of printing a warning. - - - - - f024b6e3 by Sylvain Henry at 2020-03-30T12:48:39+02:00 Expect T4267 to pass Since 54250f2d8de910b094070c1b48f086030df634b1 we expected T4267 to fail, but it passes on CI. - - - - - 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.0.0 This requires bumping the `exceptions` and `text` submodules to bring in commits that bump their respective upper version bounds on `template-haskell`. Fixes #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - ffd7eef2 by Takenobu Tani at 2020-04-22T23:09:50-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - e8a5d81b by Jonathan DK Gibbons at 2020-04-22T23:10:28-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - dcb7fe5a by John Ericson at 2020-04-22T23:10:28-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - cde23cd4 by John Ericson at 2020-04-22T23:10:28-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - 72cb6bcc by John Ericson at 2020-04-22T23:10:28-04:00 Generalize type of `matchCanFail` - - - - - 401f7bb3 by John Ericson at 2020-04-22T23:10:28-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 6c9fae23 by Alexis King at 2020-04-22T23:11:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 48b8951e by Roland Senn at 2020-04-22T23:11:51-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 34a45ee6 by Peter Trommler at 2020-04-22T23:12:27-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - ffde2348 by Simon Peyton Jones at 2020-04-22T23:13:06-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 6f84aca3 by Ben Gamari at 2020-04-22T23:13:43-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - c29f0fa6 by Andreas Klebinger at 2020-04-22T23:14:21-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 4b4a8b60 by Ben Gamari at 2020-04-22T23:14:57-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 831b6642 by Moritz Angermann at 2020-04-22T23:15:33-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - c409961a by Ryan Scott at 2020-04-22T23:16:12-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 125aa2b8 by Ömer Sinan Ağacan at 2020-04-22T23:16:51-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - 8ea37b01 by Sylvain Henry at 2020-04-22T23:17:34-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - cd8409c2 by Ryan Scott at 2020-04-23T11:39:24-04:00 Create di_scoped_tvs for associated data family instances properly See `Note [Associated data family instances and di_scoped_tvs]` in `GHC.Tc.TyCl.Instance`, which explains all of the moving parts. Fixes #18055. - - - - - 339e8ece by Ben Gamari at 2020-04-23T11:40:02-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 5946c85a by Ben Gamari at 2020-04-23T11:40:38-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - c42754d5 by John Ericson at 2020-04-23T18:32:43-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 72da0c29 by mniip at 2020-04-23T18:33:21-04:00 Add :doc to GHC.Prim - - - - - 2c23e2e3 by mniip at 2020-04-23T18:33:21-04:00 Include docs for non-primop entries in primops.txt as well - - - - - 0ac29c88 by mniip at 2020-04-23T18:33:21-04:00 GHC.Prim docs: note and test - - - - - b0fbfc75 by John Ericson at 2020-04-24T12:07:14-04:00 Switch order on `GhcMake.IsBoot` In !1798 we were requested to replace many `Bool`s with this data type. But those bools had `False` meaning `NotBoot`, so the `Ord` instance would be flipped if we use this data-type as-is. Since the planned formally-`Bool` occurrences vastly outnumber the current occurrences, we figured it would be better to conform the `Ord` instance to how the `Bool` is used now, fixing any issues, rather than fix them currently with the bigger refactor later in !1798. That way, !1798 can be a "pure" refactor with no behavioral changes. - - - - - af332442 by Sylvain Henry at 2020-04-26T13:55:14-04:00 Modules: Utils and Data (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - cd4434c8 by Sylvain Henry at 2020-04-26T13:55:16-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 22bf5c73 by Ömer Sinan Ağacan at 2020-04-26T13:55:22-04:00 Tweak includes in non-moving GC headers We don't use hash tables in non-moving GC so remove the includes. This breaks Compact.c as existing includes no longer include Hash.h, so include Hash.h explicitly in Compact.c. - - - - - 99823ed2 by Sylvain Henry at 2020-04-27T20:24:46-04:00 TH: fix Show/Eq/Ord instances for Bytes (#16457) We shouldn't compare pointer values but the actual bytes. - - - - - c62271a2 by Alp Mestanogullari at 2020-04-27T20:25:33-04:00 hadrian: always capture both stdout and stderr when running a builder fails The idea being that when a builder('s command) fails, we quite likely want to have all the information available to figure out why. Depending on the builder _and_ the particular problem, the useful bits of information can be printed on stdout or stderr. We accomplish this by defining a simple wrapper for Shake's `cmd` function, that just _always_ captures both streams in case the command returns a non-zero exit code, and by using this wrapper everywhere in `hadrian/src/Builder.hs`. Fixes #18089. - - - - - 4b9764db by Ryan Scott at 2020-04-28T15:40:04-04:00 Define a Quote IO instance Fixes #18103. - - - - - 518a63d4 by Ryan Scott at 2020-04-28T15:40:42-04:00 Make boxed 1-tuples have known keys Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. - - - - - 2cfc4ab9 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Document backpack fields in DynFlags - - - - - 10a2ba90 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 69562e34 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 9e2c8e0e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - ea717aa4 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 10d15f1e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 8bfb0219 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - 71484b09 by Alexis King at 2020-04-30T01:57:35-04:00 Allow block arguments in arrow control operators Arrow control operators have their own entries in the grammar, so they did not cooperate with BlockArguments. This was just a minor oversight, so this patch adjusts the grammar to add the desired behavior. fixes #18050 - - - - - a48cd2a0 by Alexis King at 2020-04-30T01:57:35-04:00 Allow LambdaCase to be used as a command in proc notation - - - - - f4d3773c by Alexis King at 2020-04-30T01:57:35-04:00 Document BlockArguments/LambdaCase support in arrow notation - - - - - 5bdfdd13 by Simon Peyton Jones at 2020-04-30T01:58:15-04:00 Add tests for #17873 - - - - - 19b701c2 by Simon Peyton Jones at 2020-04-30T07:30:13-04:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - 014ef4a3 by Matthew Pickering at 2020-04-30T07:30:50-04:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 2aa67611 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - 54dad3cf by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - 99ff8145 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 05b0a9fd by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 Remove OneShotInfo field of LFReEntrant, document OneShotInfo The field is only used in withNewTickyCounterFun and it's easier to directly pass a parameter for one-shot info to withNewTickyCounterFun instead of passing it via LFReEntrant. This also makes !2842 simpler. Other changes: - New Note (by SPJ) [OneShotInfo overview] added. - Arity argument of thunkCode removed as it's always 0. - - - - - a43620c6 by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 GHC.StgToCmm.Ticky: remove a few unused stuff - - - - - 780de9e1 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Use platform in Iface Binary - - - - - f8386c7b by Sylvain Henry at 2020-05-01T10:37:39-04:00 Refactor PprDebug handling If `-dppr-debug` is set, then PprUser and PprDump styles are silently replaced with PprDebug style. This was done in `mkUserStyle` and `mkDumpStyle` smart constructors. As a consequence they needed a DynFlags parameter. Now we keep the original PprUser and PprDump styles until they are used to create an `SDocContext`. I.e. the substitution is only performed in `initSDocContext`. - - - - - b3df9e78 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Remove PprStyle param of logging actions Use `withPprStyle` instead to apply a specific style to a SDoc. - - - - - de9fc995 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Fully remove PprDebug PprDebug was a pain to deal with consistently as it is implied by `-dppr-debug` but it isn't really a PprStyle. We remove it completely and query the appropriate SDoc flag instead (`sdocPprDebug`) via helpers (`getPprDebug` and its friends). - - - - - 8b51fcbd by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Only call checkSingle if we would report warnings - - - - - fd7ea0fe by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - f387ecaa by Richard Eisenberg at 2020-05-02T23:14:24+01:00 Check kinds of AppTys when checking equality. See updates to Note [Respecting definitional equality] in TyCoRep. Close #17674. - - - - - d533a7b0 by Richard Eisenberg at 2020-05-02T23:14:24+01:00 Compare FunTys as if they were TyConApps. See Note [Equality on FunTys] in TyCoRep. Close #17675. - - - - - 3ef8df65 by Richard Eisenberg at 2020-05-02T23:14:24+01:00 Update comments around definitional equality. No changes to code. Close #17655. - - - - - 15 changed files: - .ghcid - .gitlab-ci.yml - + .gitlab/ci.sh - − .gitlab/darwin-init.sh - .gitlab/linters/check-cpp.py - .gitlab/merge_request_templates/merge-request.md - − .gitlab/prepare-system.sh - − .gitlab/win32-init.sh - CODEOWNERS - HACKING.md - aclocal.m4 - boot - + compiler/GHC.hs - + compiler/GHC/Builtin/Names.hs - + compiler/GHC/Builtin/Names.hs-boot The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d36910105e490e40aa54650576c090f55967db64...3ef8df658be2cd1755eb19d54cada21d7cfa5284 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d36910105e490e40aa54650576c090f55967db64...3ef8df658be2cd1755eb19d54cada21d7cfa5284 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 3 00:16:14 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Sat, 02 May 2020 20:16:14 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18127 Message-ID: <5eae0d4eb9e27_61673f81cc913ba08470934@gitlab.haskell.org.mail> Ryan Scott pushed new branch wip/T18127 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18127 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 3 00:17:18 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Sat, 02 May 2020 20:17:18 -0400 Subject: [Git][ghc/ghc][wip/T18127] Make isTauTy detect higher-rank contexts Message-ID: <5eae0d8e70f9f_616711ab08a484711ba@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T18127 at Glasgow Haskell Compiler / GHC Commits: 110d3601 by Ryan Scott at 2020-05-02T20:16:42-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _`). Fixes #18127. - - - - - 7 changed files: - compiler/GHC/Core/Type.hs - + testsuite/tests/deriving/should_fail/T18127b.hs - + testsuite/tests/deriving/should_fail/T18127b.stderr - testsuite/tests/deriving/should_fail/all.T - + testsuite/tests/typecheck/should_fail/T18127a.hs - + testsuite/tests/typecheck/should_fail/T18127a.stderr - testsuite/tests/typecheck/should_fail/all.T Changes: ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -1857,14 +1857,16 @@ fun_kind_arg_flags = go emptyTCvSubst -- something is ill-kinded. But this can happen -- when printing errors. Assume everything is Required. --- @isTauTy@ tests if a type has no foralls +-- @isTauTy@ tests if a type has no foralls or (=>) isTauTy :: Type -> Bool isTauTy ty | Just ty' <- coreView ty = isTauTy ty' isTauTy (TyVarTy _) = True isTauTy (LitTy {}) = True isTauTy (TyConApp tc tys) = all isTauTy tys && isTauTyCon tc isTauTy (AppTy a b) = isTauTy a && isTauTy b -isTauTy (FunTy _ a b) = isTauTy a && isTauTy b +isTauTy (FunTy af a b) = case af of + InvisArg -> False + VisArg -> isTauTy a && isTauTy b isTauTy (ForAllTy {}) = False isTauTy (CastTy ty _) = isTauTy ty isTauTy (CoercionTy _) = False -- Not sure about this ===================================== testsuite/tests/deriving/should_fail/T18127b.hs ===================================== @@ -0,0 +1,8 @@ +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE RankNTypes #-} +module T18127b where + +import GHC.Generics + +data T1 = MkT1 (forall a. a) deriving (Eq, Generic) +data T2 a = MkT2 (Show a => a) deriving (Eq, Generic) ===================================== testsuite/tests/deriving/should_fail/T18127b.stderr ===================================== @@ -0,0 +1,22 @@ + +T18127b.hs:7:40: error: + • Can't make a derived instance of ‘Eq T1’: + Constructor ‘MkT1’ has a higher-rank type + Possible fix: use a standalone deriving declaration instead + • In the data declaration for ‘T1’ + +T18127b.hs:7:44: error: + • Can't make a derived instance of ‘Generic T1’: + MkT1 must not have exotic unlifted or polymorphic arguments + • In the data declaration for ‘T1’ + +T18127b.hs:8:42: error: + • Can't make a derived instance of ‘Eq (T2 a)’: + Constructor ‘MkT2’ has a higher-rank type + Possible fix: use a standalone deriving declaration instead + • In the data declaration for ‘T2’ + +T18127b.hs:8:46: error: + • Can't make a derived instance of ‘Generic (T2 a)’: + MkT2 must not have exotic unlifted or polymorphic arguments + • In the data declaration for ‘T2’ ===================================== testsuite/tests/deriving/should_fail/all.T ===================================== @@ -76,6 +76,7 @@ test('T15073', [extra_files(['T15073a.hs'])], multimod_compile_fail, ['T15073', '-v0']) test('T16181', normal, compile_fail, ['']) test('T16923', normal, compile_fail, ['']) +test('T18127b', normal, compile_fail, ['']) test('deriving-via-fail', normal, compile_fail, ['']) test('deriving-via-fail2', normal, compile_fail, ['']) test('deriving-via-fail3', normal, compile_fail, ['']) ===================================== testsuite/tests/typecheck/should_fail/T18127a.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE RankNTypes #-} +module T18127a where + +a :: (forall a. a) -> () +a = undefined + +b :: (Show a => a) -> () +b = undefined + +type C = forall a. a +c :: C -> () +c = undefined + +type D a = Show a => a +d :: D a -> () +d = undefined ===================================== testsuite/tests/typecheck/should_fail/T18127a.stderr ===================================== @@ -0,0 +1,32 @@ + +T18127a.hs:5:5: error: + • Cannot instantiate unification variable ‘a1’ + with a type involving polytypes: (forall a. a) -> () + GHC doesn't yet support impredicative polymorphism + • In the expression: undefined + In an equation for ‘a’: a = undefined + +T18127a.hs:8:5: error: + • Cannot instantiate unification variable ‘a3’ + with a type involving polytypes: (Show a => a) -> () + GHC doesn't yet support impredicative polymorphism + • In the expression: undefined + In an equation for ‘b’: b = undefined + • Relevant bindings include + b :: (Show a => a) -> () (bound at T18127a.hs:8:1) + +T18127a.hs:12:5: error: + • Cannot instantiate unification variable ‘a0’ + with a type involving polytypes: C -> () + GHC doesn't yet support impredicative polymorphism + • In the expression: undefined + In an equation for ‘c’: c = undefined + +T18127a.hs:16:5: error: + • Cannot instantiate unification variable ‘a2’ + with a type involving polytypes: D a -> () + GHC doesn't yet support impredicative polymorphism + • In the expression: undefined + In an equation for ‘d’: d = undefined + • Relevant bindings include + d :: D a -> () (bound at T18127a.hs:16:1) ===================================== testsuite/tests/typecheck/should_fail/all.T ===================================== @@ -563,3 +563,4 @@ test('T17021', normal, compile_fail, ['']) test('T17021b', normal, compile_fail, ['']) test('T17955', normal, compile_fail, ['']) test('T17173', normal, compile_fail, ['']) +test('T18127a', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/110d36018023eca8a82aba70561e301038af961f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/110d36018023eca8a82aba70561e301038af961f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 3 02:21:27 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 02 May 2020 22:21:27 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 10 commits: Use platform in Iface Binary Message-ID: <5eae2aa79dded_6167120888bc848322a@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 780de9e1 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Use platform in Iface Binary - - - - - f8386c7b by Sylvain Henry at 2020-05-01T10:37:39-04:00 Refactor PprDebug handling If `-dppr-debug` is set, then PprUser and PprDump styles are silently replaced with PprDebug style. This was done in `mkUserStyle` and `mkDumpStyle` smart constructors. As a consequence they needed a DynFlags parameter. Now we keep the original PprUser and PprDump styles until they are used to create an `SDocContext`. I.e. the substitution is only performed in `initSDocContext`. - - - - - b3df9e78 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Remove PprStyle param of logging actions Use `withPprStyle` instead to apply a specific style to a SDoc. - - - - - de9fc995 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Fully remove PprDebug PprDebug was a pain to deal with consistently as it is implied by `-dppr-debug` but it isn't really a PprStyle. We remove it completely and query the appropriate SDoc flag instead (`sdocPprDebug`) via helpers (`getPprDebug` and its friends). - - - - - 8b51fcbd by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Only call checkSingle if we would report warnings - - - - - fd7ea0fe by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 613e8e0e by Ben Gamari at 2020-05-02T22:21:03-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. - - - - - 494a6a51 by Ben Gamari at 2020-05-02T22:21:03-04:00 users guide: Move eventlog documentation users guide - - - - - 4bfbe11f by Ben Gamari at 2020-05-02T22:21:03-04:00 users guide: Add documentation for non-moving GC events - - - - - a9b306d8 by Alexis King at 2020-05-02T22:21:22-04:00 Flatten nested casts in the simple optimizer Normally, we aren’t supposed to generated any nested casts, since mkCast takes care to flatten them, but the simple optimizer didn’t use mkCast, so they could show up after inlining. This isn’t really a problem, since the simplifier will clean them up immediately anyway, but it can clutter the -ddump-ds output, and it’s an extremely easy fix. closes #18112 - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Driver.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/TyCo/Ppr.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Match.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Iface/Type.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a6e8bbfd6161dfca0f5772e84f3f94a6de9c3baf...a9b306d88eb6ea86a7cb7fbcf31f70e8c75b5a54 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a6e8bbfd6161dfca0f5772e84f3f94a6de9c3baf...a9b306d88eb6ea86a7cb7fbcf31f70e8c75b5a54 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 3 08:41:45 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 03 May 2020 04:41:45 -0400 Subject: [Git][ghc/ghc][master] 3 commits: rts: Enable tracing of nonmoving heap census with -ln Message-ID: <5eae83c913bdd_61673f819b417d1c8504865@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 7bfe9ac5 by Ben Gamari at 2020-05-03T04:41:33-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. - - - - - c560dd07 by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Move eventlog documentation users guide - - - - - 02543d5e by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Add documentation for non-moving GC events - - - - - 6 changed files: - docs/users_guide/conf.py - docs/users_guide/eventlog-formats.rst - docs/users_guide/runtime_control.rst - includes/rts/EventLogFormat.h - rts/RtsFlags.c - rts/sm/NonMoving.c Changes: ===================================== docs/users_guide/conf.py ===================================== @@ -283,8 +283,18 @@ def setup(app): objname='runtime system command-line option', parse_node=parse_flag, indextemplate='pair: %s; RTS option', + doc_field_types=[ + Field('since', label='Introduced in GHC version', names=['since']) + ]) + + app.add_object_type('event-type', 'event-type', + objname='event log event type', + indextemplate='pair: %s; eventlog event type', doc_field_types=[ Field('since', label='Introduced in GHC version', names=['since']), + Field('tag', label='Event type ID', names=['tag']), + Field('length', label='Record length', names=['length']), + TypedField('fields', label='Fields', names='field', typenames=('fieldtype', 'type')) ]) app.add_object_type('pragma', 'pragma', ===================================== docs/users_guide/eventlog-formats.rst ===================================== @@ -1,3 +1,5 @@ +.. _eventlog-encodings: + Eventlog encodings ================== @@ -7,6 +9,481 @@ thread scheduling events, garbage collection statistics, profiling information, user-defined tracing events. This section is intended for implementors of tooling which consume these events. +GHC ships with a C header file (``EventlogFormat.h``) which provides symbolic +names for the event type IDs described in this file. + + +Event log format +---------------- + +The log format is designed to be extensible: old tools should be +able to parse (but not necessarily understand all of) new versions +of the format, and new tools will be able to understand old log +files. + +- The format is endian-independent: all values are represented in + big-endian order. + +- The format is extensible: + + - The header describes each event type and its length. Tools + that don't recognise a particular event type can skip those events. + + - There is room for extra information in the event type + specification, which can be ignored by older tools. + + - Events can have extra information added, but existing fields + cannot be changed. Tools should ignore extra fields at the + end of the event record. + +The event-log stream begins with a header describing the event types present in +the file. The header is followed by the event records themselves, each of which +consist of a 64-bit timestamp + +.. code-block:: none + + log : EVENT_HEADER_BEGIN + EventType* + EVENT_HEADER_END + EVENT_DATA_BEGIN + Event* + EVENT_DATA_END + + EventType : + EVENT_ET_BEGIN + Word16 -- unique identifier for this event + Int16 -- >=0 size of the event in bytes (minus the header) + -- -1 variable size + Word32 -- length of the next field in bytes + Word8* -- string describing the event + Word32 -- length of the next field in bytes + Word8* -- extra info (for future extensions) + EVENT_ET_END + + Event : + Word16 -- event_type + Word64 -- time (nanosecs) + [Word16] -- length of the rest (for variable-sized events only) + ... extra event-specific info ... + +There are two classes of event types: + + - *Fixed size*: All event records of a fixed-sized type are of the same + length, given in the header event-log header. + + - *Variable size*: Each event record includes a length field. + +Runtime system diagnostics +-------------------------- + + * ``ThreadId ~ Word32`` + * ``CapNo ~ Word16`` + * ``CapSetId ~ Word32`` + +Capability sets +~~~~~~~~~~~~~~~ + +TODO + +Environment information +~~~~~~~~~~~~~~~~~~~~~~~ + +These events are typically produced during program startup and describe the +environment which the program is being run in. + +.. event-type:: RTS_IDENTIFIER + + :tag: 29 + :length: variable + :field CapSetId: Capability set + :field String: Runtime system name and version. + + Describes the name and version of the runtime system responsible for the + indicated capability set. + +.. event-type:: PROGRAM_ARGS + + :tag: 30 + :length: variable + :field CapSetId: Capability set + :field [String]: The command-line arguments passed to the program + + Describes the command-line used to start the program. + +.. event-type:: PROGRAM_ENV + + :tag: 31 + :length: variable + :field CapSetId: Capability set + :field [String]: The environment variable name/value pairs. (TODO: encoding?) + + Describes the environment variables present in the program's environment. + +Thread and scheduling events +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. event-type:: CREATE_THREAD + + :tag: 0 + :length: fixed + :field ThreadId: thread id + + Marks the creation of a Haskell thread. + + +.. event-type:: RUN_THREAD + + :tag: 1 + :length: fixed + :field ThreadId: thread id + + The indicated thread has started running. + + +.. event-type:: STOP_THREAD + + :tag: 2 + :length: fixed + :field ThreadId: thread id + :field Word16: status + + * 1: HeapOverflow + * 2: StackOverflow + * 3: ThreadYielding + * 4: ThreadBlocked + * 5: ThreadFinished + * 6: ForeignCall + * 7: BlockedOnMVar + * 8: BlockedOnBlackHole + * 9: BlockedOnRead + * 10: BlockedOnWrite + * 11: BlockedOnDelay + * 12: BlockedOnSTM + * 13: BlockedOnDoProc + * 16: BlockedOnMsgThrowTo + + :field ThreadId: thread id of thread being blocked on (only for some status + values) + + The indicated thread has stopped running for the reason given by ``status``. + + +.. event-type:: THREAD_RUNNABLE + + :tag: 3 + :length: fixed + :field ThreadId: thread id + + The indicated thread is has been marked as ready to run. + + +.. event-type:: MIGRATE_THREAD + + :tag: 4 + :length: fixed + :field ThreadId: thread id + :field CapNo: capability + + The indicated thread has been migrated to a new capability. + + +.. event-type:: THREAD_WAKEUP + + :tag: 8 + :length: fixed + :field ThreadId: thread id + :field CapNo: other capability + + The indicated thread has been been woken up on another capability. + +.. event-type:: THREAD_LABEL + + :tag: 44 + :length: fixed + :field ThreadId: thread id + :field String: label + + The indicated thread has been given a label (e.g. with + :base-ref:`Control.Concurrent.setThreadLabel`). + + +Garbage collector events +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. event-type:: GC_START + + :tag: 9 + :length: fixed + + A garbage collection pass has been started. + +.. event-type:: GC_END + + :tag: 10 + :length: fixed + + A garbage collection pass has been finished. + +.. event-type:: REQUEST_SEQ_GC + + :tag: 11 + :length: fixed + + A sequential garbage collection has been requested by a capability. + +.. event-type:: REQUEST_PAR_GC + + :tag: 12 + :length: fixed + + A parallel garbage collection has been requested by a capability. + +.. event-type:: GC_IDLE + + :tag: 20 + :length: fixed + + An idle-time garbage collection has been started. + +.. event-type:: GC_WORK + + :tag: 21 + :length: fixed + + Marks the start of concurrent scavenging. + +.. event-type:: GC_DONE + + :tag: 22 + :length: fixed + + Marks the end of concurrent scavenging. + +.. event-type:: GC_STATS_GHC + + :tag: 53 + :length: fixed + :field CapSetId: heap capability set + :field Word16: generation of collection + :field Word64: bytes copied + :field Word64: bytes of slop found + :field Word64: TODO + :field Word64: number of parallel garbage collection threads + :field Word64: maximum number of bytes copied by any single collector thread + :field Word64: total bytes copied by all collector threads + + Report various information about the heap configuration. Typically produced + during RTS initialization.. + +.. event-type:: GC_GLOBAL_SYNC + + :tag: 54 + :length: fixed + + TODO + +Heap events and statistics +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. event-type:: HEAP_ALLOCATED + + :tag: 49 + :length: fixed + :field CapSetId: heap capability set + :field Word64: allocated bytes + + A new chunk of heap has been allocated by the indicated capability set. + +.. event-type:: HEAP_SIZE + + :tag: 50 + :length: fixed + :field CapSetId: heap capability set + :field Word64: heap size in bytes + + Report the heap size. + +.. event-type:: HEAP_LIVE + + :tag: 51 + :length: fixed + :field CapSetId: heap capability set + :field Word64: heap size in bytes + + Report the live heap size. + +.. event-type:: HEAP_INFO_GHC + + :tag: 52 + :length: fixed + :field CapSetId: heap capability set + :field Word16: number of garbage collection generations + :field Word64: maximum heap size + :field Word64: allocation area size + :field Word64: MBlock size + :field Word64: Block size + + Report various information about the heap configuration. Typically produced + during RTS initialization.. + +Spark events +~~~~~~~~~~~~ + +.. event-type:: CREATE_SPARK_THREAD + + :tag: 15 + :length: fixed + + A thread has been created to perform spark evaluation. + +.. event-type:: SPARK_COUNTERS + + :tag: 34 + :length: fixed + + A periodic reporting of various statistics of spark evaluation. + +.. event-type:: SPARK_CREATE + + :tag: 35 + :length: fixed + + A spark has been added to the spark pool. + +.. event-type:: SPARK_DUD + + :tag: 36 + :length: fixed + + TODO + +.. event-type:: SPARK_OVERFLOW + + :tag: 37 + :length: fixed + + TODO + +.. event-type:: SPARK_RUN + + :tag: 38 + :length: fixed + + Evaluation has started on a spark. + +.. event-type:: SPARK_STEAL + + :tag: 39 + :length: fixed + :field Word16: capability from which the spark was stolen + + A spark has been stolen from another capability for evaluation. + +.. event-type:: SPARK_FIZZLE + + :tag: 40 + :length: fixed + + A spark has been GC'd before being evaluated. + +.. event-type:: SPARK_GC + + :tag: 41 + :length: fixed + + An unevaluated spark has been garbage collected. + +Capability events +~~~~~~~~~~~~~~~~~ + +.. event-type:: CAP_CREATE + + :tag: 45 + :length: fixed + :field CapNo: the capability number + + A capability has been started. + +.. event-type:: CAP_DELETE + + :tag: 46 + :length: fixed + + A capability has been deleted. + +.. event-type:: CAP_DISABLE + + :tag: 47 + :length: fixed + + A capability has been disabled. + +.. event-type:: CAP_ENABLE + + :tag: 48 + :length: fixed + + A capability has been enabled. + +Task events +~~~~~~~~~~~ + +.. event-type:: TASK_CREATE + + :tag: 55 + :length: fixed + :field TaskId: task id + :field CapNo: capability number + :field ThreadId: TODO + + Marks the creation of a task. + +.. event-type:: TASK_MIGRATE + + :tag: 56 + :length: fixed + :field TaskId: task id + :field CapNo: old capability + :field CapNo: new capability + + Marks the migration of a task to a new capability. + +Tracing events +~~~~~~~~~~~~~~ + +.. event-type:: LOG_MSG + + :tag: 16 + :length: variable + :field String: The message + + A log message from the runtime system. + +.. event-type:: BLOCK_MARKER + + :tag: 18 + :length: variable + :field Word32: size + :field Word64: end time in nanoseconds + :field String: marker name + + TODO + +.. event-type:: USER_MSG + + :tag: 19 + :length: variable + :field String: message + + A user log message (from, e.g., :base-ref:`Control.Concurrent.traceEvent`). + +.. event-type:: USER_MARKER + + :tag: 58 + :length: variable + :field String: marker name + + A user marker (from :base-ref:`Debug.Trace.traceMarker`). .. _heap-profiler-events: @@ -28,11 +505,13 @@ Beginning of sample stream A single fixed-width event emitted during program start-up describing the samples that follow. - * ``EVENT_HEAP_PROF_BEGIN`` +.. event-type:: HEAP_PROF_BEGIN - * ``Word8``: Profile ID - * ``Word64``: Sampling period in nanoseconds - * ``Word32``: Sample break-down type. One of, + :tag: 160 + :length: variable + :field Word8: profile ID + :field Word64: sampling period in nanoseconds + :field Word32: sample breadown type. One of, * ``HEAP_PROF_BREAKDOWN_COST_CENTER`` (output from :rts-flag:`-hc`) * ``HEAP_PROF_BREAKDOWN_CLOSURE_DESCR`` (output from :rts-flag:`-hd`) @@ -42,32 +521,34 @@ A single fixed-width event emitted during program start-up describing the sample * ``HEAP_PROF_BREAKDOWN_BIOGRAPHY`` (output from :rts-flag:`-hb`) * ``HEAP_PROF_BREAKDOWN_CLOSURE_TYPE`` (output from :rts-flag:`-hT`) - * ``String``: Module filter - * ``String``: Closure description filter - * ``String``: Type description filter - * ``String``: Cost centre filter - * ``String``: Cost centre stack filter - * ``String``: Retainer filter - * ``String``: Biography filter + :field String: module filter + :field String: closure description filter + :field String: type description filter + :field String: cost centre filter + :field String: cost centre stack filter + :field String: retainer filter + :field String: biography filter Cost centre definitions ^^^^^^^^^^^^^^^^^^^^^^^ A variable-length packet produced once for each cost centre, - * ``EVENT_HEAP_PROF_COST_CENTRE`` +.. event-type:: HEAP_PROF_COST_CENTRE - * ``Word32``: cost centre number - * ``String``: label - * ``String``: module - * ``String``: source location - * ``Word8``: flags + :tag: 161 + :length: fixed + :field Word32: cost centre number + :field String: label + :field String: module + :field String: source location + :field Word8: flags: * bit 0: is the cost-centre a CAF? Sample event types -~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^ A sample (consisting of a list of break-down classes, e.g. cost centres, and heap residency sizes), is to be encoded in the body of one or more events. @@ -75,9 +556,12 @@ heap residency sizes), is to be encoded in the body of one or more events. We normally mark the beginning of a new sample with an ``EVENT_HEAP_PROF_SAMPLE_BEGIN`` event, - * ``EVENT_HEAP_PROF_SAMPLE_BEGIN`` +.. event-type:: HEAP_PROF_SAMPLE_BEGIN + + :length: fixed + :field Word64: sample number - * ``Word64``: sample number + Marks the beginning of a heap profile sample. Biographical profiling samples start with the ``EVENT_HEAP_BIO_PROF_SAMPLE_BEGIN`` event. These events also include a timestamp which indicates when the sample @@ -85,11 +569,12 @@ was taken. This is because all these samples will appear at the end of the eventlog due to how the biographical profiling mode works. You can use the timestamp to reorder the samples relative to the other events. - * ``EVENT_HEAP_BIO_PROF_SAMPLE_BEGIN`` - - * ``Word64``: sample number - * ``Word64``: eventlog timestamp in ns +.. event-type:: HEAP_BIO_PROF_SAMPLE_BEGIN + :tag: 166 + :length: fixed + :field Word64: sample number + :field Word64: eventlog timestamp in ns A heap residency census will follow. Since events may only be up to 2^16^ bytes in length a single sample may need to be split among multiple @@ -101,23 +586,29 @@ emitted. This is useful to properly delimit the sampling period and to record the total time spent profiling. - * ``EVENT_HEAP_PROF_SAMPLE_END`` - * ``Word64``: sample number +.. event-type:: HEAP_PROF_SAMPLE_END + :tag: 165 + :length: fixed + :field Word64: sample number + + Marks the end of a heap profile sample. Cost-centre break-down ^^^^^^^^^^^^^^^^^^^^^^ A variable-length packet encoding a heap profile sample broken down by, - * cost-centre (``-hc``) + * cost-centre (:rts-flag:`-hc`) - * ``EVENT_HEAP_PROF_SAMPLE_COST_CENTRE`` +.. event-type:: HEAP_PROF_SAMPLE_COST_CENTRE - * ``Word8``: Profile ID - * ``Word64``: heap residency in bytes - * ``Word8``: stack depth - * ``Word32[]``: cost centre stack starting with inner-most (cost centre numbers) + :tag: 163 + :length: variable + :field Word8: profile ID + :field Word64: heap residency in bytes + :field Word8: stack depth + :field Word32[]: cost centre stack starting with inner-most (cost centre numbers) String break-down @@ -125,42 +616,142 @@ String break-down A variable-length event encoding a heap sample broken down by, - * type description (``-hy``) - * closure description (``-hd``) - * module (``-hm``) + * type description (:rts-flag:`-hy`) + * closure description (:rts-flag:`-hd`) + * module (:rts-flag:`-hm`) - * ``EVENT_HEAP_PROF_SAMPLE_STRING`` +.. event-type:: HEAP_PROF_SAMPLE_STRING - * ``Word8``: Profile ID - * ``Word64``: heap residency in bytes - * ``String``: type or closure description, or module name + :tag: 164 + :length: variable + :field Word8: profile ID + :field Word64: heap residency in bytes + :field String: type or closure description, or module name .. _time-profiler-events: Time profiler event log output ------------------------------ -The time profiling mode enabled by ``-p`` also emits sample events to the eventlog. -At the start of profiling the tick interval is emitted to the eventlog and then -on each tick the current cost centre stack is emitted. Together these enable -a user to construct an approximate track of the executation of their program. +The time profiling mode enabled by :rts-flag:`-p` also emits +sample events to the eventlog. At the start of profiling the +tick interval is emitted to the eventlog and then on each tick +the current cost centre stack is emitted. Together these +enable a user to construct an approximate track of the +executation of their program. Profile begin event ~~~~~~~~~~~~~~~~~~~ - * ``EVENT_PROF_BEGIN`` +.. event-type:: PROF_BEGIN - * ``Word64``: Tick interval, in nanoseconds + :tag: 168 + :length: fixed + :field Word64: tick interval, in nanoseconds + Marks the beginning of a time profile. -Tick sample event -~~~~~~~~~~~~~~~~~ +Profile sample event +~~~~~~~~~~~~~~~~~~~~ A variable-length packet encoding a profile sample. - * ``EVENT_PROF_SAMPLE_COST_CENTRE`` +.. event-type:: PROF_SAMPLE_COST_CENTRE + + :tag: 167 + :length: variable + :field Word32: capability + :field Word64: current profiling tick + :field Word8: stack depth + :field Word32[]: cost centre stack starting with inner-most (cost centre numbers) + +Biographical profile sample event +--------------------------------- + +A variable-length packet encoding a profile sample. + +.. event-type:: BIO_PROF_SAMPLE_BEGIN + + :tag: 166 + + TODO + +.. _nonmoving-gc-events: + +Non-moving GC event output +-------------------------- + +These events mark various stages of the +:rts-flag:`non-moving collection <--nonmoving-gc>` lifecycle. These are enabled +with the ``+RTS -lg`` event-set. + +.. event-type:: CONC_MARK_BEGIN + + :tag: 200 + :length: fixed + + Marks the beginning of marking by the concurrent collector. + +.. event-type:: CONC_MARK_END + + :tag: 201 + :length: fixed + + Marks the end of marking by the concurrent collector. + +.. event-type:: CONC_SYNC_BEGIN + + :tag: 202 + :length: fixed + + Marks the beginning of the concurrent garbage collector's + post-mark synchronization phase. + +.. event-type:: CONC_SYNC_END + + :tag: 203 + :length: fixed + + Marks the end of the concurrent garbage collector's + post-mark synchronization phase. + +.. event-type:: CONC_SWEEP_BEGIN + + :tag: 204 + :length: fixed + + Marks the beginning of the concurrent garbage collector's + sweep phase. + +.. event-type:: CONC_SWEEP_END + + :tag: 205 + :length: fixed + + Marks the end of the concurrent garbage collector's + sweep phase. + +.. event-type:: CONC_UPD_REM_SET_FLUSH + + :tag: 206 + :length: fixed + + Marks a capability flushing its local update remembered set + accumulator. + +Non-moving heap census +~~~~~~~~~~~~~~~~~~~~~~ + +The non-moving heap census events (enabled with the ``+RTS -ln`` event-set) are +intended to provide insight into fragmentation of the non-moving heap. + +.. event-type:: NONMOVING_HEAP_CENSUS + + :tag: 207 + :length: fixed + :field Word8: base-2 logarithm of *blk_sz*. + :field Word32: number of active segments. + :field Word32: number of filled segments. + :field Word32: number of live blocks. - * ``Word32``: Capability - * ``Word64``: Current profiling tick - * ``Word8``: stack depth - * ``Word32[]``: cost centre stack starting with inner-most (cost centre numbers) + Describes the occupancy of the *blk_sz* sub-heap. ===================================== docs/users_guide/runtime_control.rst ===================================== @@ -1161,6 +1161,10 @@ When the program is linked with the :ghc-flag:`-eventlog` option - ``g`` — GC events, including GC start/stop. Enabled by default. + - ``n`` — non-moving garbage collector (see :rts-flag:`--nonmoving-gc`) + events including start and end of the concurrent mark and census + information to characterise heap fragmentation. Disabled by default. + - ``p`` — parallel sparks (sampled). Enabled by default. - ``f`` — parallel sparks (fully accurate). Disabled by default. @@ -1186,9 +1190,8 @@ When the program is linked with the :ghc-flag:`-eventlog` option accurate mode every spark event is logged individually. The latter has a higher runtime overhead and is not enabled by default. - The format of the log file is described by the header - ``EventLogFormat.h`` that comes with GHC, and it can be parsed in - Haskell using the + The format of the log file is described in this users guide in + :ref:`eventlog-encodings` It can be parsed in Haskell using the `ghc-events `__ library. To dump the contents of a ``.eventlog`` file as text, use the tool ``ghc-events show`` that comes with the ===================================== includes/rts/EventLogFormat.h ===================================== @@ -9,65 +9,25 @@ * of the format, and new tools will be able to understand old log * files. * - * Each event has a specific format. If you add new events, give them - * new numbers: we never re-use old event numbers. - * - * - The format is endian-independent: all values are represented in - * bigendian order. - * - * - The format is extensible: - * - * - The header describes each event type and its length. Tools - * that don't recognise a particular event type can skip those events. - * - * - There is room for extra information in the event type - * specification, which can be ignored by older tools. - * - * - Events can have extra information added, but existing fields - * cannot be changed. Tools should ignore extra fields at the - * end of the event record. - * - * - Old event type ids are never re-used; just take a new identifier. - * - * - * The format - * ---------- - * - * log : EVENT_HEADER_BEGIN - * EventType* - * EVENT_HEADER_END - * EVENT_DATA_BEGIN - * Event* - * EVENT_DATA_END - * - * EventType : - * EVENT_ET_BEGIN - * Word16 -- unique identifier for this event - * Int16 -- >=0 size of the event in bytes (minus the header) - * -- -1 variable size - * Word32 -- length of the next field in bytes - * Word8* -- string describing the event - * Word32 -- length of the next field in bytes - * Word8* -- extra info (for future extensions) - * EVENT_ET_END - * - * Event : - * Word16 -- event_type - * Word64 -- time (nanosecs) - * [Word16] -- length of the rest (for variable-sized events only) - * ... extra event-specific info ... - * + * The canonical documentation for the event log format and record layouts is + * the "Eventlog encodings" section of the GHC User's Guide. * * To add a new event * ------------------ * * - In this file: - * - give it a new number, add a new #define EVENT_XXX below + * - give it a new number, add a new #define EVENT_XXX + * below. Do not reuse event ids from deprecated event types. + * * - In EventLog.c * - add it to the EventDesc array * - emit the event type in initEventLogging() * - emit the new event in postEvent_() * - generate the event itself by calling postEvent() somewhere + * + * - Describe the meaning and encoding of the event in the users guide + * (docs/user_guide/eventlog-formats.rst) + * * - In the Haskell code to parse the event log file: * - add types and code to read the new event * ===================================== rts/RtsFlags.c ===================================== @@ -382,6 +382,7 @@ usage_text[] = { " where [flags] can contain:", " s scheduler events", " g GC and heap events", +" n non-moving GC heap census events", " p par spark events (sampled)", " f par spark events (full detail)", " u user events (emitted from Haskell code)", ===================================== rts/sm/NonMoving.c ===================================== @@ -1125,6 +1125,10 @@ static void nonmovingMark_(MarkQueue *mark_queue, StgWeak **dead_weaks, StgTSO * if (RtsFlags.DebugFlags.nonmoving_gc) nonmovingPrintAllocatorCensus(); #endif +#if defined(TRACING) + if (RtsFlags.TraceFlags.nonmoving_gc) + nonmovingTraceAllocatorCensus(); +#endif // TODO: Remainder of things done by GarbageCollect (update stats) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fd7ea0fee92a60f9658254cc4fe3abdb4ff299b1...02543d5ef9bd7a910fc9fece895780583ab9635a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fd7ea0fee92a60f9658254cc4fe3abdb4ff299b1...02543d5ef9bd7a910fc9fece895780583ab9635a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 3 08:42:24 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 03 May 2020 04:42:24 -0400 Subject: [Git][ghc/ghc][master] Flatten nested casts in the simple optimizer Message-ID: <5eae83f0675b_6167bac3158850899c@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: b465dd45 by Alexis King at 2020-05-03T04:42:12-04:00 Flatten nested casts in the simple optimizer Normally, we aren’t supposed to generated any nested casts, since mkCast takes care to flatten them, but the simple optimizer didn’t use mkCast, so they could show up after inlining. This isn’t really a problem, since the simplifier will clean them up immediately anyway, but it can clutter the -ddump-ds output, and it’s an extremely easy fix. closes #18112 - - - - - 4 changed files: - compiler/GHC/Core/SimpleOpt.hs - + testsuite/tests/deSugar/should_compile/T18112.hs - testsuite/tests/deSugar/should_compile/all.T - testsuite/tests/dependent/should_compile/dynamic-paper.stderr Changes: ===================================== compiler/GHC/Core/SimpleOpt.hs ===================================== @@ -221,10 +221,13 @@ simple_opt_expr env expr go (Coercion co) = Coercion (optCoercion (soe_dflags env) (getTCvSubst subst) co) go (Lit lit) = Lit lit go (Tick tickish e) = mkTick (substTickish subst tickish) (go e) - go (Cast e co) | isReflCo co' = go e - | otherwise = Cast (go e) co' - where - co' = optCoercion (soe_dflags env) (getTCvSubst subst) co + go (Cast e co) = case go e of + -- flatten nested casts before calling the coercion optimizer; + -- see #18112 (note that mkCast handles dropping Refl coercions) + Cast e' co' -> mkCast e' (opt_co (mkTransCo co' co)) + e' -> mkCast e' (opt_co co) + where + opt_co = optCoercion (soe_dflags env) (getTCvSubst subst) go (Let bind body) = case simple_opt_bind env bind NotTopLevel of (env', Nothing) -> simple_opt_expr env' body ===================================== testsuite/tests/deSugar/should_compile/T18112.hs ===================================== @@ -0,0 +1,14 @@ +{-# LANGUAGE TypeFamilies #-} +module T18112 where + +type family F a where + F Int = String + +-- This test is really testing the simple optimizer. We expect the +-- optimized desugared output to contain no casts, since the simple +-- optimizer should fuse the two casts together after inlining y. + +blah :: Bool -> String +blah x = let y :: F Int + y = show x + in y ===================================== testsuite/tests/deSugar/should_compile/all.T ===================================== @@ -109,3 +109,4 @@ test('T14773b', normal, compile, ['-Wincomplete-patterns']) test('T14815', [], makefile_test, ['T14815']) test('T13208', [], makefile_test, ['T13208']) test('T16615', normal, compile, ['-ddump-ds -dsuppress-uniques']) +test('T18112', [grep_errmsg('cast')], compile, ['-ddump-ds']) ===================================== testsuite/tests/dependent/should_compile/dynamic-paper.stderr ===================================== @@ -12,4 +12,4 @@ Simplifier ticks exhausted simplifier non-termination has been judged acceptable. To see detailed counts use -ddump-simpl-stats - Total ticks: 140084 + Total ticks: 138082 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b465dd4500beffe919e8b8dcd075008399fbf446 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b465dd4500beffe919e8b8dcd075008399fbf446 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 3 11:54:56 2020 From: gitlab at gitlab.haskell.org (Matthew Pickering) Date: Sun, 03 May 2020 07:54:56 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/profile-info-table Message-ID: <5eaeb11023701_616787c09cc85313d1@gitlab.haskell.org.mail> Matthew Pickering pushed new branch wip/profile-info-table at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/profile-info-table You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 3 16:52:10 2020 From: gitlab at gitlab.haskell.org (Sven Tennie) Date: Sun, 03 May 2020 12:52:10 -0400 Subject: [Git][ghc/ghc][wip/ghc-debug] 71 commits: Derive Ord instance for Extension Message-ID: <5eaef6ba62068_6167bac315885550a8@gitlab.haskell.org.mail> Sven Tennie pushed to branch wip/ghc-debug at Glasgow Haskell Compiler / GHC Commits: 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - ffd7eef2 by Takenobu Tani at 2020-04-22T23:09:50-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - e8a5d81b by Jonathan DK Gibbons at 2020-04-22T23:10:28-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - dcb7fe5a by John Ericson at 2020-04-22T23:10:28-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - cde23cd4 by John Ericson at 2020-04-22T23:10:28-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - 72cb6bcc by John Ericson at 2020-04-22T23:10:28-04:00 Generalize type of `matchCanFail` - - - - - 401f7bb3 by John Ericson at 2020-04-22T23:10:28-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 6c9fae23 by Alexis King at 2020-04-22T23:11:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 48b8951e by Roland Senn at 2020-04-22T23:11:51-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 34a45ee6 by Peter Trommler at 2020-04-22T23:12:27-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - ffde2348 by Simon Peyton Jones at 2020-04-22T23:13:06-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 6f84aca3 by Ben Gamari at 2020-04-22T23:13:43-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - c29f0fa6 by Andreas Klebinger at 2020-04-22T23:14:21-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 4b4a8b60 by Ben Gamari at 2020-04-22T23:14:57-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 831b6642 by Moritz Angermann at 2020-04-22T23:15:33-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - c409961a by Ryan Scott at 2020-04-22T23:16:12-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 125aa2b8 by Ömer Sinan Ağacan at 2020-04-22T23:16:51-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - 8ea37b01 by Sylvain Henry at 2020-04-22T23:17:34-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - cd8409c2 by Ryan Scott at 2020-04-23T11:39:24-04:00 Create di_scoped_tvs for associated data family instances properly See `Note [Associated data family instances and di_scoped_tvs]` in `GHC.Tc.TyCl.Instance`, which explains all of the moving parts. Fixes #18055. - - - - - 339e8ece by Ben Gamari at 2020-04-23T11:40:02-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 5946c85a by Ben Gamari at 2020-04-23T11:40:38-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - c42754d5 by John Ericson at 2020-04-23T18:32:43-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 72da0c29 by mniip at 2020-04-23T18:33:21-04:00 Add :doc to GHC.Prim - - - - - 2c23e2e3 by mniip at 2020-04-23T18:33:21-04:00 Include docs for non-primop entries in primops.txt as well - - - - - 0ac29c88 by mniip at 2020-04-23T18:33:21-04:00 GHC.Prim docs: note and test - - - - - b0fbfc75 by John Ericson at 2020-04-24T12:07:14-04:00 Switch order on `GhcMake.IsBoot` In !1798 we were requested to replace many `Bool`s with this data type. But those bools had `False` meaning `NotBoot`, so the `Ord` instance would be flipped if we use this data-type as-is. Since the planned formally-`Bool` occurrences vastly outnumber the current occurrences, we figured it would be better to conform the `Ord` instance to how the `Bool` is used now, fixing any issues, rather than fix them currently with the bigger refactor later in !1798. That way, !1798 can be a "pure" refactor with no behavioral changes. - - - - - af332442 by Sylvain Henry at 2020-04-26T13:55:14-04:00 Modules: Utils and Data (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - cd4434c8 by Sylvain Henry at 2020-04-26T13:55:16-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 22bf5c73 by Ömer Sinan Ağacan at 2020-04-26T13:55:22-04:00 Tweak includes in non-moving GC headers We don't use hash tables in non-moving GC so remove the includes. This breaks Compact.c as existing includes no longer include Hash.h, so include Hash.h explicitly in Compact.c. - - - - - 99823ed2 by Sylvain Henry at 2020-04-27T20:24:46-04:00 TH: fix Show/Eq/Ord instances for Bytes (#16457) We shouldn't compare pointer values but the actual bytes. - - - - - c62271a2 by Alp Mestanogullari at 2020-04-27T20:25:33-04:00 hadrian: always capture both stdout and stderr when running a builder fails The idea being that when a builder('s command) fails, we quite likely want to have all the information available to figure out why. Depending on the builder _and_ the particular problem, the useful bits of information can be printed on stdout or stderr. We accomplish this by defining a simple wrapper for Shake's `cmd` function, that just _always_ captures both streams in case the command returns a non-zero exit code, and by using this wrapper everywhere in `hadrian/src/Builder.hs`. Fixes #18089. - - - - - 4b9764db by Ryan Scott at 2020-04-28T15:40:04-04:00 Define a Quote IO instance Fixes #18103. - - - - - 518a63d4 by Ryan Scott at 2020-04-28T15:40:42-04:00 Make boxed 1-tuples have known keys Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. - - - - - 2cfc4ab9 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Document backpack fields in DynFlags - - - - - 10a2ba90 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 69562e34 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 9e2c8e0e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - ea717aa4 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 10d15f1e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 8bfb0219 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - 71484b09 by Alexis King at 2020-04-30T01:57:35-04:00 Allow block arguments in arrow control operators Arrow control operators have their own entries in the grammar, so they did not cooperate with BlockArguments. This was just a minor oversight, so this patch adjusts the grammar to add the desired behavior. fixes #18050 - - - - - a48cd2a0 by Alexis King at 2020-04-30T01:57:35-04:00 Allow LambdaCase to be used as a command in proc notation - - - - - f4d3773c by Alexis King at 2020-04-30T01:57:35-04:00 Document BlockArguments/LambdaCase support in arrow notation - - - - - 5bdfdd13 by Simon Peyton Jones at 2020-04-30T01:58:15-04:00 Add tests for #17873 - - - - - 19b701c2 by Simon Peyton Jones at 2020-04-30T07:30:13-04:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - 014ef4a3 by Matthew Pickering at 2020-04-30T07:30:50-04:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 2aa67611 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - 54dad3cf by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - 99ff8145 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 05b0a9fd by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 Remove OneShotInfo field of LFReEntrant, document OneShotInfo The field is only used in withNewTickyCounterFun and it's easier to directly pass a parameter for one-shot info to withNewTickyCounterFun instead of passing it via LFReEntrant. This also makes !2842 simpler. Other changes: - New Note (by SPJ) [OneShotInfo overview] added. - Arity argument of thunkCode removed as it's always 0. - - - - - a43620c6 by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 GHC.StgToCmm.Ticky: remove a few unused stuff - - - - - 780de9e1 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Use platform in Iface Binary - - - - - f8386c7b by Sylvain Henry at 2020-05-01T10:37:39-04:00 Refactor PprDebug handling If `-dppr-debug` is set, then PprUser and PprDump styles are silently replaced with PprDebug style. This was done in `mkUserStyle` and `mkDumpStyle` smart constructors. As a consequence they needed a DynFlags parameter. Now we keep the original PprUser and PprDump styles until they are used to create an `SDocContext`. I.e. the substitution is only performed in `initSDocContext`. - - - - - b3df9e78 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Remove PprStyle param of logging actions Use `withPprStyle` instead to apply a specific style to a SDoc. - - - - - de9fc995 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Fully remove PprDebug PprDebug was a pain to deal with consistently as it is implied by `-dppr-debug` but it isn't really a PprStyle. We remove it completely and query the appropriate SDoc flag instead (`sdocPprDebug`) via helpers (`getPprDebug` and its friends). - - - - - 8b51fcbd by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Only call checkSingle if we would report warnings - - - - - fd7ea0fe by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 7bfe9ac5 by Ben Gamari at 2020-05-03T04:41:33-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. - - - - - c560dd07 by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Move eventlog documentation users guide - - - - - 02543d5e by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Add documentation for non-moving GC events - - - - - b465dd45 by Alexis King at 2020-05-03T04:42:12-04:00 Flatten nested casts in the simple optimizer Normally, we aren’t supposed to generated any nested casts, since mkCast takes care to flatten them, but the simple optimizer didn’t use mkCast, so they could show up after inlining. This isn’t really a problem, since the simplifier will clean them up immediately anyway, but it can clutter the -ddump-ds output, and it’s an extremely easy fix. closes #18112 - - - - - eace41bb by Matthew Pickering at 2020-05-03T17:54:04+02:00 rts: Implement ghc-debug API There are four components to this patch which make it possible to implement `ghc-debug`. 1. Add four new functions to the RtsAPI. * rts_pause and rts_unpause allow an external process to completely pause and unpause the RTS. * rts_listThreads and rts_listMiscRoots are used to find the current roots of the garbage collector. These changes also mean that `Task.h` is exposed to the user. 2. Generalise the `ghc-heap` API so that raw `Word`s can be returned rather than actual objects. This is necessary when trying to decode closures on an external process because the pointers in such closures are correct for the internal rather than external process. If you used the previous API then you would get a segfault as the garbage collector would try to traverse into these nonsensical branches. ``` -- before getClosureData :: a -> IO Closure -- after getClosureDataX :: (forall c . c -> IO (Ptr StgInfoTable, [Word], [b])) -> a -> IO (GenClosure b) ``` For the normal case `b` is instantiated to `Box`, which contains a pointer to a heap object. ``` data Box = Box a -- GenClosure Box ``` For `ghc-debug` we instead just take the word of the address as we have to explicitly interpret it on the external process. ``` GenClosure Word ``` 3. Support for decoding `TSO` and `STACK` closures is partially implemented. There is still quite a bit of work to do to finish both but these at least allow us to make some more progress. 4. findPtr is generalised to take a callback argument. This means that its result can be communicated to the debugger rather than just printing out the result. The debugger has a function which invokes `findPtr` and passes a callback which sends the result over a socket. Co-authored-by: Ben Gamari <ben at smart-cactus.org> - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/PrimOps.hs-boot - 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/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/ByteCode/Asm.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/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Block.hs - compiler/GHC/Cmm/Dataflow/Collections.hs - compiler/GHC/Cmm/Dataflow/Graph.hs - compiler/GHC/Cmm/Dataflow/Label.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Expr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d0dd6f0e7301f15d0f3e0fcc83b2cb143c29a6a2...eace41bb01b1ef6b49dd19d55cd866c1abc3e718 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d0dd6f0e7301f15d0f3e0fcc83b2cb143c29a6a2...eace41bb01b1ef6b49dd19d55cd866c1abc3e718 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 3 17:19:48 2020 From: gitlab at gitlab.haskell.org (Richard Eisenberg) Date: Sun, 03 May 2020 13:19:48 -0400 Subject: [Git][ghc/ghc][wip/hole-refactor] Refactor hole constraints. Message-ID: <5eaefd3432347_61673f81cd4c695c8559596@gitlab.haskell.org.mail> Richard Eisenberg pushed to branch wip/hole-refactor at Glasgow Haskell Compiler / GHC Commits: 8147d941 by Richard Eisenberg at 2020-05-03T18:19:28+01:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. - - - - - 23 changed files: - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/Plugins.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Errors/Hole.hs-boot - compiler/GHC/Tc/Errors/Hole/FitTypes.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Rule.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/Solver/Canonical.hs - compiler/GHC/Tc/Solver/Flatten.hs - compiler/GHC/Tc/Solver/Interact.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Types/Constraint.hs - compiler/GHC/Tc/Types/Origin.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Tc/Utils/TcMType.hs - testsuite/tests/partial-sigs/should_compile/SplicesUsed.stderr - testsuite/tests/plugins/hole-fit-plugin/HoleFitPlugin.hs - testsuite/tests/th/T12411.stderr - testsuite/tests/typecheck/should_fail/T12589.stderr Changes: ===================================== compiler/GHC/HsToCore/PmCheck/Oracle.hs ===================================== @@ -438,7 +438,7 @@ then newtypes. (b) dcs is the list of newtype constructors "skipped", every time we normalise a newtype to its core representation, we keep track of the source data - constructor. For convenienve, we also track the type we unwrap and the + constructor. For convenience, we also track the type we unwrap and the type of its field. Example: @Down 42@ => @[(Down @Int, Down, Int)] (c) core_ty is the rewritten type. That is, pmTopNormaliseType env ty_cs ty = Just (src_ty, dcs, core_ty) ===================================== compiler/GHC/Plugins.hs ===================================== @@ -48,6 +48,7 @@ module GHC.Plugins , module GHC.Utils.Outputable , module GHC.Types.Unique.Supply , module GHC.Data.FastString + , module GHC.Tc.Errors.Hole.FitTypes -- for hole-fit plugins , -- * Getting 'Name's thNameToGhcName ) @@ -121,6 +122,8 @@ import GHC.Utils.Monad ( mapMaybeM ) import GHC.ThToHs ( thRdrNameGuesses ) import GHC.Tc.Utils.Env ( lookupGlobal ) +import GHC.Tc.Errors.Hole.FitTypes + import qualified Language.Haskell.TH as TH {- This instance is defined outside GHC.Core.Opt.Monad.hs so that ===================================== compiler/GHC/Tc/Errors.hs ===================================== @@ -285,8 +285,8 @@ important :: SDoc -> Report important doc = mempty { report_important = [doc] } -- | Put a doc into the relevant bindings block. -relevant_bindings :: SDoc -> Report -relevant_bindings doc = mempty { report_relevant_bindings = [doc] } +mk_relevant_bindings :: SDoc -> Report +mk_relevant_bindings doc = mempty { report_relevant_bindings = [doc] } -- | Put a doc into the valid hole fits block. valid_hole_fits :: SDoc -> Report @@ -524,16 +524,29 @@ This only matters in instance declarations.. -} reportWanteds :: ReportErrCtxt -> TcLevel -> WantedConstraints -> TcM () -reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) +reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics + , wc_holes = holes }) = do { traceTc "reportWanteds" (vcat [ text "Simples =" <+> ppr simples - , text "Suppress =" <+> ppr (cec_suppress ctxt)]) - ; traceTc "rw2" (ppr tidy_cts) - - -- First deal with things that are utterly wrong + , text "Suppress =" <+> ppr (cec_suppress ctxt) + , text "tidy_cts =" <+> ppr tidy_cts + , text "tidy_holes = " <+> ppr tidy_holes ]) + + -- First, deal with any out-of-scope errors: + ; let (out_of_scope, other_holes) = partition isOutOfScopeHole tidy_holes + -- don't suppress out-of-scope errors + ctxt_for_scope_errs = ctxt { cec_suppress = False } + ; (_, no_out_of_scope) <- askNoErrs $ + reportHoles tidy_cts ctxt_for_scope_errs out_of_scope + + -- Next, deal with things that are utterly wrong -- Like Int ~ Bool (incl nullary TyCons) -- or Int ~ t a (AppTy on one side) -- These /ones/ are not suppressed by the incoming context - ; let ctxt_for_insols = ctxt { cec_suppress = False } + -- (but will be by out-of-scope errors) + ; let ctxt_for_insols = ctxt { cec_suppress = not no_out_of_scope } + ; reportHoles tidy_cts ctxt_for_insols other_holes + -- holes never suppress + ; (ctxt1, cts1) <- tryReporters ctxt_for_insols report1 tidy_cts -- Now all the other constraints. We suppress errors here if @@ -554,7 +567,8 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) -- if there's a *given* insoluble here (= inaccessible code) where env = cec_tidy ctxt - tidy_cts = bagToList (mapBag (tidyCt env) simples) + tidy_cts = bagToList (mapBag (tidyCt env) simples) + tidy_holes = bagToList (mapBag (tidyHole env) holes) -- report1: ones that should *not* be suppressed by -- an insoluble somewhere else in the tree @@ -562,9 +576,7 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) -- (see GHC.Tc.Utils.insolubleCt) is caught here, otherwise -- we might suppress its error message, and proceed on past -- type checking to get a Lint error later - report1 = [ ("Out of scope", unblocked is_out_of_scope, True, mkHoleReporter tidy_cts) - , ("Holes", unblocked is_hole, False, mkHoleReporter tidy_cts) - , ("custom_error", unblocked is_user_type_error, True, mkUserTypeErrorReporter) + report1 = [ ("custom_error", unblocked is_user_type_error, True, mkUserTypeErrorReporter) , given_eq_spec , ("insoluble2", unblocked utterly_wrong, True, mkGroupReporter mkEqErr) @@ -593,8 +605,7 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) unblocked checker ct pred = checker ct pred -- rigid_nom_eq, rigid_nom_tv_eq, - is_hole, is_dict, - is_equality, is_ip, is_irred :: Ct -> Pred -> Bool + is_dict, is_equality, is_ip, is_irred :: Ct -> Pred -> Bool is_given_eq ct pred | EqPred {} <- pred = arisesFromGivens ct @@ -617,9 +628,6 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) non_tv_eq _ (EqPred NomEq ty1 _) = not (isTyVarTy ty1) non_tv_eq _ _ = False - is_out_of_scope ct _ = isOutOfScopeCt ct - is_hole ct _ = isHoleCt ct - is_user_type_error ct _ = isUserTypeErrorCt ct is_homo_equality _ (EqPred _ ty1 ty2) = tcTypeKind ty1 `tcEqType` tcTypeKind ty2 @@ -705,12 +713,12 @@ mkSkolReporter ctxt cts | eq_lhs_type ct1 ct2 = True | otherwise = False -mkHoleReporter :: [Ct] -> Reporter --- Reports errors one at a time -mkHoleReporter tidy_simples ctxt - = mapM_ $ \ct -> do { err <- mkHoleError tidy_simples ctxt ct - ; maybeReportHoleError ctxt ct err - ; maybeAddDeferredHoleBinding ctxt err ct } +reportHoles :: [Ct] -- other (tidied) constraints + -> ReportErrCtxt -> [Hole] -> TcM () +reportHoles tidy_cts ctxt + = mapM_ $ \hole -> do { err <- mkHoleError tidy_cts ctxt hole + ; maybeReportHoleError ctxt hole err + ; maybeAddDeferredHoleBinding ctxt err hole } mkUserTypeErrorReporter :: Reporter mkUserTypeErrorReporter ctxt @@ -742,7 +750,7 @@ mkGivenErrorReporter ctxt cts inaccessible_msg = hang (text "Inaccessible code in") 2 (ppr (ic_info implic)) report = important inaccessible_msg `mappend` - relevant_bindings binds_msg + mk_relevant_bindings binds_msg ; err <- mkEqErr_help dflags ctxt report ct' Nothing ty1 ty2 @@ -843,15 +851,27 @@ suppressGroup mk_err ctxt cts ; traceTc "Suppressing errors for" (ppr cts) ; mapM_ (addDeferredBinding ctxt err) cts } -maybeReportHoleError :: ReportErrCtxt -> Ct -> ErrMsg -> TcM () +maybeReportHoleError :: ReportErrCtxt -> Hole -> ErrMsg -> TcM () +maybeReportHoleError ctxt hole err + | isOutOfScopeHole hole + -- Always report an error for out-of-scope variables + -- Unless -fdefer-out-of-scope-variables is on, + -- in which case the messages are discarded. + -- See #12170, #12406 + = -- If deferring, report a warning only if -Wout-of-scope-variables is on + case cec_out_of_scope_holes ctxt of + HoleError -> reportError err + HoleWarn -> + reportWarning (Reason Opt_WarnDeferredOutOfScopeVariables) err + HoleDefer -> return () + -- Unlike maybeReportError, these "hole" errors are -- /not/ suppressed by cec_suppress. We want to see them! -maybeReportHoleError ctxt ct err +maybeReportHoleError ctxt (Hole { hole_sort = TypeHole }) err -- When -XPartialTypeSignatures is on, warnings (instead of errors) are -- generated for holes in partial type signatures. -- Unless -fwarn-partial-type-signatures is not on, -- in which case the messages are discarded. - | isTypeHoleCt ct = -- For partial type signatures, generate warnings only, and do that -- only if -fwarn-partial-type-signatures is on case cec_type_holes ctxt of @@ -859,22 +879,12 @@ maybeReportHoleError ctxt ct err HoleWarn -> reportWarning (Reason Opt_WarnPartialTypeSignatures) err HoleDefer -> return () - -- Always report an error for out-of-scope variables - -- Unless -fdefer-out-of-scope-variables is on, - -- in which case the messages are discarded. - -- See #12170, #12406 - | isOutOfScopeCt ct - = -- If deferring, report a warning only if -Wout-of-scope-variables is on - case cec_out_of_scope_holes ctxt of - HoleError -> reportError err - HoleWarn -> - reportWarning (Reason Opt_WarnDeferredOutOfScopeVariables) err - HoleDefer -> return () - +maybeReportHoleError ctxt hole@(Hole { hole_sort = ExprHole _ }) err -- Otherwise this is a typed hole in an expression, - -- but not for an out-of-scope variable - | otherwise + -- but not for an out-of-scope variable (because that goes through a + -- different function) = -- If deferring, report a warning only if -Wtyped-holes is on + ASSERT( not (isOutOfScopeHole hole) ) case cec_expr_holes ctxt of HoleError -> reportError err HoleWarn -> reportWarning (Reason Opt_WarnTypedHoles) err @@ -899,10 +909,7 @@ addDeferredBinding ctxt err ct , CtWanted { ctev_pred = pred, ctev_dest = dest } <- ctEvidence ct -- Only add deferred bindings for Wanted constraints = do { dflags <- getDynFlags - ; let err_msg = pprLocErrMsg err - err_fs = mkFastString $ showSDoc dflags $ - err_msg $$ text "(deferred type error)" - err_tm = evDelayedError pred err_fs + ; let err_tm = mkErrorTerm dflags pred err ev_binds_var = cec_binds ctxt ; case dest of @@ -917,11 +924,27 @@ addDeferredBinding ctxt err ct | otherwise -- Do not set any evidence for Given/Derived = return () -maybeAddDeferredHoleBinding :: ReportErrCtxt -> ErrMsg -> Ct -> TcM () -maybeAddDeferredHoleBinding ctxt err ct - | isExprHoleCt ct - = addDeferredBinding ctxt err ct -- Only add bindings for holes in expressions - | otherwise -- not for holes in partial type signatures +mkErrorTerm :: DynFlags -> Type -- of the error term + -> ErrMsg -> EvTerm +mkErrorTerm dflags ty err = evDelayedError ty err_fs + where + err_msg = pprLocErrMsg err + err_fs = mkFastString $ showSDoc dflags $ + err_msg $$ text "(deferred type error)" +maybeAddDeferredHoleBinding :: ReportErrCtxt -> ErrMsg -> Hole -> TcM () +maybeAddDeferredHoleBinding ctxt err (Hole { hole_sort = ExprHole ev_id }) +-- Only add bindings for holes in expressions +-- not for holes in partial type signatures +-- cf. addDeferredBinding + | deferringAnyBindings ctxt + = do { dflags <- getDynFlags + ; let err_tm = mkErrorTerm dflags (idType ev_id) err + -- NB: idType ev_id, not hole_ty. hole_ty might be rewritten. + -- See Note [Holes] in GHC.Tc.Types.Constraint + ; addTcEvBind (cec_binds ctxt) $ mkWantedEvBind ev_id err_tm } + | otherwise + = return () +maybeAddDeferredHoleBinding _ _ (Hole { hole_sort = TypeHole }) = return () tryReporters :: ReportErrCtxt -> [ReporterSpec] -> [Ct] -> TcM (ReportErrCtxt, [Ct]) @@ -961,7 +984,6 @@ tryReporter ctxt (str, keep_me, suppress_after, reporter) cts where (yeses, nos) = partition (\ct -> keep_me ct (classifyPredType (ctPred ct))) cts - pprArising :: CtOrigin -> SDoc -- Used for the main, top-level error message -- We've done special processing for TypeEq, KindEq, Given @@ -1104,15 +1126,16 @@ mkIrredErr ctxt cts ; let orig = ctOrigin ct1 msg = couldNotDeduce (getUserGivens ctxt) (map ctPred cts, orig) ; mkErrorMsgFromCt ctxt ct1 $ - important msg `mappend` relevant_bindings binds_msg } + important msg `mappend` mk_relevant_bindings binds_msg } where (ct1:_) = cts ---------------- -mkHoleError :: [Ct] -> ReportErrCtxt -> Ct -> TcM ErrMsg -mkHoleError tidy_simples ctxt ct@(CHoleCan { cc_occ = occ, cc_hole = hole_sort }) - | isOutOfScopeCt ct -- Out of scope variables, like 'a', where 'a' isn't bound - -- Suggest possible in-scope variables in the message +mkHoleError :: [Ct] -> ReportErrCtxt -> Hole -> TcM ErrMsg +mkHoleError _tidy_simples _ctxt hole@(Hole { hole_occ = occ + , hole_ty = hole_ty + , hole_loc = ct_loc }) + | isOutOfScopeHole hole = do { dflags <- getDynFlags ; rdr_env <- getGlobalRdrEnv ; imp_info <- getImports @@ -1122,48 +1145,52 @@ mkHoleError tidy_simples ctxt ct@(CHoleCan { cc_occ = occ, cc_hole = hole_sort } errDoc [out_of_scope_msg] [] [unknownNameSuggestions dflags hpt curr_mod rdr_env (tcl_rdr lcl_env) imp_info (mkRdrUnqual occ)] } + where + herald | isDataOcc occ = text "Data constructor not in scope:" + | otherwise = text "Variable not in scope:" - | otherwise -- Explicit holes, like "_" or "_f" - = do { (ctxt, binds_msg, ct) <- relevantBindings False ctxt ct + out_of_scope_msg -- Print v :: ty only if the type has structure + | boring_type = hang herald 2 (ppr occ) + | otherwise = hang herald 2 (pp_occ_with_type occ hole_ty) + + lcl_env = ctLocEnv ct_loc + boring_type = isTyVarTy hole_ty + + -- general case: not an out-of-scope error +mkHoleError tidy_simples ctxt hole@(Hole { hole_occ = occ + , hole_ty = hole_ty + , hole_sort = sort + , hole_loc = ct_loc }) + = do { (ctxt, binds_msg) + <- relevant_bindings False ctxt lcl_env (tyCoVarsOfType hole_ty) -- The 'False' means "don't filter the bindings"; see Trac #8191 ; show_hole_constraints <- goptM Opt_ShowHoleConstraints ; let constraints_msg - | isExprHoleCt ct, show_hole_constraints + | ExprHole _ <- sort, show_hole_constraints = givenConstraintsMsg ctxt | otherwise = empty ; show_valid_hole_fits <- goptM Opt_ShowValidHoleFits ; (ctxt, sub_msg) <- if show_valid_hole_fits - then validHoleFits ctxt tidy_simples ct + then validHoleFits ctxt tidy_simples hole else return (ctxt, empty) - ; mkErrorMsgFromCt ctxt ct $ + ; mkErrorReport ctxt lcl_env $ important hole_msg `mappend` - relevant_bindings (binds_msg $$ constraints_msg) `mappend` + mk_relevant_bindings (binds_msg $$ constraints_msg) `mappend` valid_hole_fits sub_msg } where - ct_loc = ctLoc ct lcl_env = ctLocEnv ct_loc - hole_ty = ctEvPred (ctEvidence ct) hole_kind = tcTypeKind hole_ty tyvars = tyCoVarsOfTypeList hole_ty - boring_type = isTyVarTy hole_ty - - out_of_scope_msg -- Print v :: ty only if the type has structure - | boring_type = hang herald 2 (ppr occ) - | otherwise = hang herald 2 pp_with_type - pp_with_type = hang (pprPrefixOcc occ) 2 (dcolon <+> pprType hole_ty) - herald | isDataOcc occ = text "Data constructor not in scope:" - | otherwise = text "Variable not in scope:" - - hole_msg = case hole_sort of - ExprHole -> vcat [ hang (text "Found hole:") - 2 pp_with_type - , tyvars_msg, expr_hole_hint ] + hole_msg = case sort of + ExprHole _ -> vcat [ hang (text "Found hole:") + 2 (pp_occ_with_type occ hole_ty) + , tyvars_msg, expr_hole_hint ] TypeHole -> vcat [ hang (text "Found type wildcard" <+> quotes (ppr occ)) 2 (text "standing for" <+> quotes pp_hole_type_with_kind) , tyvars_msg, type_hole_hint ] @@ -1207,21 +1234,22 @@ mkHoleError tidy_simples ctxt ct@(CHoleCan { cc_occ = occ, cc_hole = hole_sort } = ppWhenOption sdocPrintExplicitCoercions $ quotes (ppr tv) <+> text "is a coercion variable" -mkHoleError _ _ ct = pprPanic "mkHoleError" (ppr ct) +pp_occ_with_type :: OccName -> Type -> SDoc +pp_occ_with_type occ hole_ty = hang (pprPrefixOcc occ) 2 (dcolon <+> pprType hole_ty) -- We unwrap the ReportErrCtxt here, to avoid introducing a loop in module -- imports validHoleFits :: ReportErrCtxt -- The context we're in, i.e. the -- implications and the tidy environment -> [Ct] -- Unsolved simple constraints - -> Ct -- The hole constraint. + -> Hole -- The hole -> TcM (ReportErrCtxt, SDoc) -- We return the new context -- with a possibly updated -- tidy environment, and -- the message. validHoleFits ctxt@(CEC {cec_encl = implics - , cec_tidy = lcl_env}) simps ct - = do { (tidy_env, msg) <- findValidHoleFits lcl_env implics simps ct + , cec_tidy = lcl_env}) simps hole + = do { (tidy_env, msg) <- findValidHoleFits lcl_env implics simps hole ; return (ctxt {cec_tidy = tidy_env}, msg) } -- See Note [Constraints include ...] @@ -1255,7 +1283,7 @@ mkIPErr ctxt cts = couldNotDeduce givens (preds, orig) ; mkErrorMsgFromCt ctxt ct1 $ - important msg `mappend` relevant_bindings binds_msg } + important msg `mappend` mk_relevant_bindings binds_msg } where (ct1:_) = cts @@ -1337,7 +1365,7 @@ mkEqErr1 ctxt ct -- Wanted or derived; ; dflags <- getDynFlags ; traceTc "mkEqErr1" (ppr ct $$ pprCtOrigin (ctOrigin ct) $$ ppr keep_going) ; let report = mconcat [important wanted_msg, important coercible_msg, - relevant_bindings binds_msg] + mk_relevant_bindings binds_msg] ; if keep_going then mkEqErr_help dflags ctxt report ct is_oriented ty1 ty2 else mkErrorMsgFromCt ctxt ct report } @@ -1513,7 +1541,7 @@ mkTyVarEqErr' dflags ctxt report ct oriented tv1 ty2 filter isTyVar $ fvVarList $ tyCoFVsOfType ty1 `unionFV` tyCoFVsOfType ty2 - extra3 = relevant_bindings $ + extra3 = mk_relevant_bindings $ ppWhen (not (null interesting_tyvars)) $ hang (text "Type variable kinds:") 2 $ vcat (map (tyvar_binding . tidyTyCoVarOcc (cec_tidy ctxt)) @@ -2819,27 +2847,45 @@ relevantBindings :: Bool -- True <=> filter by tyvar; False <=> no filtering -> TcM (ReportErrCtxt, SDoc, Ct) -- Also returns the zonked and tidied CtOrigin of the constraint relevantBindings want_filtering ctxt ct - = do { dflags <- getDynFlags + = do { traceTc "relevantBindings" (ppr ct) ; (env1, tidy_orig) <- zonkTidyOrigin (cec_tidy ctxt) (ctLocOrigin loc) - ; let ct_tvs = tyCoVarsOfCt ct `unionVarSet` extra_tvs -- For *kind* errors, report the relevant bindings of the -- enclosing *type* equality, because that's more useful for the programmer - extra_tvs = case tidy_orig of + ; let extra_tvs = case tidy_orig of KindEqOrigin t1 m_t2 _ _ -> tyCoVarsOfTypes $ t1 : maybeToList m_t2 _ -> emptyVarSet - ; traceTc "relevantBindings" $ - vcat [ ppr ct - , pprCtOrigin (ctLocOrigin loc) - , ppr ct_tvs + ct_fvs = tyCoVarsOfCt ct `unionVarSet` extra_tvs + + -- Put a zonked, tidied CtOrigin into the Ct + loc' = setCtLocOrigin loc tidy_orig + ct' = setCtLoc ct loc' + ctxt1 = ctxt { cec_tidy = env1 } + + ; (ctxt2, doc) <- relevant_bindings want_filtering ctxt1 lcl_env ct_fvs + ; return (ctxt2, doc, ct') } + where + loc = ctLoc ct + lcl_env = ctLocEnv loc + +-- slightly more general version, to work also with holes +relevant_bindings :: Bool + -> ReportErrCtxt + -> TcLclEnv + -> TyCoVarSet + -> TcM (ReportErrCtxt, SDoc) +relevant_bindings want_filtering ctxt lcl_env ct_tvs + = do { dflags <- getDynFlags + ; traceTc "relevant_bindings" $ + vcat [ ppr ct_tvs , pprWithCommas id [ ppr id <+> dcolon <+> ppr (idType id) | TcIdBndr id _ <- tcl_bndrs lcl_env ] , pprWithCommas id [ ppr id | TcIdBndr_ExpType id _ _ <- tcl_bndrs lcl_env ] ] ; (tidy_env', docs, discards) - <- go dflags env1 ct_tvs (maxRelevantBinds dflags) + <- go dflags (cec_tidy ctxt) (maxRelevantBinds dflags) emptyVarSet [] False (removeBindingShadowing $ tcl_bndrs lcl_env) -- tcl_bndrs has the innermost bindings first, @@ -2849,17 +2895,10 @@ relevantBindings want_filtering ctxt ct hang (text "Relevant bindings include") 2 (vcat docs $$ ppWhen discards discardMsg) - -- Put a zonked, tidied CtOrigin into the Ct - loc' = setCtLocOrigin loc tidy_orig - ct' = setCtLoc ct loc' ctxt' = ctxt { cec_tidy = tidy_env' } - ; return (ctxt', doc, ct') } + ; return (ctxt', doc) } where - ev = ctEvidence ct - loc = ctEvLoc ev - lcl_env = ctLocEnv loc - run_out :: Maybe Int -> Bool run_out Nothing = False run_out (Just n) = n <= 0 @@ -2868,14 +2907,14 @@ relevantBindings want_filtering ctxt ct dec_max = fmap (\n -> n - 1) - go :: DynFlags -> TidyEnv -> TcTyVarSet -> Maybe Int -> TcTyVarSet -> [SDoc] + go :: DynFlags -> TidyEnv -> Maybe Int -> TcTyVarSet -> [SDoc] -> Bool -- True <=> some filtered out due to lack of fuel -> [TcBinder] -> TcM (TidyEnv, [SDoc], Bool) -- The bool says if we filtered any out -- because of lack of fuel - go _ tidy_env _ _ _ docs discards [] + go _ tidy_env _ _ docs discards [] = return (tidy_env, reverse docs, discards) - go dflags tidy_env ct_tvs n_left tvs_seen docs discards (tc_bndr : tc_bndrs) + go dflags tidy_env n_left tvs_seen docs discards (tc_bndr : tc_bndrs) = case tc_bndr of TcTvBndr {} -> discard_it TcIdBndr id top_lvl -> go2 (idName id) (idType id) top_lvl @@ -2891,7 +2930,7 @@ relevantBindings want_filtering ctxt ct Nothing -> discard_it -- No info; discard } where - discard_it = go dflags tidy_env ct_tvs n_left tvs_seen docs + discard_it = go dflags tidy_env n_left tvs_seen docs discards tc_bndrs go2 id_name id_type top_lvl = do { (tidy_env', tidy_ty) <- zonkTidyTcType tidy_env id_type @@ -2916,12 +2955,12 @@ relevantBindings want_filtering ctxt ct else if run_out n_left && id_tvs `subVarSet` tvs_seen -- We've run out of n_left fuel and this binding only -- mentions already-seen type variables, so discard it - then go dflags tidy_env ct_tvs n_left tvs_seen docs + then go dflags tidy_env n_left tvs_seen docs True -- Record that we have now discarded something tc_bndrs -- Keep this binding, decrement fuel - else go dflags tidy_env' ct_tvs (dec_max n_left) new_seen + else go dflags tidy_env' (dec_max n_left) new_seen (doc:docs) discards tc_bndrs } ===================================== compiler/GHC/Tc/Errors/Hole.hs ===================================== @@ -2,17 +2,9 @@ {-# LANGUAGE ExistentialQuantification #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} module GHC.Tc.Errors.Hole - ( findValidHoleFits, tcFilterHoleFits - , tcCheckHoleFit, tcSubsumes - , withoutUnification - , fromPureHFPlugin - -- Re-exports for convenience - , hfIsLcl - , pprHoleFit, debugHoleFitDispConfig + ( findValidHoleFits -- Re-exported from GHC.Tc.Errors.Hole.FitTypes - , TypedHole (..), HoleFit (..), HoleFitCandidate (..) - , CandPlugin, FitPlugin , HoleFitPlugin (..), HoleFitPluginR (..) ) where @@ -121,7 +113,7 @@ The hole in `f` would generate the message: Valid hole fits are found by checking top level identifiers and local bindings in scope for whether their type can be instantiated to the the type of the hole. Additionally, we also need to check whether all relevant constraints are solved -by choosing an identifier of that type as well, see Note [Relevant Constraints] +by choosing an identifier of that type as well, see Note [Relevant constraints] Since checking for subsumption results in the side-effect of type variables being unified by the simplifier, we need to take care to restore them after @@ -143,9 +135,13 @@ that the quantified type variables would take if that fit is used, like If -XTypeApplications is enabled, this can even be copied verbatim as a replacement for the hole. - -Note [Nested implications] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Checking hole fits] +~~~~~~~~~~~~~~~~~~~~~~~~~ +If we have a hole of type hole_ty, we want to know whether a variable +of type ty is a valid fit for the whole. This is a subsumption check: +we wish to know whether ty <: hole_ty. But, of course, the check +must take into account any givens and relevant constraints. +(See also Note [Relevant constraints]). For the simplifier to be able to use any givens present in the enclosing implications to solve relevant constraints, we nest the wanted subsumption @@ -156,10 +152,7 @@ As an example, let's look at the following code: f :: Show a => a -> String f x = show _ -The hole will result in the hole constraint: - - [WD] __a1ph {0}:: a0_a1pd[tau:2] (CHoleCan: ExprHole(_)) - +Suppose the hole is assigned type a0_a1pd[tau:2]. Here the nested implications are just one level deep, namely: [Implic { @@ -170,36 +163,25 @@ Here the nested implications are just one level deep, namely: Given = $dShow_a1pc :: Show a_a1pa[sk:2] Wanted = WC {wc_simple = - [WD] __a1ph {0}:: a_a1pd[tau:2] (CHoleCan: ExprHole(_)) - [WD] $dShow_a1pe {0}:: Show a_a1pd[tau:2] (CDictCan(psc))} + [WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CDictCan(psc))} Binds = EvBindsVar Needed inner = [] Needed outer = [] the type signature for: f :: forall a. Show a => a -> String }] -As we can see, the givens say that the information about the skolem -`a_a1pa[sk:2]` fulfills the Show constraint. - -The simples are: +As we can see, the givens say that the skolem +`a_a1pa[sk:2]` fulfills the Show constraint, and that we must prove +the [W] Show a0_a1pd[tau:2] constraint -- that is, whatever fills the +hole must have a Show instance. - [[WD] __a1ph {0}:: a0_a1pd[tau:2] (CHoleCan: ExprHole(_)), - [WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CNonCanonical)] - -I.e. the hole `a0_a1pd[tau:2]` and the constraint that the type of the hole must -fulfill `Show a0_a1pd[tau:2])`. - -So when we run the check, we need to make sure that the - - [WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CNonCanonical) - -Constraint gets solved. When we now check for whether `x :: a0_a1pd[tau:2]` fits -the hole in `tcCheckHoleFit`, the call to `tcSubType` will end up writing the -meta type variable `a0_a1pd[tau:2] := a_a1pa[sk:2]`. By wrapping the wanted -constraints needed by tcSubType_NC and the relevant constraints (see -Note [Relevant Constraints] for more details) in the nested implications, we -can pass the information in the givens along to the simplifier. For our example, -we end up needing to check whether the following constraints are soluble. +When we now check whether `x :: a_a1pa[sk:2]` fits the hole in +`tcCheckHoleFit`, the call to `tcSubType` will end up unifying the meta type +variable `a0_a1pd[tau:2] := a_a1pa[sk:2]`. By wrapping the wanted constraints +needed by tcSubType_NC and the relevant constraints (see Note [Relevant +Constraints] for more details) in the nested implications, we can pass the +information in the givens along to the simplifier. For our example, we end up +needing to check whether the following constraints are soluble. WC {wc_impl = Implic { @@ -223,10 +205,12 @@ with a final WC of WC {}, confirming x :: a0_a1pd[tau:2] as a match. To avoid side-effects on the nested implications, we create a new EvBindsVar so that any changes to the ev binds during a check remains localised to that check. - +In addition, we call withoutUnification to reset any unified metavariables; this +call is actually done outside tcCheckHoleFit so that the results can be formatted +for the user before resetting variables. Note [Valid refinement hole fits include ...] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When the `-frefinement-level-hole-fits=N` flag is given, we additionally look for "valid refinement hole fits"", i.e. valid hole fits with up to N additional holes in them. @@ -337,10 +321,8 @@ In the free monad example above, this is demonstrated with be applied to an expression of type `a -> Free f b` in order to match. If -XScopedTypeVariables is enabled, this hole fit can even be copied verbatim. - -Note [Relevant Constraints] -~~~~~~~~~~~~~~~~~~~ - +Note [Relevant constraints] +~~~~~~~~~~~~~~~~~~~~~~~~~~~ As highlighted by #14273, we need to check any relevant constraints as well as checking for subsumption. Relevant constraints are the simple constraints whose free unification variables are mentioned in the type of the hole. @@ -351,10 +333,9 @@ as is the case in f :: String f = show _ -Where the simples will be : +Here, the hole is given type a0_a1kv[tau:1]. Then, the emitted constraint is: - [[WD] __a1kz {0}:: a0_a1kv[tau:1] (CHoleCan: ExprHole(_)), - [WD] $dShow_a1kw {0}:: Show a0_a1kv[tau:1] (CNonCanonical)] + [WD] $dShow_a1kw {0}:: Show a0_a1kv[tau:1] (CNonCanonical) However, when there are multiple holes, we need to be more careful. As an example, Let's take a look at the following code: @@ -362,29 +343,24 @@ example, Let's take a look at the following code: f :: Show a => a -> String f x = show (_b (show _a)) -Here there are two holes, `_a` and `_b`, and the simple constraints passed to +Here there are two holes, `_a` and `_b`. Suppose _a :: a0_a1pd[tau:2] and +_b :: a1_a1po[tau:2]. Then, the simple constraints passed to findValidHoleFits are: - [[WD] _a_a1pi {0}:: String - -> a0_a1pd[tau:2] (CHoleCan: ExprHole(_b)), - [WD] _b_a1ps {0}:: a1_a1po[tau:2] (CHoleCan: ExprHole(_a)), - [WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CNonCanonical), + [[WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CNonCanonical), [WD] $dShow_a1pp {0}:: Show a1_a1po[tau:2] (CNonCanonical)] - -Here we have the two hole constraints for `_a` and `_b`, but also additional -constraints that these holes must fulfill. When we are looking for a match for -the hole `_a`, we filter the simple constraints to the "Relevant constraints", -by throwing out all hole constraints and any constraints which do not mention -a variable mentioned in the type of the hole. For hole `_a`, we will then -only require that the `$dShow_a1pp` constraint is solved, since that is -the only non-hole constraint that mentions any free type variables mentioned in -the hole constraint for `_a`, namely `a_a1pd[tau:2]` , and similarly for the -hole `_b` we only require that the `$dShow_a1pe` constraint is solved. +When we are looking for a match for the hole `_a`, we filter the simple +constraints to the "Relevant constraints", by throwing out any constraints +which do not mention a variable mentioned in the type of the hole. For hole +`_a`, we will then only require that the `$dShow_a1pe` constraint is solved, +since that is the only constraint that mentions any free type variables +mentioned in the hole constraint for `_a`, namely `a_a1pd[tau:2]`, and +similarly for the hole `_b` we only require that the `$dShow_a1pe` constraint +is solved. Note [Leaking errors] -~~~~~~~~~~~~~~~~~~~ - +~~~~~~~~~~~~~~~~~~~~~ When considering candidates, GHC believes that we're checking for validity in actual source. However, As evidenced by #15321, #15007 and #15202, this can cause bewildering error messages. The solution here is simple: if a candidate @@ -393,17 +369,12 @@ is discarded. -} - data HoleFitDispConfig = HFDC { showWrap :: Bool , showWrapVars :: Bool , showType :: Bool , showProv :: Bool , showMatches :: Bool } -debugHoleFitDispConfig :: HoleFitDispConfig -debugHoleFitDispConfig = HFDC True True True False False - - -- We read the various -no-show-*-of-hole-fits flags -- and set the display config accordingly. getHoleFitDispConfig :: TcM HoleFitDispConfig @@ -516,13 +487,12 @@ pprHoleFit (HFDC sWrp sWrpVars sTy sProv sMs) (HoleFit {..}) = GreHFCand gre -> pprNameProvenance gre _ -> text "bound at" <+> ppr (getSrcLoc name) -getLocalBindings :: TidyEnv -> Ct -> TcM [Id] -getLocalBindings tidy_orig ct - = do { (env1, _) <- zonkTidyOrigin tidy_orig (ctLocOrigin loc) +getLocalBindings :: TidyEnv -> CtLoc -> TcM [Id] +getLocalBindings tidy_orig ct_loc + = do { (env1, _) <- zonkTidyOrigin tidy_orig (ctLocOrigin ct_loc) ; go env1 [] (removeBindingShadowing $ tcl_bndrs lcl_env) } where - loc = ctEvLoc (ctEvidence ct) - lcl_env = ctLocEnv loc + lcl_env = ctLocEnv ct_loc go :: TidyEnv -> [Id] -> [TcBinder] -> TcM [Id] go _ sofar [] = return (reverse sofar) @@ -542,11 +512,13 @@ findValidHoleFits :: TidyEnv -- ^ The tidy_env for zonking -> [Ct] -- ^ The unsolved simple constraints in the implication for -- the hole. - -> Ct -- ^ The hole constraint itself + -> Hole -> TcM (TidyEnv, SDoc) -findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = +findValidHoleFits tidy_env implics simples h@(Hole { hole_sort = ExprHole _ + , hole_loc = ct_loc + , hole_ty = hole_ty }) = do { rdr_env <- getGlobalRdrEnv - ; lclBinds <- getLocalBindings tidy_env ct + ; lclBinds <- getLocalBindings tidy_env ct_loc ; maxVSubs <- maxValidHoleFits <$> getDynFlags ; hfdc <- getHoleFitDispConfig ; sortingAlg <- getSortingAlg @@ -554,7 +526,9 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = ; hfPlugs <- tcg_hf_plugins <$> getGblEnv ; let findVLimit = if sortingAlg > NoSorting then Nothing else maxVSubs refLevel = refLevelHoleFits dflags - hole = TyH (listToBag relevantCts) implics (Just ct) + hole = TypedHole { th_relevant_cts = listToBag relevantCts + , th_implics = implics + , th_hole = Just h } (candidatePlugins, fitPlugins) = unzip $ map (\p-> ((candPlugin p) hole, (fitPlugin p) hole)) hfPlugs ; traceTc "findingValidHoleFitsFor { " $ ppr hole @@ -625,11 +599,9 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = where -- We extract the type, the tcLevel and the types free variables -- from from the constraint. - hole_ty :: TcPredType - hole_ty = ctPred ct hole_fvs :: FV hole_fvs = tyCoFVsOfType hole_ty - hole_lvl = ctLocLevel $ ctEvLoc $ ctEvidence ct + hole_lvl = ctLocLevel ct_loc -- BuiltInSyntax names like (:) and [] builtIns :: [Name] @@ -668,7 +640,7 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = <*> sortByGraph (sort gblFits) where (lclFits, gblFits) = span hfIsLcl subs - -- See Note [Relevant Constraints] + -- See Note [Relevant constraints] relevantCts :: [Ct] relevantCts = if isEmptyVarSet (fvVarSet hole_fvs) then [] else filter isRelevant simples @@ -684,7 +656,6 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = -- trying to find hole fits for many holes at once. isRelevant ct = not (isEmptyVarSet (ctFreeVarSet ct)) && anyFVMentioned ct - && not (isHoleCt ct) -- We zonk the hole fits so that the output aligns with the rest -- of the typed hole error message output. @@ -761,7 +732,7 @@ tcFilterHoleFits :: Maybe Int -- ^ We return whether or not we stopped due to hitting the limit -- and the fits we found. tcFilterHoleFits (Just 0) _ _ _ = return (False, []) -- Stop right away on 0 -tcFilterHoleFits limit (TyH {..}) ht@(hole_ty, _) candidates = +tcFilterHoleFits limit typed_hole ht@(hole_ty, _) candidates = do { traceTc "checkingFitsFor {" $ ppr hole_ty ; (discards, subs) <- go [] emptyVarSet limit ht candidates ; traceTc "checkingFitsFor }" empty @@ -895,8 +866,7 @@ tcFilterHoleFits limit (TyH {..}) ht@(hole_ty, _) candidates = else return Nothing } else return Nothing } where fvs = mkFVs ref_vars `unionFV` hole_fvs `unionFV` tyCoFVsOfType ty - hole = TyH tyHRelevantCts tyHImplics Nothing - + hole = typed_hole { th_hole = Nothing } subsDiscardMsg :: SDoc subsDiscardMsg = @@ -925,7 +895,8 @@ withoutUnification free_vars action = -- Reset any mutated free variables ; mapM_ restore flexis ; return result } - where restore = flip writeTcRef Flexi . metaTyVarRef + where restore tv = do { traceTc "withoutUnification: restore flexi" (ppr tv) + ; writeTcRef (metaTyVarRef tv) Flexi } fuvs = fvVarList free_vars -- | Reports whether first type (ty_a) subsumes the second type (ty_b), @@ -933,14 +904,14 @@ withoutUnification free_vars action = -- ty_a, i.e. `tcSubsumes a b == True` if b is a subtype of a. tcSubsumes :: TcSigmaType -> TcSigmaType -> TcM Bool tcSubsumes ty_a ty_b = fst <$> tcCheckHoleFit dummyHole ty_a ty_b - where dummyHole = TyH emptyBag [] Nothing + where dummyHole = TypedHole { th_relevant_cts = emptyBag + , th_implics = [] + , th_hole = Nothing } -- | A tcSubsumes which takes into account relevant constraints, to fix trac -- #14273. This makes sure that when checking whether a type fits the hole, -- the type has to be subsumed by type of the hole as well as fulfill all -- constraints on the type of the hole. --- Note: The simplifier may perform unification, so make sure to restore any --- free type variables to avoid side-effects. tcCheckHoleFit :: TypedHole -- ^ The hole to check against -> TcSigmaType -- ^ The type to check against (possibly modified, e.g. refined) @@ -949,56 +920,48 @@ tcCheckHoleFit :: TypedHole -- ^ The hole to check against -- ^ Whether it was a match, and the wrapper from hole_ty to ty. tcCheckHoleFit _ hole_ty ty | hole_ty `eqType` ty = return (True, idHsWrapper) -tcCheckHoleFit (TyH {..}) hole_ty ty = discardErrs $ +tcCheckHoleFit (TypedHole {..}) hole_ty ty = discardErrs $ do { -- We wrap the subtype constraint in the implications to pass along the -- givens, and so we must ensure that any nested implications and skolems -- end up with the correct level. The implications are ordered so that -- the innermost (the one with the highest level) is first, so it -- suffices to get the level of the first one (or the current level, if -- there are no implications involved). - innermost_lvl <- case tyHImplics of + innermost_lvl <- case th_implics of [] -> getTcLevel -- imp is the innermost implication (imp:_) -> return (ic_tclvl imp) - ; (wrp, wanted) <- setTcLevel innermost_lvl $ captureConstraints $ - tcSubType_NC ExprSigCtxt ty hole_ty + ; (wrap, wanted) <- setTcLevel innermost_lvl $ captureConstraints $ + tcSubType_NC ExprSigCtxt ty hole_ty ; traceTc "Checking hole fit {" empty ; traceTc "wanteds are: " $ ppr wanted - ; if isEmptyWC wanted && isEmptyBag tyHRelevantCts - then traceTc "}" empty >> return (True, wrp) + ; if isEmptyWC wanted && isEmptyBag th_relevant_cts + then do { traceTc "}" empty + ; return (True, wrap) } else do { fresh_binds <- newTcEvBinds -- The relevant constraints may contain HoleDests, so we must -- take care to clone them as well (to avoid #15370). - ; cloned_relevants <- mapBagM cloneWanted tyHRelevantCts + ; cloned_relevants <- mapBagM cloneWanted th_relevant_cts -- We wrap the WC in the nested implications, see - -- Note [Nested Implications] - ; let outermost_first = reverse tyHImplics - setWC = setWCAndBinds fresh_binds + -- Note [Checking hole fits] + ; let outermost_first = reverse th_implics -- We add the cloned relevants to the wanteds generated by - -- the call to tcSubType_NC, see Note [Relevant Constraints] + -- the call to tcSubType_NC, see Note [Relevant constraints] -- There's no need to clone the wanteds, because they are -- freshly generated by `tcSubtype_NC`. w_rel_cts = addSimples wanted cloned_relevants - w_givens = foldr setWC w_rel_cts outermost_first - ; traceTc "w_givens are: " $ ppr w_givens - ; rem <- runTcSDeriveds $ simpl_top w_givens + final_wc = foldr (setWCAndBinds fresh_binds) w_rel_cts outermost_first + ; traceTc "final_wc is: " $ ppr final_wc + ; rem <- runTcSDeriveds $ simpl_top final_wc -- We don't want any insoluble or simple constraints left, but -- solved implications are ok (and necessary for e.g. undefined) ; traceTc "rems was:" $ ppr rem ; traceTc "}" empty - ; return (isSolvedWC rem, wrp) } } + ; return (isSolvedWC rem, wrap) } } where setWCAndBinds :: EvBindsVar -- Fresh ev binds var. -> Implication -- The implication to put WC in. -> WantedConstraints -- The WC constraints to put implic. -> WantedConstraints -- The new constraints. setWCAndBinds binds imp wc - = WC { wc_simple = emptyBag - , wc_impl = unitBag $ imp { ic_wanted = wc , ic_binds = binds } } - --- | Maps a plugin that needs no state to one with an empty one. -fromPureHFPlugin :: HoleFitPlugin -> HoleFitPluginR -fromPureHFPlugin plug = - HoleFitPluginR { hfPluginInit = newTcRef () - , hfPluginRun = const plug - , hfPluginStop = const $ return () } + = mkImplicWC $ unitBag $ imp { ic_wanted = wc , ic_binds = binds } ===================================== compiler/GHC/Tc/Errors/Hole.hs-boot ===================================== @@ -5,9 +5,9 @@ module GHC.Tc.Errors.Hole where import GHC.Tc.Types ( TcM ) -import GHC.Tc.Types.Constraint ( Ct, Implication ) +import GHC.Tc.Types.Constraint ( Ct, Hole, Implication ) import GHC.Utils.Outputable ( SDoc ) import GHC.Types.Var.Env ( TidyEnv ) -findValidHoleFits :: TidyEnv -> [Implication] -> [Ct] -> Ct +findValidHoleFits :: TidyEnv -> [Implication] -> [Ct] -> Hole -> TcM (TidyEnv, SDoc) ===================================== compiler/GHC/Tc/Errors/Hole/FitTypes.hs ===================================== @@ -21,20 +21,21 @@ import GHC.Types.Name import Data.Function ( on ) -data TypedHole = TyH { tyHRelevantCts :: Cts - -- ^ Any relevant Cts to the hole - , tyHImplics :: [Implication] - -- ^ The nested implications of the hole with the - -- innermost implication first. - , tyHCt :: Maybe Ct - -- ^ The hole constraint itself, if available. - } +data TypedHole = TypedHole { th_relevant_cts :: Cts + -- ^ Any relevant Cts to the hole + , th_implics :: [Implication] + -- ^ The nested implications of the hole with the + -- innermost implication first. + , th_hole :: Maybe Hole + -- ^ The hole itself, if available. Only for debugging. + } instance Outputable TypedHole where - ppr (TyH rels implics ct) + ppr (TypedHole { th_relevant_cts = rels + , th_implics = implics + , th_hole = hole }) = hang (text "TypedHole") 2 - (ppr rels $+$ ppr implics $+$ ppr ct) - + (ppr rels $+$ ppr implics $+$ ppr hole) -- | HoleFitCandidates are passed to hole fit plugins and then -- checked whether they fit a given typed-hole. @@ -51,9 +52,6 @@ pprHoleFitCand (IdHFCand cid) = text "Id HFC: " <> ppr cid pprHoleFitCand (NameHFCand cname) = text "Name HFC: " <> ppr cname pprHoleFitCand (GreHFCand cgre) = text "Gre HFC: " <> ppr cgre - - - instance NamedThing HoleFitCandidate where getName hfc = case hfc of IdHFCand cid -> idName cid ===================================== compiler/GHC/Tc/Gen/Expr.hs ===================================== @@ -36,7 +36,6 @@ import {-# SOURCE #-} GHC.Tc.Gen.Splice( tcSpliceExpr, tcTypedBracket, tcUntyp import GHC.Builtin.Names.TH( liftStringName, liftName ) import GHC.Hs -import GHC.Tc.Types.Constraint ( HoleSort(..) ) import GHC.Tc.Utils.Zonk import GHC.Tc.Utils.Monad import GHC.Tc.Utils.Unify @@ -1408,22 +1407,21 @@ Suppose 'wurble' is not in scope, and we have Then the renamer will make (HsUnboundVar "wurble) for 'wurble', and the typechecker will typecheck it with tcUnboundId, giving it -a type 'alpha', and emitting a deferred CHoleCan constraint, to -be reported later. +a type 'alpha', and emitting a deferred Hole, to be reported later. But then comes the visible type application. If we do nothing, we'll generate an immediate failure (in tc_app_err), saying that a function of type 'alpha' can't be applied to Bool. That's insane! And indeed users complain bitterly (#13834, #17150.) -The right error is the CHoleCan, which has /already/ been emitted by +The right error is the Hole, which has /already/ been emitted by tcUnboundId. It later reports 'wurble' as out of scope, and tries to give its type. Fortunately in tcArgs we still have access to the function, so we can check if it is a HsUnboundVar. We use this info to simply skip over any visible type arguments. We've already inferred the type of the -function, so we'll /already/ have emitted a CHoleCan constraint; +function, so we'll /already/ have emitted a Hole; failing preserves that constraint. We do /not/ want to fail altogether in this case (via failM) becuase @@ -1900,14 +1898,13 @@ tcUnboundId :: HsExpr GhcRn -> OccName -> ExpRhoType -> TcM (HsExpr GhcTc) -- Others might simply be variables that accidentally have no binding site -- -- We turn all of them into HsVar, since HsUnboundVar can't contain an --- Id; and indeed the evidence for the CHoleCan does bind it, so it's +-- Id; and indeed the evidence for the ExprHole does bind it, so it's -- not unbound any more! tcUnboundId rn_expr occ res_ty = do { ty <- newOpenFlexiTyVarTy -- Allow Int# etc (#12531) ; name <- newSysName occ ; let ev = mkLocalId name ty - ; can <- newHoleCt ExprHole ev ty - ; emitInsoluble can + ; emitNewExprHole occ ev ty ; tcWrapResultO (UnboundOccurrenceOf occ) rn_expr (HsVar noExtField (noLoc ev)) ty res_ty } ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -419,7 +419,7 @@ tcHsTypeApp wc_ty kind ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A HsWildCardBndrs's hswc_ext now only includes /named/ wildcards, so any unnamed wildcards stay unchanged in hswc_body. When called in -tcHsTypeApp, tcCheckLHsType will call emitAnonWildCardHoleConstraint +tcHsTypeApp, tcCheckLHsType will call emitAnonTypeHole on these anonymous wildcards. However, this would trigger error/warning when an anonymous wildcard is passed in as a visible type argument, which we do not want because users should be able to write @@ -891,7 +891,7 @@ tcAnonWildCardOcc wc exp_kind ; warning <- woptM Opt_WarnPartialTypeSignatures ; unless (part_tysig && not warning) $ - emitAnonWildCardHoleConstraint wc_tv + emitAnonTypeHole wc_tv -- Why the 'unless' guard? -- See Note [Wildcards in visible kind application] @@ -911,11 +911,11 @@ x = MkT So we should allow '@_' without emitting any hole constraints, and regardless of whether PartialTypeSignatures is enabled or not. But how would the typechecker know which '_' is being used in VKA and which is not when it -calls emitNamedWildCardHoleConstraints in tcHsPartialSigType on all HsWildCardBndrs? +calls emitNamedTypeHole in tcHsPartialSigType on all HsWildCardBndrs? The solution then is to neither rename nor include unnamed wildcards in HsWildCardBndrs, but instead give every anonymous wildcard a fresh wild tyvar in tcAnonWildCardOcc. And whenever we see a '@', we automatically turn on PartialTypeSignatures and -turn off hole constraint warnings, and do not call emitAnonWildCardHoleConstraint +turn off hole constraint warnings, and do not call emitAnonTypeHole under these conditions. See related Note [Wildcards in visible type application] here and Note [The wildcard story for types] in GHC.Hs.Types @@ -3192,7 +3192,7 @@ tcHsPartialSigType ctxt sig_ty -- Spit out the wildcards (including the extra-constraints one) -- as "hole" constraints, so that they'll be reported if necessary -- See Note [Extra-constraint holes in partial type signatures] - ; emitNamedWildCardHoleConstraints wcs + ; mapM_ emitNamedTypeHole wcs -- Zonk, so that any nested foralls can "see" their occurrences -- See Note [Checking partial type signatures], in @@ -3365,7 +3365,7 @@ tcHsPatSigType ctxt sig_ty do { sig_ty <- tcHsOpenType hs_ty ; return (wcs, sig_ty) } - ; emitNamedWildCardHoleConstraints wcs + ; mapM_ emitNamedTypeHole wcs -- sig_ty might have tyvars that are at a higher TcLevel (if hs_ty -- contains a forall). Promote these. ===================================== compiler/GHC/Tc/Gen/Rule.hs ===================================== @@ -460,9 +460,9 @@ getRuleQuantCts wc = float_wc emptyVarSet wc where float_wc :: TcTyCoVarSet -> WantedConstraints -> (Cts, WantedConstraints) - float_wc skol_tvs (WC { wc_simple = simples, wc_impl = implics }) + float_wc skol_tvs (WC { wc_simple = simples, wc_impl = implics, wc_holes = holes }) = ( simple_yes `andCts` implic_yes - , WC { wc_simple = simple_no, wc_impl = implics_no }) + , emptyWC { wc_simple = simple_no, wc_impl = implics_no, wc_holes = holes }) where (simple_yes, simple_no) = partitionBag (rule_quant_ct skol_tvs) simples (implic_yes, implics_no) = mapAccumBagL (float_implic skol_tvs) @@ -480,8 +480,6 @@ getRuleQuantCts wc | EqPred _ t1 t2 <- classifyPredType (ctPred ct) , not (ok_eq t1 t2) = False -- Note [RULE quantification over equalities] - | isHoleCt ct - = False -- Don't quantify over type holes, obviously | otherwise = tyCoVarsOfCt ct `disjointVarSet` skol_tvs ===================================== compiler/GHC/Tc/Module.hs ===================================== @@ -2589,7 +2589,7 @@ tcRnType hsc_env flexi normalise rdr_type -- kindGeneralize, below solveEqualities $ tcNamedWildCardBinders wcs $ \ wcs' -> - do { emitNamedWildCardHoleConstraints wcs' + do { mapM_ emitNamedTypeHole wcs' ; tcLHsTypeUnsaturated rn_type } -- Do kind generalisation; see Note [Kind-generalise in tcRnType] ===================================== compiler/GHC/Tc/Solver.hs ===================================== @@ -31,7 +31,7 @@ import GHC.Prelude import GHC.Data.Bag import GHC.Core.Class ( Class, classKey, classTyCon ) import GHC.Driver.Session -import GHC.Types.Id ( idType, mkLocalId ) +import GHC.Types.Id ( idType ) import GHC.Tc.Utils.Instantiate import GHC.Data.List.SetOps import GHC.Types.Name @@ -42,6 +42,7 @@ import GHC.Tc.Errors import GHC.Tc.Types.Evidence import GHC.Tc.Solver.Interact import GHC.Tc.Solver.Canonical ( makeSuperClasses, solveCallStack ) +import GHC.Tc.Solver.Flatten ( flattenType ) import GHC.Tc.Utils.TcMType as TcM import GHC.Tc.Utils.Monad as TcM import GHC.Tc.Solver.Monad as TcS @@ -145,8 +146,7 @@ simplifyTop wanteds ; saved_msg <- TcM.readTcRef errs_var ; TcM.writeTcRef errs_var emptyMessages - ; warnAllUnsolved $ WC { wc_simple = unsafe_ol - , wc_impl = emptyBag } + ; warnAllUnsolved $ emptyWC { wc_simple = unsafe_ol } ; whyUnsafe <- fst <$> TcM.readTcRef errs_var ; TcM.writeTcRef errs_var saved_msg @@ -638,27 +638,15 @@ tcNormalise :: Bag EvVar -> Type -> TcM Type tcNormalise given_ids ty = do { lcl_env <- TcM.getLclEnv ; let given_loc = mkGivenLoc topTcLevel UnkSkol lcl_env - ; wanted_ct <- mk_wanted_ct + ; norm_loc <- getCtLocM PatCheckOrigin Nothing ; (res, _ev_binds) <- runTcS $ do { traceTcS "tcNormalise {" (ppr given_ids) ; let given_cts = mkGivens given_loc (bagToList given_ids) ; solveSimpleGivens given_cts - ; wcs <- solveSimpleWanteds (unitBag wanted_ct) - -- It's an invariant that this wc_simple will always be - -- a singleton Ct, since that's what we fed in as input. - ; let ty' = case bagToList (wc_simple wcs) of - (ct:_) -> ctEvPred (ctEvidence ct) - cts -> pprPanic "tcNormalise" (ppr cts) + ; ty' <- flattenType norm_loc ty ; traceTcS "tcNormalise }" (ppr ty') ; pure ty' } ; return res } - where - mk_wanted_ct :: TcM Ct - mk_wanted_ct = do - let occ = mkVarOcc "$tcNorm" - name <- newSysName occ - let ev = mkLocalId name ty - newHoleCt ExprHole ev ty {- Note [Superclasses and satisfiability] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -696,11 +684,8 @@ if some local equalities are solved for. See "Wrinkle: Local equalities" in Note [Type normalisation] in Check. To accomplish its stated goal, tcNormalise first feeds the local constraints -into solveSimpleGivens, then stuffs the argument type in a CHoleCan, and feeds -that singleton Ct into solveSimpleWanteds, which reduces the type in the -CHoleCan as much as possible with respect to the local given constraints. When -solveSimpleWanteds is finished, we dig out the type from the CHoleCan and -return that. +into solveSimpleGivens, then uses flattenType to simplify the desired type +with respect to the givens. *********************************************************************************** * * @@ -889,8 +874,8 @@ mkResidualConstraints rhs_tclvl ev_binds_var , ic_no_eqs = False , ic_info = skol_info } - ; return (WC { wc_simple = outer_simple - , wc_impl = implics })} + ; return (emptyWC { wc_simple = outer_simple + , wc_impl = implics })} where full_theta = map idType full_theta_vars skol_info = InferSkol [ (name, mkSigmaTy [] full_theta ty) @@ -1516,7 +1501,7 @@ solveWantedsAndDrop wanted solveWanteds :: WantedConstraints -> TcS WantedConstraints -- so that the inert set doesn't mindlessly propagate. -- NB: wc_simples may be wanted /or/ derived now -solveWanteds wc@(WC { wc_simple = simples, wc_impl = implics }) +solveWanteds wc@(WC { wc_simple = simples, wc_impl = implics, wc_holes = holes }) = do { cur_lvl <- TcS.getTcLevel ; traceTcS "solveWanteds {" $ vcat [ text "Level =" <+> ppr cur_lvl @@ -1530,9 +1515,12 @@ solveWanteds wc@(WC { wc_simple = simples, wc_impl = implics }) implics `unionBags` wc_impl wc1 ; dflags <- getDynFlags - ; final_wc <- simpl_loop 0 (solverIterations dflags) floated_eqs + ; solved_wc <- simpl_loop 0 (solverIterations dflags) floated_eqs (wc1 { wc_impl = implics2 }) + ; holes' <- simplifyHoles holes + ; let final_wc = solved_wc { wc_holes = holes' } + ; ev_binds_var <- getTcEvBindsVar ; bb <- TcS.getTcEvBindsMap ev_binds_var ; traceTcS "solveWanteds }" $ @@ -1779,12 +1767,13 @@ setImplicationStatus implic@(Implic { ic_status = status then Nothing else Just final_implic } where - WC { wc_simple = simples, wc_impl = implics } = wc + WC { wc_simple = simples, wc_impl = implics, wc_holes = holes } = wc pruned_simples = dropDerivedSimples simples pruned_implics = filterBag keep_me implics pruned_wc = WC { wc_simple = pruned_simples - , wc_impl = pruned_implics } + , wc_impl = pruned_implics + , wc_holes = holes } -- do not prune holes; these should be reported keep_me :: Implication -> Bool keep_me ic @@ -1898,6 +1887,14 @@ neededEvVars implic@(Implic { ic_given = givens | is_given = needs -- Add the rhs vars of the Wanted bindings only | otherwise = evVarsOfTerm rhs `unionVarSet` needs +------------------------------------------------- +simplifyHoles :: Bag Hole -> TcS (Bag Hole) +simplifyHoles = mapBagM simpl_hole + where + simpl_hole :: Hole -> TcS Hole + simpl_hole h@(Hole { hole_ty = ty, hole_loc = loc }) + = do { ty' <- flattenType loc ty + ; return (h { hole_ty = ty' }) } {- Note [Delete dead Given evidence bindings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2143,7 +2140,6 @@ approximateWC float_past_equalities wc is_floatable skol_tvs ct | isGivenCt ct = False - | isHoleCt ct = False | insolubleEqCt ct = False | otherwise = tyCoVarsOfCt ct `disjointVarSet` skol_tvs ===================================== compiler/GHC/Tc/Solver/Canonical.hs ===================================== @@ -34,7 +34,6 @@ import GHC.Tc.Instance.Family ( tcTopNormaliseNewTypeTF_maybe ) import GHC.Types.Var import GHC.Types.Var.Env( mkInScopeSet ) import GHC.Types.Var.Set( delVarSetList ) -import GHC.Types.Name.Occurrence ( OccName ) import GHC.Utils.Outputable import GHC.Driver.Session( DynFlags ) import GHC.Types.Name.Set @@ -67,8 +66,7 @@ Canonicalization converts a simple constraint to a canonical form. It is unary (i.e. treats individual constraints one at a time). Constraints originating from user-written code come into being as -CNonCanonicals (except for CHoleCans, arising from holes). We know nothing -about these constraints. So, first: +CNonCanonicals. We know nothing about these constraints. So, first: Classify CNonCanoncal constraints, depending on whether they are equalities, class predicates, or other. @@ -137,9 +135,6 @@ canonicalize (CFunEqCan { cc_ev = ev = {-# SCC "canEqLeafFunEq" #-} canCFunEqCan ev fn xis1 fsk -canonicalize (CHoleCan { cc_ev = ev, cc_occ = occ, cc_hole = hole }) - = canHole ev occ hole - {- ************************************************************************ * * @@ -718,17 +713,6 @@ canIrred status ev _ -> continueWith $ mkIrredCt status new_ev } } -canHole :: CtEvidence -> OccName -> HoleSort -> TcS (StopOrContinue Ct) -canHole ev occ hole_sort - = do { let pred = ctEvPred ev - ; (xi,co) <- flatten FM_SubstOnly ev pred -- co :: xi ~ pred - ; rewriteEvidence ev xi co `andWhenContinue` \ new_ev -> - do { updInertIrreds (`snocCts` (CHoleCan { cc_ev = new_ev - , cc_occ = occ - , cc_hole = hole_sort })) - ; stopWith new_ev "Emit insoluble hole" } } - - {- ********************************************************************* * * * Quantified predicates @@ -1401,6 +1385,7 @@ can_eq_app ev s1 t1 s2 t2 | CtDerived {} <- ev = do { unifyDeriveds loc [Nominal, Nominal] [s1, t1] [s2, t2] ; stopWith ev "Decomposed [D] AppTy" } + | CtWanted { ctev_dest = dest } <- ev = do { co_s <- unifyWanted loc Nominal s1 s2 ; let arg_loc ===================================== compiler/GHC/Tc/Solver/Flatten.hs ===================================== @@ -5,7 +5,7 @@ module GHC.Tc.Solver.Flatten( FlattenMode(..), flatten, flattenKind, flattenArgsNom, - rewriteTyVar, + rewriteTyVar, flattenType, unflattenWanteds ) where @@ -825,6 +825,20 @@ flattenArgsNom ev tc tys ; traceTcS "flatten }" (vcat (map ppr tys')) ; return (tys', cos, kind_co) } +-- | Flatten a type w.r.t. nominal equality. This is useful to rewrite +-- a type w.r.t. any givens. It does not do type-family reduction. This +-- will never emit new constraints. Call this when the inert set contains +-- only givens. +flattenType :: CtLoc -> TcType -> TcS TcType +flattenType loc ty + -- More info about FM_SubstOnly in Note [Holes] in GHC.Tc.Types.Constraint + = do { (xi, _) <- runFlatten FM_SubstOnly loc Given NomEq $ + flatten_one ty + -- use Given flavor so that it is rewritten + -- only w.r.t. Givens, never Wanteds/Deriveds + -- (Shouldn't matter, if only Givens are present + -- anyway) + ; return xi } {- ********************************************************************* * * ===================================== compiler/GHC/Tc/Solver/Interact.hs ===================================== @@ -195,7 +195,7 @@ solve_simple_wanteds :: WantedConstraints -> TcS (Int, WantedConstraints) -- Try solving these constraints -- Affects the unification state (of course) but not the inert set -- The result is not necessarily zonked -solve_simple_wanteds (WC { wc_simple = simples1, wc_impl = implics1 }) +solve_simple_wanteds (WC { wc_simple = simples1, wc_impl = implics1, wc_holes = holes }) = nestTcS $ do { solveSimples simples1 ; (implics2, tv_eqs, fun_eqs, others) <- getUnsolvedInerts @@ -204,7 +204,8 @@ solve_simple_wanteds (WC { wc_simple = simples1, wc_impl = implics1 }) -- See Note [Unflatten after solving the simple wanteds] ; return ( unif_count , WC { wc_simple = others `andCts` unflattened_eqs - , wc_impl = implics1 `unionBags` implics2 }) } + , wc_impl = implics1 `unionBags` implics2 + , wc_holes = holes }) } {- Note [The solveSimpleWanteds loop] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -264,7 +265,7 @@ runTcPluginsGiven -- 'solveSimpleWanteds' should feed the updated wanteds back into the -- main solver. runTcPluginsWanted :: WantedConstraints -> TcS (Bool, WantedConstraints) -runTcPluginsWanted wc@(WC { wc_simple = simples1, wc_impl = implics1 }) +runTcPluginsWanted wc@(WC { wc_simple = simples1 }) | isEmptyBag simples1 = return (False, wc) | otherwise @@ -285,11 +286,10 @@ runTcPluginsWanted wc@(WC { wc_simple = simples1, wc_impl = implics1 }) ; mapM_ setEv solved_wanted ; return ( notNull (pluginNewCts p) - , WC { wc_simple = listToBag new_wanted `andCts` + , wc { wc_simple = listToBag new_wanted `andCts` listToBag unsolved_wanted `andCts` listToBag unsolved_derived `andCts` - listToBag insols - , wc_impl = implics1 } ) } } + listToBag insols } ) } } where setEv :: (EvTerm,Ct) -> TcS () setEv (ev,ct) = case ctEvidence ct of @@ -494,7 +494,6 @@ interactWithInertsStage wi CIrredCan {} -> interactIrred ics wi CDictCan {} -> interactDict ics wi _ -> pprPanic "interactWithInerts" (ppr wi) } - -- CHoleCan are put straight into inert_frozen, so never get here -- CNonCanonical have been canonicalised data InteractResult ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -198,7 +198,7 @@ import GHC.Types.Unique.Set Note [WorkList priorities] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -A WorkList contains canonical and non-canonical items (of all flavors). +A WorkList contains canonical and non-canonical items (of all flavours). Notice that each Ct now has a simplification depth. We may consider using this depth for prioritization as well in the future. @@ -1653,8 +1653,7 @@ add_item ics item@(CDictCan { cc_ev = ev, cc_class = cls, cc_tyargs = tys }) add_item _ item = pprPanic "upd_inert set: can't happen! Inserting " $ - ppr item -- Can't be CNonCanonical, CHoleCan, - -- because they only land in inert_irreds + ppr item -- Can't be CNonCanonical because they only land in inert_irreds bumpUnsolvedCount :: CtEvidence -> Int -> Int bumpUnsolvedCount ev n | isWanted ev = n+1 @@ -1896,10 +1895,6 @@ be decomposed. Otherwise we end up with a "Can't match [Int] ~ [[Int]]" which is true, but a bit confusing because the outer type constructors match. -Similarly, if we have a CHoleCan, we'd like to rewrite it with any -Givens, to give as informative an error messasge as possible -(#12468, #11325). - Hence: * In the main simplifier loops in GHC.Tc.Solver (solveWanteds, simpl_loop), we feed the insolubles in solveSimpleWanteds, @@ -2352,8 +2347,6 @@ removeInertCt is ct = CQuantCan {} -> panic "removeInertCt: CQuantCan" CIrredCan {} -> panic "removeInertCt: CIrredEvCan" CNonCanonical {} -> panic "removeInertCt: CNonCanonical" - CHoleCan {} -> panic "removeInertCt: CHoleCan" - lookupFlatCache :: TyCon -> [Type] -> TcS (Maybe (TcCoercion, TcType, CtFlavour)) lookupFlatCache fam_tc tys ===================================== compiler/GHC/Tc/Types/Constraint.hs ===================================== @@ -14,8 +14,7 @@ module GHC.Tc.Types.Constraint ( isEmptyCts, isCTyEqCan, isCFunEqCan, isPendingScDict, superClassesMightHelp, getPendingWantedScs, isCDictCan_Maybe, isCFunEqCan_maybe, - isCNonCanonical, isWantedCt, isDerivedCt, - isGivenCt, isHoleCt, isOutOfScopeCt, isExprHoleCt, isTypeHoleCt, + isCNonCanonical, isWantedCt, isDerivedCt, isGivenCt, isUserTypeErrorCt, getUserTypeErrorMsg, ctEvidence, ctLoc, setCtLoc, ctPred, ctFlavour, ctEqRel, ctOrigin, ctEvId, mkTcEqPredLikeEv, @@ -26,9 +25,11 @@ module GHC.Tc.Types.Constraint ( tyCoVarsOfCt, tyCoVarsOfCts, tyCoVarsOfCtList, tyCoVarsOfCtsList, + Hole(..), HoleSort(..), isOutOfScopeHole, + WantedConstraints(..), insolubleWC, emptyWC, isEmptyWC, isSolvedWC, andWC, unionsWC, mkSimpleWC, mkImplicWC, - addInsols, insolublesOnly, addSimples, addImplics, + addInsols, insolublesOnly, addSimples, addImplics, addHole, tyCoVarsOfWC, dropDerivedWC, dropDerivedSimples, tyCoVarsOfWCList, insolubleCt, insolubleEqCt, isDroppableCt, insolubleImplic, @@ -62,9 +63,6 @@ module GHC.Tc.Types.Constraint ( pprEvVarTheta, pprEvVars, pprEvVarWithType, - -- holes - HoleSort(..), - ) where @@ -202,14 +200,6 @@ data Ct cc_ev :: CtEvidence } - | CHoleCan { -- See Note [Hole constraints] - -- Treated as an "insoluble" constraint - -- See Note [Insoluble constraints] - cc_ev :: CtEvidence, - cc_occ :: OccName, -- The name of this hole - cc_hole :: HoleSort -- The sort of this hole (expr, type, ...) - } - | CQuantCan QCInst -- A quantified constraint -- NB: I expect to make more of the cases in Ct -- look like this, with the payload in an @@ -230,13 +220,47 @@ instance Outputable QCInst where ppr (QCI { qci_ev = ev }) = ppr ev ------------ +-- | A hole stores the information needed to report diagnostics +-- about holes in terms (unbound identifiers or underscores) or +-- in types (also called wildcards, as used in partial type +-- signatures). See Note [Holes]. +data Hole + = Hole { hole_sort :: HoleSort -- ^ What flavour of hole is this? + , hole_occ :: OccName -- ^ The name of this hole + , hole_ty :: TcType -- ^ Type to be printed to the user + -- For expression holes: type of expr + -- For type holes: the missing type + , hole_loc :: CtLoc -- ^ Where hole was written + } + -- For the hole_loc, we usually only want the TcLclEnv stored within. + -- Except when we flatten, where we need a whole location. And this + -- might get reported to the user if reducing type families in a + -- hole type loops. + + -- | Used to indicate which sort of hole we have. -data HoleSort = ExprHole +data HoleSort = ExprHole Id -- ^ Either an out-of-scope variable or a "true" hole in an - -- expression (TypedHoles) + -- expression (TypedHoles). + -- The 'Id' is where to store "evidence": this evidence + -- will be an erroring expression for -fdefer-type-errors. | TypeHole -- ^ A hole in a type (PartialTypeSignatures) +instance Outputable Hole where + ppr (Hole { hole_sort = ExprHole id + , hole_occ = occ + , hole_ty = ty }) + = parens $ (braces $ ppr occ <> colon <> ppr id) <+> dcolon <+> ppr ty + ppr (Hole { hole_sort = TypeHole + , hole_occ = occ + , hole_ty = ty }) + = braces $ ppr occ <> colon <> ppr ty + +instance Outputable HoleSort where + ppr (ExprHole id) = text "ExprHole:" <> ppr id + ppr TypeHole = text "TypeHole" + ------------ -- | Used to indicate extra information about why a CIrredCan is irreducible data CtIrredStatus @@ -252,20 +276,8 @@ instance Outputable CtIrredStatus where ppr BlockedCIS = text "(blocked)" ppr OtherCIS = text "(soluble)" -{- Note [Hole constraints] -~~~~~~~~~~~~~~~~~~~~~~~~~~ -CHoleCan constraints are used for two kinds of holes, -distinguished by cc_hole: - - * For holes in expressions - e.g. f x = g _ x - - * For holes in type signatures - e.g. f :: _ -> _ - f x = [x,True] - -Note [CIrredCan constraints] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [CIrredCan constraints] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CIrredCan constraints are used for constraints that are "stuck" - we can't solve them (yet) - we can't use them to solve other constraints @@ -350,6 +362,40 @@ unenforced). The almost-function-free property is checked by isAlmostFunctionFree in GHC.Tc.Utils.TcType. The flattener (in GHC.Tc.Solver.Flatten) produces types that are almost function-free. +Note [Holes] +~~~~~~~~~~~~ +This Note explains how GHC tracks *holes*. + +A hole represents one of two conditions: + - A missing bit of an expression. Example: foo x = x + _ + - A missing bit of a type. Example: bar :: Int -> _ + +What these have in common is that both cause GHC to emit a diagnostic to the +user describing the bit that is left out. + +When a hole is encountered, a new entry of type Hole is added to the ambient +WantedConstraints. The type (hole_ty) of the hole is then simplified during +solving (with respect to any Givens in surrounding implications). It is +reported with all the other errors in GHC.Tc.Errors. No type family reduction +is done on hole types; this is purely because we think it will produce +better error messages not to reduce type families. This is why the +GHC.Tc.Solver.Flatten.flattenType function uses FM_SubstOnly. + +For expression holes, the user has the option of deferring errors until runtime +with -fdefer-type-errors. In this case, the hole actually has evidence: this +evidence is an erroring expression that prints an error and crashes at runtime. +The ExprHole variant of holes stores the Id that will be bound to this evidence; +during constraint generation, this Id was inserted into the expression output +by the type checker. + +You might think that the type of the stored Id is the same as the type of the +hole. However, because the hole type (hole_ty) is rewritten with respect to +givens, this might not be the case. That is, the hole_ty is always (~) to the +type of the Id, but they might not be `eqType`. We need the type of the generated +evidence to match what is expected in the context of the hole, and so we must +store these types separately. + +Type-level holes have no evidence at all. -} mkNonCanonical :: CtEvidence -> Ct @@ -419,7 +465,6 @@ instance Outputable Ct where | pend_sc -> text "CDictCan(psc)" | otherwise -> text "CDictCan" CIrredCan { cc_status = status } -> text "CIrredCan" <> ppr status - CHoleCan { cc_occ = occ } -> text "CHoleCan:" <+> ppr occ CQuantCan (QCI { qci_pend_sc = pend_sc }) | pend_sc -> text "CQuantCan(psc)" | otherwise -> text "CQuantCan" @@ -482,9 +527,10 @@ tyCoVarsOfWCList = fvVarList . tyCoFVsOfWC -- computation. See Note [Deterministic FV] in GHC.Utils.FV. tyCoFVsOfWC :: WantedConstraints -> FV -- Only called on *zonked* things, hence no need to worry about flatten-skolems -tyCoFVsOfWC (WC { wc_simple = simple, wc_impl = implic }) +tyCoFVsOfWC (WC { wc_simple = simple, wc_impl = implic, wc_holes = holes }) = tyCoFVsOfCts simple `unionFV` - tyCoFVsOfBag tyCoFVsOfImplic implic + tyCoFVsOfBag tyCoFVsOfImplic implic `unionFV` + tyCoFVsOfBag tyCoFVsOfHole holes -- | Returns free variables of Implication as a composable FV computation. -- See Note [Deterministic FV] in GHC.Utils.FV. @@ -500,6 +546,9 @@ tyCoFVsOfImplic (Implic { ic_skols = skols tyCoFVsVarBndrs givens $ tyCoFVsOfWC wanted +tyCoFVsOfHole :: Hole -> FV +tyCoFVsOfHole (Hole { hole_ty = ty }) = tyCoFVsOfType ty + tyCoFVsOfBag :: (a -> FV) -> Bag a -> FV tyCoFVsOfBag tvs_of = foldr (unionFV . tvs_of) emptyFV @@ -552,7 +601,6 @@ isDroppableCt ct keep_deriv = case ct of - CHoleCan {} -> True CIrredCan { cc_status = InsolubleCIS } -> keep_eq True _ -> keep_eq False @@ -676,26 +724,6 @@ isCNonCanonical :: Ct -> Bool isCNonCanonical (CNonCanonical {}) = True isCNonCanonical _ = False -isHoleCt:: Ct -> Bool -isHoleCt (CHoleCan {}) = True -isHoleCt _ = False - -isOutOfScopeCt :: Ct -> Bool --- A Hole that does not have a leading underscore is --- simply an out-of-scope variable, and we treat that --- a bit differently when it comes to error reporting -isOutOfScopeCt (CHoleCan { cc_occ = occ }) = not (startsWithUnderscore occ) -isOutOfScopeCt _ = False - -isExprHoleCt :: Ct -> Bool -isExprHoleCt (CHoleCan { cc_hole = ExprHole }) = True -isExprHoleCt _ = False - -isTypeHoleCt :: Ct -> Bool -isTypeHoleCt (CHoleCan { cc_hole = TypeHole }) = True -isTypeHoleCt _ = False - - {- Note [Custom type errors in constraints] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -884,37 +912,39 @@ v%************************************************************************ data WantedConstraints = WC { wc_simple :: Cts -- Unsolved constraints, all wanted , wc_impl :: Bag Implication + , wc_holes :: Bag Hole } emptyWC :: WantedConstraints -emptyWC = WC { wc_simple = emptyBag, wc_impl = emptyBag } +emptyWC = WC { wc_simple = emptyBag + , wc_impl = emptyBag + , wc_holes = emptyBag } mkSimpleWC :: [CtEvidence] -> WantedConstraints mkSimpleWC cts - = WC { wc_simple = listToBag (map mkNonCanonical cts) - , wc_impl = emptyBag } + = emptyWC { wc_simple = listToBag (map mkNonCanonical cts) } mkImplicWC :: Bag Implication -> WantedConstraints mkImplicWC implic - = WC { wc_simple = emptyBag, wc_impl = implic } + = emptyWC { wc_impl = implic } isEmptyWC :: WantedConstraints -> Bool -isEmptyWC (WC { wc_simple = f, wc_impl = i }) - = isEmptyBag f && isEmptyBag i - +isEmptyWC (WC { wc_simple = f, wc_impl = i, wc_holes = holes }) + = isEmptyBag f && isEmptyBag i && isEmptyBag holes -- | Checks whether a the given wanted constraints are solved, i.e. -- that there are no simple constraints left and all the implications -- are solved. isSolvedWC :: WantedConstraints -> Bool -isSolvedWC WC {wc_simple = wc_simple, wc_impl = wc_impl} = - isEmptyBag wc_simple && allBag (isSolvedStatus . ic_status) wc_impl +isSolvedWC WC {wc_simple = wc_simple, wc_impl = wc_impl, wc_holes = holes} = + isEmptyBag wc_simple && allBag (isSolvedStatus . ic_status) wc_impl && isEmptyBag holes andWC :: WantedConstraints -> WantedConstraints -> WantedConstraints -andWC (WC { wc_simple = f1, wc_impl = i1 }) - (WC { wc_simple = f2, wc_impl = i2 }) +andWC (WC { wc_simple = f1, wc_impl = i1, wc_holes = h1 }) + (WC { wc_simple = f2, wc_impl = i2, wc_holes = h2 }) = WC { wc_simple = f1 `unionBags` f2 - , wc_impl = i1 `unionBags` i2 } + , wc_impl = i1 `unionBags` i2 + , wc_holes = h1 `unionBags` h2 } unionsWC :: [WantedConstraints] -> WantedConstraints unionsWC = foldr andWC emptyWC @@ -931,11 +961,16 @@ addInsols :: WantedConstraints -> Bag Ct -> WantedConstraints addInsols wc cts = wc { wc_simple = wc_simple wc `unionBags` cts } +addHole :: WantedConstraints -> Hole -> WantedConstraints +addHole wc hole + = wc { wc_holes = hole `consBag` wc_holes wc } + insolublesOnly :: WantedConstraints -> WantedConstraints -- Keep only the definitely-insoluble constraints -insolublesOnly (WC { wc_simple = simples, wc_impl = implics }) +insolublesOnly (WC { wc_simple = simples, wc_impl = implics, wc_holes = holes }) = WC { wc_simple = filterBag insolubleCt simples - , wc_impl = mapBag implic_insols_only implics } + , wc_impl = mapBag implic_insols_only implics + , wc_holes = filterBag isOutOfScopeHole holes } where implic_insols_only implic = implic { ic_wanted = insolublesOnly (ic_wanted implic) } @@ -953,9 +988,10 @@ insolubleImplic :: Implication -> Bool insolubleImplic ic = isInsolubleStatus (ic_status ic) insolubleWC :: WantedConstraints -> Bool -insolubleWC (WC { wc_impl = implics, wc_simple = simples }) +insolubleWC (WC { wc_impl = implics, wc_simple = simples, wc_holes = holes }) = anyBag insolubleCt simples || anyBag insolubleImplic implics + || anyBag isOutOfScopeHole holes -- See Note [Insoluble holes] insolubleCt :: Ct -> Bool -- Definitely insoluble, in particular /excluding/ type-hole constraints @@ -963,7 +999,6 @@ insolubleCt :: Ct -> Bool -- b) that is insoluble -- c) and does not arise from a Given insolubleCt ct - | isHoleCt ct = isOutOfScopeCt ct -- See Note [Insoluble holes] | not (insolubleEqCt ct) = False | arisesFromGivens ct = False -- See Note [Given insolubles] | otherwise = True @@ -986,11 +1021,17 @@ insolubleEqCt :: Ct -> Bool insolubleEqCt (CIrredCan { cc_status = InsolubleCIS }) = True insolubleEqCt _ = False +-- | Does this hole represent an "out of scope" error? +-- See Note [Insoluble holes] +isOutOfScopeHole :: Hole -> Bool +isOutOfScopeHole (Hole { hole_occ = occ }) = not (startsWithUnderscore occ) + instance Outputable WantedConstraints where - ppr (WC {wc_simple = s, wc_impl = i}) + ppr (WC {wc_simple = s, wc_impl = i, wc_holes = h}) = text "WC" <+> braces (vcat [ ppr_bag (text "wc_simple") s - , ppr_bag (text "wc_impl") i ]) + , ppr_bag (text "wc_impl") i + , ppr_bag (text "wc_holes") h ]) ppr_bag :: Outputable a => SDoc -> Bag a -> SDoc ppr_bag doc bag @@ -1035,7 +1076,7 @@ Hole constraints that ARE NOT treated as truly insoluble: a) type holes, arising from PartialTypeSignatures, b) "true" expression holes arising from TypedHoles -An "expression hole" or "type hole" constraint isn't really an error +An "expression hole" or "type hole" isn't really an error at all; it's a report saying "_ :: Int" here. But an out-of-scope variable masquerading as expression holes IS treated as truly insoluble, so that it trumps other errors during error reporting. @@ -1512,10 +1553,6 @@ ctFlavourRole (CTyEqCan { cc_ev = ev, cc_eq_rel = eq_rel }) = (ctEvFlavour ev, eq_rel) ctFlavourRole (CFunEqCan { cc_ev = ev }) = (ctEvFlavour ev, NomEq) -ctFlavourRole (CHoleCan { cc_ev = ev }) - = (ctEvFlavour ev, NomEq) -- NomEq: CHoleCans can be rewritten by - -- by nominal equalities but empahatically - -- not by representational equalities ctFlavourRole ct = ctEvFlavourRole (ctEvidence ct) ===================================== compiler/GHC/Tc/Types/Origin.hs ===================================== @@ -427,7 +427,9 @@ data CtOrigin -- We only need a CtOrigin on the first, because the location -- is pinned on the entire error message - | HoleOrigin + | ExprHoleOrigin OccName -- from an expression hole + | TypeHoleOrigin OccName -- from a type hole (partial type signature) + | PatCheckOrigin -- normalisation of a type during pattern-match checking | UnboundOccurrenceOf OccName | ListOrigin -- An overloaded list | BracketOrigin -- An overloaded quotation bracket @@ -640,7 +642,9 @@ pprCtO MCompOrigin = text "a statement in a monad comprehension" pprCtO ProcOrigin = text "a proc expression" pprCtO (TypeEqOrigin t1 t2 _ _)= text "a type equality" <+> sep [ppr t1, char '~', ppr t2] pprCtO AnnOrigin = text "an annotation" -pprCtO HoleOrigin = text "a use of" <+> quotes (text "_") +pprCtO (ExprHoleOrigin occ) = text "a use of" <+> quotes (ppr occ) +pprCtO (TypeHoleOrigin occ) = text "a use of wildcard" <+> quotes (ppr occ) +pprCtO PatCheckOrigin = text "a pattern-match completeness check" pprCtO ListOrigin = text "an overloaded list" pprCtO StaticOrigin = text "a static form" pprCtO BracketOrigin = text "a quotation bracket" ===================================== compiler/GHC/Tc/Utils/Monad.hs ===================================== @@ -98,14 +98,14 @@ module GHC.Tc.Utils.Monad( chooseUniqueOccTc, getConstraintVar, setConstraintVar, emitConstraints, emitStaticConstraints, emitSimple, emitSimples, - emitImplication, emitImplications, emitInsoluble, + emitImplication, emitImplications, emitInsoluble, emitHole, discardConstraints, captureConstraints, tryCaptureConstraints, pushLevelAndCaptureConstraints, pushTcLevelM_, pushTcLevelM, pushTcLevelsM, getTcLevel, setTcLevel, isTouchableTcM, getLclTypeEnv, setLclTypeEnv, traceTcConstraints, - emitNamedWildCardHoleConstraints, emitAnonWildCardHoleConstraint, + emitNamedTypeHole, emitAnonTypeHole, -- * Template Haskell context recordThUse, recordThSpliceUse, @@ -1569,12 +1569,11 @@ emitInsoluble ct ; lie_var <- getConstraintVar ; updTcRef lie_var (`addInsols` unitBag ct) } -emitInsolubles :: Cts -> TcM () -emitInsolubles cts - | isEmptyBag cts = return () - | otherwise = do { traceTc "emitInsolubles" (ppr cts) - ; lie_var <- getConstraintVar - ; updTcRef lie_var (`addInsols` cts) } +emitHole :: Hole -> TcM () +emitHole hole + = do { traceTc "emitHole" (ppr hole) + ; lie_var <- getConstraintVar + ; updTcRef lie_var (`addHole` hole) } -- | Throw out any constraints emitted by the thing_inside discardConstraints :: TcM a -> TcM a @@ -1644,34 +1643,28 @@ traceTcConstraints msg hang (text (msg ++ ": LIE:")) 2 (ppr lie) } -emitAnonWildCardHoleConstraint :: TcTyVar -> TcM () -emitAnonWildCardHoleConstraint tv - = do { ct_loc <- getCtLocM HoleOrigin Nothing - ; emitInsolubles $ unitBag $ - CHoleCan { cc_ev = CtDerived { ctev_pred = mkTyVarTy tv - , ctev_loc = ct_loc } - , cc_occ = mkTyVarOcc "_" - , cc_hole = TypeHole } } - -emitNamedWildCardHoleConstraints :: [(Name, TcTyVar)] -> TcM () -emitNamedWildCardHoleConstraints wcs - = do { ct_loc <- getCtLocM HoleOrigin Nothing - ; emitInsolubles $ listToBag $ - map (do_one ct_loc) wcs } +emitAnonTypeHole :: TcTyVar -> TcM () +emitAnonTypeHole tv + = do { ct_loc <- getCtLocM (TypeHoleOrigin occ) Nothing + ; let hole = Hole { hole_sort = TypeHole + , hole_occ = occ + , hole_ty = mkTyVarTy tv + , hole_loc = ct_loc } + ; emitHole hole } + where + occ = mkTyVarOcc "_" + +emitNamedTypeHole :: (Name, TcTyVar) -> TcM () +emitNamedTypeHole (name, tv) + = do { ct_loc <- setSrcSpan (nameSrcSpan name) $ + getCtLocM (TypeHoleOrigin occ) Nothing + ; let hole = Hole { hole_sort = TypeHole + , hole_occ = occ + , hole_ty = mkTyVarTy tv + , hole_loc = ct_loc } + ; emitHole hole } where - do_one :: CtLoc -> (Name, TcTyVar) -> Ct - do_one ct_loc (name, tv) - = CHoleCan { cc_ev = CtDerived { ctev_pred = mkTyVarTy tv - , ctev_loc = ct_loc' } - , cc_occ = occName name - , cc_hole = TypeHole } - where - real_span = case nameSrcSpan name of - RealSrcSpan span _ -> span - UnhelpfulSpan str -> pprPanic "emitNamedWildCardHoleConstraints" - (ppr name <+> quotes (ftext str)) - -- Wildcards are defined locally, and so have RealSrcSpans - ct_loc' = setCtLocSpan ct_loc real_span + occ = nameOccName name {- Note [Constraints and errors] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Tc/Utils/TcMType.hs ===================================== @@ -41,10 +41,11 @@ module GHC.Tc.Utils.TcMType ( -------------------------------- -- Creating new evidence variables newEvVar, newEvVars, newDict, - newWanted, newWanteds, newHoleCt, cloneWanted, cloneWC, + newWanted, newWanteds, cloneWanted, cloneWC, emitWanted, emitWantedEq, emitWantedEvVar, emitWantedEvVars, emitDerivedEqs, newTcEvBinds, newNoTcEvBinds, addTcEvBind, + emitNewExprHole, newCoercionHole, fillCoercionHole, isFilledCoercionHole, unpackCoercionHole, unpackCoercionHole_maybe, @@ -67,7 +68,7 @@ module GHC.Tc.Utils.TcMType ( -------------------------------- -- Zonking and tidying zonkTidyTcType, zonkTidyTcTypes, zonkTidyOrigin, - tidyEvVar, tidyCt, tidySkolemInfo, + tidyEvVar, tidyCt, tidyHole, tidySkolemInfo, zonkTcTyVar, zonkTcTyVars, zonkTcTyVarToTyVar, zonkTyVarTyVarPairs, zonkTyCoVarsAndFV, zonkTcTypeAndFV, zonkDTyCoVarSetAndFV, @@ -193,17 +194,6 @@ newWanted orig t_or_k pty newWanteds :: CtOrigin -> ThetaType -> TcM [CtEvidence] newWanteds orig = mapM (newWanted orig Nothing) --- | Create a new 'CHoleCan' 'Ct'. -newHoleCt :: HoleSort -> Id -> Type -> TcM Ct -newHoleCt hole ev ty = do - loc <- getCtLocM HoleOrigin Nothing - pure $ CHoleCan { cc_ev = CtWanted { ctev_pred = ty - , ctev_dest = EvVarDest ev - , ctev_nosh = WDeriv - , ctev_loc = loc } - , cc_occ = getOccName ev - , cc_hole = hole } - ---------------------------------------------- -- Cloning constraints ---------------------------------------------- @@ -286,6 +276,18 @@ emitWantedEvVar origin ty emitWantedEvVars :: CtOrigin -> [TcPredType] -> TcM [EvVar] emitWantedEvVars orig = mapM (emitWantedEvVar orig) +-- | Emit a new wanted expression hole +emitNewExprHole :: OccName -- of the hole + -> Id -- of the evidence + -> Type -> TcM () +emitNewExprHole occ ev_id ty + = do { loc <- getCtLocM (ExprHoleOrigin occ) (Just TypeLevel) + ; let hole = Hole { hole_sort = ExprHole ev_id + , hole_occ = getOccName ev_id + , hole_ty = ty + , hole_loc = loc } + ; emitHole hole } + newDict :: Class -> [TcType] -> TcM DictId newDict cls tys = do { name <- newSysName (mkDictOcc (getOccName cls)) @@ -2002,21 +2004,28 @@ zonkWC :: WantedConstraints -> TcM WantedConstraints zonkWC wc = zonkWCRec wc zonkWCRec :: WantedConstraints -> TcM WantedConstraints -zonkWCRec (WC { wc_simple = simple, wc_impl = implic }) +zonkWCRec (WC { wc_simple = simple, wc_impl = implic, wc_holes = holes }) = do { simple' <- zonkSimples simple ; implic' <- mapBagM zonkImplication implic - ; return (WC { wc_simple = simple', wc_impl = implic' }) } + ; holes' <- mapBagM zonkHole holes + ; return (WC { wc_simple = simple', wc_impl = implic', wc_holes = holes' }) } zonkSimples :: Cts -> TcM Cts zonkSimples cts = do { cts' <- mapBagM zonkCt cts ; traceTc "zonkSimples done:" (ppr cts') ; return cts' } +zonkHole :: Hole -> TcM Hole +zonkHole hole@(Hole { hole_ty = ty }) + = do { ty' <- zonkTcType ty + ; return (hole { hole_ty = ty' }) } + -- No need to zonk the Id in any ExprHole because we never look at it + -- until after the final zonk and desugaring + {- Note [zonkCt behaviour] ~~~~~~~~~~~~~~~~~~~~~~~~~~ zonkCt tries to maintain the canonical form of a Ct. For example, - a CDictCan should stay a CDictCan; - - a CHoleCan should stay a CHoleCan - a CIrredCan should stay a CIrredCan with its cc_status flag intact Why?, for example: @@ -2026,8 +2035,6 @@ Why?, for example: don't preserve a canonical form, @expandSuperClasses@ fails to expand superclasses. This is what happened in #11525. -- For CHoleCan, once we forget that it's a hole, we can never recover that info. - - For CIrredCan we want to see if a constraint is insoluble with insolubleWC On the other hand, we change CTyEqCan to CNonCanonical, because of all of @@ -2046,10 +2053,6 @@ creates e.g. a CDictCan where the cc_tyars are /not/ function free. zonkCt :: Ct -> TcM Ct -- See Note [zonkCt behaviour] -zonkCt ct@(CHoleCan { cc_ev = ev }) - = do { ev' <- zonkCtEvidence ev - ; return $ ct { cc_ev = ev' } } - zonkCt ct@(CDictCan { cc_ev = ev, cc_tyargs = args }) = do { ev' <- zonkCtEvidence ev ; args' <- mapM zonkTcType args @@ -2262,17 +2265,15 @@ zonkTidyOrigin env orig = return (env, orig) tidyCt :: TidyEnv -> Ct -> Ct -- Used only in error reporting tidyCt env ct - = ct { cc_ev = tidy_ev env (ctEvidence ct) } + = ct { cc_ev = tidy_ev (ctEvidence ct) } where - tidy_ev :: TidyEnv -> CtEvidence -> CtEvidence + tidy_ev :: CtEvidence -> CtEvidence -- NB: we do not tidy the ctev_evar field because we don't -- show it in error messages - tidy_ev env ctev@(CtGiven { ctev_pred = pred }) - = ctev { ctev_pred = tidyType env pred } - tidy_ev env ctev@(CtWanted { ctev_pred = pred }) - = ctev { ctev_pred = tidyType env pred } - tidy_ev env ctev@(CtDerived { ctev_pred = pred }) - = ctev { ctev_pred = tidyType env pred } + tidy_ev ctev = ctev { ctev_pred = tidyType env (ctev_pred ctev) } + +tidyHole :: TidyEnv -> Hole -> Hole +tidyHole env h@(Hole { hole_ty = ty }) = h { hole_ty = tidyType env ty } ---------------- tidyEvVar :: TidyEnv -> EvVar -> EvVar ===================================== testsuite/tests/partial-sigs/should_compile/SplicesUsed.stderr ===================================== @@ -34,7 +34,7 @@ SplicesUsed.hs:10:16: warning: [-Wpartial-type-signatures (in -Wdefault)] In the type signature: charA :: a -> (_) SplicesUsed.hs:13:13: warning: [-Wpartial-type-signatures (in -Wdefault)] - • Found type wildcard ‘_’ standing for ‘a -> Bool’ + • Found type wildcard ‘_’ standing for ‘[a]’ Where: ‘a’ is a rigid type variable bound by the inferred type of filter' :: (a -> Bool) -> [a] -> [a] at SplicesUsed.hs:14:1-16 @@ -50,7 +50,7 @@ SplicesUsed.hs:13:13: warning: [-Wpartial-type-signatures (in -Wdefault)] In the type signature: filter' :: (_ -> _ -> _) SplicesUsed.hs:13:13: warning: [-Wpartial-type-signatures (in -Wdefault)] - • Found type wildcard ‘_’ standing for ‘[a]’ + • Found type wildcard ‘_’ standing for ‘a -> Bool’ Where: ‘a’ is a rigid type variable bound by the inferred type of filter' :: (a -> Bool) -> [a] -> [a] at SplicesUsed.hs:14:1-16 @@ -58,26 +58,26 @@ SplicesUsed.hs:13:13: warning: [-Wpartial-type-signatures (in -Wdefault)] In the type signature: filter' :: (_ -> _ -> _) SplicesUsed.hs:16:2: warning: [-Wpartial-type-signatures (in -Wdefault)] - • Found type wildcard ‘_’ standing for ‘Eq a’ + • Found type wildcard ‘_’ standing for ‘a -> a -> Bool’ Where: ‘a’ is a rigid type variable bound by the inferred type of foo :: Eq a => a -> a -> Bool at SplicesUsed.hs:16:2-11 • In the type signature: foo :: _ => _ SplicesUsed.hs:16:2: warning: [-Wpartial-type-signatures (in -Wdefault)] - • Found type wildcard ‘_’ standing for ‘a -> a -> Bool’ + • Found type wildcard ‘_’ standing for ‘Eq a’ Where: ‘a’ is a rigid type variable bound by the inferred type of foo :: Eq a => a -> a -> Bool at SplicesUsed.hs:16:2-11 • In the type signature: foo :: _ => _ -SplicesUsed.hs:18:2: warning: [-Wpartial-type-signatures (in -Wdefault)] - • Found type wildcard ‘_a’ standing for ‘Bool’ - • In the type signature: bar :: _a -> _b -> (_a, _b) - SplicesUsed.hs:18:2: warning: [-Wpartial-type-signatures (in -Wdefault)] • Found type wildcard ‘_b’ standing for ‘_’ Where: ‘_’ is a rigid type variable bound by the inferred type of bar :: Bool -> _ -> (Bool, _) at SplicesUsed.hs:18:2-11 • In the type signature: bar :: _a -> _b -> (_a, _b) + +SplicesUsed.hs:18:2: warning: [-Wpartial-type-signatures (in -Wdefault)] + • Found type wildcard ‘_a’ standing for ‘Bool’ + • In the type signature: bar :: _a -> _b -> (_a, _b) ===================================== testsuite/tests/plugins/hole-fit-plugin/HoleFitPlugin.hs ===================================== @@ -3,8 +3,6 @@ module HoleFitPlugin where import GHC.Plugins hiding ((<>)) -import GHC.Tc.Errors.Hole - import Data.List (stripPrefix, sortOn) import GHC.Tc.Types.Constraint @@ -34,7 +32,7 @@ fromModule (GreHFCand gre) = fromModule _ = [] toHoleFitCommand :: TypedHole -> String -> Maybe String -toHoleFitCommand TyH{tyHCt = Just (CHoleCan _ h _)} str +toHoleFitCommand (TypedHole {th_hole = Just (Hole { hole_occ = h })}) str = stripPrefix ("_" <> str) $ occNameString h toHoleFitCommand _ _ = Nothing ===================================== testsuite/tests/th/T12411.stderr ===================================== @@ -2,7 +2,7 @@ T12411.hs:4:6: error: Variable not in scope: (@) - :: (a0 -> f0 a0) -> t0 -> Language.Haskell.TH.Lib.Internal.DecsQ + :: (a1 -> f0 a1) -> t0 -> Language.Haskell.TH.Lib.Internal.DecsQ T12411.hs:4:7: error: - Data constructor not in scope: Q :: [a1] -> t0 + Data constructor not in scope: Q :: [a0] -> t0 ===================================== testsuite/tests/typecheck/should_fail/T12589.stderr ===================================== @@ -1,8 +1,8 @@ -T12589.hs:13:3: error: Variable not in scope: (&) :: t1 -> t0 -> t +T12589.hs:13:3: error: Variable not in scope: (&) :: t0 -> t1 -> t T12589.hs:13:5: error: - • Cannot instantiate unification variable ‘t0’ + • Cannot instantiate unification variable ‘t1’ with a type involving polytypes: (forall a. Bounded a => f0 a) -> h0 f0 xs0 GHC doesn't yet support impredicative polymorphism View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8147d941e5ba8ff25b8f047580c82ead5d331e8c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8147d941e5ba8ff25b8f047580c82ead5d331e8c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 3 19:16:54 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 03 May 2020 15:16:54 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 6 commits: rts: Enable tracing of nonmoving heap census with -ln Message-ID: <5eaf18a61bb88_6167e5b152c8571864@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 7bfe9ac5 by Ben Gamari at 2020-05-03T04:41:33-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. - - - - - c560dd07 by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Move eventlog documentation users guide - - - - - 02543d5e by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Add documentation for non-moving GC events - - - - - b465dd45 by Alexis King at 2020-05-03T04:42:12-04:00 Flatten nested casts in the simple optimizer Normally, we aren’t supposed to generated any nested casts, since mkCast takes care to flatten them, but the simple optimizer didn’t use mkCast, so they could show up after inlining. This isn’t really a problem, since the simplifier will clean them up immediately anyway, but it can clutter the -ddump-ds output, and it’s an extremely easy fix. closes #18112 - - - - - 1e1e32a6 by Simon Peyton Jones at 2020-05-03T15:16:40-04:00 Don't return a panic in tcNestedSplice In GHC.Tc.Gen.Splice.tcNestedSplice we were returning a typechecked expression of "panic". That is usually OK, because the result is discarded. But it happens that tcApp now looks at the typechecked expression, trivially, to ask if it is tagToEnum. So being bottom is bad. Moreover a debug-trace might print it out. So better to return a civilised expression, even though it is usually discarded. - - - - - 1c49d150 by Baldur Blöndal at 2020-05-03T15:16:44-04:00 Don't require parentheses around via type (`-XDerivingVia'). Fixes #18130". - - - - - 20 changed files: - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Parser.y - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Splice.hs - docs/users_guide/conf.py - docs/users_guide/eventlog-formats.rst - docs/users_guide/runtime_control.rst - includes/rts/EventLogFormat.h - rts/RtsFlags.c - rts/sm/NonMoving.c - + testsuite/tests/deSugar/should_compile/T18112.hs - testsuite/tests/deSugar/should_compile/all.T - testsuite/tests/dependent/should_compile/dynamic-paper.stderr - + testsuite/tests/parser/should_compile/T18130.hs - testsuite/tests/parser/should_compile/all.T - + testsuite/tests/parser/should_fail/T18130Fail.hs - + testsuite/tests/parser/should_fail/T18130Fail.stderr - testsuite/tests/parser/should_fail/all.T - + testsuite/tests/th/T18121.hs - testsuite/tests/th/all.T Changes: ===================================== compiler/GHC/Core/SimpleOpt.hs ===================================== @@ -221,10 +221,13 @@ simple_opt_expr env expr go (Coercion co) = Coercion (optCoercion (soe_dflags env) (getTCvSubst subst) co) go (Lit lit) = Lit lit go (Tick tickish e) = mkTick (substTickish subst tickish) (go e) - go (Cast e co) | isReflCo co' = go e - | otherwise = Cast (go e) co' - where - co' = optCoercion (soe_dflags env) (getTCvSubst subst) co + go (Cast e co) = case go e of + -- flatten nested casts before calling the coercion optimizer; + -- see #18112 (note that mkCast handles dropping Refl coercions) + Cast e' co' -> mkCast e' (opt_co (mkTransCo co' co)) + e' -> mkCast e' (opt_co co) + where + opt_co = optCoercion (soe_dflags env) (getTCvSubst subst) go (Let bind body) = case simple_opt_bind env bind NotTopLevel of (env', Nothing) -> simple_opt_expr env' body ===================================== compiler/GHC/Parser.y ===================================== @@ -1209,8 +1209,8 @@ deriv_strategy_no_via :: { LDerivStrategy GhcPs } [mj AnnNewtype $1] } deriv_strategy_via :: { LDerivStrategy GhcPs } - : 'via' type {% ams (sLL $1 $> (ViaStrategy (mkLHsSigType $2))) - [mj AnnVia $1] } + : 'via' ktype {% ams (sLL $1 $> (ViaStrategy (mkLHsSigType $2))) + [mj AnnVia $1] } deriv_standalone_strategy :: { Maybe (LDerivStrategy GhcPs) } : 'stock' {% ajs (sL1 $1 StockStrategy) ===================================== compiler/GHC/Tc/Gen/Expr.hs ===================================== @@ -981,12 +981,9 @@ tcExpr (HsSpliceE _ (HsSpliced _ mod_finalizers (HsSplicedExpr expr))) res_ty = do addModFinalizersWithLclEnv mod_finalizers tcExpr expr res_ty -tcExpr (HsSpliceE _ splice) res_ty - = tcSpliceExpr splice res_ty -tcExpr e@(HsBracket _ brack) res_ty - = tcTypedBracket e brack res_ty -tcExpr e@(HsRnBracketOut _ brack ps) res_ty - = tcUntypedBracket e brack ps res_ty +tcExpr (HsSpliceE _ splice) res_ty = tcSpliceExpr splice res_ty +tcExpr e@(HsBracket _ brack) res_ty = tcTypedBracket e brack res_ty +tcExpr e@(HsRnBracketOut _ brack ps) res_ty = tcUntypedBracket e brack ps res_ty {- ************************************************************************ @@ -1219,7 +1216,11 @@ tcApp expr res_ty = do { (fun, args, app_res_ty) <- tcInferApp expr ; if isTagToEnum fun then tcTagToEnum expr fun args app_res_ty res_ty - else -- The wildly common case + -- Done here because we have res_ty, + -- whereas tcInferApp does not + else + + -- The wildly common case do { let expr' = applyHsArgs fun args ; addFunResCtxt True fun app_res_ty res_ty $ tcWrapResult expr expr' app_res_ty res_ty } } @@ -1232,10 +1233,10 @@ tcInferApp :: HsExpr GhcRn -- Also used by Module.tcRnExpr to implement GHCi :type tcInferApp expr | -- Gruesome special case for ambiguous record selectors - HsRecFld _ fld_lbl <- fun - , Ambiguous _ lbl <- fld_lbl -- Still ambiguous + HsRecFld _ fld_lbl <- fun + , Ambiguous _ lbl <- fld_lbl -- Still ambiguous , HsEValArg _ (L _ arg) : _ <- filterOut isArgPar args -- A value arg is first - , Just sig_ty <- obviousSig arg -- A type sig on the arg disambiguates + , Just sig_ty <- obviousSig arg -- A type sig on the arg disambiguates = do { sig_tc_ty <- tcHsSigWcType ExprSigCtxt sig_ty ; sel_name <- disambiguateSelector lbl sig_tc_ty ; (tc_fun, fun_ty) <- tcInferRecSelId (Unambiguous sel_name lbl) @@ -1259,11 +1260,7 @@ tcInferApp_finish -> TcM (HsExpr GhcTc, [LHsExprArgOut], TcSigmaType) tcInferApp_finish rn_fun tc_fun fun_sigma rn_args - = do { traceTc "tcInferApp_finish" $ - vcat [ ppr rn_fun <+> dcolon <+> ppr fun_sigma, ppr rn_args ] - - ; (tc_args, actual_res_ty) <- tcArgs rn_fun fun_sigma rn_args - + = do { (tc_args, actual_res_ty) <- tcArgs rn_fun fun_sigma rn_args ; return (tc_fun, tc_args, actual_res_ty) } mk_op_msg :: LHsExpr GhcRn -> SDoc ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -625,7 +625,13 @@ tcNestedSplice pop_stage (TcPending ps_var lie_var q@(QuoteWrapper _ m_var)) spl ; writeMutVar ps_var (PendingTcSplice splice_name expr'' : ps) -- The returned expression is ignored; it's in the pending splices - ; return (panic "tcSpliceExpr") } + -- But we still return a plausible expression + -- (a) in case we print it in debug messages, and + -- (b) because we test whether it is tagToEnum in Tc.Gen.Expr.tcApp + ; return (HsSpliceE noExtField $ + HsSpliced noExtField (ThModFinalizers []) $ + HsSplicedExpr (unLoc expr'')) } + tcNestedSplice _ _ splice_name _ _ = pprPanic "tcNestedSplice: rename stage found" (ppr splice_name) ===================================== docs/users_guide/conf.py ===================================== @@ -283,8 +283,18 @@ def setup(app): objname='runtime system command-line option', parse_node=parse_flag, indextemplate='pair: %s; RTS option', + doc_field_types=[ + Field('since', label='Introduced in GHC version', names=['since']) + ]) + + app.add_object_type('event-type', 'event-type', + objname='event log event type', + indextemplate='pair: %s; eventlog event type', doc_field_types=[ Field('since', label='Introduced in GHC version', names=['since']), + Field('tag', label='Event type ID', names=['tag']), + Field('length', label='Record length', names=['length']), + TypedField('fields', label='Fields', names='field', typenames=('fieldtype', 'type')) ]) app.add_object_type('pragma', 'pragma', ===================================== docs/users_guide/eventlog-formats.rst ===================================== @@ -1,3 +1,5 @@ +.. _eventlog-encodings: + Eventlog encodings ================== @@ -7,6 +9,481 @@ thread scheduling events, garbage collection statistics, profiling information, user-defined tracing events. This section is intended for implementors of tooling which consume these events. +GHC ships with a C header file (``EventlogFormat.h``) which provides symbolic +names for the event type IDs described in this file. + + +Event log format +---------------- + +The log format is designed to be extensible: old tools should be +able to parse (but not necessarily understand all of) new versions +of the format, and new tools will be able to understand old log +files. + +- The format is endian-independent: all values are represented in + big-endian order. + +- The format is extensible: + + - The header describes each event type and its length. Tools + that don't recognise a particular event type can skip those events. + + - There is room for extra information in the event type + specification, which can be ignored by older tools. + + - Events can have extra information added, but existing fields + cannot be changed. Tools should ignore extra fields at the + end of the event record. + +The event-log stream begins with a header describing the event types present in +the file. The header is followed by the event records themselves, each of which +consist of a 64-bit timestamp + +.. code-block:: none + + log : EVENT_HEADER_BEGIN + EventType* + EVENT_HEADER_END + EVENT_DATA_BEGIN + Event* + EVENT_DATA_END + + EventType : + EVENT_ET_BEGIN + Word16 -- unique identifier for this event + Int16 -- >=0 size of the event in bytes (minus the header) + -- -1 variable size + Word32 -- length of the next field in bytes + Word8* -- string describing the event + Word32 -- length of the next field in bytes + Word8* -- extra info (for future extensions) + EVENT_ET_END + + Event : + Word16 -- event_type + Word64 -- time (nanosecs) + [Word16] -- length of the rest (for variable-sized events only) + ... extra event-specific info ... + +There are two classes of event types: + + - *Fixed size*: All event records of a fixed-sized type are of the same + length, given in the header event-log header. + + - *Variable size*: Each event record includes a length field. + +Runtime system diagnostics +-------------------------- + + * ``ThreadId ~ Word32`` + * ``CapNo ~ Word16`` + * ``CapSetId ~ Word32`` + +Capability sets +~~~~~~~~~~~~~~~ + +TODO + +Environment information +~~~~~~~~~~~~~~~~~~~~~~~ + +These events are typically produced during program startup and describe the +environment which the program is being run in. + +.. event-type:: RTS_IDENTIFIER + + :tag: 29 + :length: variable + :field CapSetId: Capability set + :field String: Runtime system name and version. + + Describes the name and version of the runtime system responsible for the + indicated capability set. + +.. event-type:: PROGRAM_ARGS + + :tag: 30 + :length: variable + :field CapSetId: Capability set + :field [String]: The command-line arguments passed to the program + + Describes the command-line used to start the program. + +.. event-type:: PROGRAM_ENV + + :tag: 31 + :length: variable + :field CapSetId: Capability set + :field [String]: The environment variable name/value pairs. (TODO: encoding?) + + Describes the environment variables present in the program's environment. + +Thread and scheduling events +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. event-type:: CREATE_THREAD + + :tag: 0 + :length: fixed + :field ThreadId: thread id + + Marks the creation of a Haskell thread. + + +.. event-type:: RUN_THREAD + + :tag: 1 + :length: fixed + :field ThreadId: thread id + + The indicated thread has started running. + + +.. event-type:: STOP_THREAD + + :tag: 2 + :length: fixed + :field ThreadId: thread id + :field Word16: status + + * 1: HeapOverflow + * 2: StackOverflow + * 3: ThreadYielding + * 4: ThreadBlocked + * 5: ThreadFinished + * 6: ForeignCall + * 7: BlockedOnMVar + * 8: BlockedOnBlackHole + * 9: BlockedOnRead + * 10: BlockedOnWrite + * 11: BlockedOnDelay + * 12: BlockedOnSTM + * 13: BlockedOnDoProc + * 16: BlockedOnMsgThrowTo + + :field ThreadId: thread id of thread being blocked on (only for some status + values) + + The indicated thread has stopped running for the reason given by ``status``. + + +.. event-type:: THREAD_RUNNABLE + + :tag: 3 + :length: fixed + :field ThreadId: thread id + + The indicated thread is has been marked as ready to run. + + +.. event-type:: MIGRATE_THREAD + + :tag: 4 + :length: fixed + :field ThreadId: thread id + :field CapNo: capability + + The indicated thread has been migrated to a new capability. + + +.. event-type:: THREAD_WAKEUP + + :tag: 8 + :length: fixed + :field ThreadId: thread id + :field CapNo: other capability + + The indicated thread has been been woken up on another capability. + +.. event-type:: THREAD_LABEL + + :tag: 44 + :length: fixed + :field ThreadId: thread id + :field String: label + + The indicated thread has been given a label (e.g. with + :base-ref:`Control.Concurrent.setThreadLabel`). + + +Garbage collector events +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. event-type:: GC_START + + :tag: 9 + :length: fixed + + A garbage collection pass has been started. + +.. event-type:: GC_END + + :tag: 10 + :length: fixed + + A garbage collection pass has been finished. + +.. event-type:: REQUEST_SEQ_GC + + :tag: 11 + :length: fixed + + A sequential garbage collection has been requested by a capability. + +.. event-type:: REQUEST_PAR_GC + + :tag: 12 + :length: fixed + + A parallel garbage collection has been requested by a capability. + +.. event-type:: GC_IDLE + + :tag: 20 + :length: fixed + + An idle-time garbage collection has been started. + +.. event-type:: GC_WORK + + :tag: 21 + :length: fixed + + Marks the start of concurrent scavenging. + +.. event-type:: GC_DONE + + :tag: 22 + :length: fixed + + Marks the end of concurrent scavenging. + +.. event-type:: GC_STATS_GHC + + :tag: 53 + :length: fixed + :field CapSetId: heap capability set + :field Word16: generation of collection + :field Word64: bytes copied + :field Word64: bytes of slop found + :field Word64: TODO + :field Word64: number of parallel garbage collection threads + :field Word64: maximum number of bytes copied by any single collector thread + :field Word64: total bytes copied by all collector threads + + Report various information about the heap configuration. Typically produced + during RTS initialization.. + +.. event-type:: GC_GLOBAL_SYNC + + :tag: 54 + :length: fixed + + TODO + +Heap events and statistics +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. event-type:: HEAP_ALLOCATED + + :tag: 49 + :length: fixed + :field CapSetId: heap capability set + :field Word64: allocated bytes + + A new chunk of heap has been allocated by the indicated capability set. + +.. event-type:: HEAP_SIZE + + :tag: 50 + :length: fixed + :field CapSetId: heap capability set + :field Word64: heap size in bytes + + Report the heap size. + +.. event-type:: HEAP_LIVE + + :tag: 51 + :length: fixed + :field CapSetId: heap capability set + :field Word64: heap size in bytes + + Report the live heap size. + +.. event-type:: HEAP_INFO_GHC + + :tag: 52 + :length: fixed + :field CapSetId: heap capability set + :field Word16: number of garbage collection generations + :field Word64: maximum heap size + :field Word64: allocation area size + :field Word64: MBlock size + :field Word64: Block size + + Report various information about the heap configuration. Typically produced + during RTS initialization.. + +Spark events +~~~~~~~~~~~~ + +.. event-type:: CREATE_SPARK_THREAD + + :tag: 15 + :length: fixed + + A thread has been created to perform spark evaluation. + +.. event-type:: SPARK_COUNTERS + + :tag: 34 + :length: fixed + + A periodic reporting of various statistics of spark evaluation. + +.. event-type:: SPARK_CREATE + + :tag: 35 + :length: fixed + + A spark has been added to the spark pool. + +.. event-type:: SPARK_DUD + + :tag: 36 + :length: fixed + + TODO + +.. event-type:: SPARK_OVERFLOW + + :tag: 37 + :length: fixed + + TODO + +.. event-type:: SPARK_RUN + + :tag: 38 + :length: fixed + + Evaluation has started on a spark. + +.. event-type:: SPARK_STEAL + + :tag: 39 + :length: fixed + :field Word16: capability from which the spark was stolen + + A spark has been stolen from another capability for evaluation. + +.. event-type:: SPARK_FIZZLE + + :tag: 40 + :length: fixed + + A spark has been GC'd before being evaluated. + +.. event-type:: SPARK_GC + + :tag: 41 + :length: fixed + + An unevaluated spark has been garbage collected. + +Capability events +~~~~~~~~~~~~~~~~~ + +.. event-type:: CAP_CREATE + + :tag: 45 + :length: fixed + :field CapNo: the capability number + + A capability has been started. + +.. event-type:: CAP_DELETE + + :tag: 46 + :length: fixed + + A capability has been deleted. + +.. event-type:: CAP_DISABLE + + :tag: 47 + :length: fixed + + A capability has been disabled. + +.. event-type:: CAP_ENABLE + + :tag: 48 + :length: fixed + + A capability has been enabled. + +Task events +~~~~~~~~~~~ + +.. event-type:: TASK_CREATE + + :tag: 55 + :length: fixed + :field TaskId: task id + :field CapNo: capability number + :field ThreadId: TODO + + Marks the creation of a task. + +.. event-type:: TASK_MIGRATE + + :tag: 56 + :length: fixed + :field TaskId: task id + :field CapNo: old capability + :field CapNo: new capability + + Marks the migration of a task to a new capability. + +Tracing events +~~~~~~~~~~~~~~ + +.. event-type:: LOG_MSG + + :tag: 16 + :length: variable + :field String: The message + + A log message from the runtime system. + +.. event-type:: BLOCK_MARKER + + :tag: 18 + :length: variable + :field Word32: size + :field Word64: end time in nanoseconds + :field String: marker name + + TODO + +.. event-type:: USER_MSG + + :tag: 19 + :length: variable + :field String: message + + A user log message (from, e.g., :base-ref:`Control.Concurrent.traceEvent`). + +.. event-type:: USER_MARKER + + :tag: 58 + :length: variable + :field String: marker name + + A user marker (from :base-ref:`Debug.Trace.traceMarker`). .. _heap-profiler-events: @@ -28,11 +505,13 @@ Beginning of sample stream A single fixed-width event emitted during program start-up describing the samples that follow. - * ``EVENT_HEAP_PROF_BEGIN`` +.. event-type:: HEAP_PROF_BEGIN - * ``Word8``: Profile ID - * ``Word64``: Sampling period in nanoseconds - * ``Word32``: Sample break-down type. One of, + :tag: 160 + :length: variable + :field Word8: profile ID + :field Word64: sampling period in nanoseconds + :field Word32: sample breadown type. One of, * ``HEAP_PROF_BREAKDOWN_COST_CENTER`` (output from :rts-flag:`-hc`) * ``HEAP_PROF_BREAKDOWN_CLOSURE_DESCR`` (output from :rts-flag:`-hd`) @@ -42,32 +521,34 @@ A single fixed-width event emitted during program start-up describing the sample * ``HEAP_PROF_BREAKDOWN_BIOGRAPHY`` (output from :rts-flag:`-hb`) * ``HEAP_PROF_BREAKDOWN_CLOSURE_TYPE`` (output from :rts-flag:`-hT`) - * ``String``: Module filter - * ``String``: Closure description filter - * ``String``: Type description filter - * ``String``: Cost centre filter - * ``String``: Cost centre stack filter - * ``String``: Retainer filter - * ``String``: Biography filter + :field String: module filter + :field String: closure description filter + :field String: type description filter + :field String: cost centre filter + :field String: cost centre stack filter + :field String: retainer filter + :field String: biography filter Cost centre definitions ^^^^^^^^^^^^^^^^^^^^^^^ A variable-length packet produced once for each cost centre, - * ``EVENT_HEAP_PROF_COST_CENTRE`` +.. event-type:: HEAP_PROF_COST_CENTRE - * ``Word32``: cost centre number - * ``String``: label - * ``String``: module - * ``String``: source location - * ``Word8``: flags + :tag: 161 + :length: fixed + :field Word32: cost centre number + :field String: label + :field String: module + :field String: source location + :field Word8: flags: * bit 0: is the cost-centre a CAF? Sample event types -~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^ A sample (consisting of a list of break-down classes, e.g. cost centres, and heap residency sizes), is to be encoded in the body of one or more events. @@ -75,9 +556,12 @@ heap residency sizes), is to be encoded in the body of one or more events. We normally mark the beginning of a new sample with an ``EVENT_HEAP_PROF_SAMPLE_BEGIN`` event, - * ``EVENT_HEAP_PROF_SAMPLE_BEGIN`` +.. event-type:: HEAP_PROF_SAMPLE_BEGIN + + :length: fixed + :field Word64: sample number - * ``Word64``: sample number + Marks the beginning of a heap profile sample. Biographical profiling samples start with the ``EVENT_HEAP_BIO_PROF_SAMPLE_BEGIN`` event. These events also include a timestamp which indicates when the sample @@ -85,11 +569,12 @@ was taken. This is because all these samples will appear at the end of the eventlog due to how the biographical profiling mode works. You can use the timestamp to reorder the samples relative to the other events. - * ``EVENT_HEAP_BIO_PROF_SAMPLE_BEGIN`` - - * ``Word64``: sample number - * ``Word64``: eventlog timestamp in ns +.. event-type:: HEAP_BIO_PROF_SAMPLE_BEGIN + :tag: 166 + :length: fixed + :field Word64: sample number + :field Word64: eventlog timestamp in ns A heap residency census will follow. Since events may only be up to 2^16^ bytes in length a single sample may need to be split among multiple @@ -101,23 +586,29 @@ emitted. This is useful to properly delimit the sampling period and to record the total time spent profiling. - * ``EVENT_HEAP_PROF_SAMPLE_END`` - * ``Word64``: sample number +.. event-type:: HEAP_PROF_SAMPLE_END + :tag: 165 + :length: fixed + :field Word64: sample number + + Marks the end of a heap profile sample. Cost-centre break-down ^^^^^^^^^^^^^^^^^^^^^^ A variable-length packet encoding a heap profile sample broken down by, - * cost-centre (``-hc``) + * cost-centre (:rts-flag:`-hc`) - * ``EVENT_HEAP_PROF_SAMPLE_COST_CENTRE`` +.. event-type:: HEAP_PROF_SAMPLE_COST_CENTRE - * ``Word8``: Profile ID - * ``Word64``: heap residency in bytes - * ``Word8``: stack depth - * ``Word32[]``: cost centre stack starting with inner-most (cost centre numbers) + :tag: 163 + :length: variable + :field Word8: profile ID + :field Word64: heap residency in bytes + :field Word8: stack depth + :field Word32[]: cost centre stack starting with inner-most (cost centre numbers) String break-down @@ -125,42 +616,142 @@ String break-down A variable-length event encoding a heap sample broken down by, - * type description (``-hy``) - * closure description (``-hd``) - * module (``-hm``) + * type description (:rts-flag:`-hy`) + * closure description (:rts-flag:`-hd`) + * module (:rts-flag:`-hm`) - * ``EVENT_HEAP_PROF_SAMPLE_STRING`` +.. event-type:: HEAP_PROF_SAMPLE_STRING - * ``Word8``: Profile ID - * ``Word64``: heap residency in bytes - * ``String``: type or closure description, or module name + :tag: 164 + :length: variable + :field Word8: profile ID + :field Word64: heap residency in bytes + :field String: type or closure description, or module name .. _time-profiler-events: Time profiler event log output ------------------------------ -The time profiling mode enabled by ``-p`` also emits sample events to the eventlog. -At the start of profiling the tick interval is emitted to the eventlog and then -on each tick the current cost centre stack is emitted. Together these enable -a user to construct an approximate track of the executation of their program. +The time profiling mode enabled by :rts-flag:`-p` also emits +sample events to the eventlog. At the start of profiling the +tick interval is emitted to the eventlog and then on each tick +the current cost centre stack is emitted. Together these +enable a user to construct an approximate track of the +executation of their program. Profile begin event ~~~~~~~~~~~~~~~~~~~ - * ``EVENT_PROF_BEGIN`` +.. event-type:: PROF_BEGIN - * ``Word64``: Tick interval, in nanoseconds + :tag: 168 + :length: fixed + :field Word64: tick interval, in nanoseconds + Marks the beginning of a time profile. -Tick sample event -~~~~~~~~~~~~~~~~~ +Profile sample event +~~~~~~~~~~~~~~~~~~~~ A variable-length packet encoding a profile sample. - * ``EVENT_PROF_SAMPLE_COST_CENTRE`` +.. event-type:: PROF_SAMPLE_COST_CENTRE + + :tag: 167 + :length: variable + :field Word32: capability + :field Word64: current profiling tick + :field Word8: stack depth + :field Word32[]: cost centre stack starting with inner-most (cost centre numbers) + +Biographical profile sample event +--------------------------------- + +A variable-length packet encoding a profile sample. + +.. event-type:: BIO_PROF_SAMPLE_BEGIN + + :tag: 166 + + TODO + +.. _nonmoving-gc-events: + +Non-moving GC event output +-------------------------- + +These events mark various stages of the +:rts-flag:`non-moving collection <--nonmoving-gc>` lifecycle. These are enabled +with the ``+RTS -lg`` event-set. + +.. event-type:: CONC_MARK_BEGIN + + :tag: 200 + :length: fixed + + Marks the beginning of marking by the concurrent collector. + +.. event-type:: CONC_MARK_END + + :tag: 201 + :length: fixed + + Marks the end of marking by the concurrent collector. + +.. event-type:: CONC_SYNC_BEGIN + + :tag: 202 + :length: fixed + + Marks the beginning of the concurrent garbage collector's + post-mark synchronization phase. + +.. event-type:: CONC_SYNC_END + + :tag: 203 + :length: fixed + + Marks the end of the concurrent garbage collector's + post-mark synchronization phase. + +.. event-type:: CONC_SWEEP_BEGIN + + :tag: 204 + :length: fixed + + Marks the beginning of the concurrent garbage collector's + sweep phase. + +.. event-type:: CONC_SWEEP_END + + :tag: 205 + :length: fixed + + Marks the end of the concurrent garbage collector's + sweep phase. + +.. event-type:: CONC_UPD_REM_SET_FLUSH + + :tag: 206 + :length: fixed + + Marks a capability flushing its local update remembered set + accumulator. + +Non-moving heap census +~~~~~~~~~~~~~~~~~~~~~~ + +The non-moving heap census events (enabled with the ``+RTS -ln`` event-set) are +intended to provide insight into fragmentation of the non-moving heap. + +.. event-type:: NONMOVING_HEAP_CENSUS + + :tag: 207 + :length: fixed + :field Word8: base-2 logarithm of *blk_sz*. + :field Word32: number of active segments. + :field Word32: number of filled segments. + :field Word32: number of live blocks. - * ``Word32``: Capability - * ``Word64``: Current profiling tick - * ``Word8``: stack depth - * ``Word32[]``: cost centre stack starting with inner-most (cost centre numbers) + Describes the occupancy of the *blk_sz* sub-heap. ===================================== docs/users_guide/runtime_control.rst ===================================== @@ -1161,6 +1161,10 @@ When the program is linked with the :ghc-flag:`-eventlog` option - ``g`` — GC events, including GC start/stop. Enabled by default. + - ``n`` — non-moving garbage collector (see :rts-flag:`--nonmoving-gc`) + events including start and end of the concurrent mark and census + information to characterise heap fragmentation. Disabled by default. + - ``p`` — parallel sparks (sampled). Enabled by default. - ``f`` — parallel sparks (fully accurate). Disabled by default. @@ -1186,9 +1190,8 @@ When the program is linked with the :ghc-flag:`-eventlog` option accurate mode every spark event is logged individually. The latter has a higher runtime overhead and is not enabled by default. - The format of the log file is described by the header - ``EventLogFormat.h`` that comes with GHC, and it can be parsed in - Haskell using the + The format of the log file is described in this users guide in + :ref:`eventlog-encodings` It can be parsed in Haskell using the `ghc-events `__ library. To dump the contents of a ``.eventlog`` file as text, use the tool ``ghc-events show`` that comes with the ===================================== includes/rts/EventLogFormat.h ===================================== @@ -9,65 +9,25 @@ * of the format, and new tools will be able to understand old log * files. * - * Each event has a specific format. If you add new events, give them - * new numbers: we never re-use old event numbers. - * - * - The format is endian-independent: all values are represented in - * bigendian order. - * - * - The format is extensible: - * - * - The header describes each event type and its length. Tools - * that don't recognise a particular event type can skip those events. - * - * - There is room for extra information in the event type - * specification, which can be ignored by older tools. - * - * - Events can have extra information added, but existing fields - * cannot be changed. Tools should ignore extra fields at the - * end of the event record. - * - * - Old event type ids are never re-used; just take a new identifier. - * - * - * The format - * ---------- - * - * log : EVENT_HEADER_BEGIN - * EventType* - * EVENT_HEADER_END - * EVENT_DATA_BEGIN - * Event* - * EVENT_DATA_END - * - * EventType : - * EVENT_ET_BEGIN - * Word16 -- unique identifier for this event - * Int16 -- >=0 size of the event in bytes (minus the header) - * -- -1 variable size - * Word32 -- length of the next field in bytes - * Word8* -- string describing the event - * Word32 -- length of the next field in bytes - * Word8* -- extra info (for future extensions) - * EVENT_ET_END - * - * Event : - * Word16 -- event_type - * Word64 -- time (nanosecs) - * [Word16] -- length of the rest (for variable-sized events only) - * ... extra event-specific info ... - * + * The canonical documentation for the event log format and record layouts is + * the "Eventlog encodings" section of the GHC User's Guide. * * To add a new event * ------------------ * * - In this file: - * - give it a new number, add a new #define EVENT_XXX below + * - give it a new number, add a new #define EVENT_XXX + * below. Do not reuse event ids from deprecated event types. + * * - In EventLog.c * - add it to the EventDesc array * - emit the event type in initEventLogging() * - emit the new event in postEvent_() * - generate the event itself by calling postEvent() somewhere + * + * - Describe the meaning and encoding of the event in the users guide + * (docs/user_guide/eventlog-formats.rst) + * * - In the Haskell code to parse the event log file: * - add types and code to read the new event * ===================================== rts/RtsFlags.c ===================================== @@ -382,6 +382,7 @@ usage_text[] = { " where [flags] can contain:", " s scheduler events", " g GC and heap events", +" n non-moving GC heap census events", " p par spark events (sampled)", " f par spark events (full detail)", " u user events (emitted from Haskell code)", ===================================== rts/sm/NonMoving.c ===================================== @@ -1125,6 +1125,10 @@ static void nonmovingMark_(MarkQueue *mark_queue, StgWeak **dead_weaks, StgTSO * if (RtsFlags.DebugFlags.nonmoving_gc) nonmovingPrintAllocatorCensus(); #endif +#if defined(TRACING) + if (RtsFlags.TraceFlags.nonmoving_gc) + nonmovingTraceAllocatorCensus(); +#endif // TODO: Remainder of things done by GarbageCollect (update stats) ===================================== testsuite/tests/deSugar/should_compile/T18112.hs ===================================== @@ -0,0 +1,14 @@ +{-# LANGUAGE TypeFamilies #-} +module T18112 where + +type family F a where + F Int = String + +-- This test is really testing the simple optimizer. We expect the +-- optimized desugared output to contain no casts, since the simple +-- optimizer should fuse the two casts together after inlining y. + +blah :: Bool -> String +blah x = let y :: F Int + y = show x + in y ===================================== testsuite/tests/deSugar/should_compile/all.T ===================================== @@ -109,3 +109,4 @@ test('T14773b', normal, compile, ['-Wincomplete-patterns']) test('T14815', [], makefile_test, ['T14815']) test('T13208', [], makefile_test, ['T13208']) test('T16615', normal, compile, ['-ddump-ds -dsuppress-uniques']) +test('T18112', [grep_errmsg('cast')], compile, ['-ddump-ds']) ===================================== testsuite/tests/dependent/should_compile/dynamic-paper.stderr ===================================== @@ -12,4 +12,4 @@ Simplifier ticks exhausted simplifier non-termination has been judged acceptable. To see detailed counts use -ddump-simpl-stats - Total ticks: 140084 + Total ticks: 138082 ===================================== testsuite/tests/parser/should_compile/T18130.hs ===================================== @@ -0,0 +1,20 @@ +{-# Language DerivingVia #-} +{-# Language KindSignatures #-} + +module T18130 where + +import Data.Functor.Classes +import Data.Kind + +newtype Par a b = Par (a, b) + deriving Eq + via (a, b) + :: Type + + deriving Eq1 + via (,) a + :: Type -> Type + + deriving Eq2 + via (,) + :: Type -> Type -> Type ===================================== testsuite/tests/parser/should_compile/all.T ===================================== @@ -166,3 +166,4 @@ test('proposal-229f', multimod_compile_and_run, ['proposal-229f.hs', '']) test('T15730a', normal, compile_and_run, ['']) +test('T18130', normal, compile, ['']) ===================================== testsuite/tests/parser/should_fail/T18130Fail.hs ===================================== @@ -0,0 +1,20 @@ +{-# Language DerivingVia #-} +{-# Language KindSignatures #-} + +module T18130Fail where + +import Data.Functor.Classes +import Data.Kind + +newtype Par a b = Par (a, b) + deriving Eq + via (a, b) + :: Type -> Type + + deriving Eq1 + via (,) a + :: Type -> Type + + deriving Eq2 + via (,) + :: Type -> Type -> Type ===================================== testsuite/tests/parser/should_fail/T18130Fail.stderr ===================================== @@ -0,0 +1,4 @@ + +T18130Fail.hs:11:7: error: + • Expected kind ‘* -> *’, but ‘(a, b)’ has kind ‘*’ + • In the newtype declaration for ‘Par’ ===================================== testsuite/tests/parser/should_fail/all.T ===================================== @@ -166,3 +166,4 @@ test('T17162', normal, compile_fail, ['']) test('proposal-229c', normal, compile_fail, ['']) test('T15730', normal, compile_fail, ['']) test('T15730b', normal, compile_fail, ['']) +test('T18130Fail', normal, compile_fail, ['']) ===================================== testsuite/tests/th/T18121.hs ===================================== @@ -0,0 +1,7 @@ +{-# LANGUAGE TemplateHaskell #-} +module Bug where + +import Language.Haskell.TH + +sapply :: Q (TExp (a -> b)) -> Q (TExp a) -> Q (TExp b) +sapply cf cx = [|| $$cf $$cx ||] ===================================== testsuite/tests/th/all.T ===================================== @@ -506,3 +506,4 @@ test('T18097', normal, compile, ['']) test('TH_PprStar', normal, compile, ['-v0 -dsuppress-uniques']) test('TH_StringLift', normal, compile, ['']) test('TH_BytesShowEqOrd', normal, compile_and_run, ['']) +test('T18121', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a9b306d88eb6ea86a7cb7fbcf31f70e8c75b5a54...1c49d150404bef958110dd7167cb6131f550c88a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a9b306d88eb6ea86a7cb7fbcf31f70e8c75b5a54...1c49d150404bef958110dd7167cb6131f550c88a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 4 05:57:08 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Mon, 04 May 2020 01:57:08 -0400 Subject: [Git][ghc/ghc][master] Don't return a panic in tcNestedSplice Message-ID: <5eafaeb4960b2_6167e11371886137a3@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 8bdc03d6 by Simon Peyton Jones at 2020-05-04T01:56:59-04:00 Don't return a panic in tcNestedSplice In GHC.Tc.Gen.Splice.tcNestedSplice we were returning a typechecked expression of "panic". That is usually OK, because the result is discarded. But it happens that tcApp now looks at the typechecked expression, trivially, to ask if it is tagToEnum. So being bottom is bad. Moreover a debug-trace might print it out. So better to return a civilised expression, even though it is usually discarded. - - - - - 4 changed files: - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Splice.hs - + testsuite/tests/th/T18121.hs - testsuite/tests/th/all.T Changes: ===================================== compiler/GHC/Tc/Gen/Expr.hs ===================================== @@ -981,12 +981,9 @@ tcExpr (HsSpliceE _ (HsSpliced _ mod_finalizers (HsSplicedExpr expr))) res_ty = do addModFinalizersWithLclEnv mod_finalizers tcExpr expr res_ty -tcExpr (HsSpliceE _ splice) res_ty - = tcSpliceExpr splice res_ty -tcExpr e@(HsBracket _ brack) res_ty - = tcTypedBracket e brack res_ty -tcExpr e@(HsRnBracketOut _ brack ps) res_ty - = tcUntypedBracket e brack ps res_ty +tcExpr (HsSpliceE _ splice) res_ty = tcSpliceExpr splice res_ty +tcExpr e@(HsBracket _ brack) res_ty = tcTypedBracket e brack res_ty +tcExpr e@(HsRnBracketOut _ brack ps) res_ty = tcUntypedBracket e brack ps res_ty {- ************************************************************************ @@ -1219,7 +1216,11 @@ tcApp expr res_ty = do { (fun, args, app_res_ty) <- tcInferApp expr ; if isTagToEnum fun then tcTagToEnum expr fun args app_res_ty res_ty - else -- The wildly common case + -- Done here because we have res_ty, + -- whereas tcInferApp does not + else + + -- The wildly common case do { let expr' = applyHsArgs fun args ; addFunResCtxt True fun app_res_ty res_ty $ tcWrapResult expr expr' app_res_ty res_ty } } @@ -1232,10 +1233,10 @@ tcInferApp :: HsExpr GhcRn -- Also used by Module.tcRnExpr to implement GHCi :type tcInferApp expr | -- Gruesome special case for ambiguous record selectors - HsRecFld _ fld_lbl <- fun - , Ambiguous _ lbl <- fld_lbl -- Still ambiguous + HsRecFld _ fld_lbl <- fun + , Ambiguous _ lbl <- fld_lbl -- Still ambiguous , HsEValArg _ (L _ arg) : _ <- filterOut isArgPar args -- A value arg is first - , Just sig_ty <- obviousSig arg -- A type sig on the arg disambiguates + , Just sig_ty <- obviousSig arg -- A type sig on the arg disambiguates = do { sig_tc_ty <- tcHsSigWcType ExprSigCtxt sig_ty ; sel_name <- disambiguateSelector lbl sig_tc_ty ; (tc_fun, fun_ty) <- tcInferRecSelId (Unambiguous sel_name lbl) @@ -1259,11 +1260,7 @@ tcInferApp_finish -> TcM (HsExpr GhcTc, [LHsExprArgOut], TcSigmaType) tcInferApp_finish rn_fun tc_fun fun_sigma rn_args - = do { traceTc "tcInferApp_finish" $ - vcat [ ppr rn_fun <+> dcolon <+> ppr fun_sigma, ppr rn_args ] - - ; (tc_args, actual_res_ty) <- tcArgs rn_fun fun_sigma rn_args - + = do { (tc_args, actual_res_ty) <- tcArgs rn_fun fun_sigma rn_args ; return (tc_fun, tc_args, actual_res_ty) } mk_op_msg :: LHsExpr GhcRn -> SDoc ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -625,7 +625,13 @@ tcNestedSplice pop_stage (TcPending ps_var lie_var q@(QuoteWrapper _ m_var)) spl ; writeMutVar ps_var (PendingTcSplice splice_name expr'' : ps) -- The returned expression is ignored; it's in the pending splices - ; return (panic "tcSpliceExpr") } + -- But we still return a plausible expression + -- (a) in case we print it in debug messages, and + -- (b) because we test whether it is tagToEnum in Tc.Gen.Expr.tcApp + ; return (HsSpliceE noExtField $ + HsSpliced noExtField (ThModFinalizers []) $ + HsSplicedExpr (unLoc expr'')) } + tcNestedSplice _ _ splice_name _ _ = pprPanic "tcNestedSplice: rename stage found" (ppr splice_name) ===================================== testsuite/tests/th/T18121.hs ===================================== @@ -0,0 +1,7 @@ +{-# LANGUAGE TemplateHaskell #-} +module Bug where + +import Language.Haskell.TH + +sapply :: Q (TExp (a -> b)) -> Q (TExp a) -> Q (TExp b) +sapply cf cx = [|| $$cf $$cx ||] ===================================== testsuite/tests/th/all.T ===================================== @@ -506,3 +506,4 @@ test('T18097', normal, compile, ['']) test('TH_PprStar', normal, compile, ['-v0 -dsuppress-uniques']) test('TH_StringLift', normal, compile, ['']) test('TH_BytesShowEqOrd', normal, compile_and_run, ['']) +test('T18121', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8bdc03d61cb7a2f96887c86bd0b253f7c108fcde -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8bdc03d61cb7a2f96887c86bd0b253f7c108fcde You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 4 05:57:47 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Mon, 04 May 2020 01:57:47 -0400 Subject: [Git][ghc/ghc][master] Don't require parentheses around via type (`-XDerivingVia'). Fixes #18130". Message-ID: <5eafaedb71ded_61673f81a47933c0861783d@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 0bf640b1 by Baldur Blöndal at 2020-05-04T01:57:36-04:00 Don't require parentheses around via type (`-XDerivingVia'). Fixes #18130". - - - - - 6 changed files: - compiler/GHC/Parser.y - + testsuite/tests/parser/should_compile/T18130.hs - testsuite/tests/parser/should_compile/all.T - + testsuite/tests/parser/should_fail/T18130Fail.hs - + testsuite/tests/parser/should_fail/T18130Fail.stderr - testsuite/tests/parser/should_fail/all.T Changes: ===================================== compiler/GHC/Parser.y ===================================== @@ -1209,8 +1209,8 @@ deriv_strategy_no_via :: { LDerivStrategy GhcPs } [mj AnnNewtype $1] } deriv_strategy_via :: { LDerivStrategy GhcPs } - : 'via' type {% ams (sLL $1 $> (ViaStrategy (mkLHsSigType $2))) - [mj AnnVia $1] } + : 'via' ktype {% ams (sLL $1 $> (ViaStrategy (mkLHsSigType $2))) + [mj AnnVia $1] } deriv_standalone_strategy :: { Maybe (LDerivStrategy GhcPs) } : 'stock' {% ajs (sL1 $1 StockStrategy) ===================================== testsuite/tests/parser/should_compile/T18130.hs ===================================== @@ -0,0 +1,20 @@ +{-# Language DerivingVia #-} +{-# Language KindSignatures #-} + +module T18130 where + +import Data.Functor.Classes +import Data.Kind + +newtype Par a b = Par (a, b) + deriving Eq + via (a, b) + :: Type + + deriving Eq1 + via (,) a + :: Type -> Type + + deriving Eq2 + via (,) + :: Type -> Type -> Type ===================================== testsuite/tests/parser/should_compile/all.T ===================================== @@ -166,3 +166,4 @@ test('proposal-229f', multimod_compile_and_run, ['proposal-229f.hs', '']) test('T15730a', normal, compile_and_run, ['']) +test('T18130', normal, compile, ['']) ===================================== testsuite/tests/parser/should_fail/T18130Fail.hs ===================================== @@ -0,0 +1,20 @@ +{-# Language DerivingVia #-} +{-# Language KindSignatures #-} + +module T18130Fail where + +import Data.Functor.Classes +import Data.Kind + +newtype Par a b = Par (a, b) + deriving Eq + via (a, b) + :: Type -> Type + + deriving Eq1 + via (,) a + :: Type -> Type + + deriving Eq2 + via (,) + :: Type -> Type -> Type ===================================== testsuite/tests/parser/should_fail/T18130Fail.stderr ===================================== @@ -0,0 +1,4 @@ + +T18130Fail.hs:11:7: error: + • Expected kind ‘* -> *’, but ‘(a, b)’ has kind ‘*’ + • In the newtype declaration for ‘Par’ ===================================== testsuite/tests/parser/should_fail/all.T ===================================== @@ -166,3 +166,4 @@ test('T17162', normal, compile_fail, ['']) test('proposal-229c', normal, compile_fail, ['']) test('T15730', normal, compile_fail, ['']) test('T15730b', normal, compile_fail, ['']) +test('T18130Fail', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0bf640b19d7a7ad0800152752a71c1dd4e6c696d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0bf640b19d7a7ad0800152752a71c1dd4e6c696d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 4 07:59:44 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Mon, 04 May 2020 03:59:44 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 4 commits: Don't return a panic in tcNestedSplice Message-ID: <5eafcb7015366_6167e1137188623774@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 8bdc03d6 by Simon Peyton Jones at 2020-05-04T01:56:59-04:00 Don't return a panic in tcNestedSplice In GHC.Tc.Gen.Splice.tcNestedSplice we were returning a typechecked expression of "panic". That is usually OK, because the result is discarded. But it happens that tcApp now looks at the typechecked expression, trivially, to ask if it is tagToEnum. So being bottom is bad. Moreover a debug-trace might print it out. So better to return a civilised expression, even though it is usually discarded. - - - - - 0bf640b1 by Baldur Blöndal at 2020-05-04T01:57:36-04:00 Don't require parentheses around via type (`-XDerivingVia'). Fixes #18130". - - - - - 436732ca by Artem Pelenitsyn at 2020-05-04T03:59:34-04:00 Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) - - - - - 8f0e7941 by jneira at 2020-05-04T03:59:36-04:00 Remove unused hs-boot file - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Data/IOEnv.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Monad.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Types.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Parser.y - compiler/GHC/Runtime/Debugger.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Linker.hs - compiler/GHC/SysTools/FileCleanup.hs - compiler/GHC/SysTools/Tasks.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Splice.hs - − compiler/GHC/Unit/Module/Env.hs-boot - compiler/GHC/Utils/Error.hs - compiler/GHC/Utils/Exception.hs - compiler/GHC/Utils/Panic.hs - compiler/ghc.cabal.in - docs/users_guide/8.12.1-notes.rst - ghc.mk - ghc/GHCi/UI.hs - ghc/GHCi/UI/Info.hs - ghc/GHCi/UI/Monad.hs - hadrian/src/Settings/Default.hs - testsuite/tests/ghc-api/Makefile - testsuite/tests/ghc-api/T8628.hs - testsuite/tests/ghc-api/downsweep/PartialDownsweep.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1c49d150404bef958110dd7167cb6131f550c88a...8f0e7941771a1ea19f41372a47116fe9a57958cb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1c49d150404bef958110dd7167cb6131f550c88a...8f0e7941771a1ea19f41372a47116fe9a57958cb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 4 10:21:37 2020 From: gitlab at gitlab.haskell.org (Richard Eisenberg) Date: Mon, 04 May 2020 06:21:37 -0400 Subject: [Git][ghc/ghc][wip/hole-refactor] Refactor hole constraints. Message-ID: <5eafecb1490b5_61673f81cd4c695c8641661@gitlab.haskell.org.mail> Richard Eisenberg pushed to branch wip/hole-refactor at Glasgow Haskell Compiler / GHC Commits: 3f4aaac6 by Richard Eisenberg at 2020-05-04T11:20:23+01:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG ------------------------- - - - - - 23 changed files: - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/Plugins.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Errors/Hole.hs-boot - compiler/GHC/Tc/Errors/Hole/FitTypes.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Rule.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/Solver/Canonical.hs - compiler/GHC/Tc/Solver/Flatten.hs - compiler/GHC/Tc/Solver/Interact.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Types/Constraint.hs - compiler/GHC/Tc/Types/Origin.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Tc/Utils/TcMType.hs - testsuite/tests/partial-sigs/should_compile/SplicesUsed.stderr - testsuite/tests/plugins/hole-fit-plugin/HoleFitPlugin.hs - testsuite/tests/th/T12411.stderr - testsuite/tests/typecheck/should_fail/T12589.stderr Changes: ===================================== compiler/GHC/HsToCore/PmCheck/Oracle.hs ===================================== @@ -438,7 +438,7 @@ then newtypes. (b) dcs is the list of newtype constructors "skipped", every time we normalise a newtype to its core representation, we keep track of the source data - constructor. For convenienve, we also track the type we unwrap and the + constructor. For convenience, we also track the type we unwrap and the type of its field. Example: @Down 42@ => @[(Down @Int, Down, Int)] (c) core_ty is the rewritten type. That is, pmTopNormaliseType env ty_cs ty = Just (src_ty, dcs, core_ty) ===================================== compiler/GHC/Plugins.hs ===================================== @@ -48,6 +48,7 @@ module GHC.Plugins , module GHC.Utils.Outputable , module GHC.Types.Unique.Supply , module GHC.Data.FastString + , module GHC.Tc.Errors.Hole.FitTypes -- for hole-fit plugins , -- * Getting 'Name's thNameToGhcName ) @@ -121,6 +122,8 @@ import GHC.Utils.Monad ( mapMaybeM ) import GHC.ThToHs ( thRdrNameGuesses ) import GHC.Tc.Utils.Env ( lookupGlobal ) +import GHC.Tc.Errors.Hole.FitTypes + import qualified Language.Haskell.TH as TH {- This instance is defined outside GHC.Core.Opt.Monad.hs so that ===================================== compiler/GHC/Tc/Errors.hs ===================================== @@ -285,8 +285,8 @@ important :: SDoc -> Report important doc = mempty { report_important = [doc] } -- | Put a doc into the relevant bindings block. -relevant_bindings :: SDoc -> Report -relevant_bindings doc = mempty { report_relevant_bindings = [doc] } +mk_relevant_bindings :: SDoc -> Report +mk_relevant_bindings doc = mempty { report_relevant_bindings = [doc] } -- | Put a doc into the valid hole fits block. valid_hole_fits :: SDoc -> Report @@ -524,16 +524,29 @@ This only matters in instance declarations.. -} reportWanteds :: ReportErrCtxt -> TcLevel -> WantedConstraints -> TcM () -reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) +reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics + , wc_holes = holes }) = do { traceTc "reportWanteds" (vcat [ text "Simples =" <+> ppr simples - , text "Suppress =" <+> ppr (cec_suppress ctxt)]) - ; traceTc "rw2" (ppr tidy_cts) - - -- First deal with things that are utterly wrong + , text "Suppress =" <+> ppr (cec_suppress ctxt) + , text "tidy_cts =" <+> ppr tidy_cts + , text "tidy_holes = " <+> ppr tidy_holes ]) + + -- First, deal with any out-of-scope errors: + ; let (out_of_scope, other_holes) = partition isOutOfScopeHole tidy_holes + -- don't suppress out-of-scope errors + ctxt_for_scope_errs = ctxt { cec_suppress = False } + ; (_, no_out_of_scope) <- askNoErrs $ + reportHoles tidy_cts ctxt_for_scope_errs out_of_scope + + -- Next, deal with things that are utterly wrong -- Like Int ~ Bool (incl nullary TyCons) -- or Int ~ t a (AppTy on one side) -- These /ones/ are not suppressed by the incoming context - ; let ctxt_for_insols = ctxt { cec_suppress = False } + -- (but will be by out-of-scope errors) + ; let ctxt_for_insols = ctxt { cec_suppress = not no_out_of_scope } + ; reportHoles tidy_cts ctxt_for_insols other_holes + -- holes never suppress + ; (ctxt1, cts1) <- tryReporters ctxt_for_insols report1 tidy_cts -- Now all the other constraints. We suppress errors here if @@ -554,7 +567,8 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) -- if there's a *given* insoluble here (= inaccessible code) where env = cec_tidy ctxt - tidy_cts = bagToList (mapBag (tidyCt env) simples) + tidy_cts = bagToList (mapBag (tidyCt env) simples) + tidy_holes = bagToList (mapBag (tidyHole env) holes) -- report1: ones that should *not* be suppressed by -- an insoluble somewhere else in the tree @@ -562,9 +576,7 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) -- (see GHC.Tc.Utils.insolubleCt) is caught here, otherwise -- we might suppress its error message, and proceed on past -- type checking to get a Lint error later - report1 = [ ("Out of scope", unblocked is_out_of_scope, True, mkHoleReporter tidy_cts) - , ("Holes", unblocked is_hole, False, mkHoleReporter tidy_cts) - , ("custom_error", unblocked is_user_type_error, True, mkUserTypeErrorReporter) + report1 = [ ("custom_error", unblocked is_user_type_error, True, mkUserTypeErrorReporter) , given_eq_spec , ("insoluble2", unblocked utterly_wrong, True, mkGroupReporter mkEqErr) @@ -593,8 +605,7 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) unblocked checker ct pred = checker ct pred -- rigid_nom_eq, rigid_nom_tv_eq, - is_hole, is_dict, - is_equality, is_ip, is_irred :: Ct -> Pred -> Bool + is_dict, is_equality, is_ip, is_irred :: Ct -> Pred -> Bool is_given_eq ct pred | EqPred {} <- pred = arisesFromGivens ct @@ -617,9 +628,6 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) non_tv_eq _ (EqPred NomEq ty1 _) = not (isTyVarTy ty1) non_tv_eq _ _ = False - is_out_of_scope ct _ = isOutOfScopeCt ct - is_hole ct _ = isHoleCt ct - is_user_type_error ct _ = isUserTypeErrorCt ct is_homo_equality _ (EqPred _ ty1 ty2) = tcTypeKind ty1 `tcEqType` tcTypeKind ty2 @@ -705,12 +713,12 @@ mkSkolReporter ctxt cts | eq_lhs_type ct1 ct2 = True | otherwise = False -mkHoleReporter :: [Ct] -> Reporter --- Reports errors one at a time -mkHoleReporter tidy_simples ctxt - = mapM_ $ \ct -> do { err <- mkHoleError tidy_simples ctxt ct - ; maybeReportHoleError ctxt ct err - ; maybeAddDeferredHoleBinding ctxt err ct } +reportHoles :: [Ct] -- other (tidied) constraints + -> ReportErrCtxt -> [Hole] -> TcM () +reportHoles tidy_cts ctxt + = mapM_ $ \hole -> do { err <- mkHoleError tidy_cts ctxt hole + ; maybeReportHoleError ctxt hole err + ; maybeAddDeferredHoleBinding ctxt err hole } mkUserTypeErrorReporter :: Reporter mkUserTypeErrorReporter ctxt @@ -742,7 +750,7 @@ mkGivenErrorReporter ctxt cts inaccessible_msg = hang (text "Inaccessible code in") 2 (ppr (ic_info implic)) report = important inaccessible_msg `mappend` - relevant_bindings binds_msg + mk_relevant_bindings binds_msg ; err <- mkEqErr_help dflags ctxt report ct' Nothing ty1 ty2 @@ -843,15 +851,27 @@ suppressGroup mk_err ctxt cts ; traceTc "Suppressing errors for" (ppr cts) ; mapM_ (addDeferredBinding ctxt err) cts } -maybeReportHoleError :: ReportErrCtxt -> Ct -> ErrMsg -> TcM () +maybeReportHoleError :: ReportErrCtxt -> Hole -> ErrMsg -> TcM () +maybeReportHoleError ctxt hole err + | isOutOfScopeHole hole + -- Always report an error for out-of-scope variables + -- Unless -fdefer-out-of-scope-variables is on, + -- in which case the messages are discarded. + -- See #12170, #12406 + = -- If deferring, report a warning only if -Wout-of-scope-variables is on + case cec_out_of_scope_holes ctxt of + HoleError -> reportError err + HoleWarn -> + reportWarning (Reason Opt_WarnDeferredOutOfScopeVariables) err + HoleDefer -> return () + -- Unlike maybeReportError, these "hole" errors are -- /not/ suppressed by cec_suppress. We want to see them! -maybeReportHoleError ctxt ct err +maybeReportHoleError ctxt (Hole { hole_sort = TypeHole }) err -- When -XPartialTypeSignatures is on, warnings (instead of errors) are -- generated for holes in partial type signatures. -- Unless -fwarn-partial-type-signatures is not on, -- in which case the messages are discarded. - | isTypeHoleCt ct = -- For partial type signatures, generate warnings only, and do that -- only if -fwarn-partial-type-signatures is on case cec_type_holes ctxt of @@ -859,22 +879,12 @@ maybeReportHoleError ctxt ct err HoleWarn -> reportWarning (Reason Opt_WarnPartialTypeSignatures) err HoleDefer -> return () - -- Always report an error for out-of-scope variables - -- Unless -fdefer-out-of-scope-variables is on, - -- in which case the messages are discarded. - -- See #12170, #12406 - | isOutOfScopeCt ct - = -- If deferring, report a warning only if -Wout-of-scope-variables is on - case cec_out_of_scope_holes ctxt of - HoleError -> reportError err - HoleWarn -> - reportWarning (Reason Opt_WarnDeferredOutOfScopeVariables) err - HoleDefer -> return () - +maybeReportHoleError ctxt hole@(Hole { hole_sort = ExprHole _ }) err -- Otherwise this is a typed hole in an expression, - -- but not for an out-of-scope variable - | otherwise + -- but not for an out-of-scope variable (because that goes through a + -- different function) = -- If deferring, report a warning only if -Wtyped-holes is on + ASSERT( not (isOutOfScopeHole hole) ) case cec_expr_holes ctxt of HoleError -> reportError err HoleWarn -> reportWarning (Reason Opt_WarnTypedHoles) err @@ -899,10 +909,7 @@ addDeferredBinding ctxt err ct , CtWanted { ctev_pred = pred, ctev_dest = dest } <- ctEvidence ct -- Only add deferred bindings for Wanted constraints = do { dflags <- getDynFlags - ; let err_msg = pprLocErrMsg err - err_fs = mkFastString $ showSDoc dflags $ - err_msg $$ text "(deferred type error)" - err_tm = evDelayedError pred err_fs + ; let err_tm = mkErrorTerm dflags pred err ev_binds_var = cec_binds ctxt ; case dest of @@ -917,11 +924,27 @@ addDeferredBinding ctxt err ct | otherwise -- Do not set any evidence for Given/Derived = return () -maybeAddDeferredHoleBinding :: ReportErrCtxt -> ErrMsg -> Ct -> TcM () -maybeAddDeferredHoleBinding ctxt err ct - | isExprHoleCt ct - = addDeferredBinding ctxt err ct -- Only add bindings for holes in expressions - | otherwise -- not for holes in partial type signatures +mkErrorTerm :: DynFlags -> Type -- of the error term + -> ErrMsg -> EvTerm +mkErrorTerm dflags ty err = evDelayedError ty err_fs + where + err_msg = pprLocErrMsg err + err_fs = mkFastString $ showSDoc dflags $ + err_msg $$ text "(deferred type error)" +maybeAddDeferredHoleBinding :: ReportErrCtxt -> ErrMsg -> Hole -> TcM () +maybeAddDeferredHoleBinding ctxt err (Hole { hole_sort = ExprHole ev_id }) +-- Only add bindings for holes in expressions +-- not for holes in partial type signatures +-- cf. addDeferredBinding + | deferringAnyBindings ctxt + = do { dflags <- getDynFlags + ; let err_tm = mkErrorTerm dflags (idType ev_id) err + -- NB: idType ev_id, not hole_ty. hole_ty might be rewritten. + -- See Note [Holes] in GHC.Tc.Types.Constraint + ; addTcEvBind (cec_binds ctxt) $ mkWantedEvBind ev_id err_tm } + | otherwise + = return () +maybeAddDeferredHoleBinding _ _ (Hole { hole_sort = TypeHole }) = return () tryReporters :: ReportErrCtxt -> [ReporterSpec] -> [Ct] -> TcM (ReportErrCtxt, [Ct]) @@ -961,7 +984,6 @@ tryReporter ctxt (str, keep_me, suppress_after, reporter) cts where (yeses, nos) = partition (\ct -> keep_me ct (classifyPredType (ctPred ct))) cts - pprArising :: CtOrigin -> SDoc -- Used for the main, top-level error message -- We've done special processing for TypeEq, KindEq, Given @@ -1104,15 +1126,16 @@ mkIrredErr ctxt cts ; let orig = ctOrigin ct1 msg = couldNotDeduce (getUserGivens ctxt) (map ctPred cts, orig) ; mkErrorMsgFromCt ctxt ct1 $ - important msg `mappend` relevant_bindings binds_msg } + important msg `mappend` mk_relevant_bindings binds_msg } where (ct1:_) = cts ---------------- -mkHoleError :: [Ct] -> ReportErrCtxt -> Ct -> TcM ErrMsg -mkHoleError tidy_simples ctxt ct@(CHoleCan { cc_occ = occ, cc_hole = hole_sort }) - | isOutOfScopeCt ct -- Out of scope variables, like 'a', where 'a' isn't bound - -- Suggest possible in-scope variables in the message +mkHoleError :: [Ct] -> ReportErrCtxt -> Hole -> TcM ErrMsg +mkHoleError _tidy_simples _ctxt hole@(Hole { hole_occ = occ + , hole_ty = hole_ty + , hole_loc = ct_loc }) + | isOutOfScopeHole hole = do { dflags <- getDynFlags ; rdr_env <- getGlobalRdrEnv ; imp_info <- getImports @@ -1122,48 +1145,52 @@ mkHoleError tidy_simples ctxt ct@(CHoleCan { cc_occ = occ, cc_hole = hole_sort } errDoc [out_of_scope_msg] [] [unknownNameSuggestions dflags hpt curr_mod rdr_env (tcl_rdr lcl_env) imp_info (mkRdrUnqual occ)] } + where + herald | isDataOcc occ = text "Data constructor not in scope:" + | otherwise = text "Variable not in scope:" - | otherwise -- Explicit holes, like "_" or "_f" - = do { (ctxt, binds_msg, ct) <- relevantBindings False ctxt ct + out_of_scope_msg -- Print v :: ty only if the type has structure + | boring_type = hang herald 2 (ppr occ) + | otherwise = hang herald 2 (pp_occ_with_type occ hole_ty) + + lcl_env = ctLocEnv ct_loc + boring_type = isTyVarTy hole_ty + + -- general case: not an out-of-scope error +mkHoleError tidy_simples ctxt hole@(Hole { hole_occ = occ + , hole_ty = hole_ty + , hole_sort = sort + , hole_loc = ct_loc }) + = do { (ctxt, binds_msg) + <- relevant_bindings False ctxt lcl_env (tyCoVarsOfType hole_ty) -- The 'False' means "don't filter the bindings"; see Trac #8191 ; show_hole_constraints <- goptM Opt_ShowHoleConstraints ; let constraints_msg - | isExprHoleCt ct, show_hole_constraints + | ExprHole _ <- sort, show_hole_constraints = givenConstraintsMsg ctxt | otherwise = empty ; show_valid_hole_fits <- goptM Opt_ShowValidHoleFits ; (ctxt, sub_msg) <- if show_valid_hole_fits - then validHoleFits ctxt tidy_simples ct + then validHoleFits ctxt tidy_simples hole else return (ctxt, empty) - ; mkErrorMsgFromCt ctxt ct $ + ; mkErrorReport ctxt lcl_env $ important hole_msg `mappend` - relevant_bindings (binds_msg $$ constraints_msg) `mappend` + mk_relevant_bindings (binds_msg $$ constraints_msg) `mappend` valid_hole_fits sub_msg } where - ct_loc = ctLoc ct lcl_env = ctLocEnv ct_loc - hole_ty = ctEvPred (ctEvidence ct) hole_kind = tcTypeKind hole_ty tyvars = tyCoVarsOfTypeList hole_ty - boring_type = isTyVarTy hole_ty - - out_of_scope_msg -- Print v :: ty only if the type has structure - | boring_type = hang herald 2 (ppr occ) - | otherwise = hang herald 2 pp_with_type - pp_with_type = hang (pprPrefixOcc occ) 2 (dcolon <+> pprType hole_ty) - herald | isDataOcc occ = text "Data constructor not in scope:" - | otherwise = text "Variable not in scope:" - - hole_msg = case hole_sort of - ExprHole -> vcat [ hang (text "Found hole:") - 2 pp_with_type - , tyvars_msg, expr_hole_hint ] + hole_msg = case sort of + ExprHole _ -> vcat [ hang (text "Found hole:") + 2 (pp_occ_with_type occ hole_ty) + , tyvars_msg, expr_hole_hint ] TypeHole -> vcat [ hang (text "Found type wildcard" <+> quotes (ppr occ)) 2 (text "standing for" <+> quotes pp_hole_type_with_kind) , tyvars_msg, type_hole_hint ] @@ -1207,21 +1234,22 @@ mkHoleError tidy_simples ctxt ct@(CHoleCan { cc_occ = occ, cc_hole = hole_sort } = ppWhenOption sdocPrintExplicitCoercions $ quotes (ppr tv) <+> text "is a coercion variable" -mkHoleError _ _ ct = pprPanic "mkHoleError" (ppr ct) +pp_occ_with_type :: OccName -> Type -> SDoc +pp_occ_with_type occ hole_ty = hang (pprPrefixOcc occ) 2 (dcolon <+> pprType hole_ty) -- We unwrap the ReportErrCtxt here, to avoid introducing a loop in module -- imports validHoleFits :: ReportErrCtxt -- The context we're in, i.e. the -- implications and the tidy environment -> [Ct] -- Unsolved simple constraints - -> Ct -- The hole constraint. + -> Hole -- The hole -> TcM (ReportErrCtxt, SDoc) -- We return the new context -- with a possibly updated -- tidy environment, and -- the message. validHoleFits ctxt@(CEC {cec_encl = implics - , cec_tidy = lcl_env}) simps ct - = do { (tidy_env, msg) <- findValidHoleFits lcl_env implics simps ct + , cec_tidy = lcl_env}) simps hole + = do { (tidy_env, msg) <- findValidHoleFits lcl_env implics simps hole ; return (ctxt {cec_tidy = tidy_env}, msg) } -- See Note [Constraints include ...] @@ -1255,7 +1283,7 @@ mkIPErr ctxt cts = couldNotDeduce givens (preds, orig) ; mkErrorMsgFromCt ctxt ct1 $ - important msg `mappend` relevant_bindings binds_msg } + important msg `mappend` mk_relevant_bindings binds_msg } where (ct1:_) = cts @@ -1337,7 +1365,7 @@ mkEqErr1 ctxt ct -- Wanted or derived; ; dflags <- getDynFlags ; traceTc "mkEqErr1" (ppr ct $$ pprCtOrigin (ctOrigin ct) $$ ppr keep_going) ; let report = mconcat [important wanted_msg, important coercible_msg, - relevant_bindings binds_msg] + mk_relevant_bindings binds_msg] ; if keep_going then mkEqErr_help dflags ctxt report ct is_oriented ty1 ty2 else mkErrorMsgFromCt ctxt ct report } @@ -1513,7 +1541,7 @@ mkTyVarEqErr' dflags ctxt report ct oriented tv1 ty2 filter isTyVar $ fvVarList $ tyCoFVsOfType ty1 `unionFV` tyCoFVsOfType ty2 - extra3 = relevant_bindings $ + extra3 = mk_relevant_bindings $ ppWhen (not (null interesting_tyvars)) $ hang (text "Type variable kinds:") 2 $ vcat (map (tyvar_binding . tidyTyCoVarOcc (cec_tidy ctxt)) @@ -2819,27 +2847,45 @@ relevantBindings :: Bool -- True <=> filter by tyvar; False <=> no filtering -> TcM (ReportErrCtxt, SDoc, Ct) -- Also returns the zonked and tidied CtOrigin of the constraint relevantBindings want_filtering ctxt ct - = do { dflags <- getDynFlags + = do { traceTc "relevantBindings" (ppr ct) ; (env1, tidy_orig) <- zonkTidyOrigin (cec_tidy ctxt) (ctLocOrigin loc) - ; let ct_tvs = tyCoVarsOfCt ct `unionVarSet` extra_tvs -- For *kind* errors, report the relevant bindings of the -- enclosing *type* equality, because that's more useful for the programmer - extra_tvs = case tidy_orig of + ; let extra_tvs = case tidy_orig of KindEqOrigin t1 m_t2 _ _ -> tyCoVarsOfTypes $ t1 : maybeToList m_t2 _ -> emptyVarSet - ; traceTc "relevantBindings" $ - vcat [ ppr ct - , pprCtOrigin (ctLocOrigin loc) - , ppr ct_tvs + ct_fvs = tyCoVarsOfCt ct `unionVarSet` extra_tvs + + -- Put a zonked, tidied CtOrigin into the Ct + loc' = setCtLocOrigin loc tidy_orig + ct' = setCtLoc ct loc' + ctxt1 = ctxt { cec_tidy = env1 } + + ; (ctxt2, doc) <- relevant_bindings want_filtering ctxt1 lcl_env ct_fvs + ; return (ctxt2, doc, ct') } + where + loc = ctLoc ct + lcl_env = ctLocEnv loc + +-- slightly more general version, to work also with holes +relevant_bindings :: Bool + -> ReportErrCtxt + -> TcLclEnv + -> TyCoVarSet + -> TcM (ReportErrCtxt, SDoc) +relevant_bindings want_filtering ctxt lcl_env ct_tvs + = do { dflags <- getDynFlags + ; traceTc "relevant_bindings" $ + vcat [ ppr ct_tvs , pprWithCommas id [ ppr id <+> dcolon <+> ppr (idType id) | TcIdBndr id _ <- tcl_bndrs lcl_env ] , pprWithCommas id [ ppr id | TcIdBndr_ExpType id _ _ <- tcl_bndrs lcl_env ] ] ; (tidy_env', docs, discards) - <- go dflags env1 ct_tvs (maxRelevantBinds dflags) + <- go dflags (cec_tidy ctxt) (maxRelevantBinds dflags) emptyVarSet [] False (removeBindingShadowing $ tcl_bndrs lcl_env) -- tcl_bndrs has the innermost bindings first, @@ -2849,17 +2895,10 @@ relevantBindings want_filtering ctxt ct hang (text "Relevant bindings include") 2 (vcat docs $$ ppWhen discards discardMsg) - -- Put a zonked, tidied CtOrigin into the Ct - loc' = setCtLocOrigin loc tidy_orig - ct' = setCtLoc ct loc' ctxt' = ctxt { cec_tidy = tidy_env' } - ; return (ctxt', doc, ct') } + ; return (ctxt', doc) } where - ev = ctEvidence ct - loc = ctEvLoc ev - lcl_env = ctLocEnv loc - run_out :: Maybe Int -> Bool run_out Nothing = False run_out (Just n) = n <= 0 @@ -2868,14 +2907,14 @@ relevantBindings want_filtering ctxt ct dec_max = fmap (\n -> n - 1) - go :: DynFlags -> TidyEnv -> TcTyVarSet -> Maybe Int -> TcTyVarSet -> [SDoc] + go :: DynFlags -> TidyEnv -> Maybe Int -> TcTyVarSet -> [SDoc] -> Bool -- True <=> some filtered out due to lack of fuel -> [TcBinder] -> TcM (TidyEnv, [SDoc], Bool) -- The bool says if we filtered any out -- because of lack of fuel - go _ tidy_env _ _ _ docs discards [] + go _ tidy_env _ _ docs discards [] = return (tidy_env, reverse docs, discards) - go dflags tidy_env ct_tvs n_left tvs_seen docs discards (tc_bndr : tc_bndrs) + go dflags tidy_env n_left tvs_seen docs discards (tc_bndr : tc_bndrs) = case tc_bndr of TcTvBndr {} -> discard_it TcIdBndr id top_lvl -> go2 (idName id) (idType id) top_lvl @@ -2891,7 +2930,7 @@ relevantBindings want_filtering ctxt ct Nothing -> discard_it -- No info; discard } where - discard_it = go dflags tidy_env ct_tvs n_left tvs_seen docs + discard_it = go dflags tidy_env n_left tvs_seen docs discards tc_bndrs go2 id_name id_type top_lvl = do { (tidy_env', tidy_ty) <- zonkTidyTcType tidy_env id_type @@ -2916,12 +2955,12 @@ relevantBindings want_filtering ctxt ct else if run_out n_left && id_tvs `subVarSet` tvs_seen -- We've run out of n_left fuel and this binding only -- mentions already-seen type variables, so discard it - then go dflags tidy_env ct_tvs n_left tvs_seen docs + then go dflags tidy_env n_left tvs_seen docs True -- Record that we have now discarded something tc_bndrs -- Keep this binding, decrement fuel - else go dflags tidy_env' ct_tvs (dec_max n_left) new_seen + else go dflags tidy_env' (dec_max n_left) new_seen (doc:docs) discards tc_bndrs } ===================================== compiler/GHC/Tc/Errors/Hole.hs ===================================== @@ -2,17 +2,9 @@ {-# LANGUAGE ExistentialQuantification #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} module GHC.Tc.Errors.Hole - ( findValidHoleFits, tcFilterHoleFits - , tcCheckHoleFit, tcSubsumes - , withoutUnification - , fromPureHFPlugin - -- Re-exports for convenience - , hfIsLcl - , pprHoleFit, debugHoleFitDispConfig + ( findValidHoleFits -- Re-exported from GHC.Tc.Errors.Hole.FitTypes - , TypedHole (..), HoleFit (..), HoleFitCandidate (..) - , CandPlugin, FitPlugin , HoleFitPlugin (..), HoleFitPluginR (..) ) where @@ -121,7 +113,7 @@ The hole in `f` would generate the message: Valid hole fits are found by checking top level identifiers and local bindings in scope for whether their type can be instantiated to the the type of the hole. Additionally, we also need to check whether all relevant constraints are solved -by choosing an identifier of that type as well, see Note [Relevant Constraints] +by choosing an identifier of that type as well, see Note [Relevant constraints] Since checking for subsumption results in the side-effect of type variables being unified by the simplifier, we need to take care to restore them after @@ -143,9 +135,13 @@ that the quantified type variables would take if that fit is used, like If -XTypeApplications is enabled, this can even be copied verbatim as a replacement for the hole. - -Note [Nested implications] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Checking hole fits] +~~~~~~~~~~~~~~~~~~~~~~~~~ +If we have a hole of type hole_ty, we want to know whether a variable +of type ty is a valid fit for the whole. This is a subsumption check: +we wish to know whether ty <: hole_ty. But, of course, the check +must take into account any givens and relevant constraints. +(See also Note [Relevant constraints]). For the simplifier to be able to use any givens present in the enclosing implications to solve relevant constraints, we nest the wanted subsumption @@ -156,10 +152,7 @@ As an example, let's look at the following code: f :: Show a => a -> String f x = show _ -The hole will result in the hole constraint: - - [WD] __a1ph {0}:: a0_a1pd[tau:2] (CHoleCan: ExprHole(_)) - +Suppose the hole is assigned type a0_a1pd[tau:2]. Here the nested implications are just one level deep, namely: [Implic { @@ -170,36 +163,25 @@ Here the nested implications are just one level deep, namely: Given = $dShow_a1pc :: Show a_a1pa[sk:2] Wanted = WC {wc_simple = - [WD] __a1ph {0}:: a_a1pd[tau:2] (CHoleCan: ExprHole(_)) - [WD] $dShow_a1pe {0}:: Show a_a1pd[tau:2] (CDictCan(psc))} + [WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CDictCan(psc))} Binds = EvBindsVar Needed inner = [] Needed outer = [] the type signature for: f :: forall a. Show a => a -> String }] -As we can see, the givens say that the information about the skolem -`a_a1pa[sk:2]` fulfills the Show constraint. - -The simples are: +As we can see, the givens say that the skolem +`a_a1pa[sk:2]` fulfills the Show constraint, and that we must prove +the [W] Show a0_a1pd[tau:2] constraint -- that is, whatever fills the +hole must have a Show instance. - [[WD] __a1ph {0}:: a0_a1pd[tau:2] (CHoleCan: ExprHole(_)), - [WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CNonCanonical)] - -I.e. the hole `a0_a1pd[tau:2]` and the constraint that the type of the hole must -fulfill `Show a0_a1pd[tau:2])`. - -So when we run the check, we need to make sure that the - - [WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CNonCanonical) - -Constraint gets solved. When we now check for whether `x :: a0_a1pd[tau:2]` fits -the hole in `tcCheckHoleFit`, the call to `tcSubType` will end up writing the -meta type variable `a0_a1pd[tau:2] := a_a1pa[sk:2]`. By wrapping the wanted -constraints needed by tcSubType_NC and the relevant constraints (see -Note [Relevant Constraints] for more details) in the nested implications, we -can pass the information in the givens along to the simplifier. For our example, -we end up needing to check whether the following constraints are soluble. +When we now check whether `x :: a_a1pa[sk:2]` fits the hole in +`tcCheckHoleFit`, the call to `tcSubType` will end up unifying the meta type +variable `a0_a1pd[tau:2] := a_a1pa[sk:2]`. By wrapping the wanted constraints +needed by tcSubType_NC and the relevant constraints (see Note [Relevant +Constraints] for more details) in the nested implications, we can pass the +information in the givens along to the simplifier. For our example, we end up +needing to check whether the following constraints are soluble. WC {wc_impl = Implic { @@ -223,10 +205,12 @@ with a final WC of WC {}, confirming x :: a0_a1pd[tau:2] as a match. To avoid side-effects on the nested implications, we create a new EvBindsVar so that any changes to the ev binds during a check remains localised to that check. - +In addition, we call withoutUnification to reset any unified metavariables; this +call is actually done outside tcCheckHoleFit so that the results can be formatted +for the user before resetting variables. Note [Valid refinement hole fits include ...] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When the `-frefinement-level-hole-fits=N` flag is given, we additionally look for "valid refinement hole fits"", i.e. valid hole fits with up to N additional holes in them. @@ -337,10 +321,8 @@ In the free monad example above, this is demonstrated with be applied to an expression of type `a -> Free f b` in order to match. If -XScopedTypeVariables is enabled, this hole fit can even be copied verbatim. - -Note [Relevant Constraints] -~~~~~~~~~~~~~~~~~~~ - +Note [Relevant constraints] +~~~~~~~~~~~~~~~~~~~~~~~~~~~ As highlighted by #14273, we need to check any relevant constraints as well as checking for subsumption. Relevant constraints are the simple constraints whose free unification variables are mentioned in the type of the hole. @@ -351,10 +333,9 @@ as is the case in f :: String f = show _ -Where the simples will be : +Here, the hole is given type a0_a1kv[tau:1]. Then, the emitted constraint is: - [[WD] __a1kz {0}:: a0_a1kv[tau:1] (CHoleCan: ExprHole(_)), - [WD] $dShow_a1kw {0}:: Show a0_a1kv[tau:1] (CNonCanonical)] + [WD] $dShow_a1kw {0}:: Show a0_a1kv[tau:1] (CNonCanonical) However, when there are multiple holes, we need to be more careful. As an example, Let's take a look at the following code: @@ -362,29 +343,24 @@ example, Let's take a look at the following code: f :: Show a => a -> String f x = show (_b (show _a)) -Here there are two holes, `_a` and `_b`, and the simple constraints passed to +Here there are two holes, `_a` and `_b`. Suppose _a :: a0_a1pd[tau:2] and +_b :: a1_a1po[tau:2]. Then, the simple constraints passed to findValidHoleFits are: - [[WD] _a_a1pi {0}:: String - -> a0_a1pd[tau:2] (CHoleCan: ExprHole(_b)), - [WD] _b_a1ps {0}:: a1_a1po[tau:2] (CHoleCan: ExprHole(_a)), - [WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CNonCanonical), + [[WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CNonCanonical), [WD] $dShow_a1pp {0}:: Show a1_a1po[tau:2] (CNonCanonical)] - -Here we have the two hole constraints for `_a` and `_b`, but also additional -constraints that these holes must fulfill. When we are looking for a match for -the hole `_a`, we filter the simple constraints to the "Relevant constraints", -by throwing out all hole constraints and any constraints which do not mention -a variable mentioned in the type of the hole. For hole `_a`, we will then -only require that the `$dShow_a1pp` constraint is solved, since that is -the only non-hole constraint that mentions any free type variables mentioned in -the hole constraint for `_a`, namely `a_a1pd[tau:2]` , and similarly for the -hole `_b` we only require that the `$dShow_a1pe` constraint is solved. +When we are looking for a match for the hole `_a`, we filter the simple +constraints to the "Relevant constraints", by throwing out any constraints +which do not mention a variable mentioned in the type of the hole. For hole +`_a`, we will then only require that the `$dShow_a1pe` constraint is solved, +since that is the only constraint that mentions any free type variables +mentioned in the hole constraint for `_a`, namely `a_a1pd[tau:2]`, and +similarly for the hole `_b` we only require that the `$dShow_a1pe` constraint +is solved. Note [Leaking errors] -~~~~~~~~~~~~~~~~~~~ - +~~~~~~~~~~~~~~~~~~~~~ When considering candidates, GHC believes that we're checking for validity in actual source. However, As evidenced by #15321, #15007 and #15202, this can cause bewildering error messages. The solution here is simple: if a candidate @@ -393,17 +369,12 @@ is discarded. -} - data HoleFitDispConfig = HFDC { showWrap :: Bool , showWrapVars :: Bool , showType :: Bool , showProv :: Bool , showMatches :: Bool } -debugHoleFitDispConfig :: HoleFitDispConfig -debugHoleFitDispConfig = HFDC True True True False False - - -- We read the various -no-show-*-of-hole-fits flags -- and set the display config accordingly. getHoleFitDispConfig :: TcM HoleFitDispConfig @@ -516,13 +487,12 @@ pprHoleFit (HFDC sWrp sWrpVars sTy sProv sMs) (HoleFit {..}) = GreHFCand gre -> pprNameProvenance gre _ -> text "bound at" <+> ppr (getSrcLoc name) -getLocalBindings :: TidyEnv -> Ct -> TcM [Id] -getLocalBindings tidy_orig ct - = do { (env1, _) <- zonkTidyOrigin tidy_orig (ctLocOrigin loc) +getLocalBindings :: TidyEnv -> CtLoc -> TcM [Id] +getLocalBindings tidy_orig ct_loc + = do { (env1, _) <- zonkTidyOrigin tidy_orig (ctLocOrigin ct_loc) ; go env1 [] (removeBindingShadowing $ tcl_bndrs lcl_env) } where - loc = ctEvLoc (ctEvidence ct) - lcl_env = ctLocEnv loc + lcl_env = ctLocEnv ct_loc go :: TidyEnv -> [Id] -> [TcBinder] -> TcM [Id] go _ sofar [] = return (reverse sofar) @@ -542,11 +512,13 @@ findValidHoleFits :: TidyEnv -- ^ The tidy_env for zonking -> [Ct] -- ^ The unsolved simple constraints in the implication for -- the hole. - -> Ct -- ^ The hole constraint itself + -> Hole -> TcM (TidyEnv, SDoc) -findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = +findValidHoleFits tidy_env implics simples h@(Hole { hole_sort = ExprHole _ + , hole_loc = ct_loc + , hole_ty = hole_ty }) = do { rdr_env <- getGlobalRdrEnv - ; lclBinds <- getLocalBindings tidy_env ct + ; lclBinds <- getLocalBindings tidy_env ct_loc ; maxVSubs <- maxValidHoleFits <$> getDynFlags ; hfdc <- getHoleFitDispConfig ; sortingAlg <- getSortingAlg @@ -554,7 +526,9 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = ; hfPlugs <- tcg_hf_plugins <$> getGblEnv ; let findVLimit = if sortingAlg > NoSorting then Nothing else maxVSubs refLevel = refLevelHoleFits dflags - hole = TyH (listToBag relevantCts) implics (Just ct) + hole = TypedHole { th_relevant_cts = listToBag relevantCts + , th_implics = implics + , th_hole = Just h } (candidatePlugins, fitPlugins) = unzip $ map (\p-> ((candPlugin p) hole, (fitPlugin p) hole)) hfPlugs ; traceTc "findingValidHoleFitsFor { " $ ppr hole @@ -625,11 +599,9 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = where -- We extract the type, the tcLevel and the types free variables -- from from the constraint. - hole_ty :: TcPredType - hole_ty = ctPred ct hole_fvs :: FV hole_fvs = tyCoFVsOfType hole_ty - hole_lvl = ctLocLevel $ ctEvLoc $ ctEvidence ct + hole_lvl = ctLocLevel ct_loc -- BuiltInSyntax names like (:) and [] builtIns :: [Name] @@ -668,7 +640,7 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = <*> sortByGraph (sort gblFits) where (lclFits, gblFits) = span hfIsLcl subs - -- See Note [Relevant Constraints] + -- See Note [Relevant constraints] relevantCts :: [Ct] relevantCts = if isEmptyVarSet (fvVarSet hole_fvs) then [] else filter isRelevant simples @@ -684,7 +656,6 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = -- trying to find hole fits for many holes at once. isRelevant ct = not (isEmptyVarSet (ctFreeVarSet ct)) && anyFVMentioned ct - && not (isHoleCt ct) -- We zonk the hole fits so that the output aligns with the rest -- of the typed hole error message output. @@ -761,7 +732,7 @@ tcFilterHoleFits :: Maybe Int -- ^ We return whether or not we stopped due to hitting the limit -- and the fits we found. tcFilterHoleFits (Just 0) _ _ _ = return (False, []) -- Stop right away on 0 -tcFilterHoleFits limit (TyH {..}) ht@(hole_ty, _) candidates = +tcFilterHoleFits limit typed_hole ht@(hole_ty, _) candidates = do { traceTc "checkingFitsFor {" $ ppr hole_ty ; (discards, subs) <- go [] emptyVarSet limit ht candidates ; traceTc "checkingFitsFor }" empty @@ -895,8 +866,7 @@ tcFilterHoleFits limit (TyH {..}) ht@(hole_ty, _) candidates = else return Nothing } else return Nothing } where fvs = mkFVs ref_vars `unionFV` hole_fvs `unionFV` tyCoFVsOfType ty - hole = TyH tyHRelevantCts tyHImplics Nothing - + hole = typed_hole { th_hole = Nothing } subsDiscardMsg :: SDoc subsDiscardMsg = @@ -925,7 +895,8 @@ withoutUnification free_vars action = -- Reset any mutated free variables ; mapM_ restore flexis ; return result } - where restore = flip writeTcRef Flexi . metaTyVarRef + where restore tv = do { traceTc "withoutUnification: restore flexi" (ppr tv) + ; writeTcRef (metaTyVarRef tv) Flexi } fuvs = fvVarList free_vars -- | Reports whether first type (ty_a) subsumes the second type (ty_b), @@ -933,14 +904,14 @@ withoutUnification free_vars action = -- ty_a, i.e. `tcSubsumes a b == True` if b is a subtype of a. tcSubsumes :: TcSigmaType -> TcSigmaType -> TcM Bool tcSubsumes ty_a ty_b = fst <$> tcCheckHoleFit dummyHole ty_a ty_b - where dummyHole = TyH emptyBag [] Nothing + where dummyHole = TypedHole { th_relevant_cts = emptyBag + , th_implics = [] + , th_hole = Nothing } -- | A tcSubsumes which takes into account relevant constraints, to fix trac -- #14273. This makes sure that when checking whether a type fits the hole, -- the type has to be subsumed by type of the hole as well as fulfill all -- constraints on the type of the hole. --- Note: The simplifier may perform unification, so make sure to restore any --- free type variables to avoid side-effects. tcCheckHoleFit :: TypedHole -- ^ The hole to check against -> TcSigmaType -- ^ The type to check against (possibly modified, e.g. refined) @@ -949,56 +920,48 @@ tcCheckHoleFit :: TypedHole -- ^ The hole to check against -- ^ Whether it was a match, and the wrapper from hole_ty to ty. tcCheckHoleFit _ hole_ty ty | hole_ty `eqType` ty = return (True, idHsWrapper) -tcCheckHoleFit (TyH {..}) hole_ty ty = discardErrs $ +tcCheckHoleFit (TypedHole {..}) hole_ty ty = discardErrs $ do { -- We wrap the subtype constraint in the implications to pass along the -- givens, and so we must ensure that any nested implications and skolems -- end up with the correct level. The implications are ordered so that -- the innermost (the one with the highest level) is first, so it -- suffices to get the level of the first one (or the current level, if -- there are no implications involved). - innermost_lvl <- case tyHImplics of + innermost_lvl <- case th_implics of [] -> getTcLevel -- imp is the innermost implication (imp:_) -> return (ic_tclvl imp) - ; (wrp, wanted) <- setTcLevel innermost_lvl $ captureConstraints $ - tcSubType_NC ExprSigCtxt ty hole_ty + ; (wrap, wanted) <- setTcLevel innermost_lvl $ captureConstraints $ + tcSubType_NC ExprSigCtxt ty hole_ty ; traceTc "Checking hole fit {" empty ; traceTc "wanteds are: " $ ppr wanted - ; if isEmptyWC wanted && isEmptyBag tyHRelevantCts - then traceTc "}" empty >> return (True, wrp) + ; if isEmptyWC wanted && isEmptyBag th_relevant_cts + then do { traceTc "}" empty + ; return (True, wrap) } else do { fresh_binds <- newTcEvBinds -- The relevant constraints may contain HoleDests, so we must -- take care to clone them as well (to avoid #15370). - ; cloned_relevants <- mapBagM cloneWanted tyHRelevantCts + ; cloned_relevants <- mapBagM cloneWanted th_relevant_cts -- We wrap the WC in the nested implications, see - -- Note [Nested Implications] - ; let outermost_first = reverse tyHImplics - setWC = setWCAndBinds fresh_binds + -- Note [Checking hole fits] + ; let outermost_first = reverse th_implics -- We add the cloned relevants to the wanteds generated by - -- the call to tcSubType_NC, see Note [Relevant Constraints] + -- the call to tcSubType_NC, see Note [Relevant constraints] -- There's no need to clone the wanteds, because they are -- freshly generated by `tcSubtype_NC`. w_rel_cts = addSimples wanted cloned_relevants - w_givens = foldr setWC w_rel_cts outermost_first - ; traceTc "w_givens are: " $ ppr w_givens - ; rem <- runTcSDeriveds $ simpl_top w_givens + final_wc = foldr (setWCAndBinds fresh_binds) w_rel_cts outermost_first + ; traceTc "final_wc is: " $ ppr final_wc + ; rem <- runTcSDeriveds $ simpl_top final_wc -- We don't want any insoluble or simple constraints left, but -- solved implications are ok (and necessary for e.g. undefined) ; traceTc "rems was:" $ ppr rem ; traceTc "}" empty - ; return (isSolvedWC rem, wrp) } } + ; return (isSolvedWC rem, wrap) } } where setWCAndBinds :: EvBindsVar -- Fresh ev binds var. -> Implication -- The implication to put WC in. -> WantedConstraints -- The WC constraints to put implic. -> WantedConstraints -- The new constraints. setWCAndBinds binds imp wc - = WC { wc_simple = emptyBag - , wc_impl = unitBag $ imp { ic_wanted = wc , ic_binds = binds } } - --- | Maps a plugin that needs no state to one with an empty one. -fromPureHFPlugin :: HoleFitPlugin -> HoleFitPluginR -fromPureHFPlugin plug = - HoleFitPluginR { hfPluginInit = newTcRef () - , hfPluginRun = const plug - , hfPluginStop = const $ return () } + = mkImplicWC $ unitBag $ imp { ic_wanted = wc , ic_binds = binds } ===================================== compiler/GHC/Tc/Errors/Hole.hs-boot ===================================== @@ -5,9 +5,9 @@ module GHC.Tc.Errors.Hole where import GHC.Tc.Types ( TcM ) -import GHC.Tc.Types.Constraint ( Ct, Implication ) +import GHC.Tc.Types.Constraint ( Ct, Hole, Implication ) import GHC.Utils.Outputable ( SDoc ) import GHC.Types.Var.Env ( TidyEnv ) -findValidHoleFits :: TidyEnv -> [Implication] -> [Ct] -> Ct +findValidHoleFits :: TidyEnv -> [Implication] -> [Ct] -> Hole -> TcM (TidyEnv, SDoc) ===================================== compiler/GHC/Tc/Errors/Hole/FitTypes.hs ===================================== @@ -21,20 +21,21 @@ import GHC.Types.Name import Data.Function ( on ) -data TypedHole = TyH { tyHRelevantCts :: Cts - -- ^ Any relevant Cts to the hole - , tyHImplics :: [Implication] - -- ^ The nested implications of the hole with the - -- innermost implication first. - , tyHCt :: Maybe Ct - -- ^ The hole constraint itself, if available. - } +data TypedHole = TypedHole { th_relevant_cts :: Cts + -- ^ Any relevant Cts to the hole + , th_implics :: [Implication] + -- ^ The nested implications of the hole with the + -- innermost implication first. + , th_hole :: Maybe Hole + -- ^ The hole itself, if available. Only for debugging. + } instance Outputable TypedHole where - ppr (TyH rels implics ct) + ppr (TypedHole { th_relevant_cts = rels + , th_implics = implics + , th_hole = hole }) = hang (text "TypedHole") 2 - (ppr rels $+$ ppr implics $+$ ppr ct) - + (ppr rels $+$ ppr implics $+$ ppr hole) -- | HoleFitCandidates are passed to hole fit plugins and then -- checked whether they fit a given typed-hole. @@ -51,9 +52,6 @@ pprHoleFitCand (IdHFCand cid) = text "Id HFC: " <> ppr cid pprHoleFitCand (NameHFCand cname) = text "Name HFC: " <> ppr cname pprHoleFitCand (GreHFCand cgre) = text "Gre HFC: " <> ppr cgre - - - instance NamedThing HoleFitCandidate where getName hfc = case hfc of IdHFCand cid -> idName cid ===================================== compiler/GHC/Tc/Gen/Expr.hs ===================================== @@ -36,7 +36,6 @@ import {-# SOURCE #-} GHC.Tc.Gen.Splice( tcSpliceExpr, tcTypedBracket, tcUntyp import GHC.Builtin.Names.TH( liftStringName, liftName ) import GHC.Hs -import GHC.Tc.Types.Constraint ( HoleSort(..) ) import GHC.Tc.Utils.Zonk import GHC.Tc.Utils.Monad import GHC.Tc.Utils.Unify @@ -1408,22 +1407,21 @@ Suppose 'wurble' is not in scope, and we have Then the renamer will make (HsUnboundVar "wurble) for 'wurble', and the typechecker will typecheck it with tcUnboundId, giving it -a type 'alpha', and emitting a deferred CHoleCan constraint, to -be reported later. +a type 'alpha', and emitting a deferred Hole, to be reported later. But then comes the visible type application. If we do nothing, we'll generate an immediate failure (in tc_app_err), saying that a function of type 'alpha' can't be applied to Bool. That's insane! And indeed users complain bitterly (#13834, #17150.) -The right error is the CHoleCan, which has /already/ been emitted by +The right error is the Hole, which has /already/ been emitted by tcUnboundId. It later reports 'wurble' as out of scope, and tries to give its type. Fortunately in tcArgs we still have access to the function, so we can check if it is a HsUnboundVar. We use this info to simply skip over any visible type arguments. We've already inferred the type of the -function, so we'll /already/ have emitted a CHoleCan constraint; +function, so we'll /already/ have emitted a Hole; failing preserves that constraint. We do /not/ want to fail altogether in this case (via failM) becuase @@ -1900,14 +1898,13 @@ tcUnboundId :: HsExpr GhcRn -> OccName -> ExpRhoType -> TcM (HsExpr GhcTc) -- Others might simply be variables that accidentally have no binding site -- -- We turn all of them into HsVar, since HsUnboundVar can't contain an --- Id; and indeed the evidence for the CHoleCan does bind it, so it's +-- Id; and indeed the evidence for the ExprHole does bind it, so it's -- not unbound any more! tcUnboundId rn_expr occ res_ty = do { ty <- newOpenFlexiTyVarTy -- Allow Int# etc (#12531) ; name <- newSysName occ ; let ev = mkLocalId name ty - ; can <- newHoleCt ExprHole ev ty - ; emitInsoluble can + ; emitNewExprHole occ ev ty ; tcWrapResultO (UnboundOccurrenceOf occ) rn_expr (HsVar noExtField (noLoc ev)) ty res_ty } ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -419,7 +419,7 @@ tcHsTypeApp wc_ty kind ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A HsWildCardBndrs's hswc_ext now only includes /named/ wildcards, so any unnamed wildcards stay unchanged in hswc_body. When called in -tcHsTypeApp, tcCheckLHsType will call emitAnonWildCardHoleConstraint +tcHsTypeApp, tcCheckLHsType will call emitAnonTypeHole on these anonymous wildcards. However, this would trigger error/warning when an anonymous wildcard is passed in as a visible type argument, which we do not want because users should be able to write @@ -891,7 +891,7 @@ tcAnonWildCardOcc wc exp_kind ; warning <- woptM Opt_WarnPartialTypeSignatures ; unless (part_tysig && not warning) $ - emitAnonWildCardHoleConstraint wc_tv + emitAnonTypeHole wc_tv -- Why the 'unless' guard? -- See Note [Wildcards in visible kind application] @@ -911,11 +911,11 @@ x = MkT So we should allow '@_' without emitting any hole constraints, and regardless of whether PartialTypeSignatures is enabled or not. But how would the typechecker know which '_' is being used in VKA and which is not when it -calls emitNamedWildCardHoleConstraints in tcHsPartialSigType on all HsWildCardBndrs? +calls emitNamedTypeHole in tcHsPartialSigType on all HsWildCardBndrs? The solution then is to neither rename nor include unnamed wildcards in HsWildCardBndrs, but instead give every anonymous wildcard a fresh wild tyvar in tcAnonWildCardOcc. And whenever we see a '@', we automatically turn on PartialTypeSignatures and -turn off hole constraint warnings, and do not call emitAnonWildCardHoleConstraint +turn off hole constraint warnings, and do not call emitAnonTypeHole under these conditions. See related Note [Wildcards in visible type application] here and Note [The wildcard story for types] in GHC.Hs.Types @@ -3192,7 +3192,7 @@ tcHsPartialSigType ctxt sig_ty -- Spit out the wildcards (including the extra-constraints one) -- as "hole" constraints, so that they'll be reported if necessary -- See Note [Extra-constraint holes in partial type signatures] - ; emitNamedWildCardHoleConstraints wcs + ; mapM_ emitNamedTypeHole wcs -- Zonk, so that any nested foralls can "see" their occurrences -- See Note [Checking partial type signatures], in @@ -3365,7 +3365,7 @@ tcHsPatSigType ctxt sig_ty do { sig_ty <- tcHsOpenType hs_ty ; return (wcs, sig_ty) } - ; emitNamedWildCardHoleConstraints wcs + ; mapM_ emitNamedTypeHole wcs -- sig_ty might have tyvars that are at a higher TcLevel (if hs_ty -- contains a forall). Promote these. ===================================== compiler/GHC/Tc/Gen/Rule.hs ===================================== @@ -460,9 +460,9 @@ getRuleQuantCts wc = float_wc emptyVarSet wc where float_wc :: TcTyCoVarSet -> WantedConstraints -> (Cts, WantedConstraints) - float_wc skol_tvs (WC { wc_simple = simples, wc_impl = implics }) + float_wc skol_tvs (WC { wc_simple = simples, wc_impl = implics, wc_holes = holes }) = ( simple_yes `andCts` implic_yes - , WC { wc_simple = simple_no, wc_impl = implics_no }) + , emptyWC { wc_simple = simple_no, wc_impl = implics_no, wc_holes = holes }) where (simple_yes, simple_no) = partitionBag (rule_quant_ct skol_tvs) simples (implic_yes, implics_no) = mapAccumBagL (float_implic skol_tvs) @@ -480,8 +480,6 @@ getRuleQuantCts wc | EqPred _ t1 t2 <- classifyPredType (ctPred ct) , not (ok_eq t1 t2) = False -- Note [RULE quantification over equalities] - | isHoleCt ct - = False -- Don't quantify over type holes, obviously | otherwise = tyCoVarsOfCt ct `disjointVarSet` skol_tvs ===================================== compiler/GHC/Tc/Module.hs ===================================== @@ -2589,7 +2589,7 @@ tcRnType hsc_env flexi normalise rdr_type -- kindGeneralize, below solveEqualities $ tcNamedWildCardBinders wcs $ \ wcs' -> - do { emitNamedWildCardHoleConstraints wcs' + do { mapM_ emitNamedTypeHole wcs' ; tcLHsTypeUnsaturated rn_type } -- Do kind generalisation; see Note [Kind-generalise in tcRnType] ===================================== compiler/GHC/Tc/Solver.hs ===================================== @@ -31,7 +31,7 @@ import GHC.Prelude import GHC.Data.Bag import GHC.Core.Class ( Class, classKey, classTyCon ) import GHC.Driver.Session -import GHC.Types.Id ( idType, mkLocalId ) +import GHC.Types.Id ( idType ) import GHC.Tc.Utils.Instantiate import GHC.Data.List.SetOps import GHC.Types.Name @@ -42,6 +42,7 @@ import GHC.Tc.Errors import GHC.Tc.Types.Evidence import GHC.Tc.Solver.Interact import GHC.Tc.Solver.Canonical ( makeSuperClasses, solveCallStack ) +import GHC.Tc.Solver.Flatten ( flattenType ) import GHC.Tc.Utils.TcMType as TcM import GHC.Tc.Utils.Monad as TcM import GHC.Tc.Solver.Monad as TcS @@ -145,8 +146,7 @@ simplifyTop wanteds ; saved_msg <- TcM.readTcRef errs_var ; TcM.writeTcRef errs_var emptyMessages - ; warnAllUnsolved $ WC { wc_simple = unsafe_ol - , wc_impl = emptyBag } + ; warnAllUnsolved $ emptyWC { wc_simple = unsafe_ol } ; whyUnsafe <- fst <$> TcM.readTcRef errs_var ; TcM.writeTcRef errs_var saved_msg @@ -638,27 +638,15 @@ tcNormalise :: Bag EvVar -> Type -> TcM Type tcNormalise given_ids ty = do { lcl_env <- TcM.getLclEnv ; let given_loc = mkGivenLoc topTcLevel UnkSkol lcl_env - ; wanted_ct <- mk_wanted_ct + ; norm_loc <- getCtLocM PatCheckOrigin Nothing ; (res, _ev_binds) <- runTcS $ do { traceTcS "tcNormalise {" (ppr given_ids) ; let given_cts = mkGivens given_loc (bagToList given_ids) ; solveSimpleGivens given_cts - ; wcs <- solveSimpleWanteds (unitBag wanted_ct) - -- It's an invariant that this wc_simple will always be - -- a singleton Ct, since that's what we fed in as input. - ; let ty' = case bagToList (wc_simple wcs) of - (ct:_) -> ctEvPred (ctEvidence ct) - cts -> pprPanic "tcNormalise" (ppr cts) + ; ty' <- flattenType norm_loc ty ; traceTcS "tcNormalise }" (ppr ty') ; pure ty' } ; return res } - where - mk_wanted_ct :: TcM Ct - mk_wanted_ct = do - let occ = mkVarOcc "$tcNorm" - name <- newSysName occ - let ev = mkLocalId name ty - newHoleCt ExprHole ev ty {- Note [Superclasses and satisfiability] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -696,11 +684,8 @@ if some local equalities are solved for. See "Wrinkle: Local equalities" in Note [Type normalisation] in Check. To accomplish its stated goal, tcNormalise first feeds the local constraints -into solveSimpleGivens, then stuffs the argument type in a CHoleCan, and feeds -that singleton Ct into solveSimpleWanteds, which reduces the type in the -CHoleCan as much as possible with respect to the local given constraints. When -solveSimpleWanteds is finished, we dig out the type from the CHoleCan and -return that. +into solveSimpleGivens, then uses flattenType to simplify the desired type +with respect to the givens. *********************************************************************************** * * @@ -889,8 +874,8 @@ mkResidualConstraints rhs_tclvl ev_binds_var , ic_no_eqs = False , ic_info = skol_info } - ; return (WC { wc_simple = outer_simple - , wc_impl = implics })} + ; return (emptyWC { wc_simple = outer_simple + , wc_impl = implics })} where full_theta = map idType full_theta_vars skol_info = InferSkol [ (name, mkSigmaTy [] full_theta ty) @@ -1516,7 +1501,7 @@ solveWantedsAndDrop wanted solveWanteds :: WantedConstraints -> TcS WantedConstraints -- so that the inert set doesn't mindlessly propagate. -- NB: wc_simples may be wanted /or/ derived now -solveWanteds wc@(WC { wc_simple = simples, wc_impl = implics }) +solveWanteds wc@(WC { wc_simple = simples, wc_impl = implics, wc_holes = holes }) = do { cur_lvl <- TcS.getTcLevel ; traceTcS "solveWanteds {" $ vcat [ text "Level =" <+> ppr cur_lvl @@ -1530,9 +1515,12 @@ solveWanteds wc@(WC { wc_simple = simples, wc_impl = implics }) implics `unionBags` wc_impl wc1 ; dflags <- getDynFlags - ; final_wc <- simpl_loop 0 (solverIterations dflags) floated_eqs + ; solved_wc <- simpl_loop 0 (solverIterations dflags) floated_eqs (wc1 { wc_impl = implics2 }) + ; holes' <- simplifyHoles holes + ; let final_wc = solved_wc { wc_holes = holes' } + ; ev_binds_var <- getTcEvBindsVar ; bb <- TcS.getTcEvBindsMap ev_binds_var ; traceTcS "solveWanteds }" $ @@ -1779,12 +1767,13 @@ setImplicationStatus implic@(Implic { ic_status = status then Nothing else Just final_implic } where - WC { wc_simple = simples, wc_impl = implics } = wc + WC { wc_simple = simples, wc_impl = implics, wc_holes = holes } = wc pruned_simples = dropDerivedSimples simples pruned_implics = filterBag keep_me implics pruned_wc = WC { wc_simple = pruned_simples - , wc_impl = pruned_implics } + , wc_impl = pruned_implics + , wc_holes = holes } -- do not prune holes; these should be reported keep_me :: Implication -> Bool keep_me ic @@ -1898,6 +1887,14 @@ neededEvVars implic@(Implic { ic_given = givens | is_given = needs -- Add the rhs vars of the Wanted bindings only | otherwise = evVarsOfTerm rhs `unionVarSet` needs +------------------------------------------------- +simplifyHoles :: Bag Hole -> TcS (Bag Hole) +simplifyHoles = mapBagM simpl_hole + where + simpl_hole :: Hole -> TcS Hole + simpl_hole h@(Hole { hole_ty = ty, hole_loc = loc }) + = do { ty' <- flattenType loc ty + ; return (h { hole_ty = ty' }) } {- Note [Delete dead Given evidence bindings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2143,7 +2140,6 @@ approximateWC float_past_equalities wc is_floatable skol_tvs ct | isGivenCt ct = False - | isHoleCt ct = False | insolubleEqCt ct = False | otherwise = tyCoVarsOfCt ct `disjointVarSet` skol_tvs ===================================== compiler/GHC/Tc/Solver/Canonical.hs ===================================== @@ -34,7 +34,6 @@ import GHC.Tc.Instance.Family ( tcTopNormaliseNewTypeTF_maybe ) import GHC.Types.Var import GHC.Types.Var.Env( mkInScopeSet ) import GHC.Types.Var.Set( delVarSetList ) -import GHC.Types.Name.Occurrence ( OccName ) import GHC.Utils.Outputable import GHC.Driver.Session( DynFlags ) import GHC.Types.Name.Set @@ -67,8 +66,7 @@ Canonicalization converts a simple constraint to a canonical form. It is unary (i.e. treats individual constraints one at a time). Constraints originating from user-written code come into being as -CNonCanonicals (except for CHoleCans, arising from holes). We know nothing -about these constraints. So, first: +CNonCanonicals. We know nothing about these constraints. So, first: Classify CNonCanoncal constraints, depending on whether they are equalities, class predicates, or other. @@ -137,9 +135,6 @@ canonicalize (CFunEqCan { cc_ev = ev = {-# SCC "canEqLeafFunEq" #-} canCFunEqCan ev fn xis1 fsk -canonicalize (CHoleCan { cc_ev = ev, cc_occ = occ, cc_hole = hole }) - = canHole ev occ hole - {- ************************************************************************ * * @@ -718,17 +713,6 @@ canIrred status ev _ -> continueWith $ mkIrredCt status new_ev } } -canHole :: CtEvidence -> OccName -> HoleSort -> TcS (StopOrContinue Ct) -canHole ev occ hole_sort - = do { let pred = ctEvPred ev - ; (xi,co) <- flatten FM_SubstOnly ev pred -- co :: xi ~ pred - ; rewriteEvidence ev xi co `andWhenContinue` \ new_ev -> - do { updInertIrreds (`snocCts` (CHoleCan { cc_ev = new_ev - , cc_occ = occ - , cc_hole = hole_sort })) - ; stopWith new_ev "Emit insoluble hole" } } - - {- ********************************************************************* * * * Quantified predicates @@ -1401,6 +1385,7 @@ can_eq_app ev s1 t1 s2 t2 | CtDerived {} <- ev = do { unifyDeriveds loc [Nominal, Nominal] [s1, t1] [s2, t2] ; stopWith ev "Decomposed [D] AppTy" } + | CtWanted { ctev_dest = dest } <- ev = do { co_s <- unifyWanted loc Nominal s1 s2 ; let arg_loc ===================================== compiler/GHC/Tc/Solver/Flatten.hs ===================================== @@ -5,7 +5,7 @@ module GHC.Tc.Solver.Flatten( FlattenMode(..), flatten, flattenKind, flattenArgsNom, - rewriteTyVar, + rewriteTyVar, flattenType, unflattenWanteds ) where @@ -825,6 +825,20 @@ flattenArgsNom ev tc tys ; traceTcS "flatten }" (vcat (map ppr tys')) ; return (tys', cos, kind_co) } +-- | Flatten a type w.r.t. nominal equality. This is useful to rewrite +-- a type w.r.t. any givens. It does not do type-family reduction. This +-- will never emit new constraints. Call this when the inert set contains +-- only givens. +flattenType :: CtLoc -> TcType -> TcS TcType +flattenType loc ty + -- More info about FM_SubstOnly in Note [Holes] in GHC.Tc.Types.Constraint + = do { (xi, _) <- runFlatten FM_SubstOnly loc Given NomEq $ + flatten_one ty + -- use Given flavor so that it is rewritten + -- only w.r.t. Givens, never Wanteds/Deriveds + -- (Shouldn't matter, if only Givens are present + -- anyway) + ; return xi } {- ********************************************************************* * * ===================================== compiler/GHC/Tc/Solver/Interact.hs ===================================== @@ -195,7 +195,7 @@ solve_simple_wanteds :: WantedConstraints -> TcS (Int, WantedConstraints) -- Try solving these constraints -- Affects the unification state (of course) but not the inert set -- The result is not necessarily zonked -solve_simple_wanteds (WC { wc_simple = simples1, wc_impl = implics1 }) +solve_simple_wanteds (WC { wc_simple = simples1, wc_impl = implics1, wc_holes = holes }) = nestTcS $ do { solveSimples simples1 ; (implics2, tv_eqs, fun_eqs, others) <- getUnsolvedInerts @@ -204,7 +204,8 @@ solve_simple_wanteds (WC { wc_simple = simples1, wc_impl = implics1 }) -- See Note [Unflatten after solving the simple wanteds] ; return ( unif_count , WC { wc_simple = others `andCts` unflattened_eqs - , wc_impl = implics1 `unionBags` implics2 }) } + , wc_impl = implics1 `unionBags` implics2 + , wc_holes = holes }) } {- Note [The solveSimpleWanteds loop] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -264,7 +265,7 @@ runTcPluginsGiven -- 'solveSimpleWanteds' should feed the updated wanteds back into the -- main solver. runTcPluginsWanted :: WantedConstraints -> TcS (Bool, WantedConstraints) -runTcPluginsWanted wc@(WC { wc_simple = simples1, wc_impl = implics1 }) +runTcPluginsWanted wc@(WC { wc_simple = simples1 }) | isEmptyBag simples1 = return (False, wc) | otherwise @@ -285,11 +286,10 @@ runTcPluginsWanted wc@(WC { wc_simple = simples1, wc_impl = implics1 }) ; mapM_ setEv solved_wanted ; return ( notNull (pluginNewCts p) - , WC { wc_simple = listToBag new_wanted `andCts` + , wc { wc_simple = listToBag new_wanted `andCts` listToBag unsolved_wanted `andCts` listToBag unsolved_derived `andCts` - listToBag insols - , wc_impl = implics1 } ) } } + listToBag insols } ) } } where setEv :: (EvTerm,Ct) -> TcS () setEv (ev,ct) = case ctEvidence ct of @@ -494,7 +494,6 @@ interactWithInertsStage wi CIrredCan {} -> interactIrred ics wi CDictCan {} -> interactDict ics wi _ -> pprPanic "interactWithInerts" (ppr wi) } - -- CHoleCan are put straight into inert_frozen, so never get here -- CNonCanonical have been canonicalised data InteractResult ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -198,7 +198,7 @@ import GHC.Types.Unique.Set Note [WorkList priorities] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -A WorkList contains canonical and non-canonical items (of all flavors). +A WorkList contains canonical and non-canonical items (of all flavours). Notice that each Ct now has a simplification depth. We may consider using this depth for prioritization as well in the future. @@ -1653,8 +1653,7 @@ add_item ics item@(CDictCan { cc_ev = ev, cc_class = cls, cc_tyargs = tys }) add_item _ item = pprPanic "upd_inert set: can't happen! Inserting " $ - ppr item -- Can't be CNonCanonical, CHoleCan, - -- because they only land in inert_irreds + ppr item -- Can't be CNonCanonical because they only land in inert_irreds bumpUnsolvedCount :: CtEvidence -> Int -> Int bumpUnsolvedCount ev n | isWanted ev = n+1 @@ -1896,10 +1895,6 @@ be decomposed. Otherwise we end up with a "Can't match [Int] ~ [[Int]]" which is true, but a bit confusing because the outer type constructors match. -Similarly, if we have a CHoleCan, we'd like to rewrite it with any -Givens, to give as informative an error messasge as possible -(#12468, #11325). - Hence: * In the main simplifier loops in GHC.Tc.Solver (solveWanteds, simpl_loop), we feed the insolubles in solveSimpleWanteds, @@ -2352,8 +2347,6 @@ removeInertCt is ct = CQuantCan {} -> panic "removeInertCt: CQuantCan" CIrredCan {} -> panic "removeInertCt: CIrredEvCan" CNonCanonical {} -> panic "removeInertCt: CNonCanonical" - CHoleCan {} -> panic "removeInertCt: CHoleCan" - lookupFlatCache :: TyCon -> [Type] -> TcS (Maybe (TcCoercion, TcType, CtFlavour)) lookupFlatCache fam_tc tys ===================================== compiler/GHC/Tc/Types/Constraint.hs ===================================== @@ -14,8 +14,7 @@ module GHC.Tc.Types.Constraint ( isEmptyCts, isCTyEqCan, isCFunEqCan, isPendingScDict, superClassesMightHelp, getPendingWantedScs, isCDictCan_Maybe, isCFunEqCan_maybe, - isCNonCanonical, isWantedCt, isDerivedCt, - isGivenCt, isHoleCt, isOutOfScopeCt, isExprHoleCt, isTypeHoleCt, + isCNonCanonical, isWantedCt, isDerivedCt, isGivenCt, isUserTypeErrorCt, getUserTypeErrorMsg, ctEvidence, ctLoc, setCtLoc, ctPred, ctFlavour, ctEqRel, ctOrigin, ctEvId, mkTcEqPredLikeEv, @@ -26,9 +25,11 @@ module GHC.Tc.Types.Constraint ( tyCoVarsOfCt, tyCoVarsOfCts, tyCoVarsOfCtList, tyCoVarsOfCtsList, + Hole(..), HoleSort(..), isOutOfScopeHole, + WantedConstraints(..), insolubleWC, emptyWC, isEmptyWC, isSolvedWC, andWC, unionsWC, mkSimpleWC, mkImplicWC, - addInsols, insolublesOnly, addSimples, addImplics, + addInsols, insolublesOnly, addSimples, addImplics, addHole, tyCoVarsOfWC, dropDerivedWC, dropDerivedSimples, tyCoVarsOfWCList, insolubleCt, insolubleEqCt, isDroppableCt, insolubleImplic, @@ -62,9 +63,6 @@ module GHC.Tc.Types.Constraint ( pprEvVarTheta, pprEvVars, pprEvVarWithType, - -- holes - HoleSort(..), - ) where @@ -202,14 +200,6 @@ data Ct cc_ev :: CtEvidence } - | CHoleCan { -- See Note [Hole constraints] - -- Treated as an "insoluble" constraint - -- See Note [Insoluble constraints] - cc_ev :: CtEvidence, - cc_occ :: OccName, -- The name of this hole - cc_hole :: HoleSort -- The sort of this hole (expr, type, ...) - } - | CQuantCan QCInst -- A quantified constraint -- NB: I expect to make more of the cases in Ct -- look like this, with the payload in an @@ -230,13 +220,47 @@ instance Outputable QCInst where ppr (QCI { qci_ev = ev }) = ppr ev ------------ +-- | A hole stores the information needed to report diagnostics +-- about holes in terms (unbound identifiers or underscores) or +-- in types (also called wildcards, as used in partial type +-- signatures). See Note [Holes]. +data Hole + = Hole { hole_sort :: HoleSort -- ^ What flavour of hole is this? + , hole_occ :: OccName -- ^ The name of this hole + , hole_ty :: TcType -- ^ Type to be printed to the user + -- For expression holes: type of expr + -- For type holes: the missing type + , hole_loc :: CtLoc -- ^ Where hole was written + } + -- For the hole_loc, we usually only want the TcLclEnv stored within. + -- Except when we flatten, where we need a whole location. And this + -- might get reported to the user if reducing type families in a + -- hole type loops. + + -- | Used to indicate which sort of hole we have. -data HoleSort = ExprHole +data HoleSort = ExprHole Id -- ^ Either an out-of-scope variable or a "true" hole in an - -- expression (TypedHoles) + -- expression (TypedHoles). + -- The 'Id' is where to store "evidence": this evidence + -- will be an erroring expression for -fdefer-type-errors. | TypeHole -- ^ A hole in a type (PartialTypeSignatures) +instance Outputable Hole where + ppr (Hole { hole_sort = ExprHole id + , hole_occ = occ + , hole_ty = ty }) + = parens $ (braces $ ppr occ <> colon <> ppr id) <+> dcolon <+> ppr ty + ppr (Hole { hole_sort = TypeHole + , hole_occ = occ + , hole_ty = ty }) + = braces $ ppr occ <> colon <> ppr ty + +instance Outputable HoleSort where + ppr (ExprHole id) = text "ExprHole:" <> ppr id + ppr TypeHole = text "TypeHole" + ------------ -- | Used to indicate extra information about why a CIrredCan is irreducible data CtIrredStatus @@ -252,20 +276,8 @@ instance Outputable CtIrredStatus where ppr BlockedCIS = text "(blocked)" ppr OtherCIS = text "(soluble)" -{- Note [Hole constraints] -~~~~~~~~~~~~~~~~~~~~~~~~~~ -CHoleCan constraints are used for two kinds of holes, -distinguished by cc_hole: - - * For holes in expressions - e.g. f x = g _ x - - * For holes in type signatures - e.g. f :: _ -> _ - f x = [x,True] - -Note [CIrredCan constraints] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [CIrredCan constraints] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CIrredCan constraints are used for constraints that are "stuck" - we can't solve them (yet) - we can't use them to solve other constraints @@ -350,6 +362,40 @@ unenforced). The almost-function-free property is checked by isAlmostFunctionFree in GHC.Tc.Utils.TcType. The flattener (in GHC.Tc.Solver.Flatten) produces types that are almost function-free. +Note [Holes] +~~~~~~~~~~~~ +This Note explains how GHC tracks *holes*. + +A hole represents one of two conditions: + - A missing bit of an expression. Example: foo x = x + _ + - A missing bit of a type. Example: bar :: Int -> _ + +What these have in common is that both cause GHC to emit a diagnostic to the +user describing the bit that is left out. + +When a hole is encountered, a new entry of type Hole is added to the ambient +WantedConstraints. The type (hole_ty) of the hole is then simplified during +solving (with respect to any Givens in surrounding implications). It is +reported with all the other errors in GHC.Tc.Errors. No type family reduction +is done on hole types; this is purely because we think it will produce +better error messages not to reduce type families. This is why the +GHC.Tc.Solver.Flatten.flattenType function uses FM_SubstOnly. + +For expression holes, the user has the option of deferring errors until runtime +with -fdefer-type-errors. In this case, the hole actually has evidence: this +evidence is an erroring expression that prints an error and crashes at runtime. +The ExprHole variant of holes stores the Id that will be bound to this evidence; +during constraint generation, this Id was inserted into the expression output +by the type checker. + +You might think that the type of the stored Id is the same as the type of the +hole. However, because the hole type (hole_ty) is rewritten with respect to +givens, this might not be the case. That is, the hole_ty is always (~) to the +type of the Id, but they might not be `eqType`. We need the type of the generated +evidence to match what is expected in the context of the hole, and so we must +store these types separately. + +Type-level holes have no evidence at all. -} mkNonCanonical :: CtEvidence -> Ct @@ -419,7 +465,6 @@ instance Outputable Ct where | pend_sc -> text "CDictCan(psc)" | otherwise -> text "CDictCan" CIrredCan { cc_status = status } -> text "CIrredCan" <> ppr status - CHoleCan { cc_occ = occ } -> text "CHoleCan:" <+> ppr occ CQuantCan (QCI { qci_pend_sc = pend_sc }) | pend_sc -> text "CQuantCan(psc)" | otherwise -> text "CQuantCan" @@ -482,9 +527,10 @@ tyCoVarsOfWCList = fvVarList . tyCoFVsOfWC -- computation. See Note [Deterministic FV] in GHC.Utils.FV. tyCoFVsOfWC :: WantedConstraints -> FV -- Only called on *zonked* things, hence no need to worry about flatten-skolems -tyCoFVsOfWC (WC { wc_simple = simple, wc_impl = implic }) +tyCoFVsOfWC (WC { wc_simple = simple, wc_impl = implic, wc_holes = holes }) = tyCoFVsOfCts simple `unionFV` - tyCoFVsOfBag tyCoFVsOfImplic implic + tyCoFVsOfBag tyCoFVsOfImplic implic `unionFV` + tyCoFVsOfBag tyCoFVsOfHole holes -- | Returns free variables of Implication as a composable FV computation. -- See Note [Deterministic FV] in GHC.Utils.FV. @@ -500,6 +546,9 @@ tyCoFVsOfImplic (Implic { ic_skols = skols tyCoFVsVarBndrs givens $ tyCoFVsOfWC wanted +tyCoFVsOfHole :: Hole -> FV +tyCoFVsOfHole (Hole { hole_ty = ty }) = tyCoFVsOfType ty + tyCoFVsOfBag :: (a -> FV) -> Bag a -> FV tyCoFVsOfBag tvs_of = foldr (unionFV . tvs_of) emptyFV @@ -552,7 +601,6 @@ isDroppableCt ct keep_deriv = case ct of - CHoleCan {} -> True CIrredCan { cc_status = InsolubleCIS } -> keep_eq True _ -> keep_eq False @@ -676,26 +724,6 @@ isCNonCanonical :: Ct -> Bool isCNonCanonical (CNonCanonical {}) = True isCNonCanonical _ = False -isHoleCt:: Ct -> Bool -isHoleCt (CHoleCan {}) = True -isHoleCt _ = False - -isOutOfScopeCt :: Ct -> Bool --- A Hole that does not have a leading underscore is --- simply an out-of-scope variable, and we treat that --- a bit differently when it comes to error reporting -isOutOfScopeCt (CHoleCan { cc_occ = occ }) = not (startsWithUnderscore occ) -isOutOfScopeCt _ = False - -isExprHoleCt :: Ct -> Bool -isExprHoleCt (CHoleCan { cc_hole = ExprHole }) = True -isExprHoleCt _ = False - -isTypeHoleCt :: Ct -> Bool -isTypeHoleCt (CHoleCan { cc_hole = TypeHole }) = True -isTypeHoleCt _ = False - - {- Note [Custom type errors in constraints] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -884,37 +912,39 @@ v%************************************************************************ data WantedConstraints = WC { wc_simple :: Cts -- Unsolved constraints, all wanted , wc_impl :: Bag Implication + , wc_holes :: Bag Hole } emptyWC :: WantedConstraints -emptyWC = WC { wc_simple = emptyBag, wc_impl = emptyBag } +emptyWC = WC { wc_simple = emptyBag + , wc_impl = emptyBag + , wc_holes = emptyBag } mkSimpleWC :: [CtEvidence] -> WantedConstraints mkSimpleWC cts - = WC { wc_simple = listToBag (map mkNonCanonical cts) - , wc_impl = emptyBag } + = emptyWC { wc_simple = listToBag (map mkNonCanonical cts) } mkImplicWC :: Bag Implication -> WantedConstraints mkImplicWC implic - = WC { wc_simple = emptyBag, wc_impl = implic } + = emptyWC { wc_impl = implic } isEmptyWC :: WantedConstraints -> Bool -isEmptyWC (WC { wc_simple = f, wc_impl = i }) - = isEmptyBag f && isEmptyBag i - +isEmptyWC (WC { wc_simple = f, wc_impl = i, wc_holes = holes }) + = isEmptyBag f && isEmptyBag i && isEmptyBag holes -- | Checks whether a the given wanted constraints are solved, i.e. -- that there are no simple constraints left and all the implications -- are solved. isSolvedWC :: WantedConstraints -> Bool -isSolvedWC WC {wc_simple = wc_simple, wc_impl = wc_impl} = - isEmptyBag wc_simple && allBag (isSolvedStatus . ic_status) wc_impl +isSolvedWC WC {wc_simple = wc_simple, wc_impl = wc_impl, wc_holes = holes} = + isEmptyBag wc_simple && allBag (isSolvedStatus . ic_status) wc_impl && isEmptyBag holes andWC :: WantedConstraints -> WantedConstraints -> WantedConstraints -andWC (WC { wc_simple = f1, wc_impl = i1 }) - (WC { wc_simple = f2, wc_impl = i2 }) +andWC (WC { wc_simple = f1, wc_impl = i1, wc_holes = h1 }) + (WC { wc_simple = f2, wc_impl = i2, wc_holes = h2 }) = WC { wc_simple = f1 `unionBags` f2 - , wc_impl = i1 `unionBags` i2 } + , wc_impl = i1 `unionBags` i2 + , wc_holes = h1 `unionBags` h2 } unionsWC :: [WantedConstraints] -> WantedConstraints unionsWC = foldr andWC emptyWC @@ -931,11 +961,16 @@ addInsols :: WantedConstraints -> Bag Ct -> WantedConstraints addInsols wc cts = wc { wc_simple = wc_simple wc `unionBags` cts } +addHole :: WantedConstraints -> Hole -> WantedConstraints +addHole wc hole + = wc { wc_holes = hole `consBag` wc_holes wc } + insolublesOnly :: WantedConstraints -> WantedConstraints -- Keep only the definitely-insoluble constraints -insolublesOnly (WC { wc_simple = simples, wc_impl = implics }) +insolublesOnly (WC { wc_simple = simples, wc_impl = implics, wc_holes = holes }) = WC { wc_simple = filterBag insolubleCt simples - , wc_impl = mapBag implic_insols_only implics } + , wc_impl = mapBag implic_insols_only implics + , wc_holes = filterBag isOutOfScopeHole holes } where implic_insols_only implic = implic { ic_wanted = insolublesOnly (ic_wanted implic) } @@ -953,9 +988,10 @@ insolubleImplic :: Implication -> Bool insolubleImplic ic = isInsolubleStatus (ic_status ic) insolubleWC :: WantedConstraints -> Bool -insolubleWC (WC { wc_impl = implics, wc_simple = simples }) +insolubleWC (WC { wc_impl = implics, wc_simple = simples, wc_holes = holes }) = anyBag insolubleCt simples || anyBag insolubleImplic implics + || anyBag isOutOfScopeHole holes -- See Note [Insoluble holes] insolubleCt :: Ct -> Bool -- Definitely insoluble, in particular /excluding/ type-hole constraints @@ -963,7 +999,6 @@ insolubleCt :: Ct -> Bool -- b) that is insoluble -- c) and does not arise from a Given insolubleCt ct - | isHoleCt ct = isOutOfScopeCt ct -- See Note [Insoluble holes] | not (insolubleEqCt ct) = False | arisesFromGivens ct = False -- See Note [Given insolubles] | otherwise = True @@ -986,11 +1021,17 @@ insolubleEqCt :: Ct -> Bool insolubleEqCt (CIrredCan { cc_status = InsolubleCIS }) = True insolubleEqCt _ = False +-- | Does this hole represent an "out of scope" error? +-- See Note [Insoluble holes] +isOutOfScopeHole :: Hole -> Bool +isOutOfScopeHole (Hole { hole_occ = occ }) = not (startsWithUnderscore occ) + instance Outputable WantedConstraints where - ppr (WC {wc_simple = s, wc_impl = i}) + ppr (WC {wc_simple = s, wc_impl = i, wc_holes = h}) = text "WC" <+> braces (vcat [ ppr_bag (text "wc_simple") s - , ppr_bag (text "wc_impl") i ]) + , ppr_bag (text "wc_impl") i + , ppr_bag (text "wc_holes") h ]) ppr_bag :: Outputable a => SDoc -> Bag a -> SDoc ppr_bag doc bag @@ -1035,7 +1076,7 @@ Hole constraints that ARE NOT treated as truly insoluble: a) type holes, arising from PartialTypeSignatures, b) "true" expression holes arising from TypedHoles -An "expression hole" or "type hole" constraint isn't really an error +An "expression hole" or "type hole" isn't really an error at all; it's a report saying "_ :: Int" here. But an out-of-scope variable masquerading as expression holes IS treated as truly insoluble, so that it trumps other errors during error reporting. @@ -1512,10 +1553,6 @@ ctFlavourRole (CTyEqCan { cc_ev = ev, cc_eq_rel = eq_rel }) = (ctEvFlavour ev, eq_rel) ctFlavourRole (CFunEqCan { cc_ev = ev }) = (ctEvFlavour ev, NomEq) -ctFlavourRole (CHoleCan { cc_ev = ev }) - = (ctEvFlavour ev, NomEq) -- NomEq: CHoleCans can be rewritten by - -- by nominal equalities but empahatically - -- not by representational equalities ctFlavourRole ct = ctEvFlavourRole (ctEvidence ct) ===================================== compiler/GHC/Tc/Types/Origin.hs ===================================== @@ -427,7 +427,9 @@ data CtOrigin -- We only need a CtOrigin on the first, because the location -- is pinned on the entire error message - | HoleOrigin + | ExprHoleOrigin OccName -- from an expression hole + | TypeHoleOrigin OccName -- from a type hole (partial type signature) + | PatCheckOrigin -- normalisation of a type during pattern-match checking | UnboundOccurrenceOf OccName | ListOrigin -- An overloaded list | BracketOrigin -- An overloaded quotation bracket @@ -640,7 +642,9 @@ pprCtO MCompOrigin = text "a statement in a monad comprehension" pprCtO ProcOrigin = text "a proc expression" pprCtO (TypeEqOrigin t1 t2 _ _)= text "a type equality" <+> sep [ppr t1, char '~', ppr t2] pprCtO AnnOrigin = text "an annotation" -pprCtO HoleOrigin = text "a use of" <+> quotes (text "_") +pprCtO (ExprHoleOrigin occ) = text "a use of" <+> quotes (ppr occ) +pprCtO (TypeHoleOrigin occ) = text "a use of wildcard" <+> quotes (ppr occ) +pprCtO PatCheckOrigin = text "a pattern-match completeness check" pprCtO ListOrigin = text "an overloaded list" pprCtO StaticOrigin = text "a static form" pprCtO BracketOrigin = text "a quotation bracket" ===================================== compiler/GHC/Tc/Utils/Monad.hs ===================================== @@ -98,14 +98,14 @@ module GHC.Tc.Utils.Monad( chooseUniqueOccTc, getConstraintVar, setConstraintVar, emitConstraints, emitStaticConstraints, emitSimple, emitSimples, - emitImplication, emitImplications, emitInsoluble, + emitImplication, emitImplications, emitInsoluble, emitHole, discardConstraints, captureConstraints, tryCaptureConstraints, pushLevelAndCaptureConstraints, pushTcLevelM_, pushTcLevelM, pushTcLevelsM, getTcLevel, setTcLevel, isTouchableTcM, getLclTypeEnv, setLclTypeEnv, traceTcConstraints, - emitNamedWildCardHoleConstraints, emitAnonWildCardHoleConstraint, + emitNamedTypeHole, emitAnonTypeHole, -- * Template Haskell context recordThUse, recordThSpliceUse, @@ -1569,12 +1569,11 @@ emitInsoluble ct ; lie_var <- getConstraintVar ; updTcRef lie_var (`addInsols` unitBag ct) } -emitInsolubles :: Cts -> TcM () -emitInsolubles cts - | isEmptyBag cts = return () - | otherwise = do { traceTc "emitInsolubles" (ppr cts) - ; lie_var <- getConstraintVar - ; updTcRef lie_var (`addInsols` cts) } +emitHole :: Hole -> TcM () +emitHole hole + = do { traceTc "emitHole" (ppr hole) + ; lie_var <- getConstraintVar + ; updTcRef lie_var (`addHole` hole) } -- | Throw out any constraints emitted by the thing_inside discardConstraints :: TcM a -> TcM a @@ -1644,34 +1643,28 @@ traceTcConstraints msg hang (text (msg ++ ": LIE:")) 2 (ppr lie) } -emitAnonWildCardHoleConstraint :: TcTyVar -> TcM () -emitAnonWildCardHoleConstraint tv - = do { ct_loc <- getCtLocM HoleOrigin Nothing - ; emitInsolubles $ unitBag $ - CHoleCan { cc_ev = CtDerived { ctev_pred = mkTyVarTy tv - , ctev_loc = ct_loc } - , cc_occ = mkTyVarOcc "_" - , cc_hole = TypeHole } } - -emitNamedWildCardHoleConstraints :: [(Name, TcTyVar)] -> TcM () -emitNamedWildCardHoleConstraints wcs - = do { ct_loc <- getCtLocM HoleOrigin Nothing - ; emitInsolubles $ listToBag $ - map (do_one ct_loc) wcs } +emitAnonTypeHole :: TcTyVar -> TcM () +emitAnonTypeHole tv + = do { ct_loc <- getCtLocM (TypeHoleOrigin occ) Nothing + ; let hole = Hole { hole_sort = TypeHole + , hole_occ = occ + , hole_ty = mkTyVarTy tv + , hole_loc = ct_loc } + ; emitHole hole } + where + occ = mkTyVarOcc "_" + +emitNamedTypeHole :: (Name, TcTyVar) -> TcM () +emitNamedTypeHole (name, tv) + = do { ct_loc <- setSrcSpan (nameSrcSpan name) $ + getCtLocM (TypeHoleOrigin occ) Nothing + ; let hole = Hole { hole_sort = TypeHole + , hole_occ = occ + , hole_ty = mkTyVarTy tv + , hole_loc = ct_loc } + ; emitHole hole } where - do_one :: CtLoc -> (Name, TcTyVar) -> Ct - do_one ct_loc (name, tv) - = CHoleCan { cc_ev = CtDerived { ctev_pred = mkTyVarTy tv - , ctev_loc = ct_loc' } - , cc_occ = occName name - , cc_hole = TypeHole } - where - real_span = case nameSrcSpan name of - RealSrcSpan span _ -> span - UnhelpfulSpan str -> pprPanic "emitNamedWildCardHoleConstraints" - (ppr name <+> quotes (ftext str)) - -- Wildcards are defined locally, and so have RealSrcSpans - ct_loc' = setCtLocSpan ct_loc real_span + occ = nameOccName name {- Note [Constraints and errors] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Tc/Utils/TcMType.hs ===================================== @@ -41,10 +41,11 @@ module GHC.Tc.Utils.TcMType ( -------------------------------- -- Creating new evidence variables newEvVar, newEvVars, newDict, - newWanted, newWanteds, newHoleCt, cloneWanted, cloneWC, + newWanted, newWanteds, cloneWanted, cloneWC, emitWanted, emitWantedEq, emitWantedEvVar, emitWantedEvVars, emitDerivedEqs, newTcEvBinds, newNoTcEvBinds, addTcEvBind, + emitNewExprHole, newCoercionHole, fillCoercionHole, isFilledCoercionHole, unpackCoercionHole, unpackCoercionHole_maybe, @@ -67,7 +68,7 @@ module GHC.Tc.Utils.TcMType ( -------------------------------- -- Zonking and tidying zonkTidyTcType, zonkTidyTcTypes, zonkTidyOrigin, - tidyEvVar, tidyCt, tidySkolemInfo, + tidyEvVar, tidyCt, tidyHole, tidySkolemInfo, zonkTcTyVar, zonkTcTyVars, zonkTcTyVarToTyVar, zonkTyVarTyVarPairs, zonkTyCoVarsAndFV, zonkTcTypeAndFV, zonkDTyCoVarSetAndFV, @@ -193,17 +194,6 @@ newWanted orig t_or_k pty newWanteds :: CtOrigin -> ThetaType -> TcM [CtEvidence] newWanteds orig = mapM (newWanted orig Nothing) --- | Create a new 'CHoleCan' 'Ct'. -newHoleCt :: HoleSort -> Id -> Type -> TcM Ct -newHoleCt hole ev ty = do - loc <- getCtLocM HoleOrigin Nothing - pure $ CHoleCan { cc_ev = CtWanted { ctev_pred = ty - , ctev_dest = EvVarDest ev - , ctev_nosh = WDeriv - , ctev_loc = loc } - , cc_occ = getOccName ev - , cc_hole = hole } - ---------------------------------------------- -- Cloning constraints ---------------------------------------------- @@ -286,6 +276,18 @@ emitWantedEvVar origin ty emitWantedEvVars :: CtOrigin -> [TcPredType] -> TcM [EvVar] emitWantedEvVars orig = mapM (emitWantedEvVar orig) +-- | Emit a new wanted expression hole +emitNewExprHole :: OccName -- of the hole + -> Id -- of the evidence + -> Type -> TcM () +emitNewExprHole occ ev_id ty + = do { loc <- getCtLocM (ExprHoleOrigin occ) (Just TypeLevel) + ; let hole = Hole { hole_sort = ExprHole ev_id + , hole_occ = getOccName ev_id + , hole_ty = ty + , hole_loc = loc } + ; emitHole hole } + newDict :: Class -> [TcType] -> TcM DictId newDict cls tys = do { name <- newSysName (mkDictOcc (getOccName cls)) @@ -2002,21 +2004,28 @@ zonkWC :: WantedConstraints -> TcM WantedConstraints zonkWC wc = zonkWCRec wc zonkWCRec :: WantedConstraints -> TcM WantedConstraints -zonkWCRec (WC { wc_simple = simple, wc_impl = implic }) +zonkWCRec (WC { wc_simple = simple, wc_impl = implic, wc_holes = holes }) = do { simple' <- zonkSimples simple ; implic' <- mapBagM zonkImplication implic - ; return (WC { wc_simple = simple', wc_impl = implic' }) } + ; holes' <- mapBagM zonkHole holes + ; return (WC { wc_simple = simple', wc_impl = implic', wc_holes = holes' }) } zonkSimples :: Cts -> TcM Cts zonkSimples cts = do { cts' <- mapBagM zonkCt cts ; traceTc "zonkSimples done:" (ppr cts') ; return cts' } +zonkHole :: Hole -> TcM Hole +zonkHole hole@(Hole { hole_ty = ty }) + = do { ty' <- zonkTcType ty + ; return (hole { hole_ty = ty' }) } + -- No need to zonk the Id in any ExprHole because we never look at it + -- until after the final zonk and desugaring + {- Note [zonkCt behaviour] ~~~~~~~~~~~~~~~~~~~~~~~~~~ zonkCt tries to maintain the canonical form of a Ct. For example, - a CDictCan should stay a CDictCan; - - a CHoleCan should stay a CHoleCan - a CIrredCan should stay a CIrredCan with its cc_status flag intact Why?, for example: @@ -2026,8 +2035,6 @@ Why?, for example: don't preserve a canonical form, @expandSuperClasses@ fails to expand superclasses. This is what happened in #11525. -- For CHoleCan, once we forget that it's a hole, we can never recover that info. - - For CIrredCan we want to see if a constraint is insoluble with insolubleWC On the other hand, we change CTyEqCan to CNonCanonical, because of all of @@ -2046,10 +2053,6 @@ creates e.g. a CDictCan where the cc_tyars are /not/ function free. zonkCt :: Ct -> TcM Ct -- See Note [zonkCt behaviour] -zonkCt ct@(CHoleCan { cc_ev = ev }) - = do { ev' <- zonkCtEvidence ev - ; return $ ct { cc_ev = ev' } } - zonkCt ct@(CDictCan { cc_ev = ev, cc_tyargs = args }) = do { ev' <- zonkCtEvidence ev ; args' <- mapM zonkTcType args @@ -2262,17 +2265,15 @@ zonkTidyOrigin env orig = return (env, orig) tidyCt :: TidyEnv -> Ct -> Ct -- Used only in error reporting tidyCt env ct - = ct { cc_ev = tidy_ev env (ctEvidence ct) } + = ct { cc_ev = tidy_ev (ctEvidence ct) } where - tidy_ev :: TidyEnv -> CtEvidence -> CtEvidence + tidy_ev :: CtEvidence -> CtEvidence -- NB: we do not tidy the ctev_evar field because we don't -- show it in error messages - tidy_ev env ctev@(CtGiven { ctev_pred = pred }) - = ctev { ctev_pred = tidyType env pred } - tidy_ev env ctev@(CtWanted { ctev_pred = pred }) - = ctev { ctev_pred = tidyType env pred } - tidy_ev env ctev@(CtDerived { ctev_pred = pred }) - = ctev { ctev_pred = tidyType env pred } + tidy_ev ctev = ctev { ctev_pred = tidyType env (ctev_pred ctev) } + +tidyHole :: TidyEnv -> Hole -> Hole +tidyHole env h@(Hole { hole_ty = ty }) = h { hole_ty = tidyType env ty } ---------------- tidyEvVar :: TidyEnv -> EvVar -> EvVar ===================================== testsuite/tests/partial-sigs/should_compile/SplicesUsed.stderr ===================================== @@ -34,7 +34,7 @@ SplicesUsed.hs:10:16: warning: [-Wpartial-type-signatures (in -Wdefault)] In the type signature: charA :: a -> (_) SplicesUsed.hs:13:13: warning: [-Wpartial-type-signatures (in -Wdefault)] - • Found type wildcard ‘_’ standing for ‘a -> Bool’ + • Found type wildcard ‘_’ standing for ‘[a]’ Where: ‘a’ is a rigid type variable bound by the inferred type of filter' :: (a -> Bool) -> [a] -> [a] at SplicesUsed.hs:14:1-16 @@ -50,7 +50,7 @@ SplicesUsed.hs:13:13: warning: [-Wpartial-type-signatures (in -Wdefault)] In the type signature: filter' :: (_ -> _ -> _) SplicesUsed.hs:13:13: warning: [-Wpartial-type-signatures (in -Wdefault)] - • Found type wildcard ‘_’ standing for ‘[a]’ + • Found type wildcard ‘_’ standing for ‘a -> Bool’ Where: ‘a’ is a rigid type variable bound by the inferred type of filter' :: (a -> Bool) -> [a] -> [a] at SplicesUsed.hs:14:1-16 @@ -58,26 +58,26 @@ SplicesUsed.hs:13:13: warning: [-Wpartial-type-signatures (in -Wdefault)] In the type signature: filter' :: (_ -> _ -> _) SplicesUsed.hs:16:2: warning: [-Wpartial-type-signatures (in -Wdefault)] - • Found type wildcard ‘_’ standing for ‘Eq a’ + • Found type wildcard ‘_’ standing for ‘a -> a -> Bool’ Where: ‘a’ is a rigid type variable bound by the inferred type of foo :: Eq a => a -> a -> Bool at SplicesUsed.hs:16:2-11 • In the type signature: foo :: _ => _ SplicesUsed.hs:16:2: warning: [-Wpartial-type-signatures (in -Wdefault)] - • Found type wildcard ‘_’ standing for ‘a -> a -> Bool’ + • Found type wildcard ‘_’ standing for ‘Eq a’ Where: ‘a’ is a rigid type variable bound by the inferred type of foo :: Eq a => a -> a -> Bool at SplicesUsed.hs:16:2-11 • In the type signature: foo :: _ => _ -SplicesUsed.hs:18:2: warning: [-Wpartial-type-signatures (in -Wdefault)] - • Found type wildcard ‘_a’ standing for ‘Bool’ - • In the type signature: bar :: _a -> _b -> (_a, _b) - SplicesUsed.hs:18:2: warning: [-Wpartial-type-signatures (in -Wdefault)] • Found type wildcard ‘_b’ standing for ‘_’ Where: ‘_’ is a rigid type variable bound by the inferred type of bar :: Bool -> _ -> (Bool, _) at SplicesUsed.hs:18:2-11 • In the type signature: bar :: _a -> _b -> (_a, _b) + +SplicesUsed.hs:18:2: warning: [-Wpartial-type-signatures (in -Wdefault)] + • Found type wildcard ‘_a’ standing for ‘Bool’ + • In the type signature: bar :: _a -> _b -> (_a, _b) ===================================== testsuite/tests/plugins/hole-fit-plugin/HoleFitPlugin.hs ===================================== @@ -3,8 +3,6 @@ module HoleFitPlugin where import GHC.Plugins hiding ((<>)) -import GHC.Tc.Errors.Hole - import Data.List (stripPrefix, sortOn) import GHC.Tc.Types.Constraint @@ -34,7 +32,7 @@ fromModule (GreHFCand gre) = fromModule _ = [] toHoleFitCommand :: TypedHole -> String -> Maybe String -toHoleFitCommand TyH{tyHCt = Just (CHoleCan _ h _)} str +toHoleFitCommand (TypedHole {th_hole = Just (Hole { hole_occ = h })}) str = stripPrefix ("_" <> str) $ occNameString h toHoleFitCommand _ _ = Nothing ===================================== testsuite/tests/th/T12411.stderr ===================================== @@ -2,7 +2,7 @@ T12411.hs:4:6: error: Variable not in scope: (@) - :: (a0 -> f0 a0) -> t0 -> Language.Haskell.TH.Lib.Internal.DecsQ + :: (a1 -> f0 a1) -> t0 -> Language.Haskell.TH.Lib.Internal.DecsQ T12411.hs:4:7: error: - Data constructor not in scope: Q :: [a1] -> t0 + Data constructor not in scope: Q :: [a0] -> t0 ===================================== testsuite/tests/typecheck/should_fail/T12589.stderr ===================================== @@ -1,8 +1,8 @@ -T12589.hs:13:3: error: Variable not in scope: (&) :: t1 -> t0 -> t +T12589.hs:13:3: error: Variable not in scope: (&) :: t0 -> t1 -> t T12589.hs:13:5: error: - • Cannot instantiate unification variable ‘t0’ + • Cannot instantiate unification variable ‘t1’ with a type involving polytypes: (forall a. Bounded a => f0 a) -> h0 f0 xs0 GHC doesn't yet support impredicative polymorphism View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3f4aaac646dd921f6fa202a0fd8c32d124522caf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3f4aaac646dd921f6fa202a0fd8c32d124522caf You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 4 11:01:53 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Mon, 04 May 2020 07:01:53 -0400 Subject: [Git][ghc/ghc][wip/T17775] 12 commits: rts: Enable tracing of nonmoving heap census with -ln Message-ID: <5eaff621898d1_6167e5b152c8656731@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: 7bfe9ac5 by Ben Gamari at 2020-05-03T04:41:33-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. - - - - - c560dd07 by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Move eventlog documentation users guide - - - - - 02543d5e by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Add documentation for non-moving GC events - - - - - b465dd45 by Alexis King at 2020-05-03T04:42:12-04:00 Flatten nested casts in the simple optimizer Normally, we aren’t supposed to generated any nested casts, since mkCast takes care to flatten them, but the simple optimizer didn’t use mkCast, so they could show up after inlining. This isn’t really a problem, since the simplifier will clean them up immediately anyway, but it can clutter the -ddump-ds output, and it’s an extremely easy fix. closes #18112 - - - - - 8bdc03d6 by Simon Peyton Jones at 2020-05-04T01:56:59-04:00 Don't return a panic in tcNestedSplice In GHC.Tc.Gen.Splice.tcNestedSplice we were returning a typechecked expression of "panic". That is usually OK, because the result is discarded. But it happens that tcApp now looks at the typechecked expression, trivially, to ask if it is tagToEnum. So being bottom is bad. Moreover a debug-trace might print it out. So better to return a civilised expression, even though it is usually discarded. - - - - - 0bf640b1 by Baldur Blöndal at 2020-05-04T01:57:36-04:00 Don't require parentheses around via type (`-XDerivingVia'). Fixes #18130". - - - - - 26aedf3d by Simon Peyton Jones at 2020-05-04T11:18:15+01:00 Simple subsumption This patch simplifies GHC to use simple subsumption. Ticket #17775 Implements GHC proposal #287 https://github.com/ghc-proposals/ghc-proposals/blob/master/ proposals/0287-simplify-subsumption.rst All the motivation is described there; I will not repeat it here. The implementation payload: * tcSubType and friends become noticably simpler, because it no longer uses eta-expansion when checking subsumption. * No deeplyInstantiate or deeplySkolemise That in turn means that some tests fail, by design; they can all be fixed by eta expansion. There is a list of such changes below. Implementing the patch led me into a variety of sticky corners, so the patch includes several othe changes, some quite significant: * I made String wired-in, so that "foo" :: String rather than "foo" :: [Char] This improves error messages, and fixes #15679 * isTauTy: was replying True for (Show a => a ->a), which is utterly bogus. Fixed. * The pattern match checker relies on knowing about in-scope equality constraints, andd adds them to the desugarer's environment using addTyCsDs. But the co_fn in a FunBind was missed, and for some reason simple-subsumption ends up with dictionaries there. So I added a call to addTyCsDs. This is really part of #18049. * I moved the ic_telescope field out of Implication and into ForAllSkol instead. This is a nice win; just expresses the code much better. * There was a bug in GHC.Tc.TyCl.Instance.tcDataFamInstHeader. We called checkDataKindSig inside tc_kind_sig, /before/ solveEqualities and zonking. Obviously wrong, easily fixed. * solveLocalEqualitiesX: there was a whole mess in here, around failing fast enough. I discovered a bad latent bug where we could successfully kind-check a type signature, and use it, but have unsolved constraints that could fill in coercion holes in that signature -- aargh. It's all explained in Note [Failure in local type signatures] in GHC.Tc.Solver. Much better now. * I fixed a serious bug in anonymous type holes. IN f :: Int -> (forall a. a -> _) -> Int that "_" should be a unification variable at the /outer/ level; it cannot be instantiated to 'a'. This was plain wrong. New fields mode_lvl and mode_holes in TcTyMode, and auxiliary data type GHC.Tc.Gen.HsType.HoleMode. This fixes #16292, but makes no progress towards the more ambitious #16082 * I got sucked into an enormous refactoring of the reporting of equality errors in GHC.Tc.Errors, especially in mkEqErr1 mkTyVarEqErr misMatchMsg misMatchMsgOrCND In particular, the very tricky mkExpectedActualMsg function is gone. It took me a full day. But the result is far easier to understand. (Still not easy!) This led to various minor improvements in error output, and an enormous number of test-case error wibbles. One particular point: for occurs-check errors I now just say Can't match 'a' against '[a]' rather than using the intimidating language of "occurs check". * Pretty-printing AbsBinds Tests review * Eta expansions T11305: one eta expansion T12082: one eta expansion (undefined) T13585a: one eta expansion T3102: one eta expansion T3692: two eta expansions (tricky) T2239: two eta expansions T16473: one eta determ004: two eta expansions (undefined) annfail06: two eta (undefined) T17923: four eta expansions (a strange program indeed!) tcrun035: one eta expansion * Ambiguity check at higher rank. Now that we have simple subsumption, a type like f :: (forall a. Eq a => Int) -> Int is no longer ambiguous, because we could write g :: (forall a. Eq a => Int) -> Int g = f and it'd typecheck just fine. But f's type is a bit suspicious, and we might want to consider making the ambiguity check do a check on each sub-term. Meanwhile, these tests are accepted, whereas they were previously rejected as ambiguous: T7220a T15438 T10503 T9222 * Some more interesting error message wibbles T13381: Fine: one error (Int ~ Exp Int) rather than two (Int ~ Exp Int, Exp Int ~ Int) T9834: Small change in error (improvement) T10619: Improved T2414: Small change, due to order of unification, fine T2534: A very simple case in which a change of unification order means we get tow unsolved constraints instead of one tc211: bizarre impredicative tests; just accept this for now - - - - - a6b1ee08 by Simon Peyton Jones at 2020-05-04T11:18:16+01:00 Wibbles Especially make major improvement to hsWrapDictBinders - - - - - 3310af0c by Simon Peyton Jones at 2020-05-04T11:18:16+01:00 Wibbles esp to tcPolyCheck - - - - - 52089110 by Simon Peyton Jones at 2020-05-04T11:18:16+01:00 Wibbles - - - - - 54d93222 by Simon Peyton Jones at 2020-05-04T11:18:16+01:00 Wibbles - - - - - 188205d6 by Simon Peyton Jones at 2020-05-04T12:01:25+01:00 Wibbles (dynamic-paper ticks) - - - - - 23 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Types.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Parser.y - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Splice.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Default.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Expr.hs-boot - compiler/GHC/Tc/Gen/Foreign.hs - compiler/GHC/Tc/Gen/HsType.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b4d28d52e62db37a11f58a4c035d5414c4ed9209...188205d687bac490ed8bd7a038569aca15c25a68 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b4d28d52e62db37a11f58a4c035d5414c4ed9209...188205d687bac490ed8bd7a038569aca15c25a68 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 4 11:02:30 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Mon, 04 May 2020 07:02:30 -0400 Subject: [Git][ghc/ghc][wip/T18127] 7 commits: rts: Enable tracing of nonmoving heap census with -ln Message-ID: <5eaff646d6575_6167e5b152c865794@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T18127 at Glasgow Haskell Compiler / GHC Commits: 7bfe9ac5 by Ben Gamari at 2020-05-03T04:41:33-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. - - - - - c560dd07 by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Move eventlog documentation users guide - - - - - 02543d5e by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Add documentation for non-moving GC events - - - - - b465dd45 by Alexis King at 2020-05-03T04:42:12-04:00 Flatten nested casts in the simple optimizer Normally, we aren’t supposed to generated any nested casts, since mkCast takes care to flatten them, but the simple optimizer didn’t use mkCast, so they could show up after inlining. This isn’t really a problem, since the simplifier will clean them up immediately anyway, but it can clutter the -ddump-ds output, and it’s an extremely easy fix. closes #18112 - - - - - 8bdc03d6 by Simon Peyton Jones at 2020-05-04T01:56:59-04:00 Don't return a panic in tcNestedSplice In GHC.Tc.Gen.Splice.tcNestedSplice we were returning a typechecked expression of "panic". That is usually OK, because the result is discarded. But it happens that tcApp now looks at the typechecked expression, trivially, to ask if it is tagToEnum. So being bottom is bad. Moreover a debug-trace might print it out. So better to return a civilised expression, even though it is usually discarded. - - - - - 0bf640b1 by Baldur Blöndal at 2020-05-04T01:57:36-04:00 Don't require parentheses around via type (`-XDerivingVia'). Fixes #18130". - - - - - 6687b27b by Ryan Scott at 2020-05-04T07:02:03-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _)`. Fixes #18127. - - - - - 27 changed files: - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Parser.y - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Splice.hs - docs/users_guide/conf.py - docs/users_guide/eventlog-formats.rst - docs/users_guide/runtime_control.rst - includes/rts/EventLogFormat.h - rts/RtsFlags.c - rts/sm/NonMoving.c - + testsuite/tests/deSugar/should_compile/T18112.hs - testsuite/tests/deSugar/should_compile/all.T - testsuite/tests/dependent/should_compile/dynamic-paper.stderr - + testsuite/tests/deriving/should_fail/T18127b.hs - + testsuite/tests/deriving/should_fail/T18127b.stderr - testsuite/tests/deriving/should_fail/all.T - + testsuite/tests/parser/should_compile/T18130.hs - testsuite/tests/parser/should_compile/all.T - + testsuite/tests/parser/should_fail/T18130Fail.hs - + testsuite/tests/parser/should_fail/T18130Fail.stderr - testsuite/tests/parser/should_fail/all.T - + testsuite/tests/th/T18121.hs - testsuite/tests/th/all.T - + testsuite/tests/typecheck/should_fail/T18127a.hs - + testsuite/tests/typecheck/should_fail/T18127a.stderr - testsuite/tests/typecheck/should_fail/all.T Changes: ===================================== compiler/GHC/Core/SimpleOpt.hs ===================================== @@ -221,10 +221,13 @@ simple_opt_expr env expr go (Coercion co) = Coercion (optCoercion (soe_dflags env) (getTCvSubst subst) co) go (Lit lit) = Lit lit go (Tick tickish e) = mkTick (substTickish subst tickish) (go e) - go (Cast e co) | isReflCo co' = go e - | otherwise = Cast (go e) co' - where - co' = optCoercion (soe_dflags env) (getTCvSubst subst) co + go (Cast e co) = case go e of + -- flatten nested casts before calling the coercion optimizer; + -- see #18112 (note that mkCast handles dropping Refl coercions) + Cast e' co' -> mkCast e' (opt_co (mkTransCo co' co)) + e' -> mkCast e' (opt_co co) + where + opt_co = optCoercion (soe_dflags env) (getTCvSubst subst) go (Let bind body) = case simple_opt_bind env bind NotTopLevel of (env', Nothing) -> simple_opt_expr env' body ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -1857,17 +1857,19 @@ fun_kind_arg_flags = go emptyTCvSubst -- something is ill-kinded. But this can happen -- when printing errors. Assume everything is Required. --- @isTauTy@ tests if a type has no foralls +-- @isTauTy@ tests if a type has no foralls or (=>) isTauTy :: Type -> Bool isTauTy ty | Just ty' <- coreView ty = isTauTy ty' -isTauTy (TyVarTy _) = True -isTauTy (LitTy {}) = True -isTauTy (TyConApp tc tys) = all isTauTy tys && isTauTyCon tc -isTauTy (AppTy a b) = isTauTy a && isTauTy b -isTauTy (FunTy _ a b) = isTauTy a && isTauTy b -isTauTy (ForAllTy {}) = False -isTauTy (CastTy ty _) = isTauTy ty -isTauTy (CoercionTy _) = False -- Not sure about this +isTauTy (TyVarTy _) = True +isTauTy (LitTy {}) = True +isTauTy (TyConApp tc tys) = all isTauTy tys && isTauTyCon tc +isTauTy (AppTy a b) = isTauTy a && isTauTy b +isTauTy (FunTy af a b) = case af of + InvisArg -> False -- e.g., Eq a => b + VisArg -> isTauTy a && isTauTy b -- e.g., a -> b +isTauTy (ForAllTy {}) = False +isTauTy (CastTy ty _) = isTauTy ty +isTauTy (CoercionTy _) = False -- Not sure about this {- %************************************************************************ ===================================== compiler/GHC/Parser.y ===================================== @@ -1209,8 +1209,8 @@ deriv_strategy_no_via :: { LDerivStrategy GhcPs } [mj AnnNewtype $1] } deriv_strategy_via :: { LDerivStrategy GhcPs } - : 'via' type {% ams (sLL $1 $> (ViaStrategy (mkLHsSigType $2))) - [mj AnnVia $1] } + : 'via' ktype {% ams (sLL $1 $> (ViaStrategy (mkLHsSigType $2))) + [mj AnnVia $1] } deriv_standalone_strategy :: { Maybe (LDerivStrategy GhcPs) } : 'stock' {% ajs (sL1 $1 StockStrategy) ===================================== compiler/GHC/Tc/Gen/Expr.hs ===================================== @@ -981,12 +981,9 @@ tcExpr (HsSpliceE _ (HsSpliced _ mod_finalizers (HsSplicedExpr expr))) res_ty = do addModFinalizersWithLclEnv mod_finalizers tcExpr expr res_ty -tcExpr (HsSpliceE _ splice) res_ty - = tcSpliceExpr splice res_ty -tcExpr e@(HsBracket _ brack) res_ty - = tcTypedBracket e brack res_ty -tcExpr e@(HsRnBracketOut _ brack ps) res_ty - = tcUntypedBracket e brack ps res_ty +tcExpr (HsSpliceE _ splice) res_ty = tcSpliceExpr splice res_ty +tcExpr e@(HsBracket _ brack) res_ty = tcTypedBracket e brack res_ty +tcExpr e@(HsRnBracketOut _ brack ps) res_ty = tcUntypedBracket e brack ps res_ty {- ************************************************************************ @@ -1219,7 +1216,11 @@ tcApp expr res_ty = do { (fun, args, app_res_ty) <- tcInferApp expr ; if isTagToEnum fun then tcTagToEnum expr fun args app_res_ty res_ty - else -- The wildly common case + -- Done here because we have res_ty, + -- whereas tcInferApp does not + else + + -- The wildly common case do { let expr' = applyHsArgs fun args ; addFunResCtxt True fun app_res_ty res_ty $ tcWrapResult expr expr' app_res_ty res_ty } } @@ -1232,10 +1233,10 @@ tcInferApp :: HsExpr GhcRn -- Also used by Module.tcRnExpr to implement GHCi :type tcInferApp expr | -- Gruesome special case for ambiguous record selectors - HsRecFld _ fld_lbl <- fun - , Ambiguous _ lbl <- fld_lbl -- Still ambiguous + HsRecFld _ fld_lbl <- fun + , Ambiguous _ lbl <- fld_lbl -- Still ambiguous , HsEValArg _ (L _ arg) : _ <- filterOut isArgPar args -- A value arg is first - , Just sig_ty <- obviousSig arg -- A type sig on the arg disambiguates + , Just sig_ty <- obviousSig arg -- A type sig on the arg disambiguates = do { sig_tc_ty <- tcHsSigWcType ExprSigCtxt sig_ty ; sel_name <- disambiguateSelector lbl sig_tc_ty ; (tc_fun, fun_ty) <- tcInferRecSelId (Unambiguous sel_name lbl) @@ -1259,11 +1260,7 @@ tcInferApp_finish -> TcM (HsExpr GhcTc, [LHsExprArgOut], TcSigmaType) tcInferApp_finish rn_fun tc_fun fun_sigma rn_args - = do { traceTc "tcInferApp_finish" $ - vcat [ ppr rn_fun <+> dcolon <+> ppr fun_sigma, ppr rn_args ] - - ; (tc_args, actual_res_ty) <- tcArgs rn_fun fun_sigma rn_args - + = do { (tc_args, actual_res_ty) <- tcArgs rn_fun fun_sigma rn_args ; return (tc_fun, tc_args, actual_res_ty) } mk_op_msg :: LHsExpr GhcRn -> SDoc ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -625,7 +625,13 @@ tcNestedSplice pop_stage (TcPending ps_var lie_var q@(QuoteWrapper _ m_var)) spl ; writeMutVar ps_var (PendingTcSplice splice_name expr'' : ps) -- The returned expression is ignored; it's in the pending splices - ; return (panic "tcSpliceExpr") } + -- But we still return a plausible expression + -- (a) in case we print it in debug messages, and + -- (b) because we test whether it is tagToEnum in Tc.Gen.Expr.tcApp + ; return (HsSpliceE noExtField $ + HsSpliced noExtField (ThModFinalizers []) $ + HsSplicedExpr (unLoc expr'')) } + tcNestedSplice _ _ splice_name _ _ = pprPanic "tcNestedSplice: rename stage found" (ppr splice_name) ===================================== docs/users_guide/conf.py ===================================== @@ -283,8 +283,18 @@ def setup(app): objname='runtime system command-line option', parse_node=parse_flag, indextemplate='pair: %s; RTS option', + doc_field_types=[ + Field('since', label='Introduced in GHC version', names=['since']) + ]) + + app.add_object_type('event-type', 'event-type', + objname='event log event type', + indextemplate='pair: %s; eventlog event type', doc_field_types=[ Field('since', label='Introduced in GHC version', names=['since']), + Field('tag', label='Event type ID', names=['tag']), + Field('length', label='Record length', names=['length']), + TypedField('fields', label='Fields', names='field', typenames=('fieldtype', 'type')) ]) app.add_object_type('pragma', 'pragma', ===================================== docs/users_guide/eventlog-formats.rst ===================================== @@ -1,3 +1,5 @@ +.. _eventlog-encodings: + Eventlog encodings ================== @@ -7,6 +9,481 @@ thread scheduling events, garbage collection statistics, profiling information, user-defined tracing events. This section is intended for implementors of tooling which consume these events. +GHC ships with a C header file (``EventlogFormat.h``) which provides symbolic +names for the event type IDs described in this file. + + +Event log format +---------------- + +The log format is designed to be extensible: old tools should be +able to parse (but not necessarily understand all of) new versions +of the format, and new tools will be able to understand old log +files. + +- The format is endian-independent: all values are represented in + big-endian order. + +- The format is extensible: + + - The header describes each event type and its length. Tools + that don't recognise a particular event type can skip those events. + + - There is room for extra information in the event type + specification, which can be ignored by older tools. + + - Events can have extra information added, but existing fields + cannot be changed. Tools should ignore extra fields at the + end of the event record. + +The event-log stream begins with a header describing the event types present in +the file. The header is followed by the event records themselves, each of which +consist of a 64-bit timestamp + +.. code-block:: none + + log : EVENT_HEADER_BEGIN + EventType* + EVENT_HEADER_END + EVENT_DATA_BEGIN + Event* + EVENT_DATA_END + + EventType : + EVENT_ET_BEGIN + Word16 -- unique identifier for this event + Int16 -- >=0 size of the event in bytes (minus the header) + -- -1 variable size + Word32 -- length of the next field in bytes + Word8* -- string describing the event + Word32 -- length of the next field in bytes + Word8* -- extra info (for future extensions) + EVENT_ET_END + + Event : + Word16 -- event_type + Word64 -- time (nanosecs) + [Word16] -- length of the rest (for variable-sized events only) + ... extra event-specific info ... + +There are two classes of event types: + + - *Fixed size*: All event records of a fixed-sized type are of the same + length, given in the header event-log header. + + - *Variable size*: Each event record includes a length field. + +Runtime system diagnostics +-------------------------- + + * ``ThreadId ~ Word32`` + * ``CapNo ~ Word16`` + * ``CapSetId ~ Word32`` + +Capability sets +~~~~~~~~~~~~~~~ + +TODO + +Environment information +~~~~~~~~~~~~~~~~~~~~~~~ + +These events are typically produced during program startup and describe the +environment which the program is being run in. + +.. event-type:: RTS_IDENTIFIER + + :tag: 29 + :length: variable + :field CapSetId: Capability set + :field String: Runtime system name and version. + + Describes the name and version of the runtime system responsible for the + indicated capability set. + +.. event-type:: PROGRAM_ARGS + + :tag: 30 + :length: variable + :field CapSetId: Capability set + :field [String]: The command-line arguments passed to the program + + Describes the command-line used to start the program. + +.. event-type:: PROGRAM_ENV + + :tag: 31 + :length: variable + :field CapSetId: Capability set + :field [String]: The environment variable name/value pairs. (TODO: encoding?) + + Describes the environment variables present in the program's environment. + +Thread and scheduling events +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. event-type:: CREATE_THREAD + + :tag: 0 + :length: fixed + :field ThreadId: thread id + + Marks the creation of a Haskell thread. + + +.. event-type:: RUN_THREAD + + :tag: 1 + :length: fixed + :field ThreadId: thread id + + The indicated thread has started running. + + +.. event-type:: STOP_THREAD + + :tag: 2 + :length: fixed + :field ThreadId: thread id + :field Word16: status + + * 1: HeapOverflow + * 2: StackOverflow + * 3: ThreadYielding + * 4: ThreadBlocked + * 5: ThreadFinished + * 6: ForeignCall + * 7: BlockedOnMVar + * 8: BlockedOnBlackHole + * 9: BlockedOnRead + * 10: BlockedOnWrite + * 11: BlockedOnDelay + * 12: BlockedOnSTM + * 13: BlockedOnDoProc + * 16: BlockedOnMsgThrowTo + + :field ThreadId: thread id of thread being blocked on (only for some status + values) + + The indicated thread has stopped running for the reason given by ``status``. + + +.. event-type:: THREAD_RUNNABLE + + :tag: 3 + :length: fixed + :field ThreadId: thread id + + The indicated thread is has been marked as ready to run. + + +.. event-type:: MIGRATE_THREAD + + :tag: 4 + :length: fixed + :field ThreadId: thread id + :field CapNo: capability + + The indicated thread has been migrated to a new capability. + + +.. event-type:: THREAD_WAKEUP + + :tag: 8 + :length: fixed + :field ThreadId: thread id + :field CapNo: other capability + + The indicated thread has been been woken up on another capability. + +.. event-type:: THREAD_LABEL + + :tag: 44 + :length: fixed + :field ThreadId: thread id + :field String: label + + The indicated thread has been given a label (e.g. with + :base-ref:`Control.Concurrent.setThreadLabel`). + + +Garbage collector events +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. event-type:: GC_START + + :tag: 9 + :length: fixed + + A garbage collection pass has been started. + +.. event-type:: GC_END + + :tag: 10 + :length: fixed + + A garbage collection pass has been finished. + +.. event-type:: REQUEST_SEQ_GC + + :tag: 11 + :length: fixed + + A sequential garbage collection has been requested by a capability. + +.. event-type:: REQUEST_PAR_GC + + :tag: 12 + :length: fixed + + A parallel garbage collection has been requested by a capability. + +.. event-type:: GC_IDLE + + :tag: 20 + :length: fixed + + An idle-time garbage collection has been started. + +.. event-type:: GC_WORK + + :tag: 21 + :length: fixed + + Marks the start of concurrent scavenging. + +.. event-type:: GC_DONE + + :tag: 22 + :length: fixed + + Marks the end of concurrent scavenging. + +.. event-type:: GC_STATS_GHC + + :tag: 53 + :length: fixed + :field CapSetId: heap capability set + :field Word16: generation of collection + :field Word64: bytes copied + :field Word64: bytes of slop found + :field Word64: TODO + :field Word64: number of parallel garbage collection threads + :field Word64: maximum number of bytes copied by any single collector thread + :field Word64: total bytes copied by all collector threads + + Report various information about the heap configuration. Typically produced + during RTS initialization.. + +.. event-type:: GC_GLOBAL_SYNC + + :tag: 54 + :length: fixed + + TODO + +Heap events and statistics +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. event-type:: HEAP_ALLOCATED + + :tag: 49 + :length: fixed + :field CapSetId: heap capability set + :field Word64: allocated bytes + + A new chunk of heap has been allocated by the indicated capability set. + +.. event-type:: HEAP_SIZE + + :tag: 50 + :length: fixed + :field CapSetId: heap capability set + :field Word64: heap size in bytes + + Report the heap size. + +.. event-type:: HEAP_LIVE + + :tag: 51 + :length: fixed + :field CapSetId: heap capability set + :field Word64: heap size in bytes + + Report the live heap size. + +.. event-type:: HEAP_INFO_GHC + + :tag: 52 + :length: fixed + :field CapSetId: heap capability set + :field Word16: number of garbage collection generations + :field Word64: maximum heap size + :field Word64: allocation area size + :field Word64: MBlock size + :field Word64: Block size + + Report various information about the heap configuration. Typically produced + during RTS initialization.. + +Spark events +~~~~~~~~~~~~ + +.. event-type:: CREATE_SPARK_THREAD + + :tag: 15 + :length: fixed + + A thread has been created to perform spark evaluation. + +.. event-type:: SPARK_COUNTERS + + :tag: 34 + :length: fixed + + A periodic reporting of various statistics of spark evaluation. + +.. event-type:: SPARK_CREATE + + :tag: 35 + :length: fixed + + A spark has been added to the spark pool. + +.. event-type:: SPARK_DUD + + :tag: 36 + :length: fixed + + TODO + +.. event-type:: SPARK_OVERFLOW + + :tag: 37 + :length: fixed + + TODO + +.. event-type:: SPARK_RUN + + :tag: 38 + :length: fixed + + Evaluation has started on a spark. + +.. event-type:: SPARK_STEAL + + :tag: 39 + :length: fixed + :field Word16: capability from which the spark was stolen + + A spark has been stolen from another capability for evaluation. + +.. event-type:: SPARK_FIZZLE + + :tag: 40 + :length: fixed + + A spark has been GC'd before being evaluated. + +.. event-type:: SPARK_GC + + :tag: 41 + :length: fixed + + An unevaluated spark has been garbage collected. + +Capability events +~~~~~~~~~~~~~~~~~ + +.. event-type:: CAP_CREATE + + :tag: 45 + :length: fixed + :field CapNo: the capability number + + A capability has been started. + +.. event-type:: CAP_DELETE + + :tag: 46 + :length: fixed + + A capability has been deleted. + +.. event-type:: CAP_DISABLE + + :tag: 47 + :length: fixed + + A capability has been disabled. + +.. event-type:: CAP_ENABLE + + :tag: 48 + :length: fixed + + A capability has been enabled. + +Task events +~~~~~~~~~~~ + +.. event-type:: TASK_CREATE + + :tag: 55 + :length: fixed + :field TaskId: task id + :field CapNo: capability number + :field ThreadId: TODO + + Marks the creation of a task. + +.. event-type:: TASK_MIGRATE + + :tag: 56 + :length: fixed + :field TaskId: task id + :field CapNo: old capability + :field CapNo: new capability + + Marks the migration of a task to a new capability. + +Tracing events +~~~~~~~~~~~~~~ + +.. event-type:: LOG_MSG + + :tag: 16 + :length: variable + :field String: The message + + A log message from the runtime system. + +.. event-type:: BLOCK_MARKER + + :tag: 18 + :length: variable + :field Word32: size + :field Word64: end time in nanoseconds + :field String: marker name + + TODO + +.. event-type:: USER_MSG + + :tag: 19 + :length: variable + :field String: message + + A user log message (from, e.g., :base-ref:`Control.Concurrent.traceEvent`). + +.. event-type:: USER_MARKER + + :tag: 58 + :length: variable + :field String: marker name + + A user marker (from :base-ref:`Debug.Trace.traceMarker`). .. _heap-profiler-events: @@ -28,11 +505,13 @@ Beginning of sample stream A single fixed-width event emitted during program start-up describing the samples that follow. - * ``EVENT_HEAP_PROF_BEGIN`` +.. event-type:: HEAP_PROF_BEGIN - * ``Word8``: Profile ID - * ``Word64``: Sampling period in nanoseconds - * ``Word32``: Sample break-down type. One of, + :tag: 160 + :length: variable + :field Word8: profile ID + :field Word64: sampling period in nanoseconds + :field Word32: sample breadown type. One of, * ``HEAP_PROF_BREAKDOWN_COST_CENTER`` (output from :rts-flag:`-hc`) * ``HEAP_PROF_BREAKDOWN_CLOSURE_DESCR`` (output from :rts-flag:`-hd`) @@ -42,32 +521,34 @@ A single fixed-width event emitted during program start-up describing the sample * ``HEAP_PROF_BREAKDOWN_BIOGRAPHY`` (output from :rts-flag:`-hb`) * ``HEAP_PROF_BREAKDOWN_CLOSURE_TYPE`` (output from :rts-flag:`-hT`) - * ``String``: Module filter - * ``String``: Closure description filter - * ``String``: Type description filter - * ``String``: Cost centre filter - * ``String``: Cost centre stack filter - * ``String``: Retainer filter - * ``String``: Biography filter + :field String: module filter + :field String: closure description filter + :field String: type description filter + :field String: cost centre filter + :field String: cost centre stack filter + :field String: retainer filter + :field String: biography filter Cost centre definitions ^^^^^^^^^^^^^^^^^^^^^^^ A variable-length packet produced once for each cost centre, - * ``EVENT_HEAP_PROF_COST_CENTRE`` +.. event-type:: HEAP_PROF_COST_CENTRE - * ``Word32``: cost centre number - * ``String``: label - * ``String``: module - * ``String``: source location - * ``Word8``: flags + :tag: 161 + :length: fixed + :field Word32: cost centre number + :field String: label + :field String: module + :field String: source location + :field Word8: flags: * bit 0: is the cost-centre a CAF? Sample event types -~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^ A sample (consisting of a list of break-down classes, e.g. cost centres, and heap residency sizes), is to be encoded in the body of one or more events. @@ -75,9 +556,12 @@ heap residency sizes), is to be encoded in the body of one or more events. We normally mark the beginning of a new sample with an ``EVENT_HEAP_PROF_SAMPLE_BEGIN`` event, - * ``EVENT_HEAP_PROF_SAMPLE_BEGIN`` +.. event-type:: HEAP_PROF_SAMPLE_BEGIN + + :length: fixed + :field Word64: sample number - * ``Word64``: sample number + Marks the beginning of a heap profile sample. Biographical profiling samples start with the ``EVENT_HEAP_BIO_PROF_SAMPLE_BEGIN`` event. These events also include a timestamp which indicates when the sample @@ -85,11 +569,12 @@ was taken. This is because all these samples will appear at the end of the eventlog due to how the biographical profiling mode works. You can use the timestamp to reorder the samples relative to the other events. - * ``EVENT_HEAP_BIO_PROF_SAMPLE_BEGIN`` - - * ``Word64``: sample number - * ``Word64``: eventlog timestamp in ns +.. event-type:: HEAP_BIO_PROF_SAMPLE_BEGIN + :tag: 166 + :length: fixed + :field Word64: sample number + :field Word64: eventlog timestamp in ns A heap residency census will follow. Since events may only be up to 2^16^ bytes in length a single sample may need to be split among multiple @@ -101,23 +586,29 @@ emitted. This is useful to properly delimit the sampling period and to record the total time spent profiling. - * ``EVENT_HEAP_PROF_SAMPLE_END`` - * ``Word64``: sample number +.. event-type:: HEAP_PROF_SAMPLE_END + :tag: 165 + :length: fixed + :field Word64: sample number + + Marks the end of a heap profile sample. Cost-centre break-down ^^^^^^^^^^^^^^^^^^^^^^ A variable-length packet encoding a heap profile sample broken down by, - * cost-centre (``-hc``) + * cost-centre (:rts-flag:`-hc`) - * ``EVENT_HEAP_PROF_SAMPLE_COST_CENTRE`` +.. event-type:: HEAP_PROF_SAMPLE_COST_CENTRE - * ``Word8``: Profile ID - * ``Word64``: heap residency in bytes - * ``Word8``: stack depth - * ``Word32[]``: cost centre stack starting with inner-most (cost centre numbers) + :tag: 163 + :length: variable + :field Word8: profile ID + :field Word64: heap residency in bytes + :field Word8: stack depth + :field Word32[]: cost centre stack starting with inner-most (cost centre numbers) String break-down @@ -125,42 +616,142 @@ String break-down A variable-length event encoding a heap sample broken down by, - * type description (``-hy``) - * closure description (``-hd``) - * module (``-hm``) + * type description (:rts-flag:`-hy`) + * closure description (:rts-flag:`-hd`) + * module (:rts-flag:`-hm`) - * ``EVENT_HEAP_PROF_SAMPLE_STRING`` +.. event-type:: HEAP_PROF_SAMPLE_STRING - * ``Word8``: Profile ID - * ``Word64``: heap residency in bytes - * ``String``: type or closure description, or module name + :tag: 164 + :length: variable + :field Word8: profile ID + :field Word64: heap residency in bytes + :field String: type or closure description, or module name .. _time-profiler-events: Time profiler event log output ------------------------------ -The time profiling mode enabled by ``-p`` also emits sample events to the eventlog. -At the start of profiling the tick interval is emitted to the eventlog and then -on each tick the current cost centre stack is emitted. Together these enable -a user to construct an approximate track of the executation of their program. +The time profiling mode enabled by :rts-flag:`-p` also emits +sample events to the eventlog. At the start of profiling the +tick interval is emitted to the eventlog and then on each tick +the current cost centre stack is emitted. Together these +enable a user to construct an approximate track of the +executation of their program. Profile begin event ~~~~~~~~~~~~~~~~~~~ - * ``EVENT_PROF_BEGIN`` +.. event-type:: PROF_BEGIN - * ``Word64``: Tick interval, in nanoseconds + :tag: 168 + :length: fixed + :field Word64: tick interval, in nanoseconds + Marks the beginning of a time profile. -Tick sample event -~~~~~~~~~~~~~~~~~ +Profile sample event +~~~~~~~~~~~~~~~~~~~~ A variable-length packet encoding a profile sample. - * ``EVENT_PROF_SAMPLE_COST_CENTRE`` +.. event-type:: PROF_SAMPLE_COST_CENTRE + + :tag: 167 + :length: variable + :field Word32: capability + :field Word64: current profiling tick + :field Word8: stack depth + :field Word32[]: cost centre stack starting with inner-most (cost centre numbers) + +Biographical profile sample event +--------------------------------- + +A variable-length packet encoding a profile sample. + +.. event-type:: BIO_PROF_SAMPLE_BEGIN + + :tag: 166 + + TODO + +.. _nonmoving-gc-events: + +Non-moving GC event output +-------------------------- + +These events mark various stages of the +:rts-flag:`non-moving collection <--nonmoving-gc>` lifecycle. These are enabled +with the ``+RTS -lg`` event-set. + +.. event-type:: CONC_MARK_BEGIN + + :tag: 200 + :length: fixed + + Marks the beginning of marking by the concurrent collector. + +.. event-type:: CONC_MARK_END + + :tag: 201 + :length: fixed + + Marks the end of marking by the concurrent collector. + +.. event-type:: CONC_SYNC_BEGIN + + :tag: 202 + :length: fixed + + Marks the beginning of the concurrent garbage collector's + post-mark synchronization phase. + +.. event-type:: CONC_SYNC_END + + :tag: 203 + :length: fixed + + Marks the end of the concurrent garbage collector's + post-mark synchronization phase. + +.. event-type:: CONC_SWEEP_BEGIN + + :tag: 204 + :length: fixed + + Marks the beginning of the concurrent garbage collector's + sweep phase. + +.. event-type:: CONC_SWEEP_END + + :tag: 205 + :length: fixed + + Marks the end of the concurrent garbage collector's + sweep phase. + +.. event-type:: CONC_UPD_REM_SET_FLUSH + + :tag: 206 + :length: fixed + + Marks a capability flushing its local update remembered set + accumulator. + +Non-moving heap census +~~~~~~~~~~~~~~~~~~~~~~ + +The non-moving heap census events (enabled with the ``+RTS -ln`` event-set) are +intended to provide insight into fragmentation of the non-moving heap. + +.. event-type:: NONMOVING_HEAP_CENSUS + + :tag: 207 + :length: fixed + :field Word8: base-2 logarithm of *blk_sz*. + :field Word32: number of active segments. + :field Word32: number of filled segments. + :field Word32: number of live blocks. - * ``Word32``: Capability - * ``Word64``: Current profiling tick - * ``Word8``: stack depth - * ``Word32[]``: cost centre stack starting with inner-most (cost centre numbers) + Describes the occupancy of the *blk_sz* sub-heap. ===================================== docs/users_guide/runtime_control.rst ===================================== @@ -1161,6 +1161,10 @@ When the program is linked with the :ghc-flag:`-eventlog` option - ``g`` — GC events, including GC start/stop. Enabled by default. + - ``n`` — non-moving garbage collector (see :rts-flag:`--nonmoving-gc`) + events including start and end of the concurrent mark and census + information to characterise heap fragmentation. Disabled by default. + - ``p`` — parallel sparks (sampled). Enabled by default. - ``f`` — parallel sparks (fully accurate). Disabled by default. @@ -1186,9 +1190,8 @@ When the program is linked with the :ghc-flag:`-eventlog` option accurate mode every spark event is logged individually. The latter has a higher runtime overhead and is not enabled by default. - The format of the log file is described by the header - ``EventLogFormat.h`` that comes with GHC, and it can be parsed in - Haskell using the + The format of the log file is described in this users guide in + :ref:`eventlog-encodings` It can be parsed in Haskell using the `ghc-events `__ library. To dump the contents of a ``.eventlog`` file as text, use the tool ``ghc-events show`` that comes with the ===================================== includes/rts/EventLogFormat.h ===================================== @@ -9,65 +9,25 @@ * of the format, and new tools will be able to understand old log * files. * - * Each event has a specific format. If you add new events, give them - * new numbers: we never re-use old event numbers. - * - * - The format is endian-independent: all values are represented in - * bigendian order. - * - * - The format is extensible: - * - * - The header describes each event type and its length. Tools - * that don't recognise a particular event type can skip those events. - * - * - There is room for extra information in the event type - * specification, which can be ignored by older tools. - * - * - Events can have extra information added, but existing fields - * cannot be changed. Tools should ignore extra fields at the - * end of the event record. - * - * - Old event type ids are never re-used; just take a new identifier. - * - * - * The format - * ---------- - * - * log : EVENT_HEADER_BEGIN - * EventType* - * EVENT_HEADER_END - * EVENT_DATA_BEGIN - * Event* - * EVENT_DATA_END - * - * EventType : - * EVENT_ET_BEGIN - * Word16 -- unique identifier for this event - * Int16 -- >=0 size of the event in bytes (minus the header) - * -- -1 variable size - * Word32 -- length of the next field in bytes - * Word8* -- string describing the event - * Word32 -- length of the next field in bytes - * Word8* -- extra info (for future extensions) - * EVENT_ET_END - * - * Event : - * Word16 -- event_type - * Word64 -- time (nanosecs) - * [Word16] -- length of the rest (for variable-sized events only) - * ... extra event-specific info ... - * + * The canonical documentation for the event log format and record layouts is + * the "Eventlog encodings" section of the GHC User's Guide. * * To add a new event * ------------------ * * - In this file: - * - give it a new number, add a new #define EVENT_XXX below + * - give it a new number, add a new #define EVENT_XXX + * below. Do not reuse event ids from deprecated event types. + * * - In EventLog.c * - add it to the EventDesc array * - emit the event type in initEventLogging() * - emit the new event in postEvent_() * - generate the event itself by calling postEvent() somewhere + * + * - Describe the meaning and encoding of the event in the users guide + * (docs/user_guide/eventlog-formats.rst) + * * - In the Haskell code to parse the event log file: * - add types and code to read the new event * ===================================== rts/RtsFlags.c ===================================== @@ -382,6 +382,7 @@ usage_text[] = { " where [flags] can contain:", " s scheduler events", " g GC and heap events", +" n non-moving GC heap census events", " p par spark events (sampled)", " f par spark events (full detail)", " u user events (emitted from Haskell code)", ===================================== rts/sm/NonMoving.c ===================================== @@ -1125,6 +1125,10 @@ static void nonmovingMark_(MarkQueue *mark_queue, StgWeak **dead_weaks, StgTSO * if (RtsFlags.DebugFlags.nonmoving_gc) nonmovingPrintAllocatorCensus(); #endif +#if defined(TRACING) + if (RtsFlags.TraceFlags.nonmoving_gc) + nonmovingTraceAllocatorCensus(); +#endif // TODO: Remainder of things done by GarbageCollect (update stats) ===================================== testsuite/tests/deSugar/should_compile/T18112.hs ===================================== @@ -0,0 +1,14 @@ +{-# LANGUAGE TypeFamilies #-} +module T18112 where + +type family F a where + F Int = String + +-- This test is really testing the simple optimizer. We expect the +-- optimized desugared output to contain no casts, since the simple +-- optimizer should fuse the two casts together after inlining y. + +blah :: Bool -> String +blah x = let y :: F Int + y = show x + in y ===================================== testsuite/tests/deSugar/should_compile/all.T ===================================== @@ -109,3 +109,4 @@ test('T14773b', normal, compile, ['-Wincomplete-patterns']) test('T14815', [], makefile_test, ['T14815']) test('T13208', [], makefile_test, ['T13208']) test('T16615', normal, compile, ['-ddump-ds -dsuppress-uniques']) +test('T18112', [grep_errmsg('cast')], compile, ['-ddump-ds']) ===================================== testsuite/tests/dependent/should_compile/dynamic-paper.stderr ===================================== @@ -12,4 +12,4 @@ Simplifier ticks exhausted simplifier non-termination has been judged acceptable. To see detailed counts use -ddump-simpl-stats - Total ticks: 140084 + Total ticks: 138082 ===================================== testsuite/tests/deriving/should_fail/T18127b.hs ===================================== @@ -0,0 +1,8 @@ +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE RankNTypes #-} +module T18127b where + +import GHC.Generics + +data T1 = MkT1 (forall a. a) deriving (Eq, Generic) +data T2 a = MkT2 (Show a => a) deriving (Eq, Generic) ===================================== testsuite/tests/deriving/should_fail/T18127b.stderr ===================================== @@ -0,0 +1,22 @@ + +T18127b.hs:7:40: error: + • Can't make a derived instance of ‘Eq T1’: + Constructor ‘MkT1’ has a higher-rank type + Possible fix: use a standalone deriving declaration instead + • In the data declaration for ‘T1’ + +T18127b.hs:7:44: error: + • Can't make a derived instance of ‘Generic T1’: + MkT1 must not have exotic unlifted or polymorphic arguments + • In the data declaration for ‘T1’ + +T18127b.hs:8:42: error: + • Can't make a derived instance of ‘Eq (T2 a)’: + Constructor ‘MkT2’ has a higher-rank type + Possible fix: use a standalone deriving declaration instead + • In the data declaration for ‘T2’ + +T18127b.hs:8:46: error: + • Can't make a derived instance of ‘Generic (T2 a)’: + MkT2 must not have exotic unlifted or polymorphic arguments + • In the data declaration for ‘T2’ ===================================== testsuite/tests/deriving/should_fail/all.T ===================================== @@ -76,6 +76,7 @@ test('T15073', [extra_files(['T15073a.hs'])], multimod_compile_fail, ['T15073', '-v0']) test('T16181', normal, compile_fail, ['']) test('T16923', normal, compile_fail, ['']) +test('T18127b', normal, compile_fail, ['']) test('deriving-via-fail', normal, compile_fail, ['']) test('deriving-via-fail2', normal, compile_fail, ['']) test('deriving-via-fail3', normal, compile_fail, ['']) ===================================== testsuite/tests/parser/should_compile/T18130.hs ===================================== @@ -0,0 +1,20 @@ +{-# Language DerivingVia #-} +{-# Language KindSignatures #-} + +module T18130 where + +import Data.Functor.Classes +import Data.Kind + +newtype Par a b = Par (a, b) + deriving Eq + via (a, b) + :: Type + + deriving Eq1 + via (,) a + :: Type -> Type + + deriving Eq2 + via (,) + :: Type -> Type -> Type ===================================== testsuite/tests/parser/should_compile/all.T ===================================== @@ -166,3 +166,4 @@ test('proposal-229f', multimod_compile_and_run, ['proposal-229f.hs', '']) test('T15730a', normal, compile_and_run, ['']) +test('T18130', normal, compile, ['']) ===================================== testsuite/tests/parser/should_fail/T18130Fail.hs ===================================== @@ -0,0 +1,20 @@ +{-# Language DerivingVia #-} +{-# Language KindSignatures #-} + +module T18130Fail where + +import Data.Functor.Classes +import Data.Kind + +newtype Par a b = Par (a, b) + deriving Eq + via (a, b) + :: Type -> Type + + deriving Eq1 + via (,) a + :: Type -> Type + + deriving Eq2 + via (,) + :: Type -> Type -> Type ===================================== testsuite/tests/parser/should_fail/T18130Fail.stderr ===================================== @@ -0,0 +1,4 @@ + +T18130Fail.hs:11:7: error: + • Expected kind ‘* -> *’, but ‘(a, b)’ has kind ‘*’ + • In the newtype declaration for ‘Par’ ===================================== testsuite/tests/parser/should_fail/all.T ===================================== @@ -166,3 +166,4 @@ test('T17162', normal, compile_fail, ['']) test('proposal-229c', normal, compile_fail, ['']) test('T15730', normal, compile_fail, ['']) test('T15730b', normal, compile_fail, ['']) +test('T18130Fail', normal, compile_fail, ['']) ===================================== testsuite/tests/th/T18121.hs ===================================== @@ -0,0 +1,7 @@ +{-# LANGUAGE TemplateHaskell #-} +module Bug where + +import Language.Haskell.TH + +sapply :: Q (TExp (a -> b)) -> Q (TExp a) -> Q (TExp b) +sapply cf cx = [|| $$cf $$cx ||] ===================================== testsuite/tests/th/all.T ===================================== @@ -506,3 +506,4 @@ test('T18097', normal, compile, ['']) test('TH_PprStar', normal, compile, ['-v0 -dsuppress-uniques']) test('TH_StringLift', normal, compile, ['']) test('TH_BytesShowEqOrd', normal, compile_and_run, ['']) +test('T18121', normal, compile, ['']) ===================================== testsuite/tests/typecheck/should_fail/T18127a.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE RankNTypes #-} +module T18127a where + +a :: (forall a. a) -> () +a = undefined + +b :: (Show a => a) -> () +b = undefined + +type C = forall a. a +c :: C -> () +c = undefined + +type D a = Show a => a +d :: D a -> () +d = undefined ===================================== testsuite/tests/typecheck/should_fail/T18127a.stderr ===================================== @@ -0,0 +1,32 @@ + +T18127a.hs:5:5: error: + • Cannot instantiate unification variable ‘a1’ + with a type involving polytypes: (forall a. a) -> () + GHC doesn't yet support impredicative polymorphism + • In the expression: undefined + In an equation for ‘a’: a = undefined + +T18127a.hs:8:5: error: + • Cannot instantiate unification variable ‘a3’ + with a type involving polytypes: (Show a => a) -> () + GHC doesn't yet support impredicative polymorphism + • In the expression: undefined + In an equation for ‘b’: b = undefined + • Relevant bindings include + b :: (Show a => a) -> () (bound at T18127a.hs:8:1) + +T18127a.hs:12:5: error: + • Cannot instantiate unification variable ‘a0’ + with a type involving polytypes: C -> () + GHC doesn't yet support impredicative polymorphism + • In the expression: undefined + In an equation for ‘c’: c = undefined + +T18127a.hs:16:5: error: + • Cannot instantiate unification variable ‘a2’ + with a type involving polytypes: D a -> () + GHC doesn't yet support impredicative polymorphism + • In the expression: undefined + In an equation for ‘d’: d = undefined + • Relevant bindings include + d :: D a -> () (bound at T18127a.hs:16:1) ===================================== testsuite/tests/typecheck/should_fail/all.T ===================================== @@ -563,3 +563,4 @@ test('T17021', normal, compile_fail, ['']) test('T17021b', normal, compile_fail, ['']) test('T17955', normal, compile_fail, ['']) test('T17173', normal, compile_fail, ['']) +test('T18127a', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/110d36018023eca8a82aba70561e301038af961f...6687b27bdb249c7bf78a36546c6064871e140dc1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/110d36018023eca8a82aba70561e301038af961f...6687b27bdb249c7bf78a36546c6064871e140dc1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 4 11:48:17 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Mon, 04 May 2020 07:48:17 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn-simpl] DmdAnal: Improve handling of precise exceptions Message-ID: <5eb001015c485_6167c5ce1b0867142e@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn-simpl at Glasgow Haskell Compiler / GHC Commits: 13b9529e by Sebastian Graf at 2020-05-04T13:48:10+02:00 DmdAnal: Improve handling of precise exceptions This patch does two things: Fix possible unsoundness in what was called the "IO hack" and implement part 2.1 of the "fixing precise exceptions" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions, which, in combination with !2956, supersedes !3014 and !2525. **IO hack** The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is called `exprMayThrowPreciseException` now. I came up with two testcases exemplifying possible unsoundness (if twisted enough) in the old approach: - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. - `T13380e`: Demonstrating unsoundness of the "IO hack" when we have Nested CPR. Not currently relevant, as we don't have Nested CPR yet. Basically, the IO hack assumed that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future, see `T13380e`. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380{d,e}` (and will hopefully be robust to Nested CPR). **Precise exceptions** In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that was terribly unprincipled. That unprincipledness resulted in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception (and the existing IO hack doesn't detect that) Fixing both issues in !3014 turned out to be too complicated and had the potential to regress in the future. Hence we decided to only fix `T13380b` and augment the `Divergence` lattice with a new middle-layer element, `ExnOrDiv`, which means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. See the wiki page on Step 2.1 for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#dead-code-elimination-for-raiseio-with-isdeadenddiv-introducing-exnordiv-step-21 - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/LiberateCase.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Make.hs - testsuite/tests/stranal/should_compile/T10482a.stderr - testsuite/tests/stranal/should_compile/T10694.stderr - + testsuite/tests/stranal/should_compile/T13380b.hs - testsuite/tests/stranal/should_compile/all.T - + testsuite/tests/stranal/should_run/T13380d.hs - + testsuite/tests/stranal/should_run/T13380d.stderr - + testsuite/tests/stranal/should_run/T13380e.hs - + testsuite/tests/stranal/should_run/T13380e.stderr - testsuite/tests/stranal/should_run/all.T The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/13b9529eb2365d53a8978b2ef4ad51fc98282345 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/13b9529eb2365d53a8978b2ef4ad51fc98282345 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 4 12:25:01 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Mon, 04 May 2020 08:25:01 -0400 Subject: [Git][ghc/ghc][wip/T17917] 31 commits: Document backpack fields in DynFlags Message-ID: <5eb0099dedfa7_61673f819b417d1c867675f@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17917 at Glasgow Haskell Compiler / GHC Commits: 2cfc4ab9 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Document backpack fields in DynFlags - - - - - 10a2ba90 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 69562e34 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 9e2c8e0e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - ea717aa4 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 10d15f1e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 8bfb0219 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - 71484b09 by Alexis King at 2020-04-30T01:57:35-04:00 Allow block arguments in arrow control operators Arrow control operators have their own entries in the grammar, so they did not cooperate with BlockArguments. This was just a minor oversight, so this patch adjusts the grammar to add the desired behavior. fixes #18050 - - - - - a48cd2a0 by Alexis King at 2020-04-30T01:57:35-04:00 Allow LambdaCase to be used as a command in proc notation - - - - - f4d3773c by Alexis King at 2020-04-30T01:57:35-04:00 Document BlockArguments/LambdaCase support in arrow notation - - - - - 5bdfdd13 by Simon Peyton Jones at 2020-04-30T01:58:15-04:00 Add tests for #17873 - - - - - 19b701c2 by Simon Peyton Jones at 2020-04-30T07:30:13-04:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - 014ef4a3 by Matthew Pickering at 2020-04-30T07:30:50-04:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 2aa67611 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - 54dad3cf by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - 99ff8145 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 05b0a9fd by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 Remove OneShotInfo field of LFReEntrant, document OneShotInfo The field is only used in withNewTickyCounterFun and it's easier to directly pass a parameter for one-shot info to withNewTickyCounterFun instead of passing it via LFReEntrant. This also makes !2842 simpler. Other changes: - New Note (by SPJ) [OneShotInfo overview] added. - Arity argument of thunkCode removed as it's always 0. - - - - - a43620c6 by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 GHC.StgToCmm.Ticky: remove a few unused stuff - - - - - 780de9e1 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Use platform in Iface Binary - - - - - f8386c7b by Sylvain Henry at 2020-05-01T10:37:39-04:00 Refactor PprDebug handling If `-dppr-debug` is set, then PprUser and PprDump styles are silently replaced with PprDebug style. This was done in `mkUserStyle` and `mkDumpStyle` smart constructors. As a consequence they needed a DynFlags parameter. Now we keep the original PprUser and PprDump styles until they are used to create an `SDocContext`. I.e. the substitution is only performed in `initSDocContext`. - - - - - b3df9e78 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Remove PprStyle param of logging actions Use `withPprStyle` instead to apply a specific style to a SDoc. - - - - - de9fc995 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Fully remove PprDebug PprDebug was a pain to deal with consistently as it is implied by `-dppr-debug` but it isn't really a PprStyle. We remove it completely and query the appropriate SDoc flag instead (`sdocPprDebug`) via helpers (`getPprDebug` and its friends). - - - - - 8b51fcbd by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Only call checkSingle if we would report warnings - - - - - fd7ea0fe by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 7bfe9ac5 by Ben Gamari at 2020-05-03T04:41:33-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. - - - - - c560dd07 by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Move eventlog documentation users guide - - - - - 02543d5e by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Add documentation for non-moving GC events - - - - - b465dd45 by Alexis King at 2020-05-03T04:42:12-04:00 Flatten nested casts in the simple optimizer Normally, we aren’t supposed to generated any nested casts, since mkCast takes care to flatten them, but the simple optimizer didn’t use mkCast, so they could show up after inlining. This isn’t really a problem, since the simplifier will clean them up immediately anyway, but it can clutter the -ddump-ds output, and it’s an extremely easy fix. closes #18112 - - - - - 8bdc03d6 by Simon Peyton Jones at 2020-05-04T01:56:59-04:00 Don't return a panic in tcNestedSplice In GHC.Tc.Gen.Splice.tcNestedSplice we were returning a typechecked expression of "panic". That is usually OK, because the result is discarded. But it happens that tcApp now looks at the typechecked expression, trivially, to ask if it is tagToEnum. So being bottom is bad. Moreover a debug-trace might print it out. So better to return a civilised expression, even though it is usually discarded. - - - - - 0bf640b1 by Baldur Blöndal at 2020-05-04T01:57:36-04:00 Don't require parentheses around via type (`-XDerivingVia'). Fixes #18130". - - - - - 4590001a by Simon Peyton Jones at 2020-05-04T11:20:39+01:00 Avoid useless w/w split This patch is just a tidy-up for the post-strictness-analysis worker wrapper split. Consider f x = x Strictnesss analysis does not lead to a w/w split, so the obvious thing is to leave it 100% alone. But actually, because the RHS is small, we ended up adding a StableUnfolding for it. There is some reason to do this if we choose /not/ do to w/w on the grounds that the function is small. See Note [Don't w/w inline small non-loop-breaker things] But there is no reason if we would not have done w/w anyway. This patch just moves the conditional to later. Easy. This does move soem -ddump-simpl printouts around a bit. I also discovered that the previous code was overwritten an InlineCompulsory with InlineStable, which is utterly wrong. That in turn meant that some default methods (marked InlineCompulsory) were getting their InlineCompulsory squashed. This patch fixes that bug --- but of course that does mean a bit more inlining! - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Config.hs - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Driver.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/de2f34e7f874a960a1c1059b47690651999fa58a...4590001a7b25ee1ca19b620dfdd3031d3b0b505f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/de2f34e7f874a960a1c1059b47690651999fa58a...4590001a7b25ee1ca19b620dfdd3031d3b0b505f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 4 14:53:33 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Mon, 04 May 2020 10:53:33 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn-simpl] DmdAnal: Improve handling of precise exceptions Message-ID: <5eb02c6d7c4f8_61673f81cd4c695c8707884@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn-simpl at Glasgow Haskell Compiler / GHC Commits: e17007d1 by Sebastian Graf at 2020-05-04T16:53:27+02:00 DmdAnal: Improve handling of precise exceptions This patch does two things: Fix possible unsoundness in what was called the "IO hack" and implement part 2.1 of the "fixing precise exceptions" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions, which, in combination with !2956, supersedes !3014 and !2525. **IO hack** The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is called `exprMayThrowPreciseException` now. I came up with two testcases exemplifying possible unsoundness (if twisted enough) in the old approach: - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. - `T13380e`: Demonstrating unsoundness of the "IO hack" when we have Nested CPR. Not currently relevant, as we don't have Nested CPR yet. Basically, the IO hack assumed that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future, see `T13380e`. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380{d,e}` (and will hopefully be robust to Nested CPR). **Precise exceptions** In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that was terribly unprincipled. That unprincipledness resulted in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception (and the existing IO hack doesn't detect that) Fixing both issues in !3014 turned out to be too complicated and had the potential to regress in the future. Hence we decided to only fix `T13380b` and augment the `Divergence` lattice with a new middle-layer element, `ExnOrDiv`, which means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. See the wiki page on Step 2.1 for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#dead-code-elimination-for-raiseio-with-isdeadenddiv-introducing-exnordiv-step-21 - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/LiberateCase.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Make.hs - testsuite/tests/stranal/should_compile/T10482a.stderr - testsuite/tests/stranal/should_compile/T10694.stderr - + testsuite/tests/stranal/should_compile/T13380b.hs - testsuite/tests/stranal/should_compile/all.T - + testsuite/tests/stranal/should_run/T13380d.hs - + testsuite/tests/stranal/should_run/T13380d.stderr - + testsuite/tests/stranal/should_run/T13380e.hs - + testsuite/tests/stranal/should_run/T13380e.stderr - testsuite/tests/stranal/should_run/all.T The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e17007d1ee27bca845330c3e0b24d58ab7f150c9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e17007d1ee27bca845330c3e0b24d58ab7f150c9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 4 15:28:19 2020 From: gitlab at gitlab.haskell.org (Vladislav Zavialov) Date: Mon, 04 May 2020 11:28:19 -0400 Subject: [Git][ghc/ghc][wip/t18123] 7 commits: rts: Enable tracing of nonmoving heap census with -ln Message-ID: <5eb034936e630_6167e5b152c871688d@gitlab.haskell.org.mail> Vladislav Zavialov pushed to branch wip/t18123 at Glasgow Haskell Compiler / GHC Commits: 7bfe9ac5 by Ben Gamari at 2020-05-03T04:41:33-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. - - - - - c560dd07 by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Move eventlog documentation users guide - - - - - 02543d5e by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Add documentation for non-moving GC events - - - - - b465dd45 by Alexis King at 2020-05-03T04:42:12-04:00 Flatten nested casts in the simple optimizer Normally, we aren’t supposed to generated any nested casts, since mkCast takes care to flatten them, but the simple optimizer didn’t use mkCast, so they could show up after inlining. This isn’t really a problem, since the simplifier will clean them up immediately anyway, but it can clutter the -ddump-ds output, and it’s an extremely easy fix. closes #18112 - - - - - 8bdc03d6 by Simon Peyton Jones at 2020-05-04T01:56:59-04:00 Don't return a panic in tcNestedSplice In GHC.Tc.Gen.Splice.tcNestedSplice we were returning a typechecked expression of "panic". That is usually OK, because the result is discarded. But it happens that tcApp now looks at the typechecked expression, trivially, to ask if it is tagToEnum. So being bottom is bad. Moreover a debug-trace might print it out. So better to return a civilised expression, even though it is usually discarded. - - - - - 0bf640b1 by Baldur Blöndal at 2020-05-04T01:57:36-04:00 Don't require parentheses around via type (`-XDerivingVia'). Fixes #18130". - - - - - b4d771c3 by Vladislav Zavialov at 2020-05-04T18:28:06+03:00 Add Semigroup/Monoid for Q (#18123) - - - - - 23 changed files: - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Parser.y - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Splice.hs - docs/users_guide/conf.py - docs/users_guide/eventlog-formats.rst - docs/users_guide/runtime_control.rst - includes/rts/EventLogFormat.h - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/changelog.md - rts/RtsFlags.c - rts/sm/NonMoving.c - + testsuite/tests/deSugar/should_compile/T18112.hs - testsuite/tests/deSugar/should_compile/all.T - testsuite/tests/dependent/should_compile/dynamic-paper.stderr - + testsuite/tests/parser/should_compile/T18130.hs - testsuite/tests/parser/should_compile/all.T - + testsuite/tests/parser/should_fail/T18130Fail.hs - + testsuite/tests/parser/should_fail/T18130Fail.stderr - testsuite/tests/parser/should_fail/all.T - + testsuite/tests/th/T18121.hs - + testsuite/tests/th/T18123.hs - testsuite/tests/th/all.T Changes: ===================================== compiler/GHC/Core/SimpleOpt.hs ===================================== @@ -221,10 +221,13 @@ simple_opt_expr env expr go (Coercion co) = Coercion (optCoercion (soe_dflags env) (getTCvSubst subst) co) go (Lit lit) = Lit lit go (Tick tickish e) = mkTick (substTickish subst tickish) (go e) - go (Cast e co) | isReflCo co' = go e - | otherwise = Cast (go e) co' - where - co' = optCoercion (soe_dflags env) (getTCvSubst subst) co + go (Cast e co) = case go e of + -- flatten nested casts before calling the coercion optimizer; + -- see #18112 (note that mkCast handles dropping Refl coercions) + Cast e' co' -> mkCast e' (opt_co (mkTransCo co' co)) + e' -> mkCast e' (opt_co co) + where + opt_co = optCoercion (soe_dflags env) (getTCvSubst subst) go (Let bind body) = case simple_opt_bind env bind NotTopLevel of (env', Nothing) -> simple_opt_expr env' body ===================================== compiler/GHC/Parser.y ===================================== @@ -1209,8 +1209,8 @@ deriv_strategy_no_via :: { LDerivStrategy GhcPs } [mj AnnNewtype $1] } deriv_strategy_via :: { LDerivStrategy GhcPs } - : 'via' type {% ams (sLL $1 $> (ViaStrategy (mkLHsSigType $2))) - [mj AnnVia $1] } + : 'via' ktype {% ams (sLL $1 $> (ViaStrategy (mkLHsSigType $2))) + [mj AnnVia $1] } deriv_standalone_strategy :: { Maybe (LDerivStrategy GhcPs) } : 'stock' {% ajs (sL1 $1 StockStrategy) ===================================== compiler/GHC/Tc/Gen/Expr.hs ===================================== @@ -981,12 +981,9 @@ tcExpr (HsSpliceE _ (HsSpliced _ mod_finalizers (HsSplicedExpr expr))) res_ty = do addModFinalizersWithLclEnv mod_finalizers tcExpr expr res_ty -tcExpr (HsSpliceE _ splice) res_ty - = tcSpliceExpr splice res_ty -tcExpr e@(HsBracket _ brack) res_ty - = tcTypedBracket e brack res_ty -tcExpr e@(HsRnBracketOut _ brack ps) res_ty - = tcUntypedBracket e brack ps res_ty +tcExpr (HsSpliceE _ splice) res_ty = tcSpliceExpr splice res_ty +tcExpr e@(HsBracket _ brack) res_ty = tcTypedBracket e brack res_ty +tcExpr e@(HsRnBracketOut _ brack ps) res_ty = tcUntypedBracket e brack ps res_ty {- ************************************************************************ @@ -1219,7 +1216,11 @@ tcApp expr res_ty = do { (fun, args, app_res_ty) <- tcInferApp expr ; if isTagToEnum fun then tcTagToEnum expr fun args app_res_ty res_ty - else -- The wildly common case + -- Done here because we have res_ty, + -- whereas tcInferApp does not + else + + -- The wildly common case do { let expr' = applyHsArgs fun args ; addFunResCtxt True fun app_res_ty res_ty $ tcWrapResult expr expr' app_res_ty res_ty } } @@ -1232,10 +1233,10 @@ tcInferApp :: HsExpr GhcRn -- Also used by Module.tcRnExpr to implement GHCi :type tcInferApp expr | -- Gruesome special case for ambiguous record selectors - HsRecFld _ fld_lbl <- fun - , Ambiguous _ lbl <- fld_lbl -- Still ambiguous + HsRecFld _ fld_lbl <- fun + , Ambiguous _ lbl <- fld_lbl -- Still ambiguous , HsEValArg _ (L _ arg) : _ <- filterOut isArgPar args -- A value arg is first - , Just sig_ty <- obviousSig arg -- A type sig on the arg disambiguates + , Just sig_ty <- obviousSig arg -- A type sig on the arg disambiguates = do { sig_tc_ty <- tcHsSigWcType ExprSigCtxt sig_ty ; sel_name <- disambiguateSelector lbl sig_tc_ty ; (tc_fun, fun_ty) <- tcInferRecSelId (Unambiguous sel_name lbl) @@ -1259,11 +1260,7 @@ tcInferApp_finish -> TcM (HsExpr GhcTc, [LHsExprArgOut], TcSigmaType) tcInferApp_finish rn_fun tc_fun fun_sigma rn_args - = do { traceTc "tcInferApp_finish" $ - vcat [ ppr rn_fun <+> dcolon <+> ppr fun_sigma, ppr rn_args ] - - ; (tc_args, actual_res_ty) <- tcArgs rn_fun fun_sigma rn_args - + = do { (tc_args, actual_res_ty) <- tcArgs rn_fun fun_sigma rn_args ; return (tc_fun, tc_args, actual_res_ty) } mk_op_msg :: LHsExpr GhcRn -> SDoc ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -625,7 +625,13 @@ tcNestedSplice pop_stage (TcPending ps_var lie_var q@(QuoteWrapper _ m_var)) spl ; writeMutVar ps_var (PendingTcSplice splice_name expr'' : ps) -- The returned expression is ignored; it's in the pending splices - ; return (panic "tcSpliceExpr") } + -- But we still return a plausible expression + -- (a) in case we print it in debug messages, and + -- (b) because we test whether it is tagToEnum in Tc.Gen.Expr.tcApp + ; return (HsSpliceE noExtField $ + HsSpliced noExtField (ThModFinalizers []) $ + HsSplicedExpr (unLoc expr'')) } + tcNestedSplice _ _ splice_name _ _ = pprPanic "tcNestedSplice: rename stage found" (ppr splice_name) ===================================== docs/users_guide/conf.py ===================================== @@ -283,8 +283,18 @@ def setup(app): objname='runtime system command-line option', parse_node=parse_flag, indextemplate='pair: %s; RTS option', + doc_field_types=[ + Field('since', label='Introduced in GHC version', names=['since']) + ]) + + app.add_object_type('event-type', 'event-type', + objname='event log event type', + indextemplate='pair: %s; eventlog event type', doc_field_types=[ Field('since', label='Introduced in GHC version', names=['since']), + Field('tag', label='Event type ID', names=['tag']), + Field('length', label='Record length', names=['length']), + TypedField('fields', label='Fields', names='field', typenames=('fieldtype', 'type')) ]) app.add_object_type('pragma', 'pragma', ===================================== docs/users_guide/eventlog-formats.rst ===================================== @@ -1,3 +1,5 @@ +.. _eventlog-encodings: + Eventlog encodings ================== @@ -7,6 +9,481 @@ thread scheduling events, garbage collection statistics, profiling information, user-defined tracing events. This section is intended for implementors of tooling which consume these events. +GHC ships with a C header file (``EventlogFormat.h``) which provides symbolic +names for the event type IDs described in this file. + + +Event log format +---------------- + +The log format is designed to be extensible: old tools should be +able to parse (but not necessarily understand all of) new versions +of the format, and new tools will be able to understand old log +files. + +- The format is endian-independent: all values are represented in + big-endian order. + +- The format is extensible: + + - The header describes each event type and its length. Tools + that don't recognise a particular event type can skip those events. + + - There is room for extra information in the event type + specification, which can be ignored by older tools. + + - Events can have extra information added, but existing fields + cannot be changed. Tools should ignore extra fields at the + end of the event record. + +The event-log stream begins with a header describing the event types present in +the file. The header is followed by the event records themselves, each of which +consist of a 64-bit timestamp + +.. code-block:: none + + log : EVENT_HEADER_BEGIN + EventType* + EVENT_HEADER_END + EVENT_DATA_BEGIN + Event* + EVENT_DATA_END + + EventType : + EVENT_ET_BEGIN + Word16 -- unique identifier for this event + Int16 -- >=0 size of the event in bytes (minus the header) + -- -1 variable size + Word32 -- length of the next field in bytes + Word8* -- string describing the event + Word32 -- length of the next field in bytes + Word8* -- extra info (for future extensions) + EVENT_ET_END + + Event : + Word16 -- event_type + Word64 -- time (nanosecs) + [Word16] -- length of the rest (for variable-sized events only) + ... extra event-specific info ... + +There are two classes of event types: + + - *Fixed size*: All event records of a fixed-sized type are of the same + length, given in the header event-log header. + + - *Variable size*: Each event record includes a length field. + +Runtime system diagnostics +-------------------------- + + * ``ThreadId ~ Word32`` + * ``CapNo ~ Word16`` + * ``CapSetId ~ Word32`` + +Capability sets +~~~~~~~~~~~~~~~ + +TODO + +Environment information +~~~~~~~~~~~~~~~~~~~~~~~ + +These events are typically produced during program startup and describe the +environment which the program is being run in. + +.. event-type:: RTS_IDENTIFIER + + :tag: 29 + :length: variable + :field CapSetId: Capability set + :field String: Runtime system name and version. + + Describes the name and version of the runtime system responsible for the + indicated capability set. + +.. event-type:: PROGRAM_ARGS + + :tag: 30 + :length: variable + :field CapSetId: Capability set + :field [String]: The command-line arguments passed to the program + + Describes the command-line used to start the program. + +.. event-type:: PROGRAM_ENV + + :tag: 31 + :length: variable + :field CapSetId: Capability set + :field [String]: The environment variable name/value pairs. (TODO: encoding?) + + Describes the environment variables present in the program's environment. + +Thread and scheduling events +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. event-type:: CREATE_THREAD + + :tag: 0 + :length: fixed + :field ThreadId: thread id + + Marks the creation of a Haskell thread. + + +.. event-type:: RUN_THREAD + + :tag: 1 + :length: fixed + :field ThreadId: thread id + + The indicated thread has started running. + + +.. event-type:: STOP_THREAD + + :tag: 2 + :length: fixed + :field ThreadId: thread id + :field Word16: status + + * 1: HeapOverflow + * 2: StackOverflow + * 3: ThreadYielding + * 4: ThreadBlocked + * 5: ThreadFinished + * 6: ForeignCall + * 7: BlockedOnMVar + * 8: BlockedOnBlackHole + * 9: BlockedOnRead + * 10: BlockedOnWrite + * 11: BlockedOnDelay + * 12: BlockedOnSTM + * 13: BlockedOnDoProc + * 16: BlockedOnMsgThrowTo + + :field ThreadId: thread id of thread being blocked on (only for some status + values) + + The indicated thread has stopped running for the reason given by ``status``. + + +.. event-type:: THREAD_RUNNABLE + + :tag: 3 + :length: fixed + :field ThreadId: thread id + + The indicated thread is has been marked as ready to run. + + +.. event-type:: MIGRATE_THREAD + + :tag: 4 + :length: fixed + :field ThreadId: thread id + :field CapNo: capability + + The indicated thread has been migrated to a new capability. + + +.. event-type:: THREAD_WAKEUP + + :tag: 8 + :length: fixed + :field ThreadId: thread id + :field CapNo: other capability + + The indicated thread has been been woken up on another capability. + +.. event-type:: THREAD_LABEL + + :tag: 44 + :length: fixed + :field ThreadId: thread id + :field String: label + + The indicated thread has been given a label (e.g. with + :base-ref:`Control.Concurrent.setThreadLabel`). + + +Garbage collector events +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. event-type:: GC_START + + :tag: 9 + :length: fixed + + A garbage collection pass has been started. + +.. event-type:: GC_END + + :tag: 10 + :length: fixed + + A garbage collection pass has been finished. + +.. event-type:: REQUEST_SEQ_GC + + :tag: 11 + :length: fixed + + A sequential garbage collection has been requested by a capability. + +.. event-type:: REQUEST_PAR_GC + + :tag: 12 + :length: fixed + + A parallel garbage collection has been requested by a capability. + +.. event-type:: GC_IDLE + + :tag: 20 + :length: fixed + + An idle-time garbage collection has been started. + +.. event-type:: GC_WORK + + :tag: 21 + :length: fixed + + Marks the start of concurrent scavenging. + +.. event-type:: GC_DONE + + :tag: 22 + :length: fixed + + Marks the end of concurrent scavenging. + +.. event-type:: GC_STATS_GHC + + :tag: 53 + :length: fixed + :field CapSetId: heap capability set + :field Word16: generation of collection + :field Word64: bytes copied + :field Word64: bytes of slop found + :field Word64: TODO + :field Word64: number of parallel garbage collection threads + :field Word64: maximum number of bytes copied by any single collector thread + :field Word64: total bytes copied by all collector threads + + Report various information about the heap configuration. Typically produced + during RTS initialization.. + +.. event-type:: GC_GLOBAL_SYNC + + :tag: 54 + :length: fixed + + TODO + +Heap events and statistics +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. event-type:: HEAP_ALLOCATED + + :tag: 49 + :length: fixed + :field CapSetId: heap capability set + :field Word64: allocated bytes + + A new chunk of heap has been allocated by the indicated capability set. + +.. event-type:: HEAP_SIZE + + :tag: 50 + :length: fixed + :field CapSetId: heap capability set + :field Word64: heap size in bytes + + Report the heap size. + +.. event-type:: HEAP_LIVE + + :tag: 51 + :length: fixed + :field CapSetId: heap capability set + :field Word64: heap size in bytes + + Report the live heap size. + +.. event-type:: HEAP_INFO_GHC + + :tag: 52 + :length: fixed + :field CapSetId: heap capability set + :field Word16: number of garbage collection generations + :field Word64: maximum heap size + :field Word64: allocation area size + :field Word64: MBlock size + :field Word64: Block size + + Report various information about the heap configuration. Typically produced + during RTS initialization.. + +Spark events +~~~~~~~~~~~~ + +.. event-type:: CREATE_SPARK_THREAD + + :tag: 15 + :length: fixed + + A thread has been created to perform spark evaluation. + +.. event-type:: SPARK_COUNTERS + + :tag: 34 + :length: fixed + + A periodic reporting of various statistics of spark evaluation. + +.. event-type:: SPARK_CREATE + + :tag: 35 + :length: fixed + + A spark has been added to the spark pool. + +.. event-type:: SPARK_DUD + + :tag: 36 + :length: fixed + + TODO + +.. event-type:: SPARK_OVERFLOW + + :tag: 37 + :length: fixed + + TODO + +.. event-type:: SPARK_RUN + + :tag: 38 + :length: fixed + + Evaluation has started on a spark. + +.. event-type:: SPARK_STEAL + + :tag: 39 + :length: fixed + :field Word16: capability from which the spark was stolen + + A spark has been stolen from another capability for evaluation. + +.. event-type:: SPARK_FIZZLE + + :tag: 40 + :length: fixed + + A spark has been GC'd before being evaluated. + +.. event-type:: SPARK_GC + + :tag: 41 + :length: fixed + + An unevaluated spark has been garbage collected. + +Capability events +~~~~~~~~~~~~~~~~~ + +.. event-type:: CAP_CREATE + + :tag: 45 + :length: fixed + :field CapNo: the capability number + + A capability has been started. + +.. event-type:: CAP_DELETE + + :tag: 46 + :length: fixed + + A capability has been deleted. + +.. event-type:: CAP_DISABLE + + :tag: 47 + :length: fixed + + A capability has been disabled. + +.. event-type:: CAP_ENABLE + + :tag: 48 + :length: fixed + + A capability has been enabled. + +Task events +~~~~~~~~~~~ + +.. event-type:: TASK_CREATE + + :tag: 55 + :length: fixed + :field TaskId: task id + :field CapNo: capability number + :field ThreadId: TODO + + Marks the creation of a task. + +.. event-type:: TASK_MIGRATE + + :tag: 56 + :length: fixed + :field TaskId: task id + :field CapNo: old capability + :field CapNo: new capability + + Marks the migration of a task to a new capability. + +Tracing events +~~~~~~~~~~~~~~ + +.. event-type:: LOG_MSG + + :tag: 16 + :length: variable + :field String: The message + + A log message from the runtime system. + +.. event-type:: BLOCK_MARKER + + :tag: 18 + :length: variable + :field Word32: size + :field Word64: end time in nanoseconds + :field String: marker name + + TODO + +.. event-type:: USER_MSG + + :tag: 19 + :length: variable + :field String: message + + A user log message (from, e.g., :base-ref:`Control.Concurrent.traceEvent`). + +.. event-type:: USER_MARKER + + :tag: 58 + :length: variable + :field String: marker name + + A user marker (from :base-ref:`Debug.Trace.traceMarker`). .. _heap-profiler-events: @@ -28,11 +505,13 @@ Beginning of sample stream A single fixed-width event emitted during program start-up describing the samples that follow. - * ``EVENT_HEAP_PROF_BEGIN`` +.. event-type:: HEAP_PROF_BEGIN - * ``Word8``: Profile ID - * ``Word64``: Sampling period in nanoseconds - * ``Word32``: Sample break-down type. One of, + :tag: 160 + :length: variable + :field Word8: profile ID + :field Word64: sampling period in nanoseconds + :field Word32: sample breadown type. One of, * ``HEAP_PROF_BREAKDOWN_COST_CENTER`` (output from :rts-flag:`-hc`) * ``HEAP_PROF_BREAKDOWN_CLOSURE_DESCR`` (output from :rts-flag:`-hd`) @@ -42,32 +521,34 @@ A single fixed-width event emitted during program start-up describing the sample * ``HEAP_PROF_BREAKDOWN_BIOGRAPHY`` (output from :rts-flag:`-hb`) * ``HEAP_PROF_BREAKDOWN_CLOSURE_TYPE`` (output from :rts-flag:`-hT`) - * ``String``: Module filter - * ``String``: Closure description filter - * ``String``: Type description filter - * ``String``: Cost centre filter - * ``String``: Cost centre stack filter - * ``String``: Retainer filter - * ``String``: Biography filter + :field String: module filter + :field String: closure description filter + :field String: type description filter + :field String: cost centre filter + :field String: cost centre stack filter + :field String: retainer filter + :field String: biography filter Cost centre definitions ^^^^^^^^^^^^^^^^^^^^^^^ A variable-length packet produced once for each cost centre, - * ``EVENT_HEAP_PROF_COST_CENTRE`` +.. event-type:: HEAP_PROF_COST_CENTRE - * ``Word32``: cost centre number - * ``String``: label - * ``String``: module - * ``String``: source location - * ``Word8``: flags + :tag: 161 + :length: fixed + :field Word32: cost centre number + :field String: label + :field String: module + :field String: source location + :field Word8: flags: * bit 0: is the cost-centre a CAF? Sample event types -~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^ A sample (consisting of a list of break-down classes, e.g. cost centres, and heap residency sizes), is to be encoded in the body of one or more events. @@ -75,9 +556,12 @@ heap residency sizes), is to be encoded in the body of one or more events. We normally mark the beginning of a new sample with an ``EVENT_HEAP_PROF_SAMPLE_BEGIN`` event, - * ``EVENT_HEAP_PROF_SAMPLE_BEGIN`` +.. event-type:: HEAP_PROF_SAMPLE_BEGIN + + :length: fixed + :field Word64: sample number - * ``Word64``: sample number + Marks the beginning of a heap profile sample. Biographical profiling samples start with the ``EVENT_HEAP_BIO_PROF_SAMPLE_BEGIN`` event. These events also include a timestamp which indicates when the sample @@ -85,11 +569,12 @@ was taken. This is because all these samples will appear at the end of the eventlog due to how the biographical profiling mode works. You can use the timestamp to reorder the samples relative to the other events. - * ``EVENT_HEAP_BIO_PROF_SAMPLE_BEGIN`` - - * ``Word64``: sample number - * ``Word64``: eventlog timestamp in ns +.. event-type:: HEAP_BIO_PROF_SAMPLE_BEGIN + :tag: 166 + :length: fixed + :field Word64: sample number + :field Word64: eventlog timestamp in ns A heap residency census will follow. Since events may only be up to 2^16^ bytes in length a single sample may need to be split among multiple @@ -101,23 +586,29 @@ emitted. This is useful to properly delimit the sampling period and to record the total time spent profiling. - * ``EVENT_HEAP_PROF_SAMPLE_END`` - * ``Word64``: sample number +.. event-type:: HEAP_PROF_SAMPLE_END + :tag: 165 + :length: fixed + :field Word64: sample number + + Marks the end of a heap profile sample. Cost-centre break-down ^^^^^^^^^^^^^^^^^^^^^^ A variable-length packet encoding a heap profile sample broken down by, - * cost-centre (``-hc``) + * cost-centre (:rts-flag:`-hc`) - * ``EVENT_HEAP_PROF_SAMPLE_COST_CENTRE`` +.. event-type:: HEAP_PROF_SAMPLE_COST_CENTRE - * ``Word8``: Profile ID - * ``Word64``: heap residency in bytes - * ``Word8``: stack depth - * ``Word32[]``: cost centre stack starting with inner-most (cost centre numbers) + :tag: 163 + :length: variable + :field Word8: profile ID + :field Word64: heap residency in bytes + :field Word8: stack depth + :field Word32[]: cost centre stack starting with inner-most (cost centre numbers) String break-down @@ -125,42 +616,142 @@ String break-down A variable-length event encoding a heap sample broken down by, - * type description (``-hy``) - * closure description (``-hd``) - * module (``-hm``) + * type description (:rts-flag:`-hy`) + * closure description (:rts-flag:`-hd`) + * module (:rts-flag:`-hm`) - * ``EVENT_HEAP_PROF_SAMPLE_STRING`` +.. event-type:: HEAP_PROF_SAMPLE_STRING - * ``Word8``: Profile ID - * ``Word64``: heap residency in bytes - * ``String``: type or closure description, or module name + :tag: 164 + :length: variable + :field Word8: profile ID + :field Word64: heap residency in bytes + :field String: type or closure description, or module name .. _time-profiler-events: Time profiler event log output ------------------------------ -The time profiling mode enabled by ``-p`` also emits sample events to the eventlog. -At the start of profiling the tick interval is emitted to the eventlog and then -on each tick the current cost centre stack is emitted. Together these enable -a user to construct an approximate track of the executation of their program. +The time profiling mode enabled by :rts-flag:`-p` also emits +sample events to the eventlog. At the start of profiling the +tick interval is emitted to the eventlog and then on each tick +the current cost centre stack is emitted. Together these +enable a user to construct an approximate track of the +executation of their program. Profile begin event ~~~~~~~~~~~~~~~~~~~ - * ``EVENT_PROF_BEGIN`` +.. event-type:: PROF_BEGIN - * ``Word64``: Tick interval, in nanoseconds + :tag: 168 + :length: fixed + :field Word64: tick interval, in nanoseconds + Marks the beginning of a time profile. -Tick sample event -~~~~~~~~~~~~~~~~~ +Profile sample event +~~~~~~~~~~~~~~~~~~~~ A variable-length packet encoding a profile sample. - * ``EVENT_PROF_SAMPLE_COST_CENTRE`` +.. event-type:: PROF_SAMPLE_COST_CENTRE + + :tag: 167 + :length: variable + :field Word32: capability + :field Word64: current profiling tick + :field Word8: stack depth + :field Word32[]: cost centre stack starting with inner-most (cost centre numbers) + +Biographical profile sample event +--------------------------------- + +A variable-length packet encoding a profile sample. + +.. event-type:: BIO_PROF_SAMPLE_BEGIN + + :tag: 166 + + TODO + +.. _nonmoving-gc-events: + +Non-moving GC event output +-------------------------- + +These events mark various stages of the +:rts-flag:`non-moving collection <--nonmoving-gc>` lifecycle. These are enabled +with the ``+RTS -lg`` event-set. + +.. event-type:: CONC_MARK_BEGIN + + :tag: 200 + :length: fixed + + Marks the beginning of marking by the concurrent collector. + +.. event-type:: CONC_MARK_END + + :tag: 201 + :length: fixed + + Marks the end of marking by the concurrent collector. + +.. event-type:: CONC_SYNC_BEGIN + + :tag: 202 + :length: fixed + + Marks the beginning of the concurrent garbage collector's + post-mark synchronization phase. + +.. event-type:: CONC_SYNC_END + + :tag: 203 + :length: fixed + + Marks the end of the concurrent garbage collector's + post-mark synchronization phase. + +.. event-type:: CONC_SWEEP_BEGIN + + :tag: 204 + :length: fixed + + Marks the beginning of the concurrent garbage collector's + sweep phase. + +.. event-type:: CONC_SWEEP_END + + :tag: 205 + :length: fixed + + Marks the end of the concurrent garbage collector's + sweep phase. + +.. event-type:: CONC_UPD_REM_SET_FLUSH + + :tag: 206 + :length: fixed + + Marks a capability flushing its local update remembered set + accumulator. + +Non-moving heap census +~~~~~~~~~~~~~~~~~~~~~~ + +The non-moving heap census events (enabled with the ``+RTS -ln`` event-set) are +intended to provide insight into fragmentation of the non-moving heap. + +.. event-type:: NONMOVING_HEAP_CENSUS + + :tag: 207 + :length: fixed + :field Word8: base-2 logarithm of *blk_sz*. + :field Word32: number of active segments. + :field Word32: number of filled segments. + :field Word32: number of live blocks. - * ``Word32``: Capability - * ``Word64``: Current profiling tick - * ``Word8``: stack depth - * ``Word32[]``: cost centre stack starting with inner-most (cost centre numbers) + Describes the occupancy of the *blk_sz* sub-heap. ===================================== docs/users_guide/runtime_control.rst ===================================== @@ -1161,6 +1161,10 @@ When the program is linked with the :ghc-flag:`-eventlog` option - ``g`` — GC events, including GC start/stop. Enabled by default. + - ``n`` — non-moving garbage collector (see :rts-flag:`--nonmoving-gc`) + events including start and end of the concurrent mark and census + information to characterise heap fragmentation. Disabled by default. + - ``p`` — parallel sparks (sampled). Enabled by default. - ``f`` — parallel sparks (fully accurate). Disabled by default. @@ -1186,9 +1190,8 @@ When the program is linked with the :ghc-flag:`-eventlog` option accurate mode every spark event is logged individually. The latter has a higher runtime overhead and is not enabled by default. - The format of the log file is described by the header - ``EventLogFormat.h`` that comes with GHC, and it can be parsed in - Haskell using the + The format of the log file is described in this users guide in + :ref:`eventlog-encodings` It can be parsed in Haskell using the `ghc-events `__ library. To dump the contents of a ``.eventlog`` file as text, use the tool ``ghc-events show`` that comes with the ===================================== includes/rts/EventLogFormat.h ===================================== @@ -9,65 +9,25 @@ * of the format, and new tools will be able to understand old log * files. * - * Each event has a specific format. If you add new events, give them - * new numbers: we never re-use old event numbers. - * - * - The format is endian-independent: all values are represented in - * bigendian order. - * - * - The format is extensible: - * - * - The header describes each event type and its length. Tools - * that don't recognise a particular event type can skip those events. - * - * - There is room for extra information in the event type - * specification, which can be ignored by older tools. - * - * - Events can have extra information added, but existing fields - * cannot be changed. Tools should ignore extra fields at the - * end of the event record. - * - * - Old event type ids are never re-used; just take a new identifier. - * - * - * The format - * ---------- - * - * log : EVENT_HEADER_BEGIN - * EventType* - * EVENT_HEADER_END - * EVENT_DATA_BEGIN - * Event* - * EVENT_DATA_END - * - * EventType : - * EVENT_ET_BEGIN - * Word16 -- unique identifier for this event - * Int16 -- >=0 size of the event in bytes (minus the header) - * -- -1 variable size - * Word32 -- length of the next field in bytes - * Word8* -- string describing the event - * Word32 -- length of the next field in bytes - * Word8* -- extra info (for future extensions) - * EVENT_ET_END - * - * Event : - * Word16 -- event_type - * Word64 -- time (nanosecs) - * [Word16] -- length of the rest (for variable-sized events only) - * ... extra event-specific info ... - * + * The canonical documentation for the event log format and record layouts is + * the "Eventlog encodings" section of the GHC User's Guide. * * To add a new event * ------------------ * * - In this file: - * - give it a new number, add a new #define EVENT_XXX below + * - give it a new number, add a new #define EVENT_XXX + * below. Do not reuse event ids from deprecated event types. + * * - In EventLog.c * - add it to the EventDesc array * - emit the event type in initEventLogging() * - emit the new event in postEvent_() * - generate the event itself by calling postEvent() somewhere + * + * - Describe the meaning and encoding of the event in the users guide + * (docs/user_guide/eventlog-formats.rst) + * * - In the Haskell code to parse the event log file: * - add types and code to read the new event * ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -33,6 +33,7 @@ import Data.IORef import System.IO.Unsafe ( unsafePerformIO ) import Control.Monad (liftM) import Control.Monad.IO.Class (MonadIO (..)) +import Control.Applicative (liftA2) import System.IO ( hPutStrLn, stderr ) import Data.Char ( isAlpha, isAlphaNum, isUpper, ord ) import Data.Int @@ -206,6 +207,12 @@ instance Applicative Q where Q f <*> Q x = Q (f <*> x) Q m *> Q n = Q (m *> n) +instance Semigroup a => Semigroup (Q a) where + (<>) = liftA2 (<>) + +instance Monoid a => Monoid (Q a) where + mempty = pure mempty + ----------------------------------------------------- -- -- The Quote class ===================================== libraries/template-haskell/changelog.md ===================================== @@ -16,6 +16,8 @@ * Fix Show instance for `Bytes`: we were showing the pointer value while we want to show the contents (#16457). + * Add `Semigroup` and `Monoid` instances for `Q` (#18123). + ## 2.16.0.0 *TBA* * Add support for tuple sections. (#15843) The type signatures of `TupE` and ===================================== rts/RtsFlags.c ===================================== @@ -382,6 +382,7 @@ usage_text[] = { " where [flags] can contain:", " s scheduler events", " g GC and heap events", +" n non-moving GC heap census events", " p par spark events (sampled)", " f par spark events (full detail)", " u user events (emitted from Haskell code)", ===================================== rts/sm/NonMoving.c ===================================== @@ -1125,6 +1125,10 @@ static void nonmovingMark_(MarkQueue *mark_queue, StgWeak **dead_weaks, StgTSO * if (RtsFlags.DebugFlags.nonmoving_gc) nonmovingPrintAllocatorCensus(); #endif +#if defined(TRACING) + if (RtsFlags.TraceFlags.nonmoving_gc) + nonmovingTraceAllocatorCensus(); +#endif // TODO: Remainder of things done by GarbageCollect (update stats) ===================================== testsuite/tests/deSugar/should_compile/T18112.hs ===================================== @@ -0,0 +1,14 @@ +{-# LANGUAGE TypeFamilies #-} +module T18112 where + +type family F a where + F Int = String + +-- This test is really testing the simple optimizer. We expect the +-- optimized desugared output to contain no casts, since the simple +-- optimizer should fuse the two casts together after inlining y. + +blah :: Bool -> String +blah x = let y :: F Int + y = show x + in y ===================================== testsuite/tests/deSugar/should_compile/all.T ===================================== @@ -109,3 +109,4 @@ test('T14773b', normal, compile, ['-Wincomplete-patterns']) test('T14815', [], makefile_test, ['T14815']) test('T13208', [], makefile_test, ['T13208']) test('T16615', normal, compile, ['-ddump-ds -dsuppress-uniques']) +test('T18112', [grep_errmsg('cast')], compile, ['-ddump-ds']) ===================================== testsuite/tests/dependent/should_compile/dynamic-paper.stderr ===================================== @@ -12,4 +12,4 @@ Simplifier ticks exhausted simplifier non-termination has been judged acceptable. To see detailed counts use -ddump-simpl-stats - Total ticks: 140084 + Total ticks: 138082 ===================================== testsuite/tests/parser/should_compile/T18130.hs ===================================== @@ -0,0 +1,20 @@ +{-# Language DerivingVia #-} +{-# Language KindSignatures #-} + +module T18130 where + +import Data.Functor.Classes +import Data.Kind + +newtype Par a b = Par (a, b) + deriving Eq + via (a, b) + :: Type + + deriving Eq1 + via (,) a + :: Type -> Type + + deriving Eq2 + via (,) + :: Type -> Type -> Type ===================================== testsuite/tests/parser/should_compile/all.T ===================================== @@ -166,3 +166,4 @@ test('proposal-229f', multimod_compile_and_run, ['proposal-229f.hs', '']) test('T15730a', normal, compile_and_run, ['']) +test('T18130', normal, compile, ['']) ===================================== testsuite/tests/parser/should_fail/T18130Fail.hs ===================================== @@ -0,0 +1,20 @@ +{-# Language DerivingVia #-} +{-# Language KindSignatures #-} + +module T18130Fail where + +import Data.Functor.Classes +import Data.Kind + +newtype Par a b = Par (a, b) + deriving Eq + via (a, b) + :: Type -> Type + + deriving Eq1 + via (,) a + :: Type -> Type + + deriving Eq2 + via (,) + :: Type -> Type -> Type ===================================== testsuite/tests/parser/should_fail/T18130Fail.stderr ===================================== @@ -0,0 +1,4 @@ + +T18130Fail.hs:11:7: error: + • Expected kind ‘* -> *’, but ‘(a, b)’ has kind ‘*’ + • In the newtype declaration for ‘Par’ ===================================== testsuite/tests/parser/should_fail/all.T ===================================== @@ -166,3 +166,4 @@ test('T17162', normal, compile_fail, ['']) test('proposal-229c', normal, compile_fail, ['']) test('T15730', normal, compile_fail, ['']) test('T15730b', normal, compile_fail, ['']) +test('T18130Fail', normal, compile_fail, ['']) ===================================== testsuite/tests/th/T18121.hs ===================================== @@ -0,0 +1,7 @@ +{-# LANGUAGE TemplateHaskell #-} +module Bug where + +import Language.Haskell.TH + +sapply :: Q (TExp (a -> b)) -> Q (TExp a) -> Q (TExp b) +sapply cf cx = [|| $$cf $$cx ||] ===================================== testsuite/tests/th/T18123.hs ===================================== @@ -0,0 +1,13 @@ +{-# LANGUAGE TemplateHaskell, StandaloneDeriving #-} +module T18123 where + +import Language.Haskell.TH + +data Point = MkPoint { _x, _y :: Double } +data Rect = MkRect { _p1, _p2 :: Point } + +let + deriveEq :: Name -> DecsQ + deriveEq name = [d| deriving instance Eq $(conT name) |] + in + foldMap deriveEq [ ''Point, ''Rect ] ===================================== testsuite/tests/th/all.T ===================================== @@ -506,3 +506,5 @@ test('T18097', normal, compile, ['']) test('TH_PprStar', normal, compile, ['-v0 -dsuppress-uniques']) test('TH_StringLift', normal, compile, ['']) test('TH_BytesShowEqOrd', normal, compile_and_run, ['']) +test('T18121', normal, compile, ['']) +test('T18123', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/611d3111708142bfe42283a14d1017cbae70592d...b4d771c3d750840fc7a7d20bda9119f20f65f39c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/611d3111708142bfe42283a14d1017cbae70592d...b4d771c3d750840fc7a7d20bda9119f20f65f39c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 4 15:32:58 2020 From: gitlab at gitlab.haskell.org (Matthew Pickering) Date: Mon, 04 May 2020 11:32:58 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/typed-th-working Message-ID: <5eb035aa11584_61673f81a47933c087188de@gitlab.haskell.org.mail> Matthew Pickering pushed new branch wip/typed-th-working at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/typed-th-working You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 4 15:33:29 2020 From: gitlab at gitlab.haskell.org (Matthew Pickering) Date: Mon, 04 May 2020 11:33:29 -0400 Subject: [Git][ghc/ghc] Deleted branch wip/typed-th-working Message-ID: <5eb035c91ba34_616711ab08a487190ee@gitlab.haskell.org.mail> Matthew Pickering deleted branch wip/typed-th-working at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 4 16:24:57 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Mon, 04 May 2020 12:24:57 -0400 Subject: [Git][ghc/ghc][wip/nested-cpr-2019] 54 commits: Switch order on `GhcMake.IsBoot` Message-ID: <5eb041d95bfec_61673f819b417d1c8725153@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/nested-cpr-2019 at Glasgow Haskell Compiler / GHC Commits: b0fbfc75 by John Ericson at 2020-04-24T12:07:14-04:00 Switch order on `GhcMake.IsBoot` In !1798 we were requested to replace many `Bool`s with this data type. But those bools had `False` meaning `NotBoot`, so the `Ord` instance would be flipped if we use this data-type as-is. Since the planned formally-`Bool` occurrences vastly outnumber the current occurrences, we figured it would be better to conform the `Ord` instance to how the `Bool` is used now, fixing any issues, rather than fix them currently with the bigger refactor later in !1798. That way, !1798 can be a "pure" refactor with no behavioral changes. - - - - - af332442 by Sylvain Henry at 2020-04-26T13:55:14-04:00 Modules: Utils and Data (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - cd4434c8 by Sylvain Henry at 2020-04-26T13:55:16-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 22bf5c73 by Ömer Sinan Ağacan at 2020-04-26T13:55:22-04:00 Tweak includes in non-moving GC headers We don't use hash tables in non-moving GC so remove the includes. This breaks Compact.c as existing includes no longer include Hash.h, so include Hash.h explicitly in Compact.c. - - - - - 99823ed2 by Sylvain Henry at 2020-04-27T20:24:46-04:00 TH: fix Show/Eq/Ord instances for Bytes (#16457) We shouldn't compare pointer values but the actual bytes. - - - - - c62271a2 by Alp Mestanogullari at 2020-04-27T20:25:33-04:00 hadrian: always capture both stdout and stderr when running a builder fails The idea being that when a builder('s command) fails, we quite likely want to have all the information available to figure out why. Depending on the builder _and_ the particular problem, the useful bits of information can be printed on stdout or stderr. We accomplish this by defining a simple wrapper for Shake's `cmd` function, that just _always_ captures both streams in case the command returns a non-zero exit code, and by using this wrapper everywhere in `hadrian/src/Builder.hs`. Fixes #18089. - - - - - 4b9764db by Ryan Scott at 2020-04-28T15:40:04-04:00 Define a Quote IO instance Fixes #18103. - - - - - 518a63d4 by Ryan Scott at 2020-04-28T15:40:42-04:00 Make boxed 1-tuples have known keys Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. - - - - - 2cfc4ab9 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Document backpack fields in DynFlags - - - - - 10a2ba90 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 69562e34 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 9e2c8e0e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - ea717aa4 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 10d15f1e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 8bfb0219 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - 71484b09 by Alexis King at 2020-04-30T01:57:35-04:00 Allow block arguments in arrow control operators Arrow control operators have their own entries in the grammar, so they did not cooperate with BlockArguments. This was just a minor oversight, so this patch adjusts the grammar to add the desired behavior. fixes #18050 - - - - - a48cd2a0 by Alexis King at 2020-04-30T01:57:35-04:00 Allow LambdaCase to be used as a command in proc notation - - - - - f4d3773c by Alexis King at 2020-04-30T01:57:35-04:00 Document BlockArguments/LambdaCase support in arrow notation - - - - - 5bdfdd13 by Simon Peyton Jones at 2020-04-30T01:58:15-04:00 Add tests for #17873 - - - - - 19b701c2 by Simon Peyton Jones at 2020-04-30T07:30:13-04:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - 014ef4a3 by Matthew Pickering at 2020-04-30T07:30:50-04:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 2aa67611 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - 54dad3cf by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - 99ff8145 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 05b0a9fd by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 Remove OneShotInfo field of LFReEntrant, document OneShotInfo The field is only used in withNewTickyCounterFun and it's easier to directly pass a parameter for one-shot info to withNewTickyCounterFun instead of passing it via LFReEntrant. This also makes !2842 simpler. Other changes: - New Note (by SPJ) [OneShotInfo overview] added. - Arity argument of thunkCode removed as it's always 0. - - - - - a43620c6 by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 GHC.StgToCmm.Ticky: remove a few unused stuff - - - - - 780de9e1 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Use platform in Iface Binary - - - - - f8386c7b by Sylvain Henry at 2020-05-01T10:37:39-04:00 Refactor PprDebug handling If `-dppr-debug` is set, then PprUser and PprDump styles are silently replaced with PprDebug style. This was done in `mkUserStyle` and `mkDumpStyle` smart constructors. As a consequence they needed a DynFlags parameter. Now we keep the original PprUser and PprDump styles until they are used to create an `SDocContext`. I.e. the substitution is only performed in `initSDocContext`. - - - - - b3df9e78 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Remove PprStyle param of logging actions Use `withPprStyle` instead to apply a specific style to a SDoc. - - - - - de9fc995 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Fully remove PprDebug PprDebug was a pain to deal with consistently as it is implied by `-dppr-debug` but it isn't really a PprStyle. We remove it completely and query the appropriate SDoc flag instead (`sdocPprDebug`) via helpers (`getPprDebug` and its friends). - - - - - 8b51fcbd by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Only call checkSingle if we would report warnings - - - - - fd7ea0fe by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 7bfe9ac5 by Ben Gamari at 2020-05-03T04:41:33-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. - - - - - c560dd07 by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Move eventlog documentation users guide - - - - - 02543d5e by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Add documentation for non-moving GC events - - - - - b465dd45 by Alexis King at 2020-05-03T04:42:12-04:00 Flatten nested casts in the simple optimizer Normally, we aren’t supposed to generated any nested casts, since mkCast takes care to flatten them, but the simple optimizer didn’t use mkCast, so they could show up after inlining. This isn’t really a problem, since the simplifier will clean them up immediately anyway, but it can clutter the -ddump-ds output, and it’s an extremely easy fix. closes #18112 - - - - - 5189d36b by Sebastian Graf at 2020-05-03T22:24:23+02:00 Nested CPR - - - - - bd709eed by Sebastian Graf at 2020-05-03T22:24:25+02:00 Move tests from stranal to cpranal - - - - - 8b10d824 by Sebastian Graf at 2020-05-03T22:24:25+02:00 Accept FacState - - - - - ab1d9661 by Sebastian Graf at 2020-05-03T22:26:22+02:00 Factor Cpr and Termination into a joint lattice As a result, we don't even have to export Termination from Cpr. Neat! Also I realised there is a simpler and more sound way to generate and unleash CPR signatures. - - - - - 32696ae3 by Sebastian Graf at 2020-05-03T22:29:08+02:00 Consider unboxing effects of WW better and get rid of hack - - - - - db52466c by Sebastian Graf at 2020-05-03T22:29:10+02:00 stuff - - - - - 08923728 by Sebastian Graf at 2020-05-03T22:29:10+02:00 Debug output - - - - - 5fa39431 by Sebastian Graf at 2020-05-03T22:29:11+02:00 A slew of testsuite changes - - - - - bab525de by Sebastian Graf at 2020-05-03T22:29:11+02:00 Fix T1600 - - - - - 31f4f11b by Sebastian Graf at 2020-05-03T22:29:11+02:00 Inline `decodeDoubleInteger` and constant-fold `decodeDouble_Int64#` instead Currently, `decodeDoubleInteger` is known-key so that it can be recognised in constant folding. But that is very brittle and doesn't survive worker/wrapper, which we even do for `NOINLINE`/`CONSTANT_FOLDED` things since #13143. Also it is a trade-off: The implementation of `decodeDoubleInteger` allocates an `Integer` box that never cancels aways if we don't inline it. Hence we recognise the `decodeDouble_Int64#` primop instead in constant folding, so that we can inline `decodeDoubleInteger`. You may wonder how this affects performance of code using `integer-simple`; Apparently, according to @hsyl20 this is not a concern since we will hopefully land !2231 soon. Fixes #18092. - - - - - 8427dd1c by Sebastian Graf at 2020-05-03T22:29:11+02:00 Fix primop termination - - - - - 26599e89 by Sebastian Graf at 2020-05-03T22:29:11+02:00 Test for DataCon wrapper CPR - - - - - f1cebd39 by Sebastian Graf at 2020-05-03T22:29:11+02:00 Fix CPR of bottoming functions/primops - - - - - db9873c0 by Sebastian Graf at 2020-05-03T22:29:11+02:00 Fix DataConWrapperCpr and accept other test outputs - - - - - 9e20dd85 by Sebastian Graf at 2020-05-03T22:29:11+02:00 Accept two more changed test outputs - - - - - 6d523cc8 by Sebastian Graf at 2020-05-03T22:29:11+02:00 Update CaseBinderCPR with a new function - - - - - 910edd76 by Sebastian Graf at 2020-05-03T22:29:38+02:00 Don't give the case binder the CPR property - - - - - 91b545f5 by Sebastian Graf at 2020-05-04T18:24:42+02:00 Limit CPR on DataCon app bindings - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/PrimOps.hs-boot - 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/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/ByteCode/Asm.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/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Block.hs - compiler/GHC/Cmm/Dataflow/Collections.hs - compiler/GHC/Cmm/Dataflow/Graph.hs - compiler/GHC/Cmm/Dataflow/Label.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Expr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e64516e7a710c7402660b9a05bdf97fa8f7d5134...91b545f5e2aefede98603d65b2a7056558d27880 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e64516e7a710c7402660b9a05bdf97fa8f7d5134...91b545f5e2aefede98603d65b2a7056558d27880 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 4 17:20:13 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Mon, 04 May 2020 13:20:13 -0400 Subject: [Git][ghc/ghc][master] Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) Message-ID: <5eb04ecde8f15_61673f81cd4c695c87397d6@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 30272412 by Artem Pelenitsyn at 2020-05-04T13:19:59-04:00 Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Data/IOEnv.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Monad.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Types.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Runtime/Debugger.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Linker.hs - compiler/GHC/SysTools/FileCleanup.hs - compiler/GHC/SysTools/Tasks.hs - compiler/GHC/Utils/Error.hs - compiler/GHC/Utils/Exception.hs - compiler/GHC/Utils/Panic.hs - compiler/ghc.cabal.in - docs/users_guide/8.12.1-notes.rst - ghc.mk - ghc/GHCi/UI.hs - ghc/GHCi/UI/Info.hs - ghc/GHCi/UI/Monad.hs - hadrian/src/Settings/Default.hs - testsuite/tests/ghc-api/Makefile - testsuite/tests/ghc-api/T8628.hs - testsuite/tests/ghc-api/downsweep/PartialDownsweep.hs - testsuite/tests/ghc-api/downsweep/all.T - testsuite/tests/ghc-api/target-contents/TargetContents.hs - testsuite/tests/ghc-api/target-contents/all.T - utils/haddock Changes: ===================================== compiler/GHC.hs ===================================== @@ -22,7 +22,6 @@ module GHC ( -- * GHC Monad Ghc, GhcT, GhcMonad(..), HscEnv, runGhc, runGhcT, initGhcMonad, - gcatch, gbracket, gfinally, printException, handleSourceError, needsTemplateHaskellOrQQ, @@ -378,6 +377,7 @@ import Data.IORef import System.FilePath import Control.Concurrent import Control.Applicative ((<|>)) +import Control.Monad.Catch as MC import GHC.Data.Maybe import System.IO.Error ( isDoesNotExistError ) @@ -400,7 +400,7 @@ defaultErrorHandler :: (ExceptionMonad m) => FatalMessager -> FlushOut -> m a -> m a defaultErrorHandler fm (FlushOut flushOut) inner = -- top-level exception handler: any unrecognised exception is a compiler bug. - ghandle (\exception -> liftIO $ do + MC.handle (\exception -> liftIO $ do flushOut case fromException exception of -- an IO exception probably isn't our fault, so don't panic @@ -437,7 +437,7 @@ defaultErrorHandler fm (FlushOut flushOut) inner = {-# DEPRECATED defaultCleanupHandler "Cleanup is now done by runGhc/runGhcT" #-} defaultCleanupHandler :: (ExceptionMonad m) => DynFlags -> m a -> m a defaultCleanupHandler _ m = m - where _warning_suppression = m `gonException` undefined + where _warning_suppression = m `MC.onException` undefined -- %************************************************************************ @@ -483,7 +483,7 @@ runGhcT mb_top_dir ghct = do withCleanupSession ghct withCleanupSession :: GhcMonad m => m a -> m a -withCleanupSession ghc = ghc `gfinally` cleanup +withCleanupSession ghc = ghc `MC.finally` cleanup where cleanup = do hsc_env <- getSession @@ -1698,7 +1698,7 @@ interpretPackageEnv dflags = do getEnvVar :: MaybeT IO String getEnvVar = do - mvar <- liftMaybeT $ try $ getEnv "GHC_ENVIRONMENT" + mvar <- liftMaybeT $ MC.try $ getEnv "GHC_ENVIRONMENT" case mvar of Right var -> return var Left err -> if isDoesNotExistError err then mzero ===================================== compiler/GHC/Data/IOEnv.hs ===================================== @@ -1,5 +1,6 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE DeriveFunctor #-} +{-# LANGUAGE DerivingVia #-} -- -- (c) The University of Glasgow 2002-2006 -- @@ -43,6 +44,8 @@ import Data.IORef ( IORef, newIORef, readIORef, writeIORef, modifyIORef, import System.IO.Unsafe ( unsafeInterleaveIO ) import System.IO ( fixIO ) import Control.Monad +import Control.Monad.Trans.Reader +import Control.Monad.Catch (MonadCatch, MonadMask, MonadThrow) import GHC.Utils.Monad import Control.Applicative (Alternative(..)) @@ -51,7 +54,9 @@ import Control.Applicative (Alternative(..)) ---------------------------------------------------------------------- -newtype IOEnv env a = IOEnv (env -> IO a) deriving (Functor) +newtype IOEnv env a = IOEnv (env -> IO a) + deriving (Functor) + deriving (MonadThrow, MonadCatch, MonadMask, MonadIO) via (ReaderT env IO) unIOEnv :: IOEnv env a -> (env -> IO a) unIOEnv (IOEnv m) = m @@ -91,16 +96,6 @@ instance Show IOEnvFailure where instance Exception IOEnvFailure -instance ExceptionMonad (IOEnv a) where - gcatch act handle = - IOEnv $ \s -> unIOEnv act s `gcatch` \e -> unIOEnv (handle e) s - gmask f = - IOEnv $ \s -> gmask $ \io_restore -> - let - g_restore (IOEnv m) = IOEnv $ \s -> io_restore (m s) - in - unIOEnv (f g_restore) s - instance ContainsDynFlags env => HasDynFlags (IOEnv env) where getDynFlags = do env <- getEnv return $! extractDynFlags env @@ -176,9 +171,6 @@ instance MonadPlus (IOEnv env) -- Accessing input/output ---------------------------------------------------------------------- -instance MonadIO (IOEnv env) where - liftIO io = IOEnv (\ _ -> io) - newMutVar :: a -> IOEnv env (IORef a) newMutVar val = liftIO (newIORef val) ===================================== compiler/GHC/Driver/Make.hs ===================================== @@ -53,7 +53,7 @@ import GHC.Driver.Main import GHC.Data.Bag ( unitBag, listToBag, unionManyBags, isEmptyBag ) import GHC.Types.Basic import GHC.Data.Graph.Directed -import GHC.Utils.Exception ( tryIO, gbracket, gfinally ) +import GHC.Utils.Exception ( tryIO ) import GHC.Data.FastString import GHC.Data.Maybe ( expectJust ) import GHC.Types.Name @@ -85,6 +85,7 @@ import Control.Concurrent.QSem import Control.Exception import Control.Monad import Control.Monad.Trans.Except ( ExceptT(..), runExceptT, throwE ) +import qualified Control.Monad.Catch as MC import Data.IORef import Data.List import qualified Data.List as List @@ -994,10 +995,10 @@ parUpsweep n_jobs mHscMessage old_hpt stable_mods cleanup sccs = do -- Reset the number of capabilities once the upsweep ends. let resetNumCapabilities orig_n = liftIO $ setNumCapabilities orig_n - gbracket updNumCapabilities resetNumCapabilities $ \_ -> do + MC.bracket updNumCapabilities resetNumCapabilities $ \_ -> do -- Sync the global session with the latest HscEnv once the upsweep ends. - let finallySyncSession io = io `gfinally` do + let finallySyncSession io = io `MC.finally` do hsc_env <- liftIO $ readMVar hsc_env_var setSession hsc_env @@ -1061,7 +1062,7 @@ parUpsweep n_jobs mHscMessage old_hpt stable_mods cleanup sccs = do -- Unmask asynchronous exceptions and perform the thread-local -- work to compile the module (see parUpsweep_one). - m_res <- try $ unmask $ prettyPrintGhcErrors lcl_dflags $ + m_res <- MC.try $ unmask $ prettyPrintGhcErrors lcl_dflags $ parUpsweep_one mod home_mod_map comp_graph_loops lcl_dflags mHscMessage cleanup par_sem hsc_env_var old_hpt_var @@ -1097,12 +1098,12 @@ parUpsweep n_jobs mHscMessage old_hpt stable_mods cleanup sccs = do -- Kill all the workers, masking interrupts (since killThread is -- interruptible). XXX: This is not ideal. - ; killWorkers = uninterruptibleMask_ . mapM_ killThread } + ; killWorkers = MC.uninterruptibleMask_ . mapM_ killThread } -- Spawn the workers, making sure to kill them later. Collect the results -- of each compile. - results <- liftIO $ bracket spawnWorkers killWorkers $ \_ -> + results <- liftIO $ MC.bracket spawnWorkers killWorkers $ \_ -> -- Loop over each module in the compilation graph in order, printing -- each message from its log_queue. forM comp_graph $ \(mod,mvar,log_queue) -> do @@ -1278,7 +1279,7 @@ parUpsweep_one mod home_mod_map comp_graph_loops lcl_dflags mHscMessage cleanup let logger err = printBagOfErrors lcl_dflags (srcErrorMessages err) -- Limit the number of parallel compiles. - let withSem sem = bracket_ (waitQSem sem) (signalQSem sem) + let withSem sem = MC.bracket_ (waitQSem sem) (signalQSem sem) mb_mod_info <- withSem par_sem $ handleSourceError (\err -> do logger err; return Nothing) $ do -- Have the ModSummary and HscEnv point to our local log_action @@ -2671,7 +2672,7 @@ withDeferredDiagnostics f = do setLogAction action = modifySession $ \hsc_env -> hsc_env{ hsc_dflags = (hsc_dflags hsc_env){ log_action = action } } - gbracket + MC.bracket (setLogAction deferDiagnostics) (\_ -> setLogAction (log_action dflags) >> printDeferredDiagnostics) (\_ -> f) ===================================== compiler/GHC/Driver/Monad.hs ===================================== @@ -1,4 +1,4 @@ -{-# LANGUAGE CPP, DeriveFunctor, RankNTypes #-} +{-# LANGUAGE CPP, DeriveFunctor, DerivingVia, RankNTypes #-} {-# OPTIONS_GHC -funbox-strict-fields #-} -- ----------------------------------------------------------------------------- -- @@ -32,6 +32,8 @@ import GHC.Utils.Exception import GHC.Utils.Error import Control.Monad +import Control.Monad.Catch as MC +import Control.Monad.Trans.Reader import Data.IORef -- ----------------------------------------------------------------------------- @@ -50,7 +52,7 @@ import Data.IORef -- If you do not use 'Ghc' or 'GhcT', make sure to call 'GHC.initGhcMonad' -- before any call to the GHC API functions can occur. -- -class (Functor m, MonadIO m, ExceptionMonad m, HasDynFlags m) => GhcMonad m where +class (Functor m, ExceptionMonad m, HasDynFlags m) => GhcMonad m where getSession :: m HscEnv setSession :: HscEnv -> m () @@ -71,7 +73,7 @@ modifySession f = do h <- getSession withSavedSession :: GhcMonad m => m a -> m a withSavedSession m = do saved_session <- getSession - m `gfinally` setSession saved_session + m `MC.finally` setSession saved_session -- | Call an action with a temporarily modified Session. withTempSession :: GhcMonad m => (HscEnv -> HscEnv) -> m a -> m a @@ -90,7 +92,9 @@ logWarnings warns = do -- | A minimal implementation of a 'GhcMonad'. If you need a custom monad, -- e.g., to maintain additional state consider wrapping this monad or using -- 'GhcT'. -newtype Ghc a = Ghc { unGhc :: Session -> IO a } deriving (Functor) +newtype Ghc a = Ghc { unGhc :: Session -> IO a } + deriving (Functor) + deriving (MonadThrow, MonadCatch, MonadMask) via (ReaderT Session IO) -- | The Session is a handle to the complete state of a compilation -- session. A compilation session consists of a set of modules @@ -111,16 +115,6 @@ instance MonadIO Ghc where instance MonadFix Ghc where mfix f = Ghc $ \s -> mfix (\x -> unGhc (f x) s) -instance ExceptionMonad Ghc where - gcatch act handle = - Ghc $ \s -> unGhc act s `gcatch` \e -> unGhc (handle e) s - gmask f = - Ghc $ \s -> gmask $ \io_restore -> - let - g_restore (Ghc m) = Ghc $ \s -> io_restore (m s) - in - unGhc (f g_restore) s - instance HasDynFlags Ghc where getDynFlags = getSessionDynFlags @@ -155,7 +149,8 @@ reifyGhc act = Ghc $ act -- -- Note that the wrapped monad must support IO and handling of exceptions. newtype GhcT m a = GhcT { unGhcT :: Session -> m a } - deriving (Functor) + deriving (Functor) + deriving (MonadThrow, MonadCatch, MonadMask) via (ReaderT Session m) liftGhcT :: m a -> GhcT m a liftGhcT m = GhcT $ \_ -> m @@ -170,16 +165,6 @@ instance Monad m => Monad (GhcT m) where instance MonadIO m => MonadIO (GhcT m) where liftIO ioA = GhcT $ \_ -> liftIO ioA -instance ExceptionMonad m => ExceptionMonad (GhcT m) where - gcatch act handle = - GhcT $ \s -> unGhcT act s `gcatch` \e -> unGhcT (handle e) s - gmask f = - GhcT $ \s -> gmask $ \io_restore -> - let - g_restore (GhcT m) = GhcT $ \s -> io_restore (m s) - in - unGhcT (f g_restore) s - instance MonadIO m => HasDynFlags (GhcT m) where getDynFlags = GhcT $ \(Session r) -> liftM hsc_dflags (liftIO $ readIORef r) ===================================== compiler/GHC/Driver/Pipeline.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE CPP, NamedFieldPuns, NondecreasingIndentation, BangPatterns, MultiWayIf #-} +{-# LANGUAGE ScopedTypeVariables #-} {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} @@ -77,6 +78,7 @@ import System.Directory import System.FilePath import System.IO import Control.Monad +import qualified Control.Monad.Catch as MC (handle) import Data.List ( isInfixOf, intercalate ) import Data.Maybe import Data.Version @@ -101,7 +103,7 @@ preprocess :: HscEnv -> IO (Either ErrorMessages (DynFlags, FilePath)) preprocess hsc_env input_fn mb_input_buf mb_phase = handleSourceError (\err -> return (Left (srcErrorMessages err))) $ - ghandle handler $ + MC.handle handler $ fmap Right $ do MASSERT2(isJust mb_phase || isHaskellSrcFilename input_fn, text input_fn) (dflags, fp, mb_iface) <- runPipeline anyHsc hsc_env (input_fn, mb_input_buf, fmap RealPhase mb_phase) ===================================== compiler/GHC/Driver/Types.hs ===================================== @@ -231,6 +231,7 @@ import System.FilePath import Control.DeepSeq import Control.Monad.Trans.Reader import Control.Monad.Trans.Class +import Control.Monad.Catch as MC (MonadCatch, catch) -- ----------------------------------------------------------------------------- -- Compilation state @@ -352,12 +353,12 @@ instance Exception SourceError -- | Perform the given action and call the exception handler if the action -- throws a 'SourceError'. See 'SourceError' for more information. -handleSourceError :: (ExceptionMonad m) => +handleSourceError :: (MonadCatch m) => (SourceError -> m a) -- ^ exception handler -> m a -- ^ action to perform -> m a handleSourceError handler act = - gcatch act (\(e :: SourceError) -> handler e) + MC.catch act (\(e :: SourceError) -> handler e) -- | An error thrown if the GHC API is used in an incorrect fashion. newtype GhcApiError = GhcApiError String ===================================== compiler/GHC/Iface/Recomp.hs ===================================== @@ -615,14 +615,14 @@ checkModUsage this_pkg UsageHomeModule{ checkModUsage _this_pkg UsageFile{ usg_file_path = file, usg_file_hash = old_hash } = liftIO $ - handleIO handle $ do + handleIO handler $ do new_hash <- getFileHash file if (old_hash /= new_hash) then return recomp else return UpToDate where - recomp = RecompBecause (file ++ " changed") - handle = + recomp = RecompBecause (file ++ " changed") + handler = #if defined(DEBUG) \e -> pprTrace "UsageFile" (text (show e)) $ return recomp #else ===================================== compiler/GHC/Runtime/Debugger.hs ===================================== @@ -40,6 +40,7 @@ import GHC.Driver.Session import GHC.Utils.Exception import Control.Monad +import Control.Monad.Catch as MC import Data.List ( (\\) ) import Data.Maybe import Data.IORef @@ -192,7 +193,7 @@ showTerm term = do return $ Just $ cparen (prec >= myprec && needsParens txt) (text txt) else return Nothing - `gfinally` do + `MC.finally` do setSession hsc_env GHC.setSessionDynFlags dflags cPprShowable prec NewtypeWrap{ty=new_ty,wrapped_term=t} = @@ -228,7 +229,7 @@ pprTypeAndContents id = do let depthBound = 100 -- If the value is an exception, make sure we catch it and -- show the exception, rather than propagating the exception out. - e_term <- gtry $ GHC.obtainTermFromId depthBound False id + e_term <- MC.try $ GHC.obtainTermFromId depthBound False id docs_term <- case e_term of Right term -> showTerm term Left exn -> return (text "*** Exception:" <+> ===================================== compiler/GHC/Runtime/Eval.hs ===================================== @@ -108,6 +108,7 @@ import Data.Map (Map) import qualified Data.Map as Map import GHC.Data.StringBuffer (stringToStringBuffer) import Control.Monad +import Control.Monad.Catch as MC import Data.Array import GHC.Utils.Exception import Unsafe.Coerce ( unsafeCoerce ) @@ -291,7 +292,7 @@ withVirtualCWD m = do setSession hsc_env{ hsc_IC = old_IC{ ic_cwd = Just virt_dir } } liftIO $ setCurrentDirectory orig_dir - gbracket set_cwd reset_cwd $ \_ -> m + MC.bracket set_cwd reset_cwd $ \_ -> m parseImportDecl :: GhcMonad m => String -> m (ImportDecl GhcPs) parseImportDecl expr = withSession $ \hsc_env -> liftIO $ hscImport hsc_env expr ===================================== compiler/GHC/Runtime/Interpreter.hs ===================================== @@ -65,7 +65,7 @@ import GHC.Driver.Types import GHC.Types.Unique.FM import GHC.Utils.Panic import GHC.Driver.Session -import GHC.Utils.Exception +import GHC.Utils.Exception as Ex import GHC.Types.Basic import GHC.Data.FastString import GHC.Utils.Misc @@ -85,6 +85,7 @@ import GHC.Driver.Ways import Control.Concurrent import Control.Monad import Control.Monad.IO.Class +import Control.Monad.Catch as MC (mask, onException) import Data.Binary import Data.Binary.Put import Data.ByteString (ByteString) @@ -211,17 +212,17 @@ hscInterp hsc_env = case hsc_interp hsc_env of -- | Grab a lock on the 'IServ' and do something with it. -- Overloaded because this is used from TcM as well as IO. withIServ - :: (MonadIO m, ExceptionMonad m) + :: (ExceptionMonad m) => IServConfig -> IServ -> (IServInstance -> m (IServInstance, a)) -> m a withIServ conf (IServ mIServState) action = do - gmask $ \restore -> do + MC.mask $ \restore -> do state <- liftIO $ takeMVar mIServState iserv <- case state of -- start the external iserv process if we haven't done so yet IServPending -> liftIO (spawnIServ conf) - `gonException` (liftIO $ putMVar mIServState state) + `MC.onException` (liftIO $ putMVar mIServState state) IServRunning inst -> return inst @@ -234,7 +235,7 @@ withIServ conf (IServ mIServState) action = do iservCall iserv (FreeHValueRefs (iservPendingFrees iserv)) -- run the inner action restore $ action iserv') - `gonException` (liftIO $ putMVar mIServState (IServRunning iserv')) + `MC.onException` (liftIO $ putMVar mIServState (IServRunning iserv')) liftIO $ putMVar mIServState (IServRunning iserv'') return a @@ -584,7 +585,7 @@ stopInterp hsc_env = case hsc_interp hsc_env of Just InternalInterp -> pure () #endif Just (ExternalInterp _ (IServ mstate)) -> - gmask $ \_restore -> modifyMVar_ mstate $ \state -> do + MC.mask $ \_restore -> modifyMVar_ mstate $ \state -> do case state of IServPending -> pure state -- already stopped IServRunning i -> do @@ -614,7 +615,7 @@ runWithPipes createProc prog opts = do wh <- mkHandle wfd2 return (ph, rh, wh) where mkHandle :: CInt -> IO Handle - mkHandle fd = (fdToHandle fd) `onException` (c__close fd) + mkHandle fd = (fdToHandle fd) `Ex.onException` (c__close fd) #else runWithPipes createProc prog opts = do ===================================== compiler/GHC/Runtime/Linker.hs ===================================== @@ -72,6 +72,7 @@ import Data.IORef import Data.List (intercalate, isPrefixOf, isSuffixOf, nub, partition) import Data.Maybe import Control.Concurrent.MVar +import qualified Control.Monad.Catch as MC import System.FilePath import System.Directory @@ -216,7 +217,7 @@ linkDependencies hsc_env pls span needed_mods = do withExtendedLinkEnv :: (ExceptionMonad m) => DynLinker -> [(Name,ForeignHValue)] -> m a -> m a withExtendedLinkEnv dl new_env action - = gbracket (liftIO $ extendLinkEnv dl new_env) + = MC.bracket (liftIO $ extendLinkEnv dl new_env) (\_ -> reset_old_env) (\_ -> action) where ===================================== compiler/GHC/SysTools/FileCleanup.hs ===================================== @@ -299,7 +299,7 @@ withTempDirectory targetDir template = (ignoringIOErrors . removeDirectoryRecursive) ignoringIOErrors :: IO () -> IO () -ignoringIOErrors ioe = ioe `catch` (\e -> const (return ()) (e :: IOError)) +ignoringIOErrors ioe = ioe `catchIO` const (return ()) createTempDirectory :: FilePath -> String -> IO FilePath ===================================== compiler/GHC/SysTools/Tasks.hs ===================================== @@ -186,7 +186,7 @@ runClang dflags args = traceToolCommand dflags "clang" $ do args1 = map Option (getOpts dflags opt_a) args2 = args0 ++ args1 ++ args mb_env <- getGccEnv args2 - Exception.catch (do + catch (do runSomethingFiltered dflags id "Clang (Assembler)" clang args2 Nothing mb_env ) (\(err :: SomeException) -> do ===================================== compiler/GHC/Utils/Error.hs ===================================== @@ -89,6 +89,7 @@ import Data.Time import Debug.Trace import Control.Monad import Control.Monad.IO.Class +import Control.Monad.Catch as MC (handle) import System.IO import System.IO.Error ( catchIOError ) import GHC.Conc ( getAllocationCounter ) @@ -800,7 +801,7 @@ logOutput dflags msg prettyPrintGhcErrors :: ExceptionMonad m => DynFlags -> m a -> m a prettyPrintGhcErrors dflags - = ghandle $ \e -> case e of + = MC.handle $ \e -> case e of PprPanic str doc -> pprDebugAndThen dflags panic (text str) doc PprSorry str doc -> ===================================== compiler/GHC/Utils/Exception.hs ===================================== @@ -1,4 +1,6 @@ {-# OPTIONS_GHC -fno-warn-deprecations #-} +{-# LANGUAGE ConstraintKinds #-} + module GHC.Utils.Exception ( module Control.Exception, @@ -9,75 +11,18 @@ module GHC.Utils.Exception import GHC.Prelude import Control.Exception +import Control.Exception as CE import Control.Monad.IO.Class +import Control.Monad.Catch +-- Monomorphised versions of exception-handling utilities catchIO :: IO a -> (IOException -> IO a) -> IO a -catchIO = Control.Exception.catch +catchIO = CE.catch handleIO :: (IOException -> IO a) -> IO a -> IO a handleIO = flip catchIO tryIO :: IO a -> IO (Either IOException a) -tryIO = try - --- | A monad that can catch exceptions. A minimal definition --- requires a definition of 'gcatch'. --- --- Implementations on top of 'IO' should implement 'gmask' to --- eventually call the primitive 'Control.Exception.mask'. --- These are used for --- implementations that support asynchronous exceptions. The default --- implementations of 'gbracket' and 'gfinally' use 'gmask' --- thus rarely require overriding. --- -class MonadIO m => ExceptionMonad m where - - -- | Generalised version of 'Control.Exception.catch', allowing an arbitrary - -- exception handling monad instead of just 'IO'. - gcatch :: Exception e => m a -> (e -> m a) -> m a - - -- | Generalised version of 'Control.Exception.mask_', allowing an arbitrary - -- exception handling monad instead of just 'IO'. - gmask :: ((m a -> m a) -> m b) -> m b - - -- | Generalised version of 'Control.Exception.bracket', allowing an arbitrary - -- exception handling monad instead of just 'IO'. - gbracket :: m a -> (a -> m b) -> (a -> m c) -> m c - - -- | Generalised version of 'Control.Exception.finally', allowing an arbitrary - -- exception handling monad instead of just 'IO'. - gfinally :: m a -> m b -> m a - - gbracket before after thing = - gmask $ \restore -> do - a <- before - r <- restore (thing a) `gonException` after a - _ <- after a - return r - - a `gfinally` sequel = - gmask $ \restore -> do - r <- restore a `gonException` sequel - _ <- sequel - return r - -instance ExceptionMonad IO where - gcatch = Control.Exception.catch - gmask f = mask (\x -> f x) - -gtry :: (ExceptionMonad m, Exception e) => m a -> m (Either e a) -gtry act = gcatch (act >>= \a -> return (Right a)) - (\e -> return (Left e)) - --- | Generalised version of 'Control.Exception.handle', allowing an arbitrary --- exception handling monad instead of just 'IO'. -ghandle :: (ExceptionMonad m, Exception e) => (e -> m a) -> m a -> m a -ghandle = flip gcatch - --- | Always executes the first argument. If this throws an exception the --- second argument is executed and the exception is raised again. -gonException :: (ExceptionMonad m) => m a -> m b -> m a -gonException ioA cleanup = ioA `gcatch` \e -> - do _ <- cleanup - liftIO $ throwIO (e :: SomeException) +tryIO = CE.try +type ExceptionMonad m = (MonadCatch m, MonadThrow m, MonadMask m, MonadIO m) ===================================== compiler/GHC/Utils/Panic.hs ===================================== @@ -36,6 +36,7 @@ import GHC.Utils.Panic.Plain import GHC.Utils.Exception as Exception import Control.Monad.IO.Class +import qualified Control.Monad.Catch as MC import Control.Concurrent import Data.Typeable ( cast ) import Debug.Trace ( trace ) @@ -155,7 +156,7 @@ throwGhcExceptionIO :: GhcException -> IO a throwGhcExceptionIO = Exception.throwIO handleGhcException :: ExceptionMonad m => (GhcException -> m a) -> m a -> m a -handleGhcException = ghandle +handleGhcException = MC.handle panicDoc, sorryDoc, pgmErrorDoc :: String -> SDoc -> a panicDoc x doc = throwGhcException (PprPanic x doc) @@ -197,7 +198,7 @@ signalHandlersRefCount = unsafePerformIO $ newMVar (0,Nothing) -- | Temporarily install standard signal handlers for catching ^C, which just -- throw an exception in the current thread. -withSignalHandlers :: (ExceptionMonad m, MonadIO m) => m a -> m a +withSignalHandlers :: ExceptionMonad m => m a -> m a withSignalHandlers act = do main_thread <- liftIO myThreadId wtid <- liftIO (mkWeakThreadId main_thread) @@ -256,4 +257,4 @@ withSignalHandlers act = do (c,oldHandlers) -> return (c-1,oldHandlers) mayInstallHandlers - act `gfinally` mayUninstallHandlers + act `MC.finally` mayUninstallHandlers ===================================== compiler/ghc.cabal.in ===================================== @@ -72,6 +72,7 @@ Library template-haskell == 2.17.*, hpc == 0.6.*, transformers == 0.5.*, + exceptions == 0.10.*, ghc-boot == @ProjectVersionMunged@, ghc-boot-th == @ProjectVersionMunged@, ghc-heap == @ProjectVersionMunged@, ===================================== docs/users_guide/8.12.1-notes.rst ===================================== @@ -148,6 +148,14 @@ Arrow notation ``hsGroupTopLevelFixitySigs`` function, which collects all top-level fixity signatures, including those for class methods defined inside classes. +- The ``Exception`` module was boiled down acknowledging the existence of + the ``exceptions`` dependency. In particular, the ``ExceptionMonad`` + class is not a proper class anymore, but a mere synonym for ``MonadThrow``, + ``MonadCatch``, ``MonadMask`` (all from ``exceptions``) and ``MonadIO``. + All of ``g*``-functions from the module (``gtry``, ``gcatch``, etc.) are + erased, and their ``exceptions``-alternatives are meant to be used in the + GHC code instead. + ``base`` library ~~~~~~~~~~~~~~~~ ===================================== ghc.mk ===================================== @@ -414,7 +414,7 @@ else # CLEANING # programs such as GHC and ghc-pkg, that we do not assume the stage0 # compiler already has installed (or up-to-date enough). # Note that these must be given in topological order. -PACKAGES_STAGE0 = binary transformers mtl hpc ghc-boot-th ghc-boot template-haskell text parsec Cabal/Cabal ghc-heap ghci +PACKAGES_STAGE0 = binary transformers mtl hpc ghc-boot-th ghc-boot template-haskell text parsec Cabal/Cabal ghc-heap exceptions ghci ifeq "$(Windows_Host)" "NO" PACKAGES_STAGE0 += terminfo endif ===================================== ghc/GHCi/UI.hs ===================================== @@ -80,7 +80,7 @@ import GHC.Data.FastString import GHC.Runtime.Linker import GHC.Data.Maybe ( orElse, expectJust ) import GHC.Types.Name.Set -import GHC.Utils.Panic hiding ( showException ) +import GHC.Utils.Panic hiding ( showException, try ) import GHC.Utils.Misc import qualified GHC.LanguageExtensions as LangExt import GHC.Data.Bag (unitBag) @@ -91,6 +91,7 @@ import System.Console.Haskeline as Haskeline import Control.Applicative hiding (empty) import Control.DeepSeq (deepseq) import Control.Monad as Monad +import Control.Monad.Catch as MC import Control.Monad.IO.Class import Control.Monad.Trans.Class import Control.Monad.Trans.Except @@ -112,7 +113,7 @@ import Data.Time.Format ( formatTime, defaultTimeLocale ) import Data.Version ( showVersion ) import Prelude hiding ((<>)) -import GHC.Utils.Exception as Exception hiding (catch) +import GHC.Utils.Exception as Exception hiding (catch, mask, handle) import Foreign hiding (void) import GHC.Stack hiding (SrcLoc(..)) @@ -984,12 +985,9 @@ runCommands gCmd = runCommands' handler Nothing gCmd >> return () runCommands' :: (SomeException -> GHCi Bool) -- ^ Exception handler -> Maybe (GHCi ()) -- ^ Source error handler -> InputT GHCi (Maybe String) - -> InputT GHCi (Maybe Bool) - -- We want to return () here, but have to return (Maybe Bool) - -- because gmask is not polymorphic enough: we want to use - -- unmask at two different types. -runCommands' eh sourceErrorHandler gCmd = gmask $ \unmask -> do - b <- ghandle (\e -> case fromException e of + -> InputT GHCi () +runCommands' eh sourceErrorHandler gCmd = mask $ \unmask -> do + b <- handle (\e -> case fromException e of Just UserInterrupt -> return $ Just False _ -> case fromException e of Just ghce -> @@ -999,7 +997,7 @@ runCommands' eh sourceErrorHandler gCmd = gmask $ \unmask -> do liftIO (Exception.throwIO e)) (unmask $ runOneCommand eh gCmd) case b of - Nothing -> return Nothing + Nothing -> return () Just success -> do unless success $ maybe (return ()) lift sourceErrorHandler unmask $ runCommands' eh sourceErrorHandler gCmd @@ -1039,7 +1037,7 @@ runOneCommand eh gCmd = do st <- getGHCiState let p = prompt st setGHCiState st{ prompt = prompt_cont st } - mb_cmd <- collectCommand q "" `GHC.gfinally` + mb_cmd <- collectCommand q "" `MC.finally` modifyGHCiState (\st' -> st' { prompt = p }) return mb_cmd -- we can't use removeSpaces for the sublines here, so @@ -1819,7 +1817,7 @@ instancesCmd s = do -- '-fdefer-type-errors' again if it has not been set before. wrapDeferTypeErrors :: GHC.GhcMonad m => m a -> m a wrapDeferTypeErrors load = - gbracket + MC.bracket (do -- Force originalFlags to avoid leaking the associated HscEnv !originalFlags <- getDynFlags @@ -1960,11 +1958,11 @@ doLoad retain_context howmuch = do -- Enable buffering stdout and stderr as we're compiling. Keeping these -- handles unbuffered will just slow the compilation down, especially when -- compiling in parallel. - gbracket (liftIO $ do hSetBuffering stdout LineBuffering - hSetBuffering stderr LineBuffering) - (\_ -> - liftIO $ do hSetBuffering stdout NoBuffering - hSetBuffering stderr NoBuffering) $ \_ -> do + MC.bracket (liftIO $ do hSetBuffering stdout LineBuffering + hSetBuffering stderr LineBuffering) + (\_ -> + liftIO $ do hSetBuffering stdout NoBuffering + hSetBuffering stderr NoBuffering) $ \_ -> do ok <- trySuccess $ GHC.load howmuch afterLoad ok retain_context return ok @@ -2048,7 +2046,7 @@ keepPackageImports = filterM is_pkg_import is_pkg_import :: GHC.GhcMonad m => InteractiveImport -> m Bool is_pkg_import (IIModule _) = return False is_pkg_import (IIDecl d) - = do e <- gtry $ GHC.findModule mod_name (fmap sl_fs $ ideclPkgQual d) + = do e <- MC.try $ GHC.findModule mod_name (fmap sl_fs $ ideclPkgQual d) case e :: Either SomeException Module of Left _ -> return False Right m -> return (not (isHomeModule m)) @@ -2556,7 +2554,7 @@ restoreContextOnFailure :: GhciMonad m => m a -> m a restoreContextOnFailure do_this = do st <- getGHCiState let rc = remembered_ctx st; tc = transient_ctx st - do_this `gonException` (modifyGHCiState $ \st' -> + do_this `MC.onException` (modifyGHCiState $ \st' -> st' { remembered_ctx = rc, transient_ctx = tc }) -- ----------------------------------------------------------------------------- @@ -4160,13 +4158,13 @@ showException se = -- may never be delivered. Thanks to Marcin for pointing out the bug. ghciHandle :: (HasDynFlags m, ExceptionMonad m) => (SomeException -> m a) -> m a -> m a -ghciHandle h m = gmask $ \restore -> do +ghciHandle h m = mask $ \restore -> do -- Force dflags to avoid leaking the associated HscEnv !dflags <- getDynFlags - gcatch (restore (GHC.prettyPrintGhcErrors dflags m)) $ \e -> restore (h e) + catch (restore (GHC.prettyPrintGhcErrors dflags m)) $ \e -> restore (h e) ghciTry :: ExceptionMonad m => m a -> m (Either SomeException a) -ghciTry m = fmap Right m `gcatch` \e -> return $ Left e +ghciTry m = fmap Right m `catch` \e -> return $ Left e tryBool :: ExceptionMonad m => m a -> m Bool tryBool m = do ===================================== ghc/GHCi/UI/Info.hs ===================================== @@ -18,6 +18,7 @@ module GHCi.UI.Info import Control.Exception import Control.Monad +import Control.Monad.Catch as MC import Control.Monad.Trans.Class import Control.Monad.Trans.Except import Control.Monad.Trans.Maybe @@ -270,7 +271,7 @@ collectInfo ms loaded = do foldM (go df) ms invalidated where go df m name = do { info <- getModInfo name; return (M.insert name info m) } - `gcatch` + `MC.catch` (\(e :: SomeException) -> do liftIO $ putStrLn $ showSDocForUser df alwaysQualify ===================================== ghc/GHCi/UI/Monad.hs ===================================== @@ -1,4 +1,4 @@ -{-# LANGUAGE CPP, FlexibleInstances, DeriveFunctor #-} +{-# LANGUAGE CPP, FlexibleInstances, DeriveFunctor, DerivingVia #-} {-# OPTIONS_GHC -fno-warn-orphans #-} ----------------------------------------------------------------------------- @@ -65,8 +65,9 @@ import Control.Monad import Prelude hiding ((<>)) import System.Console.Haskeline (CompletionFunc, InputT) -import Control.Monad.Catch +import Control.Monad.Catch as MC import Control.Monad.Trans.Class +import Control.Monad.Trans.Reader import Control.Monad.IO.Class import Data.Map.Strict (Map) import qualified Data.IntMap.Strict as IntMap @@ -259,6 +260,7 @@ recordBreak brkLoc = do newtype GHCi a = GHCi { unGHCi :: IORef GHCiState -> Ghc a } deriving (Functor) + deriving (MonadThrow, MonadCatch, MonadMask) via (ReaderT (IORef GHCiState) Ghc) reflectGHCi :: (Session, IORef GHCiState) -> GHCi a -> IO a reflectGHCi (s, gs) m = unGhc (unGHCi m gs) s @@ -311,61 +313,6 @@ instance GhcMonad (InputT GHCi) where setSession = lift . setSession getSession = lift getSession -instance ExceptionMonad GHCi where - gcatch m h = GHCi $ \r -> unGHCi m r `gcatch` (\e -> unGHCi (h e) r) - gmask f = - GHCi $ \s -> gmask $ \io_restore -> - let - g_restore (GHCi m) = GHCi $ \s' -> io_restore (m s') - in - unGHCi (f g_restore) s - -instance MonadThrow Ghc where - throwM = liftIO . throwM - -instance MonadCatch Ghc where - catch = gcatch - -instance MonadMask Ghc where - mask f = Ghc $ \s -> - mask $ \io_restore -> - let g_restore (Ghc m) = Ghc $ \s -> io_restore (m s) - in unGhc (f g_restore) s - uninterruptibleMask f = Ghc $ \s -> - uninterruptibleMask $ \io_restore -> - let g_restore (Ghc m) = Ghc $ \s -> io_restore (m s) - in unGhc (f g_restore) s - generalBracket acquire release use = Ghc $ \s -> - generalBracket - (unGhc acquire s) - (\resource exitCase -> unGhc (release resource exitCase) s) - (\resource -> unGhc (use resource) s) - -instance MonadThrow GHCi where - throwM = liftIO . throwM - -instance MonadCatch GHCi where - catch = gcatch - -instance MonadMask GHCi where - mask f = GHCi $ \s -> - mask $ \io_restore -> - let g_restore (GHCi m) = GHCi $ \s -> io_restore (m s) - in unGHCi (f g_restore) s - uninterruptibleMask f = GHCi $ \s -> - uninterruptibleMask $ \io_restore -> - let g_restore (GHCi m) = GHCi $ \s -> io_restore (m s) - in unGHCi (f g_restore) s - generalBracket acquire release use = GHCi $ \s -> - generalBracket - (unGHCi acquire s) - (\resource exitCase -> unGHCi (release resource exitCase) s) - (\resource -> unGHCi (use resource) s) - -instance ExceptionMonad (InputT GHCi) where - gcatch = catch - gmask = mask - isOptionSet :: GhciMonad m => GHCiOption -> m Bool isOptionSet opt = do st <- getGHCiState @@ -482,7 +429,7 @@ runWithStats => (a -> Maybe Integer) -> m a -> m (ActionStats, Either SomeException a) runWithStats getAllocs action = do t0 <- liftIO getCurrentTime - result <- gtry action + result <- MC.try action let allocs = either (const Nothing) getAllocs result t1 <- liftIO getCurrentTime let elapsedTime = realToFrac $ t1 `diffUTCTime` t0 ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -59,6 +59,7 @@ stage0Packages = do , compareSizes , compiler , deriveConstants + , exceptions , genapply , genprimopcode , ghc ===================================== testsuite/tests/ghc-api/Makefile ===================================== @@ -17,7 +17,7 @@ T8639_api: T8628: rm -f T8628.o T8628.hi - '$(TEST_HC)' $(TEST_HC_OPTS) --make -v0 -package ghc T8628 + '$(TEST_HC)' $(TEST_HC_OPTS) --make -v0 -package ghc -package exceptions T8628 ./T8628 "`'$(TEST_HC)' $(TEST_HC_OPTS) --print-libdir | tr -d '\r'`" T9015: ===================================== testsuite/tests/ghc-api/T8628.hs ===================================== @@ -12,6 +12,7 @@ import GHC.Data.Bag (filterBag,isEmptyBag) import System.Directory (removeFile) import System.Environment( getArgs ) import GHC.Builtin.Names +import Control.Monad.Catch as MC main :: IO() main @@ -25,7 +26,7 @@ main , IIDecl (simpleImportDecl (mkModuleNameFS (fsLit "System.IO")))] runDecls "data X = Y ()" execStmt "print True" execOptions - gtry $ execStmt "print (Y ())" execOptions :: GhcMonad m => m (Either SomeException ExecResult) + MC.try $ execStmt "print (Y ())" execOptions :: GhcMonad m => m (Either SomeException ExecResult) runDecls "data X = Y () deriving Show" _ <- dynCompileExpr "'x'" execStmt "print (Y ())" execOptions ===================================== testsuite/tests/ghc-api/downsweep/PartialDownsweep.hs ===================================== @@ -7,10 +7,11 @@ import GHC import GHC.Driver.Make import GHC.Driver.Session import GHC.Utils.Outputable -import GHC.Utils.Exception (ExceptionMonad, ghandle) +import GHC.Utils.Exception (ExceptionMonad) import GHC.Data.Bag import Control.Monad +import Control.Monad.Catch as MC (handle) import Control.Monad.IO.Class (liftIO) import Control.Exception import Data.IORef @@ -28,8 +29,8 @@ any_failed = unsafePerformIO $ newIORef False it :: ExceptionMonad m => [Char] -> m Bool -> m () it msg act = - ghandle (\(_ex :: AssertionFailed) -> dofail) $ - ghandle (\(_ex :: ExitCode) -> dofail) $ do + MC.handle (\(_ex :: AssertionFailed) -> dofail) $ + MC.handle (\(_ex :: ExitCode) -> dofail) $ do res <- act case res of False -> dofail ===================================== testsuite/tests/ghc-api/downsweep/all.T ===================================== @@ -3,7 +3,7 @@ test('PartialDownsweep', , ignore_stderr ], compile_and_run, - ['-package ghc']) + ['-package ghc -package exceptions']) test('OldModLocation', [ extra_run_opts('"' + config.libdir + '"') ===================================== testsuite/tests/ghc-api/target-contents/TargetContents.hs ===================================== @@ -6,6 +6,7 @@ import GHC.Driver.Session import GHC import Control.Monad +import Control.Monad.Catch as MC (try) import Control.Monad.IO.Class (liftIO) import Data.List (intercalate) import Data.Maybe @@ -105,7 +106,7 @@ go label targets mods = do liftIO $ hPutStrLn stderr $ "== " ++ label t <- liftIO getCurrentTime setTargets =<< catMaybes <$> mapM (mkTarget t) mods - ex <- gtry $ load LoadAllTargets + ex <- MC.try $ load LoadAllTargets case ex of Left ex -> liftIO $ hPutStrLn stderr $ show (ex :: SourceError) Right _ -> return () ===================================== testsuite/tests/ghc-api/target-contents/all.T ===================================== @@ -1,4 +1,4 @@ test('TargetContents', [extra_run_opts('"' + config.libdir + '"')] , compile_and_run, - ['-package ghc']) + ['-package ghc -package exceptions']) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit a61dbdb0a7420e15e978bce6c09de1ce99290f44 +Subproject commit c60995fe05d9cc267e892448604b8b96a705ccc7 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/30272412fa437ab8e7a8035db94a278e10513413 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/30272412fa437ab8e7a8035db94a278e10513413 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 4 17:20:50 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Mon, 04 May 2020 13:20:50 -0400 Subject: [Git][ghc/ghc][master] Remove unused hs-boot file Message-ID: <5eb04ef2be480_61673f81cd4c695c874251e@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: b9f7c08f by jneira at 2020-05-04T13:20:37-04:00 Remove unused hs-boot file - - - - - 1 changed file: - − compiler/GHC/Unit/Module/Env.hs-boot Changes: ===================================== compiler/GHC/Unit/Module/Env.hs-boot deleted ===================================== @@ -1,6 +0,0 @@ -module GHC.Unit.Module.Env where - -import GhcPrelude () -import GHC.Types.Unique.FM - -type ModuleNameEnv elt = UniqFM elt View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b9f7c08ff5aa71b7673c8136b897e6f29de01330 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b9f7c08ff5aa71b7673c8136b897e6f29de01330 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 4 17:28:45 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Mon, 04 May 2020 13:28:45 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/refactor-rnMethodBinds Message-ID: <5eb050cdbb2d5_61673f81cd4c695c87438f0@gitlab.haskell.org.mail> Ryan Scott pushed new branch wip/refactor-rnMethodBinds at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/refactor-rnMethodBinds You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 4 17:52:19 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Mon, 04 May 2020 13:52:19 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 7 commits: Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) Message-ID: <5eb05653b72b7_61673f819b417d1c874713a@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 30272412 by Artem Pelenitsyn at 2020-05-04T13:19:59-04:00 Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) - - - - - b9f7c08f by jneira at 2020-05-04T13:20:37-04:00 Remove unused hs-boot file - - - - - 340a40a8 by Sylvain Henry at 2020-05-04T13:52:07-04:00 Remove references to -package-key * remove references to `-package-key` which has been removed in 2016 (240ddd7c39536776e955e881d709bbb039b48513) * remove support for `-this-package-key` which has been deprecated at the same time - - - - - aa53c71e by Sylvain Henry at 2020-05-04T13:52:10-04:00 Remove SpecConstrAnnotation (#13681) This has been deprecated since 2013. Use GHC.Types.SPEC instead. Make GHC.Exts "not-home" for haddock Metric Decrease: haddock.base - - - - - 72fbab81 by DenisFrezzato at 2020-05-04T13:52:11-04:00 Fix Haskell98 short description in documentation - - - - - df995a3d by Ryan Scott at 2020-05-04T13:52:12-04:00 Add regression tests for #16244, #16245, #16758 Commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70 ended up fixing quite a few bugs: * This commit fixes #16244 completely. A regression test has been added. * This commit fixes one program from #16245. (The program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211369 still panics, and the program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211400 still loops infinitely.) A regression test has been added for this program. * This commit fixes #16758. Accordingly, this patch removes the `expect_broken` label from the `T16758` test case, moves it from `should_compile` to `should_fail` (as it should produce an error message), and checks in the expected stderr. - - - - - 5072198b by Sylvain Henry at 2020-05-04T13:52:14-04:00 Fix colorized error messages (#18128) In b3df9e780fb2f5658412c644849cd0f1e6f50331 I broke colorized messages by using "dump" style instead of "user" style. This commits fixes it. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Data/IOEnv.hs - compiler/GHC/Driver/Finder.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Monad.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Driver/Types.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Runtime/Debugger.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Linker.hs - compiler/GHC/SysTools/FileCleanup.hs - compiler/GHC/SysTools/Tasks.hs - − compiler/GHC/Unit/Module/Env.hs-boot - compiler/GHC/Utils/Error.hs - compiler/GHC/Utils/Exception.hs - compiler/GHC/Utils/Panic.hs - compiler/ghc.cabal.in - docs/users_guide/8.12.1-notes.rst - docs/users_guide/expected-undocumented-flags.txt - docs/users_guide/exts/control.rst - docs/users_guide/packages.rst - ghc.mk - ghc/GHCi/UI.hs - ghc/GHCi/UI/Info.hs - ghc/GHCi/UI/Monad.hs - hadrian/src/Settings/Default.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8f0e7941771a1ea19f41372a47116fe9a57958cb...5072198b0ee7606ab8a5b7e6d9f64926ae6fdb7d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8f0e7941771a1ea19f41372a47116fe9a57958cb...5072198b0ee7606ab8a5b7e6d9f64926ae6fdb7d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 4 20:24:59 2020 From: gitlab at gitlab.haskell.org (John Ericson) Date: Mon, 04 May 2020 16:24:59 -0400 Subject: [Git][ghc/ghc] Deleted branch wip/no-ghci-next-to-code-prep Message-ID: <5eb07a1b2780d_61673f81cd4c695c87761fc@gitlab.haskell.org.mail> John Ericson deleted branch wip/no-ghci-next-to-code-prep at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 5 07:22:59 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 05 May 2020 03:22:59 -0400 Subject: [Git][ghc/ghc][master] Remove references to -package-key Message-ID: <5eb114533aa15_61673f81a47933c08811362@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 1d8f80cd by Sylvain Henry at 2020-05-05T03:22:46-04:00 Remove references to -package-key * remove references to `-package-key` which has been removed in 2016 (240ddd7c39536776e955e881d709bbb039b48513) * remove support for `-this-package-key` which has been deprecated at the same time - - - - - 6 changed files: - compiler/GHC/Driver/Finder.hs - compiler/GHC/Driver/Session.hs - docs/users_guide/expected-undocumented-flags.txt - docs/users_guide/packages.rst - testsuite/tests/package/package07e.stderr - testsuite/tests/package/package08e.stderr Changes: ===================================== compiler/GHC/Driver/Finder.hs ===================================== @@ -774,7 +774,7 @@ cantFindErr cannot_find _ dflags mod_name find_result provenance (ModOrigin{ fromOrigPackage = e, fromHiddenReexport = rhs }) | Just False <- e - = parens (text "needs flag -package-key" + = parens (text "needs flag -package-id" <+> ppr (moduleUnit mod)) | (pkg:_) <- rhs = parens (text "needs flag -package-id" ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -3191,13 +3191,6 @@ package_flags_deps = [ (NoArg removeUserPkgDb) "Use -no-user-package-db instead" , make_ord_flag defGhcFlag "package-name" (HasArg $ \name -> do upd (setUnitId name)) - -- TODO: Since we JUST deprecated - -- -this-package-key, let's keep this - -- undeprecated for another cycle. - -- Deprecate this eventually. - -- deprecate "Use -this-unit-id instead") - , make_dep_flag defGhcFlag "this-package-key" (HasArg $ upd . setUnitId) - "Use -this-unit-id instead" , make_ord_flag defGhcFlag "this-unit-id" (hasArg setUnitId) , make_ord_flag defFlag "package" (HasArg exposePackage) , make_ord_flag defFlag "plugin-package-id" (HasArg exposePluginPackageId) @@ -4887,7 +4880,8 @@ compilerInfo dflags -- built in it ("Requires unified installed package IDs", "YES"), -- Whether or not we support the @-this-package-key@ flag. Prefer - -- "Uses unit IDs" over it. + -- "Uses unit IDs" over it. We still say yes even if @-this-package-key@ + -- flag has been removed, otherwise it breaks Cabal... ("Uses package keys", "YES"), -- Whether or not we support the @-this-unit-id@ flag ("Uses unit IDs", "YES"), ===================================== docs/users_guide/expected-undocumented-flags.txt ===================================== @@ -167,7 +167,6 @@ -split-objs -syslib -this-component-id --this-package-key -ticky-LNE -ticky-allocd -ticky-dyn-thunk ===================================== docs/users_guide/packages.rst ===================================== @@ -965,28 +965,18 @@ Additionally, the following flags are accepted by ``ghc-pkg``: Output the ``ghc-pkg`` version number. -``--ipid`` +``--ipid``, ``--unit-id`` .. index:: single: --ipid; ghc-pkg option + single: --unit-id; ghc-pkg option - Causes ``ghc-pkg`` to interpret arguments as installed package IDs + Causes ``ghc-pkg`` to interpret arguments as installed unit IDs (e.g., an identifier like ``unix-2.3.1.0-de7803f1a8cd88d2161b29b083c94240``). This is useful if providing just the package name and version are ambiguous (in old versions of GHC, this was guaranteed to be unique, but this invariant no longer necessarily holds). -``--package-key`` - .. index:: - single: --package-key; ghc-pkg option - - Causes ``ghc-pkg`` to interpret arguments as unit IDs (e.g., an - identifier like ``I5BErHzyOm07EBNpKBEeUv``). Package keys are used - to prefix symbol names GHC produces (e.g., - ``6VWy06pWzzJq9evDvK2d4w6_DataziByteStringziInternal_unsafePackLenChars_info``), - so if you need to figure out what package a symbol belongs to, use - ``ghc-pkg`` with this flag. - .. _building-packages: Building a package from Haskell source ===================================== testsuite/tests/package/package07e.stderr ===================================== @@ -2,8 +2,8 @@ package07e.hs:2:1: error: Could not find module ‘GHC.Hs.MyTypes’ Perhaps you meant - GHC.Hs.Types (needs flag -package-key ghc-8.11.0.20200401) - GHC.Tc.Types (needs flag -package-key ghc-8.11.0.20200401) + GHC.Hs.Types (needs flag -package-id ghc-8.11.0.20200401) + GHC.Tc.Types (needs flag -package-id ghc-8.11.0.20200401) Use -v (or `:set -v` in ghci) to see a list of the files searched for. package07e.hs:3:1: error: ===================================== testsuite/tests/package/package08e.stderr ===================================== @@ -2,8 +2,8 @@ package08e.hs:2:1: error: Could not find module ‘GHC.Hs.MyTypes’ Perhaps you meant - GHC.Hs.Types (needs flag -package-key ghc-8.11.0.20200401) - GHC.Tc.Types (needs flag -package-key ghc-8.11.0.20200401) + GHC.Hs.Types (needs flag -package-id ghc-8.11.0.20200401) + GHC.Tc.Types (needs flag -package-id ghc-8.11.0.20200401) Use -v (or `:set -v` in ghci) to see a list of the files searched for. package08e.hs:3:1: error: View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1d8f80cd64edd1ea6a5d4c4aa2e09ad0d077ae1b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1d8f80cd64edd1ea6a5d4c4aa2e09ad0d077ae1b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 5 07:23:42 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 05 May 2020 03:23:42 -0400 Subject: [Git][ghc/ghc][master] Remove SpecConstrAnnotation (#13681) Message-ID: <5eb1147e4770d_6167c5ce1b08813828@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 7bc3a65b by Sylvain Henry at 2020-05-05T03:23:31-04:00 Remove SpecConstrAnnotation (#13681) This has been deprecated since 2013. Use GHC.Types.SPEC instead. Make GHC.Exts "not-home" for haddock Metric Decrease: haddock.base - - - - - 5 changed files: - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Driver/Session.hs - libraries/base/GHC/Exts.hs - testsuite/tests/simplCore/should_compile/T5550.hs - testsuite/tests/simplCore/should_compile/T7944.hs Changes: ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -1,23 +1,18 @@ {- -ToDo [Oct 2013] -~~~~~~~~~~~~~~~ -1. Nuke ForceSpecConstr for good (it is subsumed by GHC.Types.SPEC in ghc-prim) -2. Nuke NoSpecConstr - (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 -\section[SpecConstr]{Specialise over constructors} -} {-# LANGUAGE CPP #-} {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} -module GHC.Core.Opt.SpecConstr( - specConstrProgram, - SpecConstrAnnotation(..) - ) where +-- | Specialise over constructors +module GHC.Core.Opt.SpecConstr + ( specConstrProgram + ) +where #include "HsVersions.h" @@ -49,7 +44,6 @@ import GHC.Driver.Session ( DynFlags(..), GeneralFlag( Opt_SpecConstrKeen ) import GHC.Data.Maybe ( orElse, catMaybes, isJust, isNothing ) import GHC.Types.Demand import GHC.Types.Cpr -import GHC.Serialized ( deserializeWithData ) import GHC.Utils.Misc import GHC.Data.Pair import GHC.Types.Unique.Supply @@ -61,8 +55,6 @@ import Control.Monad ( zipWithM ) import Data.List import GHC.Builtin.Names ( specTyConName ) import GHC.Unit.Module -import GHC.Core.TyCon ( TyCon ) -import GHC.Exts( SpecConstrAnnotation(..) ) import Data.Ord( comparing ) {- @@ -454,32 +446,19 @@ With stream fusion and in other similar cases, we want to fully specialise some (but not necessarily all!) loops regardless of their size and the number of specialisations. -We allow a library to do this, in one of two ways (one which is -deprecated): - - 1) Add a parameter of type GHC.Types.SPEC (from ghc-prim) to the loop body. - - 2) (Deprecated) Annotate a type with ForceSpecConstr from GHC.Exts, - and then add *that* type as a parameter to the loop body +We allow a library to force the specialisation by adding a parameter of type +GHC.Types.SPEC (from ghc-prim) to the loop body. -The reason #2 is deprecated is because it requires GHCi, which isn't -available for things like a cross compiler using stage1. + Historical note: in the past any datatype could be used in place of + GHC.Types.SPEC as long as it was annotated with GHC.Exts.ForceSpecConstr. It + has been deprecated because it required GHCi, which isn't available for + things like a cross compiler using stage1. Here's a (simplified) example from the `vector` package. You may bring the special 'force specialization' type into scope by saying: import GHC.Types (SPEC(..)) -or by defining your own type (again, deprecated): - - data SPEC = SPEC | SPEC2 - {-# ANN type SPEC ForceSpecConstr #-} - -(Note this is the exact same definition of GHC.Types.SPEC, just -without the annotation.) - -After that, you say: - foldl :: (a -> b -> a) -> a -> Stream b -> a {-# INLINE foldl #-} foldl f z (Stream step s _) = foldl_loop SPEC z s @@ -501,7 +480,7 @@ foldl_loop. Note that This is all quite ugly; we ought to come up with a better design. -ForceSpecConstr arguments are spotted in scExpr' and scTopBinds which then set +SPEC arguments are spotted in scExpr' and scTopBinds which then set sc_force to True when calling specLoop. This flag does four things: * Ignore specConstrThreshold, to specialise functions of arbitrary size @@ -544,8 +523,8 @@ What alternatives did I consider? user (e.g., the accumulator here) but we still want to specialise as much as possible. -Alternatives to ForceSpecConstr -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Alternatives to SPEC +~~~~~~~~~~~~~~~~~~~~ Instead of giving the loop an extra argument of type SPEC, we also considered *wrapping* arguments in SPEC, thus data SPEC a = SPEC a | SPEC2 @@ -569,13 +548,13 @@ this doesn't look like a specialisable call. Note [Limit recursive specialisation] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -It is possible for ForceSpecConstr to cause an infinite loop of specialisation. +It is possible for SPEC to cause an infinite loop of specialisation. Because there is no limit on the number of specialisations, a recursive call with a recursive constructor as an argument (for example, list cons) will generate a specialisation for that constructor. If the resulting specialisation also contains a recursive call with the constructor, this could proceed indefinitely. -For example, if ForceSpecConstr is on: +For example, if SPEC is on: loop :: [Int] -> [Int] -> [Int] loop z [] = z loop z (x:xs) = loop (x:z) xs @@ -605,16 +584,6 @@ more than N times (controlled by -fspec-constr-recursive=N) we check See #5550. Also #13623, where this test had become over-aggressive, and we lost a wonderful specialisation that we really wanted! -Note [NoSpecConstr] -~~~~~~~~~~~~~~~~~~~ -The ignoreDataCon stuff allows you to say - {-# ANN type T NoSpecConstr #-} -to mean "don't specialise on arguments of this type". It was added -before we had ForceSpecConstr. Lacking ForceSpecConstr we specialised -regardless of size; and then we needed a way to turn that *off*. Now -that we have ForceSpecConstr, this NoSpecConstr is probably redundant. -(Used only for PArray, TODO: remove?) - ----------------------------------------------------- Stuff not yet handled ----------------------------------------------------- @@ -702,11 +671,10 @@ specConstrProgram guts = do dflags <- getDynFlags us <- getUniqueSupplyM - (_, annos) <- getFirstAnnotations deserializeWithData guts this_mod <- getModule let binds' = reverse $ fst $ initUs us $ do -- Note [Top-level recursive groups] - (env, binds) <- goEnv (initScEnv dflags this_mod annos) + (env, binds) <- goEnv (initScEnv dflags this_mod) (mg_binds guts) -- binds is identical to (mg_binds guts), except that the -- binders on the LHS have been replaced by extendBndr @@ -821,7 +789,7 @@ data ScEnv = SCE { sc_dflags :: DynFlags, -- See Note [Avoiding exponential blowup] sc_recursive :: Int, -- Max # of specialisations over recursive type. - -- Stops ForceSpecConstr from diverging. + -- Stops SPEC from diverging. sc_keen :: Bool, -- Specialise on arguments that are known -- constructors, even if they are not @@ -838,15 +806,13 @@ data ScEnv = SCE { sc_dflags :: DynFlags, -- Binds interesting non-top-level variables -- Domain is OutVars (*after* applying the substitution) - sc_vals :: ValueEnv, + sc_vals :: ValueEnv -- Domain is OutIds (*after* applying the substitution) -- Used even for top-level bindings (but not imported ones) -- The range of the ValueEnv is *work-free* values -- such as (\x. blah), or (Just v) -- but NOT (Just (expensive v)) -- See Note [Work-free values only in environment] - - sc_annotations :: UniqFM SpecConstrAnnotation } --------------------- @@ -863,8 +829,8 @@ instance Outputable Value where ppr LambdaVal = text "" --------------------- -initScEnv :: DynFlags -> Module -> UniqFM SpecConstrAnnotation -> ScEnv -initScEnv dflags this_mod anns +initScEnv :: DynFlags -> Module -> ScEnv +initScEnv dflags this_mod = SCE { sc_dflags = dflags, sc_module = this_mod, sc_size = specConstrThreshold dflags, @@ -874,8 +840,7 @@ initScEnv dflags this_mod anns sc_force = False, sc_subst = emptySubst, sc_how_bound = emptyVarEnv, - sc_vals = emptyVarEnv, - sc_annotations = anns } + sc_vals = emptyVarEnv } data HowBound = RecFun -- These are the recursive functions for which -- we seek interesting call patterns @@ -1000,21 +965,7 @@ decreaseSpecCount env n_specs --------------------------------------------------- -- See Note [Forcing specialisation] -ignoreType :: ScEnv -> Type -> Bool -ignoreDataCon :: ScEnv -> DataCon -> Bool forceSpecBndr :: ScEnv -> Var -> Bool - -ignoreDataCon env dc = ignoreTyCon env (dataConTyCon dc) - -ignoreType env ty - = case tyConAppTyCon_maybe ty of - Just tycon -> ignoreTyCon env tycon - _ -> False - -ignoreTyCon :: ScEnv -> TyCon -> Bool -ignoreTyCon env tycon - = lookupUFM (sc_annotations env) tycon == Just NoSpecConstr - forceSpecBndr env var = forceSpecFunTy env . snd . splitForAllTys . varType $ var forceSpecFunTy :: ScEnv -> Type -> Bool @@ -1028,7 +979,6 @@ forceSpecArgTy env ty | Just (tycon, tys) <- splitTyConApp_maybe ty , tycon /= funTyCon = tyConName tycon == specTyConName - || lookupUFM (sc_annotations env) tycon == Just ForceSpecConstr || any (forceSpecArgTy env) tys forceSpecArgTy _ _ = False @@ -1898,9 +1848,9 @@ by trim_pats. of specialisations for a given function to N. * -fno-spec-constr-count sets the sc_count field to Nothing, - which switches of the limit. + which switches off the limit. -* The ghastly ForceSpecConstr trick also switches of the limit +* The ghastly SPEC trick also switches off the limit for a particular function * Otherwise we sort the patterns to choose the most general @@ -2173,7 +2123,6 @@ argToPat env in_scope val_env (Case scrut _ _ [(_, _, rhs)]) arg_occ -} argToPat env in_scope val_env (Cast arg co) arg_occ - | not (ignoreType env ty2) = do { (interesting, arg') <- argToPat env in_scope val_env arg arg_occ ; if not interesting then wildCardPat ty2 @@ -2204,7 +2153,6 @@ argToPat in_scope val_env arg arg_occ -- NB: this *precedes* the Var case, so that we catch nullary constrs argToPat env in_scope val_env arg arg_occ | Just (ConVal (DataAlt dc) args) <- isValue val_env arg - , not (ignoreDataCon env dc) -- See Note [NoSpecConstr] , Just arg_occs <- mb_scrut dc = do { let (ty_args, rest_args) = splitAtList (dataConUnivTyVars dc) args ; (_, args') <- argsToPats env in_scope val_env rest_args arg_occs @@ -2225,11 +2173,10 @@ argToPat env in_scope val_env arg arg_occ -- In that case it counts as "interesting" argToPat env in_scope val_env (Var v) arg_occ | sc_force env || case arg_occ of { UnkOcc -> False; _other -> True }, -- (a) - is_value, -- (b) + is_value -- (b) -- Ignoring sc_keen here to avoid gratuitously incurring Note [Reboxing] -- So sc_keen focused just on f (I# x), where we have freshly-allocated -- box that we can eliminate in the caller - not (ignoreType env (varType v)) = return (True, Var v) where is_value ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -496,7 +496,7 @@ data DynFlags = DynFlags { specConstrThreshold :: Maybe Int, -- ^ Threshold for SpecConstr specConstrCount :: Maybe Int, -- ^ Max number of specialisations for any one function specConstrRecursive :: Int, -- ^ Max number of specialisations for recursive types - -- Not optional; otherwise ForceSpecConstr can diverge. + -- Not optional; otherwise SPEC can diverge. binBlobThreshold :: Word, -- ^ Binary literals (e.g. strings) whose size is above -- this threshold will be dumped in a binary file -- by the assembler code generator (0 to disable) ===================================== libraries/base/GHC/Exts.hs ===================================== @@ -2,6 +2,8 @@ {-# LANGUAGE MagicHash, UnboxedTuples, TypeFamilies, DeriveDataTypeable, MultiParamTypeClasses, FlexibleInstances, NoImplicitPrelude #-} +{-# OPTIONS_HADDOCK not-home #-} + ----------------------------------------------------------------------------- -- | -- Module : GHC.Exts @@ -83,9 +85,6 @@ module GHC.Exts -- * Event logging traceEvent, - -- * SpecConstr annotations - SpecConstrAnnotation(..), - -- * The call stack currentCallStack, @@ -111,7 +110,6 @@ import GHC.Stack import qualified Data.Coerce import Data.String import Data.OldList -import Data.Data import Data.Ord import Data.Version ( Version(..), makeVersion ) import qualified Debug.Trace @@ -159,25 +157,6 @@ traceEvent = Debug.Trace.traceEventIO {-# DEPRECATED traceEvent "Use 'Debug.Trace.traceEvent' or 'Debug.Trace.traceEventIO'" #-} -- deprecated in 7.4 -{- ********************************************************************** -* * -* SpecConstr annotation * -* * -********************************************************************** -} - --- Annotating a type with NoSpecConstr will make SpecConstr --- not specialise for arguments of that type. - --- This data type is defined here, rather than in the SpecConstr module --- itself, so that importing it doesn't force stupidly linking the --- entire ghc package at runtime - -data SpecConstrAnnotation = NoSpecConstr | ForceSpecConstr - deriving ( Data -- ^ @since 4.3.0.0 - , Eq -- ^ @since 4.3.0.0 - ) - - {- ********************************************************************** * * * The IsList class * ===================================== testsuite/tests/simplCore/should_compile/T5550.hs ===================================== @@ -1,9 +1,6 @@ module T5550 where -import GHC.Exts ( SpecConstrAnnotation(..) ) - -data SPEC = SPEC | SPEC2 -{-# ANN type SPEC ForceSpecConstr #-} +import GHC.Types loop :: SPEC -> [Int] -> [Int] -> [Int] loop SPEC z [] = z ===================================== testsuite/tests/simplCore/should_compile/T7944.hs ===================================== @@ -1,10 +1,6 @@ module T7944 where -import GHC.Exts - --- Force specialisation of "go" -data SPEC = SPEC | SPEC2 -{-# ANN type SPEC ForceSpecConstr #-} +import GHC.Types -- This is more or less just an ordinary fold go :: SPEC -> [a] -> IntMap a -> IntMap a View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7bc3a65b467c4286377b9bded277d5a2f69160b3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7bc3a65b467c4286377b9bded277d5a2f69160b3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 5 07:24:23 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 05 May 2020 03:24:23 -0400 Subject: [Git][ghc/ghc][master] Fix Haskell98 short description in documentation Message-ID: <5eb114a7dfd40_61673f81a47933c08816565@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 3c862f63 by DenisFrezzato at 2020-05-05T03:24:15-04:00 Fix Haskell98 short description in documentation - - - - - 1 changed file: - docs/users_guide/exts/control.rst Changes: ===================================== docs/users_guide/exts/control.rst ===================================== @@ -39,7 +39,7 @@ Language extensions can be controlled (i.e. allowed or not) in two ways: .. extension:: Haskell98 - :shortdesc: Use the Haskell 2010 language variant. + :shortdesc: Use the Haskell 98 language variant. Compile using Haskell 98 language variant. Enables the following language extensions: View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3c862f635394b02c121f917a4d9ea7802033eebb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3c862f635394b02c121f917a4d9ea7802033eebb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 5 07:25:04 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 05 May 2020 03:25:04 -0400 Subject: [Git][ghc/ghc][master] Add regression tests for #16244, #16245, #16758 Message-ID: <5eb114d01b7bc_61673f81cc913ba08821179@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 2420c555 by Ryan Scott at 2020-05-05T03:24:53-04:00 Add regression tests for #16244, #16245, #16758 Commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70 ended up fixing quite a few bugs: * This commit fixes #16244 completely. A regression test has been added. * This commit fixes one program from #16245. (The program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211369 still panics, and the program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211400 still loops infinitely.) A regression test has been added for this program. * This commit fixes #16758. Accordingly, this patch removes the `expect_broken` label from the `T16758` test case, moves it from `should_compile` to `should_fail` (as it should produce an error message), and checks in the expected stderr. - - - - - 9 changed files: - + testsuite/tests/polykinds/T16244.hs - + testsuite/tests/polykinds/T16244.stderr - + testsuite/tests/polykinds/T16245.hs - + testsuite/tests/polykinds/T16245.stderr - testsuite/tests/polykinds/all.T - testsuite/tests/saks/should_compile/all.T - testsuite/tests/saks/should_compile/T16758.hs → testsuite/tests/saks/should_fail/T16758.hs - + testsuite/tests/saks/should_fail/T16758.stderr - testsuite/tests/saks/should_fail/all.T Changes: ===================================== testsuite/tests/polykinds/T16244.hs ===================================== @@ -0,0 +1,11 @@ +{-# LANGUAGE ConstraintKinds #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE PolyKinds #-} +module T16244 where + +import Data.Kind + +type Const a b = a +type SameKind (a :: k) (b :: k) = (() :: Constraint) +class SameKind a b => C (k :: Const Type a) (b :: k) ===================================== testsuite/tests/polykinds/T16244.stderr ===================================== @@ -0,0 +1,11 @@ + +T16244.hs:11:18: error: + • Couldn't match kind ‘k1’ with ‘k’ + ‘k1’ is a rigid type variable bound by + the class declaration for ‘C’ + at T16244.hs:11:26 + ‘k’ is a rigid type variable bound by + the class declaration for ‘C’ + at T16244.hs:11:1-52 + • In the second argument of ‘SameKind’, namely ‘b’ + In the class declaration for ‘C’ ===================================== testsuite/tests/polykinds/T16245.hs ===================================== @@ -0,0 +1,11 @@ +{-# LANGUAGE ConstraintKinds #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE QuantifiedConstraints #-} +module T16245 where + +import Data.Kind + +type Const a b = a +type SameKind (a :: k) (b :: k) = (() :: Constraint) +class (forall (b :: k). SameKind a b) => C (k :: Const Type a) ===================================== testsuite/tests/polykinds/T16245.stderr ===================================== @@ -0,0 +1,11 @@ + +T16245.hs:11:36: error: + • Couldn't match kind ‘k1’ with ‘k’ + ‘k1’ is a rigid type variable bound by + the class declaration for ‘C’ + at T16245.hs:11:45 + ‘k’ is a rigid type variable bound by + the class declaration for ‘C’ + at T16245.hs:11:1-62 + • In the second argument of ‘SameKind’, namely ‘b’ + In the class declaration for ‘C’ ===================================== testsuite/tests/polykinds/all.T ===================================== @@ -211,6 +211,8 @@ test('T16247a', normal, compile_fail, ['']) test('KindVarOrder', normal, ghci_script, ['KindVarOrder.script']) test('T16221', normal, compile, ['']) test('T16221a', normal, compile_fail, ['']) +test('T16244', normal, compile_fail, ['']) +test('T16245', normal, compile_fail, ['']) test('T16342', normal, compile, ['']) test('T16263', normal, compile_fail, ['']) test('T16902', normal, compile_fail, ['']) ===================================== testsuite/tests/saks/should_compile/all.T ===================================== @@ -34,7 +34,6 @@ test('T16723', normal, compile, ['']) test('T16724', extra_files(['T16724.hs']), ghci_script, ['T16724.script']) test('T16726', normal, compile, ['']) test('T16731', normal, compile, ['']) -test('T16758', expect_broken(16758), compile, ['']) test('T16721', normal, ghci_script, ['T16721.script']) test('T16756a', normal, compile, ['']) ===================================== testsuite/tests/saks/should_compile/T16758.hs → testsuite/tests/saks/should_fail/T16758.hs ===================================== ===================================== testsuite/tests/saks/should_fail/T16758.stderr ===================================== @@ -0,0 +1,8 @@ + +T16758.hs:14:8: error: + • Couldn't match expected kind ‘Int’ with actual kind ‘a’ + ‘a’ is a rigid type variable bound by + the class declaration for ‘C’ + at T16758.hs:12:19 + • In the type signature: f :: C a => a -> Int + In the class declaration for ‘C’ ===================================== testsuite/tests/saks/should_fail/all.T ===================================== @@ -30,3 +30,4 @@ test('T16727b', normal, compile_fail, ['']) test('T16725', normal, compile_fail, ['']) test('T16826', normal, compile_fail, ['']) test('T16756b', normal, compile_fail, ['']) +test('T16758', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2420c555e6cb681f4ef7c4ae3192a850ab431759 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2420c555e6cb681f4ef7c4ae3192a850ab431759 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 5 07:25:42 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 05 May 2020 03:25:42 -0400 Subject: [Git][ghc/ghc][master] Fix colorized error messages (#18128) Message-ID: <5eb114f64469_61673f81cc913ba088243b9@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 40c71c2c by Sylvain Henry at 2020-05-05T03:25:31-04:00 Fix colorized error messages (#18128) In b3df9e780fb2f5658412c644849cd0f1e6f50331 I broke colorized messages by using "dump" style instead of "user" style. This commits fixes it. - - - - - 1 changed file: - compiler/GHC/Driver/Session.hs Changes: ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -1593,7 +1593,7 @@ defaultLogActionHPutStrDoc dflags h d -- Don't add a newline at the end, so that successive -- calls to this log-action can output all on the same line = printSDoc ctx Pretty.PageMode h d - where ctx = initSDocContext dflags defaultDumpStyle + where ctx = initSDocContext dflags defaultUserStyle newtype FlushOut = FlushOut (IO ()) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/40c71c2cf38b4e134d81b7184a4d5e02949ae70c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/40c71c2cf38b4e134d81b7184a4d5e02949ae70c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 5 07:55:44 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Tue, 05 May 2020 03:55:44 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18126 Message-ID: <5eb11c00613e6_61673f81cc913ba0882508f@gitlab.haskell.org.mail> Simon Peyton Jones pushed new branch wip/T18126 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18126 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 5 07:57:49 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 05 May 2020 03:57:49 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 9 commits: Remove references to -package-key Message-ID: <5eb11c7dd4b0a_6167c5ce1b088281d2@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 1d8f80cd by Sylvain Henry at 2020-05-05T03:22:46-04:00 Remove references to -package-key * remove references to `-package-key` which has been removed in 2016 (240ddd7c39536776e955e881d709bbb039b48513) * remove support for `-this-package-key` which has been deprecated at the same time - - - - - 7bc3a65b by Sylvain Henry at 2020-05-05T03:23:31-04:00 Remove SpecConstrAnnotation (#13681) This has been deprecated since 2013. Use GHC.Types.SPEC instead. Make GHC.Exts "not-home" for haddock Metric Decrease: haddock.base - - - - - 3c862f63 by DenisFrezzato at 2020-05-05T03:24:15-04:00 Fix Haskell98 short description in documentation - - - - - 2420c555 by Ryan Scott at 2020-05-05T03:24:53-04:00 Add regression tests for #16244, #16245, #16758 Commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70 ended up fixing quite a few bugs: * This commit fixes #16244 completely. A regression test has been added. * This commit fixes one program from #16245. (The program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211369 still panics, and the program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211400 still loops infinitely.) A regression test has been added for this program. * This commit fixes #16758. Accordingly, this patch removes the `expect_broken` label from the `T16758` test case, moves it from `should_compile` to `should_fail` (as it should produce an error message), and checks in the expected stderr. - - - - - 40c71c2c by Sylvain Henry at 2020-05-05T03:25:31-04:00 Fix colorized error messages (#18128) In b3df9e780fb2f5658412c644849cd0f1e6f50331 I broke colorized messages by using "dump" style instead of "user" style. This commits fixes it. - - - - - e884c7cf by Sebastian Graf at 2020-05-05T03:57:31-04:00 DmdAnal: Improve handling of precise exceptions This patch does two things: Fix possible unsoundness in what was called the "IO hack" and implement part 2.1 of the "fixing precise exceptions" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions, which, in combination with !2956, supersedes !3014 and !2525. **IO hack** The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is called `exprMayThrowPreciseException` now. I came up with two testcases exemplifying possible unsoundness (if twisted enough) in the old approach: - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. - `T13380e`: Demonstrating unsoundness of the "IO hack" when we have Nested CPR. Not currently relevant, as we don't have Nested CPR yet. Basically, the IO hack assumed that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future, see `T13380e`. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380{d,e}` (and will hopefully be robust to Nested CPR). **Precise exceptions** In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that was terribly unprincipled. That unprincipledness resulted in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception (and the existing IO hack doesn't detect that) Fixing both issues in !3014 turned out to be too complicated and had the potential to regress in the future. Hence we decided to only fix `T13380b` and augment the `Divergence` lattice with a new middle-layer element, `ExnOrDiv`, which means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. See the wiki page on Step 2.1 for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#dead-code-elimination-for-raiseio-with-isdeadenddiv-introducing-exnordiv-step-21 - - - - - e353bf7b by Richard Eisenberg at 2020-05-05T03:57:32-04:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG ------------------------- - - - - - 3cb104b1 by Zubin Duggal at 2020-05-05T03:57:38-04:00 Allow atomic update of NameCache in readHieFile The situation arises in ghcide where multiple different threads may need to update the name cache, therefore with the older interface it could happen that you start reading a hie file with name cache A and produce name cache A + B, but another thread in the meantime updated the namecache to A + C. Therefore if you write the new namecache you will lose the A' updates from the second thread. Updates haddock submodule - - - - - 5c55d411 by Ryan Scott at 2020-05-05T03:57:38-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _)`. Fixes #18127. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/LiberateCase.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Driver/Finder.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Plugins.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Errors/Hole.hs-boot - compiler/GHC/Tc/Errors/Hole/FitTypes.hs - compiler/GHC/Tc/Gen/Expr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5072198b0ee7606ab8a5b7e6d9f64926ae6fdb7d...5c55d411037e77a4851f472b58438ac75e8528d3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5072198b0ee7606ab8a5b7e6d9f64926ae6fdb7d...5c55d411037e77a4851f472b58438ac75e8528d3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 5 09:03:55 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Tue, 05 May 2020 05:03:55 -0400 Subject: [Git][ghc/ghc][wip/nested-cpr-2019] Prune CPR sigs to constant depth on all bindings Message-ID: <5eb12bfb7a22c_6167120888bc8844258@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/nested-cpr-2019 at Glasgow Haskell Compiler / GHC Commits: d913847b by Sebastian Graf at 2020-05-05T10:58:47+02:00 Prune CPR sigs to constant depth on all bindings - - - - - 1 changed file: - compiler/GHC/Core/Opt/CprAnal.hs Changes: ===================================== compiler/GHC/Core/Opt/CprAnal.hs ===================================== @@ -311,21 +311,24 @@ cprFix top_lvl env str orig_pairs where (id1, rhs') = cprAnalBind top_lvl env str id rhs -- See Note [Ensuring termination of fixed-point iteration] - id2 = setIdCprInfo id1 (pruneSig mAX_DEPTH (idCprInfo id1)) + id2 = setIdCprInfo id1 $ pruneSig mAX_DEPTH $ markDiverging $ idCprInfo id1 env' = extendAnalEnv env id2 (idCprInfo id2) mAX_DEPTH :: Int mAX_DEPTH = 4 +-- TODO: We need the lubCpr with the initial CPR because +-- of functions like iterate, which we would CPR +-- multiple levels deep, thereby changing termination +-- behavior. +markDiverging :: CprSig -> CprSig +markDiverging (CprSig cpr_ty) = CprSig $ cpr_ty { ct_cpr = ct_cpr cpr_ty `lubCpr` divergeCpr } + -- | A widening operator on 'CprSig' to ensure termination of fixed-point -- iteration. See Note [Ensuring termination of fixed-point iteration] pruneSig :: Int -> CprSig -> CprSig pruneSig d (CprSig cpr_ty) - -- TODO: We need the lubCpr with the initial CPR because - -- of functions like iterate, which we would CPR - -- multiple levels deep, thereby changing termination - -- behavior. - = CprSig $ cpr_ty { ct_cpr = pruneDeepCpr d (ct_cpr cpr_ty `lubCpr` divergeCpr) } + = CprSig $ cpr_ty { ct_cpr = pruneDeepCpr d (ct_cpr cpr_ty) } unboxingStrategy :: AnalEnv -> UnboxingStrategy unboxingStrategy env ty dmd @@ -378,7 +381,8 @@ cprAnalBind top_lvl env args id rhs | otherwise = rhs_ty -- See Note [Arity trimming for CPR signatures] - sig = mkCprSigForArity (idArity id) rhs_ty' + -- We prune so that we discard too deep info on e.g. TyCon bindings + sig = pruneSig mAX_DEPTH $ mkCprSigForArity (idArity id) rhs_ty' id' = -- pprTrace "cprAnalBind" (ppr id $$ ppr sig) $ setIdCprInfo id sig View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d913847bfdc5531f55cf7817f48b1d01d8ef905c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d913847bfdc5531f55cf7817f48b1d01d8ef905c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 5 09:39:11 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Tue, 05 May 2020 05:39:11 -0400 Subject: [Git][ghc/ghc][wip/nested-cpr-2019] Use variable length coding for ConTags Message-ID: <5eb1343f6e62e_6167120888bc88504c@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/nested-cpr-2019 at Glasgow Haskell Compiler / GHC Commits: 75867eac by Sebastian Graf at 2020-05-05T11:39:01+02:00 Use variable length coding for ConTags - - - - - 1 changed file: - compiler/GHC/Types/Cpr.hs Changes: ===================================== compiler/GHC/Types/Cpr.hs ===================================== @@ -592,9 +592,8 @@ instance Binary a => Binary (Levitated a) where _ -> pprPanic "Binary Levitated: Invalid tag" (int (fromIntegral h)) instance Binary r => Binary (KnownShape r) where - -- Note that the ConTag is 1-indexed - put_ bh (Con t fs) = do { put_ bh t; put_ bh fs} - get bh = Con <$> get bh <*> get bh + put_ bh (Con t fs) = do { putULEB128 bh t; put_ bh fs } + get bh = Con <$> getULEB128 bh <*> get bh instance Binary TerminationFlag where put_ bh Terminates = put_ bh True View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/75867eac718bdc371d286c92c3a66797e0eef505 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/75867eac718bdc371d286c92c3a66797e0eef505 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 5 10:05:36 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Tue, 05 May 2020 06:05:36 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/bump-exceptions-submod Message-ID: <5eb13a70a9be0_616711ab08a4886374@gitlab.haskell.org.mail> Ryan Scott pushed new branch wip/bump-exceptions-submod at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/bump-exceptions-submod You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 5 16:10:17 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Tue, 05 May 2020 12:10:17 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18141 Message-ID: <5eb18fe963ae7_6167136cfbac891338f@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/T18141 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18141 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 5 16:23:17 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Tue, 05 May 2020 12:23:17 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn-simpl] 40 commits: Define a Quote IO instance Message-ID: <5eb192f5805e2_6167136cfbac8917966@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn-simpl at Glasgow Haskell Compiler / GHC Commits: 4b9764db by Ryan Scott at 2020-04-28T15:40:04-04:00 Define a Quote IO instance Fixes #18103. - - - - - 518a63d4 by Ryan Scott at 2020-04-28T15:40:42-04:00 Make boxed 1-tuples have known keys Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. - - - - - 2cfc4ab9 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Document backpack fields in DynFlags - - - - - 10a2ba90 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 69562e34 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 9e2c8e0e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - ea717aa4 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 10d15f1e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 8bfb0219 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - 71484b09 by Alexis King at 2020-04-30T01:57:35-04:00 Allow block arguments in arrow control operators Arrow control operators have their own entries in the grammar, so they did not cooperate with BlockArguments. This was just a minor oversight, so this patch adjusts the grammar to add the desired behavior. fixes #18050 - - - - - a48cd2a0 by Alexis King at 2020-04-30T01:57:35-04:00 Allow LambdaCase to be used as a command in proc notation - - - - - f4d3773c by Alexis King at 2020-04-30T01:57:35-04:00 Document BlockArguments/LambdaCase support in arrow notation - - - - - 5bdfdd13 by Simon Peyton Jones at 2020-04-30T01:58:15-04:00 Add tests for #17873 - - - - - 19b701c2 by Simon Peyton Jones at 2020-04-30T07:30:13-04:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - 014ef4a3 by Matthew Pickering at 2020-04-30T07:30:50-04:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 2aa67611 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - 54dad3cf by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - 99ff8145 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 05b0a9fd by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 Remove OneShotInfo field of LFReEntrant, document OneShotInfo The field is only used in withNewTickyCounterFun and it's easier to directly pass a parameter for one-shot info to withNewTickyCounterFun instead of passing it via LFReEntrant. This also makes !2842 simpler. Other changes: - New Note (by SPJ) [OneShotInfo overview] added. - Arity argument of thunkCode removed as it's always 0. - - - - - a43620c6 by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 GHC.StgToCmm.Ticky: remove a few unused stuff - - - - - 780de9e1 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Use platform in Iface Binary - - - - - f8386c7b by Sylvain Henry at 2020-05-01T10:37:39-04:00 Refactor PprDebug handling If `-dppr-debug` is set, then PprUser and PprDump styles are silently replaced with PprDebug style. This was done in `mkUserStyle` and `mkDumpStyle` smart constructors. As a consequence they needed a DynFlags parameter. Now we keep the original PprUser and PprDump styles until they are used to create an `SDocContext`. I.e. the substitution is only performed in `initSDocContext`. - - - - - b3df9e78 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Remove PprStyle param of logging actions Use `withPprStyle` instead to apply a specific style to a SDoc. - - - - - de9fc995 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Fully remove PprDebug PprDebug was a pain to deal with consistently as it is implied by `-dppr-debug` but it isn't really a PprStyle. We remove it completely and query the appropriate SDoc flag instead (`sdocPprDebug`) via helpers (`getPprDebug` and its friends). - - - - - 8b51fcbd by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Only call checkSingle if we would report warnings - - - - - fd7ea0fe by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 7bfe9ac5 by Ben Gamari at 2020-05-03T04:41:33-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. - - - - - c560dd07 by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Move eventlog documentation users guide - - - - - 02543d5e by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Add documentation for non-moving GC events - - - - - b465dd45 by Alexis King at 2020-05-03T04:42:12-04:00 Flatten nested casts in the simple optimizer Normally, we aren’t supposed to generated any nested casts, since mkCast takes care to flatten them, but the simple optimizer didn’t use mkCast, so they could show up after inlining. This isn’t really a problem, since the simplifier will clean them up immediately anyway, but it can clutter the -ddump-ds output, and it’s an extremely easy fix. closes #18112 - - - - - 8bdc03d6 by Simon Peyton Jones at 2020-05-04T01:56:59-04:00 Don't return a panic in tcNestedSplice In GHC.Tc.Gen.Splice.tcNestedSplice we were returning a typechecked expression of "panic". That is usually OK, because the result is discarded. But it happens that tcApp now looks at the typechecked expression, trivially, to ask if it is tagToEnum. So being bottom is bad. Moreover a debug-trace might print it out. So better to return a civilised expression, even though it is usually discarded. - - - - - 0bf640b1 by Baldur Blöndal at 2020-05-04T01:57:36-04:00 Don't require parentheses around via type (`-XDerivingVia'). Fixes #18130". - - - - - 30272412 by Artem Pelenitsyn at 2020-05-04T13:19:59-04:00 Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) - - - - - b9f7c08f by jneira at 2020-05-04T13:20:37-04:00 Remove unused hs-boot file - - - - - 1d8f80cd by Sylvain Henry at 2020-05-05T03:22:46-04:00 Remove references to -package-key * remove references to `-package-key` which has been removed in 2016 (240ddd7c39536776e955e881d709bbb039b48513) * remove support for `-this-package-key` which has been deprecated at the same time - - - - - 7bc3a65b by Sylvain Henry at 2020-05-05T03:23:31-04:00 Remove SpecConstrAnnotation (#13681) This has been deprecated since 2013. Use GHC.Types.SPEC instead. Make GHC.Exts "not-home" for haddock Metric Decrease: haddock.base - - - - - 3c862f63 by DenisFrezzato at 2020-05-05T03:24:15-04:00 Fix Haskell98 short description in documentation - - - - - 2420c555 by Ryan Scott at 2020-05-05T03:24:53-04:00 Add regression tests for #16244, #16245, #16758 Commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70 ended up fixing quite a few bugs: * This commit fixes #16244 completely. A regression test has been added. * This commit fixes one program from #16245. (The program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211369 still panics, and the program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211400 still loops infinitely.) A regression test has been added for this program. * This commit fixes #16758. Accordingly, this patch removes the `expect_broken` label from the `T16758` test case, moves it from `should_compile` to `should_fail` (as it should produce an error message), and checks in the expected stderr. - - - - - 40c71c2c by Sylvain Henry at 2020-05-05T03:25:31-04:00 Fix colorized error messages (#18128) In b3df9e780fb2f5658412c644849cd0f1e6f50331 I broke colorized messages by using "dump" style instead of "user" style. This commits fixes it. - - - - - b9af7241 by Sebastian Graf at 2020-05-05T12:23:13-04:00 DmdAnal: Improve handling of precise exceptions This patch does two things: Fix possible unsoundness in what was called the "IO hack" and implement part 2.1 of the "fixing precise exceptions" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions, which, in combination with !2956, supersedes !3014 and !2525. **IO hack** The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is called `exprMayThrowPreciseException` now. I came up with two testcases exemplifying possible unsoundness (if twisted enough) in the old approach: - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. - `T13380e`: Demonstrating unsoundness of the "IO hack" when we have Nested CPR. Not currently relevant, as we don't have Nested CPR yet. Basically, the IO hack assumed that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future, see `T13380e`. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380{d,e}` (and will hopefully be robust to Nested CPR). **Precise exceptions** In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that was terribly unprincipled. That unprincipledness resulted in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception (and the existing IO hack doesn't detect that) Fixing both issues in !3014 turned out to be too complicated and had the potential to regress in the future. Hence we decided to only fix `T13380b` and augment the `Divergence` lattice with a new middle-layer element, `ExnOrDiv`, which means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. See the wiki page on Step 2.1 for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#dead-code-elimination-for-raiseio-with-isdeadenddiv-introducing-exnordiv-step-21 - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Utils.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Config.hs - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Driver.hs - compiler/GHC/Core/Opt/FloatIn.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e17007d1ee27bca845330c3e0b24d58ab7f150c9...b9af724122375477d4c6c3ee1001d135d0616dd2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e17007d1ee27bca845330c3e0b24d58ab7f150c9...b9af724122375477d4c6c3ee1001d135d0616dd2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 5 16:40:09 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Tue, 05 May 2020 12:40:09 -0400 Subject: [Git][ghc/ghc][wip/T18126] 13 commits: rts: Enable tracing of nonmoving heap census with -ln Message-ID: <5eb196e9d1d76_61673f81cd4c695c89184a5@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T18126 at Glasgow Haskell Compiler / GHC Commits: 7bfe9ac5 by Ben Gamari at 2020-05-03T04:41:33-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. - - - - - c560dd07 by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Move eventlog documentation users guide - - - - - 02543d5e by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Add documentation for non-moving GC events - - - - - b465dd45 by Alexis King at 2020-05-03T04:42:12-04:00 Flatten nested casts in the simple optimizer Normally, we aren’t supposed to generated any nested casts, since mkCast takes care to flatten them, but the simple optimizer didn’t use mkCast, so they could show up after inlining. This isn’t really a problem, since the simplifier will clean them up immediately anyway, but it can clutter the -ddump-ds output, and it’s an extremely easy fix. closes #18112 - - - - - 8bdc03d6 by Simon Peyton Jones at 2020-05-04T01:56:59-04:00 Don't return a panic in tcNestedSplice In GHC.Tc.Gen.Splice.tcNestedSplice we were returning a typechecked expression of "panic". That is usually OK, because the result is discarded. But it happens that tcApp now looks at the typechecked expression, trivially, to ask if it is tagToEnum. So being bottom is bad. Moreover a debug-trace might print it out. So better to return a civilised expression, even though it is usually discarded. - - - - - 0bf640b1 by Baldur Blöndal at 2020-05-04T01:57:36-04:00 Don't require parentheses around via type (`-XDerivingVia'). Fixes #18130". - - - - - 26aedf3d by Simon Peyton Jones at 2020-05-04T11:18:15+01:00 Simple subsumption This patch simplifies GHC to use simple subsumption. Ticket #17775 Implements GHC proposal #287 https://github.com/ghc-proposals/ghc-proposals/blob/master/ proposals/0287-simplify-subsumption.rst All the motivation is described there; I will not repeat it here. The implementation payload: * tcSubType and friends become noticably simpler, because it no longer uses eta-expansion when checking subsumption. * No deeplyInstantiate or deeplySkolemise That in turn means that some tests fail, by design; they can all be fixed by eta expansion. There is a list of such changes below. Implementing the patch led me into a variety of sticky corners, so the patch includes several othe changes, some quite significant: * I made String wired-in, so that "foo" :: String rather than "foo" :: [Char] This improves error messages, and fixes #15679 * isTauTy: was replying True for (Show a => a ->a), which is utterly bogus. Fixed. * The pattern match checker relies on knowing about in-scope equality constraints, andd adds them to the desugarer's environment using addTyCsDs. But the co_fn in a FunBind was missed, and for some reason simple-subsumption ends up with dictionaries there. So I added a call to addTyCsDs. This is really part of #18049. * I moved the ic_telescope field out of Implication and into ForAllSkol instead. This is a nice win; just expresses the code much better. * There was a bug in GHC.Tc.TyCl.Instance.tcDataFamInstHeader. We called checkDataKindSig inside tc_kind_sig, /before/ solveEqualities and zonking. Obviously wrong, easily fixed. * solveLocalEqualitiesX: there was a whole mess in here, around failing fast enough. I discovered a bad latent bug where we could successfully kind-check a type signature, and use it, but have unsolved constraints that could fill in coercion holes in that signature -- aargh. It's all explained in Note [Failure in local type signatures] in GHC.Tc.Solver. Much better now. * I fixed a serious bug in anonymous type holes. IN f :: Int -> (forall a. a -> _) -> Int that "_" should be a unification variable at the /outer/ level; it cannot be instantiated to 'a'. This was plain wrong. New fields mode_lvl and mode_holes in TcTyMode, and auxiliary data type GHC.Tc.Gen.HsType.HoleMode. This fixes #16292, but makes no progress towards the more ambitious #16082 * I got sucked into an enormous refactoring of the reporting of equality errors in GHC.Tc.Errors, especially in mkEqErr1 mkTyVarEqErr misMatchMsg misMatchMsgOrCND In particular, the very tricky mkExpectedActualMsg function is gone. It took me a full day. But the result is far easier to understand. (Still not easy!) This led to various minor improvements in error output, and an enormous number of test-case error wibbles. One particular point: for occurs-check errors I now just say Can't match 'a' against '[a]' rather than using the intimidating language of "occurs check". * Pretty-printing AbsBinds Tests review * Eta expansions T11305: one eta expansion T12082: one eta expansion (undefined) T13585a: one eta expansion T3102: one eta expansion T3692: two eta expansions (tricky) T2239: two eta expansions T16473: one eta determ004: two eta expansions (undefined) annfail06: two eta (undefined) T17923: four eta expansions (a strange program indeed!) tcrun035: one eta expansion * Ambiguity check at higher rank. Now that we have simple subsumption, a type like f :: (forall a. Eq a => Int) -> Int is no longer ambiguous, because we could write g :: (forall a. Eq a => Int) -> Int g = f and it'd typecheck just fine. But f's type is a bit suspicious, and we might want to consider making the ambiguity check do a check on each sub-term. Meanwhile, these tests are accepted, whereas they were previously rejected as ambiguous: T7220a T15438 T10503 T9222 * Some more interesting error message wibbles T13381: Fine: one error (Int ~ Exp Int) rather than two (Int ~ Exp Int, Exp Int ~ Int) T9834: Small change in error (improvement) T10619: Improved T2414: Small change, due to order of unification, fine T2534: A very simple case in which a change of unification order means we get tow unsolved constraints instead of one tc211: bizarre impredicative tests; just accept this for now - - - - - a6b1ee08 by Simon Peyton Jones at 2020-05-04T11:18:16+01:00 Wibbles Especially make major improvement to hsWrapDictBinders - - - - - 3310af0c by Simon Peyton Jones at 2020-05-04T11:18:16+01:00 Wibbles esp to tcPolyCheck - - - - - 52089110 by Simon Peyton Jones at 2020-05-04T11:18:16+01:00 Wibbles - - - - - 54d93222 by Simon Peyton Jones at 2020-05-04T11:18:16+01:00 Wibbles - - - - - 188205d6 by Simon Peyton Jones at 2020-05-04T12:01:25+01:00 Wibbles (dynamic-paper ticks) - - - - - 87760b04 by Simon Peyton Jones at 2020-05-05T17:37:03+01:00 First draft of Quick Look impredicativity This patch implements Quick Look impredicativity (see #18126). The main action in is in the new module GHC.Tc.Gen.App, which deals with typechecking function applications. Much code has moved from Tc.Gen.Expr into Tc.Gen.App, but Tc.Gen.App also includes the new Quick Look code: see the function quickLook. Not properly tested yet -- this is just so you can see what I'm up to. - - - - - 21 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Types.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Parser.y - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Splice.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Hole.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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/55685fd8e7fbf34932eaeedeb59bfd9f52e7e69f...87760b048b7dc59b4f6d275672bb7bac0a4f0e25 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/55685fd8e7fbf34932eaeedeb59bfd9f52e7e69f...87760b048b7dc59b4f6d275672bb7bac0a4f0e25 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 5 18:18:33 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 05 May 2020 14:18:33 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 6 commits: Refactor hole constraints. Message-ID: <5eb1adf980051_61673f81cd4c695c89434ab@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 27145d04 by Richard Eisenberg at 2020-05-05T14:18:24-04:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG ------------------------- - - - - - 7ddb29e0 by Zubin Duggal at 2020-05-05T14:18:25-04:00 Allow atomic update of NameCache in readHieFile The situation arises in ghcide where multiple different threads may need to update the name cache, therefore with the older interface it could happen that you start reading a hie file with name cache A and produce name cache A + B, but another thread in the meantime updated the namecache to A + C. Therefore if you write the new namecache you will lose the A' updates from the second thread. Updates haddock submodule - - - - - 215f7fc1 by Ryan Scott at 2020-05-05T14:18:25-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _)`. Fixes #18127. - - - - - d69b6264 by Sylvain Henry at 2020-05-05T14:18:28-04:00 Move LeadingUnderscore into Platform (#17957) Avoid direct use of DynFlags to know if symbols must be prefixed by an underscore. - - - - - 9d4e0360 by Sylvain Henry at 2020-05-05T14:18:28-04:00 Don't use DynFlags in showLinkerState (#17957) - - - - - 51045526 by Ryan Scott at 2020-05-05T14:18:28-04:00 Refactoring: Use bindSigTyVarsFV in rnMethodBinds `rnMethodBinds` was explicitly using `xoptM` to determine if `ScopedTypeVariables` is enabled before bringing type variables bound by the class/instance header into scope. However, this `xoptM` logic is already performed by the `bindSigTyVarsFV` function. This patch uses `bindSigTyVarsFV` in `rnMethodBinds` to reduce the number of places where we need to consult if `ScopedTypeVariables` is on. This is purely refactoring, and there should be no user-visible change in behavior. - - - - - 30 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Plugins.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Runtime/Linker.hs - compiler/GHC/Settings.hs - compiler/GHC/Settings/IO.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Errors/Hole.hs-boot - compiler/GHC/Tc/Errors/Hole/FitTypes.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Rule.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/Solver/Canonical.hs - compiler/GHC/Tc/Solver/Flatten.hs - compiler/GHC/Tc/Solver/Interact.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Types/Constraint.hs - compiler/GHC/Tc/Types/Origin.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Tc/Utils/TcMType.hs - ghc/GHCi/UI.hs - libraries/ghc-boot/GHC/Platform.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5c55d411037e77a4851f472b58438ac75e8528d3...51045526d2373e5e1bcfcc6d626ceaeb0bc6711d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5c55d411037e77a4851f472b58438ac75e8528d3...51045526d2373e5e1bcfcc6d626ceaeb0bc6711d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 5 20:49:50 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Tue, 05 May 2020 16:49:50 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T16762-chunks-2-and-3 Message-ID: <5eb1d16eb26fd_61673f81a47933c0896967a@gitlab.haskell.org.mail> Ryan Scott pushed new branch wip/T16762-chunks-2-and-3 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T16762-chunks-2-and-3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 5 23:26:03 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Tue, 05 May 2020 19:26:03 -0400 Subject: [Git][ghc/ghc][wip/T16762-chunks-2-and-3] WIP: Factor out HsPatSigType for pat sigs/RULE term sigs (#16762) Message-ID: <5eb1f60b64d2a_61673f81cd4c695c89979a3@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T16762-chunks-2-and-3 at Glasgow Haskell Compiler / GHC Commits: de54a099 by Ryan Scott at 2020-05-05T19:25:44-04:00 WIP: Factor out HsPatSigType for pat sigs/RULE term sigs (#16762) This implements chunks (2) and (3) of https://gitlab.haskell.org/ghc/ghc/issues/16762#note_270170. Namely, it introduces a dedicated `HsPatSigType` AST type, which represents the types that can appear in pattern signatures and term-level `RULE` binders. Previously, these were represented with `LHsSigWcType`. Although `LHsSigWcType` is isomorphic to `HsPatSigType`, the intended semantics of the two types are slightly different, as evidenced by the fact that they have different code paths in the renamer and typechecker. See also my additions to `Note [HsType binders]`. - - - - - 17 changed files: - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Extension.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Types.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/ThToHs.hs - testsuite/tests/hiefile/should_compile/hie007.hs Changes: ===================================== compiler/GHC/Hs/Decls.hs ===================================== @@ -2244,7 +2244,7 @@ type LRuleBndr pass = Located (RuleBndr pass) -- | Rule Binder data RuleBndr pass = RuleBndr (XCRuleBndr pass) (Located (IdP pass)) - | RuleBndrSig (XRuleBndrSig pass) (Located (IdP pass)) (LHsSigWcType pass) + | RuleBndrSig (XRuleBndrSig pass) (Located (IdP pass)) (HsPatSigType pass) | XRuleBndr !(XXRuleBndr pass) -- ^ -- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen', @@ -2256,7 +2256,7 @@ type instance XCRuleBndr (GhcPass _) = NoExtField type instance XRuleBndrSig (GhcPass _) = NoExtField type instance XXRuleBndr (GhcPass _) = NoExtCon -collectRuleBndrSigTys :: [RuleBndr pass] -> [LHsSigWcType pass] +collectRuleBndrSigTys :: [RuleBndr pass] -> [HsPatSigType pass] collectRuleBndrSigTys bndrs = [ty | RuleBndrSig _ _ ty <- bndrs] pprFullRuleName :: Located (SourceText, RuleName) -> SDoc ===================================== compiler/GHC/Hs/Extension.hs ===================================== @@ -685,6 +685,11 @@ type family XXHsWildCardBndrs x b -- ------------------------------------- +type family XHsPS x +type family XXHsPatSigType x + +-- ------------------------------------- + type family XForAllTy x type family XQualTy x type family XTyVar x ===================================== compiler/GHC/Hs/Instances.hs ===================================== @@ -386,6 +386,11 @@ deriving instance (Data thing) => Data (HsWildCardBndrs GhcPs thing) deriving instance (Data thing) => Data (HsWildCardBndrs GhcRn thing) deriving instance (Data thing) => Data (HsWildCardBndrs GhcTc thing) +-- deriving instance (DataIdLR p p) => Data (HsPatSigType p) +deriving instance Data (HsPatSigType GhcPs) +deriving instance Data (HsPatSigType GhcRn) +deriving instance Data (HsPatSigType GhcTc) + -- deriving instance (DataIdLR p p) => Data (HsTyVarBndr p) deriving instance Data (HsTyVarBndr GhcPs) deriving instance Data (HsTyVarBndr GhcRn) ===================================== compiler/GHC/Hs/Pat.hs ===================================== @@ -240,7 +240,7 @@ data Pat p -- For details on above see note [Api annotations] in GHC.Parser.Annotation | SigPat (XSigPat p) -- After typechecker: Type (LPat p) -- Pattern with a type signature - (LHsSigWcType (NoGhcTc p)) -- Signature can bind both + (HsPatSigType (NoGhcTc p)) -- Signature can bind both -- kind and type vars -- ^ Pattern with a type signature ===================================== compiler/GHC/Hs/Types.hs ===================================== @@ -23,6 +23,7 @@ module GHC.Hs.Types ( LHsQTyVars(..), HsImplicitBndrs(..), HsWildCardBndrs(..), + HsPatSigType(..), HsPSRn(..), LHsSigType, LHsSigWcType, LHsWcType, HsTupleSort(..), HsContext, LHsContext, noLHsContext, @@ -47,7 +48,7 @@ module GHC.Hs.Types ( mkAnonWildCardTy, pprAnonWildCard, - mkHsImplicitBndrs, mkHsWildCardBndrs, hsImplicitBody, + mkHsImplicitBndrs, mkHsWildCardBndrs, mkHsPatSigType, hsImplicitBody, mkEmptyImplicitBndrs, mkEmptyWildCardBndrs, mkHsQTvs, hsQTvExplicit, emptyLHsQTvs, isEmptyLHsQTvs, isHsKindedTyVar, hsTvbAllKinded, isLHsForAllTy, @@ -59,7 +60,7 @@ module GHC.Hs.Types ( splitLHsForAllTyInvis, splitLHsQualTy, splitLHsSigmaTyInvis, splitHsFunType, hsTyGetAppHead_maybe, mkHsOpTy, mkHsAppTy, mkHsAppTys, mkHsAppKindTy, - ignoreParens, hsSigType, hsSigWcType, + ignoreParens, hsSigType, hsSigWcType, hsPatSigType, hsLTyVarBndrToType, hsLTyVarBndrsToTypes, hsTyKindSig, hsConDetailsArgs, @@ -184,6 +185,18 @@ is a bit complicated. Here's how it works. f :: _a -> _ The enclosing HsWildCardBndrs binds the wildcards _a and _. +* HsSigPatType describes types that appear in pattern signatures and + the signatures of term-level binders in RULES. Like + HsWildCardBndrs/HsImplicitBndrs, they track the names of wildcard + variables and implicitly quantified type variables. Unlike + HsImplicitBndrs, however, HsSigPatTypes do not obey the + forall-or-nothing rule. For example, in this pattern signature: + + f (g :: forall a. a -> b) x = g x :: b + + The type variable `b` is in scope on the RHS, even though it was + not explicitly quantified by the @forall@ in the pattern signature. + * The explicit presence of these wrappers specifies, in the HsSyn, exactly where implicit quantification is allowed, and where wildcards are allowed. @@ -225,13 +238,15 @@ Note carefully: Here _a is an ordinary forall'd binder, but (With NamedWildCards) _b is a named wildcard. (See the comments in #10982) -* Named wildcards are bound by the HsWildCardBndrs construct, which wraps - types that are allowed to have wildcards. Unnamed wildcards however are left - unchanged until typechecking, where we give them fresh wild tyavrs and - determine whether or not to emit hole constraints on each wildcard - (we don't if it's a visible type/kind argument or a type family pattern). - See related notes Note [Wildcards in visible kind application] - and Note [Wildcards in visible type application] in GHC.Tc.Gen.HsType +* Named wildcards are bound by the HsWildCardBndrs (for types that obey the + forall-or-nothing rule) and HsPatSigType (for type signatures in patterns + and term-level binders in RULES), which wrap types that are allowed to have + wildcards. Unnamed wildcards, however are left unchanged until typechecking, + where we give them fresh wild tyvars and determine whether or not to emit + hole constraints on each wildcard (we don't if it's a visible type/kind + argument or a type family pattern). See related notes + Note [Wildcards in visible kind application] and + Note [Wildcards in visible type application] in GHC.Tc.Gen.HsType. * After type checking is done, we report what types the wildcards got unified with. @@ -399,6 +414,30 @@ type instance XHsWC GhcTc b = [Name] type instance XXHsWildCardBndrs (GhcPass _) b = NoExtCon +-- | Types that can appear in pattern signatures, as well as the signatures for +-- term-level binders in RULES. This is very similar to 'HsSigWcType', but with +-- slightly different semantics: see @Note [HsType binders]@. +-- See also @Note [The wildcard story for types]@. +data HsPatSigType pass + = HsPS { hsps_ext :: XHsPS pass -- ^ After renamer: 'HsPSRn' + , hsps_body :: LHsType pass -- ^ Main payload (the type itself) + } + | XHsPatSigType !(XXHsPatSigType pass) + +-- | The extension field for 'HsPatSigType', which is only used in the +-- renamer onwards. +data HsPSRn = HsPSRn + { hsps_nwcs :: [Name] -- ^ Wildcard names + , hsps_imp_tvs :: [Name] -- ^ Implicitly quantified variable names + } + deriving Data + +type instance XHsPS GhcPs = NoExtField +type instance XHsPS GhcRn = HsPSRn +type instance XHsPS GhcTc = HsPSRn + +type instance XXHsPatSigType (GhcPass _) = NoExtCon + -- | Located Haskell Signature Type type LHsSigType pass = HsImplicitBndrs pass (LHsType pass) -- Implicit only @@ -419,6 +458,9 @@ hsSigType = hsImplicitBody hsSigWcType :: LHsSigWcType pass -> LHsType pass hsSigWcType sig_ty = hsib_body (hswc_body sig_ty) +hsPatSigType :: HsPatSigType pass -> LHsType pass +hsPatSigType = hsps_body + dropWildCards :: LHsSigWcType pass -> LHsSigType pass -- Drop the wildcard part of a LHsSigWcType dropWildCards sig_ty = hswc_body sig_ty @@ -451,6 +493,10 @@ mkHsWildCardBndrs :: thing -> HsWildCardBndrs GhcPs thing mkHsWildCardBndrs x = HsWC { hswc_body = x , hswc_ext = noExtField } +mkHsPatSigType :: LHsType GhcPs -> HsPatSigType GhcPs +mkHsPatSigType x = HsPS { hsps_ext = noExtField + , hsps_body = x } + -- Add empty binders. This is a bit suspicious; what if -- the wrapped thing had free type variables? mkEmptyImplicitBndrs :: thing -> HsImplicitBndrs GhcRn thing @@ -1408,6 +1454,10 @@ instance Outputable thing => Outputable (HsWildCardBndrs (GhcPass p) thing) where ppr (HsWC { hswc_body = ty }) = ppr ty +instance OutputableBndrId p + => Outputable (HsPatSigType (GhcPass p)) where + ppr (HsPS { hsps_body = ty }) = ppr ty + pprAnonWildCard :: SDoc pprAnonWildCard = char '_' ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -821,7 +821,7 @@ repRuleD (L loc (HsRule { rd_name = n ruleBndrNames :: LRuleBndr GhcRn -> [Name] ruleBndrNames (L _ (RuleBndr _ n)) = [unLoc n] ruleBndrNames (L _ (RuleBndrSig _ n sig)) - | HsWC { hswc_body = HsIB { hsib_ext = vars }} <- sig + | HsPS { hsps_ext = HsPSRn { hsps_imp_tvs = vars }} <- sig = unLoc n : vars repRuleBndr :: LRuleBndr GhcRn -> MetaM (Core (M TH.RuleBndr)) @@ -830,7 +830,7 @@ repRuleBndr (L _ (RuleBndr _ n)) ; rep2 ruleVarName [n'] } repRuleBndr (L _ (RuleBndrSig _ n sig)) = do { MkC n' <- lookupLBinder n - ; MkC ty' <- repLTy (hsSigWcType sig) + ; MkC ty' <- repLTy (hsPatSigType sig) ; rep2 typedRuleVarName [n', ty'] } repAnnD :: LAnnDecl GhcRn -> MetaM (SrcSpan, Core (M TH.Dec)) @@ -1935,7 +1935,7 @@ repP (NPat _ (L _ l) Nothing _) = do { a <- repOverloadedLiteral l repP (ViewPat _ e p) = do { e' <- repLE e; p' <- repLP p; repPview e' p' } repP p@(NPat _ _ (Just _) _) = notHandled "Negative overloaded patterns" (ppr p) repP (SigPat _ p t) = do { p' <- repLP p - ; t' <- repLTy (hsSigWcType t) + ; t' <- repLTy (hsPatSigType t) ; repPsig p' t' } repP (SplicePat _ splice) = repSplice splice repP other = notHandled "Exotic pattern" (ppr other) ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -833,7 +833,7 @@ instance ( a ~ GhcPass p [ toHie $ PS rsp scope pscope pat , let cscope = mkLScope pat in toHie $ TS (ResolvedScopes [cscope, scope, pscope]) - (protectSig @a cscope sig) + (protectSig @a cscope undefined) -- TODO RGS: Help me wz1000! -- See Note [Scoping Rules for SigPat] ] XPat e -> case ghcPass @p of @@ -1847,7 +1847,7 @@ instance ToHie (RScoped (LRuleBndr GhcRn)) where ] RuleBndrSig _ var typ -> [ toHie $ C (ValBind RegularBind sc Nothing) var - , toHie $ TS (ResolvedScopes [sc]) typ + , toHie $ TS (ResolvedScopes [sc]) (undefined :: LHsSigWcType GhcRn) -- TODO RGS: Help me wz1000! ] instance ToHie (LImportDecl GhcRn) where ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -874,7 +874,7 @@ mkRuleBndrs :: [LRuleTyTmVar] -> [LRuleBndr GhcPs] mkRuleBndrs = fmap (fmap cvt_one) where cvt_one (RuleTyTmVar v Nothing) = RuleBndr noExtField v cvt_one (RuleTyTmVar v (Just sig)) = - RuleBndrSig noExtField v (mkLHsSigWcType sig) + RuleBndrSig noExtField v (mkHsPatSigType sig) -- turns RuleTyTmVars into HsTyVarBndrs - this is more interesting mkRuleTyVarBndrs :: [LRuleTyTmVar] -> [LHsTyVarBndr GhcPs] @@ -2033,7 +2033,7 @@ instance DisambECP (PatBuilder GhcPs) where mkHsWildCardPV l = return $ L l (PatBuilderPat (WildPat noExtField)) mkHsTySigPV l b sig = do p <- checkLPat b - return $ L l (PatBuilderPat (SigPat noExtField p (mkLHsSigWcType sig))) + return $ L l (PatBuilderPat (SigPat noExtField p (mkHsPatSigType sig))) mkHsExplicitListPV l xs = do ps <- traverse checkLPat xs return (L l (PatBuilderPat (ListPat noExtField ps))) ===================================== compiler/GHC/Rename/Bind.hs ===================================== @@ -962,7 +962,7 @@ renameSig _ (IdSig _ x) renameSig ctxt sig@(TypeSig _ vs ty) = do { new_vs <- mapM (lookupSigOccRn ctxt sig) vs ; let doc = TypeSigCtx (ppr_sig_bndrs vs) - ; (new_ty, fvs) <- rnHsSigWcType BindUnlessForall doc ty + ; (new_ty, fvs) <- rnHsSigWcType doc ty ; return (TypeSig noExtField new_vs new_ty, fvs) } renameSig ctxt sig@(ClassOpSig _ is_deflt vs ty) ===================================== compiler/GHC/Rename/Expr.hs ===================================== @@ -316,7 +316,7 @@ rnExpr (RecordUpd { rupd_expr = expr, rupd_flds = rbinds }) , fvExpr `plusFV` fvRbinds) } rnExpr (ExprWithTySig _ expr pty) - = do { (pty', fvTy) <- rnHsSigWcType BindUnlessForall ExprWithTySigCtx pty + = do { (pty', fvTy) <- rnHsSigWcType ExprWithTySigCtx pty ; (expr', fvExpr) <- bindSigTyVarsFV (hsWcScopedTvs pty') $ rnLExpr expr ; return (ExprWithTySig noExtField expr' pty', fvExpr `plusFV` fvTy) } ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -13,7 +13,7 @@ module GHC.Rename.HsType ( rnHsType, rnLHsType, rnLHsTypes, rnContext, rnHsKind, rnLHsKind, rnLHsTypeArgs, rnHsSigType, rnHsWcType, - HsSigWcTypeScoping(..), rnHsSigWcType, rnHsSigWcTypeScoped, + HsSigWcTypeScoping(..), rnHsSigWcType, rnHsPatSigType, newTyVarNameRn, rnConDeclFields, rnLTyVar, @@ -71,58 +71,85 @@ import Control.Monad ( unless, when ) {- These type renamers are in a separate module, rather than in (say) GHC.Rename.Module, -to break several loop. +to break several loops. ********************************************************* * * - HsSigWcType (i.e with wildcards) + HsSigWcType and HsPatSigType (i.e with wildcards) * * ********************************************************* -} -data HsSigWcTypeScoping = AlwaysBind - -- ^ Always bind any free tyvars of the given type, - -- regardless of whether we have a forall at the top - | BindUnlessForall - -- ^ Unless there's forall at the top, do the same - -- thing as 'AlwaysBind' - | NeverBind - -- ^ Never bind any free tyvars - -rnHsSigWcType :: HsSigWcTypeScoping -> HsDocContext -> LHsSigWcType GhcPs +data HsSigWcTypeScoping + = AlwaysBind + -- ^ Always bind any free tyvars of the given type, regardless of whether we + -- have a forall at the top. + -- + -- For pattern type sigs and rules we /do/ want to bring those type + -- variables into scope, even if there's a forall at the top which usually + -- stops that happening, e.g: + -- + -- > \ (x :: forall a. a-> b) -> e + -- + -- Here we do bring 'b' into scope. + | BindUnlessForall + -- ^ Unless there's forall at the top, do the same thing as 'AlwaysBind'. + -- This is only ever used in places where the \"@forall at -or-nothing\" rule + -- is in effect. + | NeverBind + -- ^ Never bind any free tyvars. This is only used for RULES that have both + -- type and term variabls binders, e.g.: + -- + -- > {-# RULES "id" forall a. forall (x :: a) y. const x y = x #-} + -- + -- The presence of the type variable binder @forall a.@ implies that the + -- free variables in the types of the term variable binders @x@ and @y@ + -- are /not/ bound. In the example above, there are no such free variables, + -- but if the user had written @(y :: b)@ instead of @y@ in the term + -- variable binders, then @b@ would be rejected for being out of scope. + -- If the user had omitted the type variable binder, however: + -- + -- > {-# RULES "id" forall (x :: a) (y :: b). const x y = x #-} + -- + -- Then @(y :: b)@ would be fine, as it would be implicitly quantified. + -- In other words, omitting type variable binders caused 'AlwaysBind', + -- not 'NeverBind', to be picked. + +rnHsSigWcType :: HsDocContext -> LHsSigWcType GhcPs -> RnM (LHsSigWcType GhcRn, FreeVars) -rnHsSigWcType scoping doc sig_ty - = rn_hs_sig_wc_type scoping doc sig_ty $ \sig_ty' -> - return (sig_ty', emptyFVs) - -rnHsSigWcTypeScoped :: HsSigWcTypeScoping - -- AlwaysBind: for pattern type sigs and rules we /do/ want - -- to bring those type variables into scope, even - -- if there's a forall at the top which usually - -- stops that happening - -- e.g \ (x :: forall a. a-> b) -> e - -- Here we do bring 'b' into scope - -> HsDocContext -> LHsSigWcType GhcPs - -> (LHsSigWcType GhcRn -> RnM (a, FreeVars)) - -> RnM (a, FreeVars) +rnHsSigWcType doc (HsWC { hswc_body = HsIB { hsib_body = hs_ty }}) + = rn_hs_sig_wc_type BindUnlessForall doc hs_ty $ \nwcs imp_tvs body -> + let ib_ty = HsIB { hsib_ext = imp_tvs, hsib_body = body } + wc_ty = HsWC { hswc_ext = nwcs, hswc_body = ib_ty } in + pure (wc_ty, emptyFVs) + +rnHsPatSigType :: HsSigWcTypeScoping + -> HsDocContext -> HsPatSigType GhcPs + -> (HsPatSigType GhcRn -> RnM (a, FreeVars)) + -> RnM (a, FreeVars) -- Used for --- - Signatures on binders in a RULE --- - Pattern type signatures +-- - Pattern type signatures, which are only allowed with ScopedTypeVariables +-- - Signatures on binders in a RULE, which are allowed even if +-- ScopedTypeVariables isn't enabled -- Wildcards are allowed --- type signatures on binders only allowed with ScopedTypeVariables -rnHsSigWcTypeScoped scoping ctx sig_ty thing_inside +rnHsPatSigType scoping ctx sig_ty thing_inside = do { ty_sig_okay <- xoptM LangExt.ScopedTypeVariables - ; checkErr ty_sig_okay (unexpectedTypeSigErr sig_ty) - ; rn_hs_sig_wc_type scoping ctx sig_ty thing_inside - } - -rn_hs_sig_wc_type :: HsSigWcTypeScoping -> HsDocContext -> LHsSigWcType GhcPs - -> (LHsSigWcType GhcRn -> RnM (a, FreeVars)) + ; checkErr ty_sig_okay (unexpectedPatSigTypeErr sig_ty) + ; rn_hs_sig_wc_type scoping ctx (hsPatSigType sig_ty) $ + \nwcs imp_tvs body -> + do { let sig_names = HsPSRn { hsps_nwcs = nwcs, hsps_imp_tvs = imp_tvs } + sig_ty' = HsPS { hsps_ext = sig_names, hsps_body = body } + ; thing_inside sig_ty' + } } + +-- The workhorse for rnHsSigWcType and rnHsPatSigType. +rn_hs_sig_wc_type :: HsSigWcTypeScoping -> HsDocContext -> LHsType GhcPs + -> ([Name] -- Wildcard names + -> [Name] -- Implicitly quantified type variable names + -> LHsType GhcRn + -> RnM (a, FreeVars)) -> RnM (a, FreeVars) --- rn_hs_sig_wc_type is used for source-language type signatures -rn_hs_sig_wc_type scoping ctxt - (HsWC { hswc_body = HsIB { hsib_body = hs_ty }}) - thing_inside +rn_hs_sig_wc_type scoping ctxt hs_ty thing_inside = do { free_vars <- extractFilteredRdrTyVarsDups hs_ty ; (nwc_rdrs', tv_rdrs) <- partition_nwcs free_vars ; let nwc_rdrs = nubL nwc_rdrs' @@ -132,10 +159,7 @@ rn_hs_sig_wc_type scoping ctxt NeverBind -> False ; rnImplicitBndrs bind_free_tvs tv_rdrs $ \ vars -> do { (wcs, hs_ty', fvs1) <- rnWcBody ctxt nwc_rdrs hs_ty - ; let sig_ty' = HsWC { hswc_ext = wcs, hswc_body = ib_ty' } - ib_ty' = HsIB { hsib_ext = vars - , hsib_body = hs_ty' } - ; (res, fvs2) <- thing_inside sig_ty' + ; (res, fvs2) <- thing_inside wcs vars hs_ty' ; return (res, fvs1 `plusFV` fvs2) } } rnHsWcType :: HsDocContext -> LHsWcType GhcPs -> RnM (LHsWcType GhcRn, FreeVars) @@ -1376,8 +1400,8 @@ ppr_opfix (op, fixity) = pp_op <+> brackets (ppr fixity) * * ***************************************************** -} -unexpectedTypeSigErr :: LHsSigWcType GhcPs -> SDoc -unexpectedTypeSigErr ty +unexpectedPatSigTypeErr :: HsPatSigType GhcPs -> SDoc +unexpectedPatSigTypeErr ty = hang (text "Illegal type signature:" <+> quotes (ppr ty)) 2 (text "Type signatures are only allowed in patterns with ScopedTypeVariables") ===================================== compiler/GHC/Rename/Module.hs ===================================== @@ -958,7 +958,7 @@ rnSrcDerivDecl (DerivDecl _ ty mds overlap) ; unless standalone_deriv_ok (addErr standaloneDerivErr) ; (mds', ty', fvs) <- rnLDerivStrategy DerivDeclCtx mds $ - rnHsSigWcType BindUnlessForall DerivDeclCtx ty + rnHsSigWcType DerivDeclCtx ty ; warnNoDerivStrat mds' loc ; return (DerivDecl noExtField ty' mds' overlap, fvs) } where @@ -1029,7 +1029,7 @@ bindRuleTmVars doc tyvs vars names thing_inside go ((L l (RuleBndrSig _ (L loc _) bsig)) : vars) (n : ns) thing_inside - = rnHsSigWcTypeScoped bind_free_tvs doc bsig $ \ bsig' -> + = rnHsPatSigType bind_free_tvs doc bsig $ \ bsig' -> go vars ns $ \ vars' -> thing_inside (L l (RuleBndrSig noExtField (L loc n) bsig') : vars') ===================================== compiler/GHC/Rename/Pat.hs ===================================== @@ -218,9 +218,6 @@ matchNameMaker ctxt = LamMk report_unused ThPatQuote -> False _ -> True -rnHsSigCps :: LHsSigWcType GhcPs -> CpsRn (LHsSigWcType GhcRn) -rnHsSigCps sig = CpsRn (rnHsSigWcTypeScoped AlwaysBind PatCtx sig) - newPatLName :: NameMaker -> Located RdrName -> CpsRn (Located Name) newPatLName name_maker rdr_name@(L loc _) = do { name <- newPatName name_maker rdr_name @@ -410,9 +407,12 @@ rnPatAndThen mk (SigPat x pat sig) -- f ((Just (x :: a) :: Maybe a) -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~^ `a' is first bound here -- ~~~~~~~~~~~~~~~^ the same `a' then used here - = do { sig' <- rnHsSigCps sig + = do { sig' <- rnHsPatSigTypeAndThen sig ; pat' <- rnLPatAndThen mk pat ; return (SigPat x pat' sig' ) } + where + rnHsPatSigTypeAndThen :: HsPatSigType GhcPs -> CpsRn (HsPatSigType GhcRn) + rnHsPatSigTypeAndThen sig = CpsRn (rnHsPatSigType AlwaysBind PatCtx sig) rnPatAndThen mk (LitPat x lit) | HsString src s <- lit ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -3338,7 +3338,7 @@ Result works fine, but it may eventually bite us. ********************************************************************* -} tcHsPatSigType :: UserTypeCtxt - -> LHsSigWcType GhcRn -- The type signature + -> HsPatSigType GhcRn -- The type signature -> TcM ( [(Name, TcTyVar)] -- Wildcards , [(Name, TcTyVar)] -- The new bit of type environment, binding -- the scoped type variables @@ -3349,10 +3349,9 @@ tcHsPatSigType :: UserTypeCtxt -- -- This may emit constraints -- See Note [Recipe for checking a signature] -tcHsPatSigType ctxt sig_ty - | HsWC { hswc_ext = sig_wcs, hswc_body = ib_ty } <- sig_ty - , HsIB { hsib_ext = sig_ns - , hsib_body = hs_ty } <- ib_ty +tcHsPatSigType ctxt + (HsPS { hsps_ext = HsPSRn { hsps_nwcs = sig_wcs, hsps_imp_tvs = sig_ns } + , hsps_body = hs_ty }) = addSigCtxt ctxt hs_ty $ do { sig_tkv_prs <- mapM new_implicit_tv sig_ns ; (wcs, sig_ty) ===================================== compiler/GHC/Tc/Gen/Pat.hs ===================================== @@ -690,7 +690,7 @@ because they won't be in scope when we do the desugaring -} tcPatSig :: Bool -- True <=> pattern binding - -> LHsSigWcType GhcRn + -> HsPatSigType GhcRn -> ExpSigmaType -> TcM (TcType, -- The type to use for "inside" the signature [(Name,TcTyVar)], -- The new bit of type environment, binding ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -830,7 +830,7 @@ cvtRuleBndr (RuleVar n) cvtRuleBndr (TypedRuleVar n ty) = do { n' <- vNameL n ; ty' <- cvtType ty - ; return $ noLoc $ Hs.RuleBndrSig noExtField n' $ mkLHsSigWcType ty' } + ; return $ noLoc $ Hs.RuleBndrSig noExtField n' $ mkHsPatSigType ty' } --------------------------------------------------- -- Declarations @@ -1307,7 +1307,7 @@ cvtp (ListP ps) = do { ps' <- cvtPats ps ; return $ ListPat noExtField ps'} cvtp (SigP p t) = do { p' <- cvtPat p; t' <- cvtType t - ; return $ SigPat noExtField p' (mkLHsSigWcType t') } + ; return $ SigPat noExtField p' (mkHsPatSigType t') } cvtp (ViewP e p) = do { e' <- cvtl e; p' <- cvtPat p ; return $ ViewPat noExtField e' p'} ===================================== testsuite/tests/hiefile/should_compile/hie007.hs ===================================== @@ -64,3 +64,6 @@ thud f x = (x :: a, y) :: (a, b) where y = (f :: a -> b) x :: b + +rankn :: (forall a1. a1 -> b) -> a2 -> b +rankn (g :: forall a1. a1 -> b) x = g x :: b View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/de54a0994e83f4f7ddaa8e9a0ae7510e99c153d2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/de54a0994e83f4f7ddaa8e9a0ae7510e99c153d2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 6 01:49:19 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 05 May 2020 21:49:19 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 10 commits: Refactor hole constraints. Message-ID: <5eb2179f9bf20_61673f81cd4c695c90112dd@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: b8a34b81 by Richard Eisenberg at 2020-05-05T21:48:54-04:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG ------------------------- - - - - - 12425b89 by Ben Gamari at 2020-05-05T21:48:54-04:00 rts: Zero block flags with -DZ Block flags are very useful for determining the state of a block. However, some block allocator users don't touch them, leading to misleading values. Ensure that we zero then when zero-on-gc is set. This is safe and makes the flags more useful during debugging. - - - - - 7f3f62a8 by Ben Gamari at 2020-05-05T21:48:54-04:00 nonmoving: Fix incorrect failed_to_evac value during deadlock gc Previously we would incorrectly set the failed_to_evac flag if we evacuated a value due to a deadlock GC. This would cause us to mark more things as dirty than strictly necessary. It also turned up a nasty but which I will fix next. - - - - - 6e203bd4 by Ben Gamari at 2020-05-05T21:48:54-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - 5887c763 by Zubin Duggal at 2020-05-05T21:48:56-04:00 Allow atomic update of NameCache in readHieFile The situation arises in ghcide where multiple different threads may need to update the name cache, therefore with the older interface it could happen that you start reading a hie file with name cache A and produce name cache A + B, but another thread in the meantime updated the namecache to A + C. Therefore if you write the new namecache you will lose the A' updates from the second thread. Updates haddock submodule - - - - - 60f3e848 by Ryan Scott at 2020-05-05T21:48:57-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _)`. Fixes #18127. - - - - - d64d96fb by Ömer Sinan Ağacan at 2020-05-05T21:49:09-04:00 ELF linker: increment curSymbol after filling in fields of current entry The bug was introduced in a8b7cef4d45 which added a field to the `symbols` array elements and then updated this code incorrectly: - oc->symbols[curSymbol++] = nm; + oc->symbols[curSymbol++].name = nm; + oc->symbols[curSymbol].addr = symbol->addr; - - - - - 40d7e868 by Sylvain Henry at 2020-05-05T21:49:11-04:00 Move LeadingUnderscore into Platform (#17957) Avoid direct use of DynFlags to know if symbols must be prefixed by an underscore. - - - - - a03d7406 by Sylvain Henry at 2020-05-05T21:49:11-04:00 Don't use DynFlags in showLinkerState (#17957) - - - - - d3cc9c8e by Ryan Scott at 2020-05-05T21:49:12-04:00 Refactoring: Use bindSigTyVarsFV in rnMethodBinds `rnMethodBinds` was explicitly using `xoptM` to determine if `ScopedTypeVariables` is enabled before bringing type variables bound by the class/instance header into scope. However, this `xoptM` logic is already performed by the `bindSigTyVarsFV` function. This patch uses `bindSigTyVarsFV` in `rnMethodBinds` to reduce the number of places where we need to consult if `ScopedTypeVariables` is on. This is purely refactoring, and there should be no user-visible change in behavior. - - - - - 30 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Plugins.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Runtime/Linker.hs - compiler/GHC/Settings.hs - compiler/GHC/Settings/IO.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Errors/Hole.hs-boot - compiler/GHC/Tc/Errors/Hole/FitTypes.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Rule.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/Solver/Canonical.hs - compiler/GHC/Tc/Solver/Flatten.hs - compiler/GHC/Tc/Solver/Interact.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Types/Constraint.hs - compiler/GHC/Tc/Types/Origin.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Tc/Utils/TcMType.hs - ghc/GHCi/UI.hs - libraries/ghc-boot/GHC/Platform.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/51045526d2373e5e1bcfcc6d626ceaeb0bc6711d...d3cc9c8ed9a3910febec4c25ed915ea7de7ad0f3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/51045526d2373e5e1bcfcc6d626ceaeb0bc6711d...d3cc9c8ed9a3910febec4c25ed915ea7de7ad0f3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 6 08:39:50 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 06 May 2020 04:39:50 -0400 Subject: [Git][ghc/ghc][master] Refactor hole constraints. Message-ID: <5eb277d643fd9_61673f81cd4c695c9043956@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 7ab6ab09 by Richard Eisenberg at 2020-05-06T04:39:32-04:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG ------------------------- - - - - - 23 changed files: - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/Plugins.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Errors/Hole.hs-boot - compiler/GHC/Tc/Errors/Hole/FitTypes.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Rule.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/Solver/Canonical.hs - compiler/GHC/Tc/Solver/Flatten.hs - compiler/GHC/Tc/Solver/Interact.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Types/Constraint.hs - compiler/GHC/Tc/Types/Origin.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Tc/Utils/TcMType.hs - testsuite/tests/partial-sigs/should_compile/SplicesUsed.stderr - testsuite/tests/plugins/hole-fit-plugin/HoleFitPlugin.hs - testsuite/tests/th/T12411.stderr - testsuite/tests/typecheck/should_fail/T12589.stderr Changes: ===================================== compiler/GHC/HsToCore/PmCheck/Oracle.hs ===================================== @@ -438,7 +438,7 @@ then newtypes. (b) dcs is the list of newtype constructors "skipped", every time we normalise a newtype to its core representation, we keep track of the source data - constructor. For convenienve, we also track the type we unwrap and the + constructor. For convenience, we also track the type we unwrap and the type of its field. Example: @Down 42@ => @[(Down @Int, Down, Int)] (c) core_ty is the rewritten type. That is, pmTopNormaliseType env ty_cs ty = Just (src_ty, dcs, core_ty) ===================================== compiler/GHC/Plugins.hs ===================================== @@ -48,6 +48,7 @@ module GHC.Plugins , module GHC.Utils.Outputable , module GHC.Types.Unique.Supply , module GHC.Data.FastString + , module GHC.Tc.Errors.Hole.FitTypes -- for hole-fit plugins , -- * Getting 'Name's thNameToGhcName ) @@ -121,6 +122,8 @@ import GHC.Utils.Monad ( mapMaybeM ) import GHC.ThToHs ( thRdrNameGuesses ) import GHC.Tc.Utils.Env ( lookupGlobal ) +import GHC.Tc.Errors.Hole.FitTypes + import qualified Language.Haskell.TH as TH {- This instance is defined outside GHC.Core.Opt.Monad.hs so that ===================================== compiler/GHC/Tc/Errors.hs ===================================== @@ -285,8 +285,8 @@ important :: SDoc -> Report important doc = mempty { report_important = [doc] } -- | Put a doc into the relevant bindings block. -relevant_bindings :: SDoc -> Report -relevant_bindings doc = mempty { report_relevant_bindings = [doc] } +mk_relevant_bindings :: SDoc -> Report +mk_relevant_bindings doc = mempty { report_relevant_bindings = [doc] } -- | Put a doc into the valid hole fits block. valid_hole_fits :: SDoc -> Report @@ -524,16 +524,29 @@ This only matters in instance declarations.. -} reportWanteds :: ReportErrCtxt -> TcLevel -> WantedConstraints -> TcM () -reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) +reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics + , wc_holes = holes }) = do { traceTc "reportWanteds" (vcat [ text "Simples =" <+> ppr simples - , text "Suppress =" <+> ppr (cec_suppress ctxt)]) - ; traceTc "rw2" (ppr tidy_cts) - - -- First deal with things that are utterly wrong + , text "Suppress =" <+> ppr (cec_suppress ctxt) + , text "tidy_cts =" <+> ppr tidy_cts + , text "tidy_holes = " <+> ppr tidy_holes ]) + + -- First, deal with any out-of-scope errors: + ; let (out_of_scope, other_holes) = partition isOutOfScopeHole tidy_holes + -- don't suppress out-of-scope errors + ctxt_for_scope_errs = ctxt { cec_suppress = False } + ; (_, no_out_of_scope) <- askNoErrs $ + reportHoles tidy_cts ctxt_for_scope_errs out_of_scope + + -- Next, deal with things that are utterly wrong -- Like Int ~ Bool (incl nullary TyCons) -- or Int ~ t a (AppTy on one side) -- These /ones/ are not suppressed by the incoming context - ; let ctxt_for_insols = ctxt { cec_suppress = False } + -- (but will be by out-of-scope errors) + ; let ctxt_for_insols = ctxt { cec_suppress = not no_out_of_scope } + ; reportHoles tidy_cts ctxt_for_insols other_holes + -- holes never suppress + ; (ctxt1, cts1) <- tryReporters ctxt_for_insols report1 tidy_cts -- Now all the other constraints. We suppress errors here if @@ -554,7 +567,8 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) -- if there's a *given* insoluble here (= inaccessible code) where env = cec_tidy ctxt - tidy_cts = bagToList (mapBag (tidyCt env) simples) + tidy_cts = bagToList (mapBag (tidyCt env) simples) + tidy_holes = bagToList (mapBag (tidyHole env) holes) -- report1: ones that should *not* be suppressed by -- an insoluble somewhere else in the tree @@ -562,9 +576,7 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) -- (see GHC.Tc.Utils.insolubleCt) is caught here, otherwise -- we might suppress its error message, and proceed on past -- type checking to get a Lint error later - report1 = [ ("Out of scope", unblocked is_out_of_scope, True, mkHoleReporter tidy_cts) - , ("Holes", unblocked is_hole, False, mkHoleReporter tidy_cts) - , ("custom_error", unblocked is_user_type_error, True, mkUserTypeErrorReporter) + report1 = [ ("custom_error", unblocked is_user_type_error, True, mkUserTypeErrorReporter) , given_eq_spec , ("insoluble2", unblocked utterly_wrong, True, mkGroupReporter mkEqErr) @@ -593,8 +605,7 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) unblocked checker ct pred = checker ct pred -- rigid_nom_eq, rigid_nom_tv_eq, - is_hole, is_dict, - is_equality, is_ip, is_irred :: Ct -> Pred -> Bool + is_dict, is_equality, is_ip, is_irred :: Ct -> Pred -> Bool is_given_eq ct pred | EqPred {} <- pred = arisesFromGivens ct @@ -617,9 +628,6 @@ reportWanteds ctxt tc_lvl (WC { wc_simple = simples, wc_impl = implics }) non_tv_eq _ (EqPred NomEq ty1 _) = not (isTyVarTy ty1) non_tv_eq _ _ = False - is_out_of_scope ct _ = isOutOfScopeCt ct - is_hole ct _ = isHoleCt ct - is_user_type_error ct _ = isUserTypeErrorCt ct is_homo_equality _ (EqPred _ ty1 ty2) = tcTypeKind ty1 `tcEqType` tcTypeKind ty2 @@ -705,12 +713,12 @@ mkSkolReporter ctxt cts | eq_lhs_type ct1 ct2 = True | otherwise = False -mkHoleReporter :: [Ct] -> Reporter --- Reports errors one at a time -mkHoleReporter tidy_simples ctxt - = mapM_ $ \ct -> do { err <- mkHoleError tidy_simples ctxt ct - ; maybeReportHoleError ctxt ct err - ; maybeAddDeferredHoleBinding ctxt err ct } +reportHoles :: [Ct] -- other (tidied) constraints + -> ReportErrCtxt -> [Hole] -> TcM () +reportHoles tidy_cts ctxt + = mapM_ $ \hole -> do { err <- mkHoleError tidy_cts ctxt hole + ; maybeReportHoleError ctxt hole err + ; maybeAddDeferredHoleBinding ctxt err hole } mkUserTypeErrorReporter :: Reporter mkUserTypeErrorReporter ctxt @@ -742,7 +750,7 @@ mkGivenErrorReporter ctxt cts inaccessible_msg = hang (text "Inaccessible code in") 2 (ppr (ic_info implic)) report = important inaccessible_msg `mappend` - relevant_bindings binds_msg + mk_relevant_bindings binds_msg ; err <- mkEqErr_help dflags ctxt report ct' Nothing ty1 ty2 @@ -843,15 +851,27 @@ suppressGroup mk_err ctxt cts ; traceTc "Suppressing errors for" (ppr cts) ; mapM_ (addDeferredBinding ctxt err) cts } -maybeReportHoleError :: ReportErrCtxt -> Ct -> ErrMsg -> TcM () +maybeReportHoleError :: ReportErrCtxt -> Hole -> ErrMsg -> TcM () +maybeReportHoleError ctxt hole err + | isOutOfScopeHole hole + -- Always report an error for out-of-scope variables + -- Unless -fdefer-out-of-scope-variables is on, + -- in which case the messages are discarded. + -- See #12170, #12406 + = -- If deferring, report a warning only if -Wout-of-scope-variables is on + case cec_out_of_scope_holes ctxt of + HoleError -> reportError err + HoleWarn -> + reportWarning (Reason Opt_WarnDeferredOutOfScopeVariables) err + HoleDefer -> return () + -- Unlike maybeReportError, these "hole" errors are -- /not/ suppressed by cec_suppress. We want to see them! -maybeReportHoleError ctxt ct err +maybeReportHoleError ctxt (Hole { hole_sort = TypeHole }) err -- When -XPartialTypeSignatures is on, warnings (instead of errors) are -- generated for holes in partial type signatures. -- Unless -fwarn-partial-type-signatures is not on, -- in which case the messages are discarded. - | isTypeHoleCt ct = -- For partial type signatures, generate warnings only, and do that -- only if -fwarn-partial-type-signatures is on case cec_type_holes ctxt of @@ -859,22 +879,12 @@ maybeReportHoleError ctxt ct err HoleWarn -> reportWarning (Reason Opt_WarnPartialTypeSignatures) err HoleDefer -> return () - -- Always report an error for out-of-scope variables - -- Unless -fdefer-out-of-scope-variables is on, - -- in which case the messages are discarded. - -- See #12170, #12406 - | isOutOfScopeCt ct - = -- If deferring, report a warning only if -Wout-of-scope-variables is on - case cec_out_of_scope_holes ctxt of - HoleError -> reportError err - HoleWarn -> - reportWarning (Reason Opt_WarnDeferredOutOfScopeVariables) err - HoleDefer -> return () - +maybeReportHoleError ctxt hole@(Hole { hole_sort = ExprHole _ }) err -- Otherwise this is a typed hole in an expression, - -- but not for an out-of-scope variable - | otherwise + -- but not for an out-of-scope variable (because that goes through a + -- different function) = -- If deferring, report a warning only if -Wtyped-holes is on + ASSERT( not (isOutOfScopeHole hole) ) case cec_expr_holes ctxt of HoleError -> reportError err HoleWarn -> reportWarning (Reason Opt_WarnTypedHoles) err @@ -899,10 +909,7 @@ addDeferredBinding ctxt err ct , CtWanted { ctev_pred = pred, ctev_dest = dest } <- ctEvidence ct -- Only add deferred bindings for Wanted constraints = do { dflags <- getDynFlags - ; let err_msg = pprLocErrMsg err - err_fs = mkFastString $ showSDoc dflags $ - err_msg $$ text "(deferred type error)" - err_tm = evDelayedError pred err_fs + ; let err_tm = mkErrorTerm dflags pred err ev_binds_var = cec_binds ctxt ; case dest of @@ -917,11 +924,27 @@ addDeferredBinding ctxt err ct | otherwise -- Do not set any evidence for Given/Derived = return () -maybeAddDeferredHoleBinding :: ReportErrCtxt -> ErrMsg -> Ct -> TcM () -maybeAddDeferredHoleBinding ctxt err ct - | isExprHoleCt ct - = addDeferredBinding ctxt err ct -- Only add bindings for holes in expressions - | otherwise -- not for holes in partial type signatures +mkErrorTerm :: DynFlags -> Type -- of the error term + -> ErrMsg -> EvTerm +mkErrorTerm dflags ty err = evDelayedError ty err_fs + where + err_msg = pprLocErrMsg err + err_fs = mkFastString $ showSDoc dflags $ + err_msg $$ text "(deferred type error)" +maybeAddDeferredHoleBinding :: ReportErrCtxt -> ErrMsg -> Hole -> TcM () +maybeAddDeferredHoleBinding ctxt err (Hole { hole_sort = ExprHole ev_id }) +-- Only add bindings for holes in expressions +-- not for holes in partial type signatures +-- cf. addDeferredBinding + | deferringAnyBindings ctxt + = do { dflags <- getDynFlags + ; let err_tm = mkErrorTerm dflags (idType ev_id) err + -- NB: idType ev_id, not hole_ty. hole_ty might be rewritten. + -- See Note [Holes] in GHC.Tc.Types.Constraint + ; addTcEvBind (cec_binds ctxt) $ mkWantedEvBind ev_id err_tm } + | otherwise + = return () +maybeAddDeferredHoleBinding _ _ (Hole { hole_sort = TypeHole }) = return () tryReporters :: ReportErrCtxt -> [ReporterSpec] -> [Ct] -> TcM (ReportErrCtxt, [Ct]) @@ -961,7 +984,6 @@ tryReporter ctxt (str, keep_me, suppress_after, reporter) cts where (yeses, nos) = partition (\ct -> keep_me ct (classifyPredType (ctPred ct))) cts - pprArising :: CtOrigin -> SDoc -- Used for the main, top-level error message -- We've done special processing for TypeEq, KindEq, Given @@ -1104,15 +1126,16 @@ mkIrredErr ctxt cts ; let orig = ctOrigin ct1 msg = couldNotDeduce (getUserGivens ctxt) (map ctPred cts, orig) ; mkErrorMsgFromCt ctxt ct1 $ - important msg `mappend` relevant_bindings binds_msg } + important msg `mappend` mk_relevant_bindings binds_msg } where (ct1:_) = cts ---------------- -mkHoleError :: [Ct] -> ReportErrCtxt -> Ct -> TcM ErrMsg -mkHoleError tidy_simples ctxt ct@(CHoleCan { cc_occ = occ, cc_hole = hole_sort }) - | isOutOfScopeCt ct -- Out of scope variables, like 'a', where 'a' isn't bound - -- Suggest possible in-scope variables in the message +mkHoleError :: [Ct] -> ReportErrCtxt -> Hole -> TcM ErrMsg +mkHoleError _tidy_simples _ctxt hole@(Hole { hole_occ = occ + , hole_ty = hole_ty + , hole_loc = ct_loc }) + | isOutOfScopeHole hole = do { dflags <- getDynFlags ; rdr_env <- getGlobalRdrEnv ; imp_info <- getImports @@ -1122,48 +1145,52 @@ mkHoleError tidy_simples ctxt ct@(CHoleCan { cc_occ = occ, cc_hole = hole_sort } errDoc [out_of_scope_msg] [] [unknownNameSuggestions dflags hpt curr_mod rdr_env (tcl_rdr lcl_env) imp_info (mkRdrUnqual occ)] } + where + herald | isDataOcc occ = text "Data constructor not in scope:" + | otherwise = text "Variable not in scope:" - | otherwise -- Explicit holes, like "_" or "_f" - = do { (ctxt, binds_msg, ct) <- relevantBindings False ctxt ct + out_of_scope_msg -- Print v :: ty only if the type has structure + | boring_type = hang herald 2 (ppr occ) + | otherwise = hang herald 2 (pp_occ_with_type occ hole_ty) + + lcl_env = ctLocEnv ct_loc + boring_type = isTyVarTy hole_ty + + -- general case: not an out-of-scope error +mkHoleError tidy_simples ctxt hole@(Hole { hole_occ = occ + , hole_ty = hole_ty + , hole_sort = sort + , hole_loc = ct_loc }) + = do { (ctxt, binds_msg) + <- relevant_bindings False ctxt lcl_env (tyCoVarsOfType hole_ty) -- The 'False' means "don't filter the bindings"; see Trac #8191 ; show_hole_constraints <- goptM Opt_ShowHoleConstraints ; let constraints_msg - | isExprHoleCt ct, show_hole_constraints + | ExprHole _ <- sort, show_hole_constraints = givenConstraintsMsg ctxt | otherwise = empty ; show_valid_hole_fits <- goptM Opt_ShowValidHoleFits ; (ctxt, sub_msg) <- if show_valid_hole_fits - then validHoleFits ctxt tidy_simples ct + then validHoleFits ctxt tidy_simples hole else return (ctxt, empty) - ; mkErrorMsgFromCt ctxt ct $ + ; mkErrorReport ctxt lcl_env $ important hole_msg `mappend` - relevant_bindings (binds_msg $$ constraints_msg) `mappend` + mk_relevant_bindings (binds_msg $$ constraints_msg) `mappend` valid_hole_fits sub_msg } where - ct_loc = ctLoc ct lcl_env = ctLocEnv ct_loc - hole_ty = ctEvPred (ctEvidence ct) hole_kind = tcTypeKind hole_ty tyvars = tyCoVarsOfTypeList hole_ty - boring_type = isTyVarTy hole_ty - - out_of_scope_msg -- Print v :: ty only if the type has structure - | boring_type = hang herald 2 (ppr occ) - | otherwise = hang herald 2 pp_with_type - pp_with_type = hang (pprPrefixOcc occ) 2 (dcolon <+> pprType hole_ty) - herald | isDataOcc occ = text "Data constructor not in scope:" - | otherwise = text "Variable not in scope:" - - hole_msg = case hole_sort of - ExprHole -> vcat [ hang (text "Found hole:") - 2 pp_with_type - , tyvars_msg, expr_hole_hint ] + hole_msg = case sort of + ExprHole _ -> vcat [ hang (text "Found hole:") + 2 (pp_occ_with_type occ hole_ty) + , tyvars_msg, expr_hole_hint ] TypeHole -> vcat [ hang (text "Found type wildcard" <+> quotes (ppr occ)) 2 (text "standing for" <+> quotes pp_hole_type_with_kind) , tyvars_msg, type_hole_hint ] @@ -1207,21 +1234,22 @@ mkHoleError tidy_simples ctxt ct@(CHoleCan { cc_occ = occ, cc_hole = hole_sort } = ppWhenOption sdocPrintExplicitCoercions $ quotes (ppr tv) <+> text "is a coercion variable" -mkHoleError _ _ ct = pprPanic "mkHoleError" (ppr ct) +pp_occ_with_type :: OccName -> Type -> SDoc +pp_occ_with_type occ hole_ty = hang (pprPrefixOcc occ) 2 (dcolon <+> pprType hole_ty) -- We unwrap the ReportErrCtxt here, to avoid introducing a loop in module -- imports validHoleFits :: ReportErrCtxt -- The context we're in, i.e. the -- implications and the tidy environment -> [Ct] -- Unsolved simple constraints - -> Ct -- The hole constraint. + -> Hole -- The hole -> TcM (ReportErrCtxt, SDoc) -- We return the new context -- with a possibly updated -- tidy environment, and -- the message. validHoleFits ctxt@(CEC {cec_encl = implics - , cec_tidy = lcl_env}) simps ct - = do { (tidy_env, msg) <- findValidHoleFits lcl_env implics simps ct + , cec_tidy = lcl_env}) simps hole + = do { (tidy_env, msg) <- findValidHoleFits lcl_env implics simps hole ; return (ctxt {cec_tidy = tidy_env}, msg) } -- See Note [Constraints include ...] @@ -1255,7 +1283,7 @@ mkIPErr ctxt cts = couldNotDeduce givens (preds, orig) ; mkErrorMsgFromCt ctxt ct1 $ - important msg `mappend` relevant_bindings binds_msg } + important msg `mappend` mk_relevant_bindings binds_msg } where (ct1:_) = cts @@ -1337,7 +1365,7 @@ mkEqErr1 ctxt ct -- Wanted or derived; ; dflags <- getDynFlags ; traceTc "mkEqErr1" (ppr ct $$ pprCtOrigin (ctOrigin ct) $$ ppr keep_going) ; let report = mconcat [important wanted_msg, important coercible_msg, - relevant_bindings binds_msg] + mk_relevant_bindings binds_msg] ; if keep_going then mkEqErr_help dflags ctxt report ct is_oriented ty1 ty2 else mkErrorMsgFromCt ctxt ct report } @@ -1513,7 +1541,7 @@ mkTyVarEqErr' dflags ctxt report ct oriented tv1 ty2 filter isTyVar $ fvVarList $ tyCoFVsOfType ty1 `unionFV` tyCoFVsOfType ty2 - extra3 = relevant_bindings $ + extra3 = mk_relevant_bindings $ ppWhen (not (null interesting_tyvars)) $ hang (text "Type variable kinds:") 2 $ vcat (map (tyvar_binding . tidyTyCoVarOcc (cec_tidy ctxt)) @@ -2819,27 +2847,45 @@ relevantBindings :: Bool -- True <=> filter by tyvar; False <=> no filtering -> TcM (ReportErrCtxt, SDoc, Ct) -- Also returns the zonked and tidied CtOrigin of the constraint relevantBindings want_filtering ctxt ct - = do { dflags <- getDynFlags + = do { traceTc "relevantBindings" (ppr ct) ; (env1, tidy_orig) <- zonkTidyOrigin (cec_tidy ctxt) (ctLocOrigin loc) - ; let ct_tvs = tyCoVarsOfCt ct `unionVarSet` extra_tvs -- For *kind* errors, report the relevant bindings of the -- enclosing *type* equality, because that's more useful for the programmer - extra_tvs = case tidy_orig of + ; let extra_tvs = case tidy_orig of KindEqOrigin t1 m_t2 _ _ -> tyCoVarsOfTypes $ t1 : maybeToList m_t2 _ -> emptyVarSet - ; traceTc "relevantBindings" $ - vcat [ ppr ct - , pprCtOrigin (ctLocOrigin loc) - , ppr ct_tvs + ct_fvs = tyCoVarsOfCt ct `unionVarSet` extra_tvs + + -- Put a zonked, tidied CtOrigin into the Ct + loc' = setCtLocOrigin loc tidy_orig + ct' = setCtLoc ct loc' + ctxt1 = ctxt { cec_tidy = env1 } + + ; (ctxt2, doc) <- relevant_bindings want_filtering ctxt1 lcl_env ct_fvs + ; return (ctxt2, doc, ct') } + where + loc = ctLoc ct + lcl_env = ctLocEnv loc + +-- slightly more general version, to work also with holes +relevant_bindings :: Bool + -> ReportErrCtxt + -> TcLclEnv + -> TyCoVarSet + -> TcM (ReportErrCtxt, SDoc) +relevant_bindings want_filtering ctxt lcl_env ct_tvs + = do { dflags <- getDynFlags + ; traceTc "relevant_bindings" $ + vcat [ ppr ct_tvs , pprWithCommas id [ ppr id <+> dcolon <+> ppr (idType id) | TcIdBndr id _ <- tcl_bndrs lcl_env ] , pprWithCommas id [ ppr id | TcIdBndr_ExpType id _ _ <- tcl_bndrs lcl_env ] ] ; (tidy_env', docs, discards) - <- go dflags env1 ct_tvs (maxRelevantBinds dflags) + <- go dflags (cec_tidy ctxt) (maxRelevantBinds dflags) emptyVarSet [] False (removeBindingShadowing $ tcl_bndrs lcl_env) -- tcl_bndrs has the innermost bindings first, @@ -2849,17 +2895,10 @@ relevantBindings want_filtering ctxt ct hang (text "Relevant bindings include") 2 (vcat docs $$ ppWhen discards discardMsg) - -- Put a zonked, tidied CtOrigin into the Ct - loc' = setCtLocOrigin loc tidy_orig - ct' = setCtLoc ct loc' ctxt' = ctxt { cec_tidy = tidy_env' } - ; return (ctxt', doc, ct') } + ; return (ctxt', doc) } where - ev = ctEvidence ct - loc = ctEvLoc ev - lcl_env = ctLocEnv loc - run_out :: Maybe Int -> Bool run_out Nothing = False run_out (Just n) = n <= 0 @@ -2868,14 +2907,14 @@ relevantBindings want_filtering ctxt ct dec_max = fmap (\n -> n - 1) - go :: DynFlags -> TidyEnv -> TcTyVarSet -> Maybe Int -> TcTyVarSet -> [SDoc] + go :: DynFlags -> TidyEnv -> Maybe Int -> TcTyVarSet -> [SDoc] -> Bool -- True <=> some filtered out due to lack of fuel -> [TcBinder] -> TcM (TidyEnv, [SDoc], Bool) -- The bool says if we filtered any out -- because of lack of fuel - go _ tidy_env _ _ _ docs discards [] + go _ tidy_env _ _ docs discards [] = return (tidy_env, reverse docs, discards) - go dflags tidy_env ct_tvs n_left tvs_seen docs discards (tc_bndr : tc_bndrs) + go dflags tidy_env n_left tvs_seen docs discards (tc_bndr : tc_bndrs) = case tc_bndr of TcTvBndr {} -> discard_it TcIdBndr id top_lvl -> go2 (idName id) (idType id) top_lvl @@ -2891,7 +2930,7 @@ relevantBindings want_filtering ctxt ct Nothing -> discard_it -- No info; discard } where - discard_it = go dflags tidy_env ct_tvs n_left tvs_seen docs + discard_it = go dflags tidy_env n_left tvs_seen docs discards tc_bndrs go2 id_name id_type top_lvl = do { (tidy_env', tidy_ty) <- zonkTidyTcType tidy_env id_type @@ -2916,12 +2955,12 @@ relevantBindings want_filtering ctxt ct else if run_out n_left && id_tvs `subVarSet` tvs_seen -- We've run out of n_left fuel and this binding only -- mentions already-seen type variables, so discard it - then go dflags tidy_env ct_tvs n_left tvs_seen docs + then go dflags tidy_env n_left tvs_seen docs True -- Record that we have now discarded something tc_bndrs -- Keep this binding, decrement fuel - else go dflags tidy_env' ct_tvs (dec_max n_left) new_seen + else go dflags tidy_env' (dec_max n_left) new_seen (doc:docs) discards tc_bndrs } ===================================== compiler/GHC/Tc/Errors/Hole.hs ===================================== @@ -2,17 +2,9 @@ {-# LANGUAGE ExistentialQuantification #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} module GHC.Tc.Errors.Hole - ( findValidHoleFits, tcFilterHoleFits - , tcCheckHoleFit, tcSubsumes - , withoutUnification - , fromPureHFPlugin - -- Re-exports for convenience - , hfIsLcl - , pprHoleFit, debugHoleFitDispConfig + ( findValidHoleFits -- Re-exported from GHC.Tc.Errors.Hole.FitTypes - , TypedHole (..), HoleFit (..), HoleFitCandidate (..) - , CandPlugin, FitPlugin , HoleFitPlugin (..), HoleFitPluginR (..) ) where @@ -121,7 +113,7 @@ The hole in `f` would generate the message: Valid hole fits are found by checking top level identifiers and local bindings in scope for whether their type can be instantiated to the the type of the hole. Additionally, we also need to check whether all relevant constraints are solved -by choosing an identifier of that type as well, see Note [Relevant Constraints] +by choosing an identifier of that type as well, see Note [Relevant constraints] Since checking for subsumption results in the side-effect of type variables being unified by the simplifier, we need to take care to restore them after @@ -143,9 +135,13 @@ that the quantified type variables would take if that fit is used, like If -XTypeApplications is enabled, this can even be copied verbatim as a replacement for the hole. - -Note [Nested implications] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Checking hole fits] +~~~~~~~~~~~~~~~~~~~~~~~~~ +If we have a hole of type hole_ty, we want to know whether a variable +of type ty is a valid fit for the whole. This is a subsumption check: +we wish to know whether ty <: hole_ty. But, of course, the check +must take into account any givens and relevant constraints. +(See also Note [Relevant constraints]). For the simplifier to be able to use any givens present in the enclosing implications to solve relevant constraints, we nest the wanted subsumption @@ -156,10 +152,7 @@ As an example, let's look at the following code: f :: Show a => a -> String f x = show _ -The hole will result in the hole constraint: - - [WD] __a1ph {0}:: a0_a1pd[tau:2] (CHoleCan: ExprHole(_)) - +Suppose the hole is assigned type a0_a1pd[tau:2]. Here the nested implications are just one level deep, namely: [Implic { @@ -170,36 +163,25 @@ Here the nested implications are just one level deep, namely: Given = $dShow_a1pc :: Show a_a1pa[sk:2] Wanted = WC {wc_simple = - [WD] __a1ph {0}:: a_a1pd[tau:2] (CHoleCan: ExprHole(_)) - [WD] $dShow_a1pe {0}:: Show a_a1pd[tau:2] (CDictCan(psc))} + [WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CDictCan(psc))} Binds = EvBindsVar Needed inner = [] Needed outer = [] the type signature for: f :: forall a. Show a => a -> String }] -As we can see, the givens say that the information about the skolem -`a_a1pa[sk:2]` fulfills the Show constraint. - -The simples are: +As we can see, the givens say that the skolem +`a_a1pa[sk:2]` fulfills the Show constraint, and that we must prove +the [W] Show a0_a1pd[tau:2] constraint -- that is, whatever fills the +hole must have a Show instance. - [[WD] __a1ph {0}:: a0_a1pd[tau:2] (CHoleCan: ExprHole(_)), - [WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CNonCanonical)] - -I.e. the hole `a0_a1pd[tau:2]` and the constraint that the type of the hole must -fulfill `Show a0_a1pd[tau:2])`. - -So when we run the check, we need to make sure that the - - [WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CNonCanonical) - -Constraint gets solved. When we now check for whether `x :: a0_a1pd[tau:2]` fits -the hole in `tcCheckHoleFit`, the call to `tcSubType` will end up writing the -meta type variable `a0_a1pd[tau:2] := a_a1pa[sk:2]`. By wrapping the wanted -constraints needed by tcSubType_NC and the relevant constraints (see -Note [Relevant Constraints] for more details) in the nested implications, we -can pass the information in the givens along to the simplifier. For our example, -we end up needing to check whether the following constraints are soluble. +When we now check whether `x :: a_a1pa[sk:2]` fits the hole in +`tcCheckHoleFit`, the call to `tcSubType` will end up unifying the meta type +variable `a0_a1pd[tau:2] := a_a1pa[sk:2]`. By wrapping the wanted constraints +needed by tcSubType_NC and the relevant constraints (see Note [Relevant +Constraints] for more details) in the nested implications, we can pass the +information in the givens along to the simplifier. For our example, we end up +needing to check whether the following constraints are soluble. WC {wc_impl = Implic { @@ -223,10 +205,12 @@ with a final WC of WC {}, confirming x :: a0_a1pd[tau:2] as a match. To avoid side-effects on the nested implications, we create a new EvBindsVar so that any changes to the ev binds during a check remains localised to that check. - +In addition, we call withoutUnification to reset any unified metavariables; this +call is actually done outside tcCheckHoleFit so that the results can be formatted +for the user before resetting variables. Note [Valid refinement hole fits include ...] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When the `-frefinement-level-hole-fits=N` flag is given, we additionally look for "valid refinement hole fits"", i.e. valid hole fits with up to N additional holes in them. @@ -337,10 +321,8 @@ In the free monad example above, this is demonstrated with be applied to an expression of type `a -> Free f b` in order to match. If -XScopedTypeVariables is enabled, this hole fit can even be copied verbatim. - -Note [Relevant Constraints] -~~~~~~~~~~~~~~~~~~~ - +Note [Relevant constraints] +~~~~~~~~~~~~~~~~~~~~~~~~~~~ As highlighted by #14273, we need to check any relevant constraints as well as checking for subsumption. Relevant constraints are the simple constraints whose free unification variables are mentioned in the type of the hole. @@ -351,10 +333,9 @@ as is the case in f :: String f = show _ -Where the simples will be : +Here, the hole is given type a0_a1kv[tau:1]. Then, the emitted constraint is: - [[WD] __a1kz {0}:: a0_a1kv[tau:1] (CHoleCan: ExprHole(_)), - [WD] $dShow_a1kw {0}:: Show a0_a1kv[tau:1] (CNonCanonical)] + [WD] $dShow_a1kw {0}:: Show a0_a1kv[tau:1] (CNonCanonical) However, when there are multiple holes, we need to be more careful. As an example, Let's take a look at the following code: @@ -362,29 +343,24 @@ example, Let's take a look at the following code: f :: Show a => a -> String f x = show (_b (show _a)) -Here there are two holes, `_a` and `_b`, and the simple constraints passed to +Here there are two holes, `_a` and `_b`. Suppose _a :: a0_a1pd[tau:2] and +_b :: a1_a1po[tau:2]. Then, the simple constraints passed to findValidHoleFits are: - [[WD] _a_a1pi {0}:: String - -> a0_a1pd[tau:2] (CHoleCan: ExprHole(_b)), - [WD] _b_a1ps {0}:: a1_a1po[tau:2] (CHoleCan: ExprHole(_a)), - [WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CNonCanonical), + [[WD] $dShow_a1pe {0}:: Show a0_a1pd[tau:2] (CNonCanonical), [WD] $dShow_a1pp {0}:: Show a1_a1po[tau:2] (CNonCanonical)] - -Here we have the two hole constraints for `_a` and `_b`, but also additional -constraints that these holes must fulfill. When we are looking for a match for -the hole `_a`, we filter the simple constraints to the "Relevant constraints", -by throwing out all hole constraints and any constraints which do not mention -a variable mentioned in the type of the hole. For hole `_a`, we will then -only require that the `$dShow_a1pp` constraint is solved, since that is -the only non-hole constraint that mentions any free type variables mentioned in -the hole constraint for `_a`, namely `a_a1pd[tau:2]` , and similarly for the -hole `_b` we only require that the `$dShow_a1pe` constraint is solved. +When we are looking for a match for the hole `_a`, we filter the simple +constraints to the "Relevant constraints", by throwing out any constraints +which do not mention a variable mentioned in the type of the hole. For hole +`_a`, we will then only require that the `$dShow_a1pe` constraint is solved, +since that is the only constraint that mentions any free type variables +mentioned in the hole constraint for `_a`, namely `a_a1pd[tau:2]`, and +similarly for the hole `_b` we only require that the `$dShow_a1pe` constraint +is solved. Note [Leaking errors] -~~~~~~~~~~~~~~~~~~~ - +~~~~~~~~~~~~~~~~~~~~~ When considering candidates, GHC believes that we're checking for validity in actual source. However, As evidenced by #15321, #15007 and #15202, this can cause bewildering error messages. The solution here is simple: if a candidate @@ -393,17 +369,12 @@ is discarded. -} - data HoleFitDispConfig = HFDC { showWrap :: Bool , showWrapVars :: Bool , showType :: Bool , showProv :: Bool , showMatches :: Bool } -debugHoleFitDispConfig :: HoleFitDispConfig -debugHoleFitDispConfig = HFDC True True True False False - - -- We read the various -no-show-*-of-hole-fits flags -- and set the display config accordingly. getHoleFitDispConfig :: TcM HoleFitDispConfig @@ -516,13 +487,12 @@ pprHoleFit (HFDC sWrp sWrpVars sTy sProv sMs) (HoleFit {..}) = GreHFCand gre -> pprNameProvenance gre _ -> text "bound at" <+> ppr (getSrcLoc name) -getLocalBindings :: TidyEnv -> Ct -> TcM [Id] -getLocalBindings tidy_orig ct - = do { (env1, _) <- zonkTidyOrigin tidy_orig (ctLocOrigin loc) +getLocalBindings :: TidyEnv -> CtLoc -> TcM [Id] +getLocalBindings tidy_orig ct_loc + = do { (env1, _) <- zonkTidyOrigin tidy_orig (ctLocOrigin ct_loc) ; go env1 [] (removeBindingShadowing $ tcl_bndrs lcl_env) } where - loc = ctEvLoc (ctEvidence ct) - lcl_env = ctLocEnv loc + lcl_env = ctLocEnv ct_loc go :: TidyEnv -> [Id] -> [TcBinder] -> TcM [Id] go _ sofar [] = return (reverse sofar) @@ -542,11 +512,13 @@ findValidHoleFits :: TidyEnv -- ^ The tidy_env for zonking -> [Ct] -- ^ The unsolved simple constraints in the implication for -- the hole. - -> Ct -- ^ The hole constraint itself + -> Hole -> TcM (TidyEnv, SDoc) -findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = +findValidHoleFits tidy_env implics simples h@(Hole { hole_sort = ExprHole _ + , hole_loc = ct_loc + , hole_ty = hole_ty }) = do { rdr_env <- getGlobalRdrEnv - ; lclBinds <- getLocalBindings tidy_env ct + ; lclBinds <- getLocalBindings tidy_env ct_loc ; maxVSubs <- maxValidHoleFits <$> getDynFlags ; hfdc <- getHoleFitDispConfig ; sortingAlg <- getSortingAlg @@ -554,7 +526,9 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = ; hfPlugs <- tcg_hf_plugins <$> getGblEnv ; let findVLimit = if sortingAlg > NoSorting then Nothing else maxVSubs refLevel = refLevelHoleFits dflags - hole = TyH (listToBag relevantCts) implics (Just ct) + hole = TypedHole { th_relevant_cts = listToBag relevantCts + , th_implics = implics + , th_hole = Just h } (candidatePlugins, fitPlugins) = unzip $ map (\p-> ((candPlugin p) hole, (fitPlugin p) hole)) hfPlugs ; traceTc "findingValidHoleFitsFor { " $ ppr hole @@ -625,11 +599,9 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = where -- We extract the type, the tcLevel and the types free variables -- from from the constraint. - hole_ty :: TcPredType - hole_ty = ctPred ct hole_fvs :: FV hole_fvs = tyCoFVsOfType hole_ty - hole_lvl = ctLocLevel $ ctEvLoc $ ctEvidence ct + hole_lvl = ctLocLevel ct_loc -- BuiltInSyntax names like (:) and [] builtIns :: [Name] @@ -668,7 +640,7 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = <*> sortByGraph (sort gblFits) where (lclFits, gblFits) = span hfIsLcl subs - -- See Note [Relevant Constraints] + -- See Note [Relevant constraints] relevantCts :: [Ct] relevantCts = if isEmptyVarSet (fvVarSet hole_fvs) then [] else filter isRelevant simples @@ -684,7 +656,6 @@ findValidHoleFits tidy_env implics simples ct | isExprHoleCt ct = -- trying to find hole fits for many holes at once. isRelevant ct = not (isEmptyVarSet (ctFreeVarSet ct)) && anyFVMentioned ct - && not (isHoleCt ct) -- We zonk the hole fits so that the output aligns with the rest -- of the typed hole error message output. @@ -761,7 +732,7 @@ tcFilterHoleFits :: Maybe Int -- ^ We return whether or not we stopped due to hitting the limit -- and the fits we found. tcFilterHoleFits (Just 0) _ _ _ = return (False, []) -- Stop right away on 0 -tcFilterHoleFits limit (TyH {..}) ht@(hole_ty, _) candidates = +tcFilterHoleFits limit typed_hole ht@(hole_ty, _) candidates = do { traceTc "checkingFitsFor {" $ ppr hole_ty ; (discards, subs) <- go [] emptyVarSet limit ht candidates ; traceTc "checkingFitsFor }" empty @@ -895,8 +866,7 @@ tcFilterHoleFits limit (TyH {..}) ht@(hole_ty, _) candidates = else return Nothing } else return Nothing } where fvs = mkFVs ref_vars `unionFV` hole_fvs `unionFV` tyCoFVsOfType ty - hole = TyH tyHRelevantCts tyHImplics Nothing - + hole = typed_hole { th_hole = Nothing } subsDiscardMsg :: SDoc subsDiscardMsg = @@ -925,7 +895,8 @@ withoutUnification free_vars action = -- Reset any mutated free variables ; mapM_ restore flexis ; return result } - where restore = flip writeTcRef Flexi . metaTyVarRef + where restore tv = do { traceTc "withoutUnification: restore flexi" (ppr tv) + ; writeTcRef (metaTyVarRef tv) Flexi } fuvs = fvVarList free_vars -- | Reports whether first type (ty_a) subsumes the second type (ty_b), @@ -933,14 +904,14 @@ withoutUnification free_vars action = -- ty_a, i.e. `tcSubsumes a b == True` if b is a subtype of a. tcSubsumes :: TcSigmaType -> TcSigmaType -> TcM Bool tcSubsumes ty_a ty_b = fst <$> tcCheckHoleFit dummyHole ty_a ty_b - where dummyHole = TyH emptyBag [] Nothing + where dummyHole = TypedHole { th_relevant_cts = emptyBag + , th_implics = [] + , th_hole = Nothing } -- | A tcSubsumes which takes into account relevant constraints, to fix trac -- #14273. This makes sure that when checking whether a type fits the hole, -- the type has to be subsumed by type of the hole as well as fulfill all -- constraints on the type of the hole. --- Note: The simplifier may perform unification, so make sure to restore any --- free type variables to avoid side-effects. tcCheckHoleFit :: TypedHole -- ^ The hole to check against -> TcSigmaType -- ^ The type to check against (possibly modified, e.g. refined) @@ -949,56 +920,48 @@ tcCheckHoleFit :: TypedHole -- ^ The hole to check against -- ^ Whether it was a match, and the wrapper from hole_ty to ty. tcCheckHoleFit _ hole_ty ty | hole_ty `eqType` ty = return (True, idHsWrapper) -tcCheckHoleFit (TyH {..}) hole_ty ty = discardErrs $ +tcCheckHoleFit (TypedHole {..}) hole_ty ty = discardErrs $ do { -- We wrap the subtype constraint in the implications to pass along the -- givens, and so we must ensure that any nested implications and skolems -- end up with the correct level. The implications are ordered so that -- the innermost (the one with the highest level) is first, so it -- suffices to get the level of the first one (or the current level, if -- there are no implications involved). - innermost_lvl <- case tyHImplics of + innermost_lvl <- case th_implics of [] -> getTcLevel -- imp is the innermost implication (imp:_) -> return (ic_tclvl imp) - ; (wrp, wanted) <- setTcLevel innermost_lvl $ captureConstraints $ - tcSubType_NC ExprSigCtxt ty hole_ty + ; (wrap, wanted) <- setTcLevel innermost_lvl $ captureConstraints $ + tcSubType_NC ExprSigCtxt ty hole_ty ; traceTc "Checking hole fit {" empty ; traceTc "wanteds are: " $ ppr wanted - ; if isEmptyWC wanted && isEmptyBag tyHRelevantCts - then traceTc "}" empty >> return (True, wrp) + ; if isEmptyWC wanted && isEmptyBag th_relevant_cts + then do { traceTc "}" empty + ; return (True, wrap) } else do { fresh_binds <- newTcEvBinds -- The relevant constraints may contain HoleDests, so we must -- take care to clone them as well (to avoid #15370). - ; cloned_relevants <- mapBagM cloneWanted tyHRelevantCts + ; cloned_relevants <- mapBagM cloneWanted th_relevant_cts -- We wrap the WC in the nested implications, see - -- Note [Nested Implications] - ; let outermost_first = reverse tyHImplics - setWC = setWCAndBinds fresh_binds + -- Note [Checking hole fits] + ; let outermost_first = reverse th_implics -- We add the cloned relevants to the wanteds generated by - -- the call to tcSubType_NC, see Note [Relevant Constraints] + -- the call to tcSubType_NC, see Note [Relevant constraints] -- There's no need to clone the wanteds, because they are -- freshly generated by `tcSubtype_NC`. w_rel_cts = addSimples wanted cloned_relevants - w_givens = foldr setWC w_rel_cts outermost_first - ; traceTc "w_givens are: " $ ppr w_givens - ; rem <- runTcSDeriveds $ simpl_top w_givens + final_wc = foldr (setWCAndBinds fresh_binds) w_rel_cts outermost_first + ; traceTc "final_wc is: " $ ppr final_wc + ; rem <- runTcSDeriveds $ simpl_top final_wc -- We don't want any insoluble or simple constraints left, but -- solved implications are ok (and necessary for e.g. undefined) ; traceTc "rems was:" $ ppr rem ; traceTc "}" empty - ; return (isSolvedWC rem, wrp) } } + ; return (isSolvedWC rem, wrap) } } where setWCAndBinds :: EvBindsVar -- Fresh ev binds var. -> Implication -- The implication to put WC in. -> WantedConstraints -- The WC constraints to put implic. -> WantedConstraints -- The new constraints. setWCAndBinds binds imp wc - = WC { wc_simple = emptyBag - , wc_impl = unitBag $ imp { ic_wanted = wc , ic_binds = binds } } - --- | Maps a plugin that needs no state to one with an empty one. -fromPureHFPlugin :: HoleFitPlugin -> HoleFitPluginR -fromPureHFPlugin plug = - HoleFitPluginR { hfPluginInit = newTcRef () - , hfPluginRun = const plug - , hfPluginStop = const $ return () } + = mkImplicWC $ unitBag $ imp { ic_wanted = wc , ic_binds = binds } ===================================== compiler/GHC/Tc/Errors/Hole.hs-boot ===================================== @@ -5,9 +5,9 @@ module GHC.Tc.Errors.Hole where import GHC.Tc.Types ( TcM ) -import GHC.Tc.Types.Constraint ( Ct, Implication ) +import GHC.Tc.Types.Constraint ( Ct, Hole, Implication ) import GHC.Utils.Outputable ( SDoc ) import GHC.Types.Var.Env ( TidyEnv ) -findValidHoleFits :: TidyEnv -> [Implication] -> [Ct] -> Ct +findValidHoleFits :: TidyEnv -> [Implication] -> [Ct] -> Hole -> TcM (TidyEnv, SDoc) ===================================== compiler/GHC/Tc/Errors/Hole/FitTypes.hs ===================================== @@ -21,20 +21,21 @@ import GHC.Types.Name import Data.Function ( on ) -data TypedHole = TyH { tyHRelevantCts :: Cts - -- ^ Any relevant Cts to the hole - , tyHImplics :: [Implication] - -- ^ The nested implications of the hole with the - -- innermost implication first. - , tyHCt :: Maybe Ct - -- ^ The hole constraint itself, if available. - } +data TypedHole = TypedHole { th_relevant_cts :: Cts + -- ^ Any relevant Cts to the hole + , th_implics :: [Implication] + -- ^ The nested implications of the hole with the + -- innermost implication first. + , th_hole :: Maybe Hole + -- ^ The hole itself, if available. Only for debugging. + } instance Outputable TypedHole where - ppr (TyH rels implics ct) + ppr (TypedHole { th_relevant_cts = rels + , th_implics = implics + , th_hole = hole }) = hang (text "TypedHole") 2 - (ppr rels $+$ ppr implics $+$ ppr ct) - + (ppr rels $+$ ppr implics $+$ ppr hole) -- | HoleFitCandidates are passed to hole fit plugins and then -- checked whether they fit a given typed-hole. @@ -51,9 +52,6 @@ pprHoleFitCand (IdHFCand cid) = text "Id HFC: " <> ppr cid pprHoleFitCand (NameHFCand cname) = text "Name HFC: " <> ppr cname pprHoleFitCand (GreHFCand cgre) = text "Gre HFC: " <> ppr cgre - - - instance NamedThing HoleFitCandidate where getName hfc = case hfc of IdHFCand cid -> idName cid ===================================== compiler/GHC/Tc/Gen/Expr.hs ===================================== @@ -36,7 +36,6 @@ import {-# SOURCE #-} GHC.Tc.Gen.Splice( tcSpliceExpr, tcTypedBracket, tcUntyp import GHC.Builtin.Names.TH( liftStringName, liftName ) import GHC.Hs -import GHC.Tc.Types.Constraint ( HoleSort(..) ) import GHC.Tc.Utils.Zonk import GHC.Tc.Utils.Monad import GHC.Tc.Utils.Unify @@ -1405,22 +1404,21 @@ Suppose 'wurble' is not in scope, and we have Then the renamer will make (HsUnboundVar "wurble) for 'wurble', and the typechecker will typecheck it with tcUnboundId, giving it -a type 'alpha', and emitting a deferred CHoleCan constraint, to -be reported later. +a type 'alpha', and emitting a deferred Hole, to be reported later. But then comes the visible type application. If we do nothing, we'll generate an immediate failure (in tc_app_err), saying that a function of type 'alpha' can't be applied to Bool. That's insane! And indeed users complain bitterly (#13834, #17150.) -The right error is the CHoleCan, which has /already/ been emitted by +The right error is the Hole, which has /already/ been emitted by tcUnboundId. It later reports 'wurble' as out of scope, and tries to give its type. Fortunately in tcArgs we still have access to the function, so we can check if it is a HsUnboundVar. We use this info to simply skip over any visible type arguments. We've already inferred the type of the -function, so we'll /already/ have emitted a CHoleCan constraint; +function, so we'll /already/ have emitted a Hole; failing preserves that constraint. We do /not/ want to fail altogether in this case (via failM) becuase @@ -1897,14 +1895,13 @@ tcUnboundId :: HsExpr GhcRn -> OccName -> ExpRhoType -> TcM (HsExpr GhcTc) -- Others might simply be variables that accidentally have no binding site -- -- We turn all of them into HsVar, since HsUnboundVar can't contain an --- Id; and indeed the evidence for the CHoleCan does bind it, so it's +-- Id; and indeed the evidence for the ExprHole does bind it, so it's -- not unbound any more! tcUnboundId rn_expr occ res_ty = do { ty <- newOpenFlexiTyVarTy -- Allow Int# etc (#12531) ; name <- newSysName occ ; let ev = mkLocalId name ty - ; can <- newHoleCt ExprHole ev ty - ; emitInsoluble can + ; emitNewExprHole occ ev ty ; tcWrapResultO (UnboundOccurrenceOf occ) rn_expr (HsVar noExtField (noLoc ev)) ty res_ty } ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -419,7 +419,7 @@ tcHsTypeApp wc_ty kind ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ A HsWildCardBndrs's hswc_ext now only includes /named/ wildcards, so any unnamed wildcards stay unchanged in hswc_body. When called in -tcHsTypeApp, tcCheckLHsType will call emitAnonWildCardHoleConstraint +tcHsTypeApp, tcCheckLHsType will call emitAnonTypeHole on these anonymous wildcards. However, this would trigger error/warning when an anonymous wildcard is passed in as a visible type argument, which we do not want because users should be able to write @@ -891,7 +891,7 @@ tcAnonWildCardOcc wc exp_kind ; warning <- woptM Opt_WarnPartialTypeSignatures ; unless (part_tysig && not warning) $ - emitAnonWildCardHoleConstraint wc_tv + emitAnonTypeHole wc_tv -- Why the 'unless' guard? -- See Note [Wildcards in visible kind application] @@ -911,11 +911,11 @@ x = MkT So we should allow '@_' without emitting any hole constraints, and regardless of whether PartialTypeSignatures is enabled or not. But how would the typechecker know which '_' is being used in VKA and which is not when it -calls emitNamedWildCardHoleConstraints in tcHsPartialSigType on all HsWildCardBndrs? +calls emitNamedTypeHole in tcHsPartialSigType on all HsWildCardBndrs? The solution then is to neither rename nor include unnamed wildcards in HsWildCardBndrs, but instead give every anonymous wildcard a fresh wild tyvar in tcAnonWildCardOcc. And whenever we see a '@', we automatically turn on PartialTypeSignatures and -turn off hole constraint warnings, and do not call emitAnonWildCardHoleConstraint +turn off hole constraint warnings, and do not call emitAnonTypeHole under these conditions. See related Note [Wildcards in visible type application] here and Note [The wildcard story for types] in GHC.Hs.Types @@ -3192,7 +3192,7 @@ tcHsPartialSigType ctxt sig_ty -- Spit out the wildcards (including the extra-constraints one) -- as "hole" constraints, so that they'll be reported if necessary -- See Note [Extra-constraint holes in partial type signatures] - ; emitNamedWildCardHoleConstraints wcs + ; mapM_ emitNamedTypeHole wcs -- Zonk, so that any nested foralls can "see" their occurrences -- See Note [Checking partial type signatures], in @@ -3365,7 +3365,7 @@ tcHsPatSigType ctxt sig_ty do { sig_ty <- tcHsOpenType hs_ty ; return (wcs, sig_ty) } - ; emitNamedWildCardHoleConstraints wcs + ; mapM_ emitNamedTypeHole wcs -- sig_ty might have tyvars that are at a higher TcLevel (if hs_ty -- contains a forall). Promote these. ===================================== compiler/GHC/Tc/Gen/Rule.hs ===================================== @@ -460,9 +460,9 @@ getRuleQuantCts wc = float_wc emptyVarSet wc where float_wc :: TcTyCoVarSet -> WantedConstraints -> (Cts, WantedConstraints) - float_wc skol_tvs (WC { wc_simple = simples, wc_impl = implics }) + float_wc skol_tvs (WC { wc_simple = simples, wc_impl = implics, wc_holes = holes }) = ( simple_yes `andCts` implic_yes - , WC { wc_simple = simple_no, wc_impl = implics_no }) + , emptyWC { wc_simple = simple_no, wc_impl = implics_no, wc_holes = holes }) where (simple_yes, simple_no) = partitionBag (rule_quant_ct skol_tvs) simples (implic_yes, implics_no) = mapAccumBagL (float_implic skol_tvs) @@ -480,8 +480,6 @@ getRuleQuantCts wc | EqPred _ t1 t2 <- classifyPredType (ctPred ct) , not (ok_eq t1 t2) = False -- Note [RULE quantification over equalities] - | isHoleCt ct - = False -- Don't quantify over type holes, obviously | otherwise = tyCoVarsOfCt ct `disjointVarSet` skol_tvs ===================================== compiler/GHC/Tc/Module.hs ===================================== @@ -2589,7 +2589,7 @@ tcRnType hsc_env flexi normalise rdr_type -- kindGeneralize, below solveEqualities $ tcNamedWildCardBinders wcs $ \ wcs' -> - do { emitNamedWildCardHoleConstraints wcs' + do { mapM_ emitNamedTypeHole wcs' ; tcLHsTypeUnsaturated rn_type } -- Do kind generalisation; see Note [Kind-generalise in tcRnType] ===================================== compiler/GHC/Tc/Solver.hs ===================================== @@ -31,7 +31,7 @@ import GHC.Prelude import GHC.Data.Bag import GHC.Core.Class ( Class, classKey, classTyCon ) import GHC.Driver.Session -import GHC.Types.Id ( idType, mkLocalId ) +import GHC.Types.Id ( idType ) import GHC.Tc.Utils.Instantiate import GHC.Data.List.SetOps import GHC.Types.Name @@ -42,6 +42,7 @@ import GHC.Tc.Errors import GHC.Tc.Types.Evidence import GHC.Tc.Solver.Interact import GHC.Tc.Solver.Canonical ( makeSuperClasses, solveCallStack ) +import GHC.Tc.Solver.Flatten ( flattenType ) import GHC.Tc.Utils.TcMType as TcM import GHC.Tc.Utils.Monad as TcM import GHC.Tc.Solver.Monad as TcS @@ -145,8 +146,7 @@ simplifyTop wanteds ; saved_msg <- TcM.readTcRef errs_var ; TcM.writeTcRef errs_var emptyMessages - ; warnAllUnsolved $ WC { wc_simple = unsafe_ol - , wc_impl = emptyBag } + ; warnAllUnsolved $ emptyWC { wc_simple = unsafe_ol } ; whyUnsafe <- fst <$> TcM.readTcRef errs_var ; TcM.writeTcRef errs_var saved_msg @@ -638,27 +638,15 @@ tcNormalise :: Bag EvVar -> Type -> TcM Type tcNormalise given_ids ty = do { lcl_env <- TcM.getLclEnv ; let given_loc = mkGivenLoc topTcLevel UnkSkol lcl_env - ; wanted_ct <- mk_wanted_ct + ; norm_loc <- getCtLocM PatCheckOrigin Nothing ; (res, _ev_binds) <- runTcS $ do { traceTcS "tcNormalise {" (ppr given_ids) ; let given_cts = mkGivens given_loc (bagToList given_ids) ; solveSimpleGivens given_cts - ; wcs <- solveSimpleWanteds (unitBag wanted_ct) - -- It's an invariant that this wc_simple will always be - -- a singleton Ct, since that's what we fed in as input. - ; let ty' = case bagToList (wc_simple wcs) of - (ct:_) -> ctEvPred (ctEvidence ct) - cts -> pprPanic "tcNormalise" (ppr cts) + ; ty' <- flattenType norm_loc ty ; traceTcS "tcNormalise }" (ppr ty') ; pure ty' } ; return res } - where - mk_wanted_ct :: TcM Ct - mk_wanted_ct = do - let occ = mkVarOcc "$tcNorm" - name <- newSysName occ - let ev = mkLocalId name ty - newHoleCt ExprHole ev ty {- Note [Superclasses and satisfiability] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -696,11 +684,8 @@ if some local equalities are solved for. See "Wrinkle: Local equalities" in Note [Type normalisation] in Check. To accomplish its stated goal, tcNormalise first feeds the local constraints -into solveSimpleGivens, then stuffs the argument type in a CHoleCan, and feeds -that singleton Ct into solveSimpleWanteds, which reduces the type in the -CHoleCan as much as possible with respect to the local given constraints. When -solveSimpleWanteds is finished, we dig out the type from the CHoleCan and -return that. +into solveSimpleGivens, then uses flattenType to simplify the desired type +with respect to the givens. *********************************************************************************** * * @@ -889,8 +874,8 @@ mkResidualConstraints rhs_tclvl ev_binds_var , ic_no_eqs = False , ic_info = skol_info } - ; return (WC { wc_simple = outer_simple - , wc_impl = implics })} + ; return (emptyWC { wc_simple = outer_simple + , wc_impl = implics })} where full_theta = map idType full_theta_vars skol_info = InferSkol [ (name, mkSigmaTy [] full_theta ty) @@ -1516,7 +1501,7 @@ solveWantedsAndDrop wanted solveWanteds :: WantedConstraints -> TcS WantedConstraints -- so that the inert set doesn't mindlessly propagate. -- NB: wc_simples may be wanted /or/ derived now -solveWanteds wc@(WC { wc_simple = simples, wc_impl = implics }) +solveWanteds wc@(WC { wc_simple = simples, wc_impl = implics, wc_holes = holes }) = do { cur_lvl <- TcS.getTcLevel ; traceTcS "solveWanteds {" $ vcat [ text "Level =" <+> ppr cur_lvl @@ -1530,9 +1515,12 @@ solveWanteds wc@(WC { wc_simple = simples, wc_impl = implics }) implics `unionBags` wc_impl wc1 ; dflags <- getDynFlags - ; final_wc <- simpl_loop 0 (solverIterations dflags) floated_eqs + ; solved_wc <- simpl_loop 0 (solverIterations dflags) floated_eqs (wc1 { wc_impl = implics2 }) + ; holes' <- simplifyHoles holes + ; let final_wc = solved_wc { wc_holes = holes' } + ; ev_binds_var <- getTcEvBindsVar ; bb <- TcS.getTcEvBindsMap ev_binds_var ; traceTcS "solveWanteds }" $ @@ -1779,12 +1767,13 @@ setImplicationStatus implic@(Implic { ic_status = status then Nothing else Just final_implic } where - WC { wc_simple = simples, wc_impl = implics } = wc + WC { wc_simple = simples, wc_impl = implics, wc_holes = holes } = wc pruned_simples = dropDerivedSimples simples pruned_implics = filterBag keep_me implics pruned_wc = WC { wc_simple = pruned_simples - , wc_impl = pruned_implics } + , wc_impl = pruned_implics + , wc_holes = holes } -- do not prune holes; these should be reported keep_me :: Implication -> Bool keep_me ic @@ -1898,6 +1887,14 @@ neededEvVars implic@(Implic { ic_given = givens | is_given = needs -- Add the rhs vars of the Wanted bindings only | otherwise = evVarsOfTerm rhs `unionVarSet` needs +------------------------------------------------- +simplifyHoles :: Bag Hole -> TcS (Bag Hole) +simplifyHoles = mapBagM simpl_hole + where + simpl_hole :: Hole -> TcS Hole + simpl_hole h@(Hole { hole_ty = ty, hole_loc = loc }) + = do { ty' <- flattenType loc ty + ; return (h { hole_ty = ty' }) } {- Note [Delete dead Given evidence bindings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2143,7 +2140,6 @@ approximateWC float_past_equalities wc is_floatable skol_tvs ct | isGivenCt ct = False - | isHoleCt ct = False | insolubleEqCt ct = False | otherwise = tyCoVarsOfCt ct `disjointVarSet` skol_tvs ===================================== compiler/GHC/Tc/Solver/Canonical.hs ===================================== @@ -34,7 +34,6 @@ import GHC.Tc.Instance.Family ( tcTopNormaliseNewTypeTF_maybe ) import GHC.Types.Var import GHC.Types.Var.Env( mkInScopeSet ) import GHC.Types.Var.Set( delVarSetList ) -import GHC.Types.Name.Occurrence ( OccName ) import GHC.Utils.Outputable import GHC.Driver.Session( DynFlags ) import GHC.Types.Name.Set @@ -67,8 +66,7 @@ Canonicalization converts a simple constraint to a canonical form. It is unary (i.e. treats individual constraints one at a time). Constraints originating from user-written code come into being as -CNonCanonicals (except for CHoleCans, arising from holes). We know nothing -about these constraints. So, first: +CNonCanonicals. We know nothing about these constraints. So, first: Classify CNonCanoncal constraints, depending on whether they are equalities, class predicates, or other. @@ -137,9 +135,6 @@ canonicalize (CFunEqCan { cc_ev = ev = {-# SCC "canEqLeafFunEq" #-} canCFunEqCan ev fn xis1 fsk -canonicalize (CHoleCan { cc_ev = ev, cc_occ = occ, cc_hole = hole }) - = canHole ev occ hole - {- ************************************************************************ * * @@ -718,17 +713,6 @@ canIrred status ev _ -> continueWith $ mkIrredCt status new_ev } } -canHole :: CtEvidence -> OccName -> HoleSort -> TcS (StopOrContinue Ct) -canHole ev occ hole_sort - = do { let pred = ctEvPred ev - ; (xi,co) <- flatten FM_SubstOnly ev pred -- co :: xi ~ pred - ; rewriteEvidence ev xi co `andWhenContinue` \ new_ev -> - do { updInertIrreds (`snocCts` (CHoleCan { cc_ev = new_ev - , cc_occ = occ - , cc_hole = hole_sort })) - ; stopWith new_ev "Emit insoluble hole" } } - - {- ********************************************************************* * * * Quantified predicates @@ -1401,6 +1385,7 @@ can_eq_app ev s1 t1 s2 t2 | CtDerived {} <- ev = do { unifyDeriveds loc [Nominal, Nominal] [s1, t1] [s2, t2] ; stopWith ev "Decomposed [D] AppTy" } + | CtWanted { ctev_dest = dest } <- ev = do { co_s <- unifyWanted loc Nominal s1 s2 ; let arg_loc ===================================== compiler/GHC/Tc/Solver/Flatten.hs ===================================== @@ -5,7 +5,7 @@ module GHC.Tc.Solver.Flatten( FlattenMode(..), flatten, flattenKind, flattenArgsNom, - rewriteTyVar, + rewriteTyVar, flattenType, unflattenWanteds ) where @@ -825,6 +825,20 @@ flattenArgsNom ev tc tys ; traceTcS "flatten }" (vcat (map ppr tys')) ; return (tys', cos, kind_co) } +-- | Flatten a type w.r.t. nominal equality. This is useful to rewrite +-- a type w.r.t. any givens. It does not do type-family reduction. This +-- will never emit new constraints. Call this when the inert set contains +-- only givens. +flattenType :: CtLoc -> TcType -> TcS TcType +flattenType loc ty + -- More info about FM_SubstOnly in Note [Holes] in GHC.Tc.Types.Constraint + = do { (xi, _) <- runFlatten FM_SubstOnly loc Given NomEq $ + flatten_one ty + -- use Given flavor so that it is rewritten + -- only w.r.t. Givens, never Wanteds/Deriveds + -- (Shouldn't matter, if only Givens are present + -- anyway) + ; return xi } {- ********************************************************************* * * ===================================== compiler/GHC/Tc/Solver/Interact.hs ===================================== @@ -195,7 +195,7 @@ solve_simple_wanteds :: WantedConstraints -> TcS (Int, WantedConstraints) -- Try solving these constraints -- Affects the unification state (of course) but not the inert set -- The result is not necessarily zonked -solve_simple_wanteds (WC { wc_simple = simples1, wc_impl = implics1 }) +solve_simple_wanteds (WC { wc_simple = simples1, wc_impl = implics1, wc_holes = holes }) = nestTcS $ do { solveSimples simples1 ; (implics2, tv_eqs, fun_eqs, others) <- getUnsolvedInerts @@ -204,7 +204,8 @@ solve_simple_wanteds (WC { wc_simple = simples1, wc_impl = implics1 }) -- See Note [Unflatten after solving the simple wanteds] ; return ( unif_count , WC { wc_simple = others `andCts` unflattened_eqs - , wc_impl = implics1 `unionBags` implics2 }) } + , wc_impl = implics1 `unionBags` implics2 + , wc_holes = holes }) } {- Note [The solveSimpleWanteds loop] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -264,7 +265,7 @@ runTcPluginsGiven -- 'solveSimpleWanteds' should feed the updated wanteds back into the -- main solver. runTcPluginsWanted :: WantedConstraints -> TcS (Bool, WantedConstraints) -runTcPluginsWanted wc@(WC { wc_simple = simples1, wc_impl = implics1 }) +runTcPluginsWanted wc@(WC { wc_simple = simples1 }) | isEmptyBag simples1 = return (False, wc) | otherwise @@ -285,11 +286,10 @@ runTcPluginsWanted wc@(WC { wc_simple = simples1, wc_impl = implics1 }) ; mapM_ setEv solved_wanted ; return ( notNull (pluginNewCts p) - , WC { wc_simple = listToBag new_wanted `andCts` + , wc { wc_simple = listToBag new_wanted `andCts` listToBag unsolved_wanted `andCts` listToBag unsolved_derived `andCts` - listToBag insols - , wc_impl = implics1 } ) } } + listToBag insols } ) } } where setEv :: (EvTerm,Ct) -> TcS () setEv (ev,ct) = case ctEvidence ct of @@ -494,7 +494,6 @@ interactWithInertsStage wi CIrredCan {} -> interactIrred ics wi CDictCan {} -> interactDict ics wi _ -> pprPanic "interactWithInerts" (ppr wi) } - -- CHoleCan are put straight into inert_frozen, so never get here -- CNonCanonical have been canonicalised data InteractResult ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -198,7 +198,7 @@ import GHC.Types.Unique.Set Note [WorkList priorities] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -A WorkList contains canonical and non-canonical items (of all flavors). +A WorkList contains canonical and non-canonical items (of all flavours). Notice that each Ct now has a simplification depth. We may consider using this depth for prioritization as well in the future. @@ -1653,8 +1653,7 @@ add_item ics item@(CDictCan { cc_ev = ev, cc_class = cls, cc_tyargs = tys }) add_item _ item = pprPanic "upd_inert set: can't happen! Inserting " $ - ppr item -- Can't be CNonCanonical, CHoleCan, - -- because they only land in inert_irreds + ppr item -- Can't be CNonCanonical because they only land in inert_irreds bumpUnsolvedCount :: CtEvidence -> Int -> Int bumpUnsolvedCount ev n | isWanted ev = n+1 @@ -1896,10 +1895,6 @@ be decomposed. Otherwise we end up with a "Can't match [Int] ~ [[Int]]" which is true, but a bit confusing because the outer type constructors match. -Similarly, if we have a CHoleCan, we'd like to rewrite it with any -Givens, to give as informative an error messasge as possible -(#12468, #11325). - Hence: * In the main simplifier loops in GHC.Tc.Solver (solveWanteds, simpl_loop), we feed the insolubles in solveSimpleWanteds, @@ -2352,8 +2347,6 @@ removeInertCt is ct = CQuantCan {} -> panic "removeInertCt: CQuantCan" CIrredCan {} -> panic "removeInertCt: CIrredEvCan" CNonCanonical {} -> panic "removeInertCt: CNonCanonical" - CHoleCan {} -> panic "removeInertCt: CHoleCan" - lookupFlatCache :: TyCon -> [Type] -> TcS (Maybe (TcCoercion, TcType, CtFlavour)) lookupFlatCache fam_tc tys ===================================== compiler/GHC/Tc/Types/Constraint.hs ===================================== @@ -14,8 +14,7 @@ module GHC.Tc.Types.Constraint ( isEmptyCts, isCTyEqCan, isCFunEqCan, isPendingScDict, superClassesMightHelp, getPendingWantedScs, isCDictCan_Maybe, isCFunEqCan_maybe, - isCNonCanonical, isWantedCt, isDerivedCt, - isGivenCt, isHoleCt, isOutOfScopeCt, isExprHoleCt, isTypeHoleCt, + isCNonCanonical, isWantedCt, isDerivedCt, isGivenCt, isUserTypeErrorCt, getUserTypeErrorMsg, ctEvidence, ctLoc, setCtLoc, ctPred, ctFlavour, ctEqRel, ctOrigin, ctEvId, mkTcEqPredLikeEv, @@ -26,9 +25,11 @@ module GHC.Tc.Types.Constraint ( tyCoVarsOfCt, tyCoVarsOfCts, tyCoVarsOfCtList, tyCoVarsOfCtsList, + Hole(..), HoleSort(..), isOutOfScopeHole, + WantedConstraints(..), insolubleWC, emptyWC, isEmptyWC, isSolvedWC, andWC, unionsWC, mkSimpleWC, mkImplicWC, - addInsols, insolublesOnly, addSimples, addImplics, + addInsols, insolublesOnly, addSimples, addImplics, addHole, tyCoVarsOfWC, dropDerivedWC, dropDerivedSimples, tyCoVarsOfWCList, insolubleCt, insolubleEqCt, isDroppableCt, insolubleImplic, @@ -62,9 +63,6 @@ module GHC.Tc.Types.Constraint ( pprEvVarTheta, pprEvVars, pprEvVarWithType, - -- holes - HoleSort(..), - ) where @@ -202,14 +200,6 @@ data Ct cc_ev :: CtEvidence } - | CHoleCan { -- See Note [Hole constraints] - -- Treated as an "insoluble" constraint - -- See Note [Insoluble constraints] - cc_ev :: CtEvidence, - cc_occ :: OccName, -- The name of this hole - cc_hole :: HoleSort -- The sort of this hole (expr, type, ...) - } - | CQuantCan QCInst -- A quantified constraint -- NB: I expect to make more of the cases in Ct -- look like this, with the payload in an @@ -230,13 +220,47 @@ instance Outputable QCInst where ppr (QCI { qci_ev = ev }) = ppr ev ------------ +-- | A hole stores the information needed to report diagnostics +-- about holes in terms (unbound identifiers or underscores) or +-- in types (also called wildcards, as used in partial type +-- signatures). See Note [Holes]. +data Hole + = Hole { hole_sort :: HoleSort -- ^ What flavour of hole is this? + , hole_occ :: OccName -- ^ The name of this hole + , hole_ty :: TcType -- ^ Type to be printed to the user + -- For expression holes: type of expr + -- For type holes: the missing type + , hole_loc :: CtLoc -- ^ Where hole was written + } + -- For the hole_loc, we usually only want the TcLclEnv stored within. + -- Except when we flatten, where we need a whole location. And this + -- might get reported to the user if reducing type families in a + -- hole type loops. + + -- | Used to indicate which sort of hole we have. -data HoleSort = ExprHole +data HoleSort = ExprHole Id -- ^ Either an out-of-scope variable or a "true" hole in an - -- expression (TypedHoles) + -- expression (TypedHoles). + -- The 'Id' is where to store "evidence": this evidence + -- will be an erroring expression for -fdefer-type-errors. | TypeHole -- ^ A hole in a type (PartialTypeSignatures) +instance Outputable Hole where + ppr (Hole { hole_sort = ExprHole id + , hole_occ = occ + , hole_ty = ty }) + = parens $ (braces $ ppr occ <> colon <> ppr id) <+> dcolon <+> ppr ty + ppr (Hole { hole_sort = TypeHole + , hole_occ = occ + , hole_ty = ty }) + = braces $ ppr occ <> colon <> ppr ty + +instance Outputable HoleSort where + ppr (ExprHole id) = text "ExprHole:" <> ppr id + ppr TypeHole = text "TypeHole" + ------------ -- | Used to indicate extra information about why a CIrredCan is irreducible data CtIrredStatus @@ -252,20 +276,8 @@ instance Outputable CtIrredStatus where ppr BlockedCIS = text "(blocked)" ppr OtherCIS = text "(soluble)" -{- Note [Hole constraints] -~~~~~~~~~~~~~~~~~~~~~~~~~~ -CHoleCan constraints are used for two kinds of holes, -distinguished by cc_hole: - - * For holes in expressions - e.g. f x = g _ x - - * For holes in type signatures - e.g. f :: _ -> _ - f x = [x,True] - -Note [CIrredCan constraints] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [CIrredCan constraints] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ CIrredCan constraints are used for constraints that are "stuck" - we can't solve them (yet) - we can't use them to solve other constraints @@ -350,6 +362,40 @@ unenforced). The almost-function-free property is checked by isAlmostFunctionFree in GHC.Tc.Utils.TcType. The flattener (in GHC.Tc.Solver.Flatten) produces types that are almost function-free. +Note [Holes] +~~~~~~~~~~~~ +This Note explains how GHC tracks *holes*. + +A hole represents one of two conditions: + - A missing bit of an expression. Example: foo x = x + _ + - A missing bit of a type. Example: bar :: Int -> _ + +What these have in common is that both cause GHC to emit a diagnostic to the +user describing the bit that is left out. + +When a hole is encountered, a new entry of type Hole is added to the ambient +WantedConstraints. The type (hole_ty) of the hole is then simplified during +solving (with respect to any Givens in surrounding implications). It is +reported with all the other errors in GHC.Tc.Errors. No type family reduction +is done on hole types; this is purely because we think it will produce +better error messages not to reduce type families. This is why the +GHC.Tc.Solver.Flatten.flattenType function uses FM_SubstOnly. + +For expression holes, the user has the option of deferring errors until runtime +with -fdefer-type-errors. In this case, the hole actually has evidence: this +evidence is an erroring expression that prints an error and crashes at runtime. +The ExprHole variant of holes stores the Id that will be bound to this evidence; +during constraint generation, this Id was inserted into the expression output +by the type checker. + +You might think that the type of the stored Id is the same as the type of the +hole. However, because the hole type (hole_ty) is rewritten with respect to +givens, this might not be the case. That is, the hole_ty is always (~) to the +type of the Id, but they might not be `eqType`. We need the type of the generated +evidence to match what is expected in the context of the hole, and so we must +store these types separately. + +Type-level holes have no evidence at all. -} mkNonCanonical :: CtEvidence -> Ct @@ -419,7 +465,6 @@ instance Outputable Ct where | pend_sc -> text "CDictCan(psc)" | otherwise -> text "CDictCan" CIrredCan { cc_status = status } -> text "CIrredCan" <> ppr status - CHoleCan { cc_occ = occ } -> text "CHoleCan:" <+> ppr occ CQuantCan (QCI { qci_pend_sc = pend_sc }) | pend_sc -> text "CQuantCan(psc)" | otherwise -> text "CQuantCan" @@ -482,9 +527,10 @@ tyCoVarsOfWCList = fvVarList . tyCoFVsOfWC -- computation. See Note [Deterministic FV] in GHC.Utils.FV. tyCoFVsOfWC :: WantedConstraints -> FV -- Only called on *zonked* things, hence no need to worry about flatten-skolems -tyCoFVsOfWC (WC { wc_simple = simple, wc_impl = implic }) +tyCoFVsOfWC (WC { wc_simple = simple, wc_impl = implic, wc_holes = holes }) = tyCoFVsOfCts simple `unionFV` - tyCoFVsOfBag tyCoFVsOfImplic implic + tyCoFVsOfBag tyCoFVsOfImplic implic `unionFV` + tyCoFVsOfBag tyCoFVsOfHole holes -- | Returns free variables of Implication as a composable FV computation. -- See Note [Deterministic FV] in GHC.Utils.FV. @@ -500,6 +546,9 @@ tyCoFVsOfImplic (Implic { ic_skols = skols tyCoFVsVarBndrs givens $ tyCoFVsOfWC wanted +tyCoFVsOfHole :: Hole -> FV +tyCoFVsOfHole (Hole { hole_ty = ty }) = tyCoFVsOfType ty + tyCoFVsOfBag :: (a -> FV) -> Bag a -> FV tyCoFVsOfBag tvs_of = foldr (unionFV . tvs_of) emptyFV @@ -552,7 +601,6 @@ isDroppableCt ct keep_deriv = case ct of - CHoleCan {} -> True CIrredCan { cc_status = InsolubleCIS } -> keep_eq True _ -> keep_eq False @@ -676,26 +724,6 @@ isCNonCanonical :: Ct -> Bool isCNonCanonical (CNonCanonical {}) = True isCNonCanonical _ = False -isHoleCt:: Ct -> Bool -isHoleCt (CHoleCan {}) = True -isHoleCt _ = False - -isOutOfScopeCt :: Ct -> Bool --- A Hole that does not have a leading underscore is --- simply an out-of-scope variable, and we treat that --- a bit differently when it comes to error reporting -isOutOfScopeCt (CHoleCan { cc_occ = occ }) = not (startsWithUnderscore occ) -isOutOfScopeCt _ = False - -isExprHoleCt :: Ct -> Bool -isExprHoleCt (CHoleCan { cc_hole = ExprHole }) = True -isExprHoleCt _ = False - -isTypeHoleCt :: Ct -> Bool -isTypeHoleCt (CHoleCan { cc_hole = TypeHole }) = True -isTypeHoleCt _ = False - - {- Note [Custom type errors in constraints] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -884,37 +912,39 @@ v%************************************************************************ data WantedConstraints = WC { wc_simple :: Cts -- Unsolved constraints, all wanted , wc_impl :: Bag Implication + , wc_holes :: Bag Hole } emptyWC :: WantedConstraints -emptyWC = WC { wc_simple = emptyBag, wc_impl = emptyBag } +emptyWC = WC { wc_simple = emptyBag + , wc_impl = emptyBag + , wc_holes = emptyBag } mkSimpleWC :: [CtEvidence] -> WantedConstraints mkSimpleWC cts - = WC { wc_simple = listToBag (map mkNonCanonical cts) - , wc_impl = emptyBag } + = emptyWC { wc_simple = listToBag (map mkNonCanonical cts) } mkImplicWC :: Bag Implication -> WantedConstraints mkImplicWC implic - = WC { wc_simple = emptyBag, wc_impl = implic } + = emptyWC { wc_impl = implic } isEmptyWC :: WantedConstraints -> Bool -isEmptyWC (WC { wc_simple = f, wc_impl = i }) - = isEmptyBag f && isEmptyBag i - +isEmptyWC (WC { wc_simple = f, wc_impl = i, wc_holes = holes }) + = isEmptyBag f && isEmptyBag i && isEmptyBag holes -- | Checks whether a the given wanted constraints are solved, i.e. -- that there are no simple constraints left and all the implications -- are solved. isSolvedWC :: WantedConstraints -> Bool -isSolvedWC WC {wc_simple = wc_simple, wc_impl = wc_impl} = - isEmptyBag wc_simple && allBag (isSolvedStatus . ic_status) wc_impl +isSolvedWC WC {wc_simple = wc_simple, wc_impl = wc_impl, wc_holes = holes} = + isEmptyBag wc_simple && allBag (isSolvedStatus . ic_status) wc_impl && isEmptyBag holes andWC :: WantedConstraints -> WantedConstraints -> WantedConstraints -andWC (WC { wc_simple = f1, wc_impl = i1 }) - (WC { wc_simple = f2, wc_impl = i2 }) +andWC (WC { wc_simple = f1, wc_impl = i1, wc_holes = h1 }) + (WC { wc_simple = f2, wc_impl = i2, wc_holes = h2 }) = WC { wc_simple = f1 `unionBags` f2 - , wc_impl = i1 `unionBags` i2 } + , wc_impl = i1 `unionBags` i2 + , wc_holes = h1 `unionBags` h2 } unionsWC :: [WantedConstraints] -> WantedConstraints unionsWC = foldr andWC emptyWC @@ -931,11 +961,16 @@ addInsols :: WantedConstraints -> Bag Ct -> WantedConstraints addInsols wc cts = wc { wc_simple = wc_simple wc `unionBags` cts } +addHole :: WantedConstraints -> Hole -> WantedConstraints +addHole wc hole + = wc { wc_holes = hole `consBag` wc_holes wc } + insolublesOnly :: WantedConstraints -> WantedConstraints -- Keep only the definitely-insoluble constraints -insolublesOnly (WC { wc_simple = simples, wc_impl = implics }) +insolublesOnly (WC { wc_simple = simples, wc_impl = implics, wc_holes = holes }) = WC { wc_simple = filterBag insolubleCt simples - , wc_impl = mapBag implic_insols_only implics } + , wc_impl = mapBag implic_insols_only implics + , wc_holes = filterBag isOutOfScopeHole holes } where implic_insols_only implic = implic { ic_wanted = insolublesOnly (ic_wanted implic) } @@ -953,9 +988,10 @@ insolubleImplic :: Implication -> Bool insolubleImplic ic = isInsolubleStatus (ic_status ic) insolubleWC :: WantedConstraints -> Bool -insolubleWC (WC { wc_impl = implics, wc_simple = simples }) +insolubleWC (WC { wc_impl = implics, wc_simple = simples, wc_holes = holes }) = anyBag insolubleCt simples || anyBag insolubleImplic implics + || anyBag isOutOfScopeHole holes -- See Note [Insoluble holes] insolubleCt :: Ct -> Bool -- Definitely insoluble, in particular /excluding/ type-hole constraints @@ -963,7 +999,6 @@ insolubleCt :: Ct -> Bool -- b) that is insoluble -- c) and does not arise from a Given insolubleCt ct - | isHoleCt ct = isOutOfScopeCt ct -- See Note [Insoluble holes] | not (insolubleEqCt ct) = False | arisesFromGivens ct = False -- See Note [Given insolubles] | otherwise = True @@ -986,11 +1021,17 @@ insolubleEqCt :: Ct -> Bool insolubleEqCt (CIrredCan { cc_status = InsolubleCIS }) = True insolubleEqCt _ = False +-- | Does this hole represent an "out of scope" error? +-- See Note [Insoluble holes] +isOutOfScopeHole :: Hole -> Bool +isOutOfScopeHole (Hole { hole_occ = occ }) = not (startsWithUnderscore occ) + instance Outputable WantedConstraints where - ppr (WC {wc_simple = s, wc_impl = i}) + ppr (WC {wc_simple = s, wc_impl = i, wc_holes = h}) = text "WC" <+> braces (vcat [ ppr_bag (text "wc_simple") s - , ppr_bag (text "wc_impl") i ]) + , ppr_bag (text "wc_impl") i + , ppr_bag (text "wc_holes") h ]) ppr_bag :: Outputable a => SDoc -> Bag a -> SDoc ppr_bag doc bag @@ -1035,7 +1076,7 @@ Hole constraints that ARE NOT treated as truly insoluble: a) type holes, arising from PartialTypeSignatures, b) "true" expression holes arising from TypedHoles -An "expression hole" or "type hole" constraint isn't really an error +An "expression hole" or "type hole" isn't really an error at all; it's a report saying "_ :: Int" here. But an out-of-scope variable masquerading as expression holes IS treated as truly insoluble, so that it trumps other errors during error reporting. @@ -1512,10 +1553,6 @@ ctFlavourRole (CTyEqCan { cc_ev = ev, cc_eq_rel = eq_rel }) = (ctEvFlavour ev, eq_rel) ctFlavourRole (CFunEqCan { cc_ev = ev }) = (ctEvFlavour ev, NomEq) -ctFlavourRole (CHoleCan { cc_ev = ev }) - = (ctEvFlavour ev, NomEq) -- NomEq: CHoleCans can be rewritten by - -- by nominal equalities but empahatically - -- not by representational equalities ctFlavourRole ct = ctEvFlavourRole (ctEvidence ct) ===================================== compiler/GHC/Tc/Types/Origin.hs ===================================== @@ -427,7 +427,9 @@ data CtOrigin -- We only need a CtOrigin on the first, because the location -- is pinned on the entire error message - | HoleOrigin + | ExprHoleOrigin OccName -- from an expression hole + | TypeHoleOrigin OccName -- from a type hole (partial type signature) + | PatCheckOrigin -- normalisation of a type during pattern-match checking | UnboundOccurrenceOf OccName | ListOrigin -- An overloaded list | BracketOrigin -- An overloaded quotation bracket @@ -640,7 +642,9 @@ pprCtO MCompOrigin = text "a statement in a monad comprehension" pprCtO ProcOrigin = text "a proc expression" pprCtO (TypeEqOrigin t1 t2 _ _)= text "a type equality" <+> sep [ppr t1, char '~', ppr t2] pprCtO AnnOrigin = text "an annotation" -pprCtO HoleOrigin = text "a use of" <+> quotes (text "_") +pprCtO (ExprHoleOrigin occ) = text "a use of" <+> quotes (ppr occ) +pprCtO (TypeHoleOrigin occ) = text "a use of wildcard" <+> quotes (ppr occ) +pprCtO PatCheckOrigin = text "a pattern-match completeness check" pprCtO ListOrigin = text "an overloaded list" pprCtO StaticOrigin = text "a static form" pprCtO BracketOrigin = text "a quotation bracket" ===================================== compiler/GHC/Tc/Utils/Monad.hs ===================================== @@ -98,14 +98,14 @@ module GHC.Tc.Utils.Monad( chooseUniqueOccTc, getConstraintVar, setConstraintVar, emitConstraints, emitStaticConstraints, emitSimple, emitSimples, - emitImplication, emitImplications, emitInsoluble, + emitImplication, emitImplications, emitInsoluble, emitHole, discardConstraints, captureConstraints, tryCaptureConstraints, pushLevelAndCaptureConstraints, pushTcLevelM_, pushTcLevelM, pushTcLevelsM, getTcLevel, setTcLevel, isTouchableTcM, getLclTypeEnv, setLclTypeEnv, traceTcConstraints, - emitNamedWildCardHoleConstraints, emitAnonWildCardHoleConstraint, + emitNamedTypeHole, emitAnonTypeHole, -- * Template Haskell context recordThUse, recordThSpliceUse, @@ -1569,12 +1569,11 @@ emitInsoluble ct ; lie_var <- getConstraintVar ; updTcRef lie_var (`addInsols` unitBag ct) } -emitInsolubles :: Cts -> TcM () -emitInsolubles cts - | isEmptyBag cts = return () - | otherwise = do { traceTc "emitInsolubles" (ppr cts) - ; lie_var <- getConstraintVar - ; updTcRef lie_var (`addInsols` cts) } +emitHole :: Hole -> TcM () +emitHole hole + = do { traceTc "emitHole" (ppr hole) + ; lie_var <- getConstraintVar + ; updTcRef lie_var (`addHole` hole) } -- | Throw out any constraints emitted by the thing_inside discardConstraints :: TcM a -> TcM a @@ -1644,34 +1643,28 @@ traceTcConstraints msg hang (text (msg ++ ": LIE:")) 2 (ppr lie) } -emitAnonWildCardHoleConstraint :: TcTyVar -> TcM () -emitAnonWildCardHoleConstraint tv - = do { ct_loc <- getCtLocM HoleOrigin Nothing - ; emitInsolubles $ unitBag $ - CHoleCan { cc_ev = CtDerived { ctev_pred = mkTyVarTy tv - , ctev_loc = ct_loc } - , cc_occ = mkTyVarOcc "_" - , cc_hole = TypeHole } } - -emitNamedWildCardHoleConstraints :: [(Name, TcTyVar)] -> TcM () -emitNamedWildCardHoleConstraints wcs - = do { ct_loc <- getCtLocM HoleOrigin Nothing - ; emitInsolubles $ listToBag $ - map (do_one ct_loc) wcs } +emitAnonTypeHole :: TcTyVar -> TcM () +emitAnonTypeHole tv + = do { ct_loc <- getCtLocM (TypeHoleOrigin occ) Nothing + ; let hole = Hole { hole_sort = TypeHole + , hole_occ = occ + , hole_ty = mkTyVarTy tv + , hole_loc = ct_loc } + ; emitHole hole } + where + occ = mkTyVarOcc "_" + +emitNamedTypeHole :: (Name, TcTyVar) -> TcM () +emitNamedTypeHole (name, tv) + = do { ct_loc <- setSrcSpan (nameSrcSpan name) $ + getCtLocM (TypeHoleOrigin occ) Nothing + ; let hole = Hole { hole_sort = TypeHole + , hole_occ = occ + , hole_ty = mkTyVarTy tv + , hole_loc = ct_loc } + ; emitHole hole } where - do_one :: CtLoc -> (Name, TcTyVar) -> Ct - do_one ct_loc (name, tv) - = CHoleCan { cc_ev = CtDerived { ctev_pred = mkTyVarTy tv - , ctev_loc = ct_loc' } - , cc_occ = occName name - , cc_hole = TypeHole } - where - real_span = case nameSrcSpan name of - RealSrcSpan span _ -> span - UnhelpfulSpan str -> pprPanic "emitNamedWildCardHoleConstraints" - (ppr name <+> quotes (ftext str)) - -- Wildcards are defined locally, and so have RealSrcSpans - ct_loc' = setCtLocSpan ct_loc real_span + occ = nameOccName name {- Note [Constraints and errors] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Tc/Utils/TcMType.hs ===================================== @@ -41,10 +41,11 @@ module GHC.Tc.Utils.TcMType ( -------------------------------- -- Creating new evidence variables newEvVar, newEvVars, newDict, - newWanted, newWanteds, newHoleCt, cloneWanted, cloneWC, + newWanted, newWanteds, cloneWanted, cloneWC, emitWanted, emitWantedEq, emitWantedEvVar, emitWantedEvVars, emitDerivedEqs, newTcEvBinds, newNoTcEvBinds, addTcEvBind, + emitNewExprHole, newCoercionHole, fillCoercionHole, isFilledCoercionHole, unpackCoercionHole, unpackCoercionHole_maybe, @@ -67,7 +68,7 @@ module GHC.Tc.Utils.TcMType ( -------------------------------- -- Zonking and tidying zonkTidyTcType, zonkTidyTcTypes, zonkTidyOrigin, - tidyEvVar, tidyCt, tidySkolemInfo, + tidyEvVar, tidyCt, tidyHole, tidySkolemInfo, zonkTcTyVar, zonkTcTyVars, zonkTcTyVarToTyVar, zonkTyVarTyVarPairs, zonkTyCoVarsAndFV, zonkTcTypeAndFV, zonkDTyCoVarSetAndFV, @@ -193,17 +194,6 @@ newWanted orig t_or_k pty newWanteds :: CtOrigin -> ThetaType -> TcM [CtEvidence] newWanteds orig = mapM (newWanted orig Nothing) --- | Create a new 'CHoleCan' 'Ct'. -newHoleCt :: HoleSort -> Id -> Type -> TcM Ct -newHoleCt hole ev ty = do - loc <- getCtLocM HoleOrigin Nothing - pure $ CHoleCan { cc_ev = CtWanted { ctev_pred = ty - , ctev_dest = EvVarDest ev - , ctev_nosh = WDeriv - , ctev_loc = loc } - , cc_occ = getOccName ev - , cc_hole = hole } - ---------------------------------------------- -- Cloning constraints ---------------------------------------------- @@ -286,6 +276,18 @@ emitWantedEvVar origin ty emitWantedEvVars :: CtOrigin -> [TcPredType] -> TcM [EvVar] emitWantedEvVars orig = mapM (emitWantedEvVar orig) +-- | Emit a new wanted expression hole +emitNewExprHole :: OccName -- of the hole + -> Id -- of the evidence + -> Type -> TcM () +emitNewExprHole occ ev_id ty + = do { loc <- getCtLocM (ExprHoleOrigin occ) (Just TypeLevel) + ; let hole = Hole { hole_sort = ExprHole ev_id + , hole_occ = getOccName ev_id + , hole_ty = ty + , hole_loc = loc } + ; emitHole hole } + newDict :: Class -> [TcType] -> TcM DictId newDict cls tys = do { name <- newSysName (mkDictOcc (getOccName cls)) @@ -2002,21 +2004,28 @@ zonkWC :: WantedConstraints -> TcM WantedConstraints zonkWC wc = zonkWCRec wc zonkWCRec :: WantedConstraints -> TcM WantedConstraints -zonkWCRec (WC { wc_simple = simple, wc_impl = implic }) +zonkWCRec (WC { wc_simple = simple, wc_impl = implic, wc_holes = holes }) = do { simple' <- zonkSimples simple ; implic' <- mapBagM zonkImplication implic - ; return (WC { wc_simple = simple', wc_impl = implic' }) } + ; holes' <- mapBagM zonkHole holes + ; return (WC { wc_simple = simple', wc_impl = implic', wc_holes = holes' }) } zonkSimples :: Cts -> TcM Cts zonkSimples cts = do { cts' <- mapBagM zonkCt cts ; traceTc "zonkSimples done:" (ppr cts') ; return cts' } +zonkHole :: Hole -> TcM Hole +zonkHole hole@(Hole { hole_ty = ty }) + = do { ty' <- zonkTcType ty + ; return (hole { hole_ty = ty' }) } + -- No need to zonk the Id in any ExprHole because we never look at it + -- until after the final zonk and desugaring + {- Note [zonkCt behaviour] ~~~~~~~~~~~~~~~~~~~~~~~~~~ zonkCt tries to maintain the canonical form of a Ct. For example, - a CDictCan should stay a CDictCan; - - a CHoleCan should stay a CHoleCan - a CIrredCan should stay a CIrredCan with its cc_status flag intact Why?, for example: @@ -2026,8 +2035,6 @@ Why?, for example: don't preserve a canonical form, @expandSuperClasses@ fails to expand superclasses. This is what happened in #11525. -- For CHoleCan, once we forget that it's a hole, we can never recover that info. - - For CIrredCan we want to see if a constraint is insoluble with insolubleWC On the other hand, we change CTyEqCan to CNonCanonical, because of all of @@ -2046,10 +2053,6 @@ creates e.g. a CDictCan where the cc_tyars are /not/ function free. zonkCt :: Ct -> TcM Ct -- See Note [zonkCt behaviour] -zonkCt ct@(CHoleCan { cc_ev = ev }) - = do { ev' <- zonkCtEvidence ev - ; return $ ct { cc_ev = ev' } } - zonkCt ct@(CDictCan { cc_ev = ev, cc_tyargs = args }) = do { ev' <- zonkCtEvidence ev ; args' <- mapM zonkTcType args @@ -2262,17 +2265,15 @@ zonkTidyOrigin env orig = return (env, orig) tidyCt :: TidyEnv -> Ct -> Ct -- Used only in error reporting tidyCt env ct - = ct { cc_ev = tidy_ev env (ctEvidence ct) } + = ct { cc_ev = tidy_ev (ctEvidence ct) } where - tidy_ev :: TidyEnv -> CtEvidence -> CtEvidence + tidy_ev :: CtEvidence -> CtEvidence -- NB: we do not tidy the ctev_evar field because we don't -- show it in error messages - tidy_ev env ctev@(CtGiven { ctev_pred = pred }) - = ctev { ctev_pred = tidyType env pred } - tidy_ev env ctev@(CtWanted { ctev_pred = pred }) - = ctev { ctev_pred = tidyType env pred } - tidy_ev env ctev@(CtDerived { ctev_pred = pred }) - = ctev { ctev_pred = tidyType env pred } + tidy_ev ctev = ctev { ctev_pred = tidyType env (ctev_pred ctev) } + +tidyHole :: TidyEnv -> Hole -> Hole +tidyHole env h@(Hole { hole_ty = ty }) = h { hole_ty = tidyType env ty } ---------------- tidyEvVar :: TidyEnv -> EvVar -> EvVar ===================================== testsuite/tests/partial-sigs/should_compile/SplicesUsed.stderr ===================================== @@ -34,7 +34,7 @@ SplicesUsed.hs:10:16: warning: [-Wpartial-type-signatures (in -Wdefault)] In the type signature: charA :: a -> (_) SplicesUsed.hs:13:13: warning: [-Wpartial-type-signatures (in -Wdefault)] - • Found type wildcard ‘_’ standing for ‘a -> Bool’ + • Found type wildcard ‘_’ standing for ‘[a]’ Where: ‘a’ is a rigid type variable bound by the inferred type of filter' :: (a -> Bool) -> [a] -> [a] at SplicesUsed.hs:14:1-16 @@ -50,7 +50,7 @@ SplicesUsed.hs:13:13: warning: [-Wpartial-type-signatures (in -Wdefault)] In the type signature: filter' :: (_ -> _ -> _) SplicesUsed.hs:13:13: warning: [-Wpartial-type-signatures (in -Wdefault)] - • Found type wildcard ‘_’ standing for ‘[a]’ + • Found type wildcard ‘_’ standing for ‘a -> Bool’ Where: ‘a’ is a rigid type variable bound by the inferred type of filter' :: (a -> Bool) -> [a] -> [a] at SplicesUsed.hs:14:1-16 @@ -58,26 +58,26 @@ SplicesUsed.hs:13:13: warning: [-Wpartial-type-signatures (in -Wdefault)] In the type signature: filter' :: (_ -> _ -> _) SplicesUsed.hs:16:2: warning: [-Wpartial-type-signatures (in -Wdefault)] - • Found type wildcard ‘_’ standing for ‘Eq a’ + • Found type wildcard ‘_’ standing for ‘a -> a -> Bool’ Where: ‘a’ is a rigid type variable bound by the inferred type of foo :: Eq a => a -> a -> Bool at SplicesUsed.hs:16:2-11 • In the type signature: foo :: _ => _ SplicesUsed.hs:16:2: warning: [-Wpartial-type-signatures (in -Wdefault)] - • Found type wildcard ‘_’ standing for ‘a -> a -> Bool’ + • Found type wildcard ‘_’ standing for ‘Eq a’ Where: ‘a’ is a rigid type variable bound by the inferred type of foo :: Eq a => a -> a -> Bool at SplicesUsed.hs:16:2-11 • In the type signature: foo :: _ => _ -SplicesUsed.hs:18:2: warning: [-Wpartial-type-signatures (in -Wdefault)] - • Found type wildcard ‘_a’ standing for ‘Bool’ - • In the type signature: bar :: _a -> _b -> (_a, _b) - SplicesUsed.hs:18:2: warning: [-Wpartial-type-signatures (in -Wdefault)] • Found type wildcard ‘_b’ standing for ‘_’ Where: ‘_’ is a rigid type variable bound by the inferred type of bar :: Bool -> _ -> (Bool, _) at SplicesUsed.hs:18:2-11 • In the type signature: bar :: _a -> _b -> (_a, _b) + +SplicesUsed.hs:18:2: warning: [-Wpartial-type-signatures (in -Wdefault)] + • Found type wildcard ‘_a’ standing for ‘Bool’ + • In the type signature: bar :: _a -> _b -> (_a, _b) ===================================== testsuite/tests/plugins/hole-fit-plugin/HoleFitPlugin.hs ===================================== @@ -3,8 +3,6 @@ module HoleFitPlugin where import GHC.Plugins hiding ((<>)) -import GHC.Tc.Errors.Hole - import Data.List (stripPrefix, sortOn) import GHC.Tc.Types.Constraint @@ -34,7 +32,7 @@ fromModule (GreHFCand gre) = fromModule _ = [] toHoleFitCommand :: TypedHole -> String -> Maybe String -toHoleFitCommand TyH{tyHCt = Just (CHoleCan _ h _)} str +toHoleFitCommand (TypedHole {th_hole = Just (Hole { hole_occ = h })}) str = stripPrefix ("_" <> str) $ occNameString h toHoleFitCommand _ _ = Nothing ===================================== testsuite/tests/th/T12411.stderr ===================================== @@ -2,7 +2,7 @@ T12411.hs:4:6: error: Variable not in scope: (@) - :: (a0 -> f0 a0) -> t0 -> Language.Haskell.TH.Lib.Internal.DecsQ + :: (a1 -> f0 a1) -> t0 -> Language.Haskell.TH.Lib.Internal.DecsQ T12411.hs:4:7: error: - Data constructor not in scope: Q :: [a1] -> t0 + Data constructor not in scope: Q :: [a0] -> t0 ===================================== testsuite/tests/typecheck/should_fail/T12589.stderr ===================================== @@ -1,8 +1,8 @@ -T12589.hs:13:3: error: Variable not in scope: (&) :: t1 -> t0 -> t +T12589.hs:13:3: error: Variable not in scope: (&) :: t0 -> t1 -> t T12589.hs:13:5: error: - • Cannot instantiate unification variable ‘t0’ + • Cannot instantiate unification variable ‘t1’ with a type involving polytypes: (forall a. Bounded a => f0 a) -> h0 f0 xs0 GHC doesn't yet support impredicative polymorphism View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7ab6ab093c86227b6d33a5185ebbd11928ac9754 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7ab6ab093c86227b6d33a5185ebbd11928ac9754 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 6 08:40:17 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 06 May 2020 04:40:17 -0400 Subject: [Git][ghc/ghc][master] 3 commits: rts: Zero block flags with -DZ Message-ID: <5eb277f19f49e_61671341e944904419b@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 420b957d by Ben Gamari at 2020-05-06T04:40:08-04:00 rts: Zero block flags with -DZ Block flags are very useful for determining the state of a block. However, some block allocator users don't touch them, leading to misleading values. Ensure that we zero then when zero-on-gc is set. This is safe and makes the flags more useful during debugging. - - - - - 740b3b8d by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix incorrect failed_to_evac value during deadlock gc Previously we would incorrectly set the failed_to_evac flag if we evacuated a value due to a deadlock GC. This would cause us to mark more things as dirty than strictly necessary. It also turned up a nasty but which I will fix next. - - - - - b2d72c75 by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - 6 changed files: - rts/sm/BlockAlloc.c - rts/sm/Evac.c - rts/sm/NonMoving.c - rts/sm/NonMovingMark.c - rts/sm/NonMovingScav.c - rts/sm/Storage.c Changes: ===================================== rts/sm/BlockAlloc.c ===================================== @@ -233,6 +233,12 @@ initGroup(bdescr *head) last->blocks = 0; last->link = head; } + +#if defined(DEBUG) + for (uint32_t i=0; i < head->blocks; i++) { + head[i].flags = 0; + } +#endif } #if SIZEOF_VOID_P == SIZEOF_LONG @@ -792,6 +798,12 @@ freeGroup(bdescr *p) ASSERT(p->free != (P_)-1); +#if defined(DEBUG) + for (uint32_t i=0; i < p->blocks; i++) { + p[i].flags = 0; + } +#endif + node = p->node; p->free = (void *)-1; /* indicates that this block is free */ ===================================== rts/sm/Evac.c ===================================== @@ -80,16 +80,15 @@ alloc_for_copy (uint32_t size, uint32_t gen_no) if (gen_no < gct->evac_gen_no) { if (gct->eager_promotion) { gen_no = gct->evac_gen_no; + } else if (RTS_UNLIKELY(RtsFlags.GcFlags.useNonmoving) && deadlock_detect_gc) { + /* See Note [Deadlock detection under nonmoving collector]. */ + gen_no = oldest_gen->no; } else { gct->failed_to_evac = true; } } if (RTS_UNLIKELY(RtsFlags.GcFlags.useNonmoving)) { - /* See Note [Deadlock detection under nonmoving collector]. */ - if (deadlock_detect_gc) - gen_no = oldest_gen->no; - if (gen_no == oldest_gen->no) { gct->copied += size; to = nonmovingAllocate(gct->cap, size); ===================================== rts/sm/NonMoving.c ===================================== @@ -228,6 +228,10 @@ Mutex concurrent_coll_finished_lock; * - Note [Static objects under the nonmoving collector] (Storage.c) describes * treatment of static objects. * + * - Note [Dirty flags in the non-moving collector] (NonMoving.c) describes + * how we use the DIRTY flags associated with MUT_VARs and TVARs to improve + * barrier efficiency. + * * * Note [Concurrent non-moving collection] * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -369,6 +373,7 @@ Mutex concurrent_coll_finished_lock; * approximate due to concurrent collection and ultimately seems more costly * than the problem demands. * + * * Note [Spark management under the nonmoving collector] * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Every GC, both minor and major, prunes the spark queue (using @@ -387,6 +392,88 @@ Mutex concurrent_coll_finished_lock; * BF_EVACUATED flag won't be set on the nursery blocks) and will consequently * only prune dead sparks living in the non-moving heap. * + * + * Note [Dirty flags in the non-moving collector] + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Some mutable object types (e.g. MUT_VARs, TVARs) have a one-bit dirty flag + * encoded in their info table pointer. The moving collector uses this flag + * to minimize redundant mut_list entries. The flag is preserves the following + * simple invariant: + * + * An object being marked as dirty implies that the object is on mut_list. + * + * This allows a nice optimisation in the write barrier (e.g. dirty_MUT_VAR): + * if we write to an already-dirty object there is no need to + * push it to the mut_list as we know it's already there. + * + * During GC (scavenging) we will then keep track of whether all of the + * object's reference have been promoted. If so we can mark the object as clean. + * If not then we re-add it to mut_list and mark it as dirty. + * + * In the non-moving collector we use the same dirty flag to implement a + * related optimisation on the non-moving write barrier: Specifically, the + * snapshot invariant only requires that the non-moving write barrier applies + * to the *first* mutation to an object after collection begins. To achieve this, + * we impose the following invariant: + * + * An object being marked as dirty implies that all of its fields are on + * the mark queue (or, equivalently, update remembered set). + * + * With this guarantee we can safely make the the write barriers dirty objects + * no-ops. We perform this optimisation for the following object types: + * + * - MVAR + * - TVAR + * - MUT_VAR + * + * However, maintaining this invariant requires great care. For instance, + * consider the case of an MVar (which has two pointer fields) before + * preparatory collection: + * + * Non-moving heap ┊ Moving heap + * gen 1 ┊ gen 0 + * ──────────────────────┼──────────────────────────────── + * ┊ + * MVAR A ────────────────→ X + * (dirty) ───────────╮ + * ┊ ╰────→ Y + * ┊ │ + * ┊ │ + * ╭───────────────────────╯ + * │ ┊ + * ↓ ┊ + * Z ┊ + * ┊ + * + * During the preparatory collection we promote Y to the nonmoving heap but + * fail to promote X. Since the failed_to_evac field is conservative (being set + * if *any* of the fields are not promoted), this gives us: + * + * Non-moving heap ┊ Moving heap + * gen 1 ┊ gen 0 + * ──────────────────────┼──────────────────────────────── + * ┊ + * MVAR A ────────────────→ X + * (dirty) ┊ + * │ ┊ + * │ ┊ + * ↓ ┊ + * Y ┊ + * │ ┊ + * │ ┊ + * ↓ ┊ + * Z ┊ + * ┊ + * + * This is bad. When we resume mutation a mutator may mutate MVAR A; since it's + * already dirty we would fail to add Y to the update remembered set, breaking the + * snapshot invariant and potentially losing track of the liveness of Z. + * + * To avoid this nonmovingScavengeOne we eagerly pushes the values of the + * fields of all objects which it fails to evacuate (e.g. MVAR A) to the update + * remembered set during the preparatory GC. This allows us to safely skip the + * non-moving write barrier without jeopardizing the snapshot invariant. + * */ memcount nonmoving_live_words = 0; ===================================== rts/sm/NonMovingMark.c ===================================== @@ -27,6 +27,7 @@ #include "sm/Storage.h" #include "CNF.h" +static bool check_in_nonmoving_heap(StgClosure *p); static void mark_closure (MarkQueue *queue, const StgClosure *p, StgClosure **origin); static void mark_tso (MarkQueue *queue, StgTSO *tso); static void mark_stack (MarkQueue *queue, StgStack *stack); @@ -450,10 +451,17 @@ push (MarkQueue *q, const MarkQueueEnt *ent) void markQueuePushClosureGC (MarkQueue *q, StgClosure *p) { + if (!check_in_nonmoving_heap(p)) { + return; + } + /* We should not make it here if we are doing a deadlock detect GC. * See Note [Deadlock detection under nonmoving collector]. + * This is actually no longer true due to call in nonmovingScavengeOne + * introduced due to Note [Dirty flags in the non-moving collector] + * (see NonMoving.c). */ - ASSERT(!deadlock_detect_gc); + //ASSERT(!deadlock_detect_gc); // Are we at the end of the block? if (q->top->head == MARK_QUEUE_BLOCK_ENTRIES) { ===================================== rts/sm/NonMovingScav.c ===================================== @@ -31,6 +31,11 @@ nonmovingScavengeOne (StgClosure *q) gct->eager_promotion = saved_eager_promotion; if (gct->failed_to_evac) { mvar->header.info = &stg_MVAR_DIRTY_info; + + // Note [Dirty flags in the non-moving collector] in NonMoving.c + markQueuePushClosureGC(&gct->cap->upd_rem_set.queue, (StgClosure *) mvar->head); + markQueuePushClosureGC(&gct->cap->upd_rem_set.queue, (StgClosure *) mvar->tail); + markQueuePushClosureGC(&gct->cap->upd_rem_set.queue, (StgClosure *) mvar->value); } else { mvar->header.info = &stg_MVAR_CLEAN_info; } @@ -46,6 +51,10 @@ nonmovingScavengeOne (StgClosure *q) gct->eager_promotion = saved_eager_promotion; if (gct->failed_to_evac) { tvar->header.info = &stg_TVAR_DIRTY_info; + + // Note [Dirty flags in the non-moving collector] in NonMoving.c + markQueuePushClosureGC(&gct->cap->upd_rem_set.queue, (StgClosure *) tvar->current_value); + markQueuePushClosureGC(&gct->cap->upd_rem_set.queue, (StgClosure *) tvar->first_watch_queue_entry); } else { tvar->header.info = &stg_TVAR_CLEAN_info; } @@ -160,16 +169,21 @@ nonmovingScavengeOne (StgClosure *q) } case MUT_VAR_CLEAN: - case MUT_VAR_DIRTY: + case MUT_VAR_DIRTY: { + StgMutVar *mv = (StgMutVar *) p; gct->eager_promotion = false; - evacuate(&((StgMutVar *)p)->var); + evacuate(&mv->var); gct->eager_promotion = saved_eager_promotion; if (gct->failed_to_evac) { ((StgClosure *)q)->header.info = &stg_MUT_VAR_DIRTY_info; + + // Note [Dirty flags in the non-moving collector] in NonMoving.c + markQueuePushClosureGC(&gct->cap->upd_rem_set.queue, (StgClosure *) mv->var); } else { ((StgClosure *)q)->header.info = &stg_MUT_VAR_CLEAN_info; } break; + } case BLOCKING_QUEUE: { ===================================== rts/sm/Storage.c ===================================== @@ -1304,6 +1304,7 @@ dirty_MUT_VAR(StgRegTable *reg, StgMutVar *mvar, StgClosure *old) mvar->header.info = &stg_MUT_VAR_DIRTY_info; recordClosureMutated(cap, (StgClosure *) mvar); IF_NONMOVING_WRITE_BARRIER_ENABLED { + // See Note [Dirty flags in the non-moving collector] in NonMoving.c updateRemembSetPushClosure_(reg, old); } } @@ -1326,6 +1327,7 @@ dirty_TVAR(Capability *cap, StgTVar *p, p->header.info = &stg_TVAR_DIRTY_info; recordClosureMutated(cap,(StgClosure*)p); IF_NONMOVING_WRITE_BARRIER_ENABLED { + // See Note [Dirty flags in the non-moving collector] in NonMoving.c updateRemembSetPushClosure(cap, old); } } @@ -1407,6 +1409,7 @@ update_MVAR(StgRegTable *reg, StgClosure *p, StgClosure *old_val) { Capability *cap = regTableToCapability(reg); IF_NONMOVING_WRITE_BARRIER_ENABLED { + // See Note [Dirty flags in the non-moving collector] in NonMoving.c StgMVar *mvar = (StgMVar *) p; updateRemembSetPushClosure(cap, old_val); updateRemembSetPushClosure(cap, (StgClosure *) mvar->head); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7ab6ab093c86227b6d33a5185ebbd11928ac9754...b2d72c758233830446230800d0045badc01b42ca -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7ab6ab093c86227b6d33a5185ebbd11928ac9754...b2d72c758233830446230800d0045badc01b42ca You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 6 08:41:26 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 06 May 2020 04:41:26 -0400 Subject: [Git][ghc/ghc][master] Allow atomic update of NameCache in readHieFile Message-ID: <5eb27836655ce_6167128409c49049976@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 9f3e6884 by Zubin Duggal at 2020-05-06T04:41:08-04:00 Allow atomic update of NameCache in readHieFile The situation arises in ghcide where multiple different threads may need to update the name cache, therefore with the older interface it could happen that you start reading a hie file with name cache A and produce name cache A + B, but another thread in the meantime updated the namecache to A + C. Therefore if you write the new namecache you will lose the A' updates from the second thread. Updates haddock submodule - - - - - 4 changed files: - compiler/GHC/Driver/Main.hs - compiler/GHC/Iface/Ext/Binary.hs - testsuite/tests/hiefile/should_run/PatTypes.hs - utils/haddock Changes: ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -178,7 +178,7 @@ import Control.DeepSeq (force) import GHC.Iface.Ext.Ast ( mkHieFile ) import GHC.Iface.Ext.Types ( getAsts, hie_asts, hie_module ) -import GHC.Iface.Ext.Binary ( readHieFile, writeHieFile , hie_file_result) +import GHC.Iface.Ext.Binary ( readHieFile, writeHieFile , hie_file_result, NameCacheUpdater(..)) import GHC.Iface.Ext.Debug ( diffFile, validateScopes ) #include "HsVersions.h" @@ -438,8 +438,7 @@ extract_renamed_stuff mod_summary tc_result = do putMsg dflags $ text "Got invalid scopes" mapM_ (putMsg dflags) xs -- Roundtrip testing - nc <- readIORef $ hsc_NC hs_env - (file', _) <- readHieFile nc out_file + file' <- readHieFile (NCU $ updNameCache $ hsc_NC hs_env) out_file case diffFile hieFile (hie_file_result file') of [] -> putMsg dflags $ text "Got no roundtrip errors" ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -12,6 +12,7 @@ module GHC.Iface.Ext.Binary , HieFileResult(..) , hieMagic , hieNameOcc + , NameCacheUpdater(..) ) where @@ -33,6 +34,7 @@ import GHC.Types.Unique.Supply ( takeUniqFromSupply ) import GHC.Types.Unique import GHC.Types.Unique.FM import GHC.Utils.Misc +import GHC.Iface.Env (NameCacheUpdater(..)) import qualified Data.Array as A import Data.IORef @@ -189,23 +191,23 @@ type HieHeader = (Integer, ByteString) -- an existing `NameCache`. Allows you to specify -- which versions of hieFile to attempt to read. -- `Left` case returns the failing header versions. -readHieFileWithVersion :: (HieHeader -> Bool) -> NameCache -> FilePath -> IO (Either HieHeader (HieFileResult, NameCache)) -readHieFileWithVersion readVersion nc file = do +readHieFileWithVersion :: (HieHeader -> Bool) -> NameCacheUpdater -> FilePath -> IO (Either HieHeader HieFileResult) +readHieFileWithVersion readVersion ncu file = do bh0 <- readBinMem file (hieVersion, ghcVersion) <- readHieFileHeader file bh0 if readVersion (hieVersion, ghcVersion) then do - (hieFile, nc') <- readHieFileContents bh0 nc - return $ Right (HieFileResult hieVersion ghcVersion hieFile, nc') + hieFile <- readHieFileContents bh0 ncu + return $ Right (HieFileResult hieVersion ghcVersion hieFile) else return $ Left (hieVersion, ghcVersion) -- | Read a `HieFile` from a `FilePath`. Can use -- an existing `NameCache`. -readHieFile :: NameCache -> FilePath -> IO (HieFileResult, NameCache) -readHieFile nc file = do +readHieFile :: NameCacheUpdater -> FilePath -> IO HieFileResult +readHieFile ncu file = do bh0 <- readBinMem file @@ -219,8 +221,8 @@ readHieFile nc file = do , show hieVersion , "but got", show readHieVersion ] - (hieFile, nc') <- readHieFileContents bh0 nc - return $ (HieFileResult hieVersion ghcVersion hieFile, nc') + hieFile <- readHieFileContents bh0 ncu + return $ HieFileResult hieVersion ghcVersion hieFile readBinLine :: BinHandle -> IO ByteString readBinLine bh = BS.pack . reverse <$> loop [] @@ -254,24 +256,24 @@ readHieFileHeader file bh0 = do ] return (readHieVersion, ghcVersion) -readHieFileContents :: BinHandle -> NameCache -> IO (HieFile, NameCache) -readHieFileContents bh0 nc = do +readHieFileContents :: BinHandle -> NameCacheUpdater -> IO HieFile +readHieFileContents bh0 ncu = do dict <- get_dictionary bh0 -- read the symbol table so we are capable of reading the actual data - (bh1, nc') <- do + bh1 <- do let bh1 = setUserData bh0 $ newReadState (error "getSymtabName") (getDictFastString dict) - (nc', symtab) <- get_symbol_table bh1 + symtab <- get_symbol_table bh1 let bh1' = setUserData bh1 $ newReadState (getSymTabName symtab) (getDictFastString dict) - return (bh1', nc') + return bh1' -- load the actual data hiefile <- get bh1 - return (hiefile, nc') + return hiefile where get_dictionary bin_handle = do dict_p <- get bin_handle @@ -285,9 +287,9 @@ readHieFileContents bh0 nc = do symtab_p <- get bh1 data_p' <- tellBin bh1 seekBin bh1 symtab_p - (nc', symtab) <- getSymbolTable bh1 nc + symtab <- getSymbolTable bh1 ncu seekBin bh1 data_p' - return (nc', symtab) + return symtab putFastString :: HieDictionary -> BinHandle -> FastString -> IO () putFastString HieDictionary { hie_dict_next = j_r, @@ -309,13 +311,14 @@ putSymbolTable bh next_off symtab = do let names = A.elems (A.array (0,next_off-1) (nonDetEltsUFM symtab)) mapM_ (putHieName bh) names -getSymbolTable :: BinHandle -> NameCache -> IO (NameCache, SymbolTable) -getSymbolTable bh namecache = do +getSymbolTable :: BinHandle -> NameCacheUpdater -> IO SymbolTable +getSymbolTable bh ncu = do sz <- get bh od_names <- replicateM sz (getHieName bh) - let arr = A.listArray (0,sz-1) names - (namecache', names) = mapAccumR fromHieName namecache od_names - return (namecache', arr) + updateNameCache ncu $ \nc -> + let arr = A.listArray (0,sz-1) names + (nc', names) = mapAccumR fromHieName nc od_names + in (nc',arr) getSymTabName :: SymbolTable -> BinHandle -> IO Name getSymTabName st bh = do ===================================== testsuite/tests/hiefile/should_run/PatTypes.hs ===================================== @@ -57,7 +57,7 @@ main = do libdir:_ <- getArgs df <- dynFlagsForPrinting libdir nc <- makeNc - (hfr, nc') <- readHieFile nc "PatTypes.hie" + hfr <- readHieFile (NCU (\f -> pure $ snd $ f nc)) "PatTypes.hie" let hf = hie_file_result hfr forM_ [p1,p2,p3,p4] $ \point -> do putStr $ "At " ++ show point ++ ", got type: " ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit c60995fe05d9cc267e892448604b8b96a705ccc7 +Subproject commit 97f301a63ea8461074bfaa1486eb798e4be65f15 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9f3e6884e338015f2953c4c0844e04d467f53dd5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9f3e6884e338015f2953c4c0844e04d467f53dd5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 6 08:42:08 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 06 May 2020 04:42:08 -0400 Subject: [Git][ghc/ghc][master] Make isTauTy detect higher-rank contexts Message-ID: <5eb2786058f0b_61673f81cd4c695c90542e3@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: edec6a6c by Ryan Scott at 2020-05-06T04:41:57-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _)`. Fixes #18127. - - - - - 7 changed files: - compiler/GHC/Core/Type.hs - + testsuite/tests/deriving/should_fail/T18127b.hs - + testsuite/tests/deriving/should_fail/T18127b.stderr - testsuite/tests/deriving/should_fail/all.T - + testsuite/tests/typecheck/should_fail/T18127a.hs - + testsuite/tests/typecheck/should_fail/T18127a.stderr - testsuite/tests/typecheck/should_fail/all.T Changes: ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -1857,17 +1857,19 @@ fun_kind_arg_flags = go emptyTCvSubst -- something is ill-kinded. But this can happen -- when printing errors. Assume everything is Required. --- @isTauTy@ tests if a type has no foralls +-- @isTauTy@ tests if a type has no foralls or (=>) isTauTy :: Type -> Bool isTauTy ty | Just ty' <- coreView ty = isTauTy ty' -isTauTy (TyVarTy _) = True -isTauTy (LitTy {}) = True -isTauTy (TyConApp tc tys) = all isTauTy tys && isTauTyCon tc -isTauTy (AppTy a b) = isTauTy a && isTauTy b -isTauTy (FunTy _ a b) = isTauTy a && isTauTy b -isTauTy (ForAllTy {}) = False -isTauTy (CastTy ty _) = isTauTy ty -isTauTy (CoercionTy _) = False -- Not sure about this +isTauTy (TyVarTy _) = True +isTauTy (LitTy {}) = True +isTauTy (TyConApp tc tys) = all isTauTy tys && isTauTyCon tc +isTauTy (AppTy a b) = isTauTy a && isTauTy b +isTauTy (FunTy af a b) = case af of + InvisArg -> False -- e.g., Eq a => b + VisArg -> isTauTy a && isTauTy b -- e.g., a -> b +isTauTy (ForAllTy {}) = False +isTauTy (CastTy ty _) = isTauTy ty +isTauTy (CoercionTy _) = False -- Not sure about this {- %************************************************************************ ===================================== testsuite/tests/deriving/should_fail/T18127b.hs ===================================== @@ -0,0 +1,8 @@ +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE RankNTypes #-} +module T18127b where + +import GHC.Generics + +data T1 = MkT1 (forall a. a) deriving (Eq, Generic) +data T2 a = MkT2 (Show a => a) deriving (Eq, Generic) ===================================== testsuite/tests/deriving/should_fail/T18127b.stderr ===================================== @@ -0,0 +1,22 @@ + +T18127b.hs:7:40: error: + • Can't make a derived instance of ‘Eq T1’: + Constructor ‘MkT1’ has a higher-rank type + Possible fix: use a standalone deriving declaration instead + • In the data declaration for ‘T1’ + +T18127b.hs:7:44: error: + • Can't make a derived instance of ‘Generic T1’: + MkT1 must not have exotic unlifted or polymorphic arguments + • In the data declaration for ‘T1’ + +T18127b.hs:8:42: error: + • Can't make a derived instance of ‘Eq (T2 a)’: + Constructor ‘MkT2’ has a higher-rank type + Possible fix: use a standalone deriving declaration instead + • In the data declaration for ‘T2’ + +T18127b.hs:8:46: error: + • Can't make a derived instance of ‘Generic (T2 a)’: + MkT2 must not have exotic unlifted or polymorphic arguments + • In the data declaration for ‘T2’ ===================================== testsuite/tests/deriving/should_fail/all.T ===================================== @@ -76,6 +76,7 @@ test('T15073', [extra_files(['T15073a.hs'])], multimod_compile_fail, ['T15073', '-v0']) test('T16181', normal, compile_fail, ['']) test('T16923', normal, compile_fail, ['']) +test('T18127b', normal, compile_fail, ['']) test('deriving-via-fail', normal, compile_fail, ['']) test('deriving-via-fail2', normal, compile_fail, ['']) test('deriving-via-fail3', normal, compile_fail, ['']) ===================================== testsuite/tests/typecheck/should_fail/T18127a.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE RankNTypes #-} +module T18127a where + +a :: (forall a. a) -> () +a = undefined + +b :: (Show a => a) -> () +b = undefined + +type C = forall a. a +c :: C -> () +c = undefined + +type D a = Show a => a +d :: D a -> () +d = undefined ===================================== testsuite/tests/typecheck/should_fail/T18127a.stderr ===================================== @@ -0,0 +1,32 @@ + +T18127a.hs:5:5: error: + • Cannot instantiate unification variable ‘a1’ + with a type involving polytypes: (forall a. a) -> () + GHC doesn't yet support impredicative polymorphism + • In the expression: undefined + In an equation for ‘a’: a = undefined + +T18127a.hs:8:5: error: + • Cannot instantiate unification variable ‘a3’ + with a type involving polytypes: (Show a => a) -> () + GHC doesn't yet support impredicative polymorphism + • In the expression: undefined + In an equation for ‘b’: b = undefined + • Relevant bindings include + b :: (Show a => a) -> () (bound at T18127a.hs:8:1) + +T18127a.hs:12:5: error: + • Cannot instantiate unification variable ‘a0’ + with a type involving polytypes: C -> () + GHC doesn't yet support impredicative polymorphism + • In the expression: undefined + In an equation for ‘c’: c = undefined + +T18127a.hs:16:5: error: + • Cannot instantiate unification variable ‘a2’ + with a type involving polytypes: D a -> () + GHC doesn't yet support impredicative polymorphism + • In the expression: undefined + In an equation for ‘d’: d = undefined + • Relevant bindings include + d :: D a -> () (bound at T18127a.hs:16:1) ===================================== testsuite/tests/typecheck/should_fail/all.T ===================================== @@ -563,3 +563,4 @@ test('T17021', normal, compile_fail, ['']) test('T17021b', normal, compile_fail, ['']) test('T17955', normal, compile_fail, ['']) test('T17173', normal, compile_fail, ['']) +test('T18127a', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/edec6a6c205378caf15d1d874d7e901ba76dd293 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/edec6a6c205378caf15d1d874d7e901ba76dd293 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 6 08:42:50 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 06 May 2020 04:42:50 -0400 Subject: [Git][ghc/ghc][master] ELF linker: increment curSymbol after filling in fields of current entry Message-ID: <5eb2788a64369_61673f81cc913ba09056992@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: a95e7fe0 by Ömer Sinan Ağacan at 2020-05-06T04:42:39-04:00 ELF linker: increment curSymbol after filling in fields of current entry The bug was introduced in a8b7cef4d45 which added a field to the `symbols` array elements and then updated this code incorrectly: - oc->symbols[curSymbol++] = nm; + oc->symbols[curSymbol++].name = nm; + oc->symbols[curSymbol].addr = symbol->addr; - - - - - 1 changed file: - rts/linker/Elf.c Changes: ===================================== rts/linker/Elf.c ===================================== @@ -944,8 +944,9 @@ ocGetNames_ELF ( ObjectCode* oc ) ) { goto fail; } - oc->symbols[curSymbol++].name = nm; + oc->symbols[curSymbol].name = nm; oc->symbols[curSymbol].addr = symbol->addr; + curSymbol++; } } else { /* Skip. */ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a95e7fe02efd2fdeec91ba46de64bc78c81381eb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a95e7fe02efd2fdeec91ba46de64bc78c81381eb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 6 08:43:33 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 06 May 2020 04:43:33 -0400 Subject: [Git][ghc/ghc][master] 2 commits: Move LeadingUnderscore into Platform (#17957) Message-ID: <5eb278b52bed2_61673f81cc913ba090596f5@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: cab1871a by Sylvain Henry at 2020-05-06T04:43:21-04:00 Move LeadingUnderscore into Platform (#17957) Avoid direct use of DynFlags to know if symbols must be prefixed by an underscore. - - - - - 94e7c563 by Sylvain Henry at 2020-05-06T04:43:21-04:00 Don't use DynFlags in showLinkerState (#17957) - - - - - 8 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Runtime/Linker.hs - compiler/GHC/Settings.hs - compiler/GHC/Settings/IO.hs - ghc/GHCi/UI.hs - libraries/ghc-boot/GHC/Platform.hs - libraries/ghc-boot/GHC/Settings/Platform.hs Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -1218,7 +1218,7 @@ pprCLabel dflags = \case maybe_underscore :: SDoc -> SDoc maybe_underscore doc = - if platformMisc_leadingUnderscore $ platformMisc dflags + if platformLeadingUnderscore platform then pp_cSEP <> doc else doc ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -135,7 +135,6 @@ module GHC.Driver.Session ( sGhcWithSMP, sGhcRTSWays, sTablesNextToCode, - sLeadingUnderscore, sLibFFI, sGhcThreaded, sGhcDebugged, ===================================== compiler/GHC/Runtime/Linker.hs ===================================== @@ -234,11 +234,10 @@ withExtendedLinkEnv dl new_env action -- | Display the persistent linker state. -showLinkerState :: DynLinker -> DynFlags -> IO () -showLinkerState dl dflags +showLinkerState :: DynLinker -> IO SDoc +showLinkerState dl = do pls <- readPLS dl - putLogMsg dflags NoReason SevDump noSrcSpan - $ withPprStyle defaultDumpStyle + return $ withPprStyle defaultDumpStyle (vcat [text "----- Linker state -----", text "Pkgs:" <+> ppr (pkgs_loaded pls), text "Objs:" <+> ppr (objs_loaded pls), ===================================== compiler/GHC/Settings.hs ===================================== @@ -62,7 +62,6 @@ module GHC.Settings , sGhcWithSMP , sGhcRTSWays , sTablesNextToCode - , sLeadingUnderscore , sLibFFI , sGhcThreaded , sGhcDebugged @@ -277,8 +276,6 @@ sGhcRTSWays :: Settings -> String sGhcRTSWays = platformMisc_ghcRTSWays . sPlatformMisc sTablesNextToCode :: Settings -> Bool sTablesNextToCode = platformMisc_tablesNextToCode . sPlatformMisc -sLeadingUnderscore :: Settings -> Bool -sLeadingUnderscore = platformMisc_leadingUnderscore . sPlatformMisc sLibFFI :: Settings -> Bool sLibFFI = platformMisc_libFFI . sPlatformMisc sGhcThreaded :: Settings -> Bool ===================================== compiler/GHC/Settings/IO.hs ===================================== @@ -166,7 +166,6 @@ initSettings top_dir = do ghcWithNativeCodeGen <- getBooleanSetting "Use native code generator" ghcWithSMP <- getBooleanSetting "Support SMP" ghcRTSWays <- getSetting "RTS ways" - leadingUnderscore <- getBooleanSetting "Leading underscore" useLibFFI <- getBooleanSetting "Use LibFFI" ghcThreaded <- getBooleanSetting "Use Threads" ghcDebugged <- getBooleanSetting "Use Debugging" @@ -237,7 +236,6 @@ initSettings top_dir = do , platformMisc_ghcWithSMP = ghcWithSMP , platformMisc_ghcRTSWays = ghcRTSWays , platformMisc_tablesNextToCode = tablesNextToCode - , platformMisc_leadingUnderscore = leadingUnderscore , platformMisc_libFFI = useLibFFI , platformMisc_ghcThreaded = ghcThreaded , platformMisc_ghcDebugged = ghcDebugged ===================================== ghc/GHCi/UI.hs ===================================== @@ -3047,7 +3047,10 @@ showCmd str = do , action "imports" $ showImports , action "modules" $ showModules , action "bindings" $ showBindings - , action "linker" $ getDynFlags >>= liftIO . (showLinkerState (hsc_dynLinker hsc_env)) + , action "linker" $ do + msg <- liftIO $ showLinkerState (hsc_dynLinker hsc_env) + dflags <- getDynFlags + liftIO $ putLogMsg dflags NoReason SevDump noSrcSpan msg , action "breaks" $ showBkptTable , action "context" $ showContext , action "packages" $ showPackages ===================================== libraries/ghc-boot/GHC/Platform.hs ===================================== @@ -55,16 +55,17 @@ data PlatformMini deriving (Read, Show, Eq) -- | Contains enough information for the native code generator to emit --- code for this platform. +-- code for this platform. data Platform = Platform - { platformMini :: PlatformMini - , platformWordSize :: PlatformWordSize - , platformByteOrder :: ByteOrder - , platformUnregisterised :: Bool - , platformHasGnuNonexecStack :: Bool - , platformHasIdentDirective :: Bool - , platformHasSubsectionsViaSymbols :: Bool - , platformIsCrossCompiling :: Bool + { platformMini :: !PlatformMini + , platformWordSize :: !PlatformWordSize -- ^ Word size + , platformByteOrder :: !ByteOrder -- ^ Byte order (endianness) + , platformUnregisterised :: !Bool + , platformHasGnuNonexecStack :: !Bool + , platformHasIdentDirective :: !Bool + , platformHasSubsectionsViaSymbols :: !Bool + , platformIsCrossCompiling :: !Bool + , platformLeadingUnderscore :: !Bool -- ^ Symbols need underscore prefix } deriving (Read, Show, Eq) @@ -301,7 +302,6 @@ data PlatformMisc = PlatformMisc -- before the entry code, or with an indirection to the entry code. See -- TABLES_NEXT_TO_CODE in includes/rts/storage/InfoTables.h. , platformMisc_tablesNextToCode :: Bool - , platformMisc_leadingUnderscore :: Bool , platformMisc_libFFI :: Bool , platformMisc_ghcThreaded :: Bool , platformMisc_ghcDebugged :: Bool ===================================== libraries/ghc-boot/GHC/Settings/Platform.hs ===================================== @@ -37,6 +37,7 @@ getTargetPlatform settingsFile mySettings = do targetOS <- readSetting "target os" targetWordSize <- readSetting "target word size" targetWordBigEndian <- getBooleanSetting "target word big endian" + targetLeadingUnderscore <- getBooleanSetting "Leading underscore" targetUnregisterised <- getBooleanSetting "Unregisterised" targetHasGnuNonexecStack <- getBooleanSetting "target has GNU nonexec stack" targetHasIdentDirective <- getBooleanSetting "target has .ident directive" @@ -55,6 +56,7 @@ getTargetPlatform settingsFile mySettings = do , platformHasIdentDirective = targetHasIdentDirective , platformHasSubsectionsViaSymbols = targetHasSubsectionsViaSymbols , platformIsCrossCompiling = crossCompiling + , platformLeadingUnderscore = targetLeadingUnderscore } ----------------------------------------------------------------------------- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a95e7fe02efd2fdeec91ba46de64bc78c81381eb...94e7c563ab24fe452a16900a6777349970df1945 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a95e7fe02efd2fdeec91ba46de64bc78c81381eb...94e7c563ab24fe452a16900a6777349970df1945 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 6 08:44:07 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 06 May 2020 04:44:07 -0400 Subject: [Git][ghc/ghc][master] Refactoring: Use bindSigTyVarsFV in rnMethodBinds Message-ID: <5eb278d7e8cb1_6167128560089062595@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 9afd9251 by Ryan Scott at 2020-05-06T04:43:58-04:00 Refactoring: Use bindSigTyVarsFV in rnMethodBinds `rnMethodBinds` was explicitly using `xoptM` to determine if `ScopedTypeVariables` is enabled before bringing type variables bound by the class/instance header into scope. However, this `xoptM` logic is already performed by the `bindSigTyVarsFV` function. This patch uses `bindSigTyVarsFV` in `rnMethodBinds` to reduce the number of places where we need to consult if `ScopedTypeVariables` is on. This is purely refactoring, and there should be no user-visible change in behavior. - - - - - 1 changed file: - compiler/GHC/Rename/Bind.hs Changes: ===================================== compiler/GHC/Rename/Bind.hs ===================================== @@ -869,8 +869,7 @@ rnMethodBinds is_cls_decl cls ktv_names binds sigs -- Rename the bindings RHSs. Again there's an issue about whether the -- type variables from the class/instance head are in scope. -- Answer no in Haskell 2010, but yes if you have -XScopedTypeVariables - ; scoped_tvs <- xoptM LangExt.ScopedTypeVariables - ; (binds'', bind_fvs) <- maybe_extend_tyvar_env scoped_tvs $ + ; (binds'', bind_fvs) <- bindSigTyVarsFV ktv_names $ do { binds_w_dus <- mapBagM (rnLBind (mkScopedTvFn other_sigs')) binds' ; let bind_fvs = foldr (\(_,_,fv1) fv2 -> fv1 `plusFV` fv2) emptyFVs binds_w_dus @@ -878,12 +877,6 @@ rnMethodBinds is_cls_decl cls ktv_names binds sigs ; return ( binds'', spec_inst_prags' ++ other_sigs' , sig_fvs `plusFV` sip_fvs `plusFV` bind_fvs) } - where - -- For the method bindings in class and instance decls, we extend - -- the type variable environment iff -XScopedTypeVariables - maybe_extend_tyvar_env scoped_tvs thing_inside - | scoped_tvs = extendTyVarEnvFVRn ktv_names thing_inside - | otherwise = thing_inside rnMethodBindLHS :: Bool -> Name -> LHsBindLR GhcPs GhcPs View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9afd92512b41cf6c6de3a17b474d8d4bb01158c3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9afd92512b41cf6c6de3a17b474d8d4bb01158c3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 6 09:39:39 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 06 May 2020 05:39:39 -0400 Subject: [Git][ghc/ghc][wip/T17917] Avoid useless w/w split Message-ID: <5eb285dbadd98_61671341e94490778a2@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T17917 at Glasgow Haskell Compiler / GHC Commits: 9d122faa by Simon Peyton Jones at 2020-05-06T09:39:05+00:00 Avoid useless w/w split This patch is just a tidy-up for the post-strictness-analysis worker wrapper split. Consider f x = x Strictnesss analysis does not lead to a w/w split, so the obvious thing is to leave it 100% alone. But actually, because the RHS is small, we ended up adding a StableUnfolding for it. There is some reason to do this if we choose /not/ do to w/w on the grounds that the function is small. See Note [Don't w/w inline small non-loop-breaker things] But there is no reason if we would not have done w/w anyway. This patch just moves the conditional to later. Easy. This does move soem -ddump-simpl printouts around a bit. I also discovered that the previous code was overwritten an InlineCompulsory with InlineStable, which is utterly wrong. That in turn meant that some default methods (marked InlineCompulsory) were getting their InlineCompulsory squashed. This patch fixes that bug --- but of course that does mean a bit more inlining! - - - - - 11 changed files: - compiler/GHC/Core/Opt/WorkWrap.hs - compiler/GHC/Core/Unfold.hs - testsuite/tests/dependent/should_compile/dynamic-paper.stderr - testsuite/tests/driver/inline-check.stderr - testsuite/tests/numeric/should_compile/T14465.stdout - testsuite/tests/perf/compiler/T16473.stdout - testsuite/tests/simplCore/should_compile/T17901.stdout - testsuite/tests/simplCore/should_compile/T17966.stdout - testsuite/tests/simplCore/should_compile/T4201.stdout - testsuite/tests/simplCore/should_compile/T5658b.stdout - testsuite/tests/warnings/should_compile/T16282/T16282.stderr Changes: ===================================== compiler/GHC/Core/Opt/WorkWrap.hs ===================================== @@ -26,6 +26,7 @@ import GHC.Types.Cpr import GHC.Core.Opt.WorkWrap.Utils import GHC.Utils.Misc import GHC.Utils.Outputable +import GHC.Types.Unique import GHC.Core.FamInstEnv import GHC.Utils.Monad @@ -203,6 +204,23 @@ unfolding to the *worker*. So we will get something like this: How do we "transfer the unfolding"? Easy: by using the old one, wrapped in work_fn! See GHC.Core.Unfold.mkWorkerUnfolding. +Note [No worker-wrapper for record selectors] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +We sometimes generate a lot of record selectors, and generally the +don't benefit from worker/wrapper. Yes, mkWwBodies would find a w/w split, +but it is then suppressed by the certainlyWillInline test in splitFun. + +The wasted effort in mkWwBodies makes a measurable difference in +compile time (see MR !2873), so although it's a terribly ad-hoc test, +we just check here for record selectors, and do a no-op in that case. + +I did look for a generalisation, so that it's not just record +selectors that benefit. But you'd need a cheap test for "this +function will definitely get a w/w split" and that's hard to predict +in advance...the logic in mkWwBodies is complex. So I've left the +super-simple test, with this Note to explain. + + Note [Worker-wrapper for NOINLINE functions] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We used to disable worker/wrapper for NOINLINE things, but it turns out @@ -316,8 +334,8 @@ Note [Don't w/w inline small non-loop-breaker things] In general, we refrain from w/w-ing *small* functions, which are not loop breakers, because they'll inline anyway. But we must take care: it may look small now, but get to be big later after other inlining -has happened. So we take the precaution of adding an INLINE pragma to -any such functions. +has happened. So we take the precaution of adding a StableUnfolding +for any such functions. I made this change when I observed a big function at the end of compilation with a useful strictness signature but no w-w. (It was @@ -457,11 +475,6 @@ tryWW :: DynFlags tryWW dflags fam_envs is_rec fn_id rhs -- See Note [Worker-wrapper for NOINLINE functions] - | Just stable_unf <- certainlyWillInline dflags fn_info - = return [ (fn_id `setIdUnfolding` stable_unf, rhs) ] - -- See Note [Don't w/w INLINE things] - -- See Note [Don't w/w inline small non-loop-breaker things] - | is_fun && is_eta_exp = splitFun dflags fam_envs new_fn_id fn_info wrap_dmds div cpr rhs @@ -567,105 +580,125 @@ See https://gitlab.haskell.org/ghc/ghc/merge_requests/312#note_192064. splitFun :: DynFlags -> FamInstEnvs -> Id -> IdInfo -> [Demand] -> Divergence -> CprResult -> CoreExpr -> UniqSM [(Id, CoreExpr)] splitFun dflags fam_envs fn_id fn_info wrap_dmds div cpr rhs - = WARN( not (wrap_dmds `lengthIs` arity), ppr fn_id <+> (ppr arity $$ ppr wrap_dmds $$ ppr cpr) ) do - -- The arity should match the signature - stuff <- mkWwBodies dflags fam_envs rhs_fvs fn_id wrap_dmds use_cpr_info - case stuff of - Just (work_demands, join_arity, wrap_fn, work_fn) -> do - work_uniq <- getUniqueM - let work_rhs = work_fn rhs - work_act = case fn_inline_spec of -- See Note [Worker activation] - NoInline -> fn_act - _ -> wrap_act - - work_prag = InlinePragma { inl_src = SourceText "{-# INLINE" - , inl_inline = fn_inline_spec - , inl_sat = Nothing - , inl_act = work_act - , inl_rule = FunLike } - -- inl_inline: copy from fn_id; see Note [Worker-wrapper for INLINABLE functions] - -- inl_act: see Note [Worker activation] - -- inl_rule: it does not make sense for workers to be constructorlike. - - work_join_arity | isJoinId fn_id = Just join_arity - | otherwise = Nothing - -- worker is join point iff wrapper is join point - -- (see Note [Don't w/w join points for CPR]) - - work_id = mkWorkerId work_uniq fn_id (exprType work_rhs) - `setIdOccInfo` occInfo fn_info - -- Copy over occurrence info from parent - -- Notably whether it's a loop breaker - -- Doesn't matter much, since we will simplify next, but - -- seems right-er to do so - - `setInlinePragma` work_prag - - `setIdUnfolding` mkWorkerUnfolding dflags work_fn fn_unfolding - -- See Note [Worker-wrapper for INLINABLE functions] - - `setIdStrictness` mkClosedStrictSig work_demands div - -- Even though we may not be at top level, - -- it's ok to give it an empty DmdEnv - - `setIdCprInfo` mkCprSig work_arity work_cpr_info - - `setIdDemandInfo` worker_demand - - `setIdArity` work_arity - -- Set the arity so that the Core Lint check that the - -- arity is consistent with the demand type goes - -- through - `asJoinId_maybe` work_join_arity - - work_arity = length work_demands - - -- See Note [Demand on the Worker] - single_call = saturatedByOneShots arity (demandInfo fn_info) - worker_demand | single_call = mkWorkerDemand work_arity - | otherwise = topDmd - - wrap_rhs = wrap_fn work_id - wrap_act = case fn_act of -- See Note [Wrapper activation] - ActiveAfter {} -> fn_act - NeverActive -> activeDuringFinal - _ -> activeAfterInitial - wrap_prag = InlinePragma { inl_src = SourceText "{-# INLINE" - , inl_inline = NoUserInline - , inl_sat = Nothing - , inl_act = wrap_act - , inl_rule = rule_match_info } - -- inl_act: see Note [Wrapper activation] - -- inl_inline: see Note [Wrapper NoUserInline] - -- inl_rule: RuleMatchInfo is (and must be) unaffected - - wrap_id = fn_id `setIdUnfolding` mkWwInlineRule dflags wrap_rhs arity - `setInlinePragma` wrap_prag - `setIdOccInfo` noOccInfo - -- Zap any loop-breaker-ness, to avoid bleating from Lint - -- about a loop breaker with an INLINE rule - - - - return $ [(work_id, work_rhs), (wrap_id, wrap_rhs)] - -- Worker first, because wrapper mentions it - - Nothing -> return [(fn_id, rhs)] + | isRecordSelector fn_id -- See Note [No worker/wrapper for record selectors] + = return [ (fn_id, rhs ) ] + + | otherwise + = WARN( not (wrap_dmds `lengthIs` arity), ppr fn_id <+> (ppr arity $$ ppr wrap_dmds $$ ppr cpr) ) + -- The arity should match the signature + do { mb_stuff <- mkWwBodies dflags fam_envs rhs_fvs fn_id wrap_dmds use_cpr_info + ; case mb_stuff of + Nothing -> return [(fn_id, rhs)] + + Just stuff + | Just stable_unf <- certainlyWillInline dflags fn_info + -> return [ (fn_id `setIdUnfolding` stable_unf, rhs) ] + -- See Note [Don't w/w INLINE things] + -- See Note [Don't w/w inline small non-loop-breaker things] + + | otherwise + -> do { work_uniq <- getUniqueM + ; return (mkWWBindPair dflags fn_id fn_info arity rhs + work_uniq div cpr stuff) } } where - rhs_fvs = exprFreeVars rhs + rhs_fvs = exprFreeVars rhs + arity = arityInfo fn_info + -- The arity is set by the simplifier using exprEtaExpandArity + -- So it may be more than the number of top-level-visible lambdas + + -- use_cpr_info is the CPR we w/w for. Note that we kill it for join points, + -- see Note [Don't w/w join points for CPR]. + use_cpr_info | isJoinId fn_id = topCpr + | otherwise = cpr + + +mkWWBindPair :: DynFlags -> Id -> IdInfo -> Arity + -> CoreExpr -> Unique -> Divergence -> CprResult + -> ([Demand], JoinArity, Id -> CoreExpr, Expr CoreBndr -> CoreExpr) + -> [(Id, CoreExpr)] +mkWWBindPair dflags fn_id fn_info arity rhs work_uniq div cpr + (work_demands, join_arity, wrap_fn, work_fn) + = [(work_id, work_rhs), (wrap_id, wrap_rhs)] + -- Worker first, because wrapper mentions it + where + work_rhs = work_fn rhs + work_act = case fn_inline_spec of -- See Note [Worker activation] + NoInline -> fn_act + _ -> wrap_act + + work_prag = InlinePragma { inl_src = SourceText "{-# INLINE" + , inl_inline = fn_inline_spec + , inl_sat = Nothing + , inl_act = work_act + , inl_rule = FunLike } + -- inl_inline: copy from fn_id; see Note [Worker-wrapper for INLINABLE functions] + -- inl_act: see Note [Worker activation] + -- inl_rule: it does not make sense for workers to be constructorlike. + + work_join_arity | isJoinId fn_id = Just join_arity + | otherwise = Nothing + -- worker is join point iff wrapper is join point + -- (see Note [Don't w/w join points for CPR]) + + work_id = mkWorkerId work_uniq fn_id (exprType work_rhs) + `setIdOccInfo` occInfo fn_info + -- Copy over occurrence info from parent + -- Notably whether it's a loop breaker + -- Doesn't matter much, since we will simplify next, but + -- seems right-er to do so + + `setInlinePragma` work_prag + + `setIdUnfolding` mkWorkerUnfolding dflags work_fn fn_unfolding + -- See Note [Worker-wrapper for INLINABLE functions] + + `setIdStrictness` mkClosedStrictSig work_demands div + -- Even though we may not be at top level, + -- it's ok to give it an empty DmdEnv + + `setIdCprInfo` mkCprSig work_arity work_cpr_info + + `setIdDemandInfo` worker_demand + + `setIdArity` work_arity + -- Set the arity so that the Core Lint check that the + -- arity is consistent with the demand type goes + -- through + `asJoinId_maybe` work_join_arity + + work_arity = length work_demands + + -- See Note [Demand on the Worker] + single_call = saturatedByOneShots arity (demandInfo fn_info) + worker_demand | single_call = mkWorkerDemand work_arity + | otherwise = topDmd + + wrap_rhs = wrap_fn work_id + wrap_act = case fn_act of -- See Note [Wrapper activation] + ActiveAfter {} -> fn_act + NeverActive -> activeDuringFinal + _ -> activeAfterInitial + wrap_prag = InlinePragma { inl_src = SourceText "{-# INLINE" + , inl_inline = NoUserInline + , inl_sat = Nothing + , inl_act = wrap_act + , inl_rule = rule_match_info } + -- inl_act: see Note [Wrapper activation] + -- inl_inline: see Note [Wrapper NoUserInline] + -- inl_rule: RuleMatchInfo is (and must be) unaffected + + wrap_id = fn_id `setIdUnfolding` mkWwInlineRule dflags wrap_rhs arity + `setInlinePragma` wrap_prag + `setIdOccInfo` noOccInfo + -- Zap any loop-breaker-ness, to avoid bleating from Lint + -- about a loop breaker with an INLINE rule + fn_inl_prag = inlinePragInfo fn_info fn_inline_spec = inl_inline fn_inl_prag fn_act = inl_act fn_inl_prag rule_match_info = inlinePragmaRuleMatchInfo fn_inl_prag fn_unfolding = unfoldingInfo fn_info - arity = arityInfo fn_info - -- The arity is set by the simplifier using exprEtaExpandArity - -- So it may be more than the number of top-level-visible lambdas - -- use_cpr_info is the CPR we w/w for. Note that we kill it for join points, - -- see Note [Don't w/w join points for CPR]. - use_cpr_info | isJoinId fn_id = topCpr - | otherwise = cpr -- Even if we don't w/w join points for CPR, we might still do so for -- strictness. In which case a join point worker keeps its original CPR -- property; see Note [Don't w/w join points for CPR]. Otherwise, the worker ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -1121,11 +1121,21 @@ certainlyWillInline :: DynFlags -> IdInfo -> Maybe Unfolding -- ^ Sees if the unfolding is pretty certain to inline. -- If so, return a *stable* unfolding for it, that will always inline. certainlyWillInline dflags fn_info - = case unfoldingInfo fn_info of - CoreUnfolding { uf_tmpl = e, uf_guidance = g } - | loop_breaker -> Nothing -- Won't inline, so try w/w - | noinline -> Nothing -- See Note [Worker-wrapper for NOINLINE functions] - | otherwise -> do_cunf e g -- Depends on size, so look at that + = case fn_unf of + CoreUnfolding { uf_tmpl = expr, uf_guidance = guidance, uf_src = src } + | loop_breaker -> Nothing -- Won't inline, so try w/w + | noinline -> Nothing -- See Note [Worker-wrapper for NOINLINE functions] + | otherwise + -> case guidance of + UnfNever -> Nothing + UnfWhen {} -> Just (fn_unf { uf_src = src' }) + -- INLINE functions have UnfWhen + UnfIfGoodArgs { ug_size = size, ug_args = args } + -> do_cunf expr size args src' + where + src' = case src of + InlineRhs -> InlineStable + _ -> src -- Do not change InlineCompulsory! DFunUnfolding {} -> Just fn_unf -- Don't w/w DFuns; it never makes sense -- to do so, and even if it is currently a @@ -1138,17 +1148,12 @@ certainlyWillInline dflags fn_info noinline = inlinePragmaSpec (inlinePragInfo fn_info) == NoInline fn_unf = unfoldingInfo fn_info - do_cunf :: CoreExpr -> UnfoldingGuidance -> Maybe Unfolding - do_cunf _ UnfNever = Nothing - do_cunf _ (UnfWhen {}) = Just (fn_unf { uf_src = InlineStable }) - -- INLINE functions have UnfWhen - -- The UnfIfGoodArgs case seems important. If we w/w small functions -- binary sizes go up by 10%! (This is with SplitObjs.) -- I'm not totally sure why. -- INLINABLE functions come via this path -- See Note [certainlyWillInline: INLINABLE] - do_cunf expr (UnfIfGoodArgs { ug_size = size, ug_args = args }) + do_cunf expr size args src' | arityInfo fn_info > 0 -- See Note [certainlyWillInline: be careful of thunks] , not (isBottomingSig (strictnessInfo fn_info)) -- Do not unconditionally inline a bottoming functions even if @@ -1156,7 +1161,7 @@ certainlyWillInline dflags fn_info -- so we don't want to re-inline it. , let unf_arity = length args , size - (10 * (unf_arity + 1)) <= ufUseThreshold dflags - = Just (fn_unf { uf_src = InlineStable + = Just (fn_unf { uf_src = src' , uf_guidance = UnfWhen { ug_arity = unf_arity , ug_unsat_ok = unSaturatedOk , ug_boring_ok = inlineBoringOk expr } }) ===================================== testsuite/tests/dependent/should_compile/dynamic-paper.stderr ===================================== @@ -12,4 +12,4 @@ Simplifier ticks exhausted simplifier non-termination has been judged acceptable. To see detailed counts use -ddump-simpl-stats - Total ticks: 138082 + Total ticks: 157721 ===================================== testsuite/tests/driver/inline-check.stderr ===================================== @@ -21,6 +21,7 @@ Considering inlining: foo some_benefit False is exp: True is work-free: True - guidance ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False) + guidance IF_ARGS [0] 30 0 + discounted size = 20 ANSWER = NO Inactive unfolding: foo1 ===================================== testsuite/tests/numeric/should_compile/T14465.stdout ===================================== @@ -82,10 +82,8 @@ plusOne :: Natural -> Natural [GblId, Arity=1, Str=, - Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, - Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False) - Tmpl= \ (n [Occ=Once] :: Natural) -> plusNatural n M.minusOne1}] + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [0] 30 0}] plusOne = \ (n :: Natural) -> plusNatural n M.minusOne1 -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} ===================================== testsuite/tests/perf/compiler/T16473.stdout ===================================== @@ -2,10 +2,10 @@ Rule fired: Class op fmap (BUILTIN) Rule fired: Class op liftA2 (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) Rule fired: Class op <*> (BUILTIN) -Rule fired: Class op <$ (BUILTIN) +Rule fired: Class op fmap (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) Rule fired: Class op <*> (BUILTIN) -Rule fired: Class op fmap (BUILTIN) +Rule fired: Class op <$ (BUILTIN) Rule fired: Class op pure (BUILTIN) Rule fired: Class op pure (BUILTIN) Rule fired: Class op >>= (BUILTIN) ===================================== testsuite/tests/simplCore/should_compile/T17901.stdout ===================================== @@ -1,14 +1,6 @@ - (wombat1 [Occ=Once*!] :: T -> p) - A -> wombat1 T17901.A; - B -> wombat1 T17901.B; - C -> wombat1 T17901.C = \ (@p) (wombat1 :: T -> p) (x :: T) -> case x of wild { __DEFAULT -> wombat1 wild } - Tmpl= \ (@p) (wombat2 [Occ=Once!] :: S -> p) (x [Occ=Once] :: S) -> - case x of wild [Occ=Once] { __DEFAULT -> wombat2 wild }}] = \ (@p) (wombat2 :: S -> p) (x :: S) -> case x of wild { __DEFAULT -> wombat2 wild } - Tmpl= \ (@p) (wombat3 [Occ=Once!] :: W -> p) (x [Occ=Once] :: W) -> - case x of wild [Occ=Once] { __DEFAULT -> wombat3 wild }}] = \ (@p) (wombat3 :: W -> p) (x :: W) -> case x of wild { __DEFAULT -> wombat3 wild } ===================================== testsuite/tests/simplCore/should_compile/T17966.stdout ===================================== @@ -1,5 +1,3 @@ RULES: "SPEC $cm @()" [0] RULES: "SPEC f @Bool @() @(Maybe Integer)" [0] -"SPEC/T17966 $fShowMaybe_$cshow @Integer" -"SPEC/T17966 $fShowMaybe_$cshowList @Integer" "SPEC/T17966 $fShowMaybe @Integer" ===================================== testsuite/tests/simplCore/should_compile/T4201.stdout ===================================== @@ -1,3 +1,3 @@ + lift :: Foo -> T [HasNoCafRefs, Arity: 1, Strictness: , - Unfolding: InlineRule (0, True, True) - bof `cast` (Sym (N:Foo[0]) ->_R _R)] + Unfolding: (bof `cast` (Sym (N:Foo[0]) ->_R _R))] ===================================== testsuite/tests/simplCore/should_compile/T5658b.stdout ===================================== @@ -1 +1 @@ -4 +2 ===================================== testsuite/tests/warnings/should_compile/T16282/T16282.stderr ===================================== @@ -6,5 +6,4 @@ T16282.hs: warning: [-Wall-missed-specialisations] T16282.hs: warning: [-Wall-missed-specialisations] Could not specialise imported function ‘Data.Map.Internal.$w$cshowsPrec’ - when specialising ‘Data.Map.Internal.$fShowMap_$cshowsPrec’ Probable fix: add INLINABLE pragma on ‘Data.Map.Internal.$w$cshowsPrec’ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9d122faa62d76bc8bb43cffd0173a008b30e6f61 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9d122faa62d76bc8bb43cffd0173a008b30e6f61 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 6 09:41:48 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 06 May 2020 05:41:48 -0400 Subject: [Git][ghc/ghc][wip/ww-max-worker-args-old-arity] 35 commits: nonmoving: Clear bitmap after initializing block size Message-ID: <5eb2865cc4bed_616711ab08a4908138d@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/ww-max-worker-args-old-arity at Glasgow Haskell Compiler / GHC Commits: 2aa67611 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - 54dad3cf by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - 99ff8145 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 05b0a9fd by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 Remove OneShotInfo field of LFReEntrant, document OneShotInfo The field is only used in withNewTickyCounterFun and it's easier to directly pass a parameter for one-shot info to withNewTickyCounterFun instead of passing it via LFReEntrant. This also makes !2842 simpler. Other changes: - New Note (by SPJ) [OneShotInfo overview] added. - Arity argument of thunkCode removed as it's always 0. - - - - - a43620c6 by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 GHC.StgToCmm.Ticky: remove a few unused stuff - - - - - 780de9e1 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Use platform in Iface Binary - - - - - f8386c7b by Sylvain Henry at 2020-05-01T10:37:39-04:00 Refactor PprDebug handling If `-dppr-debug` is set, then PprUser and PprDump styles are silently replaced with PprDebug style. This was done in `mkUserStyle` and `mkDumpStyle` smart constructors. As a consequence they needed a DynFlags parameter. Now we keep the original PprUser and PprDump styles until they are used to create an `SDocContext`. I.e. the substitution is only performed in `initSDocContext`. - - - - - b3df9e78 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Remove PprStyle param of logging actions Use `withPprStyle` instead to apply a specific style to a SDoc. - - - - - de9fc995 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Fully remove PprDebug PprDebug was a pain to deal with consistently as it is implied by `-dppr-debug` but it isn't really a PprStyle. We remove it completely and query the appropriate SDoc flag instead (`sdocPprDebug`) via helpers (`getPprDebug` and its friends). - - - - - 8b51fcbd by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Only call checkSingle if we would report warnings - - - - - fd7ea0fe by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 7bfe9ac5 by Ben Gamari at 2020-05-03T04:41:33-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. - - - - - c560dd07 by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Move eventlog documentation users guide - - - - - 02543d5e by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Add documentation for non-moving GC events - - - - - b465dd45 by Alexis King at 2020-05-03T04:42:12-04:00 Flatten nested casts in the simple optimizer Normally, we aren’t supposed to generated any nested casts, since mkCast takes care to flatten them, but the simple optimizer didn’t use mkCast, so they could show up after inlining. This isn’t really a problem, since the simplifier will clean them up immediately anyway, but it can clutter the -ddump-ds output, and it’s an extremely easy fix. closes #18112 - - - - - 8bdc03d6 by Simon Peyton Jones at 2020-05-04T01:56:59-04:00 Don't return a panic in tcNestedSplice In GHC.Tc.Gen.Splice.tcNestedSplice we were returning a typechecked expression of "panic". That is usually OK, because the result is discarded. But it happens that tcApp now looks at the typechecked expression, trivially, to ask if it is tagToEnum. So being bottom is bad. Moreover a debug-trace might print it out. So better to return a civilised expression, even though it is usually discarded. - - - - - 0bf640b1 by Baldur Blöndal at 2020-05-04T01:57:36-04:00 Don't require parentheses around via type (`-XDerivingVia'). Fixes #18130". - - - - - 30272412 by Artem Pelenitsyn at 2020-05-04T13:19:59-04:00 Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) - - - - - b9f7c08f by jneira at 2020-05-04T13:20:37-04:00 Remove unused hs-boot file - - - - - 1d8f80cd by Sylvain Henry at 2020-05-05T03:22:46-04:00 Remove references to -package-key * remove references to `-package-key` which has been removed in 2016 (240ddd7c39536776e955e881d709bbb039b48513) * remove support for `-this-package-key` which has been deprecated at the same time - - - - - 7bc3a65b by Sylvain Henry at 2020-05-05T03:23:31-04:00 Remove SpecConstrAnnotation (#13681) This has been deprecated since 2013. Use GHC.Types.SPEC instead. Make GHC.Exts "not-home" for haddock Metric Decrease: haddock.base - - - - - 3c862f63 by DenisFrezzato at 2020-05-05T03:24:15-04:00 Fix Haskell98 short description in documentation - - - - - 2420c555 by Ryan Scott at 2020-05-05T03:24:53-04:00 Add regression tests for #16244, #16245, #16758 Commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70 ended up fixing quite a few bugs: * This commit fixes #16244 completely. A regression test has been added. * This commit fixes one program from #16245. (The program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211369 still panics, and the program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211400 still loops infinitely.) A regression test has been added for this program. * This commit fixes #16758. Accordingly, this patch removes the `expect_broken` label from the `T16758` test case, moves it from `should_compile` to `should_fail` (as it should produce an error message), and checks in the expected stderr. - - - - - 40c71c2c by Sylvain Henry at 2020-05-05T03:25:31-04:00 Fix colorized error messages (#18128) In b3df9e780fb2f5658412c644849cd0f1e6f50331 I broke colorized messages by using "dump" style instead of "user" style. This commits fixes it. - - - - - 7ab6ab09 by Richard Eisenberg at 2020-05-06T04:39:32-04:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG ------------------------- - - - - - 420b957d by Ben Gamari at 2020-05-06T04:40:08-04:00 rts: Zero block flags with -DZ Block flags are very useful for determining the state of a block. However, some block allocator users don't touch them, leading to misleading values. Ensure that we zero then when zero-on-gc is set. This is safe and makes the flags more useful during debugging. - - - - - 740b3b8d by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix incorrect failed_to_evac value during deadlock gc Previously we would incorrectly set the failed_to_evac flag if we evacuated a value due to a deadlock GC. This would cause us to mark more things as dirty than strictly necessary. It also turned up a nasty but which I will fix next. - - - - - b2d72c75 by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - 9f3e6884 by Zubin Duggal at 2020-05-06T04:41:08-04:00 Allow atomic update of NameCache in readHieFile The situation arises in ghcide where multiple different threads may need to update the name cache, therefore with the older interface it could happen that you start reading a hie file with name cache A and produce name cache A + B, but another thread in the meantime updated the namecache to A + C. Therefore if you write the new namecache you will lose the A' updates from the second thread. Updates haddock submodule - - - - - edec6a6c by Ryan Scott at 2020-05-06T04:41:57-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _)`. Fixes #18127. - - - - - a95e7fe0 by Ömer Sinan Ağacan at 2020-05-06T04:42:39-04:00 ELF linker: increment curSymbol after filling in fields of current entry The bug was introduced in a8b7cef4d45 which added a field to the `symbols` array elements and then updated this code incorrectly: - oc->symbols[curSymbol++] = nm; + oc->symbols[curSymbol++].name = nm; + oc->symbols[curSymbol].addr = symbol->addr; - - - - - cab1871a by Sylvain Henry at 2020-05-06T04:43:21-04:00 Move LeadingUnderscore into Platform (#17957) Avoid direct use of DynFlags to know if symbols must be prefixed by an underscore. - - - - - 94e7c563 by Sylvain Henry at 2020-05-06T04:43:21-04:00 Don't use DynFlags in showLinkerState (#17957) - - - - - 9afd9251 by Ryan Scott at 2020-05-06T04:43:58-04:00 Refactoring: Use bindSigTyVarsFV in rnMethodBinds `rnMethodBinds` was explicitly using `xoptM` to determine if `ScopedTypeVariables` is enabled before bringing type variables bound by the class/instance header into scope. However, this `xoptM` logic is already performed by the `bindSigTyVarsFV` function. This patch uses `bindSigTyVarsFV` in `rnMethodBinds` to reduce the number of places where we need to consult if `ScopedTypeVariables` is on. This is purely refactoring, and there should be no user-visible change in behavior. - - - - - f5840931 by Sebastian Graf at 2020-05-06T05:41:45-04:00 Make WorkWrap.Lib.isWorkerSmallEnough aware of the old arity We should allow a wrapper with up to 82 parameters when the original function had 82 parameters to begin with. I verified that this made no difference on NoFib, but then again it doesn't use huge records... Fixes #18122. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Driver.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/TyCo/Ppr.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Data/IOEnv.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Finder.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Monad.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Driver/Types.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Pat.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/54c7ea2dfda9fd3f72d9d493b0efdc5ad531bf8b...f584093138d10cd9f79de61c681d60635a23b18d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/54c7ea2dfda9fd3f72d9d493b0efdc5ad531bf8b...f584093138d10cd9f79de61c681d60635a23b18d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 6 11:33:22 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Wed, 06 May 2020 07:33:22 -0400 Subject: [Git][ghc/ghc][wip/T17775] 18 commits: Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) Message-ID: <5eb2a08285ad0_6167128409c4912724c@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: 30272412 by Artem Pelenitsyn at 2020-05-04T13:19:59-04:00 Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) - - - - - b9f7c08f by jneira at 2020-05-04T13:20:37-04:00 Remove unused hs-boot file - - - - - 1d8f80cd by Sylvain Henry at 2020-05-05T03:22:46-04:00 Remove references to -package-key * remove references to `-package-key` which has been removed in 2016 (240ddd7c39536776e955e881d709bbb039b48513) * remove support for `-this-package-key` which has been deprecated at the same time - - - - - 7bc3a65b by Sylvain Henry at 2020-05-05T03:23:31-04:00 Remove SpecConstrAnnotation (#13681) This has been deprecated since 2013. Use GHC.Types.SPEC instead. Make GHC.Exts "not-home" for haddock Metric Decrease: haddock.base - - - - - 3c862f63 by DenisFrezzato at 2020-05-05T03:24:15-04:00 Fix Haskell98 short description in documentation - - - - - 2420c555 by Ryan Scott at 2020-05-05T03:24:53-04:00 Add regression tests for #16244, #16245, #16758 Commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70 ended up fixing quite a few bugs: * This commit fixes #16244 completely. A regression test has been added. * This commit fixes one program from #16245. (The program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211369 still panics, and the program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211400 still loops infinitely.) A regression test has been added for this program. * This commit fixes #16758. Accordingly, this patch removes the `expect_broken` label from the `T16758` test case, moves it from `should_compile` to `should_fail` (as it should produce an error message), and checks in the expected stderr. - - - - - 40c71c2c by Sylvain Henry at 2020-05-05T03:25:31-04:00 Fix colorized error messages (#18128) In b3df9e780fb2f5658412c644849cd0f1e6f50331 I broke colorized messages by using "dump" style instead of "user" style. This commits fixes it. - - - - - 7ab6ab09 by Richard Eisenberg at 2020-05-06T04:39:32-04:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG ------------------------- - - - - - 420b957d by Ben Gamari at 2020-05-06T04:40:08-04:00 rts: Zero block flags with -DZ Block flags are very useful for determining the state of a block. However, some block allocator users don't touch them, leading to misleading values. Ensure that we zero then when zero-on-gc is set. This is safe and makes the flags more useful during debugging. - - - - - 740b3b8d by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix incorrect failed_to_evac value during deadlock gc Previously we would incorrectly set the failed_to_evac flag if we evacuated a value due to a deadlock GC. This would cause us to mark more things as dirty than strictly necessary. It also turned up a nasty but which I will fix next. - - - - - b2d72c75 by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - 9f3e6884 by Zubin Duggal at 2020-05-06T04:41:08-04:00 Allow atomic update of NameCache in readHieFile The situation arises in ghcide where multiple different threads may need to update the name cache, therefore with the older interface it could happen that you start reading a hie file with name cache A and produce name cache A + B, but another thread in the meantime updated the namecache to A + C. Therefore if you write the new namecache you will lose the A' updates from the second thread. Updates haddock submodule - - - - - edec6a6c by Ryan Scott at 2020-05-06T04:41:57-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _)`. Fixes #18127. - - - - - a95e7fe0 by Ömer Sinan Ağacan at 2020-05-06T04:42:39-04:00 ELF linker: increment curSymbol after filling in fields of current entry The bug was introduced in a8b7cef4d45 which added a field to the `symbols` array elements and then updated this code incorrectly: - oc->symbols[curSymbol++] = nm; + oc->symbols[curSymbol++].name = nm; + oc->symbols[curSymbol].addr = symbol->addr; - - - - - cab1871a by Sylvain Henry at 2020-05-06T04:43:21-04:00 Move LeadingUnderscore into Platform (#17957) Avoid direct use of DynFlags to know if symbols must be prefixed by an underscore. - - - - - 94e7c563 by Sylvain Henry at 2020-05-06T04:43:21-04:00 Don't use DynFlags in showLinkerState (#17957) - - - - - 9afd9251 by Ryan Scott at 2020-05-06T04:43:58-04:00 Refactoring: Use bindSigTyVarsFV in rnMethodBinds `rnMethodBinds` was explicitly using `xoptM` to determine if `ScopedTypeVariables` is enabled before bringing type variables bound by the class/instance header into scope. However, this `xoptM` logic is already performed by the `bindSigTyVarsFV` function. This patch uses `bindSigTyVarsFV` in `rnMethodBinds` to reduce the number of places where we need to consult if `ScopedTypeVariables` is on. This is purely refactoring, and there should be no user-visible change in behavior. - - - - - 79f0a901 by Simon Peyton Jones at 2020-05-06T12:32:35+01:00 Simple subsumption This patch simplifies GHC to use simple subsumption. Ticket #17775 Implements GHC proposal #287 https://github.com/ghc-proposals/ghc-proposals/blob/master/ proposals/0287-simplify-subsumption.rst All the motivation is described there; I will not repeat it here. The implementation payload: * tcSubType and friends become noticably simpler, because it no longer uses eta-expansion when checking subsumption. * No deeplyInstantiate or deeplySkolemise That in turn means that some tests fail, by design; they can all be fixed by eta expansion. There is a list of such changes below. Implementing the patch led me into a variety of sticky corners, so the patch includes several othe changes, some quite significant: * I made String wired-in, so that "foo" :: String rather than "foo" :: [Char] This improves error messages, and fixes #15679 * The pattern match checker relies on knowing about in-scope equality constraints, andd adds them to the desugarer's environment using addTyCsDs. But the co_fn in a FunBind was missed, and for some reason simple-subsumption ends up with dictionaries there. So I added a call to addTyCsDs. This is really part of #18049. * I moved the ic_telescope field out of Implication and into ForAllSkol instead. This is a nice win; just expresses the code much better. * There was a bug in GHC.Tc.TyCl.Instance.tcDataFamInstHeader. We called checkDataKindSig inside tc_kind_sig, /before/ solveEqualities and zonking. Obviously wrong, easily fixed. * solveLocalEqualitiesX: there was a whole mess in here, around failing fast enough. I discovered a bad latent bug where we could successfully kind-check a type signature, and use it, but have unsolved constraints that could fill in coercion holes in that signature -- aargh. It's all explained in Note [Failure in local type signatures] in GHC.Tc.Solver. Much better now. * I fixed a serious bug in anonymous type holes. IN f :: Int -> (forall a. a -> _) -> Int that "_" should be a unification variable at the /outer/ level; it cannot be instantiated to 'a'. This was plain wrong. New fields mode_lvl and mode_holes in TcTyMode, and auxiliary data type GHC.Tc.Gen.HsType.HoleMode. This fixes #16292, but makes no progress towards the more ambitious #16082 * I got sucked into an enormous refactoring of the reporting of equality errors in GHC.Tc.Errors, especially in mkEqErr1 mkTyVarEqErr misMatchMsg misMatchMsgOrCND In particular, the very tricky mkExpectedActualMsg function is gone. It took me a full day. But the result is far easier to understand. (Still not easy!) This led to various minor improvements in error output, and an enormous number of test-case error wibbles. One particular point: for occurs-check errors I now just say Can't match 'a' against '[a]' rather than using the intimidating language of "occurs check". * Pretty-printing AbsBinds Tests review * Eta expansions T11305: one eta expansion T12082: one eta expansion (undefined) T13585a: one eta expansion T3102: one eta expansion T3692: two eta expansions (tricky) T2239: two eta expansions T16473: one eta determ004: two eta expansions (undefined) annfail06: two eta (undefined) T17923: four eta expansions (a strange program indeed!) tcrun035: one eta expansion * Ambiguity check at higher rank. Now that we have simple subsumption, a type like f :: (forall a. Eq a => Int) -> Int is no longer ambiguous, because we could write g :: (forall a. Eq a => Int) -> Int g = f and it'd typecheck just fine. But f's type is a bit suspicious, and we might want to consider making the ambiguity check do a check on each sub-term. Meanwhile, these tests are accepted, whereas they were previously rejected as ambiguous: T7220a T15438 T10503 T9222 * Some more interesting error message wibbles T13381: Fine: one error (Int ~ Exp Int) rather than two (Int ~ Exp Int, Exp Int ~ Int) T9834: Small change in error (improvement) T10619: Improved T2414: Small change, due to order of unification, fine T2534: A very simple case in which a change of unification order means we get tow unsolved constraints instead of one tc211: bizarre impredicative tests; just accept this for now - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Data/IOEnv.hs - compiler/GHC/Driver/Finder.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Monad.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Driver/Types.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Types.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Plugins.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Splice.hs - compiler/GHC/Runtime/Debugger.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Runtime/Interpreter.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/188205d687bac490ed8bd7a038569aca15c25a68...79f0a901ebb9955e8f1306d077883c4470ecfa4b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/188205d687bac490ed8bd7a038569aca15c25a68...79f0a901ebb9955e8f1306d077883c4470ecfa4b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 6 11:46:02 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Wed, 06 May 2020 07:46:02 -0400 Subject: [Git][ghc/ghc][wip/T16762-chunks-2-and-3] WIP: Factor out HsPatSigType for pat sigs/RULE term sigs (#16762) Message-ID: <5eb2a37a71e93_6167136cfbac91284de@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T16762-chunks-2-and-3 at Glasgow Haskell Compiler / GHC Commits: af9b4340 by Ryan Scott at 2020-05-06T07:44:55-04:00 WIP: Factor out HsPatSigType for pat sigs/RULE term sigs (#16762) This implements chunks (2) and (3) of https://gitlab.haskell.org/ghc/ghc/issues/16762#note_270170. Namely, it introduces a dedicated `HsPatSigType` AST type, which represents the types that can appear in pattern signatures and term-level `RULE` binders. Previously, these were represented with `LHsSigWcType`. Although `LHsSigWcType` is isomorphic to `HsPatSigType`, the intended semantics of the two types are slightly different, as evidenced by the fact that they have different code paths in the renamer and typechecker. See also the new `Note [Pattern signature binders and scoping]` in `GHC.Hs.Types`. - - - - - 18 changed files: - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Extension.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Types.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/Gen/Rule.hs - compiler/GHC/ThToHs.hs - testsuite/tests/hiefile/should_compile/hie007.hs Changes: ===================================== compiler/GHC/Hs/Decls.hs ===================================== @@ -2244,7 +2244,7 @@ type LRuleBndr pass = Located (RuleBndr pass) -- | Rule Binder data RuleBndr pass = RuleBndr (XCRuleBndr pass) (Located (IdP pass)) - | RuleBndrSig (XRuleBndrSig pass) (Located (IdP pass)) (LHsSigWcType pass) + | RuleBndrSig (XRuleBndrSig pass) (Located (IdP pass)) (HsPatSigType pass) | XRuleBndr !(XXRuleBndr pass) -- ^ -- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen', @@ -2256,7 +2256,7 @@ type instance XCRuleBndr (GhcPass _) = NoExtField type instance XRuleBndrSig (GhcPass _) = NoExtField type instance XXRuleBndr (GhcPass _) = NoExtCon -collectRuleBndrSigTys :: [RuleBndr pass] -> [LHsSigWcType pass] +collectRuleBndrSigTys :: [RuleBndr pass] -> [HsPatSigType pass] collectRuleBndrSigTys bndrs = [ty | RuleBndrSig _ _ ty <- bndrs] pprFullRuleName :: Located (SourceText, RuleName) -> SDoc ===================================== compiler/GHC/Hs/Extension.hs ===================================== @@ -685,6 +685,11 @@ type family XXHsWildCardBndrs x b -- ------------------------------------- +type family XHsPS x +type family XXHsPatSigType x + +-- ------------------------------------- + type family XForAllTy x type family XQualTy x type family XTyVar x ===================================== compiler/GHC/Hs/Instances.hs ===================================== @@ -386,6 +386,11 @@ deriving instance (Data thing) => Data (HsWildCardBndrs GhcPs thing) deriving instance (Data thing) => Data (HsWildCardBndrs GhcRn thing) deriving instance (Data thing) => Data (HsWildCardBndrs GhcTc thing) +-- deriving instance (DataIdLR p p) => Data (HsPatSigType p) +deriving instance Data (HsPatSigType GhcPs) +deriving instance Data (HsPatSigType GhcRn) +deriving instance Data (HsPatSigType GhcTc) + -- deriving instance (DataIdLR p p) => Data (HsTyVarBndr p) deriving instance Data (HsTyVarBndr GhcPs) deriving instance Data (HsTyVarBndr GhcRn) ===================================== compiler/GHC/Hs/Pat.hs ===================================== @@ -240,7 +240,7 @@ data Pat p -- For details on above see note [Api annotations] in GHC.Parser.Annotation | SigPat (XSigPat p) -- After typechecker: Type (LPat p) -- Pattern with a type signature - (LHsSigWcType (NoGhcTc p)) -- Signature can bind both + (HsPatSigType (NoGhcTc p)) -- Signature can bind both -- kind and type vars -- ^ Pattern with a type signature ===================================== compiler/GHC/Hs/Types.hs ===================================== @@ -23,6 +23,7 @@ module GHC.Hs.Types ( LHsQTyVars(..), HsImplicitBndrs(..), HsWildCardBndrs(..), + HsPatSigType(..), HsPSRn(..), LHsSigType, LHsSigWcType, LHsWcType, HsTupleSort(..), HsContext, LHsContext, noLHsContext, @@ -47,7 +48,7 @@ module GHC.Hs.Types ( mkAnonWildCardTy, pprAnonWildCard, - mkHsImplicitBndrs, mkHsWildCardBndrs, hsImplicitBody, + mkHsImplicitBndrs, mkHsWildCardBndrs, mkHsPatSigType, hsImplicitBody, mkEmptyImplicitBndrs, mkEmptyWildCardBndrs, mkHsQTvs, hsQTvExplicit, emptyLHsQTvs, isEmptyLHsQTvs, isHsKindedTyVar, hsTvbAllKinded, isLHsForAllTy, @@ -59,7 +60,7 @@ module GHC.Hs.Types ( splitLHsForAllTyInvis, splitLHsQualTy, splitLHsSigmaTyInvis, splitHsFunType, hsTyGetAppHead_maybe, mkHsOpTy, mkHsAppTy, mkHsAppTys, mkHsAppKindTy, - ignoreParens, hsSigType, hsSigWcType, + ignoreParens, hsSigType, hsSigWcType, hsPatSigType, hsLTyVarBndrToType, hsLTyVarBndrsToTypes, hsTyKindSig, hsConDetailsArgs, @@ -184,6 +185,13 @@ is a bit complicated. Here's how it works. f :: _a -> _ The enclosing HsWildCardBndrs binds the wildcards _a and _. +* HsSigPatType describes types that appear in pattern signatures and + the signatures of term-level binders in RULES. Like + HsWildCardBndrs/HsImplicitBndrs, they track the names of wildcard + variables and implicitly bound type variables. Unlike + HsImplicitBndrs, however, HsSigPatTypes do not obey the + forall-or-nothing rule. See Note [Pattern signature binders and scoping]. + * The explicit presence of these wrappers specifies, in the HsSyn, exactly where implicit quantification is allowed, and where wildcards are allowed. @@ -225,13 +233,15 @@ Note carefully: Here _a is an ordinary forall'd binder, but (With NamedWildCards) _b is a named wildcard. (See the comments in #10982) -* Named wildcards are bound by the HsWildCardBndrs construct, which wraps - types that are allowed to have wildcards. Unnamed wildcards however are left - unchanged until typechecking, where we give them fresh wild tyavrs and - determine whether or not to emit hole constraints on each wildcard - (we don't if it's a visible type/kind argument or a type family pattern). - See related notes Note [Wildcards in visible kind application] - and Note [Wildcards in visible type application] in GHC.Tc.Gen.HsType +* Named wildcards are bound by the HsWildCardBndrs (for types that obey the + forall-or-nothing rule) and HsPatSigType (for type signatures in patterns + and term-level binders in RULES), which wrap types that are allowed to have + wildcards. Unnamed wildcards, however are left unchanged until typechecking, + where we give them fresh wild tyvars and determine whether or not to emit + hole constraints on each wildcard (we don't if it's a visible type/kind + argument or a type family pattern). See related notes + Note [Wildcards in visible kind application] and + Note [Wildcards in visible type application] in GHC.Tc.Gen.HsType. * After type checking is done, we report what types the wildcards got unified with. @@ -399,6 +409,33 @@ type instance XHsWC GhcTc b = [Name] type instance XXHsWildCardBndrs (GhcPass _) b = NoExtCon +-- | Types that can appear in pattern signatures, as well as the signatures for +-- term-level binders in RULES. +-- See @Note [Pattern signature binders and scoping]@. +-- +-- This is very similar to 'HsSigWcType', but with +-- slightly different semantics: see @Note [HsType binders]@. +-- See also @Note [The wildcard story for types]@. +data HsPatSigType pass + = HsPS { hsps_ext :: XHsPS pass -- ^ After renamer: 'HsPSRn' + , hsps_body :: LHsType pass -- ^ Main payload (the type itself) + } + | XHsPatSigType !(XXHsPatSigType pass) + +-- | The extension field for 'HsPatSigType', which is only used in the +-- renamer onwards. See @Note [Pattern signature binders and scoping]@. +data HsPSRn = HsPSRn + { hsps_nwcs :: [Name] -- ^ Wildcard names + , hsps_imp_tvs :: [Name] -- ^ Implicitly bound variable names + } + deriving Data + +type instance XHsPS GhcPs = NoExtField +type instance XHsPS GhcRn = HsPSRn +type instance XHsPS GhcTc = HsPSRn + +type instance XXHsPatSigType (GhcPass _) = NoExtCon + -- | Located Haskell Signature Type type LHsSigType pass = HsImplicitBndrs pass (LHsType pass) -- Implicit only @@ -419,6 +456,9 @@ hsSigType = hsImplicitBody hsSigWcType :: LHsSigWcType pass -> LHsType pass hsSigWcType sig_ty = hsib_body (hswc_body sig_ty) +hsPatSigType :: HsPatSigType pass -> LHsType pass +hsPatSigType = hsps_body + dropWildCards :: LHsSigWcType pass -> LHsSigType pass -- Drop the wildcard part of a LHsSigWcType dropWildCards sig_ty = hswc_body sig_ty @@ -441,6 +481,70 @@ we get , hst_body = blah } The implicit kind variable 'k' is bound by the HsIB; the explicitly forall'd tyvar 'a' is bound by the HsForAllTy + +Note [Pattern signature binders and scoping] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider the pattern signatures like those on `t` and `g` in: + + f = let h = \(t :: (b, b) -> + \(g :: forall a. a -> b) -> + ...(t :: (Int,Int))... + in woggle + +* The `b` in t's pattern signature is implicitly bound and scopes over + the signature and the body of the lambda. It stands for a type (any type); + indeed we subsequently discover that b=Int. + (See Note [TyVarTv] in GHC.Tc.Utils.TcMType for more on this point.) +* The `b` in g's pattern signature is an /occurrence/ of the `b` bound by + t's pattern signature. +* The `a` in `forall a` scopes only over the type `a -> b`, not over the body + of the lambda. +* There is no forall-or-nothing rule for pattern signatures, which is why the + type `forall a. a -> b` is permitted in `g`'s pattern signature, even though + `b` is not explicitly bound. + +Similar scoping rules apply to term variable binders in RULES, like in the +following example: + + {-# RULES "h" forall (t :: (b, b)) (g :: forall a. a -> b). h t g = ... #-} + +Just like in pattern signatures, the `b` in t's signature is implicitly bound +and scopes over the remainder of the RULE. As a result, the `b` in g's +signature is an occurrence. Moreover, the `a` in `forall a` scopes only over +the type `a -> b`, and the forall-or-nothing rule does not apply. + +While quite similar, RULE term binder signatures behave slightly differently +from pattern signatures in two ways: + +1. Unlike in pattern signatures, where type variables can stand for any type, + type variables in RULE term binder signatures are skolems. + See Note [Typechecking pattern signature binders] in GHC.Tc.Gen.HsType for + more on this point. + + In this sense, type variables in pattern signatures are quite similar to + named wildcards, as both can refer to arbitrary types. The main difference + lies in error reporting: if a named wildcard `_a` in a pattern signature + stands for Int, then by default GHC will emit a warning stating as much. + Changing `_a` to `a`, on the other hand, will cause it not to be reported. +2. In the `h` RULE above, only term variables are explicitly bound, so any free + type variables in the term variables' signatures are implicitly bound. + This is just like how the free type variables in pattern signatures are + implicitly bound. If a RULE explicitly binds both term and type variables, + however, then free type variables in term signatures are /not/ implicitly + bound. For example, this RULE would be ill scoped: + + {-# RULES "h2" forall b. forall (t :: (b, c)) (g :: forall a. a -> b). + h2 t g = ... #-} + + This is because `b` and `c` occur free in the signature for `t`, but only + `b` was explicitly bound, leaving `c` out of scope. If the RULE had started + with `forall b c.`, then it would have been accepted. + +The types in pattern signatures and RULE term binder signatures are represented +in the AST by HsSigPatType. From the renamer onward, the hsps_ext field (of +type HsPSRn) tracks the names of named wildcards and implicitly bound type +variables so that they can be brought into scope during renaming and +typechecking. -} mkHsImplicitBndrs :: thing -> HsImplicitBndrs GhcPs thing @@ -451,6 +555,10 @@ mkHsWildCardBndrs :: thing -> HsWildCardBndrs GhcPs thing mkHsWildCardBndrs x = HsWC { hswc_body = x , hswc_ext = noExtField } +mkHsPatSigType :: LHsType GhcPs -> HsPatSigType GhcPs +mkHsPatSigType x = HsPS { hsps_ext = noExtField + , hsps_body = x } + -- Add empty binders. This is a bit suspicious; what if -- the wrapped thing had free type variables? mkEmptyImplicitBndrs :: thing -> HsImplicitBndrs GhcRn thing @@ -1408,6 +1516,10 @@ instance Outputable thing => Outputable (HsWildCardBndrs (GhcPass p) thing) where ppr (HsWC { hswc_body = ty }) = ppr ty +instance OutputableBndrId p + => Outputable (HsPatSigType (GhcPass p)) where + ppr (HsPS { hsps_body = ty }) = ppr ty + pprAnonWildCard :: SDoc pprAnonWildCard = char '_' ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -821,7 +821,7 @@ repRuleD (L loc (HsRule { rd_name = n ruleBndrNames :: LRuleBndr GhcRn -> [Name] ruleBndrNames (L _ (RuleBndr _ n)) = [unLoc n] ruleBndrNames (L _ (RuleBndrSig _ n sig)) - | HsWC { hswc_body = HsIB { hsib_ext = vars }} <- sig + | HsPS { hsps_ext = HsPSRn { hsps_imp_tvs = vars }} <- sig = unLoc n : vars repRuleBndr :: LRuleBndr GhcRn -> MetaM (Core (M TH.RuleBndr)) @@ -830,7 +830,7 @@ repRuleBndr (L _ (RuleBndr _ n)) ; rep2 ruleVarName [n'] } repRuleBndr (L _ (RuleBndrSig _ n sig)) = do { MkC n' <- lookupLBinder n - ; MkC ty' <- repLTy (hsSigWcType sig) + ; MkC ty' <- repLTy (hsPatSigType sig) ; rep2 typedRuleVarName [n', ty'] } repAnnD :: LAnnDecl GhcRn -> MetaM (SrcSpan, Core (M TH.Dec)) @@ -1935,7 +1935,7 @@ repP (NPat _ (L _ l) Nothing _) = do { a <- repOverloadedLiteral l repP (ViewPat _ e p) = do { e' <- repLE e; p' <- repLP p; repPview e' p' } repP p@(NPat _ _ (Just _) _) = notHandled "Negative overloaded patterns" (ppr p) repP (SigPat _ p t) = do { p' <- repLP p - ; t' <- repLTy (hsSigWcType t) + ; t' <- repLTy (hsPatSigType t) ; repPsig p' t' } repP (SplicePat _ splice) = repSplice splice repP other = notHandled "Exotic pattern" (ppr other) ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -413,35 +413,9 @@ bar (x :: forall a. a -> a) = ... -- a is not in scope here -- ^ a is in scope here (pattern body) bax (x :: a) = ... -- a is in scope here -Because of HsWC and HsIB pass on their scope to their children -we must wrap the LHsType in pattern signatures in a -Shielded explicitly, so that the HsWC/HsIB scope is not passed -on the the LHsType --} - -data Shielded a = SH Scope a -- Ignores its TScope, uses its own scope instead - -type family ProtectedSig a where - ProtectedSig GhcRn = HsWildCardBndrs GhcRn (HsImplicitBndrs - GhcRn - (Shielded (LHsType GhcRn))) - ProtectedSig GhcTc = NoExtField - -class ProtectSig a where - protectSig :: Scope -> LHsSigWcType (NoGhcTc a) -> ProtectedSig a - -instance (HasLoc a) => HasLoc (Shielded a) where - loc (SH _ a) = loc a - -instance (ToHie (TScoped a)) => ToHie (TScoped (Shielded a)) where - toHie (TS _ (SH sc a)) = toHie (TS (ResolvedScopes [sc]) a) -instance ProtectSig GhcTc where - protectSig _ _ = noExtField - -instance ProtectSig GhcRn where - protectSig sc (HsWC a (HsIB b sig)) = - HsWC a (HsIB b (SH sc sig)) +This case in handled in the instance for HsPatSigType +-} class HasLoc a where -- ^ defined so that HsImplicitBndrs and HsWildCardBndrs can @@ -770,8 +744,6 @@ instance ( a ~ GhcPass p , ToHie (RContext (HsRecFields a (PScoped (LPat a)))) , ToHie (LHsExpr a) , ToHie (TScoped (LHsSigWcType a)) - , ProtectSig a - , ToHie (TScoped (ProtectedSig a)) , HasType (LPat a) , Data (HsSplice a) , IsPass p @@ -832,9 +804,12 @@ instance ( a ~ GhcPass p SigPat _ pat sig -> [ toHie $ PS rsp scope pscope pat , let cscope = mkLScope pat in - toHie $ TS (ResolvedScopes [cscope, scope, pscope]) - (protectSig @a cscope sig) - -- See Note [Scoping Rules for SigPat] + case ghcPass @p of + GhcPs -> pure [] + GhcTc -> pure [] + GhcRn -> + toHie $ TS (ResolvedScopes [cscope, scope, pscope]) + sig ] XPat e -> case ghcPass @p of #if __GLASGOW_HASKELL__ < 811 @@ -856,6 +831,13 @@ instance ( a ~ GhcPass p L spn $ HsRecField lbl (PS rsp scope fscope pat) pun scoped_fds = listScopes pscope fds +instance ToHie (TScoped (HsPatSigType GhcRn)) where + toHie (TS sc (HsPS (HsPSRn wcs tvs) body@(L span _))) = concatM $ + [ pure $ bindingsOnly $ map (C $ TyVarBind (mkScope span) sc) (wcs++tvs) + , toHie body + ] + -- See Note [Scoping Rules for SigPat] + instance ( ToHie body , ToHie (LGRHS a body) , ToHie (RScoped (LHsLocalBinds a)) ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -874,7 +874,7 @@ mkRuleBndrs :: [LRuleTyTmVar] -> [LRuleBndr GhcPs] mkRuleBndrs = fmap (fmap cvt_one) where cvt_one (RuleTyTmVar v Nothing) = RuleBndr noExtField v cvt_one (RuleTyTmVar v (Just sig)) = - RuleBndrSig noExtField v (mkLHsSigWcType sig) + RuleBndrSig noExtField v (mkHsPatSigType sig) -- turns RuleTyTmVars into HsTyVarBndrs - this is more interesting mkRuleTyVarBndrs :: [LRuleTyTmVar] -> [LHsTyVarBndr GhcPs] @@ -2033,7 +2033,7 @@ instance DisambECP (PatBuilder GhcPs) where mkHsWildCardPV l = return $ L l (PatBuilderPat (WildPat noExtField)) mkHsTySigPV l b sig = do p <- checkLPat b - return $ L l (PatBuilderPat (SigPat noExtField p (mkLHsSigWcType sig))) + return $ L l (PatBuilderPat (SigPat noExtField p (mkHsPatSigType sig))) mkHsExplicitListPV l xs = do ps <- traverse checkLPat xs return (L l (PatBuilderPat (ListPat noExtField ps))) ===================================== compiler/GHC/Rename/Bind.hs ===================================== @@ -962,7 +962,7 @@ renameSig _ (IdSig _ x) renameSig ctxt sig@(TypeSig _ vs ty) = do { new_vs <- mapM (lookupSigOccRn ctxt sig) vs ; let doc = TypeSigCtx (ppr_sig_bndrs vs) - ; (new_ty, fvs) <- rnHsSigWcType BindUnlessForall doc ty + ; (new_ty, fvs) <- rnHsSigWcType doc ty ; return (TypeSig noExtField new_vs new_ty, fvs) } renameSig ctxt sig@(ClassOpSig _ is_deflt vs ty) ===================================== compiler/GHC/Rename/Expr.hs ===================================== @@ -316,7 +316,7 @@ rnExpr (RecordUpd { rupd_expr = expr, rupd_flds = rbinds }) , fvExpr `plusFV` fvRbinds) } rnExpr (ExprWithTySig _ expr pty) - = do { (pty', fvTy) <- rnHsSigWcType BindUnlessForall ExprWithTySigCtx pty + = do { (pty', fvTy) <- rnHsSigWcType ExprWithTySigCtx pty ; (expr', fvExpr) <- bindSigTyVarsFV (hsWcScopedTvs pty') $ rnLExpr expr ; return (ExprWithTySig noExtField expr' pty', fvExpr `plusFV` fvTy) } ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -13,7 +13,7 @@ module GHC.Rename.HsType ( rnHsType, rnLHsType, rnLHsTypes, rnContext, rnHsKind, rnLHsKind, rnLHsTypeArgs, rnHsSigType, rnHsWcType, - HsSigWcTypeScoping(..), rnHsSigWcType, rnHsSigWcTypeScoped, + HsSigWcTypeScoping(..), rnHsSigWcType, rnHsPatSigType, newTyVarNameRn, rnConDeclFields, rnLTyVar, @@ -71,58 +71,91 @@ import Control.Monad ( unless, when ) {- These type renamers are in a separate module, rather than in (say) GHC.Rename.Module, -to break several loop. +to break several loops. ********************************************************* * * - HsSigWcType (i.e with wildcards) + HsSigWcType and HsPatSigType (i.e with wildcards) * * ********************************************************* -} -data HsSigWcTypeScoping = AlwaysBind - -- ^ Always bind any free tyvars of the given type, - -- regardless of whether we have a forall at the top - | BindUnlessForall - -- ^ Unless there's forall at the top, do the same - -- thing as 'AlwaysBind' - | NeverBind - -- ^ Never bind any free tyvars - -rnHsSigWcType :: HsSigWcTypeScoping -> HsDocContext -> LHsSigWcType GhcPs +data HsSigWcTypeScoping + = AlwaysBind + -- ^ Always bind any free tyvars of the given type, regardless of whether we + -- have a forall at the top. + -- + -- For pattern type sigs, we /do/ want to bring those type + -- variables into scope, even if there's a forall at the top which usually + -- stops that happening, e.g: + -- + -- > \ (x :: forall a. a -> b) -> e + -- + -- Here we do bring 'b' into scope. + -- + -- RULES can also use 'AlwaysBind', such as in the following example: + -- + -- > {-# RULES \"f\" forall (x :: forall a. a -> b). f x = ... b ... #-} + -- + -- This only applies to RULES that do not explicitly bind their type + -- variables. If a RULE explicitly quantifies its type variables, then + -- 'NeverBind' is used instead. See also + -- @Note [Pattern signature binders and scoping]@ in "GHC.Hs.Types". + | BindUnlessForall + -- ^ Unless there's forall at the top, do the same thing as 'AlwaysBind'. + -- This is only ever used in places where the \"@forall at -or-nothing\" rule + -- is in effect. + | NeverBind + -- ^ Never bind any free tyvars. This is used for RULES that have both + -- explicit type and term variable binders, e.g.: + -- + -- > {-# RULES \"const\" forall a. forall (x :: a) y. const x y = x #-} + -- + -- The presence of the type variable binder @forall a.@ implies that the + -- free variables in the types of the term variable binders @x@ and @y@ + -- are /not/ bound. In the example above, there are no such free variables, + -- but if the user had written @(y :: b)@ instead of @y@ in the term + -- variable binders, then @b@ would be rejected for being out of scope. + -- See also @Note [Pattern signature binders and scoping]@ in + -- "GHC.Hs.Types". + +rnHsSigWcType :: HsDocContext -> LHsSigWcType GhcPs -> RnM (LHsSigWcType GhcRn, FreeVars) -rnHsSigWcType scoping doc sig_ty - = rn_hs_sig_wc_type scoping doc sig_ty $ \sig_ty' -> - return (sig_ty', emptyFVs) - -rnHsSigWcTypeScoped :: HsSigWcTypeScoping - -- AlwaysBind: for pattern type sigs and rules we /do/ want - -- to bring those type variables into scope, even - -- if there's a forall at the top which usually - -- stops that happening - -- e.g \ (x :: forall a. a-> b) -> e - -- Here we do bring 'b' into scope - -> HsDocContext -> LHsSigWcType GhcPs - -> (LHsSigWcType GhcRn -> RnM (a, FreeVars)) - -> RnM (a, FreeVars) +rnHsSigWcType doc (HsWC { hswc_body = HsIB { hsib_body = hs_ty }}) + = rn_hs_sig_wc_type BindUnlessForall doc hs_ty $ \nwcs imp_tvs body -> + let ib_ty = HsIB { hsib_ext = imp_tvs, hsib_body = body } + wc_ty = HsWC { hswc_ext = nwcs, hswc_body = ib_ty } in + pure (wc_ty, emptyFVs) + +rnHsPatSigType :: HsSigWcTypeScoping + -> HsDocContext -> HsPatSigType GhcPs + -> (HsPatSigType GhcRn -> RnM (a, FreeVars)) + -> RnM (a, FreeVars) -- Used for --- - Signatures on binders in a RULE --- - Pattern type signatures +-- - Pattern type signatures, which are only allowed with ScopedTypeVariables +-- - Signatures on binders in a RULE, which are allowed even if +-- ScopedTypeVariables isn't enabled -- Wildcards are allowed --- type signatures on binders only allowed with ScopedTypeVariables -rnHsSigWcTypeScoped scoping ctx sig_ty thing_inside +-- +-- See Note [Pattern signature binders and scoping] in GHC.Hs.Types +rnHsPatSigType scoping ctx sig_ty thing_inside = do { ty_sig_okay <- xoptM LangExt.ScopedTypeVariables - ; checkErr ty_sig_okay (unexpectedTypeSigErr sig_ty) - ; rn_hs_sig_wc_type scoping ctx sig_ty thing_inside - } - -rn_hs_sig_wc_type :: HsSigWcTypeScoping -> HsDocContext -> LHsSigWcType GhcPs - -> (LHsSigWcType GhcRn -> RnM (a, FreeVars)) + ; checkErr ty_sig_okay (unexpectedPatSigTypeErr sig_ty) + ; rn_hs_sig_wc_type scoping ctx (hsPatSigType sig_ty) $ + \nwcs imp_tvs body -> + do { let sig_names = HsPSRn { hsps_nwcs = nwcs, hsps_imp_tvs = imp_tvs } + sig_ty' = HsPS { hsps_ext = sig_names, hsps_body = body } + ; thing_inside sig_ty' + } } + +-- The workhorse for rnHsSigWcType and rnHsPatSigType. +rn_hs_sig_wc_type :: HsSigWcTypeScoping -> HsDocContext -> LHsType GhcPs + -> ([Name] -- Wildcard names + -> [Name] -- Implicitly bound type variable names + -> LHsType GhcRn + -> RnM (a, FreeVars)) -> RnM (a, FreeVars) --- rn_hs_sig_wc_type is used for source-language type signatures -rn_hs_sig_wc_type scoping ctxt - (HsWC { hswc_body = HsIB { hsib_body = hs_ty }}) - thing_inside +rn_hs_sig_wc_type scoping ctxt hs_ty thing_inside = do { free_vars <- extractFilteredRdrTyVarsDups hs_ty ; (nwc_rdrs', tv_rdrs) <- partition_nwcs free_vars ; let nwc_rdrs = nubL nwc_rdrs' @@ -132,10 +165,7 @@ rn_hs_sig_wc_type scoping ctxt NeverBind -> False ; rnImplicitBndrs bind_free_tvs tv_rdrs $ \ vars -> do { (wcs, hs_ty', fvs1) <- rnWcBody ctxt nwc_rdrs hs_ty - ; let sig_ty' = HsWC { hswc_ext = wcs, hswc_body = ib_ty' } - ib_ty' = HsIB { hsib_ext = vars - , hsib_body = hs_ty' } - ; (res, fvs2) <- thing_inside sig_ty' + ; (res, fvs2) <- thing_inside wcs vars hs_ty' ; return (res, fvs1 `plusFV` fvs2) } } rnHsWcType :: HsDocContext -> LHsWcType GhcPs -> RnM (LHsWcType GhcRn, FreeVars) @@ -1376,8 +1406,8 @@ ppr_opfix (op, fixity) = pp_op <+> brackets (ppr fixity) * * ***************************************************** -} -unexpectedTypeSigErr :: LHsSigWcType GhcPs -> SDoc -unexpectedTypeSigErr ty +unexpectedPatSigTypeErr :: HsPatSigType GhcPs -> SDoc +unexpectedPatSigTypeErr ty = hang (text "Illegal type signature:" <+> quotes (ppr ty)) 2 (text "Type signatures are only allowed in patterns with ScopedTypeVariables") ===================================== compiler/GHC/Rename/Module.hs ===================================== @@ -958,7 +958,7 @@ rnSrcDerivDecl (DerivDecl _ ty mds overlap) ; unless standalone_deriv_ok (addErr standaloneDerivErr) ; (mds', ty', fvs) <- rnLDerivStrategy DerivDeclCtx mds $ - rnHsSigWcType BindUnlessForall DerivDeclCtx ty + rnHsSigWcType DerivDeclCtx ty ; warnNoDerivStrat mds' loc ; return (DerivDecl noExtField ty' mds' overlap, fvs) } where @@ -1029,7 +1029,7 @@ bindRuleTmVars doc tyvs vars names thing_inside go ((L l (RuleBndrSig _ (L loc _) bsig)) : vars) (n : ns) thing_inside - = rnHsSigWcTypeScoped bind_free_tvs doc bsig $ \ bsig' -> + = rnHsPatSigType bind_free_tvs doc bsig $ \ bsig' -> go vars ns $ \ vars' -> thing_inside (L l (RuleBndrSig noExtField (L loc n) bsig') : vars') ===================================== compiler/GHC/Rename/Pat.hs ===================================== @@ -218,9 +218,6 @@ matchNameMaker ctxt = LamMk report_unused ThPatQuote -> False _ -> True -rnHsSigCps :: LHsSigWcType GhcPs -> CpsRn (LHsSigWcType GhcRn) -rnHsSigCps sig = CpsRn (rnHsSigWcTypeScoped AlwaysBind PatCtx sig) - newPatLName :: NameMaker -> Located RdrName -> CpsRn (Located Name) newPatLName name_maker rdr_name@(L loc _) = do { name <- newPatName name_maker rdr_name @@ -410,9 +407,12 @@ rnPatAndThen mk (SigPat x pat sig) -- f ((Just (x :: a) :: Maybe a) -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~^ `a' is first bound here -- ~~~~~~~~~~~~~~~^ the same `a' then used here - = do { sig' <- rnHsSigCps sig + = do { sig' <- rnHsPatSigTypeAndThen sig ; pat' <- rnLPatAndThen mk pat ; return (SigPat x pat' sig' ) } + where + rnHsPatSigTypeAndThen :: HsPatSigType GhcPs -> CpsRn (HsPatSigType GhcRn) + rnHsPatSigTypeAndThen sig = CpsRn (rnHsPatSigType AlwaysBind PatCtx sig) rnPatAndThen mk (LitPat x lit) | HsString src s <- lit ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -3338,7 +3338,7 @@ Result works fine, but it may eventually bite us. ********************************************************************* -} tcHsPatSigType :: UserTypeCtxt - -> LHsSigWcType GhcRn -- The type signature + -> HsPatSigType GhcRn -- The type signature -> TcM ( [(Name, TcTyVar)] -- Wildcards , [(Name, TcTyVar)] -- The new bit of type environment, binding -- the scoped type variables @@ -3346,13 +3346,13 @@ tcHsPatSigType :: UserTypeCtxt -- Used for type-checking type signatures in -- (a) patterns e.g f (x::Int) = e -- (b) RULE forall bndrs e.g. forall (x::Int). f x = x +-- See Note [Pattern signature binders and scoping] in GHC.Hs.Types -- -- This may emit constraints -- See Note [Recipe for checking a signature] -tcHsPatSigType ctxt sig_ty - | HsWC { hswc_ext = sig_wcs, hswc_body = ib_ty } <- sig_ty - , HsIB { hsib_ext = sig_ns - , hsib_body = hs_ty } <- ib_ty +tcHsPatSigType ctxt + (HsPS { hsps_ext = HsPSRn { hsps_nwcs = sig_wcs, hsps_imp_tvs = sig_ns } + , hsps_body = hs_ty }) = addSigCtxt ctxt hs_ty $ do { sig_tkv_prs <- mapM new_implicit_tv sig_ns ; (wcs, sig_ty) @@ -3385,12 +3385,12 @@ tcHsPatSigType ctxt sig_ty ; tv <- case ctxt of RuleSigCtxt {} -> newSkolemTyVar name kind _ -> newPatSigTyVar name kind - -- See Note [Pattern signature binders] + -- See Note [Typechecking pattern signature binders] -- NB: tv's Name may be fresh (in the case of newPatSigTyVar) ; return (name, tv) } -{- Note [Pattern signature binders] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [Typechecking pattern signature binders] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ See also Note [Type variables in the type environment] in GHC.Tc.Utils. Consider ===================================== compiler/GHC/Tc/Gen/Pat.hs ===================================== @@ -690,7 +690,7 @@ because they won't be in scope when we do the desugaring -} tcPatSig :: Bool -- True <=> pattern binding - -> LHsSigWcType GhcRn + -> HsPatSigType GhcRn -> ExpSigmaType -> TcM (TcType, -- The type to use for "inside" the signature [(Name,TcTyVar)], -- The new bit of type environment, binding ===================================== compiler/GHC/Tc/Gen/Rule.hs ===================================== @@ -230,7 +230,7 @@ tcRuleTmBndrs (L _ (RuleBndrSig _ (L _ name) rn_ty) : rule_bndrs) = do { let ctxt = RuleSigCtxt name ; (_ , tvs, id_ty) <- tcHsPatSigType ctxt rn_ty ; let id = mkLocalId name id_ty - -- See Note [Pattern signature binders] in GHC.Tc.Gen.HsType + -- See Note [Typechecking pattern signature binders] in GHC.Tc.Gen.HsType -- The type variables scope over subsequent bindings; yuk ; (tyvars, tmvars) <- tcExtendNameTyVarEnv tvs $ ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -830,7 +830,7 @@ cvtRuleBndr (RuleVar n) cvtRuleBndr (TypedRuleVar n ty) = do { n' <- vNameL n ; ty' <- cvtType ty - ; return $ noLoc $ Hs.RuleBndrSig noExtField n' $ mkLHsSigWcType ty' } + ; return $ noLoc $ Hs.RuleBndrSig noExtField n' $ mkHsPatSigType ty' } --------------------------------------------------- -- Declarations @@ -1307,7 +1307,7 @@ cvtp (ListP ps) = do { ps' <- cvtPats ps ; return $ ListPat noExtField ps'} cvtp (SigP p t) = do { p' <- cvtPat p; t' <- cvtType t - ; return $ SigPat noExtField p' (mkLHsSigWcType t') } + ; return $ SigPat noExtField p' (mkHsPatSigType t') } cvtp (ViewP e p) = do { e' <- cvtl e; p' <- cvtPat p ; return $ ViewPat noExtField e' p'} ===================================== testsuite/tests/hiefile/should_compile/hie007.hs ===================================== @@ -64,3 +64,6 @@ thud f x = (x :: a, y) :: (a, b) where y = (f :: a -> b) x :: b + +rankn :: (forall a1. a1 -> b) -> a2 -> b +rankn (g :: forall a1. a1 -> b) x = g x :: b View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/af9b43409fc2e65d6a7fdd9b95c484ab9cb0a9de -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/af9b43409fc2e65d6a7fdd9b95c484ab9cb0a9de You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 6 11:46:41 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 06 May 2020 07:46:41 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 13 commits: Refactor hole constraints. Message-ID: <5eb2a3a19ec3b_61673f81cc913ba0913216b@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 7ab6ab09 by Richard Eisenberg at 2020-05-06T04:39:32-04:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG ------------------------- - - - - - 420b957d by Ben Gamari at 2020-05-06T04:40:08-04:00 rts: Zero block flags with -DZ Block flags are very useful for determining the state of a block. However, some block allocator users don't touch them, leading to misleading values. Ensure that we zero then when zero-on-gc is set. This is safe and makes the flags more useful during debugging. - - - - - 740b3b8d by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix incorrect failed_to_evac value during deadlock gc Previously we would incorrectly set the failed_to_evac flag if we evacuated a value due to a deadlock GC. This would cause us to mark more things as dirty than strictly necessary. It also turned up a nasty but which I will fix next. - - - - - b2d72c75 by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - 9f3e6884 by Zubin Duggal at 2020-05-06T04:41:08-04:00 Allow atomic update of NameCache in readHieFile The situation arises in ghcide where multiple different threads may need to update the name cache, therefore with the older interface it could happen that you start reading a hie file with name cache A and produce name cache A + B, but another thread in the meantime updated the namecache to A + C. Therefore if you write the new namecache you will lose the A' updates from the second thread. Updates haddock submodule - - - - - edec6a6c by Ryan Scott at 2020-05-06T04:41:57-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _)`. Fixes #18127. - - - - - a95e7fe0 by Ömer Sinan Ağacan at 2020-05-06T04:42:39-04:00 ELF linker: increment curSymbol after filling in fields of current entry The bug was introduced in a8b7cef4d45 which added a field to the `symbols` array elements and then updated this code incorrectly: - oc->symbols[curSymbol++] = nm; + oc->symbols[curSymbol++].name = nm; + oc->symbols[curSymbol].addr = symbol->addr; - - - - - cab1871a by Sylvain Henry at 2020-05-06T04:43:21-04:00 Move LeadingUnderscore into Platform (#17957) Avoid direct use of DynFlags to know if symbols must be prefixed by an underscore. - - - - - 94e7c563 by Sylvain Henry at 2020-05-06T04:43:21-04:00 Don't use DynFlags in showLinkerState (#17957) - - - - - 9afd9251 by Ryan Scott at 2020-05-06T04:43:58-04:00 Refactoring: Use bindSigTyVarsFV in rnMethodBinds `rnMethodBinds` was explicitly using `xoptM` to determine if `ScopedTypeVariables` is enabled before bringing type variables bound by the class/instance header into scope. However, this `xoptM` logic is already performed by the `bindSigTyVarsFV` function. This patch uses `bindSigTyVarsFV` in `rnMethodBinds` to reduce the number of places where we need to consult if `ScopedTypeVariables` is on. This is purely refactoring, and there should be no user-visible change in behavior. - - - - - 4986853e by Adam Gundry at 2020-05-06T07:46:35-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. - - - - - 67ffeb3a by Simon Peyton Jones at 2020-05-06T07:46:36-04:00 Fix specialisation for DFuns When specialising a DFun we must take care to saturate the unfolding. See Note [Specialising DFuns] in Specialise. Fixes #18120 - - - - - 6aeb9888 by Ryan Scott at 2020-05-06T07:46:36-04:00 Bump exceptions submodule so that dist-boot is .gitignore'd `exceptions` is a stage-0 boot library as of commit 30272412fa437ab8e7a8035db94a278e10513413, which means that building `exceptions` in a GHC tree will generate a `dist-boot` directory. However, this directory was not specified in `exceptions`' `.gitignore` file, which causes it to dirty up the current `git` working directory. Accordingly, this bumps the `exceptions` submodule to commit ghc/packages/exceptions at 23c0b8a50d7592af37ca09beeec16b93080df98f, which adds `dist-boot` to the `.gitignore` file. - - - - - 30 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Plugins.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Runtime/Linker.hs - compiler/GHC/Settings.hs - compiler/GHC/Settings/IO.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Errors/Hole.hs-boot - compiler/GHC/Tc/Errors/Hole/FitTypes.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Rule.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/Solver/Canonical.hs - compiler/GHC/Tc/Solver/Flatten.hs - compiler/GHC/Tc/Solver/Interact.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Types/Constraint.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d3cc9c8ed9a3910febec4c25ed915ea7de7ad0f3...6aeb9888fc1f3cb5ca2033642edf40852e911c18 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d3cc9c8ed9a3910febec4c25ed915ea7de7ad0f3...6aeb9888fc1f3cb5ca2033642edf40852e911c18 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 6 13:26:08 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 06 May 2020 09:26:08 -0400 Subject: [Git][ghc/ghc][wip/T17917] Avoid useless w/w split Message-ID: <5eb2baf049006_61673f81cd4c695c91577f@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T17917 at Glasgow Haskell Compiler / GHC Commits: 0716463f by Simon Peyton Jones at 2020-05-06T13:25:32+00:00 Avoid useless w/w split This patch is just a tidy-up for the post-strictness-analysis worker wrapper split. Consider f x = x Strictnesss analysis does not lead to a w/w split, so the obvious thing is to leave it 100% alone. But actually, because the RHS is small, we ended up adding a StableUnfolding for it. There is some reason to do this if we choose /not/ do to w/w on the grounds that the function is small. See Note [Don't w/w inline small non-loop-breaker things] But there is no reason if we would not have done w/w anyway. This patch just moves the conditional to later. Easy. This does move soem -ddump-simpl printouts around a bit. I also discovered that the previous code was overwritten an InlineCompulsory with InlineStable, which is utterly wrong. That in turn meant that some default methods (marked InlineCompulsory) were getting their InlineCompulsory squashed. This patch fixes that bug --- but of course that does mean a bit more inlining! Metric Decrease: T9233 T9675 Metric Increase: T3064 T4029 T9872b T9872d - - - - - 11 changed files: - compiler/GHC/Core/Opt/WorkWrap.hs - compiler/GHC/Core/Unfold.hs - testsuite/tests/dependent/should_compile/dynamic-paper.stderr - testsuite/tests/driver/inline-check.stderr - testsuite/tests/numeric/should_compile/T14465.stdout - testsuite/tests/perf/compiler/T16473.stdout - testsuite/tests/simplCore/should_compile/T17901.stdout - testsuite/tests/simplCore/should_compile/T17966.stdout - testsuite/tests/simplCore/should_compile/T4201.stdout - testsuite/tests/simplCore/should_compile/T5658b.stdout - testsuite/tests/warnings/should_compile/T16282/T16282.stderr Changes: ===================================== compiler/GHC/Core/Opt/WorkWrap.hs ===================================== @@ -26,6 +26,7 @@ import GHC.Types.Cpr import GHC.Core.Opt.WorkWrap.Utils import GHC.Utils.Misc import GHC.Utils.Outputable +import GHC.Types.Unique import GHC.Core.FamInstEnv import GHC.Utils.Monad @@ -203,6 +204,23 @@ unfolding to the *worker*. So we will get something like this: How do we "transfer the unfolding"? Easy: by using the old one, wrapped in work_fn! See GHC.Core.Unfold.mkWorkerUnfolding. +Note [No worker-wrapper for record selectors] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +We sometimes generate a lot of record selectors, and generally the +don't benefit from worker/wrapper. Yes, mkWwBodies would find a w/w split, +but it is then suppressed by the certainlyWillInline test in splitFun. + +The wasted effort in mkWwBodies makes a measurable difference in +compile time (see MR !2873), so although it's a terribly ad-hoc test, +we just check here for record selectors, and do a no-op in that case. + +I did look for a generalisation, so that it's not just record +selectors that benefit. But you'd need a cheap test for "this +function will definitely get a w/w split" and that's hard to predict +in advance...the logic in mkWwBodies is complex. So I've left the +super-simple test, with this Note to explain. + + Note [Worker-wrapper for NOINLINE functions] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We used to disable worker/wrapper for NOINLINE things, but it turns out @@ -316,8 +334,8 @@ Note [Don't w/w inline small non-loop-breaker things] In general, we refrain from w/w-ing *small* functions, which are not loop breakers, because they'll inline anyway. But we must take care: it may look small now, but get to be big later after other inlining -has happened. So we take the precaution of adding an INLINE pragma to -any such functions. +has happened. So we take the precaution of adding a StableUnfolding +for any such functions. I made this change when I observed a big function at the end of compilation with a useful strictness signature but no w-w. (It was @@ -457,11 +475,6 @@ tryWW :: DynFlags tryWW dflags fam_envs is_rec fn_id rhs -- See Note [Worker-wrapper for NOINLINE functions] - | Just stable_unf <- certainlyWillInline dflags fn_info - = return [ (fn_id `setIdUnfolding` stable_unf, rhs) ] - -- See Note [Don't w/w INLINE things] - -- See Note [Don't w/w inline small non-loop-breaker things] - | is_fun && is_eta_exp = splitFun dflags fam_envs new_fn_id fn_info wrap_dmds div cpr rhs @@ -567,105 +580,125 @@ See https://gitlab.haskell.org/ghc/ghc/merge_requests/312#note_192064. splitFun :: DynFlags -> FamInstEnvs -> Id -> IdInfo -> [Demand] -> Divergence -> CprResult -> CoreExpr -> UniqSM [(Id, CoreExpr)] splitFun dflags fam_envs fn_id fn_info wrap_dmds div cpr rhs - = WARN( not (wrap_dmds `lengthIs` arity), ppr fn_id <+> (ppr arity $$ ppr wrap_dmds $$ ppr cpr) ) do - -- The arity should match the signature - stuff <- mkWwBodies dflags fam_envs rhs_fvs fn_id wrap_dmds use_cpr_info - case stuff of - Just (work_demands, join_arity, wrap_fn, work_fn) -> do - work_uniq <- getUniqueM - let work_rhs = work_fn rhs - work_act = case fn_inline_spec of -- See Note [Worker activation] - NoInline -> fn_act - _ -> wrap_act - - work_prag = InlinePragma { inl_src = SourceText "{-# INLINE" - , inl_inline = fn_inline_spec - , inl_sat = Nothing - , inl_act = work_act - , inl_rule = FunLike } - -- inl_inline: copy from fn_id; see Note [Worker-wrapper for INLINABLE functions] - -- inl_act: see Note [Worker activation] - -- inl_rule: it does not make sense for workers to be constructorlike. - - work_join_arity | isJoinId fn_id = Just join_arity - | otherwise = Nothing - -- worker is join point iff wrapper is join point - -- (see Note [Don't w/w join points for CPR]) - - work_id = mkWorkerId work_uniq fn_id (exprType work_rhs) - `setIdOccInfo` occInfo fn_info - -- Copy over occurrence info from parent - -- Notably whether it's a loop breaker - -- Doesn't matter much, since we will simplify next, but - -- seems right-er to do so - - `setInlinePragma` work_prag - - `setIdUnfolding` mkWorkerUnfolding dflags work_fn fn_unfolding - -- See Note [Worker-wrapper for INLINABLE functions] - - `setIdStrictness` mkClosedStrictSig work_demands div - -- Even though we may not be at top level, - -- it's ok to give it an empty DmdEnv - - `setIdCprInfo` mkCprSig work_arity work_cpr_info - - `setIdDemandInfo` worker_demand - - `setIdArity` work_arity - -- Set the arity so that the Core Lint check that the - -- arity is consistent with the demand type goes - -- through - `asJoinId_maybe` work_join_arity - - work_arity = length work_demands - - -- See Note [Demand on the Worker] - single_call = saturatedByOneShots arity (demandInfo fn_info) - worker_demand | single_call = mkWorkerDemand work_arity - | otherwise = topDmd - - wrap_rhs = wrap_fn work_id - wrap_act = case fn_act of -- See Note [Wrapper activation] - ActiveAfter {} -> fn_act - NeverActive -> activeDuringFinal - _ -> activeAfterInitial - wrap_prag = InlinePragma { inl_src = SourceText "{-# INLINE" - , inl_inline = NoUserInline - , inl_sat = Nothing - , inl_act = wrap_act - , inl_rule = rule_match_info } - -- inl_act: see Note [Wrapper activation] - -- inl_inline: see Note [Wrapper NoUserInline] - -- inl_rule: RuleMatchInfo is (and must be) unaffected - - wrap_id = fn_id `setIdUnfolding` mkWwInlineRule dflags wrap_rhs arity - `setInlinePragma` wrap_prag - `setIdOccInfo` noOccInfo - -- Zap any loop-breaker-ness, to avoid bleating from Lint - -- about a loop breaker with an INLINE rule - - - - return $ [(work_id, work_rhs), (wrap_id, wrap_rhs)] - -- Worker first, because wrapper mentions it - - Nothing -> return [(fn_id, rhs)] + | isRecordSelector fn_id -- See Note [No worker/wrapper for record selectors] + = return [ (fn_id, rhs ) ] + + | otherwise + = WARN( not (wrap_dmds `lengthIs` arity), ppr fn_id <+> (ppr arity $$ ppr wrap_dmds $$ ppr cpr) ) + -- The arity should match the signature + do { mb_stuff <- mkWwBodies dflags fam_envs rhs_fvs fn_id wrap_dmds use_cpr_info + ; case mb_stuff of + Nothing -> return [(fn_id, rhs)] + + Just stuff + | Just stable_unf <- certainlyWillInline dflags fn_info + -> return [ (fn_id `setIdUnfolding` stable_unf, rhs) ] + -- See Note [Don't w/w INLINE things] + -- See Note [Don't w/w inline small non-loop-breaker things] + + | otherwise + -> do { work_uniq <- getUniqueM + ; return (mkWWBindPair dflags fn_id fn_info arity rhs + work_uniq div cpr stuff) } } where - rhs_fvs = exprFreeVars rhs + rhs_fvs = exprFreeVars rhs + arity = arityInfo fn_info + -- The arity is set by the simplifier using exprEtaExpandArity + -- So it may be more than the number of top-level-visible lambdas + + -- use_cpr_info is the CPR we w/w for. Note that we kill it for join points, + -- see Note [Don't w/w join points for CPR]. + use_cpr_info | isJoinId fn_id = topCpr + | otherwise = cpr + + +mkWWBindPair :: DynFlags -> Id -> IdInfo -> Arity + -> CoreExpr -> Unique -> Divergence -> CprResult + -> ([Demand], JoinArity, Id -> CoreExpr, Expr CoreBndr -> CoreExpr) + -> [(Id, CoreExpr)] +mkWWBindPair dflags fn_id fn_info arity rhs work_uniq div cpr + (work_demands, join_arity, wrap_fn, work_fn) + = [(work_id, work_rhs), (wrap_id, wrap_rhs)] + -- Worker first, because wrapper mentions it + where + work_rhs = work_fn rhs + work_act = case fn_inline_spec of -- See Note [Worker activation] + NoInline -> fn_act + _ -> wrap_act + + work_prag = InlinePragma { inl_src = SourceText "{-# INLINE" + , inl_inline = fn_inline_spec + , inl_sat = Nothing + , inl_act = work_act + , inl_rule = FunLike } + -- inl_inline: copy from fn_id; see Note [Worker-wrapper for INLINABLE functions] + -- inl_act: see Note [Worker activation] + -- inl_rule: it does not make sense for workers to be constructorlike. + + work_join_arity | isJoinId fn_id = Just join_arity + | otherwise = Nothing + -- worker is join point iff wrapper is join point + -- (see Note [Don't w/w join points for CPR]) + + work_id = mkWorkerId work_uniq fn_id (exprType work_rhs) + `setIdOccInfo` occInfo fn_info + -- Copy over occurrence info from parent + -- Notably whether it's a loop breaker + -- Doesn't matter much, since we will simplify next, but + -- seems right-er to do so + + `setInlinePragma` work_prag + + `setIdUnfolding` mkWorkerUnfolding dflags work_fn fn_unfolding + -- See Note [Worker-wrapper for INLINABLE functions] + + `setIdStrictness` mkClosedStrictSig work_demands div + -- Even though we may not be at top level, + -- it's ok to give it an empty DmdEnv + + `setIdCprInfo` mkCprSig work_arity work_cpr_info + + `setIdDemandInfo` worker_demand + + `setIdArity` work_arity + -- Set the arity so that the Core Lint check that the + -- arity is consistent with the demand type goes + -- through + `asJoinId_maybe` work_join_arity + + work_arity = length work_demands + + -- See Note [Demand on the Worker] + single_call = saturatedByOneShots arity (demandInfo fn_info) + worker_demand | single_call = mkWorkerDemand work_arity + | otherwise = topDmd + + wrap_rhs = wrap_fn work_id + wrap_act = case fn_act of -- See Note [Wrapper activation] + ActiveAfter {} -> fn_act + NeverActive -> activeDuringFinal + _ -> activeAfterInitial + wrap_prag = InlinePragma { inl_src = SourceText "{-# INLINE" + , inl_inline = NoUserInline + , inl_sat = Nothing + , inl_act = wrap_act + , inl_rule = rule_match_info } + -- inl_act: see Note [Wrapper activation] + -- inl_inline: see Note [Wrapper NoUserInline] + -- inl_rule: RuleMatchInfo is (and must be) unaffected + + wrap_id = fn_id `setIdUnfolding` mkWwInlineRule dflags wrap_rhs arity + `setInlinePragma` wrap_prag + `setIdOccInfo` noOccInfo + -- Zap any loop-breaker-ness, to avoid bleating from Lint + -- about a loop breaker with an INLINE rule + fn_inl_prag = inlinePragInfo fn_info fn_inline_spec = inl_inline fn_inl_prag fn_act = inl_act fn_inl_prag rule_match_info = inlinePragmaRuleMatchInfo fn_inl_prag fn_unfolding = unfoldingInfo fn_info - arity = arityInfo fn_info - -- The arity is set by the simplifier using exprEtaExpandArity - -- So it may be more than the number of top-level-visible lambdas - -- use_cpr_info is the CPR we w/w for. Note that we kill it for join points, - -- see Note [Don't w/w join points for CPR]. - use_cpr_info | isJoinId fn_id = topCpr - | otherwise = cpr -- Even if we don't w/w join points for CPR, we might still do so for -- strictness. In which case a join point worker keeps its original CPR -- property; see Note [Don't w/w join points for CPR]. Otherwise, the worker ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -1121,11 +1121,21 @@ certainlyWillInline :: DynFlags -> IdInfo -> Maybe Unfolding -- ^ Sees if the unfolding is pretty certain to inline. -- If so, return a *stable* unfolding for it, that will always inline. certainlyWillInline dflags fn_info - = case unfoldingInfo fn_info of - CoreUnfolding { uf_tmpl = e, uf_guidance = g } - | loop_breaker -> Nothing -- Won't inline, so try w/w - | noinline -> Nothing -- See Note [Worker-wrapper for NOINLINE functions] - | otherwise -> do_cunf e g -- Depends on size, so look at that + = case fn_unf of + CoreUnfolding { uf_tmpl = expr, uf_guidance = guidance, uf_src = src } + | loop_breaker -> Nothing -- Won't inline, so try w/w + | noinline -> Nothing -- See Note [Worker-wrapper for NOINLINE functions] + | otherwise + -> case guidance of + UnfNever -> Nothing + UnfWhen {} -> Just (fn_unf { uf_src = src' }) + -- INLINE functions have UnfWhen + UnfIfGoodArgs { ug_size = size, ug_args = args } + -> do_cunf expr size args src' + where + src' = case src of + InlineRhs -> InlineStable + _ -> src -- Do not change InlineCompulsory! DFunUnfolding {} -> Just fn_unf -- Don't w/w DFuns; it never makes sense -- to do so, and even if it is currently a @@ -1138,17 +1148,12 @@ certainlyWillInline dflags fn_info noinline = inlinePragmaSpec (inlinePragInfo fn_info) == NoInline fn_unf = unfoldingInfo fn_info - do_cunf :: CoreExpr -> UnfoldingGuidance -> Maybe Unfolding - do_cunf _ UnfNever = Nothing - do_cunf _ (UnfWhen {}) = Just (fn_unf { uf_src = InlineStable }) - -- INLINE functions have UnfWhen - -- The UnfIfGoodArgs case seems important. If we w/w small functions -- binary sizes go up by 10%! (This is with SplitObjs.) -- I'm not totally sure why. -- INLINABLE functions come via this path -- See Note [certainlyWillInline: INLINABLE] - do_cunf expr (UnfIfGoodArgs { ug_size = size, ug_args = args }) + do_cunf expr size args src' | arityInfo fn_info > 0 -- See Note [certainlyWillInline: be careful of thunks] , not (isBottomingSig (strictnessInfo fn_info)) -- Do not unconditionally inline a bottoming functions even if @@ -1156,7 +1161,7 @@ certainlyWillInline dflags fn_info -- so we don't want to re-inline it. , let unf_arity = length args , size - (10 * (unf_arity + 1)) <= ufUseThreshold dflags - = Just (fn_unf { uf_src = InlineStable + = Just (fn_unf { uf_src = src' , uf_guidance = UnfWhen { ug_arity = unf_arity , ug_unsat_ok = unSaturatedOk , ug_boring_ok = inlineBoringOk expr } }) ===================================== testsuite/tests/dependent/should_compile/dynamic-paper.stderr ===================================== @@ -12,4 +12,4 @@ Simplifier ticks exhausted simplifier non-termination has been judged acceptable. To see detailed counts use -ddump-simpl-stats - Total ticks: 138082 + Total ticks: 157721 ===================================== testsuite/tests/driver/inline-check.stderr ===================================== @@ -21,6 +21,7 @@ Considering inlining: foo some_benefit False is exp: True is work-free: True - guidance ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False) + guidance IF_ARGS [0] 30 0 + discounted size = 20 ANSWER = NO Inactive unfolding: foo1 ===================================== testsuite/tests/numeric/should_compile/T14465.stdout ===================================== @@ -82,10 +82,8 @@ plusOne :: Natural -> Natural [GblId, Arity=1, Str=, - Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, - Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False) - Tmpl= \ (n [Occ=Once] :: Natural) -> plusNatural n M.minusOne1}] + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [0] 30 0}] plusOne = \ (n :: Natural) -> plusNatural n M.minusOne1 -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} ===================================== testsuite/tests/perf/compiler/T16473.stdout ===================================== @@ -2,10 +2,10 @@ Rule fired: Class op fmap (BUILTIN) Rule fired: Class op liftA2 (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) Rule fired: Class op <*> (BUILTIN) -Rule fired: Class op <$ (BUILTIN) +Rule fired: Class op fmap (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) Rule fired: Class op <*> (BUILTIN) -Rule fired: Class op fmap (BUILTIN) +Rule fired: Class op <$ (BUILTIN) Rule fired: Class op pure (BUILTIN) Rule fired: Class op pure (BUILTIN) Rule fired: Class op >>= (BUILTIN) ===================================== testsuite/tests/simplCore/should_compile/T17901.stdout ===================================== @@ -1,14 +1,6 @@ - (wombat1 [Occ=Once*!] :: T -> p) - A -> wombat1 T17901.A; - B -> wombat1 T17901.B; - C -> wombat1 T17901.C = \ (@p) (wombat1 :: T -> p) (x :: T) -> case x of wild { __DEFAULT -> wombat1 wild } - Tmpl= \ (@p) (wombat2 [Occ=Once!] :: S -> p) (x [Occ=Once] :: S) -> - case x of wild [Occ=Once] { __DEFAULT -> wombat2 wild }}] = \ (@p) (wombat2 :: S -> p) (x :: S) -> case x of wild { __DEFAULT -> wombat2 wild } - Tmpl= \ (@p) (wombat3 [Occ=Once!] :: W -> p) (x [Occ=Once] :: W) -> - case x of wild [Occ=Once] { __DEFAULT -> wombat3 wild }}] = \ (@p) (wombat3 :: W -> p) (x :: W) -> case x of wild { __DEFAULT -> wombat3 wild } ===================================== testsuite/tests/simplCore/should_compile/T17966.stdout ===================================== @@ -1,5 +1,3 @@ RULES: "SPEC $cm @()" [0] RULES: "SPEC f @Bool @() @(Maybe Integer)" [0] -"SPEC/T17966 $fShowMaybe_$cshow @Integer" -"SPEC/T17966 $fShowMaybe_$cshowList @Integer" "SPEC/T17966 $fShowMaybe @Integer" ===================================== testsuite/tests/simplCore/should_compile/T4201.stdout ===================================== @@ -1,3 +1,3 @@ + lift :: Foo -> T [HasNoCafRefs, Arity: 1, Strictness: , - Unfolding: InlineRule (0, True, True) - bof `cast` (Sym (N:Foo[0]) ->_R _R)] + Unfolding: (bof `cast` (Sym (N:Foo[0]) ->_R _R))] ===================================== testsuite/tests/simplCore/should_compile/T5658b.stdout ===================================== @@ -1 +1 @@ -4 +2 ===================================== testsuite/tests/warnings/should_compile/T16282/T16282.stderr ===================================== @@ -6,5 +6,4 @@ T16282.hs: warning: [-Wall-missed-specialisations] T16282.hs: warning: [-Wall-missed-specialisations] Could not specialise imported function ‘Data.Map.Internal.$w$cshowsPrec’ - when specialising ‘Data.Map.Internal.$fShowMap_$cshowsPrec’ Probable fix: add INLINABLE pragma on ‘Data.Map.Internal.$w$cshowsPrec’ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0716463ffbceb635ff42dfdd466efde803896299 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0716463ffbceb635ff42dfdd466efde803896299 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 6 14:45:03 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 06 May 2020 10:45:03 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/cpr-expandable-unfoldings Message-ID: <5eb2cd6fcef12_61673f81cc913ba09177289@gitlab.haskell.org.mail> Sebastian Graf pushed new branch wip/cpr-expandable-unfoldings at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/cpr-expandable-unfoldings You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 6 15:14:00 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 06 May 2020 11:14:00 -0400 Subject: [Git][ghc/ghc][wip/cpr-expandable-unfoldings] CprAnal: Don't attach CPR sigs to expandable bindings (#18154) Message-ID: <5eb2d438674a6_61671285600891817e8@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/cpr-expandable-unfoldings at Glasgow Haskell Compiler / GHC Commits: 68b5786d by Sebastian Graf at 2020-05-06T17:13:44+02:00 CprAnal: Don't attach CPR sigs to expandable bindings (#18154) Instead, look through expandable unfoldings in `cprTransform`. See the new Note [CPR for expandable unfoldings]: ``` GHC generates a lot of TyCon and KindRep bindings, one for each new data declaration. Attaching CPR signatures to each of them is quite wasteful. In general, DataCon application bindings * Never get WW'd, so their CPR signature should be irrelevant after analysis * Would need to be inlined to see their CPR * Recording (Nested!) CPR on them blows up interface file sizes But we can't just stop giving DataCon application bindings the CPR property, for example fac 0 = 1 fac n = n * fac (n-1) fac certainly has the CPR property and should be WW'd! But FloatOut will transform the first clause to lvl = 1 fac 0 = lvl If lvl doesn't have the CPR property, fac won't either. So instead we keep on looking through *expandable* unfoldings for these arity 0 bindings. ``` Fixes #18154. - - - - - 1 changed file: - compiler/GHC/Core/Opt/CprAnal.hs Changes: ===================================== compiler/GHC/Core/Opt/CprAnal.hs ===================================== @@ -231,9 +231,14 @@ cprTransform env id sig where sig - | isGlobalId id -- imported function or data con worker + -- See Note [CPR for expandable unfoldings] + | Just rhs <- lookupExpandableUnfolding id + = fst $ cprAnal env rhs + -- Imported function or data con worker + | isGlobalId id = getCprSig (idCprInfo id) - | Just sig <- lookupSigEnv env id -- local let-bound + -- Local let-bound + | Just sig <- lookupSigEnv env id = getCprSig sig | otherwise = topCprType @@ -303,6 +308,8 @@ cprAnalBind top_lvl env id rhs | stays_thunk = trimCprTy rhs_ty -- See Note [CPR for sum types] | returns_sum = trimCprTy rhs_ty + -- See Note [CPR for expandable unfoldings] + | will_expand = topCprType | otherwise = rhs_ty -- See Note [Arity trimming for CPR signatures] sig = mkCprSigForArity (idArity id) rhs_ty' @@ -316,6 +323,19 @@ cprAnalBind top_lvl env id rhs (_, ret_ty) = splitPiTys (idType id) not_a_prod = isNothing (deepSplitProductType_maybe (ae_fam_envs env) ret_ty) returns_sum = not (isTopLevel top_lvl) && not_a_prod + -- See Note [CPR for expandable unfoldings] + will_expand = isJust (lookupExpandableUnfolding id) + +lookupExpandableUnfolding :: Id -> Maybe CoreExpr +lookupExpandableUnfolding id + | idArity id == 0 = expandUnfolding_maybe (cprIdUnfolding id) + | otherwise = Nothing + +cprIdUnfolding :: IdUnfoldingFun +cprIdUnfolding id + -- There will only be phase 0 Simplifier runs after CprAnal + | isActiveIn 0 (idInlineActivation id) = idUnfolding id + | otherwise = noUnfolding {- Note [Arity trimming for CPR signatures] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -626,6 +646,28 @@ fac won't have the CPR property here when we trim every thunk! But the assumption is that error cases are rarely entered and we are diverging anyway, so WW doesn't hurt. +Should we also trim CPR on DataCon bindings? +See Note [CPR for expandable unfoldings]! + +Note [CPR for expandable unfoldings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +GHC generates a lot of TyCon and KindRep bindings, one for each new data +declaration. Attaching CPR signatures to each of them is quite wasteful. +In general, DataCon application bindings + * Never get WW'd, so their CPR signature should be irrelevant after analysis + * Would need to be inlined to see their CPR + * Recording (Nested!) CPR on them blows up interface file sizes +But we can't just stop giving DataCon application bindings the CPR property, +for example + fac 0 = 1 + fac n = n * fac (n-1) +fac certainly has the CPR property and should be WW'd! But FloatOut will +transform the first clause to + lvl = 1 + fac 0 = lvl +If lvl doesn't have the CPR property, fac won't either. So instead we keep on +looking through *expandable* unfoldings for these arity 0 bindings. + Note [CPR examples] ~~~~~~~~~~~~~~~~~~~~ Here are some examples (stranal/should_compile/T10482a) of the View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/68b5786d17d8c9f801f15d5e4fc25167b6eff8fe -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/68b5786d17d8c9f801f15d5e4fc25167b6eff8fe You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 6 16:57:18 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 06 May 2020 12:57:18 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn-simpl] DmdAnal: Improve handling of precise exceptions Message-ID: <5eb2ec6e9b6fd_6167128409c49208196@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn-simpl at Glasgow Haskell Compiler / GHC Commits: c0bb5a19 by Sebastian Graf at 2020-05-06T18:57:06+02:00 DmdAnal: Improve handling of precise exceptions This patch does two things: Fix possible unsoundness in what was called the "IO hack" and implement part 2.1 of the "fixing precise exceptions" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions, which, in combination with !2956, supersedes !3014 and !2525. **IO hack** The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is called `exprMayThrowPreciseException` now. I came up with two testcases exemplifying possible unsoundness (if twisted enough) in the old approach: - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. - `T13380e`: Demonstrating unsoundness of the "IO hack" when we have Nested CPR. Not currently relevant, as we don't have Nested CPR yet. Basically, the IO hack assumed that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future, see `T13380e`. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380{d,e}` (and will hopefully be robust to Nested CPR). **Precise exceptions** In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that was terribly unprincipled. That unprincipledness resulted in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception (and the existing IO hack doesn't detect that) Fixing both issues in !3014 turned out to be too complicated and had the potential to regress in the future. Hence we decided to only fix `T13380b` and augment the `Divergence` lattice with a new middle-layer element, `ExnOrDiv`, which means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. See the wiki page on Step 2.1 for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#dead-code-elimination-for-raiseio-with-isdeadenddiv-introducing-exnordiv-step-21 - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/LiberateCase.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Make.hs - libraries/base/GHC/Fingerprint.hs - testsuite/tests/stranal/should_compile/T10482a.stderr - testsuite/tests/stranal/should_compile/T10694.stderr - + testsuite/tests/stranal/should_compile/T13380b.hs - testsuite/tests/stranal/should_compile/all.T - + testsuite/tests/stranal/should_run/T13380d.hs - + testsuite/tests/stranal/should_run/T13380d.stderr - + testsuite/tests/stranal/should_run/T13380e.hs - + testsuite/tests/stranal/should_run/T13380e.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c0bb5a1907fa0afb40e42532c824847bc7463333 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c0bb5a1907fa0afb40e42532c824847bc7463333 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 6 17:05:03 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 06 May 2020 13:05:03 -0400 Subject: [Git][ghc/ghc][wip/cpr-expandable-unfoldings] Accept testsuite results Message-ID: <5eb2ee3f8751_6167128560089221929@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/cpr-expandable-unfoldings at Glasgow Haskell Compiler / GHC Commits: 11fa2b07 by Sebastian Graf at 2020-05-06T19:04:54+02:00 Accept testsuite results - - - - - 27 changed files: - testsuite/tests/numeric/should_compile/T14170.stdout - testsuite/tests/numeric/should_compile/T14465.stdout - testsuite/tests/numeric/should_compile/T7116.stdout - testsuite/tests/simplCore/should_compile/T13143.stderr - testsuite/tests/simplCore/should_compile/T13543.stderr - testsuite/tests/simplCore/should_compile/T18013.stderr - testsuite/tests/simplCore/should_compile/T3717.stderr - testsuite/tests/simplCore/should_compile/T3772.stdout - testsuite/tests/simplCore/should_compile/T4908.stderr - testsuite/tests/simplCore/should_compile/T4930.stderr - testsuite/tests/simplCore/should_compile/T7360.stderr - testsuite/tests/simplCore/should_compile/noinline01.stderr - testsuite/tests/simplCore/should_compile/par01.stderr - testsuite/tests/simplCore/should_compile/spec-inline.stderr - testsuite/tests/stranal/should_compile/T10694.stderr - testsuite/tests/stranal/sigs/BottomFromInnerLambda.stderr - testsuite/tests/stranal/sigs/CaseBinderCPR.stderr - testsuite/tests/stranal/sigs/DmdAnalGADTs.stderr - testsuite/tests/stranal/sigs/HyperStrUse.stderr - testsuite/tests/stranal/sigs/NewtypeArity.stderr - testsuite/tests/stranal/sigs/StrAnalExample.stderr - testsuite/tests/stranal/sigs/T12370.stderr - testsuite/tests/stranal/sigs/T17932.stderr - testsuite/tests/stranal/sigs/T5075.stderr - testsuite/tests/stranal/sigs/T8569.stderr - testsuite/tests/stranal/sigs/T8598.stderr - testsuite/tests/stranal/sigs/UnsatFun.stderr Changes: ===================================== testsuite/tests/numeric/should_compile/T14170.stdout ===================================== @@ -13,7 +13,6 @@ NatVal.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} NatVal.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] NatVal.$trModule3 = GHC.Types.TrNameS NatVal.$trModule4 @@ -28,7 +27,6 @@ NatVal.$trModule2 = "NatVal"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} NatVal.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] NatVal.$trModule1 = GHC.Types.TrNameS NatVal.$trModule2 @@ -36,7 +34,6 @@ NatVal.$trModule1 = GHC.Types.TrNameS NatVal.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} NatVal.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] NatVal.$trModule ===================================== testsuite/tests/numeric/should_compile/T14465.stdout ===================================== @@ -20,7 +20,6 @@ M.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} M.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] M.$trModule3 = GHC.Types.TrNameS M.$trModule4 @@ -35,7 +34,6 @@ M.$trModule2 = "M"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} M.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] M.$trModule1 = GHC.Types.TrNameS M.$trModule2 @@ -43,7 +41,6 @@ M.$trModule1 = GHC.Types.TrNameS M.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} M.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] M.$trModule = GHC.Types.Module M.$trModule3 M.$trModule1 ===================================== testsuite/tests/numeric/should_compile/T7116.stdout ===================================== @@ -13,7 +13,6 @@ T7116.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7116.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7116.$trModule3 = GHC.Types.TrNameS T7116.$trModule4 @@ -28,7 +27,6 @@ T7116.$trModule2 = "T7116"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7116.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7116.$trModule1 = GHC.Types.TrNameS T7116.$trModule2 @@ -36,7 +34,6 @@ T7116.$trModule1 = GHC.Types.TrNameS T7116.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T7116.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T7116.$trModule ===================================== testsuite/tests/simplCore/should_compile/T13143.stderr ===================================== @@ -33,7 +33,6 @@ T13143.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T13143.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T13143.$trModule3 = GHC.Types.TrNameS T13143.$trModule4 @@ -48,7 +47,6 @@ T13143.$trModule2 = "T13143"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T13143.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T13143.$trModule1 = GHC.Types.TrNameS T13143.$trModule2 @@ -56,7 +54,6 @@ T13143.$trModule1 = GHC.Types.TrNameS T13143.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T13143.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T13143.$trModule ===================================== testsuite/tests/simplCore/should_compile/T13543.stderr ===================================== @@ -7,7 +7,7 @@ Foo.g: ==================== Cpr signatures ==================== -Foo.$trModule: m1 +Foo.$trModule: Foo.f: m1 Foo.g: m1 ===================================== testsuite/tests/simplCore/should_compile/T18013.stderr ===================================== @@ -177,7 +177,6 @@ T18013.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T18013.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T18013.$trModule3 = GHC.Types.TrNameS T18013.$trModule4 @@ -192,7 +191,6 @@ T18013.$trModule2 = "T18013"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T18013.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T18013.$trModule1 = GHC.Types.TrNameS T18013.$trModule2 @@ -200,7 +198,6 @@ T18013.$trModule1 = GHC.Types.TrNameS T18013.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T18013.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T18013.$trModule ===================================== testsuite/tests/simplCore/should_compile/T3717.stderr ===================================== @@ -13,7 +13,6 @@ T3717.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T3717.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T3717.$trModule3 = GHC.Types.TrNameS T3717.$trModule4 @@ -28,7 +27,6 @@ T3717.$trModule2 = "T3717"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T3717.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T3717.$trModule1 = GHC.Types.TrNameS T3717.$trModule2 @@ -36,7 +34,6 @@ T3717.$trModule1 = GHC.Types.TrNameS T3717.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T3717.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T3717.$trModule ===================================== testsuite/tests/simplCore/should_compile/T3772.stdout ===================================== @@ -13,7 +13,6 @@ T3772.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T3772.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T3772.$trModule3 = GHC.Types.TrNameS T3772.$trModule4 @@ -28,7 +27,6 @@ T3772.$trModule2 = "T3772"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T3772.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T3772.$trModule1 = GHC.Types.TrNameS T3772.$trModule2 @@ -36,7 +34,6 @@ T3772.$trModule1 = GHC.Types.TrNameS T3772.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T3772.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T3772.$trModule ===================================== testsuite/tests/simplCore/should_compile/T4908.stderr ===================================== @@ -13,7 +13,6 @@ T4908.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T4908.$trModule3 :: TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T4908.$trModule3 = GHC.Types.TrNameS T4908.$trModule4 @@ -28,7 +27,6 @@ T4908.$trModule2 = "T4908"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T4908.$trModule1 :: TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T4908.$trModule1 = GHC.Types.TrNameS T4908.$trModule2 @@ -36,7 +34,6 @@ T4908.$trModule1 = GHC.Types.TrNameS T4908.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T4908.$trModule :: Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T4908.$trModule ===================================== testsuite/tests/simplCore/should_compile/T4930.stderr ===================================== @@ -13,7 +13,6 @@ T4930.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T4930.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T4930.$trModule3 = GHC.Types.TrNameS T4930.$trModule4 @@ -28,7 +27,6 @@ T4930.$trModule2 = "T4930"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T4930.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T4930.$trModule1 = GHC.Types.TrNameS T4930.$trModule2 @@ -36,7 +34,6 @@ T4930.$trModule1 = GHC.Types.TrNameS T4930.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T4930.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T4930.$trModule ===================================== testsuite/tests/simplCore/should_compile/T7360.stderr ===================================== @@ -64,7 +64,6 @@ T7360.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$trModule3 = GHC.Types.TrNameS T7360.$trModule4 @@ -79,7 +78,6 @@ T7360.$trModule2 = "T7360"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$trModule1 = GHC.Types.TrNameS T7360.$trModule2 @@ -87,7 +85,6 @@ T7360.$trModule1 = GHC.Types.TrNameS T7360.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T7360.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T7360.$trModule @@ -110,7 +107,6 @@ T7360.$tcFoo2 = "Foo"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$tcFoo1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$tcFoo1 = GHC.Types.TrNameS T7360.$tcFoo2 @@ -118,7 +114,6 @@ T7360.$tcFoo1 = GHC.Types.TrNameS T7360.$tcFoo2 -- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} T7360.$tcFoo :: GHC.Types.TyCon [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 70}] T7360.$tcFoo @@ -147,7 +142,6 @@ T7360.$tc'Foo6 = "'Foo1"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo5 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$tc'Foo5 = GHC.Types.TrNameS T7360.$tc'Foo6 @@ -155,7 +149,6 @@ T7360.$tc'Foo5 = GHC.Types.TrNameS T7360.$tc'Foo6 -- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo1 :: GHC.Types.TyCon [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 70}] T7360.$tc'Foo1 @@ -177,7 +170,6 @@ T7360.$tc'Foo8 = "'Foo2"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo7 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$tc'Foo7 = GHC.Types.TrNameS T7360.$tc'Foo8 @@ -185,7 +177,6 @@ T7360.$tc'Foo7 = GHC.Types.TrNameS T7360.$tc'Foo8 -- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo2 :: GHC.Types.TyCon [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 70}] T7360.$tc'Foo2 @@ -212,7 +203,6 @@ T7360.$tc'Foo11 = "'Foo3"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo10 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$tc'Foo10 = GHC.Types.TrNameS T7360.$tc'Foo11 @@ -220,7 +210,6 @@ T7360.$tc'Foo10 = GHC.Types.TrNameS T7360.$tc'Foo11 -- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo3 :: GHC.Types.TyCon [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 70}] T7360.$tc'Foo3 ===================================== testsuite/tests/simplCore/should_compile/noinline01.stderr ===================================== @@ -14,7 +14,7 @@ Noinline01.$trModule4 :: GHC.Prim.Addr# "main"#; Noinline01.$trModule3 :: GHC.Types.TrName -[GblId, Cpr=m1, Unf=OtherCon []] = +[GblId, Unf=OtherCon []] = CCS_DONT_CARE GHC.Types.TrNameS! [Noinline01.$trModule4]; Noinline01.$trModule2 :: GHC.Prim.Addr# @@ -22,11 +22,11 @@ Noinline01.$trModule2 :: GHC.Prim.Addr# "Noinline01"#; Noinline01.$trModule1 :: GHC.Types.TrName -[GblId, Cpr=m1, Unf=OtherCon []] = +[GblId, Unf=OtherCon []] = CCS_DONT_CARE GHC.Types.TrNameS! [Noinline01.$trModule2]; Noinline01.$trModule :: GHC.Types.Module -[GblId, Cpr=m1, Unf=OtherCon []] = +[GblId, Unf=OtherCon []] = CCS_DONT_CARE GHC.Types.Module! [Noinline01.$trModule3 Noinline01.$trModule1]; ===================================== testsuite/tests/simplCore/should_compile/par01.stderr ===================================== @@ -21,7 +21,7 @@ Par01.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Par01.$trModule3 :: GHC.Types.TrName -[GblId, Cpr=m1, Unf=OtherCon []] +[GblId, Unf=OtherCon []] Par01.$trModule3 = GHC.Types.TrNameS Par01.$trModule4 -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} @@ -31,12 +31,12 @@ Par01.$trModule2 = "Par01"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Par01.$trModule1 :: GHC.Types.TrName -[GblId, Cpr=m1, Unf=OtherCon []] +[GblId, Unf=OtherCon []] Par01.$trModule1 = GHC.Types.TrNameS Par01.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} Par01.$trModule :: GHC.Types.Module -[GblId, Cpr=m1, Unf=OtherCon []] +[GblId, Unf=OtherCon []] Par01.$trModule = GHC.Types.Module Par01.$trModule3 Par01.$trModule1 ===================================== testsuite/tests/simplCore/should_compile/spec-inline.stderr ===================================== @@ -13,7 +13,6 @@ Roman.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Roman.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] Roman.$trModule3 = GHC.Types.TrNameS Roman.$trModule4 @@ -28,7 +27,6 @@ Roman.$trModule2 = "Roman"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Roman.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] Roman.$trModule1 = GHC.Types.TrNameS Roman.$trModule2 @@ -36,7 +34,6 @@ Roman.$trModule1 = GHC.Types.TrNameS Roman.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} Roman.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] Roman.$trModule @@ -132,7 +129,6 @@ Roman.foo_go -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Roman.foo2 :: Int [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] Roman.foo2 = GHC.Types.I# 6# @@ -140,7 +136,6 @@ Roman.foo2 = GHC.Types.I# 6# -- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0} Roman.foo1 :: Maybe Int [GblId, - Cpr=m2, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] Roman.foo1 = GHC.Maybe.Just @Int Roman.foo2 ===================================== testsuite/tests/stranal/should_compile/T10694.stderr ===================================== @@ -6,26 +6,26 @@ Result size of Tidy Core = {terms: 74, types: 65, coercions: 0, joins: 0/4} T10694.$wpm [InlPrag=NOINLINE] :: Int -> Int -> (# Int, Int #) [GblId, Arity=2, Str=, Unf=OtherCon []] T10694.$wpm - = \ (w_s1vj :: Int) (w1_s1vk :: Int) -> + = \ (w_s1v1 :: Int) (w1_s1v2 :: Int) -> let { - l_s1uR :: Int + l_s1uz :: Int [LclId] - l_s1uR - = case w_s1vj of { GHC.Types.I# x_aJ9 -> case w1_s1vk of { GHC.Types.I# y_aJc -> GHC.Types.I# (GHC.Prim.+# x_aJ9 y_aJc) } } } in + l_s1uz + = case w_s1v1 of { GHC.Types.I# x_aJ0 -> case w1_s1v2 of { GHC.Types.I# y_aJ3 -> GHC.Types.I# (GHC.Prim.+# x_aJ0 y_aJ3) } } } in let { - l1_s1uS :: Int + l1_s1uA :: Int [LclId] - l1_s1uS - = case w_s1vj of { GHC.Types.I# x_aJh -> case w1_s1vk of { GHC.Types.I# y_aJk -> GHC.Types.I# (GHC.Prim.-# x_aJh y_aJk) } } } in + l1_s1uA + = case w_s1v1 of { GHC.Types.I# x_aJ8 -> case w1_s1v2 of { GHC.Types.I# y_aJb -> GHC.Types.I# (GHC.Prim.-# x_aJ8 y_aJb) } } } in let { - l2_s1uT :: [Int] + l2_s1uB :: [Int] [LclId, Unf=OtherCon []] - l2_s1uT = GHC.Types.: @Int l1_s1uS (GHC.Types.[] @Int) } in + l2_s1uB = GHC.Types.: @Int l1_s1uA (GHC.Types.[] @Int) } in let { - l3_sJv :: [Int] + l3_sJm :: [Int] [LclId, Unf=OtherCon []] - l3_sJv = GHC.Types.: @Int l_s1uR l2_s1uT } in - (# GHC.List.$w!! @Int l3_sJv 0#, GHC.List.$w!! @Int l3_sJv 1# #) + l3_sJm = GHC.Types.: @Int l_s1uz l2_s1uB } in + (# GHC.List.$w!! @Int l3_sJm 0#, GHC.List.$w!! @Int l3_sJm 1# #) -- RHS size: {terms: 10, types: 11, coercions: 0, joins: 0/0} pm [InlPrag=NOUSERINLINE[0]] :: Int -> Int -> (Int, Int) @@ -35,9 +35,9 @@ pm [InlPrag=NOUSERINLINE[0]] :: Int -> Int -> (Int, Int) Cpr=m1, Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=2,unsat_ok=True,boring_ok=False) - Tmpl= \ (w_s1vj [Occ=Once] :: Int) (w1_s1vk [Occ=Once] :: Int) -> - case T10694.$wpm w_s1vj w1_s1vk of { (# ww1_s1vp [Occ=Once], ww2_s1vq [Occ=Once] #) -> (ww1_s1vp, ww2_s1vq) }}] -pm = \ (w_s1vj :: Int) (w1_s1vk :: Int) -> case T10694.$wpm w_s1vj w1_s1vk of { (# ww1_s1vp, ww2_s1vq #) -> (ww1_s1vp, ww2_s1vq) } + Tmpl= \ (w_s1v1 [Occ=Once] :: Int) (w1_s1v2 [Occ=Once] :: Int) -> + case T10694.$wpm w_s1v1 w1_s1v2 of { (# ww1_s1v7 [Occ=Once], ww2_s1v8 [Occ=Once] #) -> (ww1_s1v7, ww2_s1v8) }}] +pm = \ (w_s1v1 :: Int) (w1_s1v2 :: Int) -> case T10694.$wpm w_s1v1 w1_s1v2 of { (# ww1_s1v7, ww2_s1v8 #) -> (ww1_s1v7, ww2_s1v8) } -- RHS size: {terms: 8, types: 9, coercions: 0, joins: 0/0} m :: Int -> Int -> Int @@ -46,9 +46,9 @@ m :: Int -> Int -> Int Str=, Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=2,unsat_ok=True,boring_ok=False) - Tmpl= \ (x_awt [Occ=Once] :: Int) (y_awu [Occ=Once] :: Int) -> - case pm x_awt y_awu of { (_ [Occ=Dead], mr_aww [Occ=Once]) -> mr_aww }}] -m = \ (x_awt :: Int) (y_awu :: Int) -> case T10694.$wpm x_awt y_awu of { (# ww1_s1vp, ww2_s1vq #) -> ww2_s1vq } + Tmpl= \ (x_awo [Occ=Once] :: Int) (y_awp [Occ=Once] :: Int) -> + case pm x_awo y_awp of { (_ [Occ=Dead], mr_awr [Occ=Once]) -> mr_awr }}] +m = \ (x_awo :: Int) (y_awp :: Int) -> case T10694.$wpm x_awo y_awp of { (# ww1_s1v7, ww2_s1v8 #) -> ww2_s1v8 } -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T10694.$trModule4 :: GHC.Prim.Addr# @@ -57,9 +57,7 @@ T10694.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T10694.$trModule3 :: GHC.Types.TrName -[GblId, - Cpr=m1, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T10694.$trModule3 = GHC.Types.TrNameS T10694.$trModule4 -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} @@ -69,17 +67,13 @@ T10694.$trModule2 = "T10694"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T10694.$trModule1 :: GHC.Types.TrName -[GblId, - Cpr=m1, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T10694.$trModule1 = GHC.Types.TrNameS T10694.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} -T10694.$trModule :: GHC.Unit.Module -[GblId, - Cpr=m1, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] -T10694.$trModule = GHC.Unit.Module T10694.$trModule3 T10694.$trModule1 +T10694.$trModule :: GHC.Types.Module +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] +T10694.$trModule = GHC.Types.Module T10694.$trModule3 T10694.$trModule1 ===================================== testsuite/tests/stranal/sigs/BottomFromInnerLambda.stderr ===================================== @@ -7,7 +7,7 @@ BottomFromInnerLambda.f: ==================== Cpr signatures ==================== -BottomFromInnerLambda.$trModule: m1 +BottomFromInnerLambda.$trModule: BottomFromInnerLambda.expensive: m1 BottomFromInnerLambda.f: ===================================== testsuite/tests/stranal/sigs/CaseBinderCPR.stderr ===================================== @@ -6,7 +6,7 @@ CaseBinderCPR.f_list_cmp: ==================== Cpr signatures ==================== -CaseBinderCPR.$trModule: m1 +CaseBinderCPR.$trModule: CaseBinderCPR.f_list_cmp: m1 ===================================== testsuite/tests/stranal/sigs/DmdAnalGADTs.stderr ===================================== @@ -14,15 +14,15 @@ DmdAnalGADTs.hasStrSig: ==================== Cpr signatures ==================== -DmdAnalGADTs.$tc'A: m1 -DmdAnalGADTs.$tc'B: m1 -DmdAnalGADTs.$tcD: m1 -DmdAnalGADTs.$trModule: m1 +DmdAnalGADTs.$tc'A: +DmdAnalGADTs.$tc'B: +DmdAnalGADTs.$tcD: +DmdAnalGADTs.$trModule: DmdAnalGADTs.diverges: b DmdAnalGADTs.f: DmdAnalGADTs.f': m1 DmdAnalGADTs.g: -DmdAnalGADTs.hasCPR: m1 +DmdAnalGADTs.hasCPR: DmdAnalGADTs.hasStrSig: ===================================== testsuite/tests/stranal/sigs/HyperStrUse.stderr ===================================== @@ -6,7 +6,7 @@ HyperStrUse.f: ==================== Cpr signatures ==================== -HyperStrUse.$trModule: m1 +HyperStrUse.$trModule: HyperStrUse.f: m1 ===================================== testsuite/tests/stranal/sigs/NewtypeArity.stderr ===================================== @@ -9,9 +9,9 @@ Test.t2: ==================== Cpr signatures ==================== -Test.$tc'MkT: m1 -Test.$tcT: m1 -Test.$trModule: m1 +Test.$tc'MkT: +Test.$tcT: +Test.$trModule: Test.t: m1 Test.t2: m1 ===================================== testsuite/tests/stranal/sigs/StrAnalExample.stderr ===================================== @@ -6,7 +6,7 @@ StrAnalExample.foo: ==================== Cpr signatures ==================== -StrAnalExample.$trModule: m1 +StrAnalExample.$trModule: StrAnalExample.foo: ===================================== testsuite/tests/stranal/sigs/T12370.stderr ===================================== @@ -7,7 +7,7 @@ T12370.foo: ==================== Cpr signatures ==================== -T12370.$trModule: m1 +T12370.$trModule: T12370.bar: m1 T12370.foo: m1 ===================================== testsuite/tests/stranal/sigs/T17932.stderr ===================================== @@ -10,11 +10,11 @@ T17932.flags: ==================== Cpr signatures ==================== -T17932.$tc'Options: m1 -T17932.$tc'X: m1 -T17932.$tcOptions: m1 -T17932.$tcX: m1 -T17932.$trModule: m1 +T17932.$tc'Options: +T17932.$tc'X: +T17932.$tcOptions: +T17932.$tcX: +T17932.$trModule: T17932.flags: ===================================== testsuite/tests/stranal/sigs/T5075.stderr ===================================== @@ -6,7 +6,7 @@ T5075.loop: ==================== Cpr signatures ==================== -T8569.$tc'Rdata: m1 -T8569.$tc'Rint: m1 -T8569.$tcRep: m1 -T8569.$trModule: m1 +T8569.$tc'Rdata: +T8569.$tc'Rint: +T8569.$tcRep: +T8569.$trModule: T8569.addUp: ===================================== testsuite/tests/stranal/sigs/T8598.stderr ===================================== @@ -6,7 +6,7 @@ T8598.fun: ==================== Cpr signatures ==================== -T8598.$trModule: m1 +T8598.$trModule: T8598.fun: m1 ===================================== testsuite/tests/stranal/sigs/UnsatFun.stderr ===================================== @@ -12,7 +12,7 @@ UnsatFun.h3: ==================== Cpr signatures ==================== -UnsatFun.$trModule: m1 +UnsatFun.$trModule: UnsatFun.f: b UnsatFun.g: UnsatFun.g': View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/11fa2b07bd51c62266a12e0b076073d994ab9a71 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/11fa2b07bd51c62266a12e0b076073d994ab9a71 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 6 17:16:04 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 06 May 2020 13:16:04 -0400 Subject: [Git][ghc/ghc][wip/cpr-expandable-unfoldings] CprAnal: Don't attach CPR sigs to expandable bindings (#18154) Message-ID: <5eb2f0d4c4302_61671341e94492249e@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/cpr-expandable-unfoldings at Glasgow Haskell Compiler / GHC Commits: 8bea8699 by Sebastian Graf at 2020-05-06T19:15:56+02:00 CprAnal: Don't attach CPR sigs to expandable bindings (#18154) Instead, look through expandable unfoldings in `cprTransform`. See the new Note [CPR for expandable unfoldings]: ``` GHC generates a lot of TyCon and KindRep bindings, one for each new data declaration. Attaching CPR signatures to each of them is quite wasteful. In general, DataCon application bindings * Never get WW'd, so their CPR signature should be irrelevant after analysis * Would need to be inlined to see their CPR * Recording (Nested!) CPR on them blows up interface file sizes But we can't just stop giving DataCon application bindings the CPR property, for example fac 0 = 1 fac n = n * fac (n-1) fac certainly has the CPR property and should be WW'd! But FloatOut will transform the first clause to lvl = 1 fac 0 = lvl If lvl doesn't have the CPR property, fac won't either. So instead we keep on looking through *expandable* unfoldings for these arity 0 bindings. ``` Fixes #18154. - - - - - 29 changed files: - compiler/GHC/Core/Opt/CprAnal.hs - testsuite/tests/numeric/should_compile/T14170.stdout - testsuite/tests/numeric/should_compile/T14465.stdout - testsuite/tests/numeric/should_compile/T7116.stdout - testsuite/tests/simplCore/should_compile/T13143.stderr - testsuite/tests/simplCore/should_compile/T13543.stderr - testsuite/tests/simplCore/should_compile/T18013.stderr - testsuite/tests/simplCore/should_compile/T3717.stderr - testsuite/tests/simplCore/should_compile/T3772.stdout - testsuite/tests/simplCore/should_compile/T4908.stderr - testsuite/tests/simplCore/should_compile/T4930.stderr - testsuite/tests/simplCore/should_compile/T7360.stderr - testsuite/tests/simplCore/should_compile/noinline01.stderr - testsuite/tests/simplCore/should_compile/par01.stderr - testsuite/tests/simplCore/should_compile/spec-inline.stderr - testsuite/tests/stranal/should_compile/T10694.stderr - testsuite/tests/stranal/sigs/BottomFromInnerLambda.stderr - testsuite/tests/stranal/sigs/CaseBinderCPR.stderr - testsuite/tests/stranal/sigs/DmdAnalGADTs.hs - testsuite/tests/stranal/sigs/DmdAnalGADTs.stderr - testsuite/tests/stranal/sigs/HyperStrUse.stderr - testsuite/tests/stranal/sigs/NewtypeArity.stderr - testsuite/tests/stranal/sigs/StrAnalExample.stderr - testsuite/tests/stranal/sigs/T12370.stderr - testsuite/tests/stranal/sigs/T17932.stderr - testsuite/tests/stranal/sigs/T5075.stderr - testsuite/tests/stranal/sigs/T8569.stderr - testsuite/tests/stranal/sigs/T8598.stderr - testsuite/tests/stranal/sigs/UnsatFun.stderr Changes: ===================================== compiler/GHC/Core/Opt/CprAnal.hs ===================================== @@ -231,9 +231,14 @@ cprTransform env id sig where sig - | isGlobalId id -- imported function or data con worker + -- See Note [CPR for expandable unfoldings] + | Just rhs <- lookupExpandableUnfolding id + = fst $ cprAnal env rhs + -- Imported function or data con worker + | isGlobalId id = getCprSig (idCprInfo id) - | Just sig <- lookupSigEnv env id -- local let-bound + -- Local let-bound + | Just sig <- lookupSigEnv env id = getCprSig sig | otherwise = topCprType @@ -303,6 +308,8 @@ cprAnalBind top_lvl env id rhs | stays_thunk = trimCprTy rhs_ty -- See Note [CPR for sum types] | returns_sum = trimCprTy rhs_ty + -- See Note [CPR for expandable unfoldings] + | will_expand = topCprType | otherwise = rhs_ty -- See Note [Arity trimming for CPR signatures] sig = mkCprSigForArity (idArity id) rhs_ty' @@ -316,6 +323,19 @@ cprAnalBind top_lvl env id rhs (_, ret_ty) = splitPiTys (idType id) not_a_prod = isNothing (deepSplitProductType_maybe (ae_fam_envs env) ret_ty) returns_sum = not (isTopLevel top_lvl) && not_a_prod + -- See Note [CPR for expandable unfoldings] + will_expand = isJust (lookupExpandableUnfolding id) + +lookupExpandableUnfolding :: Id -> Maybe CoreExpr +lookupExpandableUnfolding id + | idArity id == 0 = expandUnfolding_maybe (cprIdUnfolding id) + | otherwise = Nothing + +cprIdUnfolding :: IdUnfoldingFun +cprIdUnfolding id + -- There will only be phase 0 Simplifier runs after CprAnal + | isActiveIn 0 (idInlineActivation id) = idUnfolding id + | otherwise = noUnfolding {- Note [Arity trimming for CPR signatures] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -626,6 +646,28 @@ fac won't have the CPR property here when we trim every thunk! But the assumption is that error cases are rarely entered and we are diverging anyway, so WW doesn't hurt. +Should we also trim CPR on DataCon bindings? +See Note [CPR for expandable unfoldings]! + +Note [CPR for expandable unfoldings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +GHC generates a lot of TyCon and KindRep bindings, one for each new data +declaration. Attaching CPR signatures to each of them is quite wasteful. +In general, DataCon application bindings + * Never get WW'd, so their CPR signature should be irrelevant after analysis + * Would need to be inlined to see their CPR + * Recording (Nested!) CPR on them blows up interface file sizes +But we can't just stop giving DataCon application bindings the CPR property, +for example + fac 0 = 1 + fac n = n * fac (n-1) +fac certainly has the CPR property and should be WW'd! But FloatOut will +transform the first clause to + lvl = 1 + fac 0 = lvl +If lvl doesn't have the CPR property, fac won't either. So instead we keep on +looking through *expandable* unfoldings for these arity 0 bindings. + Note [CPR examples] ~~~~~~~~~~~~~~~~~~~~ Here are some examples (stranal/should_compile/T10482a) of the ===================================== testsuite/tests/numeric/should_compile/T14170.stdout ===================================== @@ -13,7 +13,6 @@ NatVal.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} NatVal.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] NatVal.$trModule3 = GHC.Types.TrNameS NatVal.$trModule4 @@ -28,7 +27,6 @@ NatVal.$trModule2 = "NatVal"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} NatVal.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] NatVal.$trModule1 = GHC.Types.TrNameS NatVal.$trModule2 @@ -36,7 +34,6 @@ NatVal.$trModule1 = GHC.Types.TrNameS NatVal.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} NatVal.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] NatVal.$trModule ===================================== testsuite/tests/numeric/should_compile/T14465.stdout ===================================== @@ -20,7 +20,6 @@ M.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} M.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] M.$trModule3 = GHC.Types.TrNameS M.$trModule4 @@ -35,7 +34,6 @@ M.$trModule2 = "M"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} M.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] M.$trModule1 = GHC.Types.TrNameS M.$trModule2 @@ -43,7 +41,6 @@ M.$trModule1 = GHC.Types.TrNameS M.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} M.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] M.$trModule = GHC.Types.Module M.$trModule3 M.$trModule1 ===================================== testsuite/tests/numeric/should_compile/T7116.stdout ===================================== @@ -13,7 +13,6 @@ T7116.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7116.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7116.$trModule3 = GHC.Types.TrNameS T7116.$trModule4 @@ -28,7 +27,6 @@ T7116.$trModule2 = "T7116"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7116.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7116.$trModule1 = GHC.Types.TrNameS T7116.$trModule2 @@ -36,7 +34,6 @@ T7116.$trModule1 = GHC.Types.TrNameS T7116.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T7116.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T7116.$trModule ===================================== testsuite/tests/simplCore/should_compile/T13143.stderr ===================================== @@ -33,7 +33,6 @@ T13143.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T13143.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T13143.$trModule3 = GHC.Types.TrNameS T13143.$trModule4 @@ -48,7 +47,6 @@ T13143.$trModule2 = "T13143"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T13143.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T13143.$trModule1 = GHC.Types.TrNameS T13143.$trModule2 @@ -56,7 +54,6 @@ T13143.$trModule1 = GHC.Types.TrNameS T13143.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T13143.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T13143.$trModule ===================================== testsuite/tests/simplCore/should_compile/T13543.stderr ===================================== @@ -7,7 +7,7 @@ Foo.g: ==================== Cpr signatures ==================== -Foo.$trModule: m1 +Foo.$trModule: Foo.f: m1 Foo.g: m1 ===================================== testsuite/tests/simplCore/should_compile/T18013.stderr ===================================== @@ -177,7 +177,6 @@ T18013.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T18013.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T18013.$trModule3 = GHC.Types.TrNameS T18013.$trModule4 @@ -192,7 +191,6 @@ T18013.$trModule2 = "T18013"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T18013.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T18013.$trModule1 = GHC.Types.TrNameS T18013.$trModule2 @@ -200,7 +198,6 @@ T18013.$trModule1 = GHC.Types.TrNameS T18013.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T18013.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T18013.$trModule ===================================== testsuite/tests/simplCore/should_compile/T3717.stderr ===================================== @@ -13,7 +13,6 @@ T3717.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T3717.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T3717.$trModule3 = GHC.Types.TrNameS T3717.$trModule4 @@ -28,7 +27,6 @@ T3717.$trModule2 = "T3717"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T3717.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T3717.$trModule1 = GHC.Types.TrNameS T3717.$trModule2 @@ -36,7 +34,6 @@ T3717.$trModule1 = GHC.Types.TrNameS T3717.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T3717.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T3717.$trModule ===================================== testsuite/tests/simplCore/should_compile/T3772.stdout ===================================== @@ -13,7 +13,6 @@ T3772.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T3772.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T3772.$trModule3 = GHC.Types.TrNameS T3772.$trModule4 @@ -28,7 +27,6 @@ T3772.$trModule2 = "T3772"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T3772.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T3772.$trModule1 = GHC.Types.TrNameS T3772.$trModule2 @@ -36,7 +34,6 @@ T3772.$trModule1 = GHC.Types.TrNameS T3772.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T3772.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T3772.$trModule ===================================== testsuite/tests/simplCore/should_compile/T4908.stderr ===================================== @@ -13,7 +13,6 @@ T4908.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T4908.$trModule3 :: TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T4908.$trModule3 = GHC.Types.TrNameS T4908.$trModule4 @@ -28,7 +27,6 @@ T4908.$trModule2 = "T4908"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T4908.$trModule1 :: TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T4908.$trModule1 = GHC.Types.TrNameS T4908.$trModule2 @@ -36,7 +34,6 @@ T4908.$trModule1 = GHC.Types.TrNameS T4908.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T4908.$trModule :: Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T4908.$trModule ===================================== testsuite/tests/simplCore/should_compile/T4930.stderr ===================================== @@ -13,7 +13,6 @@ T4930.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T4930.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T4930.$trModule3 = GHC.Types.TrNameS T4930.$trModule4 @@ -28,7 +27,6 @@ T4930.$trModule2 = "T4930"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T4930.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T4930.$trModule1 = GHC.Types.TrNameS T4930.$trModule2 @@ -36,7 +34,6 @@ T4930.$trModule1 = GHC.Types.TrNameS T4930.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T4930.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T4930.$trModule ===================================== testsuite/tests/simplCore/should_compile/T7360.stderr ===================================== @@ -64,7 +64,6 @@ T7360.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$trModule3 = GHC.Types.TrNameS T7360.$trModule4 @@ -79,7 +78,6 @@ T7360.$trModule2 = "T7360"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$trModule1 = GHC.Types.TrNameS T7360.$trModule2 @@ -87,7 +85,6 @@ T7360.$trModule1 = GHC.Types.TrNameS T7360.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T7360.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T7360.$trModule @@ -110,7 +107,6 @@ T7360.$tcFoo2 = "Foo"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$tcFoo1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$tcFoo1 = GHC.Types.TrNameS T7360.$tcFoo2 @@ -118,7 +114,6 @@ T7360.$tcFoo1 = GHC.Types.TrNameS T7360.$tcFoo2 -- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} T7360.$tcFoo :: GHC.Types.TyCon [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 70}] T7360.$tcFoo @@ -147,7 +142,6 @@ T7360.$tc'Foo6 = "'Foo1"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo5 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$tc'Foo5 = GHC.Types.TrNameS T7360.$tc'Foo6 @@ -155,7 +149,6 @@ T7360.$tc'Foo5 = GHC.Types.TrNameS T7360.$tc'Foo6 -- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo1 :: GHC.Types.TyCon [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 70}] T7360.$tc'Foo1 @@ -177,7 +170,6 @@ T7360.$tc'Foo8 = "'Foo2"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo7 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$tc'Foo7 = GHC.Types.TrNameS T7360.$tc'Foo8 @@ -185,7 +177,6 @@ T7360.$tc'Foo7 = GHC.Types.TrNameS T7360.$tc'Foo8 -- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo2 :: GHC.Types.TyCon [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 70}] T7360.$tc'Foo2 @@ -212,7 +203,6 @@ T7360.$tc'Foo11 = "'Foo3"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo10 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$tc'Foo10 = GHC.Types.TrNameS T7360.$tc'Foo11 @@ -220,7 +210,6 @@ T7360.$tc'Foo10 = GHC.Types.TrNameS T7360.$tc'Foo11 -- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo3 :: GHC.Types.TyCon [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 70}] T7360.$tc'Foo3 ===================================== testsuite/tests/simplCore/should_compile/noinline01.stderr ===================================== @@ -14,7 +14,7 @@ Noinline01.$trModule4 :: GHC.Prim.Addr# "main"#; Noinline01.$trModule3 :: GHC.Types.TrName -[GblId, Cpr=m1, Unf=OtherCon []] = +[GblId, Unf=OtherCon []] = CCS_DONT_CARE GHC.Types.TrNameS! [Noinline01.$trModule4]; Noinline01.$trModule2 :: GHC.Prim.Addr# @@ -22,11 +22,11 @@ Noinline01.$trModule2 :: GHC.Prim.Addr# "Noinline01"#; Noinline01.$trModule1 :: GHC.Types.TrName -[GblId, Cpr=m1, Unf=OtherCon []] = +[GblId, Unf=OtherCon []] = CCS_DONT_CARE GHC.Types.TrNameS! [Noinline01.$trModule2]; Noinline01.$trModule :: GHC.Types.Module -[GblId, Cpr=m1, Unf=OtherCon []] = +[GblId, Unf=OtherCon []] = CCS_DONT_CARE GHC.Types.Module! [Noinline01.$trModule3 Noinline01.$trModule1]; ===================================== testsuite/tests/simplCore/should_compile/par01.stderr ===================================== @@ -21,7 +21,7 @@ Par01.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Par01.$trModule3 :: GHC.Types.TrName -[GblId, Cpr=m1, Unf=OtherCon []] +[GblId, Unf=OtherCon []] Par01.$trModule3 = GHC.Types.TrNameS Par01.$trModule4 -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} @@ -31,12 +31,12 @@ Par01.$trModule2 = "Par01"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Par01.$trModule1 :: GHC.Types.TrName -[GblId, Cpr=m1, Unf=OtherCon []] +[GblId, Unf=OtherCon []] Par01.$trModule1 = GHC.Types.TrNameS Par01.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} Par01.$trModule :: GHC.Types.Module -[GblId, Cpr=m1, Unf=OtherCon []] +[GblId, Unf=OtherCon []] Par01.$trModule = GHC.Types.Module Par01.$trModule3 Par01.$trModule1 ===================================== testsuite/tests/simplCore/should_compile/spec-inline.stderr ===================================== @@ -13,7 +13,6 @@ Roman.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Roman.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] Roman.$trModule3 = GHC.Types.TrNameS Roman.$trModule4 @@ -28,7 +27,6 @@ Roman.$trModule2 = "Roman"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Roman.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] Roman.$trModule1 = GHC.Types.TrNameS Roman.$trModule2 @@ -36,7 +34,6 @@ Roman.$trModule1 = GHC.Types.TrNameS Roman.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} Roman.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] Roman.$trModule @@ -132,7 +129,6 @@ Roman.foo_go -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Roman.foo2 :: Int [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] Roman.foo2 = GHC.Types.I# 6# @@ -140,7 +136,6 @@ Roman.foo2 = GHC.Types.I# 6# -- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0} Roman.foo1 :: Maybe Int [GblId, - Cpr=m2, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] Roman.foo1 = GHC.Maybe.Just @Int Roman.foo2 ===================================== testsuite/tests/stranal/should_compile/T10694.stderr ===================================== @@ -6,26 +6,26 @@ Result size of Tidy Core = {terms: 74, types: 65, coercions: 0, joins: 0/4} T10694.$wpm [InlPrag=NOINLINE] :: Int -> Int -> (# Int, Int #) [GblId, Arity=2, Str=, Unf=OtherCon []] T10694.$wpm - = \ (w_s1vj :: Int) (w1_s1vk :: Int) -> + = \ (w_s1v1 :: Int) (w1_s1v2 :: Int) -> let { - l_s1uR :: Int + l_s1uz :: Int [LclId] - l_s1uR - = case w_s1vj of { GHC.Types.I# x_aJ9 -> case w1_s1vk of { GHC.Types.I# y_aJc -> GHC.Types.I# (GHC.Prim.+# x_aJ9 y_aJc) } } } in + l_s1uz + = case w_s1v1 of { GHC.Types.I# x_aJ0 -> case w1_s1v2 of { GHC.Types.I# y_aJ3 -> GHC.Types.I# (GHC.Prim.+# x_aJ0 y_aJ3) } } } in let { - l1_s1uS :: Int + l1_s1uA :: Int [LclId] - l1_s1uS - = case w_s1vj of { GHC.Types.I# x_aJh -> case w1_s1vk of { GHC.Types.I# y_aJk -> GHC.Types.I# (GHC.Prim.-# x_aJh y_aJk) } } } in + l1_s1uA + = case w_s1v1 of { GHC.Types.I# x_aJ8 -> case w1_s1v2 of { GHC.Types.I# y_aJb -> GHC.Types.I# (GHC.Prim.-# x_aJ8 y_aJb) } } } in let { - l2_s1uT :: [Int] + l2_s1uB :: [Int] [LclId, Unf=OtherCon []] - l2_s1uT = GHC.Types.: @Int l1_s1uS (GHC.Types.[] @Int) } in + l2_s1uB = GHC.Types.: @Int l1_s1uA (GHC.Types.[] @Int) } in let { - l3_sJv :: [Int] + l3_sJm :: [Int] [LclId, Unf=OtherCon []] - l3_sJv = GHC.Types.: @Int l_s1uR l2_s1uT } in - (# GHC.List.$w!! @Int l3_sJv 0#, GHC.List.$w!! @Int l3_sJv 1# #) + l3_sJm = GHC.Types.: @Int l_s1uz l2_s1uB } in + (# GHC.List.$w!! @Int l3_sJm 0#, GHC.List.$w!! @Int l3_sJm 1# #) -- RHS size: {terms: 10, types: 11, coercions: 0, joins: 0/0} pm [InlPrag=NOUSERINLINE[0]] :: Int -> Int -> (Int, Int) @@ -35,9 +35,9 @@ pm [InlPrag=NOUSERINLINE[0]] :: Int -> Int -> (Int, Int) Cpr=m1, Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=2,unsat_ok=True,boring_ok=False) - Tmpl= \ (w_s1vj [Occ=Once] :: Int) (w1_s1vk [Occ=Once] :: Int) -> - case T10694.$wpm w_s1vj w1_s1vk of { (# ww1_s1vp [Occ=Once], ww2_s1vq [Occ=Once] #) -> (ww1_s1vp, ww2_s1vq) }}] -pm = \ (w_s1vj :: Int) (w1_s1vk :: Int) -> case T10694.$wpm w_s1vj w1_s1vk of { (# ww1_s1vp, ww2_s1vq #) -> (ww1_s1vp, ww2_s1vq) } + Tmpl= \ (w_s1v1 [Occ=Once] :: Int) (w1_s1v2 [Occ=Once] :: Int) -> + case T10694.$wpm w_s1v1 w1_s1v2 of { (# ww1_s1v7 [Occ=Once], ww2_s1v8 [Occ=Once] #) -> (ww1_s1v7, ww2_s1v8) }}] +pm = \ (w_s1v1 :: Int) (w1_s1v2 :: Int) -> case T10694.$wpm w_s1v1 w1_s1v2 of { (# ww1_s1v7, ww2_s1v8 #) -> (ww1_s1v7, ww2_s1v8) } -- RHS size: {terms: 8, types: 9, coercions: 0, joins: 0/0} m :: Int -> Int -> Int @@ -46,9 +46,9 @@ m :: Int -> Int -> Int Str=, Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=2,unsat_ok=True,boring_ok=False) - Tmpl= \ (x_awt [Occ=Once] :: Int) (y_awu [Occ=Once] :: Int) -> - case pm x_awt y_awu of { (_ [Occ=Dead], mr_aww [Occ=Once]) -> mr_aww }}] -m = \ (x_awt :: Int) (y_awu :: Int) -> case T10694.$wpm x_awt y_awu of { (# ww1_s1vp, ww2_s1vq #) -> ww2_s1vq } + Tmpl= \ (x_awo [Occ=Once] :: Int) (y_awp [Occ=Once] :: Int) -> + case pm x_awo y_awp of { (_ [Occ=Dead], mr_awr [Occ=Once]) -> mr_awr }}] +m = \ (x_awo :: Int) (y_awp :: Int) -> case T10694.$wpm x_awo y_awp of { (# ww1_s1v7, ww2_s1v8 #) -> ww2_s1v8 } -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T10694.$trModule4 :: GHC.Prim.Addr# @@ -57,9 +57,7 @@ T10694.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T10694.$trModule3 :: GHC.Types.TrName -[GblId, - Cpr=m1, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T10694.$trModule3 = GHC.Types.TrNameS T10694.$trModule4 -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} @@ -69,17 +67,13 @@ T10694.$trModule2 = "T10694"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T10694.$trModule1 :: GHC.Types.TrName -[GblId, - Cpr=m1, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T10694.$trModule1 = GHC.Types.TrNameS T10694.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} -T10694.$trModule :: GHC.Unit.Module -[GblId, - Cpr=m1, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] -T10694.$trModule = GHC.Unit.Module T10694.$trModule3 T10694.$trModule1 +T10694.$trModule :: GHC.Types.Module +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] +T10694.$trModule = GHC.Types.Module T10694.$trModule3 T10694.$trModule1 ===================================== testsuite/tests/stranal/sigs/BottomFromInnerLambda.stderr ===================================== @@ -7,7 +7,7 @@ BottomFromInnerLambda.f: ==================== Cpr signatures ==================== -BottomFromInnerLambda.$trModule: m1 +BottomFromInnerLambda.$trModule: BottomFromInnerLambda.expensive: m1 BottomFromInnerLambda.f: ===================================== testsuite/tests/stranal/sigs/CaseBinderCPR.stderr ===================================== @@ -6,7 +6,7 @@ CaseBinderCPR.f_list_cmp: ==================== Cpr signatures ==================== -CaseBinderCPR.$trModule: m1 +CaseBinderCPR.$trModule: CaseBinderCPR.f_list_cmp: m1 ===================================== testsuite/tests/stranal/sigs/DmdAnalGADTs.hs ===================================== @@ -7,11 +7,13 @@ data D a where A :: D Int B :: D (Int -> Int) +-- Doesn't have the CPR property anymore (#18154), but an expandable unfolding. +-- The point of this test is that f' has the CPR property. hasCPR :: Int hasCPR = 1 hasStrSig :: Int -> Int -hasStrSig x = x +hasStrSig x = x + 1 diverges :: Int diverges = diverges ===================================== testsuite/tests/stranal/sigs/DmdAnalGADTs.stderr ===================================== @@ -9,21 +9,21 @@ DmdAnalGADTs.f: DmdAnalGADTs.f': DmdAnalGADTs.g: DmdAnalGADTs.hasCPR: -DmdAnalGADTs.hasStrSig: +DmdAnalGADTs.hasStrSig: ==================== Cpr signatures ==================== -DmdAnalGADTs.$tc'A: m1 -DmdAnalGADTs.$tc'B: m1 -DmdAnalGADTs.$tcD: m1 -DmdAnalGADTs.$trModule: m1 +DmdAnalGADTs.$tc'A: +DmdAnalGADTs.$tc'B: +DmdAnalGADTs.$tcD: +DmdAnalGADTs.$trModule: DmdAnalGADTs.diverges: b DmdAnalGADTs.f: DmdAnalGADTs.f': m1 DmdAnalGADTs.g: -DmdAnalGADTs.hasCPR: m1 -DmdAnalGADTs.hasStrSig: +DmdAnalGADTs.hasCPR: +DmdAnalGADTs.hasStrSig: m1 @@ -37,6 +37,6 @@ DmdAnalGADTs.f: DmdAnalGADTs.f': DmdAnalGADTs.g: DmdAnalGADTs.hasCPR: -DmdAnalGADTs.hasStrSig: +DmdAnalGADTs.hasStrSig: ===================================== testsuite/tests/stranal/sigs/HyperStrUse.stderr ===================================== @@ -6,7 +6,7 @@ HyperStrUse.f: ==================== Cpr signatures ==================== -HyperStrUse.$trModule: m1 +HyperStrUse.$trModule: HyperStrUse.f: m1 ===================================== testsuite/tests/stranal/sigs/NewtypeArity.stderr ===================================== @@ -9,9 +9,9 @@ Test.t2: ==================== Cpr signatures ==================== -Test.$tc'MkT: m1 -Test.$tcT: m1 -Test.$trModule: m1 +Test.$tc'MkT: +Test.$tcT: +Test.$trModule: Test.t: m1 Test.t2: m1 ===================================== testsuite/tests/stranal/sigs/StrAnalExample.stderr ===================================== @@ -6,7 +6,7 @@ StrAnalExample.foo: ==================== Cpr signatures ==================== -StrAnalExample.$trModule: m1 +StrAnalExample.$trModule: StrAnalExample.foo: ===================================== testsuite/tests/stranal/sigs/T12370.stderr ===================================== @@ -7,7 +7,7 @@ T12370.foo: ==================== Cpr signatures ==================== -T12370.$trModule: m1 +T12370.$trModule: T12370.bar: m1 T12370.foo: m1 ===================================== testsuite/tests/stranal/sigs/T17932.stderr ===================================== @@ -10,11 +10,11 @@ T17932.flags: ==================== Cpr signatures ==================== -T17932.$tc'Options: m1 -T17932.$tc'X: m1 -T17932.$tcOptions: m1 -T17932.$tcX: m1 -T17932.$trModule: m1 +T17932.$tc'Options: +T17932.$tc'X: +T17932.$tcOptions: +T17932.$tcX: +T17932.$trModule: T17932.flags: ===================================== testsuite/tests/stranal/sigs/T5075.stderr ===================================== @@ -6,7 +6,7 @@ T5075.loop: ==================== Cpr signatures ==================== -T8569.$tc'Rdata: m1 -T8569.$tc'Rint: m1 -T8569.$tcRep: m1 -T8569.$trModule: m1 +T8569.$tc'Rdata: +T8569.$tc'Rint: +T8569.$tcRep: +T8569.$trModule: T8569.addUp: ===================================== testsuite/tests/stranal/sigs/T8598.stderr ===================================== @@ -6,7 +6,7 @@ T8598.fun: ==================== Cpr signatures ==================== -T8598.$trModule: m1 +T8598.$trModule: T8598.fun: m1 ===================================== testsuite/tests/stranal/sigs/UnsatFun.stderr ===================================== @@ -12,7 +12,7 @@ UnsatFun.h3: ==================== Cpr signatures ==================== -UnsatFun.$trModule: m1 +UnsatFun.$trModule: UnsatFun.f: b UnsatFun.g: UnsatFun.g': View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8bea8699437788e4616ff2a5bf2d605e101ed755 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8bea8699437788e4616ff2a5bf2d605e101ed755 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 6 23:13:43 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Wed, 06 May 2020 19:13:43 -0400 Subject: [Git][ghc/ghc][wip/T17775] Simple subsumption Message-ID: <5eb344a7e963a_61671341e94492602e5@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: 2a57ffcd by Simon Peyton Jones at 2020-05-07T00:12:33+01:00 Simple subsumption This patch simplifies GHC to use simple subsumption. Ticket #17775 Implements GHC proposal #287 https://github.com/ghc-proposals/ghc-proposals/blob/master/ proposals/0287-simplify-subsumption.rst All the motivation is described there; I will not repeat it here. The implementation payload: * tcSubType and friends become noticably simpler, because it no longer uses eta-expansion when checking subsumption. * No deeplyInstantiate or deeplySkolemise That in turn means that some tests fail, by design; they can all be fixed by eta expansion. There is a list of such changes below. Implementing the patch led me into a variety of sticky corners, so the patch includes several othe changes, some quite significant: * I made String wired-in, so that "foo" :: String rather than "foo" :: [Char] This improves error messages, and fixes #15679 * The pattern match checker relies on knowing about in-scope equality constraints, andd adds them to the desugarer's environment using addTyCsDs. But the co_fn in a FunBind was missed, and for some reason simple-subsumption ends up with dictionaries there. So I added a call to addTyCsDs. This is really part of #18049. * I moved the ic_telescope field out of Implication and into ForAllSkol instead. This is a nice win; just expresses the code much better. * There was a bug in GHC.Tc.TyCl.Instance.tcDataFamInstHeader. We called checkDataKindSig inside tc_kind_sig, /before/ solveEqualities and zonking. Obviously wrong, easily fixed. * solveLocalEqualitiesX: there was a whole mess in here, around failing fast enough. I discovered a bad latent bug where we could successfully kind-check a type signature, and use it, but have unsolved constraints that could fill in coercion holes in that signature -- aargh. It's all explained in Note [Failure in local type signatures] in GHC.Tc.Solver. Much better now. * I fixed a serious bug in anonymous type holes. IN f :: Int -> (forall a. a -> _) -> Int that "_" should be a unification variable at the /outer/ level; it cannot be instantiated to 'a'. This was plain wrong. New fields mode_lvl and mode_holes in TcTyMode, and auxiliary data type GHC.Tc.Gen.HsType.HoleMode. This fixes #16292, but makes no progress towards the more ambitious #16082 * I got sucked into an enormous refactoring of the reporting of equality errors in GHC.Tc.Errors, especially in mkEqErr1 mkTyVarEqErr misMatchMsg misMatchMsgOrCND In particular, the very tricky mkExpectedActualMsg function is gone. It took me a full day. But the result is far easier to understand. (Still not easy!) This led to various minor improvements in error output, and an enormous number of test-case error wibbles. One particular point: for occurs-check errors I now just say Can't match 'a' against '[a]' rather than using the intimidating language of "occurs check". * Pretty-printing AbsBinds Tests review * Eta expansions T11305: one eta expansion T12082: one eta expansion (undefined) T13585a: one eta expansion T3102: one eta expansion T3692: two eta expansions (tricky) T2239: two eta expansions T16473: one eta determ004: two eta expansions (undefined) annfail06: two eta (undefined) T17923: four eta expansions (a strange program indeed!) tcrun035: one eta expansion * Ambiguity check at higher rank. Now that we have simple subsumption, a type like f :: (forall a. Eq a => Int) -> Int is no longer ambiguous, because we could write g :: (forall a. Eq a => Int) -> Int g = f and it'd typecheck just fine. But f's type is a bit suspicious, and we might want to consider making the ambiguity check do a check on each sub-term. Meanwhile, these tests are accepted, whereas they were previously rejected as ambiguous: T7220a T15438 T10503 T9222 * Some more interesting error message wibbles T13381: Fine: one error (Int ~ Exp Int) rather than two (Int ~ Exp Int, Exp Int ~ Int) T9834: Small change in error (improvement) T10619: Improved T2414: Small change, due to order of unification, fine T2534: A very simple case in which a change of unification order means we get tow unsolved constraints instead of one tc211: bizarre impredicative tests; just accept this for now - - - - - 21 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Types.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Splice.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Default.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Expr.hs-boot - compiler/GHC/Tc/Gen/Foreign.hs - compiler/GHC/Tc/Gen/HsType.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2a57ffcd2e5d98ced8743403ac3f2a6df21abed3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2a57ffcd2e5d98ced8743403ac3f2a6df21abed3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 6 23:19:18 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Wed, 06 May 2020 19:19:18 -0400 Subject: [Git][ghc/ghc][wip/T18126] 19 commits: Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) Message-ID: <5eb345f6e3b4f_616713664be092614e7@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T18126 at Glasgow Haskell Compiler / GHC Commits: 30272412 by Artem Pelenitsyn at 2020-05-04T13:19:59-04:00 Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) - - - - - b9f7c08f by jneira at 2020-05-04T13:20:37-04:00 Remove unused hs-boot file - - - - - 1d8f80cd by Sylvain Henry at 2020-05-05T03:22:46-04:00 Remove references to -package-key * remove references to `-package-key` which has been removed in 2016 (240ddd7c39536776e955e881d709bbb039b48513) * remove support for `-this-package-key` which has been deprecated at the same time - - - - - 7bc3a65b by Sylvain Henry at 2020-05-05T03:23:31-04:00 Remove SpecConstrAnnotation (#13681) This has been deprecated since 2013. Use GHC.Types.SPEC instead. Make GHC.Exts "not-home" for haddock Metric Decrease: haddock.base - - - - - 3c862f63 by DenisFrezzato at 2020-05-05T03:24:15-04:00 Fix Haskell98 short description in documentation - - - - - 2420c555 by Ryan Scott at 2020-05-05T03:24:53-04:00 Add regression tests for #16244, #16245, #16758 Commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70 ended up fixing quite a few bugs: * This commit fixes #16244 completely. A regression test has been added. * This commit fixes one program from #16245. (The program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211369 still panics, and the program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211400 still loops infinitely.) A regression test has been added for this program. * This commit fixes #16758. Accordingly, this patch removes the `expect_broken` label from the `T16758` test case, moves it from `should_compile` to `should_fail` (as it should produce an error message), and checks in the expected stderr. - - - - - 40c71c2c by Sylvain Henry at 2020-05-05T03:25:31-04:00 Fix colorized error messages (#18128) In b3df9e780fb2f5658412c644849cd0f1e6f50331 I broke colorized messages by using "dump" style instead of "user" style. This commits fixes it. - - - - - 7ab6ab09 by Richard Eisenberg at 2020-05-06T04:39:32-04:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG ------------------------- - - - - - 420b957d by Ben Gamari at 2020-05-06T04:40:08-04:00 rts: Zero block flags with -DZ Block flags are very useful for determining the state of a block. However, some block allocator users don't touch them, leading to misleading values. Ensure that we zero then when zero-on-gc is set. This is safe and makes the flags more useful during debugging. - - - - - 740b3b8d by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix incorrect failed_to_evac value during deadlock gc Previously we would incorrectly set the failed_to_evac flag if we evacuated a value due to a deadlock GC. This would cause us to mark more things as dirty than strictly necessary. It also turned up a nasty but which I will fix next. - - - - - b2d72c75 by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - 9f3e6884 by Zubin Duggal at 2020-05-06T04:41:08-04:00 Allow atomic update of NameCache in readHieFile The situation arises in ghcide where multiple different threads may need to update the name cache, therefore with the older interface it could happen that you start reading a hie file with name cache A and produce name cache A + B, but another thread in the meantime updated the namecache to A + C. Therefore if you write the new namecache you will lose the A' updates from the second thread. Updates haddock submodule - - - - - edec6a6c by Ryan Scott at 2020-05-06T04:41:57-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _)`. Fixes #18127. - - - - - a95e7fe0 by Ömer Sinan Ağacan at 2020-05-06T04:42:39-04:00 ELF linker: increment curSymbol after filling in fields of current entry The bug was introduced in a8b7cef4d45 which added a field to the `symbols` array elements and then updated this code incorrectly: - oc->symbols[curSymbol++] = nm; + oc->symbols[curSymbol++].name = nm; + oc->symbols[curSymbol].addr = symbol->addr; - - - - - cab1871a by Sylvain Henry at 2020-05-06T04:43:21-04:00 Move LeadingUnderscore into Platform (#17957) Avoid direct use of DynFlags to know if symbols must be prefixed by an underscore. - - - - - 94e7c563 by Sylvain Henry at 2020-05-06T04:43:21-04:00 Don't use DynFlags in showLinkerState (#17957) - - - - - 9afd9251 by Ryan Scott at 2020-05-06T04:43:58-04:00 Refactoring: Use bindSigTyVarsFV in rnMethodBinds `rnMethodBinds` was explicitly using `xoptM` to determine if `ScopedTypeVariables` is enabled before bringing type variables bound by the class/instance header into scope. However, this `xoptM` logic is already performed by the `bindSigTyVarsFV` function. This patch uses `bindSigTyVarsFV` in `rnMethodBinds` to reduce the number of places where we need to consult if `ScopedTypeVariables` is on. This is purely refactoring, and there should be no user-visible change in behavior. - - - - - 2a57ffcd by Simon Peyton Jones at 2020-05-07T00:12:33+01:00 Simple subsumption This patch simplifies GHC to use simple subsumption. Ticket #17775 Implements GHC proposal #287 https://github.com/ghc-proposals/ghc-proposals/blob/master/ proposals/0287-simplify-subsumption.rst All the motivation is described there; I will not repeat it here. The implementation payload: * tcSubType and friends become noticably simpler, because it no longer uses eta-expansion when checking subsumption. * No deeplyInstantiate or deeplySkolemise That in turn means that some tests fail, by design; they can all be fixed by eta expansion. There is a list of such changes below. Implementing the patch led me into a variety of sticky corners, so the patch includes several othe changes, some quite significant: * I made String wired-in, so that "foo" :: String rather than "foo" :: [Char] This improves error messages, and fixes #15679 * The pattern match checker relies on knowing about in-scope equality constraints, andd adds them to the desugarer's environment using addTyCsDs. But the co_fn in a FunBind was missed, and for some reason simple-subsumption ends up with dictionaries there. So I added a call to addTyCsDs. This is really part of #18049. * I moved the ic_telescope field out of Implication and into ForAllSkol instead. This is a nice win; just expresses the code much better. * There was a bug in GHC.Tc.TyCl.Instance.tcDataFamInstHeader. We called checkDataKindSig inside tc_kind_sig, /before/ solveEqualities and zonking. Obviously wrong, easily fixed. * solveLocalEqualitiesX: there was a whole mess in here, around failing fast enough. I discovered a bad latent bug where we could successfully kind-check a type signature, and use it, but have unsolved constraints that could fill in coercion holes in that signature -- aargh. It's all explained in Note [Failure in local type signatures] in GHC.Tc.Solver. Much better now. * I fixed a serious bug in anonymous type holes. IN f :: Int -> (forall a. a -> _) -> Int that "_" should be a unification variable at the /outer/ level; it cannot be instantiated to 'a'. This was plain wrong. New fields mode_lvl and mode_holes in TcTyMode, and auxiliary data type GHC.Tc.Gen.HsType.HoleMode. This fixes #16292, but makes no progress towards the more ambitious #16082 * I got sucked into an enormous refactoring of the reporting of equality errors in GHC.Tc.Errors, especially in mkEqErr1 mkTyVarEqErr misMatchMsg misMatchMsgOrCND In particular, the very tricky mkExpectedActualMsg function is gone. It took me a full day. But the result is far easier to understand. (Still not easy!) This led to various minor improvements in error output, and an enormous number of test-case error wibbles. One particular point: for occurs-check errors I now just say Can't match 'a' against '[a]' rather than using the intimidating language of "occurs check". * Pretty-printing AbsBinds Tests review * Eta expansions T11305: one eta expansion T12082: one eta expansion (undefined) T13585a: one eta expansion T3102: one eta expansion T3692: two eta expansions (tricky) T2239: two eta expansions T16473: one eta determ004: two eta expansions (undefined) annfail06: two eta (undefined) T17923: four eta expansions (a strange program indeed!) tcrun035: one eta expansion * Ambiguity check at higher rank. Now that we have simple subsumption, a type like f :: (forall a. Eq a => Int) -> Int is no longer ambiguous, because we could write g :: (forall a. Eq a => Int) -> Int g = f and it'd typecheck just fine. But f's type is a bit suspicious, and we might want to consider making the ambiguity check do a check on each sub-term. Meanwhile, these tests are accepted, whereas they were previously rejected as ambiguous: T7220a T15438 T10503 T9222 * Some more interesting error message wibbles T13381: Fine: one error (Int ~ Exp Int) rather than two (Int ~ Exp Int, Exp Int ~ Int) T9834: Small change in error (improvement) T10619: Improved T2414: Small change, due to order of unification, fine T2534: A very simple case in which a change of unification order means we get tow unsolved constraints instead of one tc211: bizarre impredicative tests; just accept this for now - - - - - 81ef202e by Simon Peyton Jones at 2020-05-07T00:19:07+01:00 First draft of Quick Look impredicativity This patch implements Quick Look impredicativity (see #18126). The main action in is in the new module GHC.Tc.Gen.App, which deals with typechecking function applications. Much code has moved from Tc.Gen.Expr into Tc.Gen.App, but Tc.Gen.App also includes the new Quick Look code: see the function quickLook. Not properly tested yet -- this is just so you can see what I'm up to. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Data/IOEnv.hs - compiler/GHC/Driver/Finder.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Monad.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Driver/Types.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Types.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Plugins.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Splice.hs - compiler/GHC/Runtime/Debugger.hs - compiler/GHC/Runtime/Eval.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/87760b048b7dc59b4f6d275672bb7bac0a4f0e25...81ef202e7467b9ebdd52adde7af7c3dd390b77c5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/87760b048b7dc59b4f6d275672bb7bac0a4f0e25...81ef202e7467b9ebdd52adde7af7c3dd390b77c5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 7 10:08:10 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Thu, 07 May 2020 06:08:10 -0400 Subject: [Git][ghc/ghc][wip/cpr-expandable-unfoldings] CprAnal: Don't attach CPR sigs to expandable bindings (#18154) Message-ID: <5eb3de0a8e8c5_6167136cfbac92992ad@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/cpr-expandable-unfoldings at Glasgow Haskell Compiler / GHC Commits: 0ddf0bfe by Sebastian Graf at 2020-05-07T12:07:40+02:00 CprAnal: Don't attach CPR sigs to expandable bindings (#18154) Instead, look through expandable unfoldings in `cprTransform`. See the new Note [CPR for expandable unfoldings]: ``` Long static data structures (whether top-level or not) like xs = x1 : xs1 xs1 = x2 : xs2 xs2 = x3 : xs3 should not get CPR signatures, because they * Never get WW'd, so their CPR signature should be irrelevant after analysis (in fact the signature might even be harmful for that reason) * Would need to be inlined/expanded to see their constructed product * Recording CPR on them blows up interface file sizes and is redundant with their unfolding. In case of Nested CPR, this blow-up can be quadratic! But we can't just stop giving DataCon application bindings the CPR property, for example fac 0 = 1 fac n = n * fac (n-1) fac certainly has the CPR property and should be WW'd! But FloatOut will transform the first clause to lvl = 1 fac 0 = lvl If lvl doesn't have the CPR property, fac won't either. But lvl doesn't have a CPR signature to extrapolate into a CPR transformer ('cprTransform'). So instead we keep on cprAnal'ing through *expandable* unfoldings for these arity 0 bindings via 'cprExpandUnfolding_maybe'. In practice, GHC generates a lot of (nested) TyCon and KindRep bindings, one for each data declaration. It's wasteful to attach CPR signatures to each of them (and intractable in case of Nested CPR). ``` Fixes #18154. - - - - - 29 changed files: - compiler/GHC/Core/Opt/CprAnal.hs - testsuite/tests/numeric/should_compile/T14170.stdout - testsuite/tests/numeric/should_compile/T14465.stdout - testsuite/tests/numeric/should_compile/T7116.stdout - testsuite/tests/simplCore/should_compile/T13143.stderr - testsuite/tests/simplCore/should_compile/T13543.stderr - testsuite/tests/simplCore/should_compile/T18013.stderr - testsuite/tests/simplCore/should_compile/T3717.stderr - testsuite/tests/simplCore/should_compile/T3772.stdout - testsuite/tests/simplCore/should_compile/T4908.stderr - testsuite/tests/simplCore/should_compile/T4930.stderr - testsuite/tests/simplCore/should_compile/T7360.stderr - testsuite/tests/simplCore/should_compile/noinline01.stderr - testsuite/tests/simplCore/should_compile/par01.stderr - testsuite/tests/simplCore/should_compile/spec-inline.stderr - testsuite/tests/stranal/should_compile/T10694.stderr - testsuite/tests/stranal/sigs/BottomFromInnerLambda.stderr - testsuite/tests/stranal/sigs/CaseBinderCPR.stderr - testsuite/tests/stranal/sigs/DmdAnalGADTs.hs - testsuite/tests/stranal/sigs/DmdAnalGADTs.stderr - testsuite/tests/stranal/sigs/HyperStrUse.stderr - testsuite/tests/stranal/sigs/NewtypeArity.stderr - testsuite/tests/stranal/sigs/StrAnalExample.stderr - testsuite/tests/stranal/sigs/T12370.stderr - testsuite/tests/stranal/sigs/T17932.stderr - testsuite/tests/stranal/sigs/T5075.stderr - testsuite/tests/stranal/sigs/T8569.stderr - testsuite/tests/stranal/sigs/T8598.stderr - testsuite/tests/stranal/sigs/UnsatFun.stderr Changes: ===================================== compiler/GHC/Core/Opt/CprAnal.hs ===================================== @@ -21,7 +21,6 @@ import GHC.Core.Seq import GHC.Utils.Outputable import GHC.Types.Var.Env import GHC.Types.Basic -import Data.List import GHC.Core.DataCon import GHC.Types.Id import GHC.Types.Id.Info @@ -34,6 +33,9 @@ import GHC.Utils.Misc import GHC.Utils.Error ( dumpIfSet_dyn, DumpFormat (..) ) import GHC.Data.Maybe ( isJust, isNothing ) +import Control.Monad ( guard ) +import Data.List + {- Note [Constructed Product Result] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The goal of Constructed Product Result analysis is to identify functions that @@ -231,9 +233,14 @@ cprTransform env id sig where sig - | isGlobalId id -- imported function or data con worker + -- See Note [CPR for expandable unfoldings] + | Just rhs <- cprExpandUnfolding_maybe id + = fst $ cprAnal env rhs + -- Imported function or data con worker + | isGlobalId id = getCprSig (idCprInfo id) - | Just sig <- lookupSigEnv env id -- local let-bound + -- Local let-bound + | Just sig <- lookupSigEnv env id = getCprSig sig | otherwise = topCprType @@ -303,6 +310,8 @@ cprAnalBind top_lvl env id rhs | stays_thunk = trimCprTy rhs_ty -- See Note [CPR for sum types] | returns_sum = trimCprTy rhs_ty + -- See Note [CPR for expandable unfoldings] + | will_expand = topCprType | otherwise = rhs_ty -- See Note [Arity trimming for CPR signatures] sig = mkCprSigForArity (idArity id) rhs_ty' @@ -316,6 +325,15 @@ cprAnalBind top_lvl env id rhs (_, ret_ty) = splitPiTys (idType id) not_a_prod = isNothing (deepSplitProductType_maybe (ae_fam_envs env) ret_ty) returns_sum = not (isTopLevel top_lvl) && not_a_prod + -- See Note [CPR for expandable unfoldings] + will_expand = isJust (cprExpandUnfolding_maybe id) + +cprExpandUnfolding_maybe :: Id -> Maybe CoreExpr +cprExpandUnfolding_maybe id = do + guard (idArity id == 0) + -- There are only phase 0 Simplifier runs from now on + guard (isActiveIn 0 (idInlineActivation id)) + expandUnfolding_maybe (idUnfolding id) {- Note [Arity trimming for CPR signatures] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -626,6 +644,46 @@ fac won't have the CPR property here when we trim every thunk! But the assumption is that error cases are rarely entered and we are diverging anyway, so WW doesn't hurt. +Should we also trim CPR on DataCon application bindings? +See Note [CPR for expandable unfoldings]! + +Note [CPR for expandable unfoldings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Long static data structures (whether top-level or not) like + + xs = x1 : xs1 + xs1 = x2 : xs2 + xs2 = x3 : xs3 + +should not get CPR signatures, because they + + * Never get WW'd, so their CPR signature should be irrelevant after analysis + (in fact the signature might even be harmful for that reason) + * Would need to be inlined/expanded to see their constructed product + * Recording CPR on them blows up interface file sizes and is redundant with + their unfolding. In case of Nested CPR, this blow-up can be quadratic! + +But we can't just stop giving DataCon application bindings the CPR property, +for example + + fac 0 = 1 + fac n = n * fac (n-1) + +fac certainly has the CPR property and should be WW'd! But FloatOut will +transform the first clause to + + lvl = 1 + fac 0 = lvl + +If lvl doesn't have the CPR property, fac won't either. But lvl doesn't have a +CPR signature to extrapolate into a CPR transformer ('cprTransform'). So +instead we keep on cprAnal'ing through *expandable* unfoldings for these arity +0 bindings via 'cprExpandUnfolding_maybe'. + +In practice, GHC generates a lot of (nested) TyCon and KindRep bindings, one +for each data declaration. It's wasteful to attach CPR signatures to each of +them (and intractable in case of Nested CPR). + Note [CPR examples] ~~~~~~~~~~~~~~~~~~~~ Here are some examples (stranal/should_compile/T10482a) of the ===================================== testsuite/tests/numeric/should_compile/T14170.stdout ===================================== @@ -13,7 +13,6 @@ NatVal.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} NatVal.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] NatVal.$trModule3 = GHC.Types.TrNameS NatVal.$trModule4 @@ -28,7 +27,6 @@ NatVal.$trModule2 = "NatVal"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} NatVal.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] NatVal.$trModule1 = GHC.Types.TrNameS NatVal.$trModule2 @@ -36,7 +34,6 @@ NatVal.$trModule1 = GHC.Types.TrNameS NatVal.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} NatVal.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] NatVal.$trModule ===================================== testsuite/tests/numeric/should_compile/T14465.stdout ===================================== @@ -20,7 +20,6 @@ M.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} M.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] M.$trModule3 = GHC.Types.TrNameS M.$trModule4 @@ -35,7 +34,6 @@ M.$trModule2 = "M"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} M.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] M.$trModule1 = GHC.Types.TrNameS M.$trModule2 @@ -43,7 +41,6 @@ M.$trModule1 = GHC.Types.TrNameS M.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} M.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] M.$trModule = GHC.Types.Module M.$trModule3 M.$trModule1 ===================================== testsuite/tests/numeric/should_compile/T7116.stdout ===================================== @@ -13,7 +13,6 @@ T7116.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7116.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7116.$trModule3 = GHC.Types.TrNameS T7116.$trModule4 @@ -28,7 +27,6 @@ T7116.$trModule2 = "T7116"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7116.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7116.$trModule1 = GHC.Types.TrNameS T7116.$trModule2 @@ -36,7 +34,6 @@ T7116.$trModule1 = GHC.Types.TrNameS T7116.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T7116.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T7116.$trModule ===================================== testsuite/tests/simplCore/should_compile/T13143.stderr ===================================== @@ -33,7 +33,6 @@ T13143.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T13143.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T13143.$trModule3 = GHC.Types.TrNameS T13143.$trModule4 @@ -48,7 +47,6 @@ T13143.$trModule2 = "T13143"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T13143.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T13143.$trModule1 = GHC.Types.TrNameS T13143.$trModule2 @@ -56,7 +54,6 @@ T13143.$trModule1 = GHC.Types.TrNameS T13143.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T13143.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T13143.$trModule ===================================== testsuite/tests/simplCore/should_compile/T13543.stderr ===================================== @@ -7,7 +7,7 @@ Foo.g: ==================== Cpr signatures ==================== -Foo.$trModule: m1 +Foo.$trModule: Foo.f: m1 Foo.g: m1 ===================================== testsuite/tests/simplCore/should_compile/T18013.stderr ===================================== @@ -177,7 +177,6 @@ T18013.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T18013.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T18013.$trModule3 = GHC.Types.TrNameS T18013.$trModule4 @@ -192,7 +191,6 @@ T18013.$trModule2 = "T18013"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T18013.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T18013.$trModule1 = GHC.Types.TrNameS T18013.$trModule2 @@ -200,7 +198,6 @@ T18013.$trModule1 = GHC.Types.TrNameS T18013.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T18013.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T18013.$trModule ===================================== testsuite/tests/simplCore/should_compile/T3717.stderr ===================================== @@ -13,7 +13,6 @@ T3717.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T3717.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T3717.$trModule3 = GHC.Types.TrNameS T3717.$trModule4 @@ -28,7 +27,6 @@ T3717.$trModule2 = "T3717"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T3717.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T3717.$trModule1 = GHC.Types.TrNameS T3717.$trModule2 @@ -36,7 +34,6 @@ T3717.$trModule1 = GHC.Types.TrNameS T3717.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T3717.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T3717.$trModule ===================================== testsuite/tests/simplCore/should_compile/T3772.stdout ===================================== @@ -13,7 +13,6 @@ T3772.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T3772.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T3772.$trModule3 = GHC.Types.TrNameS T3772.$trModule4 @@ -28,7 +27,6 @@ T3772.$trModule2 = "T3772"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T3772.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T3772.$trModule1 = GHC.Types.TrNameS T3772.$trModule2 @@ -36,7 +34,6 @@ T3772.$trModule1 = GHC.Types.TrNameS T3772.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T3772.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T3772.$trModule ===================================== testsuite/tests/simplCore/should_compile/T4908.stderr ===================================== @@ -13,7 +13,6 @@ T4908.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T4908.$trModule3 :: TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T4908.$trModule3 = GHC.Types.TrNameS T4908.$trModule4 @@ -28,7 +27,6 @@ T4908.$trModule2 = "T4908"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T4908.$trModule1 :: TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T4908.$trModule1 = GHC.Types.TrNameS T4908.$trModule2 @@ -36,7 +34,6 @@ T4908.$trModule1 = GHC.Types.TrNameS T4908.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T4908.$trModule :: Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T4908.$trModule ===================================== testsuite/tests/simplCore/should_compile/T4930.stderr ===================================== @@ -13,7 +13,6 @@ T4930.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T4930.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T4930.$trModule3 = GHC.Types.TrNameS T4930.$trModule4 @@ -28,7 +27,6 @@ T4930.$trModule2 = "T4930"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T4930.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T4930.$trModule1 = GHC.Types.TrNameS T4930.$trModule2 @@ -36,7 +34,6 @@ T4930.$trModule1 = GHC.Types.TrNameS T4930.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T4930.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T4930.$trModule ===================================== testsuite/tests/simplCore/should_compile/T7360.stderr ===================================== @@ -64,7 +64,6 @@ T7360.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$trModule3 = GHC.Types.TrNameS T7360.$trModule4 @@ -79,7 +78,6 @@ T7360.$trModule2 = "T7360"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$trModule1 = GHC.Types.TrNameS T7360.$trModule2 @@ -87,7 +85,6 @@ T7360.$trModule1 = GHC.Types.TrNameS T7360.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T7360.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T7360.$trModule @@ -110,7 +107,6 @@ T7360.$tcFoo2 = "Foo"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$tcFoo1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$tcFoo1 = GHC.Types.TrNameS T7360.$tcFoo2 @@ -118,7 +114,6 @@ T7360.$tcFoo1 = GHC.Types.TrNameS T7360.$tcFoo2 -- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} T7360.$tcFoo :: GHC.Types.TyCon [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 70}] T7360.$tcFoo @@ -147,7 +142,6 @@ T7360.$tc'Foo6 = "'Foo1"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo5 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$tc'Foo5 = GHC.Types.TrNameS T7360.$tc'Foo6 @@ -155,7 +149,6 @@ T7360.$tc'Foo5 = GHC.Types.TrNameS T7360.$tc'Foo6 -- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo1 :: GHC.Types.TyCon [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 70}] T7360.$tc'Foo1 @@ -177,7 +170,6 @@ T7360.$tc'Foo8 = "'Foo2"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo7 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$tc'Foo7 = GHC.Types.TrNameS T7360.$tc'Foo8 @@ -185,7 +177,6 @@ T7360.$tc'Foo7 = GHC.Types.TrNameS T7360.$tc'Foo8 -- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo2 :: GHC.Types.TyCon [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 70}] T7360.$tc'Foo2 @@ -212,7 +203,6 @@ T7360.$tc'Foo11 = "'Foo3"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo10 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$tc'Foo10 = GHC.Types.TrNameS T7360.$tc'Foo11 @@ -220,7 +210,6 @@ T7360.$tc'Foo10 = GHC.Types.TrNameS T7360.$tc'Foo11 -- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo3 :: GHC.Types.TyCon [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 70}] T7360.$tc'Foo3 ===================================== testsuite/tests/simplCore/should_compile/noinline01.stderr ===================================== @@ -14,7 +14,7 @@ Noinline01.$trModule4 :: GHC.Prim.Addr# "main"#; Noinline01.$trModule3 :: GHC.Types.TrName -[GblId, Cpr=m1, Unf=OtherCon []] = +[GblId, Unf=OtherCon []] = CCS_DONT_CARE GHC.Types.TrNameS! [Noinline01.$trModule4]; Noinline01.$trModule2 :: GHC.Prim.Addr# @@ -22,11 +22,11 @@ Noinline01.$trModule2 :: GHC.Prim.Addr# "Noinline01"#; Noinline01.$trModule1 :: GHC.Types.TrName -[GblId, Cpr=m1, Unf=OtherCon []] = +[GblId, Unf=OtherCon []] = CCS_DONT_CARE GHC.Types.TrNameS! [Noinline01.$trModule2]; Noinline01.$trModule :: GHC.Types.Module -[GblId, Cpr=m1, Unf=OtherCon []] = +[GblId, Unf=OtherCon []] = CCS_DONT_CARE GHC.Types.Module! [Noinline01.$trModule3 Noinline01.$trModule1]; ===================================== testsuite/tests/simplCore/should_compile/par01.stderr ===================================== @@ -21,7 +21,7 @@ Par01.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Par01.$trModule3 :: GHC.Types.TrName -[GblId, Cpr=m1, Unf=OtherCon []] +[GblId, Unf=OtherCon []] Par01.$trModule3 = GHC.Types.TrNameS Par01.$trModule4 -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} @@ -31,12 +31,12 @@ Par01.$trModule2 = "Par01"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Par01.$trModule1 :: GHC.Types.TrName -[GblId, Cpr=m1, Unf=OtherCon []] +[GblId, Unf=OtherCon []] Par01.$trModule1 = GHC.Types.TrNameS Par01.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} Par01.$trModule :: GHC.Types.Module -[GblId, Cpr=m1, Unf=OtherCon []] +[GblId, Unf=OtherCon []] Par01.$trModule = GHC.Types.Module Par01.$trModule3 Par01.$trModule1 ===================================== testsuite/tests/simplCore/should_compile/spec-inline.stderr ===================================== @@ -13,7 +13,6 @@ Roman.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Roman.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] Roman.$trModule3 = GHC.Types.TrNameS Roman.$trModule4 @@ -28,7 +27,6 @@ Roman.$trModule2 = "Roman"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Roman.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] Roman.$trModule1 = GHC.Types.TrNameS Roman.$trModule2 @@ -36,7 +34,6 @@ Roman.$trModule1 = GHC.Types.TrNameS Roman.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} Roman.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] Roman.$trModule @@ -132,7 +129,6 @@ Roman.foo_go -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Roman.foo2 :: Int [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] Roman.foo2 = GHC.Types.I# 6# @@ -140,7 +136,6 @@ Roman.foo2 = GHC.Types.I# 6# -- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0} Roman.foo1 :: Maybe Int [GblId, - Cpr=m2, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] Roman.foo1 = GHC.Maybe.Just @Int Roman.foo2 ===================================== testsuite/tests/stranal/should_compile/T10694.stderr ===================================== @@ -6,26 +6,26 @@ Result size of Tidy Core = {terms: 74, types: 65, coercions: 0, joins: 0/4} T10694.$wpm [InlPrag=NOINLINE] :: Int -> Int -> (# Int, Int #) [GblId, Arity=2, Str=, Unf=OtherCon []] T10694.$wpm - = \ (w_s1vj :: Int) (w1_s1vk :: Int) -> + = \ (w_s1v1 :: Int) (w1_s1v2 :: Int) -> let { - l_s1uR :: Int + l_s1uz :: Int [LclId] - l_s1uR - = case w_s1vj of { GHC.Types.I# x_aJ9 -> case w1_s1vk of { GHC.Types.I# y_aJc -> GHC.Types.I# (GHC.Prim.+# x_aJ9 y_aJc) } } } in + l_s1uz + = case w_s1v1 of { GHC.Types.I# x_aJ0 -> case w1_s1v2 of { GHC.Types.I# y_aJ3 -> GHC.Types.I# (GHC.Prim.+# x_aJ0 y_aJ3) } } } in let { - l1_s1uS :: Int + l1_s1uA :: Int [LclId] - l1_s1uS - = case w_s1vj of { GHC.Types.I# x_aJh -> case w1_s1vk of { GHC.Types.I# y_aJk -> GHC.Types.I# (GHC.Prim.-# x_aJh y_aJk) } } } in + l1_s1uA + = case w_s1v1 of { GHC.Types.I# x_aJ8 -> case w1_s1v2 of { GHC.Types.I# y_aJb -> GHC.Types.I# (GHC.Prim.-# x_aJ8 y_aJb) } } } in let { - l2_s1uT :: [Int] + l2_s1uB :: [Int] [LclId, Unf=OtherCon []] - l2_s1uT = GHC.Types.: @Int l1_s1uS (GHC.Types.[] @Int) } in + l2_s1uB = GHC.Types.: @Int l1_s1uA (GHC.Types.[] @Int) } in let { - l3_sJv :: [Int] + l3_sJm :: [Int] [LclId, Unf=OtherCon []] - l3_sJv = GHC.Types.: @Int l_s1uR l2_s1uT } in - (# GHC.List.$w!! @Int l3_sJv 0#, GHC.List.$w!! @Int l3_sJv 1# #) + l3_sJm = GHC.Types.: @Int l_s1uz l2_s1uB } in + (# GHC.List.$w!! @Int l3_sJm 0#, GHC.List.$w!! @Int l3_sJm 1# #) -- RHS size: {terms: 10, types: 11, coercions: 0, joins: 0/0} pm [InlPrag=NOUSERINLINE[0]] :: Int -> Int -> (Int, Int) @@ -35,9 +35,9 @@ pm [InlPrag=NOUSERINLINE[0]] :: Int -> Int -> (Int, Int) Cpr=m1, Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=2,unsat_ok=True,boring_ok=False) - Tmpl= \ (w_s1vj [Occ=Once] :: Int) (w1_s1vk [Occ=Once] :: Int) -> - case T10694.$wpm w_s1vj w1_s1vk of { (# ww1_s1vp [Occ=Once], ww2_s1vq [Occ=Once] #) -> (ww1_s1vp, ww2_s1vq) }}] -pm = \ (w_s1vj :: Int) (w1_s1vk :: Int) -> case T10694.$wpm w_s1vj w1_s1vk of { (# ww1_s1vp, ww2_s1vq #) -> (ww1_s1vp, ww2_s1vq) } + Tmpl= \ (w_s1v1 [Occ=Once] :: Int) (w1_s1v2 [Occ=Once] :: Int) -> + case T10694.$wpm w_s1v1 w1_s1v2 of { (# ww1_s1v7 [Occ=Once], ww2_s1v8 [Occ=Once] #) -> (ww1_s1v7, ww2_s1v8) }}] +pm = \ (w_s1v1 :: Int) (w1_s1v2 :: Int) -> case T10694.$wpm w_s1v1 w1_s1v2 of { (# ww1_s1v7, ww2_s1v8 #) -> (ww1_s1v7, ww2_s1v8) } -- RHS size: {terms: 8, types: 9, coercions: 0, joins: 0/0} m :: Int -> Int -> Int @@ -46,9 +46,9 @@ m :: Int -> Int -> Int Str=, Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=2,unsat_ok=True,boring_ok=False) - Tmpl= \ (x_awt [Occ=Once] :: Int) (y_awu [Occ=Once] :: Int) -> - case pm x_awt y_awu of { (_ [Occ=Dead], mr_aww [Occ=Once]) -> mr_aww }}] -m = \ (x_awt :: Int) (y_awu :: Int) -> case T10694.$wpm x_awt y_awu of { (# ww1_s1vp, ww2_s1vq #) -> ww2_s1vq } + Tmpl= \ (x_awo [Occ=Once] :: Int) (y_awp [Occ=Once] :: Int) -> + case pm x_awo y_awp of { (_ [Occ=Dead], mr_awr [Occ=Once]) -> mr_awr }}] +m = \ (x_awo :: Int) (y_awp :: Int) -> case T10694.$wpm x_awo y_awp of { (# ww1_s1v7, ww2_s1v8 #) -> ww2_s1v8 } -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T10694.$trModule4 :: GHC.Prim.Addr# @@ -57,9 +57,7 @@ T10694.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T10694.$trModule3 :: GHC.Types.TrName -[GblId, - Cpr=m1, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T10694.$trModule3 = GHC.Types.TrNameS T10694.$trModule4 -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} @@ -69,17 +67,13 @@ T10694.$trModule2 = "T10694"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T10694.$trModule1 :: GHC.Types.TrName -[GblId, - Cpr=m1, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T10694.$trModule1 = GHC.Types.TrNameS T10694.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} -T10694.$trModule :: GHC.Unit.Module -[GblId, - Cpr=m1, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] -T10694.$trModule = GHC.Unit.Module T10694.$trModule3 T10694.$trModule1 +T10694.$trModule :: GHC.Types.Module +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] +T10694.$trModule = GHC.Types.Module T10694.$trModule3 T10694.$trModule1 ===================================== testsuite/tests/stranal/sigs/BottomFromInnerLambda.stderr ===================================== @@ -7,7 +7,7 @@ BottomFromInnerLambda.f: ==================== Cpr signatures ==================== -BottomFromInnerLambda.$trModule: m1 +BottomFromInnerLambda.$trModule: BottomFromInnerLambda.expensive: m1 BottomFromInnerLambda.f: ===================================== testsuite/tests/stranal/sigs/CaseBinderCPR.stderr ===================================== @@ -6,7 +6,7 @@ CaseBinderCPR.f_list_cmp: ==================== Cpr signatures ==================== -CaseBinderCPR.$trModule: m1 +CaseBinderCPR.$trModule: CaseBinderCPR.f_list_cmp: m1 ===================================== testsuite/tests/stranal/sigs/DmdAnalGADTs.hs ===================================== @@ -7,11 +7,13 @@ data D a where A :: D Int B :: D (Int -> Int) +-- Doesn't have the CPR property anymore (#18154), but an expandable unfolding. +-- The point of this test is that f' has the CPR property. hasCPR :: Int hasCPR = 1 hasStrSig :: Int -> Int -hasStrSig x = x +hasStrSig x = x + 1 diverges :: Int diverges = diverges ===================================== testsuite/tests/stranal/sigs/DmdAnalGADTs.stderr ===================================== @@ -9,21 +9,21 @@ DmdAnalGADTs.f: DmdAnalGADTs.f': DmdAnalGADTs.g: DmdAnalGADTs.hasCPR: -DmdAnalGADTs.hasStrSig: +DmdAnalGADTs.hasStrSig: ==================== Cpr signatures ==================== -DmdAnalGADTs.$tc'A: m1 -DmdAnalGADTs.$tc'B: m1 -DmdAnalGADTs.$tcD: m1 -DmdAnalGADTs.$trModule: m1 +DmdAnalGADTs.$tc'A: +DmdAnalGADTs.$tc'B: +DmdAnalGADTs.$tcD: +DmdAnalGADTs.$trModule: DmdAnalGADTs.diverges: b DmdAnalGADTs.f: DmdAnalGADTs.f': m1 DmdAnalGADTs.g: -DmdAnalGADTs.hasCPR: m1 -DmdAnalGADTs.hasStrSig: +DmdAnalGADTs.hasCPR: +DmdAnalGADTs.hasStrSig: m1 @@ -37,6 +37,6 @@ DmdAnalGADTs.f: DmdAnalGADTs.f': DmdAnalGADTs.g: DmdAnalGADTs.hasCPR: -DmdAnalGADTs.hasStrSig: +DmdAnalGADTs.hasStrSig: ===================================== testsuite/tests/stranal/sigs/HyperStrUse.stderr ===================================== @@ -6,7 +6,7 @@ HyperStrUse.f: ==================== Cpr signatures ==================== -HyperStrUse.$trModule: m1 +HyperStrUse.$trModule: HyperStrUse.f: m1 ===================================== testsuite/tests/stranal/sigs/NewtypeArity.stderr ===================================== @@ -9,9 +9,9 @@ Test.t2: ==================== Cpr signatures ==================== -Test.$tc'MkT: m1 -Test.$tcT: m1 -Test.$trModule: m1 +Test.$tc'MkT: +Test.$tcT: +Test.$trModule: Test.t: m1 Test.t2: m1 ===================================== testsuite/tests/stranal/sigs/StrAnalExample.stderr ===================================== @@ -6,7 +6,7 @@ StrAnalExample.foo: ==================== Cpr signatures ==================== -StrAnalExample.$trModule: m1 +StrAnalExample.$trModule: StrAnalExample.foo: ===================================== testsuite/tests/stranal/sigs/T12370.stderr ===================================== @@ -7,7 +7,7 @@ T12370.foo: ==================== Cpr signatures ==================== -T12370.$trModule: m1 +T12370.$trModule: T12370.bar: m1 T12370.foo: m1 ===================================== testsuite/tests/stranal/sigs/T17932.stderr ===================================== @@ -10,11 +10,11 @@ T17932.flags: ==================== Cpr signatures ==================== -T17932.$tc'Options: m1 -T17932.$tc'X: m1 -T17932.$tcOptions: m1 -T17932.$tcX: m1 -T17932.$trModule: m1 +T17932.$tc'Options: +T17932.$tc'X: +T17932.$tcOptions: +T17932.$tcX: +T17932.$trModule: T17932.flags: ===================================== testsuite/tests/stranal/sigs/T5075.stderr ===================================== @@ -6,7 +6,7 @@ T5075.loop: ==================== Cpr signatures ==================== -T8569.$tc'Rdata: m1 -T8569.$tc'Rint: m1 -T8569.$tcRep: m1 -T8569.$trModule: m1 +T8569.$tc'Rdata: +T8569.$tc'Rint: +T8569.$tcRep: +T8569.$trModule: T8569.addUp: ===================================== testsuite/tests/stranal/sigs/T8598.stderr ===================================== @@ -6,7 +6,7 @@ T8598.fun: ==================== Cpr signatures ==================== -T8598.$trModule: m1 +T8598.$trModule: T8598.fun: m1 ===================================== testsuite/tests/stranal/sigs/UnsatFun.stderr ===================================== @@ -12,7 +12,7 @@ UnsatFun.h3: ==================== Cpr signatures ==================== -UnsatFun.$trModule: m1 +UnsatFun.$trModule: UnsatFun.f: b UnsatFun.g: UnsatFun.g': View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0ddf0bfe1e347e153c7382997247b42fcb58b2c1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0ddf0bfe1e347e153c7382997247b42fcb58b2c1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 7 11:02:19 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Thu, 07 May 2020 07:02:19 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn-simpl] DmdAnal: Improve handling of precise exceptions Message-ID: <5eb3eabb1f0b4_6167e11371893021ad@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn-simpl at Glasgow Haskell Compiler / GHC Commits: dbc0ff0e by Sebastian Graf at 2020-05-07T13:02:09+02:00 DmdAnal: Improve handling of precise exceptions This patch does two things: Fix possible unsoundness in what was called the "IO hack" and implement part 2.1 of the "fixing precise exceptions" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions, which, in combination with !2956, supersedes !3014 and !2525. **IO hack** The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is called `exprMayThrowPreciseException` now. I came up with two testcases exemplifying possible unsoundness (if twisted enough) in the old approach: - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. - `T13380e`: Demonstrating unsoundness of the "IO hack" when we have Nested CPR. Not currently relevant, as we don't have Nested CPR yet. Basically, the IO hack assumed that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future, see `T13380e`. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380{d,e}` (and will hopefully be robust to Nested CPR). **Precise exceptions** In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that was terribly unprincipled. That unprincipledness resulted in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception (and the existing IO hack doesn't detect that) Fixing both issues in !3014 turned out to be too complicated and had the potential to regress in the future. Hence we decided to only fix `T13380b` and augment the `Divergence` lattice with a new middle-layer element, `ExnOrDiv`, which means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. See the wiki page on Step 2.1 for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#dead-code-elimination-for-raiseio-with-isdeadenddiv-introducing-exnordiv-step-21 - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/LiberateCase.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Make.hs - testsuite/tests/stranal/should_compile/T10482a.stderr - testsuite/tests/stranal/should_compile/T10694.stderr - + testsuite/tests/stranal/should_compile/T13380b.hs - testsuite/tests/stranal/should_compile/all.T - + testsuite/tests/stranal/should_run/T13380d.hs - + testsuite/tests/stranal/should_run/T13380d.stderr - + testsuite/tests/stranal/should_run/T13380e.hs - + testsuite/tests/stranal/should_run/T13380e.stderr - testsuite/tests/stranal/should_run/all.T The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dbc0ff0e53abc390a0693e6e0fbd69c200adf0fd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dbc0ff0e53abc390a0693e6e0fbd69c200adf0fd You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 7 11:09:02 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Thu, 07 May 2020 07:09:02 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn-simpl] DmdAnal: Improve handling of precise exceptions Message-ID: <5eb3ec4eccb6d_616711ab08a493053a7@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn-simpl at Glasgow Haskell Compiler / GHC Commits: 3ed278c9 by Sebastian Graf at 2020-05-07T13:08:54+02:00 DmdAnal: Improve handling of precise exceptions This patch does two things: Fix possible unsoundness in what was called the "IO hack" and implement part 2.1 of the "fixing precise exceptions" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions, which, in combination with !2956, supersedes !3014 and !2525. **IO hack** The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is called `exprMayThrowPreciseException` now. I came up with two testcases exemplifying possible unsoundness (if twisted enough) in the old approach: - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. - `T13380e`: Demonstrating unsoundness of the "IO hack" when we have Nested CPR. Not currently relevant, as we don't have Nested CPR yet. Basically, the IO hack assumed that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future, see `T13380e`. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380{d,e}` (and will hopefully be robust to Nested CPR). **Precise exceptions** In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that was terribly unprincipled. That unprincipledness resulted in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception (and the existing IO hack doesn't detect that) Fixing both issues in !3014 turned out to be too complicated and had the potential to regress in the future. Hence we decided to only fix `T13380b` and augment the `Divergence` lattice with a new middle-layer element, `ExnOrDiv`, which means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. See the wiki page on Step 2.1 for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#dead-code-elimination-for-raiseio-with-isdeadenddiv-introducing-exnordiv-step-21 - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/LiberateCase.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Make.hs - testsuite/tests/stranal/should_compile/T10482a.stderr - testsuite/tests/stranal/should_compile/T10694.stderr - + testsuite/tests/stranal/should_compile/T13380b.hs - testsuite/tests/stranal/should_compile/all.T - + testsuite/tests/stranal/should_run/T13380d.hs - + testsuite/tests/stranal/should_run/T13380d.stderr - + testsuite/tests/stranal/should_run/T13380e.hs - + testsuite/tests/stranal/should_run/T13380e.stderr - testsuite/tests/stranal/should_run/all.T The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3ed278c934e909bf4eb54ecb4ff8c4dd281b57ad -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3ed278c934e909bf4eb54ecb4ff8c4dd281b57ad You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 7 12:18:21 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 07 May 2020 08:18:21 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 15 commits: Implement cstringLength# and FinalPtr Message-ID: <5eb3fc8d112bd_61673f81cd4c695c931938@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: ccb73e1b by Andrew Martin at 2020-05-07T08:17:38-04:00 Implement cstringLength# and FinalPtr This function and its accompanying rule resolve issue #5218. A future PR to the bytestring library will make the internal Data.ByteString.Internal.unsafePackAddress compute string length with cstringLength#. This will improve the status quo because it is eligible for constant folding. Additionally, introduce a new data constructor to ForeignPtrContents named FinalPtr. This additional data constructor, when used in the IsString instance for ByteString, leads to more Core-to-Core optimization opportunities, fewer runtime allocations, and smaller binaries. Also, this commit re-exports all the functions from GHC.CString (including cstringLength#) in GHC.Exts. It also adds a new test driver. This test driver is used to perform substring matches on Core that is dumped after all the simplifier passes. In this commit, it is used to check that constant folding of cstringLength# works. - - - - - f8407e88 by Brian Foley at 2020-05-07T08:17:43-04:00 Remove further dead code found by a simple Python script. Avoid removing some functions that are part of an API even though they're not used in-tree at the moment. - - - - - 3f27676b by John Ericson at 2020-05-07T08:17:47-04:00 HsSigWcTypeScoping: Pull in documentation from stray location - - - - - 18197a7a by John Ericson at 2020-05-07T08:17:47-04:00 Rename local `real_fvs` to `implicit_vs` It doesn't make sense to call the "free" variables we are about to implicitly bind the real ones. - - - - - a6f69e21 by John Ericson at 2020-05-07T08:17:47-04:00 A few tiny style nits with renaming - Use case rather than guards that repeatedly scrutenize same thing. - No need for view pattern when `L` is fine. - Use type synnonym to convey the intent like elsewhere. - - - - - 8872bec8 by John Ericson at 2020-05-07T08:17:47-04:00 Add `forAllOrNothing` function with note - - - - - 78bf775e by Joseph C. Sible at 2020-05-07T08:17:51-04:00 Document lawlessness of Ap's Num instance - - - - - dfb6ac88 by Joseph C. Sible at 2020-05-07T08:17:51-04:00 Apply suggestion to libraries/base/Data/Monoid.hs - - - - - fea5ddd7 by Joseph C. Sible at 2020-05-07T08:17:51-04:00 Apply more suggestions from Simon Jakobi - - - - - 722c0ff5 by Adam Gundry at 2020-05-07T08:17:51-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. - - - - - a6014e52 by Simon Peyton Jones at 2020-05-07T08:17:52-04:00 Fix specialisation for DFuns When specialising a DFun we must take care to saturate the unfolding. See Note [Specialising DFuns] in Specialise. Fixes #18120 - - - - - 499754bb by Greg Steuck at 2020-05-07T08:17:55-04:00 Remove unused SEGMENT_PROT_RWX It's been unused for a year and is problematic on any OS which requires W^X for security. - - - - - b1a6ab7d by nineonine at 2020-05-07T08:18:05-04:00 Add test for #16167 - - - - - 4d7b2ce0 by Ryan Scott at 2020-05-07T08:18:05-04:00 Bump exceptions submodule so that dist-boot is .gitignore'd `exceptions` is a stage-0 boot library as of commit 30272412fa437ab8e7a8035db94a278e10513413, which means that building `exceptions` in a GHC tree will generate a `dist-boot` directory. However, this directory was not specified in `exceptions`' `.gitignore` file, which causes it to dirty up the current `git` working directory. Accordingly, this bumps the `exceptions` submodule to commit ghc/packages/exceptions at 23c0b8a50d7592af37ca09beeec16b93080df98f, which adds `dist-boot` to the `.gitignore` file. - - - - - 529d28e4 by Ömer Sinan Ağacan at 2020-05-07T08:18:11-04:00 Linker.c: initialize n_symbols of ObjectCode with other fields - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/PPC/Cond.hs - compiler/GHC/CmmToAsm/SPARC/Cond.hs - compiler/GHC/CmmToAsm/X86/Cond.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/Plugins.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/StgToCmm/Utils.hs - compiler/GHC/SysTools/Tasks.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Types/Evidence.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Tc/Validity.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/Name/Reader.hs - compiler/GHC/Types/Var/Env.hs - compiler/GHC/Utils/Misc.hs - docs/users_guide/8.12.1-notes.rst - libraries/base/Data/Monoid.hs - libraries/base/GHC/Exts.hs - libraries/base/GHC/ForeignPtr.hs - libraries/exceptions The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6aeb9888fc1f3cb5ca2033642edf40852e911c18...529d28e436cfa8066b405fc0f92aad5f46a220bf -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6aeb9888fc1f3cb5ca2033642edf40852e911c18...529d28e436cfa8066b405fc0f92aad5f46a220bf You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 7 12:46:57 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Thu, 07 May 2020 08:46:57 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn-simpl] DmdAnal: Improve handling of precise exceptions Message-ID: <5eb40341aa808_61671341e94493368a1@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn-simpl at Glasgow Haskell Compiler / GHC Commits: 29699481 by Sebastian Graf at 2020-05-07T14:46:43+02:00 DmdAnal: Improve handling of precise exceptions This patch does two things: Fix possible unsoundness in what was called the "IO hack" and implement part 2.1 of the "fixing precise exceptions" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions, which, in combination with !2956, supersedes !3014 and !2525. **IO hack** The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is called `exprMayThrowPreciseException` now. I came up with two testcases exemplifying possible unsoundness (if twisted enough) in the old approach: - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. - `T13380e`: Demonstrating unsoundness of the "IO hack" when we have Nested CPR. Not currently relevant, as we don't have Nested CPR yet. - `T13380f`: Demonstrating unsoundness of the "IO hack" for safe FFI calls. Basically, the IO hack assumed that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future, see `T13380e`. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380{d,e}` (and will hopefully be robust to Nested CPR). **Precise exceptions** In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that was terribly unprincipled. That unprincipledness resulted in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception (and the existing IO hack doesn't detect that) Fixing both issues in !3014 turned out to be too complicated and had the potential to regress in the future. Hence we decided to only fix `T13380b` and augment the `Divergence` lattice with a new middle-layer element, `ExnOrDiv`, which means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. See the wiki page on Step 2.1 for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#dead-code-elimination-for-raiseio-with-isdeadenddiv-introducing-exnordiv-step-21 - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/LiberateCase.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Make.hs - testsuite/tests/stranal/should_compile/T10482a.stderr - testsuite/tests/stranal/should_compile/T10694.stderr - + testsuite/tests/stranal/should_compile/T13380b.hs - testsuite/tests/stranal/should_compile/all.T - + testsuite/tests/stranal/should_run/T13380d.hs - + testsuite/tests/stranal/should_run/T13380d.stderr - + testsuite/tests/stranal/should_run/T13380e.hs - + testsuite/tests/stranal/should_run/T13380e.stderr - testsuite/tests/stranal/should_run/all.T The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/29699481a0682a4bd5c0bbc58788dfde5a0b523b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/29699481a0682a4bd5c0bbc58788dfde5a0b523b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 7 13:35:04 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 07 May 2020 09:35:04 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/gc/mark-queue-refactor Message-ID: <5eb40e888c215_616712856008934591a@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/gc/mark-queue-refactor at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/gc/mark-queue-refactor You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 7 17:17:21 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Thu, 07 May 2020 13:17:21 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn-simpl] DmdAnal: Improve handling of precise exceptions Message-ID: <5eb442a1c68cc_6167136cfbac93829fd@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn-simpl at Glasgow Haskell Compiler / GHC Commits: 1d5265f9 by Sebastian Graf at 2020-05-07T19:17:13+02:00 DmdAnal: Improve handling of precise exceptions This patch does two things: Fix possible unsoundness in what was called the "IO hack" and implement part 2.1 of the "fixing precise exceptions" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions, which, in combination with !2956, supersedes !3014 and !2525. **IO hack** The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is called `exprMayThrowPreciseException` now. I came up with two testcases exemplifying possible unsoundness (if twisted enough) in the old approach: - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. - `T13380e`: Demonstrating unsoundness of the "IO hack" when we have Nested CPR. Not currently relevant, as we don't have Nested CPR yet. - `T13380f`: Demonstrating unsoundness of the "IO hack" for safe FFI calls. Basically, the IO hack assumed that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future, see `T13380e`. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380{d,e}` (and will hopefully be robust to Nested CPR). **Precise exceptions** In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that was terribly unprincipled. That unprincipledness resulted in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception (and the existing IO hack doesn't detect that) Fixing both issues in !3014 turned out to be too complicated and had the potential to regress in the future. Hence we decided to only fix `T13380b` and augment the `Divergence` lattice with a new middle-layer element, `ExnOrDiv`, which means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. See the wiki page on Step 2.1 for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#dead-code-elimination-for-raiseio-with-isdeadenddiv-introducing-exnordiv-step-21 - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/LiberateCase.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Make.hs - testsuite/tests/stranal/should_compile/T10482a.stderr - testsuite/tests/stranal/should_compile/T10694.stderr - + testsuite/tests/stranal/should_compile/T13380b.hs - testsuite/tests/stranal/should_compile/all.T - + testsuite/tests/stranal/should_run/T13380d.hs - + testsuite/tests/stranal/should_run/T13380d.stderr - + testsuite/tests/stranal/should_run/T13380e.hs - + testsuite/tests/stranal/should_run/T13380e.stderr - testsuite/tests/stranal/should_run/all.T The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1d5265f9e8c3074c2129054880ae8dc9ed7ac4e8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1d5265f9e8c3074c2129054880ae8dc9ed7ac4e8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 7 18:38:06 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 07 May 2020 14:38:06 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18159 Message-ID: <5eb4558e4e968_6167128409c494104ac@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/T18159 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18159 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 7 18:43:23 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 07 May 2020 14:43:23 -0400 Subject: [Git][ghc/ghc][wip/T18159] Implement T18159 Message-ID: <5eb456cb8aee0_61673f81cc913ba0941519@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18159 at Glasgow Haskell Compiler / GHC Commits: b785a508 by Ben Gamari at 2020-05-07T14:43:17-04:00 Implement T18159 - - - - - 4 changed files: - + libraries/base/GHC/Exception/Backtrace.hs - + libraries/base/GHC/Exception/Backtrace.hs-boot - libraries/base/GHC/Exception/Type.hs - libraries/base/base.cabal Changes: ===================================== libraries/base/GHC/Exception/Backtrace.hs ===================================== @@ -0,0 +1,87 @@ +{-# LANGUAGE Trustworthy #-} +{-# LANGUAGE NoImplicitPrelude + , ExistentialQuantification + , MagicHash + , RecordWildCards + , PatternSynonyms + #-} +{-# OPTIONS_HADDOCK not-home #-} + +----------------------------------------------------------------------------- +-- | +-- Module : GHC.Exception.Backtrace +-- Copyright : (c) The University of Glasgow, 2020-2025 +-- License : see libraries/base/LICENSE +-- +-- Maintainer : cvs-ghc at haskell.org +-- Stability : internal +-- Portability : non-portable (GHC extensions) +-- +-- Exception backtraces. +-- +----------------------------------------------------------------------------- + +module GHC.Exception.Backtrace + ( Backtrace(..) + , setGlobalBacktraceMechanism + , getGlobalBacktraceMechanism + ) where + +import GHC.Ptr +import GHC.Stack.CCS +import GHC.Stack.CallStack +import GHC.ExecutionStack +import GHC.Base +import GHC.Show + +-- | An exception backtrace. +-- +-- @since 4.15 +data Backtrace + = CostCenterBacktrace (Ptr GHC.Stack.CCS.CostCentreStack) + -- ^ a cost center profiler backtrace + | HasCallStackBacktrace GHC.Stack.CallStack + -- ^ a stack from 'GHC.Stack.HasCallStack' + | ExecutionBacktrace [GHC.ExecutionStack.Location] + -- ^ a stack unwinding (e.g. DWARF) backtrace + +-- | @since 4.15 +instance Show Backtrace where + -- TODO + showsPrec p (CostCenterBacktrace ccs) = showsPrec p ccs + showsPrec p (HasCallStackBacktrace ccs) = showsPrec p ccs + showsPrec p (ExecutionBacktrace ccs) = showsPrec p ccs + +-- | How to collect a backtrace when an exception is thrown. +data BacktraceMechanism + = NoBacktrace + -- ^ don't collect a backtrace + | CostCenterBacktrace + -- ^ collect a cost center stacktrace (only available when built with profiling) + | ExecutionStackBacktrace (Maybe Int) + -- ^ use execution stack unwinding with given limit + +currentBacktraceMechanism :: IORef BacktraceMechanism +currentBacktraceMechanism = unsafePerformIO $ mkIORef Nothing +{-# NOINLINE currentBacktraceMechanism #-} + +-- | Set how 'Control.Exception.throwIO', et al. collect backtraces. +setGlobalBacktraceMechanism :: BacktraceMechanism -> IO () +setGlobalBacktraceMechanism = writeIORef currentBacktraceMechanism + +-- | Returns the currently selected 'BacktraceMechanism'. +getGlobalBacktraceMechanism :: IO BacktraceMechanism +getGlobalBacktraceMechanism = readIORef currentBacktraceMechanism + +-- | Collect a 'Backtrace' via the current global 'BacktraceMechanism'. See +-- 'setGlobalBacktraceMechanism'. +collectBacktrace :: IO (Maybe Backtrace) +collectBacktrace = do + mech <- getGlobalBacktraceMechanism + collectBacktrace' mech + +-- | Collect a 'Backtrace' via the given 'BacktraceMechanism'. +collectBacktrace' :: BacktraceMechanism -> IO (Maybe Backtrace) +collectBacktrace' NoBacktrace = Nothing +collectBacktrace' CostCenterBacktrace = Just . CostCenterBacktrace <$> getCurrentCCS +collectBacktrace' ExecutionStackBacktrace = fmap ExecutionBacktrace <$> getStackTrace ===================================== libraries/base/GHC/Exception/Backtrace.hs-boot ===================================== @@ -0,0 +1,8 @@ +{-# LANGUAGE NoImplicitPrelude #-} + +module GHC.Exception.Backtrace (Backtrace) where + +import GHC.Show + +data Backtrace +instance Show Backtrace ===================================== libraries/base/GHC/Exception/Type.hs ===================================== @@ -22,12 +22,18 @@ ----------------------------------------------------------------------------- module GHC.Exception.Type - ( Exception(..) -- Class - , SomeException(..), ArithException(..) + ( -- * Fundamentals + , Exception(..) + , SomeException(..) + , pattern SomeException + -- * Concrete exception types + , ArithException(..) , divZeroException, overflowException, ratioZeroDenomException , underflowException ) where +import {-# SOURCE #-} GHC.Exception.Backtrace (Backtrace) + import Data.Maybe import Data.Typeable (Typeable, cast) -- loop: Data.Typeable -> GHC.Err -> GHC.Exception @@ -39,11 +45,23 @@ The @SomeException@ type is the root of the exception type hierarchy. When an exception of type @e@ is thrown, behind the scenes it is encapsulated in a @SomeException at . -} -data SomeException = forall e . Exception e => SomeException e +data SomeException = forall e. Exception e => SomeExceptionWithLocation (Maybe Backtrace) e -- | @since 3.0 instance Show SomeException where - showsPrec p (SomeException e) = showsPrec p e + -- TODO: Should this obey the usual Show-is-Haskell invariant? + showsPrec p (SomeExceptionWithLocation mb_bt e) = + showsPrec p e <> backtrace + where + backtrace = + case mb_bt of + Nothing -> "" + Just bt -> "\nBacktrace:\n" <> show bt + +pattern SomeException e <- SomeExceptionWithLocation _ e + where + SomeException e = SomeExceptionWithLocation Nothing e + {- | Any type that you wish to throw or catch as an exception must be an ===================================== libraries/base/base.cabal ===================================== @@ -218,6 +218,7 @@ Library GHC.Environment GHC.Err GHC.Exception + GHC.Exception.Backtrace GHC.Exception.Type GHC.ExecutionStack GHC.ExecutionStack.Internal View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b785a508eb0829e635ab6cd499a0440176a1187f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b785a508eb0829e635ab6cd499a0440176a1187f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 7 18:59:09 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 07 May 2020 14:59:09 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 17 commits: Implement cstringLength# and FinalPtr Message-ID: <5eb45a7dc1d88_61671285600894172d9@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: acccf67e by Andrew Martin at 2020-05-07T14:58:39-04:00 Implement cstringLength# and FinalPtr This function and its accompanying rule resolve issue #5218. A future PR to the bytestring library will make the internal Data.ByteString.Internal.unsafePackAddress compute string length with cstringLength#. This will improve the status quo because it is eligible for constant folding. Additionally, introduce a new data constructor to ForeignPtrContents named FinalPtr. This additional data constructor, when used in the IsString instance for ByteString, leads to more Core-to-Core optimization opportunities, fewer runtime allocations, and smaller binaries. Also, this commit re-exports all the functions from GHC.CString (including cstringLength#) in GHC.Exts. It also adds a new test driver. This test driver is used to perform substring matches on Core that is dumped after all the simplifier passes. In this commit, it is used to check that constant folding of cstringLength# works. - - - - - c3bcb6af by Brian Foley at 2020-05-07T14:58:40-04:00 Remove further dead code found by a simple Python script. Avoid removing some functions that are part of an API even though they're not used in-tree at the moment. - - - - - ebb58b0e by Julien Debon at 2020-05-07T14:58:44-04:00 Add doc examples for Bifoldable See #17929 - - - - - e4b1d38c by Julien Debon at 2020-05-07T14:58:46-04:00 doc (Bitraversable): Add examples to Bitraversable * Add examples to Data.Bitraversable * Fix formatting for (,) in Bitraversable and Bifoldable * Fix mistake on bimapAccumR documentation See #17929 - - - - - 77ea518c by John Ericson at 2020-05-07T14:58:48-04:00 HsSigWcTypeScoping: Pull in documentation from stray location - - - - - 7f7e0e7d by John Ericson at 2020-05-07T14:58:48-04:00 Rename local `real_fvs` to `implicit_vs` It doesn't make sense to call the "free" variables we are about to implicitly bind the real ones. - - - - - c1185e83 by John Ericson at 2020-05-07T14:58:48-04:00 A few tiny style nits with renaming - Use case rather than guards that repeatedly scrutenize same thing. - No need for view pattern when `L` is fine. - Use type synnonym to convey the intent like elsewhere. - - - - - 341ece26 by John Ericson at 2020-05-07T14:58:48-04:00 Add `forAllOrNothing` function with note - - - - - 306bc7f4 by Joseph C. Sible at 2020-05-07T14:58:50-04:00 Document lawlessness of Ap's Num instance - - - - - 9e711055 by Joseph C. Sible at 2020-05-07T14:58:50-04:00 Apply suggestion to libraries/base/Data/Monoid.hs - - - - - d03c9c6f by Joseph C. Sible at 2020-05-07T14:58:50-04:00 Apply more suggestions from Simon Jakobi - - - - - 5286b945 by Adam Gundry at 2020-05-07T14:58:51-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. - - - - - df9d7db4 by Simon Peyton Jones at 2020-05-07T14:58:51-04:00 Fix specialisation for DFuns When specialising a DFun we must take care to saturate the unfolding. See Note [Specialising DFuns] in Specialise. Fixes #18120 - - - - - 62aea86f by Greg Steuck at 2020-05-07T14:58:53-04:00 Remove unused SEGMENT_PROT_RWX It's been unused for a year and is problematic on any OS which requires W^X for security. - - - - - 4484f0f7 by nineonine at 2020-05-07T14:58:54-04:00 Add test for #16167 - - - - - 0dcde93c by Ryan Scott at 2020-05-07T14:58:55-04:00 Bump exceptions submodule so that dist-boot is .gitignore'd `exceptions` is a stage-0 boot library as of commit 30272412fa437ab8e7a8035db94a278e10513413, which means that building `exceptions` in a GHC tree will generate a `dist-boot` directory. However, this directory was not specified in `exceptions`' `.gitignore` file, which causes it to dirty up the current `git` working directory. Accordingly, this bumps the `exceptions` submodule to commit ghc/packages/exceptions at 23c0b8a50d7592af37ca09beeec16b93080df98f, which adds `dist-boot` to the `.gitignore` file. - - - - - 8dfdce68 by Ömer Sinan Ağacan at 2020-05-07T14:59:00-04:00 Linker.c: initialize n_symbols of ObjectCode with other fields - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/PPC/Cond.hs - compiler/GHC/CmmToAsm/SPARC/Cond.hs - compiler/GHC/CmmToAsm/X86/Cond.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/Plugins.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/StgToCmm/Utils.hs - compiler/GHC/SysTools/Tasks.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Types/Evidence.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Tc/Validity.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/Name/Reader.hs - compiler/GHC/Types/Var/Env.hs - compiler/GHC/Utils/Misc.hs - docs/users_guide/8.12.1-notes.rst - libraries/base/Data/Bifoldable.hs - libraries/base/Data/Bitraversable.hs - libraries/base/Data/Monoid.hs - libraries/base/GHC/Exts.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/529d28e436cfa8066b405fc0f92aad5f46a220bf...8dfdce68107799c040e9387a0b7f31d8379befa5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/529d28e436cfa8066b405fc0f92aad5f46a220bf...8dfdce68107799c040e9387a0b7f31d8379befa5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 7 19:56:48 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 07 May 2020 15:56:48 -0400 Subject: [Git][ghc/ghc][wip/T18159] Implement T18159 Message-ID: <5eb468007d137_616713664be09464897@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18159 at Glasgow Haskell Compiler / GHC Commits: 79442b89 by Ben Gamari at 2020-05-07T15:56:36-04:00 Implement T18159 - - - - - 4 changed files: - + libraries/base/GHC/Exception/Backtrace.hs - + libraries/base/GHC/Exception/Backtrace.hs-boot - libraries/base/GHC/Exception/Type.hs - libraries/base/base.cabal Changes: ===================================== libraries/base/GHC/Exception/Backtrace.hs ===================================== @@ -0,0 +1,91 @@ +{-# LANGUAGE Trustworthy #-} +{-# LANGUAGE NoImplicitPrelude + , ExistentialQuantification + , MagicHash + , RecordWildCards + , PatternSynonyms + #-} +{-# OPTIONS_HADDOCK not-home #-} + +----------------------------------------------------------------------------- +-- | +-- Module : GHC.Exception.Backtrace +-- Copyright : (c) The University of Glasgow, 2020-2025 +-- License : see libraries/base/LICENSE +-- +-- Maintainer : cvs-ghc at haskell.org +-- Stability : internal +-- Portability : non-portable (GHC extensions) +-- +-- Exception backtraces. +-- +----------------------------------------------------------------------------- + +module GHC.Exception.Backtrace + ( Backtrace(..) + , setGlobalBacktraceMechanism + , getGlobalBacktraceMechanism + ) where + +import GHC.Ptr +import GHC.Stack.CCS +import GHC.Stack.CallStack +import GHC.ExecutionStack +import GHC.Base +import GHC.Show + +-- | An exception backtrace. +-- +-- @since 4.15 +data Backtrace + = CostCenterBacktrace (Ptr GHC.Stack.CCS.CostCentreStack) + -- ^ a cost center profiler backtrace + | HasCallStackBacktrace GHC.Stack.CallStack + -- ^ a stack from 'GHC.Stack.HasCallStack' + | ExecutionBacktrace [GHC.ExecutionStack.Location] + -- ^ a stack unwinding (e.g. DWARF) backtrace + +-- | @since 4.15 +instance Show Backtrace where + -- TODO + showsPrec p (CostCenterBacktrace ccs) = showsPrec p ccs + showsPrec p (HasCallStackBacktrace ccs) = showsPrec p ccs + showsPrec p (ExecutionBacktrace ccs) = showsPrec p ccs + +-- | How to collect a backtrace when an exception is thrown. +data BacktraceMechanism + = NoBacktrace + -- ^ don't collect a backtrace + | CostCenterBacktrace + -- ^ collect a cost center stacktrace (only available when built with profiling) + | ExecutionStackBacktrace (Maybe Int) + -- ^ use execution stack unwinding with given limit + +currentBacktraceMechanism :: IORef BacktraceMechanism +currentBacktraceMechanism = unsafePerformIO $ mkIORef Nothing +{-# NOINLINE currentBacktraceMechanism #-} + +-- | Set how 'Control.Exception.throwIO', et al. collect backtraces. +setGlobalBacktraceMechanism :: BacktraceMechanism -> IO () +setGlobalBacktraceMechanism = writeIORef currentBacktraceMechanism + +-- | Returns the currently selected 'BacktraceMechanism'. +getGlobalBacktraceMechanism :: IO BacktraceMechanism +getGlobalBacktraceMechanism = readIORef currentBacktraceMechanism + +-- | Collect a 'Backtrace' via the current global 'BacktraceMechanism'. See +-- 'setGlobalBacktraceMechanism'. +collectBacktrace :: IO (Maybe Backtrace) +collectBacktrace = do + mech <- getGlobalBacktraceMechanism + collectBacktrace' mech + +-- | Collect a 'Backtrace' via the given 'BacktraceMechanism'. +collectBacktrace' :: BacktraceMechanism -> IO (Maybe Backtrace) +collectBacktrace' NoBacktrace = Nothing +collectBacktrace' CostCenterBacktrace = do + ptr <- getCurrentCCS () + -- TODO: is the unit here safe? Is this dummy argument really needed? Why + -- isn't the state token sufficient? + return $ if ptr == nullPtr then Nothing else Just (CostCenterBacktrace ptr) +collectBacktrace' ExecutionStackBacktrace = fmap ExecutionBacktrace <$> getStackTrace ===================================== libraries/base/GHC/Exception/Backtrace.hs-boot ===================================== @@ -0,0 +1,8 @@ +{-# LANGUAGE NoImplicitPrelude #-} + +module GHC.Exception.Backtrace (Backtrace) where + +import GHC.Show + +data Backtrace +instance Show Backtrace ===================================== libraries/base/GHC/Exception/Type.hs ===================================== @@ -22,12 +22,18 @@ ----------------------------------------------------------------------------- module GHC.Exception.Type - ( Exception(..) -- Class - , SomeException(..), ArithException(..) + ( -- * Fundamentals + Exception(..) + , SomeException(..) + , pattern SomeException + -- * Concrete exception types + , ArithException(..) , divZeroException, overflowException, ratioZeroDenomException , underflowException ) where +import {-# SOURCE #-} GHC.Exception.Backtrace (Backtrace) + import Data.Maybe import Data.Typeable (Typeable, cast) -- loop: Data.Typeable -> GHC.Err -> GHC.Exception @@ -39,11 +45,23 @@ The @SomeException@ type is the root of the exception type hierarchy. When an exception of type @e@ is thrown, behind the scenes it is encapsulated in a @SomeException at . -} -data SomeException = forall e . Exception e => SomeException e +data SomeException = forall e. Exception e => SomeExceptionWithLocation (Maybe Backtrace) e -- | @since 3.0 instance Show SomeException where - showsPrec p (SomeException e) = showsPrec p e + -- TODO: Should this obey the usual Show-is-Haskell invariant? + showsPrec p (SomeExceptionWithLocation mb_bt e) = + showsPrec p e <> backtrace + where + backtrace = + case mb_bt of + Nothing -> "" + Just bt -> "\nBacktrace:\n" <> show bt + +pattern SomeException e <- SomeExceptionWithLocation _ e + where + SomeException e = SomeExceptionWithLocation Nothing e + {- | Any type that you wish to throw or catch as an exception must be an ===================================== libraries/base/base.cabal ===================================== @@ -218,6 +218,7 @@ Library GHC.Environment GHC.Err GHC.Exception + GHC.Exception.Backtrace GHC.Exception.Type GHC.ExecutionStack GHC.ExecutionStack.Internal View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/79442b890e3c41989a98dc31e567fd04714efab8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/79442b890e3c41989a98dc31e567fd04714efab8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 8 13:42:47 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Fri, 08 May 2020 09:42:47 -0400 Subject: [Git][ghc/ghc][wip/ww-max-worker-args-old-arity] Make WorkWrap.Lib.isWorkerSmallEnough aware of the old arity Message-ID: <5eb561d7292c0_616713664be095462b7@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/ww-max-worker-args-old-arity at Glasgow Haskell Compiler / GHC Commits: 6127b827 by Sebastian Graf at 2020-05-08T15:42:31+02:00 Make WorkWrap.Lib.isWorkerSmallEnough aware of the old arity We should allow a wrapper with up to 82 parameters when the original function had 82 parameters to begin with. I verified that this made no difference on NoFib, but then again it doesn't use huge records... Fixes #18122 and #17819. - - - - - 7 changed files: - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Rules.hs - docs/users_guide/using-optimisation.rst - + testsuite/tests/stranal/should_compile/T18122.hs - + testsuite/tests/stranal/should_compile/T18122.stderr - testsuite/tests/stranal/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -1997,7 +1997,7 @@ callsToNewPats env fn spec_info@(SI { si_specs = done_specs }) bndr_occs calls -- Remove ones that have too many worker variables small_pats = filterOut too_big non_dups - too_big (vars,_) = not (isWorkerSmallEnough (sc_dflags env) vars) + too_big (vars,args) = not (isWorkerSmallEnough (sc_dflags env) (valArgCount vars)) -- We are about to construct w/w pair in 'spec_one'. -- Omit specialisation leading to high arity workers. -- See Note [Limit w/w arity] in GHC.Core.Opt.WorkWrap.Utils @@ -2151,12 +2151,12 @@ argToPat _env _in_scope _val_env arg@(Type {}) _arg_occ argToPat env in_scope val_env (Tick _ arg) arg_occ = argToPat env in_scope val_env arg arg_occ - -- Note [Notes in call patterns] + -- Note [Tick annotations in call patterns] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- Ignore Notes. In particular, we want to ignore any InlineMe notes -- Perhaps we should not ignore profiling notes, but I'm going to -- ride roughshod over them all for now. - --- See Note [Notes in RULE matching] in GHC.Core.Rules + --- See Note [Tick annotations in RULE matching] in GHC.Core.Rules argToPat env in_scope val_env (Let _ arg) arg_occ = argToPat env in_scope val_env arg arg_occ ===================================== compiler/GHC/Core/Opt/WorkWrap/Utils.hs ===================================== @@ -162,7 +162,7 @@ mkWwBodies dflags fam_envs rhs_fvs fun_id demands cpr_info wrapper_body = wrap_fn_args . wrap_fn_cpr . wrap_fn_str . applyToVars work_call_args . Var worker_body = mkLams work_lam_args. work_fn_str . work_fn_cpr . work_fn_args - ; if isWorkerSmallEnough dflags work_args + ; if isWorkerSmallEnough dflags (length demands) work_args && not (too_many_args_for_join_point wrap_args) && ((useful1 && not only_one_void_argument) || useful2) then return (Just (worker_args_dmds, length work_call_args, @@ -203,10 +203,13 @@ mkWwBodies dflags fam_envs rhs_fvs fun_id demands cpr_info = False -- See Note [Limit w/w arity] -isWorkerSmallEnough :: DynFlags -> [Var] -> Bool -isWorkerSmallEnough dflags vars = count isId vars <= maxWorkerArgs dflags +isWorkerSmallEnough :: DynFlags -> Int -> [Var] -> Bool +isWorkerSmallEnough dflags old_n_args vars + = count isId vars <= max old_n_args (maxWorkerArgs dflags) -- We count only Free variables (isId) to skip Type, Kind -- variables which have no runtime representation. + -- Also if the function took 82 arguments before (old_n_args), it's fine if + -- it takes <= 82 arguments afterwards. {- Note [Always do CPR w/w] @@ -227,7 +230,8 @@ Guard against high worker arity as it generates a lot of stack traffic. A simplified example is #11565#comment:6 Current strategy is very simple: don't perform w/w transformation at all -if the result produces a wrapper with arity higher than -fmax-worker-args=. +if the result produces a wrapper with arity higher than -fmax-worker-args +and the number arguments before w/w. It is a bit all or nothing, consider ===================================== compiler/GHC/Core/Rules.hs ===================================== @@ -1025,7 +1025,7 @@ these cases. On the other hand, where we are allowed to insert new cost into the tick scope, we can float them upwards to the rule application site. -cf Note [Notes in call patterns] in GHC.Core.Opt.SpecConstr +cf Note [Tick annotations in call patterns] in GHC.Core.Opt.SpecConstr Note [Matching lets] ~~~~~~~~~~~~~~~~~~~~ ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -642,14 +642,15 @@ by saying ``-fno-wombat``. Sets the maximal number of iterations for the simplifier. .. ghc-flag:: -fmax-worker-args=⟨n⟩ - :shortdesc: *default: 10.* If a worker has that many arguments, none will - be unpacked anymore. + :shortdesc: *default: 10.* Maximum number of value arguments for a worker. :type: dynamic :category: :default: 10 - If a worker has that many arguments, none will be unpacked anymore. + A function will not be split into worker and wrapper if the number of + value arguments of the resulting worker exceeds both that of the original + function and this setting. .. ghc-flag:: -fno-opt-coercion :shortdesc: Turn off the coercion optimiser ===================================== testsuite/tests/stranal/should_compile/T18122.hs ===================================== @@ -0,0 +1,6 @@ +{-# OPTIONS_GHC -fforce-recomp -O2 -fmax-worker-args=1 #-} +module Lib where + +foo :: (Int, Int) -> Int -> Int +foo (x, y) z = x+z +{-# NOINLINE foo #-} ===================================== testsuite/tests/stranal/should_compile/T18122.stderr ===================================== @@ -0,0 +1,83 @@ + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 35, types: 27, coercions: 0, joins: 0/0} + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Lib.$trModule4 :: GHC.Prim.Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +Lib.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Lib.$trModule3 :: GHC.Types.TrName +[GblId, + Cpr=m1, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +Lib.$trModule3 = GHC.Types.TrNameS Lib.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Lib.$trModule2 :: GHC.Prim.Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +Lib.$trModule2 = "Lib"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Lib.$trModule1 :: GHC.Types.TrName +[GblId, + Cpr=m1, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +Lib.$trModule1 = GHC.Types.TrNameS Lib.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +Lib.$trModule :: GHC.Types.Module +[GblId, + Cpr=m1, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] +Lib.$trModule = GHC.Types.Module Lib.$trModule3 Lib.$trModule1 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Lib.$wfoo [InlPrag=NOINLINE] + :: GHC.Prim.Int# -> GHC.Prim.Int# -> GHC.Prim.Int# +[GblId, Arity=2, Str=, Unf=OtherCon []] +Lib.$wfoo = (GHC.Prim.+#) + +-- RHS size: {terms: 18, types: 14, coercions: 0, joins: 0/0} +foo [InlPrag=NOUSERINLINE[0]] :: (Int, Int) -> Int -> Int +[GblId, + Arity=2, + Str=, + Cpr=m1, + Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, + Guidance=ALWAYS_IF(arity=2,unsat_ok=True,boring_ok=False) + Tmpl= \ (w_sHs [Occ=Once!] :: (Int, Int)) + (w1_sHt [Occ=Once!] :: Int) -> + case w_sHs of { (ww1_sHw [Occ=Once!], _ [Occ=Dead]) -> + case ww1_sHw of { GHC.Types.I# ww4_sHz [Occ=Once] -> + case w1_sHt of { GHC.Types.I# ww6_sHF [Occ=Once] -> + case Lib.$wfoo ww4_sHz ww6_sHF of ww7_sHJ [Occ=Once] { __DEFAULT -> + GHC.Types.I# ww7_sHJ + } + } + } + }}] +foo + = \ (w_sHs :: (Int, Int)) (w1_sHt :: Int) -> + case w_sHs of { (ww1_sHw, ww2_sHB) -> + case ww1_sHw of { GHC.Types.I# ww4_sHz -> + case w1_sHt of { GHC.Types.I# ww6_sHF -> + case Lib.$wfoo ww4_sHz ww6_sHF of ww7_sHJ { __DEFAULT -> + GHC.Types.I# ww7_sHJ + } + } + } + } + + + ===================================== testsuite/tests/stranal/should_compile/all.T ===================================== @@ -51,3 +51,6 @@ test('T17852', [ grep_errmsg(r'\\$wf ::') ], compile, ['-ddump-worker-wrapper - test('T16029', normal, makefile_test, []) test('T10069', [ grep_errmsg(r'(wc1).*Int#$') ], compile, ['-dppr-cols=200 -ddump-simpl']) + +# We just want to find the worker of foo in there: +test('T18122', [ grep_errmsg(r'wfoo =') ], compile, ['-ddump-simpl']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6127b827dcea1aa2a66e01e11bb29192a851b02c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6127b827dcea1aa2a66e01e11bb29192a851b02c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 8 13:49:26 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Fri, 08 May 2020 09:49:26 -0400 Subject: [Git][ghc/ghc][wip/ww-max-worker-args-old-arity] 20 commits: Don't return a panic in tcNestedSplice Message-ID: <5eb56366da989_6167128560089546778@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/ww-max-worker-args-old-arity at Glasgow Haskell Compiler / GHC Commits: 8bdc03d6 by Simon Peyton Jones at 2020-05-04T01:56:59-04:00 Don't return a panic in tcNestedSplice In GHC.Tc.Gen.Splice.tcNestedSplice we were returning a typechecked expression of "panic". That is usually OK, because the result is discarded. But it happens that tcApp now looks at the typechecked expression, trivially, to ask if it is tagToEnum. So being bottom is bad. Moreover a debug-trace might print it out. So better to return a civilised expression, even though it is usually discarded. - - - - - 0bf640b1 by Baldur Blöndal at 2020-05-04T01:57:36-04:00 Don't require parentheses around via type (`-XDerivingVia'). Fixes #18130". - - - - - 30272412 by Artem Pelenitsyn at 2020-05-04T13:19:59-04:00 Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) - - - - - b9f7c08f by jneira at 2020-05-04T13:20:37-04:00 Remove unused hs-boot file - - - - - 1d8f80cd by Sylvain Henry at 2020-05-05T03:22:46-04:00 Remove references to -package-key * remove references to `-package-key` which has been removed in 2016 (240ddd7c39536776e955e881d709bbb039b48513) * remove support for `-this-package-key` which has been deprecated at the same time - - - - - 7bc3a65b by Sylvain Henry at 2020-05-05T03:23:31-04:00 Remove SpecConstrAnnotation (#13681) This has been deprecated since 2013. Use GHC.Types.SPEC instead. Make GHC.Exts "not-home" for haddock Metric Decrease: haddock.base - - - - - 3c862f63 by DenisFrezzato at 2020-05-05T03:24:15-04:00 Fix Haskell98 short description in documentation - - - - - 2420c555 by Ryan Scott at 2020-05-05T03:24:53-04:00 Add regression tests for #16244, #16245, #16758 Commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70 ended up fixing quite a few bugs: * This commit fixes #16244 completely. A regression test has been added. * This commit fixes one program from #16245. (The program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211369 still panics, and the program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211400 still loops infinitely.) A regression test has been added for this program. * This commit fixes #16758. Accordingly, this patch removes the `expect_broken` label from the `T16758` test case, moves it from `should_compile` to `should_fail` (as it should produce an error message), and checks in the expected stderr. - - - - - 40c71c2c by Sylvain Henry at 2020-05-05T03:25:31-04:00 Fix colorized error messages (#18128) In b3df9e780fb2f5658412c644849cd0f1e6f50331 I broke colorized messages by using "dump" style instead of "user" style. This commits fixes it. - - - - - 7ab6ab09 by Richard Eisenberg at 2020-05-06T04:39:32-04:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG ------------------------- - - - - - 420b957d by Ben Gamari at 2020-05-06T04:40:08-04:00 rts: Zero block flags with -DZ Block flags are very useful for determining the state of a block. However, some block allocator users don't touch them, leading to misleading values. Ensure that we zero then when zero-on-gc is set. This is safe and makes the flags more useful during debugging. - - - - - 740b3b8d by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix incorrect failed_to_evac value during deadlock gc Previously we would incorrectly set the failed_to_evac flag if we evacuated a value due to a deadlock GC. This would cause us to mark more things as dirty than strictly necessary. It also turned up a nasty but which I will fix next. - - - - - b2d72c75 by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - 9f3e6884 by Zubin Duggal at 2020-05-06T04:41:08-04:00 Allow atomic update of NameCache in readHieFile The situation arises in ghcide where multiple different threads may need to update the name cache, therefore with the older interface it could happen that you start reading a hie file with name cache A and produce name cache A + B, but another thread in the meantime updated the namecache to A + C. Therefore if you write the new namecache you will lose the A' updates from the second thread. Updates haddock submodule - - - - - edec6a6c by Ryan Scott at 2020-05-06T04:41:57-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _)`. Fixes #18127. - - - - - a95e7fe0 by Ömer Sinan Ağacan at 2020-05-06T04:42:39-04:00 ELF linker: increment curSymbol after filling in fields of current entry The bug was introduced in a8b7cef4d45 which added a field to the `symbols` array elements and then updated this code incorrectly: - oc->symbols[curSymbol++] = nm; + oc->symbols[curSymbol++].name = nm; + oc->symbols[curSymbol].addr = symbol->addr; - - - - - cab1871a by Sylvain Henry at 2020-05-06T04:43:21-04:00 Move LeadingUnderscore into Platform (#17957) Avoid direct use of DynFlags to know if symbols must be prefixed by an underscore. - - - - - 94e7c563 by Sylvain Henry at 2020-05-06T04:43:21-04:00 Don't use DynFlags in showLinkerState (#17957) - - - - - 9afd9251 by Ryan Scott at 2020-05-06T04:43:58-04:00 Refactoring: Use bindSigTyVarsFV in rnMethodBinds `rnMethodBinds` was explicitly using `xoptM` to determine if `ScopedTypeVariables` is enabled before bringing type variables bound by the class/instance header into scope. However, this `xoptM` logic is already performed by the `bindSigTyVarsFV` function. This patch uses `bindSigTyVarsFV` in `rnMethodBinds` to reduce the number of places where we need to consult if `ScopedTypeVariables` is on. This is purely refactoring, and there should be no user-visible change in behavior. - - - - - 3c9530ab by Sebastian Graf at 2020-05-08T15:49:17+02:00 Make WorkWrap.Lib.isWorkerSmallEnough aware of the old arity We should allow a wrapper with up to 82 parameters when the original function had 82 parameters to begin with. I verified that this made no difference on NoFib, but then again it doesn't use huge records... Fixes #18122. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Data/IOEnv.hs - compiler/GHC/Driver/Finder.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Monad.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Driver/Types.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Parser.y - compiler/GHC/Plugins.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Runtime/Debugger.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/Runtime/Linker.hs - compiler/GHC/Settings.hs - compiler/GHC/Settings/IO.hs - compiler/GHC/SysTools/FileCleanup.hs - compiler/GHC/SysTools/Tasks.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Hole.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6127b827dcea1aa2a66e01e11bb29192a851b02c...3c9530ab5e5c7ba07367a1d7486521a28b6f7245 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6127b827dcea1aa2a66e01e11bb29192a851b02c...3c9530ab5e5c7ba07367a1d7486521a28b6f7245 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 8 14:20:19 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Fri, 08 May 2020 10:20:19 -0400 Subject: [Git][ghc/ghc][wip/ww-max-worker-args-old-arity] Make WorkWrap.Lib.isWorkerSmallEnough aware of the old arity Message-ID: <5eb56aa34e5cf_6167128409c49551322@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/ww-max-worker-args-old-arity at Glasgow Haskell Compiler / GHC Commits: eb859b4e by Sebastian Graf at 2020-05-08T16:20:11+02:00 Make WorkWrap.Lib.isWorkerSmallEnough aware of the old arity We should allow a wrapper with up to 82 parameters when the original function had 82 parameters to begin with. I verified that this made no difference on NoFib, but then again it doesn't use huge records... Fixes #18122. - - - - - 7 changed files: - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Rules.hs - docs/users_guide/using-optimisation.rst - + testsuite/tests/stranal/should_compile/T18122.hs - + testsuite/tests/stranal/should_compile/T18122.stderr - testsuite/tests/stranal/should_compile/all.T Changes: ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -1947,7 +1947,7 @@ callsToNewPats env fn spec_info@(SI { si_specs = done_specs }) bndr_occs calls -- Remove ones that have too many worker variables small_pats = filterOut too_big non_dups - too_big (vars,_) = not (isWorkerSmallEnough (sc_dflags env) vars) + too_big (vars,args) = not (isWorkerSmallEnough (sc_dflags env) (valArgCount args) vars) -- We are about to construct w/w pair in 'spec_one'. -- Omit specialisation leading to high arity workers. -- See Note [Limit w/w arity] in GHC.Core.Opt.WorkWrap.Utils @@ -2101,12 +2101,12 @@ argToPat _env _in_scope _val_env arg@(Type {}) _arg_occ argToPat env in_scope val_env (Tick _ arg) arg_occ = argToPat env in_scope val_env arg arg_occ - -- Note [Notes in call patterns] + -- Note [Tick annotations in call patterns] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- Ignore Notes. In particular, we want to ignore any InlineMe notes -- Perhaps we should not ignore profiling notes, but I'm going to -- ride roughshod over them all for now. - --- See Note [Notes in RULE matching] in GHC.Core.Rules + --- See Note [Tick annotations in RULE matching] in GHC.Core.Rules argToPat env in_scope val_env (Let _ arg) arg_occ = argToPat env in_scope val_env arg arg_occ ===================================== compiler/GHC/Core/Opt/WorkWrap/Utils.hs ===================================== @@ -162,7 +162,7 @@ mkWwBodies dflags fam_envs rhs_fvs fun_id demands cpr_info wrapper_body = wrap_fn_args . wrap_fn_cpr . wrap_fn_str . applyToVars work_call_args . Var worker_body = mkLams work_lam_args. work_fn_str . work_fn_cpr . work_fn_args - ; if isWorkerSmallEnough dflags work_args + ; if isWorkerSmallEnough dflags (length demands) work_args && not (too_many_args_for_join_point wrap_args) && ((useful1 && not only_one_void_argument) || useful2) then return (Just (worker_args_dmds, length work_call_args, @@ -203,10 +203,13 @@ mkWwBodies dflags fam_envs rhs_fvs fun_id demands cpr_info = False -- See Note [Limit w/w arity] -isWorkerSmallEnough :: DynFlags -> [Var] -> Bool -isWorkerSmallEnough dflags vars = count isId vars <= maxWorkerArgs dflags +isWorkerSmallEnough :: DynFlags -> Int -> [Var] -> Bool +isWorkerSmallEnough dflags old_n_args vars + = count isId vars <= max old_n_args (maxWorkerArgs dflags) -- We count only Free variables (isId) to skip Type, Kind -- variables which have no runtime representation. + -- Also if the function took 82 arguments before (old_n_args), it's fine if + -- it takes <= 82 arguments afterwards. {- Note [Always do CPR w/w] @@ -227,7 +230,8 @@ Guard against high worker arity as it generates a lot of stack traffic. A simplified example is #11565#comment:6 Current strategy is very simple: don't perform w/w transformation at all -if the result produces a wrapper with arity higher than -fmax-worker-args=. +if the result produces a wrapper with arity higher than -fmax-worker-args +and the number arguments before w/w. It is a bit all or nothing, consider ===================================== compiler/GHC/Core/Rules.hs ===================================== @@ -1025,7 +1025,7 @@ these cases. On the other hand, where we are allowed to insert new cost into the tick scope, we can float them upwards to the rule application site. -cf Note [Notes in call patterns] in GHC.Core.Opt.SpecConstr +cf Note [Tick annotations in call patterns] in GHC.Core.Opt.SpecConstr Note [Matching lets] ~~~~~~~~~~~~~~~~~~~~ ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -642,14 +642,15 @@ by saying ``-fno-wombat``. Sets the maximal number of iterations for the simplifier. .. ghc-flag:: -fmax-worker-args=⟨n⟩ - :shortdesc: *default: 10.* If a worker has that many arguments, none will - be unpacked anymore. + :shortdesc: *default: 10.* Maximum number of value arguments for a worker. :type: dynamic :category: :default: 10 - If a worker has that many arguments, none will be unpacked anymore. + A function will not be split into worker and wrapper if the number of + value arguments of the resulting worker exceeds both that of the original + function and this setting. .. ghc-flag:: -fno-opt-coercion :shortdesc: Turn off the coercion optimiser ===================================== testsuite/tests/stranal/should_compile/T18122.hs ===================================== @@ -0,0 +1,6 @@ +{-# OPTIONS_GHC -fforce-recomp -O2 -fmax-worker-args=1 #-} +module Lib where + +foo :: (Int, Int) -> Int -> Int +foo (x, y) z = x+z +{-# NOINLINE foo #-} ===================================== testsuite/tests/stranal/should_compile/T18122.stderr ===================================== @@ -0,0 +1,83 @@ + +==================== Tidy Core ==================== +Result size of Tidy Core + = {terms: 35, types: 27, coercions: 0, joins: 0/0} + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Lib.$trModule4 :: GHC.Prim.Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +Lib.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Lib.$trModule3 :: GHC.Types.TrName +[GblId, + Cpr=m1, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +Lib.$trModule3 = GHC.Types.TrNameS Lib.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Lib.$trModule2 :: GHC.Prim.Addr# +[GblId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +Lib.$trModule2 = "Lib"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +Lib.$trModule1 :: GHC.Types.TrName +[GblId, + Cpr=m1, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +Lib.$trModule1 = GHC.Types.TrNameS Lib.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +Lib.$trModule :: GHC.Types.Module +[GblId, + Cpr=m1, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] +Lib.$trModule = GHC.Types.Module Lib.$trModule3 Lib.$trModule1 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +Lib.$wfoo [InlPrag=NOINLINE] + :: GHC.Prim.Int# -> GHC.Prim.Int# -> GHC.Prim.Int# +[GblId, Arity=2, Str=, Unf=OtherCon []] +Lib.$wfoo = (GHC.Prim.+#) + +-- RHS size: {terms: 18, types: 14, coercions: 0, joins: 0/0} +foo [InlPrag=NOUSERINLINE[0]] :: (Int, Int) -> Int -> Int +[GblId, + Arity=2, + Str=, + Cpr=m1, + Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, + Guidance=ALWAYS_IF(arity=2,unsat_ok=True,boring_ok=False) + Tmpl= \ (w_sHs [Occ=Once!] :: (Int, Int)) + (w1_sHt [Occ=Once!] :: Int) -> + case w_sHs of { (ww1_sHw [Occ=Once!], _ [Occ=Dead]) -> + case ww1_sHw of { GHC.Types.I# ww4_sHz [Occ=Once] -> + case w1_sHt of { GHC.Types.I# ww6_sHF [Occ=Once] -> + case Lib.$wfoo ww4_sHz ww6_sHF of ww7_sHJ [Occ=Once] { __DEFAULT -> + GHC.Types.I# ww7_sHJ + } + } + } + }}] +foo + = \ (w_sHs :: (Int, Int)) (w1_sHt :: Int) -> + case w_sHs of { (ww1_sHw, ww2_sHB) -> + case ww1_sHw of { GHC.Types.I# ww4_sHz -> + case w1_sHt of { GHC.Types.I# ww6_sHF -> + case Lib.$wfoo ww4_sHz ww6_sHF of ww7_sHJ { __DEFAULT -> + GHC.Types.I# ww7_sHJ + } + } + } + } + + + ===================================== testsuite/tests/stranal/should_compile/all.T ===================================== @@ -51,3 +51,6 @@ test('T17852', [ grep_errmsg(r'\\$wf ::') ], compile, ['-ddump-worker-wrapper - test('T16029', normal, makefile_test, []) test('T10069', [ grep_errmsg(r'(wc1).*Int#$') ], compile, ['-dppr-cols=200 -ddump-simpl']) + +# We just want to find the worker of foo in there: +test('T18122', [ grep_errmsg(r'wfoo =') ], compile, ['-ddump-simpl']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/eb859b4e4c6da4f3ad524187181ecf5af2635806 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/eb859b4e4c6da4f3ad524187181ecf5af2635806 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 8 18:59:59 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 08 May 2020 14:59:59 -0400 Subject: [Git][ghc/ghc][wip/T18159] Implement T18159 Message-ID: <5eb5ac2fa9e00_616712856008958156f@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18159 at Glasgow Haskell Compiler / GHC Commits: 48724254 by Ben Gamari at 2020-05-08T14:59:50-04:00 Implement T18159 - - - - - 4 changed files: - + libraries/base/GHC/Exception/Backtrace.hs - + libraries/base/GHC/Exception/Backtrace.hs-boot - libraries/base/GHC/Exception/Type.hs - libraries/base/base.cabal Changes: ===================================== libraries/base/GHC/Exception/Backtrace.hs ===================================== @@ -0,0 +1,91 @@ +{-# LANGUAGE Trustworthy #-} +{-# LANGUAGE NoImplicitPrelude + , ExistentialQuantification + , MagicHash + , RecordWildCards + , PatternSynonyms + #-} +{-# OPTIONS_HADDOCK not-home #-} + +----------------------------------------------------------------------------- +-- | +-- Module : GHC.Exception.Backtrace +-- Copyright : (c) The University of Glasgow, 2020-2025 +-- License : see libraries/base/LICENSE +-- +-- Maintainer : cvs-ghc at haskell.org +-- Stability : internal +-- Portability : non-portable (GHC extensions) +-- +-- Exception backtraces. +-- +----------------------------------------------------------------------------- + +module GHC.Exception.Backtrace + ( Backtrace(..) + , setGlobalBacktraceMechanism + , getGlobalBacktraceMechanism + ) where + +import GHC.Ptr +import GHC.Stack.CCS +import GHC.Stack +import GHC.ExecutionStack +import GHC.Base +import GHC.Show + +-- | An exception backtrace. +-- +-- @since 4.15 +data Backtrace + = CostCenterBacktrace (Ptr GHC.Stack.CCS.CostCentreStack) + -- ^ a cost center profiler backtrace + | HasCallStackBacktrace GHC.Stack.CallStack + -- ^ a stack from 'GHC.Stack.HasCallStack' + | ExecutionBacktrace [GHC.ExecutionStack.Location] + -- ^ a stack unwinding (e.g. DWARF) backtrace + +-- | @since 4.15 +instance Show Backtrace where + -- TODO + showsPrec p (CostCenterBacktrace ccs) = showsPrec p ccs + showsPrec p (HasCallStackBacktrace ccs) = showsPrec p ccs + showsPrec p (ExecutionBacktrace ccs) = showsPrec p ccs + +-- | How to collect a backtrace when an exception is thrown. +data BacktraceMechanism + = NoBacktrace + -- ^ don't collect a backtrace + | CostCenterBacktrace + -- ^ collect a cost center stacktrace (only available when built with profiling) + | ExecutionStackBacktrace (Maybe Int) + -- ^ use execution stack unwinding with given limit + +currentBacktraceMechanism :: IORef BacktraceMechanism +currentBacktraceMechanism = unsafePerformIO $ mkIORef Nothing +{-# NOINLINE currentBacktraceMechanism #-} + +-- | Set how 'Control.Exception.throwIO', et al. collect backtraces. +setGlobalBacktraceMechanism :: BacktraceMechanism -> IO () +setGlobalBacktraceMechanism = writeIORef currentBacktraceMechanism + +-- | Returns the currently selected 'BacktraceMechanism'. +getGlobalBacktraceMechanism :: IO BacktraceMechanism +getGlobalBacktraceMechanism = readIORef currentBacktraceMechanism + +-- | Collect a 'Backtrace' via the current global 'BacktraceMechanism'. See +-- 'setGlobalBacktraceMechanism'. +collectBacktrace :: IO (Maybe Backtrace) +collectBacktrace = do + mech <- getGlobalBacktraceMechanism + collectBacktrace' mech + +-- | Collect a 'Backtrace' via the given 'BacktraceMechanism'. +collectBacktrace' :: BacktraceMechanism -> IO (Maybe Backtrace) +collectBacktrace' NoBacktrace = Nothing +collectBacktrace' CostCenterBacktrace = do + ptr <- getCurrentCCS () + -- TODO: is the unit here safe? Is this dummy argument really needed? Why + -- isn't the state token sufficient? + return $ if ptr == nullPtr then Nothing else Just (CostCenterBacktrace ptr) +collectBacktrace' ExecutionStackBacktrace = fmap ExecutionBacktrace <$> getStackTrace ===================================== libraries/base/GHC/Exception/Backtrace.hs-boot ===================================== @@ -0,0 +1,8 @@ +{-# LANGUAGE NoImplicitPrelude #-} + +module GHC.Exception.Backtrace (Backtrace) where + +import GHC.Show + +data Backtrace +instance Show Backtrace ===================================== libraries/base/GHC/Exception/Type.hs ===================================== @@ -22,12 +22,18 @@ ----------------------------------------------------------------------------- module GHC.Exception.Type - ( Exception(..) -- Class - , SomeException(..), ArithException(..) + ( -- * Fundamentals + Exception(..) + , SomeException(..) + , pattern SomeException + -- * Concrete exception types + , ArithException(..) , divZeroException, overflowException, ratioZeroDenomException , underflowException ) where +import {-# SOURCE #-} GHC.Exception.Backtrace (Backtrace) + import Data.Maybe import Data.Typeable (Typeable, cast) -- loop: Data.Typeable -> GHC.Err -> GHC.Exception @@ -39,11 +45,23 @@ The @SomeException@ type is the root of the exception type hierarchy. When an exception of type @e@ is thrown, behind the scenes it is encapsulated in a @SomeException at . -} -data SomeException = forall e . Exception e => SomeException e +data SomeException = forall e. Exception e => SomeExceptionWithLocation (Maybe Backtrace) e -- | @since 3.0 instance Show SomeException where - showsPrec p (SomeException e) = showsPrec p e + -- TODO: Should this obey the usual Show-is-Haskell invariant? + showsPrec p (SomeExceptionWithLocation mb_bt e) = + showsPrec p e <> backtrace + where + backtrace = + case mb_bt of + Nothing -> "" + Just bt -> "\nBacktrace:\n" <> show bt + +pattern SomeException e <- SomeExceptionWithLocation _ e + where + SomeException e = SomeExceptionWithLocation Nothing e + {- | Any type that you wish to throw or catch as an exception must be an ===================================== libraries/base/base.cabal ===================================== @@ -218,6 +218,7 @@ Library GHC.Environment GHC.Err GHC.Exception + GHC.Exception.Backtrace GHC.Exception.Type GHC.ExecutionStack GHC.ExecutionStack.Internal View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/487242546d9ede9af56d08ca7510aacc753f058b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/487242546d9ede9af56d08ca7510aacc753f058b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 8 19:30:41 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 08 May 2020 15:30:41 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 17 commits: Remove further dead code found by a simple Python script. Message-ID: <5eb5b36154c19_616711ab08a49586471@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 6f6d72b2 by Brian Foley at 2020-05-08T15:29:25-04:00 Remove further dead code found by a simple Python script. Avoid removing some functions that are part of an API even though they're not used in-tree at the moment. - - - - - 78bf8bf9 by Julien Debon at 2020-05-08T15:29:28-04:00 Add doc examples for Bifoldable See #17929 - - - - - 66f0a847 by Julien Debon at 2020-05-08T15:29:29-04:00 doc (Bitraversable): Add examples to Bitraversable * Add examples to Data.Bitraversable * Fix formatting for (,) in Bitraversable and Bifoldable * Fix mistake on bimapAccumR documentation See #17929 - - - - - 9749fe12 by Baldur Blöndal at 2020-05-08T15:29:32-04:00 Specify kind variables for inferred kinds in base. - - - - - 4e9aef9e by John Ericson at 2020-05-08T15:29:36-04:00 HsSigWcTypeScoping: Pull in documentation from stray location - - - - - f4d5c6df by John Ericson at 2020-05-08T15:29:36-04:00 Rename local `real_fvs` to `implicit_vs` It doesn't make sense to call the "free" variables we are about to implicitly bind the real ones. - - - - - 20570b4b by John Ericson at 2020-05-08T15:29:36-04:00 A few tiny style nits with renaming - Use case rather than guards that repeatedly scrutenize same thing. - No need for view pattern when `L` is fine. - Use type synnonym to convey the intent like elsewhere. - - - - - 09ac8de5 by John Ericson at 2020-05-08T15:29:36-04:00 Add `forAllOrNothing` function with note - - - - - bb35c0e5 by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Document lawlessness of Ap's Num instance - - - - - cdd229ff by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply suggestion to libraries/base/Data/Monoid.hs - - - - - 926d2aab by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply more suggestions from Simon Jakobi - - - - - 7a763cff by Adam Gundry at 2020-05-08T15:29:41-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. - - - - - 88e3c815 by Simon Peyton Jones at 2020-05-08T15:29:41-04:00 Fix specialisation for DFuns When specialising a DFun we must take care to saturate the unfolding. See Note [Specialising DFuns] in Specialise. Fixes #18120 - - - - - 86c77b36 by Greg Steuck at 2020-05-08T15:29:45-04:00 Remove unused SEGMENT_PROT_RWX It's been unused for a year and is problematic on any OS which requires W^X for security. - - - - - 9d97f4b5 by nineonine at 2020-05-08T15:30:03-04:00 Add test for #16167 - - - - - aa318338 by Ryan Scott at 2020-05-08T15:30:04-04:00 Bump exceptions submodule so that dist-boot is .gitignore'd `exceptions` is a stage-0 boot library as of commit 30272412fa437ab8e7a8035db94a278e10513413, which means that building `exceptions` in a GHC tree will generate a `dist-boot` directory. However, this directory was not specified in `exceptions`' `.gitignore` file, which causes it to dirty up the current `git` working directory. Accordingly, this bumps the `exceptions` submodule to commit ghc/packages/exceptions at 23c0b8a50d7592af37ca09beeec16b93080df98f, which adds `dist-boot` to the `.gitignore` file. - - - - - ea86360f by Ömer Sinan Ağacan at 2020-05-08T15:30:30-04:00 Linker.c: initialize n_symbols of ObjectCode with other fields - - - - - 30 changed files: - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/PPC/Cond.hs - compiler/GHC/CmmToAsm/SPARC/Cond.hs - compiler/GHC/CmmToAsm/X86/Cond.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/Plugins.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/StgToCmm/Utils.hs - compiler/GHC/SysTools/Tasks.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Types/Evidence.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Tc/Validity.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/Name/Reader.hs - compiler/GHC/Types/Var/Env.hs - compiler/GHC/Utils/Misc.hs - libraries/base/Control/Arrow.hs - libraries/base/Control/Category.hs - libraries/base/Data/Bifoldable.hs - libraries/base/Data/Bitraversable.hs - libraries/base/Data/Data.hs - libraries/base/Data/Dynamic.hs - libraries/base/Data/Fixed.hs - libraries/base/Data/Functor/Compose.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8dfdce68107799c040e9387a0b7f31d8379befa5...ea86360f21e8c9812acba8dc1bc2a54fef700ece -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8dfdce68107799c040e9387a0b7f31d8379befa5...ea86360f21e8c9812acba8dc1bc2a54fef700ece You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 8 19:57:01 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 08 May 2020 15:57:01 -0400 Subject: [Git][ghc/ghc][wip/T18141] GHC.Cmm.Opt: Handle MO_XX_Conv Message-ID: <5eb5b98d96495_61671285600896126f8@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18141 at Glasgow Haskell Compiler / GHC Commits: 6f82de4a by Ben Gamari at 2020-05-05T17:41:48-04:00 GHC.Cmm.Opt: Handle MO_XX_Conv This MachOp was introduced by 2c959a1894311e59cd2fd469c1967491c1e488f3 but a wildcard match in cmmMachOpFoldM hid the fact that it wasn't handled. Ideally we would eliminate the match but this appears to be a larger task. Fixes #18141. - - - - - 3 changed files: - compiler/GHC/Cmm/Opt.hs - + testsuite/tests/cmm/opt/T18141.hs - testsuite/tests/cmm/opt/all.T Changes: ===================================== compiler/GHC/Cmm/Opt.hs ===================================== @@ -69,6 +69,7 @@ cmmMachOpFoldM _ op [CmmLit (CmmInt x rep)] MO_SF_Conv _from to -> CmmLit (CmmFloat (fromInteger x) to) MO_SS_Conv from to -> CmmLit (CmmInt (narrowS from x) to) MO_UU_Conv from to -> CmmLit (CmmInt (narrowU from x) to) + MO_XX_Conv from to -> CmmLit (CmmInt (narrowS from x) to) _ -> panic $ "cmmMachOpFoldM: unknown unary op: " ++ show op @@ -76,6 +77,7 @@ cmmMachOpFoldM _ op [CmmLit (CmmInt x rep)] -- Eliminate conversion NOPs cmmMachOpFoldM _ (MO_SS_Conv rep1 rep2) [x] | rep1 == rep2 = Just x cmmMachOpFoldM _ (MO_UU_Conv rep1 rep2) [x] | rep1 == rep2 = Just x +cmmMachOpFoldM _ (MO_XX_Conv rep1 rep2) [x] | rep1 == rep2 = Just x -- Eliminate nested conversions where possible cmmMachOpFoldM platform conv_outer [CmmMachOp conv_inner [x]] ===================================== testsuite/tests/cmm/opt/T18141.hs ===================================== @@ -0,0 +1,17 @@ +{-# LANGUAGE MagicHash #-} + +module T18141 where + +import GHC.Exts + +divInt8# :: Int8# -> Int8# -> Int8# +x# `divInt8#` y# + | isTrue# (x# `gtInt8#` zero#) && isTrue# (y# `ltInt8#` zero#) = + ((x# `subInt8#` one#) `quotInt8#` y#) `subInt8#` one# + | isTrue# (x# `ltInt8#` zero#) && isTrue# (y# `gtInt8#` zero#) = + ((x# `plusInt8#` one#) `quotInt8#` y#) `subInt8#` one# + | otherwise = x# `quotInt8#` y# + where + zero# = narrowInt8# 0# + one# = narrowInt8# 1# + ===================================== testsuite/tests/cmm/opt/all.T ===================================== @@ -1,3 +1,4 @@ # Verify that we optimize away conditional branches which always jump # to the same target. test('T15188', normal, makefile_test, []) +test('T18141', normal, compile, []) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6f82de4a5df4f14b19595f4996b58c9b901e30fc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6f82de4a5df4f14b19595f4996b58c9b901e30fc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 8 20:00:00 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 08 May 2020 16:00:00 -0400 Subject: [Git][ghc/ghc][wip/T17917] Avoid useless w/w split Message-ID: <5eb5ba40d08c7_616712856008961328f@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T17917 at Glasgow Haskell Compiler / GHC Commits: eb840476 by Simon Peyton Jones at 2020-05-08T15:58:47-04:00 Avoid useless w/w split This patch is just a tidy-up for the post-strictness-analysis worker wrapper split. Consider f x = x Strictnesss analysis does not lead to a w/w split, so the obvious thing is to leave it 100% alone. But actually, because the RHS is small, we ended up adding a StableUnfolding for it. There is some reason to do this if we choose /not/ do to w/w on the grounds that the function is small. See Note [Don't w/w inline small non-loop-breaker things] But there is no reason if we would not have done w/w anyway. This patch just moves the conditional to later. Easy. This does move soem -ddump-simpl printouts around a bit. I also discovered that the previous code was overwritten an InlineCompulsory with InlineStable, which is utterly wrong. That in turn meant that some default methods (marked InlineCompulsory) were getting their InlineCompulsory squashed. This patch fixes that bug --- but of course that does mean a bit more inlining! Metric Decrease: T9233 T9675 Metric Increase: T12707 T3064 T4029 T9872b T9872d haddock.Cabal - - - - - 11 changed files: - compiler/GHC/Core/Opt/WorkWrap.hs - compiler/GHC/Core/Unfold.hs - testsuite/tests/dependent/should_compile/dynamic-paper.stderr - testsuite/tests/driver/inline-check.stderr - testsuite/tests/numeric/should_compile/T14465.stdout - testsuite/tests/perf/compiler/T16473.stdout - testsuite/tests/simplCore/should_compile/T17901.stdout - testsuite/tests/simplCore/should_compile/T17966.stdout - testsuite/tests/simplCore/should_compile/T4201.stdout - testsuite/tests/simplCore/should_compile/T5658b.stdout - testsuite/tests/warnings/should_compile/T16282/T16282.stderr Changes: ===================================== compiler/GHC/Core/Opt/WorkWrap.hs ===================================== @@ -26,6 +26,7 @@ import GHC.Types.Cpr import GHC.Core.Opt.WorkWrap.Utils import GHC.Utils.Misc import GHC.Utils.Outputable +import GHC.Types.Unique import GHC.Core.FamInstEnv import GHC.Utils.Monad @@ -203,6 +204,23 @@ unfolding to the *worker*. So we will get something like this: How do we "transfer the unfolding"? Easy: by using the old one, wrapped in work_fn! See GHC.Core.Unfold.mkWorkerUnfolding. +Note [No worker-wrapper for record selectors] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +We sometimes generate a lot of record selectors, and generally the +don't benefit from worker/wrapper. Yes, mkWwBodies would find a w/w split, +but it is then suppressed by the certainlyWillInline test in splitFun. + +The wasted effort in mkWwBodies makes a measurable difference in +compile time (see MR !2873), so although it's a terribly ad-hoc test, +we just check here for record selectors, and do a no-op in that case. + +I did look for a generalisation, so that it's not just record +selectors that benefit. But you'd need a cheap test for "this +function will definitely get a w/w split" and that's hard to predict +in advance...the logic in mkWwBodies is complex. So I've left the +super-simple test, with this Note to explain. + + Note [Worker-wrapper for NOINLINE functions] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We used to disable worker/wrapper for NOINLINE things, but it turns out @@ -316,8 +334,8 @@ Note [Don't w/w inline small non-loop-breaker things] In general, we refrain from w/w-ing *small* functions, which are not loop breakers, because they'll inline anyway. But we must take care: it may look small now, but get to be big later after other inlining -has happened. So we take the precaution of adding an INLINE pragma to -any such functions. +has happened. So we take the precaution of adding a StableUnfolding +for any such functions. I made this change when I observed a big function at the end of compilation with a useful strictness signature but no w-w. (It was @@ -457,11 +475,6 @@ tryWW :: DynFlags tryWW dflags fam_envs is_rec fn_id rhs -- See Note [Worker-wrapper for NOINLINE functions] - | Just stable_unf <- certainlyWillInline dflags fn_info - = return [ (fn_id `setIdUnfolding` stable_unf, rhs) ] - -- See Note [Don't w/w INLINE things] - -- See Note [Don't w/w inline small non-loop-breaker things] - | is_fun && is_eta_exp = splitFun dflags fam_envs new_fn_id fn_info wrap_dmds div cpr rhs @@ -567,105 +580,125 @@ See https://gitlab.haskell.org/ghc/ghc/merge_requests/312#note_192064. splitFun :: DynFlags -> FamInstEnvs -> Id -> IdInfo -> [Demand] -> Divergence -> CprResult -> CoreExpr -> UniqSM [(Id, CoreExpr)] splitFun dflags fam_envs fn_id fn_info wrap_dmds div cpr rhs - = WARN( not (wrap_dmds `lengthIs` arity), ppr fn_id <+> (ppr arity $$ ppr wrap_dmds $$ ppr cpr) ) do - -- The arity should match the signature - stuff <- mkWwBodies dflags fam_envs rhs_fvs fn_id wrap_dmds use_cpr_info - case stuff of - Just (work_demands, join_arity, wrap_fn, work_fn) -> do - work_uniq <- getUniqueM - let work_rhs = work_fn rhs - work_act = case fn_inline_spec of -- See Note [Worker activation] - NoInline -> fn_act - _ -> wrap_act - - work_prag = InlinePragma { inl_src = SourceText "{-# INLINE" - , inl_inline = fn_inline_spec - , inl_sat = Nothing - , inl_act = work_act - , inl_rule = FunLike } - -- inl_inline: copy from fn_id; see Note [Worker-wrapper for INLINABLE functions] - -- inl_act: see Note [Worker activation] - -- inl_rule: it does not make sense for workers to be constructorlike. - - work_join_arity | isJoinId fn_id = Just join_arity - | otherwise = Nothing - -- worker is join point iff wrapper is join point - -- (see Note [Don't w/w join points for CPR]) - - work_id = mkWorkerId work_uniq fn_id (exprType work_rhs) - `setIdOccInfo` occInfo fn_info - -- Copy over occurrence info from parent - -- Notably whether it's a loop breaker - -- Doesn't matter much, since we will simplify next, but - -- seems right-er to do so - - `setInlinePragma` work_prag - - `setIdUnfolding` mkWorkerUnfolding dflags work_fn fn_unfolding - -- See Note [Worker-wrapper for INLINABLE functions] - - `setIdStrictness` mkClosedStrictSig work_demands div - -- Even though we may not be at top level, - -- it's ok to give it an empty DmdEnv - - `setIdCprInfo` mkCprSig work_arity work_cpr_info - - `setIdDemandInfo` worker_demand - - `setIdArity` work_arity - -- Set the arity so that the Core Lint check that the - -- arity is consistent with the demand type goes - -- through - `asJoinId_maybe` work_join_arity - - work_arity = length work_demands - - -- See Note [Demand on the Worker] - single_call = saturatedByOneShots arity (demandInfo fn_info) - worker_demand | single_call = mkWorkerDemand work_arity - | otherwise = topDmd - - wrap_rhs = wrap_fn work_id - wrap_act = case fn_act of -- See Note [Wrapper activation] - ActiveAfter {} -> fn_act - NeverActive -> activeDuringFinal - _ -> activeAfterInitial - wrap_prag = InlinePragma { inl_src = SourceText "{-# INLINE" - , inl_inline = NoUserInline - , inl_sat = Nothing - , inl_act = wrap_act - , inl_rule = rule_match_info } - -- inl_act: see Note [Wrapper activation] - -- inl_inline: see Note [Wrapper NoUserInline] - -- inl_rule: RuleMatchInfo is (and must be) unaffected - - wrap_id = fn_id `setIdUnfolding` mkWwInlineRule dflags wrap_rhs arity - `setInlinePragma` wrap_prag - `setIdOccInfo` noOccInfo - -- Zap any loop-breaker-ness, to avoid bleating from Lint - -- about a loop breaker with an INLINE rule - - - - return $ [(work_id, work_rhs), (wrap_id, wrap_rhs)] - -- Worker first, because wrapper mentions it - - Nothing -> return [(fn_id, rhs)] + | isRecordSelector fn_id -- See Note [No worker/wrapper for record selectors] + = return [ (fn_id, rhs ) ] + + | otherwise + = WARN( not (wrap_dmds `lengthIs` arity), ppr fn_id <+> (ppr arity $$ ppr wrap_dmds $$ ppr cpr) ) + -- The arity should match the signature + do { mb_stuff <- mkWwBodies dflags fam_envs rhs_fvs fn_id wrap_dmds use_cpr_info + ; case mb_stuff of + Nothing -> return [(fn_id, rhs)] + + Just stuff + | Just stable_unf <- certainlyWillInline dflags fn_info + -> return [ (fn_id `setIdUnfolding` stable_unf, rhs) ] + -- See Note [Don't w/w INLINE things] + -- See Note [Don't w/w inline small non-loop-breaker things] + + | otherwise + -> do { work_uniq <- getUniqueM + ; return (mkWWBindPair dflags fn_id fn_info arity rhs + work_uniq div cpr stuff) } } where - rhs_fvs = exprFreeVars rhs + rhs_fvs = exprFreeVars rhs + arity = arityInfo fn_info + -- The arity is set by the simplifier using exprEtaExpandArity + -- So it may be more than the number of top-level-visible lambdas + + -- use_cpr_info is the CPR we w/w for. Note that we kill it for join points, + -- see Note [Don't w/w join points for CPR]. + use_cpr_info | isJoinId fn_id = topCpr + | otherwise = cpr + + +mkWWBindPair :: DynFlags -> Id -> IdInfo -> Arity + -> CoreExpr -> Unique -> Divergence -> CprResult + -> ([Demand], JoinArity, Id -> CoreExpr, Expr CoreBndr -> CoreExpr) + -> [(Id, CoreExpr)] +mkWWBindPair dflags fn_id fn_info arity rhs work_uniq div cpr + (work_demands, join_arity, wrap_fn, work_fn) + = [(work_id, work_rhs), (wrap_id, wrap_rhs)] + -- Worker first, because wrapper mentions it + where + work_rhs = work_fn rhs + work_act = case fn_inline_spec of -- See Note [Worker activation] + NoInline -> fn_act + _ -> wrap_act + + work_prag = InlinePragma { inl_src = SourceText "{-# INLINE" + , inl_inline = fn_inline_spec + , inl_sat = Nothing + , inl_act = work_act + , inl_rule = FunLike } + -- inl_inline: copy from fn_id; see Note [Worker-wrapper for INLINABLE functions] + -- inl_act: see Note [Worker activation] + -- inl_rule: it does not make sense for workers to be constructorlike. + + work_join_arity | isJoinId fn_id = Just join_arity + | otherwise = Nothing + -- worker is join point iff wrapper is join point + -- (see Note [Don't w/w join points for CPR]) + + work_id = mkWorkerId work_uniq fn_id (exprType work_rhs) + `setIdOccInfo` occInfo fn_info + -- Copy over occurrence info from parent + -- Notably whether it's a loop breaker + -- Doesn't matter much, since we will simplify next, but + -- seems right-er to do so + + `setInlinePragma` work_prag + + `setIdUnfolding` mkWorkerUnfolding dflags work_fn fn_unfolding + -- See Note [Worker-wrapper for INLINABLE functions] + + `setIdStrictness` mkClosedStrictSig work_demands div + -- Even though we may not be at top level, + -- it's ok to give it an empty DmdEnv + + `setIdCprInfo` mkCprSig work_arity work_cpr_info + + `setIdDemandInfo` worker_demand + + `setIdArity` work_arity + -- Set the arity so that the Core Lint check that the + -- arity is consistent with the demand type goes + -- through + `asJoinId_maybe` work_join_arity + + work_arity = length work_demands + + -- See Note [Demand on the Worker] + single_call = saturatedByOneShots arity (demandInfo fn_info) + worker_demand | single_call = mkWorkerDemand work_arity + | otherwise = topDmd + + wrap_rhs = wrap_fn work_id + wrap_act = case fn_act of -- See Note [Wrapper activation] + ActiveAfter {} -> fn_act + NeverActive -> activeDuringFinal + _ -> activeAfterInitial + wrap_prag = InlinePragma { inl_src = SourceText "{-# INLINE" + , inl_inline = NoUserInline + , inl_sat = Nothing + , inl_act = wrap_act + , inl_rule = rule_match_info } + -- inl_act: see Note [Wrapper activation] + -- inl_inline: see Note [Wrapper NoUserInline] + -- inl_rule: RuleMatchInfo is (and must be) unaffected + + wrap_id = fn_id `setIdUnfolding` mkWwInlineRule dflags wrap_rhs arity + `setInlinePragma` wrap_prag + `setIdOccInfo` noOccInfo + -- Zap any loop-breaker-ness, to avoid bleating from Lint + -- about a loop breaker with an INLINE rule + fn_inl_prag = inlinePragInfo fn_info fn_inline_spec = inl_inline fn_inl_prag fn_act = inl_act fn_inl_prag rule_match_info = inlinePragmaRuleMatchInfo fn_inl_prag fn_unfolding = unfoldingInfo fn_info - arity = arityInfo fn_info - -- The arity is set by the simplifier using exprEtaExpandArity - -- So it may be more than the number of top-level-visible lambdas - -- use_cpr_info is the CPR we w/w for. Note that we kill it for join points, - -- see Note [Don't w/w join points for CPR]. - use_cpr_info | isJoinId fn_id = topCpr - | otherwise = cpr -- Even if we don't w/w join points for CPR, we might still do so for -- strictness. In which case a join point worker keeps its original CPR -- property; see Note [Don't w/w join points for CPR]. Otherwise, the worker ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -1121,11 +1121,21 @@ certainlyWillInline :: DynFlags -> IdInfo -> Maybe Unfolding -- ^ Sees if the unfolding is pretty certain to inline. -- If so, return a *stable* unfolding for it, that will always inline. certainlyWillInline dflags fn_info - = case unfoldingInfo fn_info of - CoreUnfolding { uf_tmpl = e, uf_guidance = g } - | loop_breaker -> Nothing -- Won't inline, so try w/w - | noinline -> Nothing -- See Note [Worker-wrapper for NOINLINE functions] - | otherwise -> do_cunf e g -- Depends on size, so look at that + = case fn_unf of + CoreUnfolding { uf_tmpl = expr, uf_guidance = guidance, uf_src = src } + | loop_breaker -> Nothing -- Won't inline, so try w/w + | noinline -> Nothing -- See Note [Worker-wrapper for NOINLINE functions] + | otherwise + -> case guidance of + UnfNever -> Nothing + UnfWhen {} -> Just (fn_unf { uf_src = src' }) + -- INLINE functions have UnfWhen + UnfIfGoodArgs { ug_size = size, ug_args = args } + -> do_cunf expr size args src' + where + src' = case src of + InlineRhs -> InlineStable + _ -> src -- Do not change InlineCompulsory! DFunUnfolding {} -> Just fn_unf -- Don't w/w DFuns; it never makes sense -- to do so, and even if it is currently a @@ -1138,17 +1148,12 @@ certainlyWillInline dflags fn_info noinline = inlinePragmaSpec (inlinePragInfo fn_info) == NoInline fn_unf = unfoldingInfo fn_info - do_cunf :: CoreExpr -> UnfoldingGuidance -> Maybe Unfolding - do_cunf _ UnfNever = Nothing - do_cunf _ (UnfWhen {}) = Just (fn_unf { uf_src = InlineStable }) - -- INLINE functions have UnfWhen - -- The UnfIfGoodArgs case seems important. If we w/w small functions -- binary sizes go up by 10%! (This is with SplitObjs.) -- I'm not totally sure why. -- INLINABLE functions come via this path -- See Note [certainlyWillInline: INLINABLE] - do_cunf expr (UnfIfGoodArgs { ug_size = size, ug_args = args }) + do_cunf expr size args src' | arityInfo fn_info > 0 -- See Note [certainlyWillInline: be careful of thunks] , not (isBottomingSig (strictnessInfo fn_info)) -- Do not unconditionally inline a bottoming functions even if @@ -1156,7 +1161,7 @@ certainlyWillInline dflags fn_info -- so we don't want to re-inline it. , let unf_arity = length args , size - (10 * (unf_arity + 1)) <= ufUseThreshold dflags - = Just (fn_unf { uf_src = InlineStable + = Just (fn_unf { uf_src = src' , uf_guidance = UnfWhen { ug_arity = unf_arity , ug_unsat_ok = unSaturatedOk , ug_boring_ok = inlineBoringOk expr } }) ===================================== testsuite/tests/dependent/should_compile/dynamic-paper.stderr ===================================== @@ -12,4 +12,4 @@ Simplifier ticks exhausted simplifier non-termination has been judged acceptable. To see detailed counts use -ddump-simpl-stats - Total ticks: 138082 + Total ticks: 157721 ===================================== testsuite/tests/driver/inline-check.stderr ===================================== @@ -21,6 +21,7 @@ Considering inlining: foo some_benefit False is exp: True is work-free: True - guidance ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False) + guidance IF_ARGS [0] 30 0 + discounted size = 20 ANSWER = NO Inactive unfolding: foo1 ===================================== testsuite/tests/numeric/should_compile/T14465.stdout ===================================== @@ -82,10 +82,8 @@ plusOne :: Natural -> Natural [GblId, Arity=1, Str=, - Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, - Guidance=ALWAYS_IF(arity=1,unsat_ok=True,boring_ok=False) - Tmpl= \ (n [Occ=Once] :: Natural) -> plusNatural n M.minusOne1}] + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [0] 30 0}] plusOne = \ (n :: Natural) -> plusNatural n M.minusOne1 -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} ===================================== testsuite/tests/perf/compiler/T16473.stdout ===================================== @@ -2,10 +2,10 @@ Rule fired: Class op fmap (BUILTIN) Rule fired: Class op liftA2 (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) Rule fired: Class op <*> (BUILTIN) -Rule fired: Class op <$ (BUILTIN) +Rule fired: Class op fmap (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) Rule fired: Class op <*> (BUILTIN) -Rule fired: Class op fmap (BUILTIN) +Rule fired: Class op <$ (BUILTIN) Rule fired: Class op pure (BUILTIN) Rule fired: Class op pure (BUILTIN) Rule fired: Class op >>= (BUILTIN) ===================================== testsuite/tests/simplCore/should_compile/T17901.stdout ===================================== @@ -1,14 +1,6 @@ - (wombat1 [Occ=Once*!] :: T -> p) - A -> wombat1 T17901.A; - B -> wombat1 T17901.B; - C -> wombat1 T17901.C = \ (@p) (wombat1 :: T -> p) (x :: T) -> case x of wild { __DEFAULT -> wombat1 wild } - Tmpl= \ (@p) (wombat2 [Occ=Once!] :: S -> p) (x [Occ=Once] :: S) -> - case x of wild [Occ=Once] { __DEFAULT -> wombat2 wild }}] = \ (@p) (wombat2 :: S -> p) (x :: S) -> case x of wild { __DEFAULT -> wombat2 wild } - Tmpl= \ (@p) (wombat3 [Occ=Once!] :: W -> p) (x [Occ=Once] :: W) -> - case x of wild [Occ=Once] { __DEFAULT -> wombat3 wild }}] = \ (@p) (wombat3 :: W -> p) (x :: W) -> case x of wild { __DEFAULT -> wombat3 wild } ===================================== testsuite/tests/simplCore/should_compile/T17966.stdout ===================================== @@ -1,5 +1,3 @@ RULES: "SPEC $cm @()" [0] RULES: "SPEC f @Bool @() @(Maybe Integer)" [0] -"SPEC/T17966 $fShowMaybe_$cshow @Integer" -"SPEC/T17966 $fShowMaybe_$cshowList @Integer" "SPEC/T17966 $fShowMaybe @Integer" ===================================== testsuite/tests/simplCore/should_compile/T4201.stdout ===================================== @@ -1,3 +1,3 @@ + lift :: Foo -> T [HasNoCafRefs, Arity: 1, Strictness: , - Unfolding: InlineRule (0, True, True) - bof `cast` (Sym (N:Foo[0]) ->_R _R)] + Unfolding: (bof `cast` (Sym (N:Foo[0]) ->_R _R))] ===================================== testsuite/tests/simplCore/should_compile/T5658b.stdout ===================================== @@ -1 +1 @@ -4 +2 ===================================== testsuite/tests/warnings/should_compile/T16282/T16282.stderr ===================================== @@ -6,5 +6,4 @@ T16282.hs: warning: [-Wall-missed-specialisations] T16282.hs: warning: [-Wall-missed-specialisations] Could not specialise imported function ‘Data.Map.Internal.$w$cshowsPrec’ - when specialising ‘Data.Map.Internal.$fShowMap_$cshowsPrec’ Probable fix: add INLINABLE pragma on ‘Data.Map.Internal.$w$cshowsPrec’ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/eb840476520070f0adfcdd44f931ef921ba04f17 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/eb840476520070f0adfcdd44f931ef921ba04f17 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 8 21:58:36 2020 From: gitlab at gitlab.haskell.org (Adam Gundry) Date: Fri, 08 May 2020 17:58:36 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/amg/hasfield-2020 Message-ID: <5eb5d60c7c1fd_6167128409c4963579b@gitlab.haskell.org.mail> Adam Gundry pushed new branch wip/amg/hasfield-2020 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/amg/hasfield-2020 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 9 03:10:53 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 08 May 2020 23:10:53 -0400 Subject: [Git][ghc/ghc][master] 14 commits: Remove further dead code found by a simple Python script. Message-ID: <5eb61f3d94b5c_616711ab08a4966165f@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 6f6d72b2 by Brian Foley at 2020-05-08T15:29:25-04:00 Remove further dead code found by a simple Python script. Avoid removing some functions that are part of an API even though they're not used in-tree at the moment. - - - - - 78bf8bf9 by Julien Debon at 2020-05-08T15:29:28-04:00 Add doc examples for Bifoldable See #17929 - - - - - 66f0a847 by Julien Debon at 2020-05-08T15:29:29-04:00 doc (Bitraversable): Add examples to Bitraversable * Add examples to Data.Bitraversable * Fix formatting for (,) in Bitraversable and Bifoldable * Fix mistake on bimapAccumR documentation See #17929 - - - - - 9749fe12 by Baldur Blöndal at 2020-05-08T15:29:32-04:00 Specify kind variables for inferred kinds in base. - - - - - 4e9aef9e by John Ericson at 2020-05-08T15:29:36-04:00 HsSigWcTypeScoping: Pull in documentation from stray location - - - - - f4d5c6df by John Ericson at 2020-05-08T15:29:36-04:00 Rename local `real_fvs` to `implicit_vs` It doesn't make sense to call the "free" variables we are about to implicitly bind the real ones. - - - - - 20570b4b by John Ericson at 2020-05-08T15:29:36-04:00 A few tiny style nits with renaming - Use case rather than guards that repeatedly scrutenize same thing. - No need for view pattern when `L` is fine. - Use type synnonym to convey the intent like elsewhere. - - - - - 09ac8de5 by John Ericson at 2020-05-08T15:29:36-04:00 Add `forAllOrNothing` function with note - - - - - bb35c0e5 by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Document lawlessness of Ap's Num instance - - - - - cdd229ff by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply suggestion to libraries/base/Data/Monoid.hs - - - - - 926d2aab by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply more suggestions from Simon Jakobi - - - - - 7a763cff by Adam Gundry at 2020-05-08T15:29:41-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. - - - - - 88e3c815 by Simon Peyton Jones at 2020-05-08T15:29:41-04:00 Fix specialisation for DFuns When specialising a DFun we must take care to saturate the unfolding. See Note [Specialising DFuns] in Specialise. Fixes #18120 - - - - - 86c77b36 by Greg Steuck at 2020-05-08T15:29:45-04:00 Remove unused SEGMENT_PROT_RWX It's been unused for a year and is problematic on any OS which requires W^X for security. - - - - - 30 changed files: - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/PPC/Cond.hs - compiler/GHC/CmmToAsm/SPARC/Cond.hs - compiler/GHC/CmmToAsm/X86/Cond.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/Plugins.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/StgToCmm/Utils.hs - compiler/GHC/SysTools/Tasks.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Types/Evidence.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Tc/Validity.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/Name/Reader.hs - compiler/GHC/Types/Var/Env.hs - compiler/GHC/Utils/Misc.hs - libraries/base/Control/Arrow.hs - libraries/base/Control/Category.hs - libraries/base/Data/Bifoldable.hs - libraries/base/Data/Bitraversable.hs - libraries/base/Data/Data.hs - libraries/base/Data/Dynamic.hs - libraries/base/Data/Fixed.hs - libraries/base/Data/Functor/Compose.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9afd92512b41cf6c6de3a17b474d8d4bb01158c3...86c77b36628dcce7bc9b066fc24c8c521fecc3ee -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9afd92512b41cf6c6de3a17b474d8d4bb01158c3...86c77b36628dcce7bc9b066fc24c8c521fecc3ee You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 9 11:35:13 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Sat, 09 May 2020 07:35:13 -0400 Subject: [Git][ghc/ghc][wip/T16762-chunks-2-and-3] 25 commits: Refactor hole constraints. Message-ID: <5eb695715a909_61671341e9449701463@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T16762-chunks-2-and-3 at Glasgow Haskell Compiler / GHC Commits: 7ab6ab09 by Richard Eisenberg at 2020-05-06T04:39:32-04:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG ------------------------- - - - - - 420b957d by Ben Gamari at 2020-05-06T04:40:08-04:00 rts: Zero block flags with -DZ Block flags are very useful for determining the state of a block. However, some block allocator users don't touch them, leading to misleading values. Ensure that we zero then when zero-on-gc is set. This is safe and makes the flags more useful during debugging. - - - - - 740b3b8d by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix incorrect failed_to_evac value during deadlock gc Previously we would incorrectly set the failed_to_evac flag if we evacuated a value due to a deadlock GC. This would cause us to mark more things as dirty than strictly necessary. It also turned up a nasty but which I will fix next. - - - - - b2d72c75 by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - 9f3e6884 by Zubin Duggal at 2020-05-06T04:41:08-04:00 Allow atomic update of NameCache in readHieFile The situation arises in ghcide where multiple different threads may need to update the name cache, therefore with the older interface it could happen that you start reading a hie file with name cache A and produce name cache A + B, but another thread in the meantime updated the namecache to A + C. Therefore if you write the new namecache you will lose the A' updates from the second thread. Updates haddock submodule - - - - - edec6a6c by Ryan Scott at 2020-05-06T04:41:57-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _)`. Fixes #18127. - - - - - a95e7fe0 by Ömer Sinan Ağacan at 2020-05-06T04:42:39-04:00 ELF linker: increment curSymbol after filling in fields of current entry The bug was introduced in a8b7cef4d45 which added a field to the `symbols` array elements and then updated this code incorrectly: - oc->symbols[curSymbol++] = nm; + oc->symbols[curSymbol++].name = nm; + oc->symbols[curSymbol].addr = symbol->addr; - - - - - cab1871a by Sylvain Henry at 2020-05-06T04:43:21-04:00 Move LeadingUnderscore into Platform (#17957) Avoid direct use of DynFlags to know if symbols must be prefixed by an underscore. - - - - - 94e7c563 by Sylvain Henry at 2020-05-06T04:43:21-04:00 Don't use DynFlags in showLinkerState (#17957) - - - - - 9afd9251 by Ryan Scott at 2020-05-06T04:43:58-04:00 Refactoring: Use bindSigTyVarsFV in rnMethodBinds `rnMethodBinds` was explicitly using `xoptM` to determine if `ScopedTypeVariables` is enabled before bringing type variables bound by the class/instance header into scope. However, this `xoptM` logic is already performed by the `bindSigTyVarsFV` function. This patch uses `bindSigTyVarsFV` in `rnMethodBinds` to reduce the number of places where we need to consult if `ScopedTypeVariables` is on. This is purely refactoring, and there should be no user-visible change in behavior. - - - - - 6f6d72b2 by Brian Foley at 2020-05-08T15:29:25-04:00 Remove further dead code found by a simple Python script. Avoid removing some functions that are part of an API even though they're not used in-tree at the moment. - - - - - 78bf8bf9 by Julien Debon at 2020-05-08T15:29:28-04:00 Add doc examples for Bifoldable See #17929 - - - - - 66f0a847 by Julien Debon at 2020-05-08T15:29:29-04:00 doc (Bitraversable): Add examples to Bitraversable * Add examples to Data.Bitraversable * Fix formatting for (,) in Bitraversable and Bifoldable * Fix mistake on bimapAccumR documentation See #17929 - - - - - 9749fe12 by Baldur Blöndal at 2020-05-08T15:29:32-04:00 Specify kind variables for inferred kinds in base. - - - - - 4e9aef9e by John Ericson at 2020-05-08T15:29:36-04:00 HsSigWcTypeScoping: Pull in documentation from stray location - - - - - f4d5c6df by John Ericson at 2020-05-08T15:29:36-04:00 Rename local `real_fvs` to `implicit_vs` It doesn't make sense to call the "free" variables we are about to implicitly bind the real ones. - - - - - 20570b4b by John Ericson at 2020-05-08T15:29:36-04:00 A few tiny style nits with renaming - Use case rather than guards that repeatedly scrutenize same thing. - No need for view pattern when `L` is fine. - Use type synnonym to convey the intent like elsewhere. - - - - - 09ac8de5 by John Ericson at 2020-05-08T15:29:36-04:00 Add `forAllOrNothing` function with note - - - - - bb35c0e5 by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Document lawlessness of Ap's Num instance - - - - - cdd229ff by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply suggestion to libraries/base/Data/Monoid.hs - - - - - 926d2aab by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply more suggestions from Simon Jakobi - - - - - 7a763cff by Adam Gundry at 2020-05-08T15:29:41-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. - - - - - 88e3c815 by Simon Peyton Jones at 2020-05-08T15:29:41-04:00 Fix specialisation for DFuns When specialising a DFun we must take care to saturate the unfolding. See Note [Specialising DFuns] in Specialise. Fixes #18120 - - - - - 86c77b36 by Greg Steuck at 2020-05-08T15:29:45-04:00 Remove unused SEGMENT_PROT_RWX It's been unused for a year and is problematic on any OS which requires W^X for security. - - - - - 2c845e85 by Ryan Scott at 2020-05-09T07:34:53-04:00 WIP: Factor out HsPatSigType for pat sigs/RULE term sigs (#16762) This implements chunks (2) and (3) of https://gitlab.haskell.org/ghc/ghc/issues/16762#note_270170. Namely, it introduces a dedicated `HsPatSigType` AST type, which represents the types that can appear in pattern signatures and term-level `RULE` binders. Previously, these were represented with `LHsSigWcType`. Although `LHsSigWcType` is isomorphic to `HsPatSigType`, the intended semantics of the two types are slightly different, as evidenced by the fact that they have different code paths in the renamer and typechecker. See also the new `Note [Pattern signature binders and scoping]` in `GHC.Hs.Types`. - - - - - 30 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/PPC/Cond.hs - compiler/GHC/CmmToAsm/SPARC/Cond.hs - compiler/GHC/CmmToAsm/X86/Cond.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Extension.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Types.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Plugins.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Runtime/Linker.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/af9b43409fc2e65d6a7fdd9b95c484ab9cb0a9de...2c845e8579d22f4d6aed8a8eb8e22e4f1ed5ec28 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/af9b43409fc2e65d6a7fdd9b95c484ab9cb0a9de...2c845e8579d22f4d6aed8a8eb8e22e4f1ed5ec28 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 9 17:03:44 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 09 May 2020 13:03:44 -0400 Subject: [Git][ghc/ghc] Deleted branch wip/marge_bot_batch_merge_job Message-ID: <5eb6e2707e284_61673f81cd4c695c97782e3@gitlab.haskell.org.mail> Ben Gamari deleted branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 9 17:03:49 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 09 May 2020 13:03:49 -0400 Subject: [Git][ghc/ghc][master] 3 commits: Add test for #16167 Message-ID: <5eb6e275a24e4_61673f819ac1caa49778437@gitlab.haskell.org.mail> Ben Gamari pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 9d97f4b5 by nineonine at 2020-05-08T15:30:03-04:00 Add test for #16167 - - - - - aa318338 by Ryan Scott at 2020-05-08T15:30:04-04:00 Bump exceptions submodule so that dist-boot is .gitignore'd `exceptions` is a stage-0 boot library as of commit 30272412fa437ab8e7a8035db94a278e10513413, which means that building `exceptions` in a GHC tree will generate a `dist-boot` directory. However, this directory was not specified in `exceptions`' `.gitignore` file, which causes it to dirty up the current `git` working directory. Accordingly, this bumps the `exceptions` submodule to commit ghc/packages/exceptions at 23c0b8a50d7592af37ca09beeec16b93080df98f, which adds `dist-boot` to the `.gitignore` file. - - - - - ea86360f by Ömer Sinan Ağacan at 2020-05-08T15:30:30-04:00 Linker.c: initialize n_symbols of ObjectCode with other fields - - - - - 5 changed files: - libraries/exceptions - rts/Linker.c - + testsuite/tests/driver/T16167.hs - + testsuite/tests/driver/T16167.stdout - testsuite/tests/driver/all.T Changes: ===================================== libraries/exceptions ===================================== @@ -1 +1 @@ -Subproject commit fe4166f8d23d8288ef2cbbf9e36118b6b99e0d7d +Subproject commit 23c0b8a50d7592af37ca09beeec16b93080df98f ===================================== rts/Linker.c ===================================== @@ -1326,6 +1326,7 @@ mkOc( pathchar *path, char *image, int imageSize, setOcInitialStatus( oc ); oc->fileSize = imageSize; + oc->n_symbols = 0; oc->symbols = NULL; oc->n_sections = 0; oc->sections = NULL; ===================================== testsuite/tests/driver/T16167.hs ===================================== @@ -0,0 +1 @@ +module f ===================================== testsuite/tests/driver/T16167.stdout ===================================== @@ -0,0 +1 @@ +{"span": {"file": "T16167.hs","startLine": 1,"startCol": 8,"endLine": 1,"endCol": 9},"doc": "parse error on input \u2018f\u2019","severity": "SevError","reason": null} ===================================== testsuite/tests/driver/all.T ===================================== @@ -261,6 +261,8 @@ test('T12955', normal, makefile_test, []) test('T12971', [when(opsys('mingw32'), expect_broken(17945)), ignore_stdout], makefile_test, []) test('json', normal, compile_fail, ['-ddump-json']) test('json2', normalise_version('base','ghc-prim'), compile, ['-ddump-types -ddump-json']) +test('T16167', exit_code(1), run_command, + ['{compiler} -x hs -e ":set prog T16167.hs" -ddump-json T16167.hs']) test('T13604', [], makefile_test, []) test('T13604a', [], makefile_test, []) # omitting hpc and profasm because they affect the View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/86c77b36628dcce7bc9b066fc24c8c521fecc3ee...ea86360f21e8c9812acba8dc1bc2a54fef700ece -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/86c77b36628dcce7bc9b066fc24c8c521fecc3ee...ea86360f21e8c9812acba8dc1bc2a54fef700ece You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 9 17:06:21 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 09 May 2020 13:06:21 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/marge_bot_batch_merge_job Message-ID: <5eb6e30d86de2_61673f819ac1caa497903c3@gitlab.haskell.org.mail> Marge Bot pushed new branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/marge_bot_batch_merge_job You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 9 17:15:32 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 09 May 2020 13:15:32 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18074 Message-ID: <5eb6e53418f47_61673f81cd4c695c979415@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/T18074 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18074 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 9 18:04:49 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 09 May 2020 14:04:49 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18101 Message-ID: <5eb6f0c1b219a_6167ca4afa498033d9@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/T18101 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18101 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 9 18:09:28 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 09 May 2020 14:09:28 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18166 Message-ID: <5eb6f1d827007_6167128560089803518@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/T18166 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18166 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 9 18:26:30 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 09 May 2020 14:26:30 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18151 Message-ID: <5eb6f5d66175a_6167128409c4980757b@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/T18151 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18151 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 9 18:27:05 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 09 May 2020 14:27:05 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18156 Message-ID: <5eb6f5f9e1735_61673f81cc913ba09809167@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/T18156 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18156 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 9 18:32:04 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 09 May 2020 14:32:04 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18135 Message-ID: <5eb6f72469519_616712856008981245e@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/T18135 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18135 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 9 18:45:49 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 09 May 2020 14:45:49 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18167 Message-ID: <5eb6fa5dee757_616711ab08a4981856e@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/T18167 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18167 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 9 18:50:40 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 09 May 2020 14:50:40 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18129 Message-ID: <5eb6fb80a54a8_616712856008982923d@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/T18129 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18129 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 9 19:02:49 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 09 May 2020 15:02:49 -0400 Subject: [Git][ghc/ghc] Deleted branch wip/T18156 Message-ID: <5eb6fe59e0853_61673f81a29c63b09852566@gitlab.haskell.org.mail> Ben Gamari deleted branch wip/T18156 at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 9 19:28:11 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 09 May 2020 15:28:11 -0400 Subject: [Git][ghc/ghc][wip/T18141] 49 commits: nonmoving: Clear bitmap after initializing block size Message-ID: <5eb7044bf3ae5_6167119f856098582cd@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18141 at Glasgow Haskell Compiler / GHC Commits: 2aa67611 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - 54dad3cf by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - 99ff8145 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 05b0a9fd by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 Remove OneShotInfo field of LFReEntrant, document OneShotInfo The field is only used in withNewTickyCounterFun and it's easier to directly pass a parameter for one-shot info to withNewTickyCounterFun instead of passing it via LFReEntrant. This also makes !2842 simpler. Other changes: - New Note (by SPJ) [OneShotInfo overview] added. - Arity argument of thunkCode removed as it's always 0. - - - - - a43620c6 by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 GHC.StgToCmm.Ticky: remove a few unused stuff - - - - - 780de9e1 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Use platform in Iface Binary - - - - - f8386c7b by Sylvain Henry at 2020-05-01T10:37:39-04:00 Refactor PprDebug handling If `-dppr-debug` is set, then PprUser and PprDump styles are silently replaced with PprDebug style. This was done in `mkUserStyle` and `mkDumpStyle` smart constructors. As a consequence they needed a DynFlags parameter. Now we keep the original PprUser and PprDump styles until they are used to create an `SDocContext`. I.e. the substitution is only performed in `initSDocContext`. - - - - - b3df9e78 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Remove PprStyle param of logging actions Use `withPprStyle` instead to apply a specific style to a SDoc. - - - - - de9fc995 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Fully remove PprDebug PprDebug was a pain to deal with consistently as it is implied by `-dppr-debug` but it isn't really a PprStyle. We remove it completely and query the appropriate SDoc flag instead (`sdocPprDebug`) via helpers (`getPprDebug` and its friends). - - - - - 8b51fcbd by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Only call checkSingle if we would report warnings - - - - - fd7ea0fe by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 7bfe9ac5 by Ben Gamari at 2020-05-03T04:41:33-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. - - - - - c560dd07 by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Move eventlog documentation users guide - - - - - 02543d5e by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Add documentation for non-moving GC events - - - - - b465dd45 by Alexis King at 2020-05-03T04:42:12-04:00 Flatten nested casts in the simple optimizer Normally, we aren’t supposed to generated any nested casts, since mkCast takes care to flatten them, but the simple optimizer didn’t use mkCast, so they could show up after inlining. This isn’t really a problem, since the simplifier will clean them up immediately anyway, but it can clutter the -ddump-ds output, and it’s an extremely easy fix. closes #18112 - - - - - 8bdc03d6 by Simon Peyton Jones at 2020-05-04T01:56:59-04:00 Don't return a panic in tcNestedSplice In GHC.Tc.Gen.Splice.tcNestedSplice we were returning a typechecked expression of "panic". That is usually OK, because the result is discarded. But it happens that tcApp now looks at the typechecked expression, trivially, to ask if it is tagToEnum. So being bottom is bad. Moreover a debug-trace might print it out. So better to return a civilised expression, even though it is usually discarded. - - - - - 0bf640b1 by Baldur Blöndal at 2020-05-04T01:57:36-04:00 Don't require parentheses around via type (`-XDerivingVia'). Fixes #18130". - - - - - 30272412 by Artem Pelenitsyn at 2020-05-04T13:19:59-04:00 Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) - - - - - b9f7c08f by jneira at 2020-05-04T13:20:37-04:00 Remove unused hs-boot file - - - - - 1d8f80cd by Sylvain Henry at 2020-05-05T03:22:46-04:00 Remove references to -package-key * remove references to `-package-key` which has been removed in 2016 (240ddd7c39536776e955e881d709bbb039b48513) * remove support for `-this-package-key` which has been deprecated at the same time - - - - - 7bc3a65b by Sylvain Henry at 2020-05-05T03:23:31-04:00 Remove SpecConstrAnnotation (#13681) This has been deprecated since 2013. Use GHC.Types.SPEC instead. Make GHC.Exts "not-home" for haddock Metric Decrease: haddock.base - - - - - 3c862f63 by DenisFrezzato at 2020-05-05T03:24:15-04:00 Fix Haskell98 short description in documentation - - - - - 2420c555 by Ryan Scott at 2020-05-05T03:24:53-04:00 Add regression tests for #16244, #16245, #16758 Commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70 ended up fixing quite a few bugs: * This commit fixes #16244 completely. A regression test has been added. * This commit fixes one program from #16245. (The program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211369 still panics, and the program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211400 still loops infinitely.) A regression test has been added for this program. * This commit fixes #16758. Accordingly, this patch removes the `expect_broken` label from the `T16758` test case, moves it from `should_compile` to `should_fail` (as it should produce an error message), and checks in the expected stderr. - - - - - 40c71c2c by Sylvain Henry at 2020-05-05T03:25:31-04:00 Fix colorized error messages (#18128) In b3df9e780fb2f5658412c644849cd0f1e6f50331 I broke colorized messages by using "dump" style instead of "user" style. This commits fixes it. - - - - - 7ab6ab09 by Richard Eisenberg at 2020-05-06T04:39:32-04:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG ------------------------- - - - - - 420b957d by Ben Gamari at 2020-05-06T04:40:08-04:00 rts: Zero block flags with -DZ Block flags are very useful for determining the state of a block. However, some block allocator users don't touch them, leading to misleading values. Ensure that we zero then when zero-on-gc is set. This is safe and makes the flags more useful during debugging. - - - - - 740b3b8d by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix incorrect failed_to_evac value during deadlock gc Previously we would incorrectly set the failed_to_evac flag if we evacuated a value due to a deadlock GC. This would cause us to mark more things as dirty than strictly necessary. It also turned up a nasty but which I will fix next. - - - - - b2d72c75 by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - 9f3e6884 by Zubin Duggal at 2020-05-06T04:41:08-04:00 Allow atomic update of NameCache in readHieFile The situation arises in ghcide where multiple different threads may need to update the name cache, therefore with the older interface it could happen that you start reading a hie file with name cache A and produce name cache A + B, but another thread in the meantime updated the namecache to A + C. Therefore if you write the new namecache you will lose the A' updates from the second thread. Updates haddock submodule - - - - - edec6a6c by Ryan Scott at 2020-05-06T04:41:57-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _)`. Fixes #18127. - - - - - a95e7fe0 by Ömer Sinan Ağacan at 2020-05-06T04:42:39-04:00 ELF linker: increment curSymbol after filling in fields of current entry The bug was introduced in a8b7cef4d45 which added a field to the `symbols` array elements and then updated this code incorrectly: - oc->symbols[curSymbol++] = nm; + oc->symbols[curSymbol++].name = nm; + oc->symbols[curSymbol].addr = symbol->addr; - - - - - cab1871a by Sylvain Henry at 2020-05-06T04:43:21-04:00 Move LeadingUnderscore into Platform (#17957) Avoid direct use of DynFlags to know if symbols must be prefixed by an underscore. - - - - - 94e7c563 by Sylvain Henry at 2020-05-06T04:43:21-04:00 Don't use DynFlags in showLinkerState (#17957) - - - - - 9afd9251 by Ryan Scott at 2020-05-06T04:43:58-04:00 Refactoring: Use bindSigTyVarsFV in rnMethodBinds `rnMethodBinds` was explicitly using `xoptM` to determine if `ScopedTypeVariables` is enabled before bringing type variables bound by the class/instance header into scope. However, this `xoptM` logic is already performed by the `bindSigTyVarsFV` function. This patch uses `bindSigTyVarsFV` in `rnMethodBinds` to reduce the number of places where we need to consult if `ScopedTypeVariables` is on. This is purely refactoring, and there should be no user-visible change in behavior. - - - - - 6f6d72b2 by Brian Foley at 2020-05-08T15:29:25-04:00 Remove further dead code found by a simple Python script. Avoid removing some functions that are part of an API even though they're not used in-tree at the moment. - - - - - 78bf8bf9 by Julien Debon at 2020-05-08T15:29:28-04:00 Add doc examples for Bifoldable See #17929 - - - - - 66f0a847 by Julien Debon at 2020-05-08T15:29:29-04:00 doc (Bitraversable): Add examples to Bitraversable * Add examples to Data.Bitraversable * Fix formatting for (,) in Bitraversable and Bifoldable * Fix mistake on bimapAccumR documentation See #17929 - - - - - 9749fe12 by Baldur Blöndal at 2020-05-08T15:29:32-04:00 Specify kind variables for inferred kinds in base. - - - - - 4e9aef9e by John Ericson at 2020-05-08T15:29:36-04:00 HsSigWcTypeScoping: Pull in documentation from stray location - - - - - f4d5c6df by John Ericson at 2020-05-08T15:29:36-04:00 Rename local `real_fvs` to `implicit_vs` It doesn't make sense to call the "free" variables we are about to implicitly bind the real ones. - - - - - 20570b4b by John Ericson at 2020-05-08T15:29:36-04:00 A few tiny style nits with renaming - Use case rather than guards that repeatedly scrutenize same thing. - No need for view pattern when `L` is fine. - Use type synnonym to convey the intent like elsewhere. - - - - - 09ac8de5 by John Ericson at 2020-05-08T15:29:36-04:00 Add `forAllOrNothing` function with note - - - - - bb35c0e5 by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Document lawlessness of Ap's Num instance - - - - - cdd229ff by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply suggestion to libraries/base/Data/Monoid.hs - - - - - 926d2aab by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply more suggestions from Simon Jakobi - - - - - 7a763cff by Adam Gundry at 2020-05-08T15:29:41-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. - - - - - 88e3c815 by Simon Peyton Jones at 2020-05-08T15:29:41-04:00 Fix specialisation for DFuns When specialising a DFun we must take care to saturate the unfolding. See Note [Specialising DFuns] in Specialise. Fixes #18120 - - - - - 86c77b36 by Greg Steuck at 2020-05-08T15:29:45-04:00 Remove unused SEGMENT_PROT_RWX It's been unused for a year and is problematic on any OS which requires W^X for security. - - - - - 202269ec by Ben Gamari at 2020-05-09T15:28:04-04:00 GHC.Cmm.Opt: Handle MO_XX_Conv This MachOp was introduced by 2c959a1894311e59cd2fd469c1967491c1e488f3 but a wildcard match in cmmMachOpFoldM hid the fact that it wasn't handled. Ideally we would eliminate the match but this appears to be a larger task. Fixes #18141. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/PPC/Cond.hs - compiler/GHC/CmmToAsm/SPARC/Cond.hs - compiler/GHC/CmmToAsm/X86/Cond.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Driver.hs - compiler/GHC/Core/Opt/Monad.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Ppr.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/TyCo/Ppr.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Data/IOEnv.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Finder.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Monad.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6f82de4a5df4f14b19595f4996b58c9b901e30fc...202269ec993da375c8daf34d02d80979781a505a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6f82de4a5df4f14b19595f4996b58c9b901e30fc...202269ec993da375c8daf34d02d80979781a505a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 9 19:50:08 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 09 May 2020 15:50:08 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/revert-MR3132 Message-ID: <5eb70970d3956_61673f81a3bd711c986582a@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/revert-MR3132 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/revert-MR3132 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 9 19:50:50 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 09 May 2020 15:50:50 -0400 Subject: [Git][ghc/ghc][wip/revert-MR3132] Revert "Specify kind variables for inferred kinds in base." Message-ID: <5eb7099a7971f_6167119ebbd098660ed@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/revert-MR3132 at Glasgow Haskell Compiler / GHC Commits: c8cf710a by Ben Gamari at 2020-05-09T15:50:28-04:00 Revert "Specify kind variables for inferred kinds in base." As noted in !3132, this has rather severe knock-on consequences in user-code. We'll need to revisit this before merging something along these lines. This reverts commit 9749fe1223d182b1f8e7e4f7378df661c509f396. - - - - - 21 changed files: - libraries/base/Control/Arrow.hs - libraries/base/Control/Category.hs - libraries/base/Data/Data.hs - libraries/base/Data/Dynamic.hs - libraries/base/Data/Fixed.hs - libraries/base/Data/Functor/Compose.hs - libraries/base/Data/Functor/Const.hs - libraries/base/Data/Functor/Product.hs - libraries/base/Data/Functor/Sum.hs - libraries/base/Data/Type/Coercion.hs - libraries/base/Data/Type/Equality.hs - libraries/base/GHC/Generics.hs - libraries/base/changelog.md - libraries/ghc-prim/GHC/Types.hs - testsuite/tests/dependent/should_fail/T11334b.stderr - testsuite/tests/deriving/should_compile/T14578.stderr - testsuite/tests/generics/T10604/T10604_deriving.stderr - testsuite/tests/ghci/scripts/T12550.stdout - testsuite/tests/partial-sigs/should_compile/T15039b.stderr - testsuite/tests/partial-sigs/should_compile/T15039d.stderr - testsuite/tests/typecheck/should_fail/T10285.stderr Changes: ===================================== libraries/base/Control/Arrow.hs ===================================== @@ -1,8 +1,8 @@ +{-# LANGUAGE Trustworthy #-} +{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveGeneric #-} -{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE StandaloneDeriving #-} -{-# LANGUAGE Trustworthy #-} {-# OPTIONS_GHC -Wno-inline-rule-shadowing #-} -- The RULES for the methods of class Arrow may never fire -- e.g. compose/arr; see #10528 ===================================== libraries/base/Control/Category.hs ===================================== @@ -1,7 +1,7 @@ +{-# LANGUAGE Trustworthy #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE PolyKinds #-} -{-# LANGUAGE Trustworthy #-} {-# OPTIONS_GHC -Wno-inline-rule-shadowing #-} -- The RULES for the methods of class Category may never fire -- e.g. identity/left, identity/right, association; see #10528 @@ -20,7 +20,7 @@ module Control.Category where -import qualified GHC.Base (id, (.)) +import qualified GHC.Base (id,(.)) import Data.Type.Coercion import Data.Type.Equality import Data.Coerce (coerce) ===================================== libraries/base/Data/Data.hs ===================================== @@ -1,10 +1,10 @@ {-# LANGUAGE BangPatterns #-} -{-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE DataKinds #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} ===================================== libraries/base/Data/Dynamic.hs ===================================== @@ -1,9 +1,9 @@ -{-# LANGUAGE ExplicitForAll #-} -{-# LANGUAGE GADTs #-} +{-# LANGUAGE Trustworthy #-} {-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE ExplicitForAll #-} {-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE Trustworthy #-} {-# LANGUAGE TypeApplications #-} ----------------------------------------------------------------------------- ===================================== libraries/base/Data/Fixed.hs ===================================== @@ -1,9 +1,7 @@ -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE PolyKinds #-} -{-# LANGUAGE RankNTypes #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE StandaloneKindSignatures #-} {-# LANGUAGE Trustworthy #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE FlexibleInstances #-} ----------------------------------------------------------------------------- -- | @@ -43,7 +41,6 @@ module Data.Fixed import Data.Data import GHC.TypeLits (KnownNat, natVal) import GHC.Read -import Data.Kind (Type, Constraint) import Text.ParserCombinators.ReadPrec import Text.Read.Lex @@ -64,8 +61,7 @@ mod' n d = n - (fromInteger f) * d where f = div' n d -- | The type parameter should be an instance of 'HasResolution'. -type Fixed :: forall k. k -> Type -newtype Fixed a = MkFixed Integer +newtype Fixed (a :: k) = MkFixed Integer deriving ( Eq -- ^ @since 2.01 , Ord -- ^ @since 2.01 ) @@ -84,8 +80,7 @@ instance (Typeable k,Typeable a) => Data (Fixed (a :: k)) where dataTypeOf _ = tyFixed toConstr _ = conMkFixed -type HasResolution :: forall k. k -> Constraint -class HasResolution a where +class HasResolution (a :: k) where resolution :: p a -> Integer -- | For example, @Fixed 1000@ will give you a 'Fixed' with a resolution of 1000. ===================================== libraries/base/Data/Functor/Compose.hs ===================================== @@ -3,7 +3,6 @@ {-# LANGUAGE GADTs #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE StandaloneKindSignatures #-} {-# LANGUAGE Trustworthy #-} {-# LANGUAGE TypeOperators #-} ----------------------------------------------------------------------------- @@ -27,7 +26,6 @@ module Data.Functor.Compose ( import Data.Functor.Classes -import Data.Kind (Type) import Control.Applicative import Data.Coerce (coerce) import Data.Data (Data) @@ -40,9 +38,6 @@ infixr 9 `Compose` -- | Right-to-left composition of functors. -- The composition of applicative functors is always applicative, -- but the composition of monads is not always a monad. --- --- Kinds `k2` and `k1` explicitly quantified since 4.15.0.0. -type Compose :: forall k2 k1. (k2 -> Type) -> (k1 -> k2) -> (k1 -> Type) newtype Compose f g a = Compose { getCompose :: f (g a) } deriving ( Data -- ^ @since 4.9.0.0 , Generic -- ^ @since 4.9.0.0 @@ -131,7 +126,7 @@ instance (Alternative f, Applicative g) => Alternative (Compose f g) where -- | The deduction (via generativity) that if @g x :~: g y@ then @x :~: y at . -- -- @since 4.14.0.0 -instance TestEquality f => TestEquality (Compose f g) where +instance (TestEquality f) => TestEquality (Compose f g) where testEquality (Compose x) (Compose y) = case testEquality x y of -- :: Maybe (g x :~: g y) Just Refl -> Just Refl -- :: Maybe (x :~: y) ===================================== libraries/base/Data/Functor/Const.hs ===================================== @@ -2,9 +2,7 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE PolyKinds #-} -{-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE StandaloneKindSignatures #-} {-# LANGUAGE Trustworthy #-} ----------------------------------------------------------------------------- @@ -38,9 +36,6 @@ import GHC.Read (Read(readsPrec), readParen, lex) import GHC.Show (Show(showsPrec), showParen, showString) -- | The 'Const' functor. --- --- Kind `k` explicitly quantified since 4.15.0.0. -type Const :: forall k. Type -> k -> Type newtype Const a b = Const { getConst :: a } deriving ( Bits -- ^ @since 4.9.0.0 , Bounded -- ^ @since 4.9.0.0 ===================================== libraries/base/Data/Functor/Product.hs ===================================== @@ -1,9 +1,7 @@ {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE PolyKinds #-} -{-# LANGUAGE RankNTypes #-} {-# LANGUAGE Safe #-} -{-# LANGUAGE StandaloneKindSignatures #-} ----------------------------------------------------------------------------- -- | -- Module : Data.Functor.Product @@ -28,15 +26,11 @@ import Control.Monad (MonadPlus(..)) import Control.Monad.Fix (MonadFix(..)) import Control.Monad.Zip (MonadZip(mzipWith)) import Data.Data (Data) -import Data.Kind (Type) import Data.Functor.Classes import GHC.Generics (Generic, Generic1) import Text.Read (Read(..), readListDefault, readListPrecDefault) -- | Lifted product of functors. --- --- Kind `k` explicitly quantified since 4.15.0.0. -type Product :: forall k. (k -> Type) -> (k -> Type) -> (k -> Type) data Product f g a = Pair (f a) (g a) deriving ( Data -- ^ @since 4.9.0.0 , Generic -- ^ @since 4.9.0.0 ===================================== libraries/base/Data/Functor/Sum.hs ===================================== @@ -1,9 +1,7 @@ {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE PolyKinds #-} -{-# LANGUAGE RankNTypes #-} {-# LANGUAGE Safe #-} -{-# LANGUAGE StandaloneKindSignatures #-} ----------------------------------------------------------------------------- -- | -- Module : Data.Functor.Sum @@ -25,15 +23,11 @@ module Data.Functor.Sum ( import Control.Applicative ((<|>)) import Data.Data (Data) -import Data.Kind (Type) import Data.Functor.Classes import GHC.Generics (Generic, Generic1) import Text.Read (Read(..), readListDefault, readListPrecDefault) -- | Lifted sum of functors. --- --- Kind `k` explicitly quantified since 4.15.0.0. -type Sum :: forall k. (k -> Type) -> (k -> Type) -> (k -> Type) data Sum f g a = InL (f a) | InR (g a) deriving ( Data -- ^ @since 4.9.0.0 , Generic -- ^ @since 4.9.0.0 ===================================== libraries/base/Data/Type/Coercion.hs ===================================== @@ -1,16 +1,14 @@ -{-# LANGUAGE DeriveGeneric #-} -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE GADTs #-} -{-# LANGUAGE MagicHash #-} -{-# LANGUAGE NoImplicitPrelude #-} -{-# LANGUAGE PolyKinds #-} -{-# LANGUAGE RankNTypes #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE StandaloneDeriving #-} -{-# LANGUAGE StandaloneKindSignatures #-} -{-# LANGUAGE TypeApplications #-} -{-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE TypeOperators #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE TypeOperators #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE StandaloneDeriving #-} +{-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE MagicHash #-} ----------------------------------------------------------------------------- -- | @@ -49,10 +47,9 @@ import GHC.Base -- To use this equality in practice, pattern-match on the @Coercion a b@ to get out -- the @Coercible a b@ instance, and then use 'coerce' to apply it. -- --- @since 4.7.0.0. Kind `k` explicitly quantified since 4.15.0.0. -type Coercion :: forall k. k -> k -> Type +-- @since 4.7.0.0 data Coercion a b where - Coercion :: Coercible @k a b => Coercion @k a b + Coercion :: Coercible a b => Coercion a b -- with credit to Conal Elliott for 'ty', Erik Hesselink & Martijn van -- Steenbergen for 'type-equality', Edward Kmett for 'eq', and Gabor Greif @@ -81,13 +78,13 @@ repr :: (a Eq.:~: b) -> Coercion a b repr Eq.Refl = Coercion -- | @since 4.7.0.0 -deriving instance Eq (Coercion a b) +deriving instance Eq (Coercion a b) -- | @since 4.7.0.0 deriving instance Show (Coercion a b) -- | @since 4.7.0.0 -deriving instance Ord (Coercion a b) +deriving instance Ord (Coercion a b) -- | @since 4.7.0.0 deriving instance Coercible a b => Read (Coercion a b) @@ -105,13 +102,9 @@ deriving instance Coercible a b => Bounded (Coercion a b) -- | This class contains types where you can learn the equality of two types -- from information contained in /terms/. Typically, only singleton types should -- inhabit this class. --- --- Kind `k` explicitly quantified since 4.15.0.0. -type TestCoercion :: forall k. (k -> Type) -> Constraint -class TestCoercion (f :: k -> Type) where +class TestCoercion f where -- | Conditionally prove the representational equality of @a@ and @b at . - testCoercion :: forall (a :: k) (b :: k). - f a -> f b -> Maybe (Coercion @k a b) + testCoercion :: f a -> f b -> Maybe (Coercion a b) -- | @since 4.7.0.0 instance TestCoercion ((Eq.:~:) a) where ===================================== libraries/base/Data/Type/Equality.hs ===================================== @@ -1,20 +1,19 @@ -{-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveGeneric #-} -{-# LANGUAGE ExplicitNamespaces #-} -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE FunctionalDependencies #-} +{-# LANGUAGE TypeOperators #-} {-# LANGUAGE GADTs #-} -{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE NoImplicitPrelude #-} -{-# LANGUAGE PolyKinds #-} {-# LANGUAGE RankNTypes #-} -{-# LANGUAGE StandaloneDeriving #-} -{-# LANGUAGE StandaloneKindSignatures #-} -{-# LANGUAGE Trustworthy #-} -{-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE ExplicitNamespaces #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE FunctionalDependencies #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE StandaloneKindSignatures #-} +{-# LANGUAGE Trustworthy #-} ----------------------------------------------------------------------------- -- | @@ -62,8 +61,7 @@ infix 4 :~:, :~~: -- in practice, pattern-match on the @a :~: b@ to get out the @Refl@ constructor; -- in the body of the pattern-match, the compiler knows that @a ~ b at . -- --- @since 4.7.0.0. Kind `k` explicitly quantified since 4.15.0.0. -type (:~:) :: forall k. k -> k -> Type +-- @since 4.7.0.0 data a :~: b where -- See Note [The equality types story] in GHC.Builtin.Types.Prim Refl :: a :~: a @@ -124,9 +122,8 @@ deriving instance a ~ b => Bounded (a :~: b) -- | Kind heterogeneous propositional equality. Like ':~:', @a :~~: b@ is -- inhabited by a terminating value if and only if @a@ is the same type as @b at . -- --- @since 4.10.0.0. Kinds `k1` and `k2` explicitly quantified since --- 4.15.0.0. -type (:~~:) :: forall k1 k2. k1 -> k2 -> Type +-- @since 4.10.0.0 +type (:~~:) :: k1 -> k2 -> Type data a :~~: b where HRefl :: a :~~: a @@ -153,9 +150,6 @@ deriving instance a ~~ b => Bounded (a :~~: b) -- | This class contains types where you can learn the equality of two types -- from information contained in /terms/. Typically, only singleton types should -- inhabit this class. --- --- Kind `k` explicitly quantified since 4.15.0.0. -type TestEquality :: forall k. (k -> Type) -> Constraint class TestEquality f where -- | Conditionally prove the equality of @a@ and @b at . testEquality :: f a -> f b -> Maybe (a :~: b) @@ -171,7 +165,7 @@ instance TestEquality ((:~~:) a) where infix 4 == -- | A type family to compute Boolean equality. -type (==) :: forall k. k -> k -> Bool +type (==) :: k -> k -> Bool type family a == b where f a == g b = f == g && a == b a == a = 'True ===================================== libraries/base/GHC/Generics.hs ===================================== @@ -11,10 +11,8 @@ {-# LANGUAGE MagicHash #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE PolyKinds #-} -{-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE StandaloneDeriving #-} -{-# LANGUAGE StandaloneKindSignatures #-} {-# LANGUAGE Trustworthy #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} @@ -756,8 +754,7 @@ import GHC.TypeLits ( KnownSymbol, KnownNat, symbolVal, natVal ) -------------------------------------------------------------------------------- -- | Void: used for datatypes without constructors -type V1 :: forall k. k -> Type -data V1 a +data V1 (p :: k) deriving ( Eq -- ^ @since 4.9.0.0 , Ord -- ^ @since 4.9.0.0 , Read -- ^ @since 4.9.0.0 @@ -772,8 +769,7 @@ instance Semigroup (V1 p) where v <> _ = v -- | Unit: used for constructors without arguments -type U1 :: forall k. k -> Type -data U1 a = U1 +data U1 (p :: k) = U1 deriving ( Generic -- ^ @since 4.7.0.0 , Generic1 -- ^ @since 4.9.0.0 ) @@ -824,8 +820,7 @@ instance Monoid (U1 p) where mempty = U1 -- | Used for marking occurrences of the parameter -type Par1 :: Type -> Type -newtype Par1 a = Par1 { unPar1 :: a } +newtype Par1 p = Par1 { unPar1 :: p } deriving ( Eq -- ^ @since 4.7.0.0 , Ord -- ^ @since 4.7.0.0 , Read -- ^ @since 4.7.0.0 @@ -853,8 +848,7 @@ deriving instance Monoid p => Monoid (Par1 p) -- | Recursive calls of kind @* -> *@ (or kind @k -> *@, when @PolyKinds@ -- is enabled) -type Rec1 :: forall k. (k -> Type) -> (k -> Type) -newtype Rec1 f a = Rec1 { unRec1 :: f a } +newtype Rec1 (f :: k -> Type) (p :: k) = Rec1 { unRec1 :: f p } deriving ( Eq -- ^ @since 4.7.0.0 , Ord -- ^ @since 4.7.0.0 , Read -- ^ @since 4.7.0.0 @@ -884,8 +878,7 @@ deriving instance Semigroup (f p) => Semigroup (Rec1 f p) deriving instance Monoid (f p) => Monoid (Rec1 f p) -- | Constants, additional parameters and recursion of kind @*@ -type K1 :: forall k. Type -> Type -> k -> Type -newtype K1 i a b = K1 { unK1 :: a } +newtype K1 (i :: Type) c (p :: k) = K1 { unK1 :: c } deriving ( Eq -- ^ @since 4.7.0.0 , Ord -- ^ @since 4.7.0.0 , Read -- ^ @since 4.7.0.0 @@ -926,9 +919,8 @@ deriving instance Semigroup (f p) => Semigroup (M1 i c f p) deriving instance Monoid (f p) => Monoid (M1 i c f p) -- | Meta-information (constructor names, etc.) -type M1 :: forall k. Type -> Meta -> (k -> Type) -> (k -> Type) -newtype M1 i meta f a = - M1 { unM1 :: f a } +newtype M1 (i :: Type) (c :: Meta) (f :: k -> Type) (p :: k) = + M1 { unM1 :: f p } deriving ( Eq -- ^ @since 4.7.0.0 , Ord -- ^ @since 4.7.0.0 , Read -- ^ @since 4.7.0.0 @@ -940,8 +932,7 @@ newtype M1 i meta f a = -- | Sums: encode choice between constructors infixr 5 :+: -type (:+:) :: forall k. (k -> Type) -> (k -> Type) -> (k -> Type) -data (f :+: g) a = L1 (f a) | R1 (g a) +data (:+:) (f :: k -> Type) (g :: k -> Type) (p :: k) = L1 (f p) | R1 (g p) deriving ( Eq -- ^ @since 4.7.0.0 , Ord -- ^ @since 4.7.0.0 , Read -- ^ @since 4.7.0.0 @@ -953,8 +944,7 @@ data (f :+: g) a = L1 (f a) | R1 (g a) -- | Products: encode multiple arguments to constructors infixr 6 :*: -type (:*:) :: forall k. (k -> Type) -> (k -> Type) -> (k -> Type) -data (f :*: g) a = f a :*: g a +data (:*:) (f :: k -> Type) (g :: k -> Type) (p :: k) = f p :*: g p deriving ( Eq -- ^ @since 4.7.0.0 , Ord -- ^ @since 4.7.0.0 , Read -- ^ @since 4.7.0.0 @@ -995,9 +985,8 @@ instance (Monoid (f p), Monoid (g p)) => Monoid ((f :*: g) p) where -- | Composition of functors infixr 7 :.: -type (:.:) :: forall k2 k1. (k2 -> Type) -> (k1 -> k2) -> (k1 -> Type) -newtype (f :.: g) a = - Comp1 { unComp1 :: f (g a) } +newtype (:.:) (f :: k2 -> Type) (g :: k1 -> k2) (p :: k1) = + Comp1 { unComp1 :: f (g p) } deriving ( Eq -- ^ @since 4.7.0.0 , Ord -- ^ @since 4.7.0.0 , Read -- ^ @since 4.7.0.0 @@ -1028,7 +1017,6 @@ deriving instance Monoid (f (g p)) => Monoid ((f :.: g) p) -- | Constants of unlifted kinds -- -- @since 4.9.0.0 -type URec :: forall k. Type -> k -> Type data family URec (a :: Type) (p :: k) -- | Used for marking occurrences of 'Addr#' @@ -1102,46 +1090,37 @@ data instance URec Word (p :: k) = UWord { uWord# :: Word# } -- | Type synonym for @'URec' 'Addr#'@ -- --- @since 4.9.0.0. Kind `k` explicitly quantified since 4.15.0.0. -type UAddr :: forall k. k -> Type -type UAddr = URec (Ptr ()) +-- @since 4.9.0.0 +type UAddr = URec (Ptr ()) -- | Type synonym for @'URec' 'Char#'@ -- --- @since 4.9.0.0. Kind `k` explicitly quantified since 4.15.0.0. -type UChar :: forall k. k -> Type -type UChar = URec Char +-- @since 4.9.0.0 +type UChar = URec Char -- | Type synonym for @'URec' 'Double#'@ -- --- @since 4.9.0.0. Kind `k` explicitly quantified since 4.15.0.0. -type UDouble :: forall k. k -> Type +-- @since 4.9.0.0 type UDouble = URec Double -- | Type synonym for @'URec' 'Float#'@ -- --- @since 4.9.0.0. Kind `k` explicitly quantified since 4.15.0.0. -type UFloat :: forall k. k -> Type -type UFloat = URec Float +-- @since 4.9.0.0 +type UFloat = URec Float -- | Type synonym for @'URec' 'Int#'@ -- --- @since 4.9.0.0. Kind `k` explicitly quantified since 4.15.0.0. -type UInt :: forall k. k -> Type -type UInt = URec Int +-- @since 4.9.0.0 +type UInt = URec Int -- | Type synonym for @'URec' 'Word#'@ -- --- @since 4.9.0.0. Kind `k` explicitly quantified since 4.15.0.0. -type UWord :: forall k. k -> Type -type UWord = URec Word +-- @since 4.9.0.0 +type UWord = URec Word -- | Tag for K1: recursion (of kind @Type@) data R -- | Type synonym for encoding recursion (of kind @Type@) --- --- Kind `k` explicitly quantified since 4.15.0.0. -type Rec0 :: forall k. Type -> k -> Type type Rec0 = K1 R -- | Tag for M1: datatype @@ -1152,27 +1131,15 @@ data C data S -- | Type synonym for encoding meta-information for datatypes --- --- Kind `k` explicitly quantified since 4.15.0.0. -type D1 :: forall k. Meta -> (k -> Type) -> (k -> Type) type D1 = M1 D -- | Type synonym for encoding meta-information for constructors --- --- Kind `k` explicitly quantified since 4.15.0.0. -type C1 :: forall k. Meta -> (k -> Type) -> (k -> Type) type C1 = M1 C -- | Type synonym for encoding meta-information for record selectors --- --- Kind `k` explicitly quantified since 4.15.0.0. -type S1 :: forall k. Meta -> (k -> Type) -> (k -> Type) type S1 = M1 S -- | Class for datatypes that represent datatypes --- --- Kind `k` explicitly quantified since 4.15.0.0. -type Datatype :: forall k. k -> Constraint class Datatype d where -- | The name of the datatype (unqualified) datatypeName :: t d (f :: k -> Type) (a :: k) -> [Char] @@ -1197,9 +1164,6 @@ instance (KnownSymbol n, KnownSymbol m, KnownSymbol p, SingI nt) isNewtype _ = fromSing (sing :: Sing nt) -- | Class for datatypes that represent data constructors --- --- Kind `k` explicitly quantified since 4.15.0.0. -type Constructor :: forall k. k -> Constraint class Constructor c where -- | The name of the constructor conName :: t c (f :: k -> Type) (a :: k) -> [Char] @@ -1339,9 +1303,6 @@ data DecidedStrictness = DecidedLazy ) -- | Class for datatypes that represent records --- --- Kind `k` explicitly quantified since 4.15.0.0. -type Selector :: forall k. k -> Constraint class Selector s where -- | The name of the selector selName :: t s (f :: k -> Type) (a :: k) -> [Char] @@ -1394,7 +1355,6 @@ class Generic a where -- 'from1' . 'to1' ≡ 'Prelude.id' -- 'to1' . 'from1' ≡ 'Prelude.id' -- @ -type Generic1 :: forall k. (k -> Type) -> Constraint class Generic1 (f :: k -> Type) where -- | Generic representation type type Rep1 f :: k -> Type @@ -1519,16 +1479,10 @@ deriving instance Generic1 Down -------------------------------------------------------------------------------- -- | The singleton kind-indexed data family. --- --- Kind `k` explicitly quantified since 4.15.0.0. -type Sing :: forall k. k -> Type data family Sing (a :: k) -- | A 'SingI' constraint is essentially an implicitly-passed singleton. --- --- Kind `k` explicitly quantified since 4.15.0.0. -type SingI :: forall k. k -> Constraint -class SingI a where +class SingI (a :: k) where -- | Produce the singleton explicitly. You will likely need the @ScopedTypeVariables@ -- extension to use this method the way you want. sing :: Sing a @@ -1536,7 +1490,6 @@ class SingI a where -- | The 'SingKind' class is essentially a /kind/ class. It classifies all kinds -- for which singletons are defined. The class supports converting between a singleton -- type and the base (unrefined) type which it is built from. -type SingKind :: Type -> Constraint class SingKind k where -- | Get a base type from a proxy for the promoted kind. For example, -- @DemoteRep Bool@ will be the type @Bool at . ===================================== libraries/base/changelog.md ===================================== @@ -2,14 +2,6 @@ ## 4.15.0.0 *TBA* - * `Const` (`Data.Functor.Const`), `Compose` (`Data.Functor.Compose`), - `Product` (`Data.Functor.Product`), `Sum` (`Data.Functor.Sum`), `Coercion` - and `TestCoercion` (`Data.Type.Coercion`), `(:~:)` and `TestEquality` - (`Data.Type.Equality`); `UAddr`, `UChar`, `UDouble` `UFloat`, `UInt`, - `UWord`, `Rec0`, `D1`, `C1`, `S1`, `Datatype`, `Constructor`, `Selector` - (`GHC.Generics`) now use specified quantification, allowing the use of - visible kind application. - * `openFile` now calls the `open` system call with an `interruptible` FFI call, ensuring that the call can be interrupted with `SIGINT` on POSIX systems. ===================================== libraries/ghc-prim/GHC/Types.hs ===================================== @@ -1,6 +1,6 @@ {-# LANGUAGE MagicHash, NoImplicitPrelude, TypeFamilies, UnboxedTuples, MultiParamTypeClasses, RoleAnnotations, CPP, TypeOperators, - PolyKinds, StandaloneKindSignatures, RankNTypes #-} + PolyKinds #-} ----------------------------------------------------------------------------- -- | -- Module : GHC.Types @@ -226,7 +226,6 @@ inside GHC, to change the kind and type. -- about the difference between heterogeneous equality @~~@ and -- homogeneous equality @~@, this is printed as @~@ unless -- @-fprint-equality-relations@ is set. -type (~~) :: forall k1 k2. k1 -> k2 -> Constraint class a ~~ b -- See also Note [The equality types story] in GHC.Builtin.Types.Prim @@ -283,8 +282,7 @@ class a ~ b -- by Joachim Breitner, Richard A. Eisenberg, Simon Peyton Jones and Stephanie Weirich. -- -- @since 4.7.0.0 -type Coercible :: forall k. k -> k -> Constraint -class Coercible a b +class Coercible (a :: k) (b :: k) -- See also Note [The equality types story] in GHC.Builtin.Types.Prim {- ********************************************************************* ===================================== testsuite/tests/dependent/should_fail/T11334b.stderr ===================================== @@ -1,7 +1,7 @@ T11334b.hs:8:14: error: • Cannot default kind variable ‘f0’ - of kind: k20 -> * + of kind: k0 -> * Perhaps enable PolyKinds or add a kind signature • In an expression type signature: Proxy 'Compose In the expression: Proxy :: Proxy 'Compose @@ -9,7 +9,7 @@ T11334b.hs:8:14: error: T11334b.hs:8:14: error: • Cannot default kind variable ‘g0’ - of kind: k10 -> k20 + of kind: k10 -> k0 Perhaps enable PolyKinds or add a kind signature • In an expression type signature: Proxy 'Compose In the expression: Proxy :: Proxy 'Compose ===================================== testsuite/tests/deriving/should_compile/T14578.stderr ===================================== @@ -13,27 +13,26 @@ Derived class instances: GHC.Real.Integral b => b -> T14578.Wat f g a -> T14578.Wat f g a (GHC.Base.<>) = GHC.Prim.coerce - @(T14578.App (Data.Functor.Compose.Compose @(TYPE 'GHC.Types.LiftedRep) @(TYPE 'GHC.Types.LiftedRep) f g) a - -> T14578.App (Data.Functor.Compose.Compose @(TYPE 'GHC.Types.LiftedRep) @(TYPE 'GHC.Types.LiftedRep) f g) a - -> T14578.App (Data.Functor.Compose.Compose @(TYPE 'GHC.Types.LiftedRep) @(TYPE 'GHC.Types.LiftedRep) f g) a) + @(T14578.App (Data.Functor.Compose.Compose f g) a + -> T14578.App (Data.Functor.Compose.Compose f g) a + -> T14578.App (Data.Functor.Compose.Compose f g) a) @(T14578.Wat f g a -> T14578.Wat f g a -> T14578.Wat f g a) - ((GHC.Base.<>) - @(T14578.App (Data.Functor.Compose.Compose @(TYPE 'GHC.Types.LiftedRep) @(TYPE 'GHC.Types.LiftedRep) f g) a)) + ((GHC.Base.<>) @(T14578.App (Data.Functor.Compose.Compose f g) a)) GHC.Base.sconcat = GHC.Prim.coerce - @(GHC.Base.NonEmpty (T14578.App (Data.Functor.Compose.Compose @(TYPE 'GHC.Types.LiftedRep) @(TYPE 'GHC.Types.LiftedRep) f g) a) - -> T14578.App (Data.Functor.Compose.Compose @(TYPE 'GHC.Types.LiftedRep) @(TYPE 'GHC.Types.LiftedRep) f g) a) + @(GHC.Base.NonEmpty (T14578.App (Data.Functor.Compose.Compose f g) a) + -> T14578.App (Data.Functor.Compose.Compose f g) a) @(GHC.Base.NonEmpty (T14578.Wat f g a) -> T14578.Wat f g a) (GHC.Base.sconcat - @(T14578.App (Data.Functor.Compose.Compose @(TYPE 'GHC.Types.LiftedRep) @(TYPE 'GHC.Types.LiftedRep) f g) a)) + @(T14578.App (Data.Functor.Compose.Compose f g) a)) GHC.Base.stimes = GHC.Prim.coerce @(b - -> T14578.App (Data.Functor.Compose.Compose @(TYPE 'GHC.Types.LiftedRep) @(TYPE 'GHC.Types.LiftedRep) f g) a - -> T14578.App (Data.Functor.Compose.Compose @(TYPE 'GHC.Types.LiftedRep) @(TYPE 'GHC.Types.LiftedRep) f g) a) + -> T14578.App (Data.Functor.Compose.Compose f g) a + -> T14578.App (Data.Functor.Compose.Compose f g) a) @(b -> T14578.Wat f g a -> T14578.Wat f g a) (GHC.Base.stimes - @(T14578.App (Data.Functor.Compose.Compose @(TYPE 'GHC.Types.LiftedRep) @(TYPE 'GHC.Types.LiftedRep) f g) a)) + @(T14578.App (Data.Functor.Compose.Compose f g) a)) instance GHC.Base.Functor f => GHC.Base.Functor (T14578.App f) where ===================================== testsuite/tests/generics/T10604/T10604_deriving.stderr ===================================== @@ -176,7 +176,7 @@ Derived class instances: Derived type family instances: type GHC.Generics.Rep (T10604_deriving.Starify a) = GHC.Generics.D1 - @(*) + @{*} ('GHC.Generics.MetaData "Starify" "T10604_deriving" @@ -185,28 +185,28 @@ Derived type family instances: ((GHC.Generics.:+:) @(*) (GHC.Generics.C1 - @(*) + @{*} ('GHC.Generics.MetaCons "Starify1" 'GHC.Generics.PrefixI 'GHC.Types.False) (GHC.Generics.S1 - @(*) + @{*} ('GHC.Generics.MetaSel ('GHC.Maybe.Nothing @GHC.Types.Symbol) 'GHC.Generics.NoSourceUnpackedness 'GHC.Generics.NoSourceStrictness 'GHC.Generics.DecidedLazy) - (GHC.Generics.Rec0 @(*) a))) + (GHC.Generics.Rec0 @{*} a))) (GHC.Generics.C1 - @(*) + @{*} ('GHC.Generics.MetaCons "Starify2" 'GHC.Generics.PrefixI 'GHC.Types.False) (GHC.Generics.S1 - @(*) + @{*} ('GHC.Generics.MetaSel ('GHC.Maybe.Nothing @GHC.Types.Symbol) @@ -214,22 +214,22 @@ Derived type family instances: 'GHC.Generics.NoSourceStrictness 'GHC.Generics.DecidedLazy) (GHC.Generics.Rec0 - @(*) GHC.Types.Int)))) + @{*} GHC.Types.Int)))) type GHC.Generics.Rep1 @(*) T10604_deriving.Starify = GHC.Generics.D1 - @(*) + @{*} ('GHC.Generics.MetaData "Starify" "T10604_deriving" "main" 'GHC.Types.False) ((GHC.Generics.:+:) @(*) (GHC.Generics.C1 - @(*) + @{*} ('GHC.Generics.MetaCons "Starify1" 'GHC.Generics.PrefixI 'GHC.Types.False) (GHC.Generics.S1 - @(*) + @{*} ('GHC.Generics.MetaSel ('GHC.Maybe.Nothing @GHC.Types.Symbol) 'GHC.Generics.NoSourceUnpackedness @@ -237,22 +237,22 @@ Derived type family instances: 'GHC.Generics.DecidedLazy) GHC.Generics.Par1)) (GHC.Generics.C1 - @(*) + @{*} ('GHC.Generics.MetaCons "Starify2" 'GHC.Generics.PrefixI 'GHC.Types.False) (GHC.Generics.S1 - @(*) + @{*} ('GHC.Generics.MetaSel ('GHC.Maybe.Nothing @GHC.Types.Symbol) 'GHC.Generics.NoSourceUnpackedness 'GHC.Generics.NoSourceStrictness 'GHC.Generics.DecidedLazy) - (GHC.Generics.Rec0 @(*) GHC.Types.Int)))) + (GHC.Generics.Rec0 @{*} GHC.Types.Int)))) type GHC.Generics.Rep (T10604_deriving.SumOfProducts @{k} a) = GHC.Generics.D1 - @(*) + @{*} ('GHC.Generics.MetaData "SumOfProducts" "T10604_deriving" @@ -261,7 +261,7 @@ Derived type family instances: ((GHC.Generics.:+:) @(*) (GHC.Generics.C1 - @(*) + @{*} ('GHC.Generics.MetaCons "Prod1" 'GHC.Generics.PrefixI @@ -269,7 +269,7 @@ Derived type family instances: ((GHC.Generics.:*:) @(*) (GHC.Generics.S1 - @(*) + @{*} ('GHC.Generics.MetaSel ('GHC.Maybe.Nothing @GHC.Types.Symbol) @@ -277,10 +277,10 @@ Derived type family instances: 'GHC.Generics.NoSourceStrictness 'GHC.Generics.DecidedLazy) (GHC.Generics.Rec0 - @(*) + @{*} (T10604_deriving.Proxy @k a))) (GHC.Generics.S1 - @(*) + @{*} ('GHC.Generics.MetaSel ('GHC.Maybe.Nothing @GHC.Types.Symbol) @@ -288,10 +288,10 @@ Derived type family instances: 'GHC.Generics.NoSourceStrictness 'GHC.Generics.DecidedLazy) (GHC.Generics.Rec0 - @(*) + @{*} (T10604_deriving.Proxy @k a))))) (GHC.Generics.C1 - @(*) + @{*} ('GHC.Generics.MetaCons "Prod2" 'GHC.Generics.PrefixI @@ -299,7 +299,7 @@ Derived type family instances: ((GHC.Generics.:*:) @(*) (GHC.Generics.S1 - @(*) + @{*} ('GHC.Generics.MetaSel ('GHC.Maybe.Nothing @GHC.Types.Symbol) @@ -307,10 +307,10 @@ Derived type family instances: 'GHC.Generics.NoSourceStrictness 'GHC.Generics.DecidedLazy) (GHC.Generics.Rec0 - @(*) + @{*} (T10604_deriving.Proxy @k a))) (GHC.Generics.S1 - @(*) + @{*} ('GHC.Generics.MetaSel ('GHC.Maybe.Nothing @GHC.Types.Symbol) @@ -318,11 +318,11 @@ Derived type family instances: 'GHC.Generics.NoSourceStrictness 'GHC.Generics.DecidedLazy) (GHC.Generics.Rec0 - @(*) + @{*} (T10604_deriving.Proxy @k a)))))) type GHC.Generics.Rep1 @k (T10604_deriving.SumOfProducts @{k}) = GHC.Generics.D1 - @k + @{k} ('GHC.Generics.MetaData "SumOfProducts" "T10604_deriving" @@ -331,7 +331,7 @@ Derived type family instances: ((GHC.Generics.:+:) @k (GHC.Generics.C1 - @k + @{k} ('GHC.Generics.MetaCons "Prod1" 'GHC.Generics.PrefixI @@ -339,7 +339,7 @@ Derived type family instances: ((GHC.Generics.:*:) @k (GHC.Generics.S1 - @k + @{k} ('GHC.Generics.MetaSel ('GHC.Maybe.Nothing @GHC.Types.Symbol) @@ -349,7 +349,7 @@ Derived type family instances: (GHC.Generics.Rec1 @k (T10604_deriving.Proxy @k))) (GHC.Generics.S1 - @k + @{k} ('GHC.Generics.MetaSel ('GHC.Maybe.Nothing @GHC.Types.Symbol) @@ -360,7 +360,7 @@ Derived type family instances: @k (T10604_deriving.Proxy @k))))) (GHC.Generics.C1 - @k + @{k} ('GHC.Generics.MetaCons "Prod2" 'GHC.Generics.PrefixI @@ -368,7 +368,7 @@ Derived type family instances: ((GHC.Generics.:*:) @k (GHC.Generics.S1 - @k + @{k} ('GHC.Generics.MetaSel ('GHC.Maybe.Nothing @GHC.Types.Symbol) @@ -378,7 +378,7 @@ Derived type family instances: (GHC.Generics.Rec1 @k (T10604_deriving.Proxy @k))) (GHC.Generics.S1 - @k + @{k} ('GHC.Generics.MetaSel ('GHC.Maybe.Nothing @GHC.Types.Symbol) @@ -390,40 +390,40 @@ Derived type family instances: (T10604_deriving.Proxy @k)))))) type GHC.Generics.Rep (T10604_deriving.Wrap2 @k a) = GHC.Generics.D1 - @(*) + @{*} ('GHC.Generics.MetaData "Wrap2" "T10604_deriving" "main" 'GHC.Types.False) (GHC.Generics.C1 - @(*) + @{*} ('GHC.Generics.MetaCons "Wrap2" 'GHC.Generics.PrefixI 'GHC.Types.False) (GHC.Generics.S1 - @(*) + @{*} ('GHC.Generics.MetaSel ('GHC.Maybe.Nothing @GHC.Types.Symbol) 'GHC.Generics.NoSourceUnpackedness 'GHC.Generics.NoSourceStrictness 'GHC.Generics.DecidedLazy) (GHC.Generics.Rec0 - @(*) + @{*} (T10604_deriving.Proxy @(*) (T10604_deriving.Proxy @(k -> *) a))))) type GHC.Generics.Rep1 @(k -> *) (T10604_deriving.Wrap2 @k) = GHC.Generics.D1 - @(k -> *) + @{k -> *} ('GHC.Generics.MetaData "Wrap2" "T10604_deriving" "main" 'GHC.Types.False) (GHC.Generics.C1 - @(k -> *) + @{k -> *} ('GHC.Generics.MetaCons "Wrap2" 'GHC.Generics.PrefixI 'GHC.Types.False) (GHC.Generics.S1 - @(k -> *) + @{k -> *} ('GHC.Generics.MetaSel ('GHC.Maybe.Nothing @GHC.Types.Symbol) 'GHC.Generics.NoSourceUnpackedness @@ -437,39 +437,39 @@ Derived type family instances: @(k -> *) (T10604_deriving.Proxy @(k -> *)))))) type GHC.Generics.Rep (T10604_deriving.Wrap a) = GHC.Generics.D1 - @(*) + @{*} ('GHC.Generics.MetaData "Wrap" "T10604_deriving" "main" 'GHC.Types.False) (GHC.Generics.C1 - @(*) + @{*} ('GHC.Generics.MetaCons "Wrap" 'GHC.Generics.PrefixI 'GHC.Types.False) (GHC.Generics.S1 - @(*) + @{*} ('GHC.Generics.MetaSel ('GHC.Maybe.Nothing @GHC.Types.Symbol) 'GHC.Generics.NoSourceUnpackedness 'GHC.Generics.NoSourceStrictness 'GHC.Generics.DecidedLazy) (GHC.Generics.Rec0 - @(*) + @{*} (T10604_deriving.Proxy @(* -> *) a)))) type GHC.Generics.Rep1 @(* -> *) T10604_deriving.Wrap = GHC.Generics.D1 - @(* -> *) + @{* -> *} ('GHC.Generics.MetaData "Wrap" "T10604_deriving" "main" 'GHC.Types.False) (GHC.Generics.C1 - @(* -> *) + @{* -> *} ('GHC.Generics.MetaCons "Wrap" 'GHC.Generics.PrefixI 'GHC.Types.False) (GHC.Generics.S1 - @(* -> *) + @{* -> *} ('GHC.Generics.MetaSel ('GHC.Maybe.Nothing @GHC.Types.Symbol) 'GHC.Generics.NoSourceUnpackedness @@ -479,26 +479,26 @@ Derived type family instances: @(* -> *) (T10604_deriving.Proxy @(* -> *))))) type GHC.Generics.Rep (T10604_deriving.Proxy @k a) = GHC.Generics.D1 - @(*) + @{*} ('GHC.Generics.MetaData "Proxy" "T10604_deriving" "main" 'GHC.Types.False) (GHC.Generics.C1 - @(*) + @{*} ('GHC.Generics.MetaCons "Proxy" 'GHC.Generics.PrefixI 'GHC.Types.False) (GHC.Generics.U1 @(*))) type GHC.Generics.Rep1 @k (T10604_deriving.Proxy @k) = GHC.Generics.D1 - @k + @{k} ('GHC.Generics.MetaData "Proxy" "T10604_deriving" "main" 'GHC.Types.False) (GHC.Generics.C1 - @k + @{k} ('GHC.Generics.MetaCons "Proxy" 'GHC.Generics.PrefixI 'GHC.Types.False) (GHC.Generics.U1 @k)) type GHC.Generics.Rep (T10604_deriving.Empty a) = GHC.Generics.D1 - @(*) + @{*} ('GHC.Generics.MetaData "Empty" "T10604_deriving" @@ -507,7 +507,7 @@ Derived type family instances: (GHC.Generics.V1 @(*)) type GHC.Generics.Rep1 @GHC.Types.Bool T10604_deriving.Empty = GHC.Generics.D1 - @GHC.Types.Bool + @{GHC.Types.Bool} ('GHC.Generics.MetaData "Empty" "T10604_deriving" ===================================== testsuite/tests/ghci/scripts/T12550.stdout ===================================== @@ -33,11 +33,9 @@ instance Functor U1 -- Defined in ‘GHC.Generics’ instance ∀ (f ∷ ★ → ★). Functor f ⇒ Functor (Rec1 f) -- Defined in ‘GHC.Generics’ instance Functor Par1 -- Defined in ‘GHC.Generics’ -instance ∀ i (meta ∷ Meta) (f ∷ ★ → ★). - Functor f ⇒ - Functor (M1 i meta f) +instance ∀ i (c ∷ Meta) (f ∷ ★ → ★). Functor f ⇒ Functor (M1 i c f) -- Defined in ‘GHC.Generics’ -instance ∀ i a. Functor (K1 i a) -- Defined in ‘GHC.Generics’ +instance ∀ i c. Functor (K1 i c) -- Defined in ‘GHC.Generics’ instance ∀ (f ∷ ★ → ★) (g ∷ ★ → ★). (Functor f, Functor g) ⇒ Functor (f :.: g) @@ -62,13 +60,13 @@ datatypeName ∷ ∀ {d} {t ∷ ★ → (★ → ★) → ★ → ★} {f ∷ ★ → ★} {a}. Datatype d ⇒ t d f a → [Char] -type Datatype :: ∀ k. k → Constraint +type Datatype :: ∀ {k}. k → Constraint class Datatype d where datatypeName ∷ ∀ k1 (t ∷ k → (k1 → ★) → k1 → ★) (f ∷ k1 → ★) (a ∷ k1). t d f a → [Char] ... -- Defined in ‘GHC.Generics’ -(:*:) ∷ ∀ {f ∷ ★ → ★} {a} {g ∷ ★ → ★}. f a → g a → (:*:) f g a +(:*:) ∷ ∀ {f ∷ ★ → ★} {p} {g ∷ ★ → ★}. f p → g p → (:*:) f g p Rep ∷ ★ → ★ → ★ M1 ∷ ∀ k. ★ → Meta → (k → ★) → k → ★ ===================================== testsuite/tests/partial-sigs/should_compile/T15039b.stderr ===================================== @@ -51,7 +51,7 @@ T15039b.hs:33:14: warning: [-Wpartial-type-signatures (in -Wdefault)] T15039b.hs:35:8: warning: [-Wpartial-type-signatures (in -Wdefault)] • Found type wildcard ‘_’ standing for ‘Coercible @(*) a b’ Where: ‘a’, ‘b’ are rigid type variables bound by - the inferred type of ex7 :: Coercible @(*) a b => Coercion @(*) a b + the inferred type of ex7 :: Coercible @(*) a b => Coercion @{*} a b at T15039b.hs:35:1-44 • In the type signature: ex7 :: _ => Coercion (a :: Type) (b :: Type) ===================================== testsuite/tests/partial-sigs/should_compile/T15039d.stderr ===================================== @@ -52,7 +52,7 @@ T15039d.hs:33:14: warning: [-Wpartial-type-signatures (in -Wdefault)] T15039d.hs:35:8: warning: [-Wpartial-type-signatures (in -Wdefault)] • Found type wildcard ‘_’ standing for ‘Coercible @(*) a b’ Where: ‘a’, ‘b’ are rigid type variables bound by - the inferred type of ex7 :: Coercible @(*) a b => Coercion @(*) a b + the inferred type of ex7 :: Coercible @(*) a b => Coercion @{*} a b at T15039d.hs:35:1-44 • In the type signature: ex7 :: _ => Coercion (a :: Type) (b :: Type) ===================================== testsuite/tests/typecheck/should_fail/T10285.stderr ===================================== @@ -3,7 +3,7 @@ T10285.hs:8:17: error: • Could not deduce: Coercible a b arising from a use of ‘coerce’ from the context: Coercible (N a) (N b) bound by a pattern with constructor: - Coercion :: forall k (a :: k) (b :: k). + Coercion :: forall {k} (a :: k) (b :: k). Coercible a b => Coercion a b, in an equation for ‘oops’ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c8cf710a02c386d5007a8a6179ec1826b7085a29 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c8cf710a02c386d5007a8a6179ec1826b7085a29 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 9 21:56:30 2020 From: gitlab at gitlab.haskell.org (Adam Gundry) Date: Sat, 09 May 2020 17:56:30 -0400 Subject: [Git][ghc/ghc][wip/amg/hasfield-2020] 73 commits: TH: fix Show/Eq/Ord instances for Bytes (#16457) Message-ID: <5eb7270ec4002_61671288ff4c9887079@gitlab.haskell.org.mail> Adam Gundry pushed to branch wip/amg/hasfield-2020 at Glasgow Haskell Compiler / GHC Commits: 99823ed2 by Sylvain Henry at 2020-04-27T20:24:46-04:00 TH: fix Show/Eq/Ord instances for Bytes (#16457) We shouldn't compare pointer values but the actual bytes. - - - - - c62271a2 by Alp Mestanogullari at 2020-04-27T20:25:33-04:00 hadrian: always capture both stdout and stderr when running a builder fails The idea being that when a builder('s command) fails, we quite likely want to have all the information available to figure out why. Depending on the builder _and_ the particular problem, the useful bits of information can be printed on stdout or stderr. We accomplish this by defining a simple wrapper for Shake's `cmd` function, that just _always_ captures both streams in case the command returns a non-zero exit code, and by using this wrapper everywhere in `hadrian/src/Builder.hs`. Fixes #18089. - - - - - 4b9764db by Ryan Scott at 2020-04-28T15:40:04-04:00 Define a Quote IO instance Fixes #18103. - - - - - 518a63d4 by Ryan Scott at 2020-04-28T15:40:42-04:00 Make boxed 1-tuples have known keys Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. - - - - - 2cfc4ab9 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Document backpack fields in DynFlags - - - - - 10a2ba90 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 69562e34 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 9e2c8e0e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - ea717aa4 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 10d15f1e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 8bfb0219 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - 71484b09 by Alexis King at 2020-04-30T01:57:35-04:00 Allow block arguments in arrow control operators Arrow control operators have their own entries in the grammar, so they did not cooperate with BlockArguments. This was just a minor oversight, so this patch adjusts the grammar to add the desired behavior. fixes #18050 - - - - - a48cd2a0 by Alexis King at 2020-04-30T01:57:35-04:00 Allow LambdaCase to be used as a command in proc notation - - - - - f4d3773c by Alexis King at 2020-04-30T01:57:35-04:00 Document BlockArguments/LambdaCase support in arrow notation - - - - - 5bdfdd13 by Simon Peyton Jones at 2020-04-30T01:58:15-04:00 Add tests for #17873 - - - - - 19b701c2 by Simon Peyton Jones at 2020-04-30T07:30:13-04:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - 014ef4a3 by Matthew Pickering at 2020-04-30T07:30:50-04:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 2aa67611 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - 54dad3cf by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - 99ff8145 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 05b0a9fd by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 Remove OneShotInfo field of LFReEntrant, document OneShotInfo The field is only used in withNewTickyCounterFun and it's easier to directly pass a parameter for one-shot info to withNewTickyCounterFun instead of passing it via LFReEntrant. This also makes !2842 simpler. Other changes: - New Note (by SPJ) [OneShotInfo overview] added. - Arity argument of thunkCode removed as it's always 0. - - - - - a43620c6 by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 GHC.StgToCmm.Ticky: remove a few unused stuff - - - - - 780de9e1 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Use platform in Iface Binary - - - - - f8386c7b by Sylvain Henry at 2020-05-01T10:37:39-04:00 Refactor PprDebug handling If `-dppr-debug` is set, then PprUser and PprDump styles are silently replaced with PprDebug style. This was done in `mkUserStyle` and `mkDumpStyle` smart constructors. As a consequence they needed a DynFlags parameter. Now we keep the original PprUser and PprDump styles until they are used to create an `SDocContext`. I.e. the substitution is only performed in `initSDocContext`. - - - - - b3df9e78 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Remove PprStyle param of logging actions Use `withPprStyle` instead to apply a specific style to a SDoc. - - - - - de9fc995 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Fully remove PprDebug PprDebug was a pain to deal with consistently as it is implied by `-dppr-debug` but it isn't really a PprStyle. We remove it completely and query the appropriate SDoc flag instead (`sdocPprDebug`) via helpers (`getPprDebug` and its friends). - - - - - 8b51fcbd by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Only call checkSingle if we would report warnings - - - - - fd7ea0fe by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 7bfe9ac5 by Ben Gamari at 2020-05-03T04:41:33-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. - - - - - c560dd07 by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Move eventlog documentation users guide - - - - - 02543d5e by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Add documentation for non-moving GC events - - - - - b465dd45 by Alexis King at 2020-05-03T04:42:12-04:00 Flatten nested casts in the simple optimizer Normally, we aren’t supposed to generated any nested casts, since mkCast takes care to flatten them, but the simple optimizer didn’t use mkCast, so they could show up after inlining. This isn’t really a problem, since the simplifier will clean them up immediately anyway, but it can clutter the -ddump-ds output, and it’s an extremely easy fix. closes #18112 - - - - - 8bdc03d6 by Simon Peyton Jones at 2020-05-04T01:56:59-04:00 Don't return a panic in tcNestedSplice In GHC.Tc.Gen.Splice.tcNestedSplice we were returning a typechecked expression of "panic". That is usually OK, because the result is discarded. But it happens that tcApp now looks at the typechecked expression, trivially, to ask if it is tagToEnum. So being bottom is bad. Moreover a debug-trace might print it out. So better to return a civilised expression, even though it is usually discarded. - - - - - 0bf640b1 by Baldur Blöndal at 2020-05-04T01:57:36-04:00 Don't require parentheses around via type (`-XDerivingVia'). Fixes #18130". - - - - - 30272412 by Artem Pelenitsyn at 2020-05-04T13:19:59-04:00 Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) - - - - - b9f7c08f by jneira at 2020-05-04T13:20:37-04:00 Remove unused hs-boot file - - - - - 1d8f80cd by Sylvain Henry at 2020-05-05T03:22:46-04:00 Remove references to -package-key * remove references to `-package-key` which has been removed in 2016 (240ddd7c39536776e955e881d709bbb039b48513) * remove support for `-this-package-key` which has been deprecated at the same time - - - - - 7bc3a65b by Sylvain Henry at 2020-05-05T03:23:31-04:00 Remove SpecConstrAnnotation (#13681) This has been deprecated since 2013. Use GHC.Types.SPEC instead. Make GHC.Exts "not-home" for haddock Metric Decrease: haddock.base - - - - - 3c862f63 by DenisFrezzato at 2020-05-05T03:24:15-04:00 Fix Haskell98 short description in documentation - - - - - 2420c555 by Ryan Scott at 2020-05-05T03:24:53-04:00 Add regression tests for #16244, #16245, #16758 Commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70 ended up fixing quite a few bugs: * This commit fixes #16244 completely. A regression test has been added. * This commit fixes one program from #16245. (The program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211369 still panics, and the program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211400 still loops infinitely.) A regression test has been added for this program. * This commit fixes #16758. Accordingly, this patch removes the `expect_broken` label from the `T16758` test case, moves it from `should_compile` to `should_fail` (as it should produce an error message), and checks in the expected stderr. - - - - - 40c71c2c by Sylvain Henry at 2020-05-05T03:25:31-04:00 Fix colorized error messages (#18128) In b3df9e780fb2f5658412c644849cd0f1e6f50331 I broke colorized messages by using "dump" style instead of "user" style. This commits fixes it. - - - - - 7ab6ab09 by Richard Eisenberg at 2020-05-06T04:39:32-04:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG ------------------------- - - - - - 420b957d by Ben Gamari at 2020-05-06T04:40:08-04:00 rts: Zero block flags with -DZ Block flags are very useful for determining the state of a block. However, some block allocator users don't touch them, leading to misleading values. Ensure that we zero then when zero-on-gc is set. This is safe and makes the flags more useful during debugging. - - - - - 740b3b8d by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix incorrect failed_to_evac value during deadlock gc Previously we would incorrectly set the failed_to_evac flag if we evacuated a value due to a deadlock GC. This would cause us to mark more things as dirty than strictly necessary. It also turned up a nasty but which I will fix next. - - - - - b2d72c75 by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - 9f3e6884 by Zubin Duggal at 2020-05-06T04:41:08-04:00 Allow atomic update of NameCache in readHieFile The situation arises in ghcide where multiple different threads may need to update the name cache, therefore with the older interface it could happen that you start reading a hie file with name cache A and produce name cache A + B, but another thread in the meantime updated the namecache to A + C. Therefore if you write the new namecache you will lose the A' updates from the second thread. Updates haddock submodule - - - - - edec6a6c by Ryan Scott at 2020-05-06T04:41:57-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _)`. Fixes #18127. - - - - - a95e7fe0 by Ömer Sinan Ağacan at 2020-05-06T04:42:39-04:00 ELF linker: increment curSymbol after filling in fields of current entry The bug was introduced in a8b7cef4d45 which added a field to the `symbols` array elements and then updated this code incorrectly: - oc->symbols[curSymbol++] = nm; + oc->symbols[curSymbol++].name = nm; + oc->symbols[curSymbol].addr = symbol->addr; - - - - - cab1871a by Sylvain Henry at 2020-05-06T04:43:21-04:00 Move LeadingUnderscore into Platform (#17957) Avoid direct use of DynFlags to know if symbols must be prefixed by an underscore. - - - - - 94e7c563 by Sylvain Henry at 2020-05-06T04:43:21-04:00 Don't use DynFlags in showLinkerState (#17957) - - - - - 9afd9251 by Ryan Scott at 2020-05-06T04:43:58-04:00 Refactoring: Use bindSigTyVarsFV in rnMethodBinds `rnMethodBinds` was explicitly using `xoptM` to determine if `ScopedTypeVariables` is enabled before bringing type variables bound by the class/instance header into scope. However, this `xoptM` logic is already performed by the `bindSigTyVarsFV` function. This patch uses `bindSigTyVarsFV` in `rnMethodBinds` to reduce the number of places where we need to consult if `ScopedTypeVariables` is on. This is purely refactoring, and there should be no user-visible change in behavior. - - - - - 6f6d72b2 by Brian Foley at 2020-05-08T15:29:25-04:00 Remove further dead code found by a simple Python script. Avoid removing some functions that are part of an API even though they're not used in-tree at the moment. - - - - - 78bf8bf9 by Julien Debon at 2020-05-08T15:29:28-04:00 Add doc examples for Bifoldable See #17929 - - - - - 66f0a847 by Julien Debon at 2020-05-08T15:29:29-04:00 doc (Bitraversable): Add examples to Bitraversable * Add examples to Data.Bitraversable * Fix formatting for (,) in Bitraversable and Bifoldable * Fix mistake on bimapAccumR documentation See #17929 - - - - - 9749fe12 by Baldur Blöndal at 2020-05-08T15:29:32-04:00 Specify kind variables for inferred kinds in base. - - - - - 4e9aef9e by John Ericson at 2020-05-08T15:29:36-04:00 HsSigWcTypeScoping: Pull in documentation from stray location - - - - - f4d5c6df by John Ericson at 2020-05-08T15:29:36-04:00 Rename local `real_fvs` to `implicit_vs` It doesn't make sense to call the "free" variables we are about to implicitly bind the real ones. - - - - - 20570b4b by John Ericson at 2020-05-08T15:29:36-04:00 A few tiny style nits with renaming - Use case rather than guards that repeatedly scrutenize same thing. - No need for view pattern when `L` is fine. - Use type synnonym to convey the intent like elsewhere. - - - - - 09ac8de5 by John Ericson at 2020-05-08T15:29:36-04:00 Add `forAllOrNothing` function with note - - - - - bb35c0e5 by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Document lawlessness of Ap's Num instance - - - - - cdd229ff by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply suggestion to libraries/base/Data/Monoid.hs - - - - - 926d2aab by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply more suggestions from Simon Jakobi - - - - - 7a763cff by Adam Gundry at 2020-05-08T15:29:41-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. - - - - - 88e3c815 by Simon Peyton Jones at 2020-05-08T15:29:41-04:00 Fix specialisation for DFuns When specialising a DFun we must take care to saturate the unfolding. See Note [Specialising DFuns] in Specialise. Fixes #18120 - - - - - 86c77b36 by Greg Steuck at 2020-05-08T15:29:45-04:00 Remove unused SEGMENT_PROT_RWX It's been unused for a year and is problematic on any OS which requires W^X for security. - - - - - 9d97f4b5 by nineonine at 2020-05-08T15:30:03-04:00 Add test for #16167 - - - - - aa318338 by Ryan Scott at 2020-05-08T15:30:04-04:00 Bump exceptions submodule so that dist-boot is .gitignore'd `exceptions` is a stage-0 boot library as of commit 30272412fa437ab8e7a8035db94a278e10513413, which means that building `exceptions` in a GHC tree will generate a `dist-boot` directory. However, this directory was not specified in `exceptions`' `.gitignore` file, which causes it to dirty up the current `git` working directory. Accordingly, this bumps the `exceptions` submodule to commit ghc/packages/exceptions at 23c0b8a50d7592af37ca09beeec16b93080df98f, which adds `dist-boot` to the `.gitignore` file. - - - - - ea86360f by Ömer Sinan Ağacan at 2020-05-08T15:30:30-04:00 Linker.c: initialize n_symbols of ObjectCode with other fields - - - - - 66d14427 by Adam Gundry at 2020-05-09T20:34:39+01:00 Attach update function names to FieldLabels in DataCons - - - - - 295e9175 by Adam Gundry at 2020-05-09T20:34:39+01:00 Update GHC.Records to use hasField instead of getField - - - - - 7745c283 by Adam Gundry at 2020-05-09T22:54:54+01:00 Generate record updaters and use in HasField - - - - - 7d080797 by Adam Gundry at 2020-05-09T22:54:54+01:00 Use rnIfaceNeverExported for updaters - - - - - f83e9a6a by Adam Gundry at 2020-05-09T22:54:54+01:00 Update HasField tests Adapt overloadedrecflds tests and T17355 to new definition of HasField Extend hasfieldrun01 test with partial record field test Update hasfieldfail02 test to check unlifted type case Accept changed T14189 output due to FieldLabel additional field - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Utils.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Config.hs - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/PPC/Cond.hs - compiler/GHC/CmmToAsm/SPARC/Cond.hs - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Cond.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/DataCon.hs-boot - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Driver.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/64fa94ede0253e6ac8c023448d8e8ac59ff34c34...f83e9a6a13ea388e94e226cd23b7ef0da4d9be81 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/64fa94ede0253e6ac8c023448d8e8ac59ff34c34...f83e9a6a13ea388e94e226cd23b7ef0da4d9be81 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 9 22:41:13 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 09 May 2020 18:41:13 -0400 Subject: [Git][ghc/ghc][wip/lower-tc-tracing-cost] 137 commits: Change zipWith to zipWithEqual in a few places Message-ID: <5eb73189ccb94_6167119ebbd098939b9@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/lower-tc-tracing-cost at Glasgow Haskell Compiler / GHC Commits: 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.0.0 This requires bumping the `exceptions` and `text` submodules to bring in commits that bump their respective upper version bounds on `template-haskell`. Fixes #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - ffd7eef2 by Takenobu Tani at 2020-04-22T23:09:50-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - e8a5d81b by Jonathan DK Gibbons at 2020-04-22T23:10:28-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - dcb7fe5a by John Ericson at 2020-04-22T23:10:28-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - cde23cd4 by John Ericson at 2020-04-22T23:10:28-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - 72cb6bcc by John Ericson at 2020-04-22T23:10:28-04:00 Generalize type of `matchCanFail` - - - - - 401f7bb3 by John Ericson at 2020-04-22T23:10:28-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 6c9fae23 by Alexis King at 2020-04-22T23:11:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 48b8951e by Roland Senn at 2020-04-22T23:11:51-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 34a45ee6 by Peter Trommler at 2020-04-22T23:12:27-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - ffde2348 by Simon Peyton Jones at 2020-04-22T23:13:06-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 6f84aca3 by Ben Gamari at 2020-04-22T23:13:43-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - c29f0fa6 by Andreas Klebinger at 2020-04-22T23:14:21-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 4b4a8b60 by Ben Gamari at 2020-04-22T23:14:57-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 831b6642 by Moritz Angermann at 2020-04-22T23:15:33-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - c409961a by Ryan Scott at 2020-04-22T23:16:12-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 125aa2b8 by Ömer Sinan Ağacan at 2020-04-22T23:16:51-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - 8ea37b01 by Sylvain Henry at 2020-04-22T23:17:34-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - cd8409c2 by Ryan Scott at 2020-04-23T11:39:24-04:00 Create di_scoped_tvs for associated data family instances properly See `Note [Associated data family instances and di_scoped_tvs]` in `GHC.Tc.TyCl.Instance`, which explains all of the moving parts. Fixes #18055. - - - - - 339e8ece by Ben Gamari at 2020-04-23T11:40:02-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 5946c85a by Ben Gamari at 2020-04-23T11:40:38-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - c42754d5 by John Ericson at 2020-04-23T18:32:43-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 72da0c29 by mniip at 2020-04-23T18:33:21-04:00 Add :doc to GHC.Prim - - - - - 2c23e2e3 by mniip at 2020-04-23T18:33:21-04:00 Include docs for non-primop entries in primops.txt as well - - - - - 0ac29c88 by mniip at 2020-04-23T18:33:21-04:00 GHC.Prim docs: note and test - - - - - b0fbfc75 by John Ericson at 2020-04-24T12:07:14-04:00 Switch order on `GhcMake.IsBoot` In !1798 we were requested to replace many `Bool`s with this data type. But those bools had `False` meaning `NotBoot`, so the `Ord` instance would be flipped if we use this data-type as-is. Since the planned formally-`Bool` occurrences vastly outnumber the current occurrences, we figured it would be better to conform the `Ord` instance to how the `Bool` is used now, fixing any issues, rather than fix them currently with the bigger refactor later in !1798. That way, !1798 can be a "pure" refactor with no behavioral changes. - - - - - af332442 by Sylvain Henry at 2020-04-26T13:55:14-04:00 Modules: Utils and Data (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - cd4434c8 by Sylvain Henry at 2020-04-26T13:55:16-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 22bf5c73 by Ömer Sinan Ağacan at 2020-04-26T13:55:22-04:00 Tweak includes in non-moving GC headers We don't use hash tables in non-moving GC so remove the includes. This breaks Compact.c as existing includes no longer include Hash.h, so include Hash.h explicitly in Compact.c. - - - - - 99823ed2 by Sylvain Henry at 2020-04-27T20:24:46-04:00 TH: fix Show/Eq/Ord instances for Bytes (#16457) We shouldn't compare pointer values but the actual bytes. - - - - - c62271a2 by Alp Mestanogullari at 2020-04-27T20:25:33-04:00 hadrian: always capture both stdout and stderr when running a builder fails The idea being that when a builder('s command) fails, we quite likely want to have all the information available to figure out why. Depending on the builder _and_ the particular problem, the useful bits of information can be printed on stdout or stderr. We accomplish this by defining a simple wrapper for Shake's `cmd` function, that just _always_ captures both streams in case the command returns a non-zero exit code, and by using this wrapper everywhere in `hadrian/src/Builder.hs`. Fixes #18089. - - - - - 4b9764db by Ryan Scott at 2020-04-28T15:40:04-04:00 Define a Quote IO instance Fixes #18103. - - - - - 518a63d4 by Ryan Scott at 2020-04-28T15:40:42-04:00 Make boxed 1-tuples have known keys Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. - - - - - 2cfc4ab9 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Document backpack fields in DynFlags - - - - - 10a2ba90 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 69562e34 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 9e2c8e0e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - ea717aa4 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 10d15f1e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 8bfb0219 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - 71484b09 by Alexis King at 2020-04-30T01:57:35-04:00 Allow block arguments in arrow control operators Arrow control operators have their own entries in the grammar, so they did not cooperate with BlockArguments. This was just a minor oversight, so this patch adjusts the grammar to add the desired behavior. fixes #18050 - - - - - a48cd2a0 by Alexis King at 2020-04-30T01:57:35-04:00 Allow LambdaCase to be used as a command in proc notation - - - - - f4d3773c by Alexis King at 2020-04-30T01:57:35-04:00 Document BlockArguments/LambdaCase support in arrow notation - - - - - 5bdfdd13 by Simon Peyton Jones at 2020-04-30T01:58:15-04:00 Add tests for #17873 - - - - - 19b701c2 by Simon Peyton Jones at 2020-04-30T07:30:13-04:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - 014ef4a3 by Matthew Pickering at 2020-04-30T07:30:50-04:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 2aa67611 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - 54dad3cf by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - 99ff8145 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 05b0a9fd by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 Remove OneShotInfo field of LFReEntrant, document OneShotInfo The field is only used in withNewTickyCounterFun and it's easier to directly pass a parameter for one-shot info to withNewTickyCounterFun instead of passing it via LFReEntrant. This also makes !2842 simpler. Other changes: - New Note (by SPJ) [OneShotInfo overview] added. - Arity argument of thunkCode removed as it's always 0. - - - - - a43620c6 by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 GHC.StgToCmm.Ticky: remove a few unused stuff - - - - - 780de9e1 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Use platform in Iface Binary - - - - - f8386c7b by Sylvain Henry at 2020-05-01T10:37:39-04:00 Refactor PprDebug handling If `-dppr-debug` is set, then PprUser and PprDump styles are silently replaced with PprDebug style. This was done in `mkUserStyle` and `mkDumpStyle` smart constructors. As a consequence they needed a DynFlags parameter. Now we keep the original PprUser and PprDump styles until they are used to create an `SDocContext`. I.e. the substitution is only performed in `initSDocContext`. - - - - - b3df9e78 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Remove PprStyle param of logging actions Use `withPprStyle` instead to apply a specific style to a SDoc. - - - - - de9fc995 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Fully remove PprDebug PprDebug was a pain to deal with consistently as it is implied by `-dppr-debug` but it isn't really a PprStyle. We remove it completely and query the appropriate SDoc flag instead (`sdocPprDebug`) via helpers (`getPprDebug` and its friends). - - - - - 8b51fcbd by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Only call checkSingle if we would report warnings - - - - - fd7ea0fe by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 7bfe9ac5 by Ben Gamari at 2020-05-03T04:41:33-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. - - - - - c560dd07 by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Move eventlog documentation users guide - - - - - 02543d5e by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Add documentation for non-moving GC events - - - - - b465dd45 by Alexis King at 2020-05-03T04:42:12-04:00 Flatten nested casts in the simple optimizer Normally, we aren’t supposed to generated any nested casts, since mkCast takes care to flatten them, but the simple optimizer didn’t use mkCast, so they could show up after inlining. This isn’t really a problem, since the simplifier will clean them up immediately anyway, but it can clutter the -ddump-ds output, and it’s an extremely easy fix. closes #18112 - - - - - 8bdc03d6 by Simon Peyton Jones at 2020-05-04T01:56:59-04:00 Don't return a panic in tcNestedSplice In GHC.Tc.Gen.Splice.tcNestedSplice we were returning a typechecked expression of "panic". That is usually OK, because the result is discarded. But it happens that tcApp now looks at the typechecked expression, trivially, to ask if it is tagToEnum. So being bottom is bad. Moreover a debug-trace might print it out. So better to return a civilised expression, even though it is usually discarded. - - - - - 0bf640b1 by Baldur Blöndal at 2020-05-04T01:57:36-04:00 Don't require parentheses around via type (`-XDerivingVia'). Fixes #18130". - - - - - 30272412 by Artem Pelenitsyn at 2020-05-04T13:19:59-04:00 Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) - - - - - b9f7c08f by jneira at 2020-05-04T13:20:37-04:00 Remove unused hs-boot file - - - - - 1d8f80cd by Sylvain Henry at 2020-05-05T03:22:46-04:00 Remove references to -package-key * remove references to `-package-key` which has been removed in 2016 (240ddd7c39536776e955e881d709bbb039b48513) * remove support for `-this-package-key` which has been deprecated at the same time - - - - - 7bc3a65b by Sylvain Henry at 2020-05-05T03:23:31-04:00 Remove SpecConstrAnnotation (#13681) This has been deprecated since 2013. Use GHC.Types.SPEC instead. Make GHC.Exts "not-home" for haddock Metric Decrease: haddock.base - - - - - 3c862f63 by DenisFrezzato at 2020-05-05T03:24:15-04:00 Fix Haskell98 short description in documentation - - - - - 2420c555 by Ryan Scott at 2020-05-05T03:24:53-04:00 Add regression tests for #16244, #16245, #16758 Commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70 ended up fixing quite a few bugs: * This commit fixes #16244 completely. A regression test has been added. * This commit fixes one program from #16245. (The program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211369 still panics, and the program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211400 still loops infinitely.) A regression test has been added for this program. * This commit fixes #16758. Accordingly, this patch removes the `expect_broken` label from the `T16758` test case, moves it from `should_compile` to `should_fail` (as it should produce an error message), and checks in the expected stderr. - - - - - 40c71c2c by Sylvain Henry at 2020-05-05T03:25:31-04:00 Fix colorized error messages (#18128) In b3df9e780fb2f5658412c644849cd0f1e6f50331 I broke colorized messages by using "dump" style instead of "user" style. This commits fixes it. - - - - - 7ab6ab09 by Richard Eisenberg at 2020-05-06T04:39:32-04:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG ------------------------- - - - - - 420b957d by Ben Gamari at 2020-05-06T04:40:08-04:00 rts: Zero block flags with -DZ Block flags are very useful for determining the state of a block. However, some block allocator users don't touch them, leading to misleading values. Ensure that we zero then when zero-on-gc is set. This is safe and makes the flags more useful during debugging. - - - - - 740b3b8d by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix incorrect failed_to_evac value during deadlock gc Previously we would incorrectly set the failed_to_evac flag if we evacuated a value due to a deadlock GC. This would cause us to mark more things as dirty than strictly necessary. It also turned up a nasty but which I will fix next. - - - - - b2d72c75 by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - 9f3e6884 by Zubin Duggal at 2020-05-06T04:41:08-04:00 Allow atomic update of NameCache in readHieFile The situation arises in ghcide where multiple different threads may need to update the name cache, therefore with the older interface it could happen that you start reading a hie file with name cache A and produce name cache A + B, but another thread in the meantime updated the namecache to A + C. Therefore if you write the new namecache you will lose the A' updates from the second thread. Updates haddock submodule - - - - - edec6a6c by Ryan Scott at 2020-05-06T04:41:57-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _)`. Fixes #18127. - - - - - a95e7fe0 by Ömer Sinan Ağacan at 2020-05-06T04:42:39-04:00 ELF linker: increment curSymbol after filling in fields of current entry The bug was introduced in a8b7cef4d45 which added a field to the `symbols` array elements and then updated this code incorrectly: - oc->symbols[curSymbol++] = nm; + oc->symbols[curSymbol++].name = nm; + oc->symbols[curSymbol].addr = symbol->addr; - - - - - cab1871a by Sylvain Henry at 2020-05-06T04:43:21-04:00 Move LeadingUnderscore into Platform (#17957) Avoid direct use of DynFlags to know if symbols must be prefixed by an underscore. - - - - - 94e7c563 by Sylvain Henry at 2020-05-06T04:43:21-04:00 Don't use DynFlags in showLinkerState (#17957) - - - - - 9afd9251 by Ryan Scott at 2020-05-06T04:43:58-04:00 Refactoring: Use bindSigTyVarsFV in rnMethodBinds `rnMethodBinds` was explicitly using `xoptM` to determine if `ScopedTypeVariables` is enabled before bringing type variables bound by the class/instance header into scope. However, this `xoptM` logic is already performed by the `bindSigTyVarsFV` function. This patch uses `bindSigTyVarsFV` in `rnMethodBinds` to reduce the number of places where we need to consult if `ScopedTypeVariables` is on. This is purely refactoring, and there should be no user-visible change in behavior. - - - - - 6f6d72b2 by Brian Foley at 2020-05-08T15:29:25-04:00 Remove further dead code found by a simple Python script. Avoid removing some functions that are part of an API even though they're not used in-tree at the moment. - - - - - 78bf8bf9 by Julien Debon at 2020-05-08T15:29:28-04:00 Add doc examples for Bifoldable See #17929 - - - - - 66f0a847 by Julien Debon at 2020-05-08T15:29:29-04:00 doc (Bitraversable): Add examples to Bitraversable * Add examples to Data.Bitraversable * Fix formatting for (,) in Bitraversable and Bifoldable * Fix mistake on bimapAccumR documentation See #17929 - - - - - 9749fe12 by Baldur Blöndal at 2020-05-08T15:29:32-04:00 Specify kind variables for inferred kinds in base. - - - - - 4e9aef9e by John Ericson at 2020-05-08T15:29:36-04:00 HsSigWcTypeScoping: Pull in documentation from stray location - - - - - f4d5c6df by John Ericson at 2020-05-08T15:29:36-04:00 Rename local `real_fvs` to `implicit_vs` It doesn't make sense to call the "free" variables we are about to implicitly bind the real ones. - - - - - 20570b4b by John Ericson at 2020-05-08T15:29:36-04:00 A few tiny style nits with renaming - Use case rather than guards that repeatedly scrutenize same thing. - No need for view pattern when `L` is fine. - Use type synnonym to convey the intent like elsewhere. - - - - - 09ac8de5 by John Ericson at 2020-05-08T15:29:36-04:00 Add `forAllOrNothing` function with note - - - - - bb35c0e5 by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Document lawlessness of Ap's Num instance - - - - - cdd229ff by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply suggestion to libraries/base/Data/Monoid.hs - - - - - 926d2aab by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply more suggestions from Simon Jakobi - - - - - 7a763cff by Adam Gundry at 2020-05-08T15:29:41-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. - - - - - 88e3c815 by Simon Peyton Jones at 2020-05-08T15:29:41-04:00 Fix specialisation for DFuns When specialising a DFun we must take care to saturate the unfolding. See Note [Specialising DFuns] in Specialise. Fixes #18120 - - - - - 86c77b36 by Greg Steuck at 2020-05-08T15:29:45-04:00 Remove unused SEGMENT_PROT_RWX It's been unused for a year and is problematic on any OS which requires W^X for security. - - - - - fdcb8f73 by Ben Gamari at 2020-05-09T18:38:46-04:00 GHC.Core.Unfold: Refactor traceInline This reduces duplication as well as fixes a bug wherein -dinlining-check would override -ddump-inlinings. Moreover, the new variant - - - - - cd08ea4f by Ben Gamari at 2020-05-09T18:40:42-04:00 typecheck: Avoid unnecessary tracing allocations While ticky-profiling the typechecker I noticed that hundreds of millions of SDocs are being allocated just in case -ddump-*-trace is enabled. This is awful. We avoid this by ensuring that the dump flag check is inlined into the call site, ensuring that the tracing document needn't be allocated unless it's actually needed. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - compiler/prelude/PrelNames.hs-boot → compiler/GHC/Builtin/Names.hs-boot - compiler/prelude/THNames.hs → compiler/GHC/Builtin/Names/TH.hs - compiler/prelude/PrimOp.hs → compiler/GHC/Builtin/PrimOps.hs - + compiler/GHC/Builtin/PrimOps.hs-boot - compiler/prelude/TysWiredIn.hs → compiler/GHC/Builtin/Types.hs - compiler/prelude/TysWiredIn.hs-boot → compiler/GHC/Builtin/Types.hs-boot - compiler/typecheck/TcTypeNats.hs → compiler/GHC/Builtin/Types/Literals.hs - compiler/prelude/TysPrim.hs → compiler/GHC/Builtin/Types/Prim.hs - compiler/prelude/KnownUniques.hs → compiler/GHC/Builtin/Uniques.hs - compiler/prelude/KnownUniques.hs-boot → compiler/GHC/Builtin/Uniques.hs-boot - compiler/prelude/PrelInfo.hs → compiler/GHC/Builtin/Utils.hs - compiler/prelude/primops.txt.pp → compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.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/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Block.hs - compiler/GHC/Cmm/Dataflow/Collections.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/815f0124db8d2fc0517d888a1bb5f02c58118408...cd08ea4f759be6b316b1a4a91a493ac5d4b936d7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/815f0124db8d2fc0517d888a1bb5f02c58118408...cd08ea4f759be6b316b1a4a91a493ac5d4b936d7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 9 23:26:14 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 09 May 2020 19:26:14 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T14781 Message-ID: <5eb73c1649eb3_6167119142e89895034@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/T14781 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T14781 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 10 00:03:15 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 09 May 2020 20:03:15 -0400 Subject: [Git][ghc/ghc][wip/caf-cleanups] 70 commits: Switch order on `GhcMake.IsBoot` Message-ID: <5eb744c3acb73_61673f819aad978c9905282@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/caf-cleanups at Glasgow Haskell Compiler / GHC Commits: b0fbfc75 by John Ericson at 2020-04-24T12:07:14-04:00 Switch order on `GhcMake.IsBoot` In !1798 we were requested to replace many `Bool`s with this data type. But those bools had `False` meaning `NotBoot`, so the `Ord` instance would be flipped if we use this data-type as-is. Since the planned formally-`Bool` occurrences vastly outnumber the current occurrences, we figured it would be better to conform the `Ord` instance to how the `Bool` is used now, fixing any issues, rather than fix them currently with the bigger refactor later in !1798. That way, !1798 can be a "pure" refactor with no behavioral changes. - - - - - af332442 by Sylvain Henry at 2020-04-26T13:55:14-04:00 Modules: Utils and Data (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - cd4434c8 by Sylvain Henry at 2020-04-26T13:55:16-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 22bf5c73 by Ömer Sinan Ağacan at 2020-04-26T13:55:22-04:00 Tweak includes in non-moving GC headers We don't use hash tables in non-moving GC so remove the includes. This breaks Compact.c as existing includes no longer include Hash.h, so include Hash.h explicitly in Compact.c. - - - - - 99823ed2 by Sylvain Henry at 2020-04-27T20:24:46-04:00 TH: fix Show/Eq/Ord instances for Bytes (#16457) We shouldn't compare pointer values but the actual bytes. - - - - - c62271a2 by Alp Mestanogullari at 2020-04-27T20:25:33-04:00 hadrian: always capture both stdout and stderr when running a builder fails The idea being that when a builder('s command) fails, we quite likely want to have all the information available to figure out why. Depending on the builder _and_ the particular problem, the useful bits of information can be printed on stdout or stderr. We accomplish this by defining a simple wrapper for Shake's `cmd` function, that just _always_ captures both streams in case the command returns a non-zero exit code, and by using this wrapper everywhere in `hadrian/src/Builder.hs`. Fixes #18089. - - - - - 4b9764db by Ryan Scott at 2020-04-28T15:40:04-04:00 Define a Quote IO instance Fixes #18103. - - - - - 518a63d4 by Ryan Scott at 2020-04-28T15:40:42-04:00 Make boxed 1-tuples have known keys Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. - - - - - 2cfc4ab9 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Document backpack fields in DynFlags - - - - - 10a2ba90 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 69562e34 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 9e2c8e0e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - ea717aa4 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 10d15f1e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 8bfb0219 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - 71484b09 by Alexis King at 2020-04-30T01:57:35-04:00 Allow block arguments in arrow control operators Arrow control operators have their own entries in the grammar, so they did not cooperate with BlockArguments. This was just a minor oversight, so this patch adjusts the grammar to add the desired behavior. fixes #18050 - - - - - a48cd2a0 by Alexis King at 2020-04-30T01:57:35-04:00 Allow LambdaCase to be used as a command in proc notation - - - - - f4d3773c by Alexis King at 2020-04-30T01:57:35-04:00 Document BlockArguments/LambdaCase support in arrow notation - - - - - 5bdfdd13 by Simon Peyton Jones at 2020-04-30T01:58:15-04:00 Add tests for #17873 - - - - - 19b701c2 by Simon Peyton Jones at 2020-04-30T07:30:13-04:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - 014ef4a3 by Matthew Pickering at 2020-04-30T07:30:50-04:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 2aa67611 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - 54dad3cf by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - 99ff8145 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 05b0a9fd by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 Remove OneShotInfo field of LFReEntrant, document OneShotInfo The field is only used in withNewTickyCounterFun and it's easier to directly pass a parameter for one-shot info to withNewTickyCounterFun instead of passing it via LFReEntrant. This also makes !2842 simpler. Other changes: - New Note (by SPJ) [OneShotInfo overview] added. - Arity argument of thunkCode removed as it's always 0. - - - - - a43620c6 by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 GHC.StgToCmm.Ticky: remove a few unused stuff - - - - - 780de9e1 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Use platform in Iface Binary - - - - - f8386c7b by Sylvain Henry at 2020-05-01T10:37:39-04:00 Refactor PprDebug handling If `-dppr-debug` is set, then PprUser and PprDump styles are silently replaced with PprDebug style. This was done in `mkUserStyle` and `mkDumpStyle` smart constructors. As a consequence they needed a DynFlags parameter. Now we keep the original PprUser and PprDump styles until they are used to create an `SDocContext`. I.e. the substitution is only performed in `initSDocContext`. - - - - - b3df9e78 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Remove PprStyle param of logging actions Use `withPprStyle` instead to apply a specific style to a SDoc. - - - - - de9fc995 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Fully remove PprDebug PprDebug was a pain to deal with consistently as it is implied by `-dppr-debug` but it isn't really a PprStyle. We remove it completely and query the appropriate SDoc flag instead (`sdocPprDebug`) via helpers (`getPprDebug` and its friends). - - - - - 8b51fcbd by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Only call checkSingle if we would report warnings - - - - - fd7ea0fe by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 7bfe9ac5 by Ben Gamari at 2020-05-03T04:41:33-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. - - - - - c560dd07 by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Move eventlog documentation users guide - - - - - 02543d5e by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Add documentation for non-moving GC events - - - - - b465dd45 by Alexis King at 2020-05-03T04:42:12-04:00 Flatten nested casts in the simple optimizer Normally, we aren’t supposed to generated any nested casts, since mkCast takes care to flatten them, but the simple optimizer didn’t use mkCast, so they could show up after inlining. This isn’t really a problem, since the simplifier will clean them up immediately anyway, but it can clutter the -ddump-ds output, and it’s an extremely easy fix. closes #18112 - - - - - 8bdc03d6 by Simon Peyton Jones at 2020-05-04T01:56:59-04:00 Don't return a panic in tcNestedSplice In GHC.Tc.Gen.Splice.tcNestedSplice we were returning a typechecked expression of "panic". That is usually OK, because the result is discarded. But it happens that tcApp now looks at the typechecked expression, trivially, to ask if it is tagToEnum. So being bottom is bad. Moreover a debug-trace might print it out. So better to return a civilised expression, even though it is usually discarded. - - - - - 0bf640b1 by Baldur Blöndal at 2020-05-04T01:57:36-04:00 Don't require parentheses around via type (`-XDerivingVia'). Fixes #18130". - - - - - 30272412 by Artem Pelenitsyn at 2020-05-04T13:19:59-04:00 Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) - - - - - b9f7c08f by jneira at 2020-05-04T13:20:37-04:00 Remove unused hs-boot file - - - - - 1d8f80cd by Sylvain Henry at 2020-05-05T03:22:46-04:00 Remove references to -package-key * remove references to `-package-key` which has been removed in 2016 (240ddd7c39536776e955e881d709bbb039b48513) * remove support for `-this-package-key` which has been deprecated at the same time - - - - - 7bc3a65b by Sylvain Henry at 2020-05-05T03:23:31-04:00 Remove SpecConstrAnnotation (#13681) This has been deprecated since 2013. Use GHC.Types.SPEC instead. Make GHC.Exts "not-home" for haddock Metric Decrease: haddock.base - - - - - 3c862f63 by DenisFrezzato at 2020-05-05T03:24:15-04:00 Fix Haskell98 short description in documentation - - - - - 2420c555 by Ryan Scott at 2020-05-05T03:24:53-04:00 Add regression tests for #16244, #16245, #16758 Commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70 ended up fixing quite a few bugs: * This commit fixes #16244 completely. A regression test has been added. * This commit fixes one program from #16245. (The program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211369 still panics, and the program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211400 still loops infinitely.) A regression test has been added for this program. * This commit fixes #16758. Accordingly, this patch removes the `expect_broken` label from the `T16758` test case, moves it from `should_compile` to `should_fail` (as it should produce an error message), and checks in the expected stderr. - - - - - 40c71c2c by Sylvain Henry at 2020-05-05T03:25:31-04:00 Fix colorized error messages (#18128) In b3df9e780fb2f5658412c644849cd0f1e6f50331 I broke colorized messages by using "dump" style instead of "user" style. This commits fixes it. - - - - - 7ab6ab09 by Richard Eisenberg at 2020-05-06T04:39:32-04:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG ------------------------- - - - - - 420b957d by Ben Gamari at 2020-05-06T04:40:08-04:00 rts: Zero block flags with -DZ Block flags are very useful for determining the state of a block. However, some block allocator users don't touch them, leading to misleading values. Ensure that we zero then when zero-on-gc is set. This is safe and makes the flags more useful during debugging. - - - - - 740b3b8d by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix incorrect failed_to_evac value during deadlock gc Previously we would incorrectly set the failed_to_evac flag if we evacuated a value due to a deadlock GC. This would cause us to mark more things as dirty than strictly necessary. It also turned up a nasty but which I will fix next. - - - - - b2d72c75 by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - 9f3e6884 by Zubin Duggal at 2020-05-06T04:41:08-04:00 Allow atomic update of NameCache in readHieFile The situation arises in ghcide where multiple different threads may need to update the name cache, therefore with the older interface it could happen that you start reading a hie file with name cache A and produce name cache A + B, but another thread in the meantime updated the namecache to A + C. Therefore if you write the new namecache you will lose the A' updates from the second thread. Updates haddock submodule - - - - - edec6a6c by Ryan Scott at 2020-05-06T04:41:57-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _)`. Fixes #18127. - - - - - a95e7fe0 by Ömer Sinan Ağacan at 2020-05-06T04:42:39-04:00 ELF linker: increment curSymbol after filling in fields of current entry The bug was introduced in a8b7cef4d45 which added a field to the `symbols` array elements and then updated this code incorrectly: - oc->symbols[curSymbol++] = nm; + oc->symbols[curSymbol++].name = nm; + oc->symbols[curSymbol].addr = symbol->addr; - - - - - cab1871a by Sylvain Henry at 2020-05-06T04:43:21-04:00 Move LeadingUnderscore into Platform (#17957) Avoid direct use of DynFlags to know if symbols must be prefixed by an underscore. - - - - - 94e7c563 by Sylvain Henry at 2020-05-06T04:43:21-04:00 Don't use DynFlags in showLinkerState (#17957) - - - - - 9afd9251 by Ryan Scott at 2020-05-06T04:43:58-04:00 Refactoring: Use bindSigTyVarsFV in rnMethodBinds `rnMethodBinds` was explicitly using `xoptM` to determine if `ScopedTypeVariables` is enabled before bringing type variables bound by the class/instance header into scope. However, this `xoptM` logic is already performed by the `bindSigTyVarsFV` function. This patch uses `bindSigTyVarsFV` in `rnMethodBinds` to reduce the number of places where we need to consult if `ScopedTypeVariables` is on. This is purely refactoring, and there should be no user-visible change in behavior. - - - - - 6f6d72b2 by Brian Foley at 2020-05-08T15:29:25-04:00 Remove further dead code found by a simple Python script. Avoid removing some functions that are part of an API even though they're not used in-tree at the moment. - - - - - 78bf8bf9 by Julien Debon at 2020-05-08T15:29:28-04:00 Add doc examples for Bifoldable See #17929 - - - - - 66f0a847 by Julien Debon at 2020-05-08T15:29:29-04:00 doc (Bitraversable): Add examples to Bitraversable * Add examples to Data.Bitraversable * Fix formatting for (,) in Bitraversable and Bifoldable * Fix mistake on bimapAccumR documentation See #17929 - - - - - 9749fe12 by Baldur Blöndal at 2020-05-08T15:29:32-04:00 Specify kind variables for inferred kinds in base. - - - - - 4e9aef9e by John Ericson at 2020-05-08T15:29:36-04:00 HsSigWcTypeScoping: Pull in documentation from stray location - - - - - f4d5c6df by John Ericson at 2020-05-08T15:29:36-04:00 Rename local `real_fvs` to `implicit_vs` It doesn't make sense to call the "free" variables we are about to implicitly bind the real ones. - - - - - 20570b4b by John Ericson at 2020-05-08T15:29:36-04:00 A few tiny style nits with renaming - Use case rather than guards that repeatedly scrutenize same thing. - No need for view pattern when `L` is fine. - Use type synnonym to convey the intent like elsewhere. - - - - - 09ac8de5 by John Ericson at 2020-05-08T15:29:36-04:00 Add `forAllOrNothing` function with note - - - - - bb35c0e5 by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Document lawlessness of Ap's Num instance - - - - - cdd229ff by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply suggestion to libraries/base/Data/Monoid.hs - - - - - 926d2aab by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply more suggestions from Simon Jakobi - - - - - 7a763cff by Adam Gundry at 2020-05-08T15:29:41-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. - - - - - 88e3c815 by Simon Peyton Jones at 2020-05-08T15:29:41-04:00 Fix specialisation for DFuns When specialising a DFun we must take care to saturate the unfolding. See Note [Specialising DFuns] in Specialise. Fixes #18120 - - - - - 86c77b36 by Greg Steuck at 2020-05-08T15:29:45-04:00 Remove unused SEGMENT_PROT_RWX It's been unused for a year and is problematic on any OS which requires W^X for security. - - - - - 7da0ca4d by Ben Gamari at 2020-05-09T19:36:36-04:00 Add few cleanups of the CAF logic - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/PrimOps.hs-boot - 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/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/ByteCode/Asm.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/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Block.hs - compiler/GHC/Cmm/Dataflow/Collections.hs - compiler/GHC/Cmm/Dataflow/Graph.hs - compiler/GHC/Cmm/Dataflow/Label.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Expr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7eb451f9cb25f316a94f470943ca3e9747d9e2a7...7da0ca4d730624137271e41671294140a7a64f5e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7eb451f9cb25f316a94f470943ca3e9747d9e2a7...7da0ca4d730624137271e41671294140a7a64f5e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 10 00:41:49 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 09 May 2020 20:41:49 -0400 Subject: [Git][ghc/ghc][wip/caf-cleanups] Add few cleanups of the CAF logic Message-ID: <5eb74dcd33920_61673f81a3bd711c992130@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/caf-cleanups at Glasgow Haskell Compiler / GHC Commits: f5c3ea83 by Ben Gamari at 2020-05-09T20:05:38-04:00 Add few cleanups of the CAF logic - - - - - 4 changed files: - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Types/Var/Set.hs Changes: ===================================== compiler/GHC/Cmm/Info/Build.hs ===================================== @@ -12,6 +12,7 @@ import GHC.Prelude hiding (succ) import GHC.Types.Id import GHC.Types.Id.Info +import GHC.Types.Var.Set import GHC.Cmm.BlockId import GHC.Cmm.Dataflow.Block import GHC.Cmm.Dataflow.Graph @@ -459,7 +460,7 @@ type CAFSet = Set CAFLabel type CAFEnv = LabelMap CAFSet mkCAFLabel :: CLabel -> CAFLabel -mkCAFLabel lbl = CAFLabel $! toClosureLbl lbl +mkCAFLabel lbl = CAFLabel (toClosureLbl lbl) -- This is a label that we can put in an SRT. It *must* be a closure label, -- pointing to either a FUN_STATIC, THUNK_STATIC, or CONSTR. @@ -736,10 +737,11 @@ getStaticFuns decls = type SRTMap = Map CAFLabel (Maybe SRTEntry) --- | Given SRTMap of a module returns the set of non-CAFFY names in the module. --- Any Names not in the set are CAFFY. -srtMapNonCAFs :: SRTMap -> NameSet -srtMapNonCAFs srtMap = mkNameSet (mapMaybe get_name (Map.toList srtMap)) +-- | Given 'SRTMap' of a module, returns the set of non-CAFFY names in the +-- module. Any 'Name's not in the set are CAFFY. +srtMapNonCAFs :: SRTMap -> NonCaffySet +srtMapNonCAFs srtMap = + NonCaffySet $ mkNameSet (mapMaybe get_name (Map.toList srtMap)) where get_name (CAFLabel l, Nothing) = hasHaskellName l get_name (_l, Just _srt_entry) = Nothing ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -1384,7 +1384,7 @@ hscWriteIface dflags iface no_change mod_location = do -- | Compile to hard-code. hscGenHardCode :: HscEnv -> CgGuts -> ModLocation -> FilePath - -> IO (FilePath, Maybe FilePath, [(ForeignSrcLang, FilePath)], NameSet) + -> IO (FilePath, Maybe FilePath, [(ForeignSrcLang, FilePath)], NonCaffySet) -- ^ @Just f@ <=> _stub.c is f hscGenHardCode hsc_env cgguts location output_filename = do let CgGuts{ -- This is the last use of the ModGuts in a compilation. @@ -1541,7 +1541,7 @@ doCodeGen :: HscEnv -> Module -> [TyCon] -> CollectedCCs -> [StgTopBinding] -> HpcInfo - -> IO (Stream IO CmmGroupSRTs NameSet) + -> IO (Stream IO CmmGroupSRTs NonCaffySet) -- Note we produce a 'Stream' of CmmGroups, so that the -- backend can be run incrementally. Otherwise it generates all -- the C-- up front, which has a significant space cost. ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -46,6 +46,7 @@ import GHC.Hs import GHC.Driver.Types import GHC.Driver.Session import GHC.Types.Var.Env +import GHC.Types.Var.Set import GHC.Types.Var import GHC.Types.Name import GHC.Types.Avail @@ -100,7 +101,7 @@ mkPartialIface hsc_env mod_details -- | Fully instantiate a interface -- Adds fingerprints and potentially code generator produced information. -mkFullIface :: HscEnv -> PartialModIface -> Maybe NameSet -> IO ModIface +mkFullIface :: HscEnv -> PartialModIface -> Maybe NonCaffySet -> IO ModIface mkFullIface hsc_env partial_iface mb_non_cafs = do let decls | gopt Opt_OmitInterfacePragmas (hsc_dflags hsc_env) @@ -117,9 +118,9 @@ mkFullIface hsc_env partial_iface mb_non_cafs = do return full_iface -updateDeclCafInfos :: [IfaceDecl] -> Maybe NameSet -> [IfaceDecl] +updateDeclCafInfos :: [IfaceDecl] -> Maybe NonCaffySet -> [IfaceDecl] updateDeclCafInfos decls Nothing = decls -updateDeclCafInfos decls (Just non_cafs) = map update_decl decls +updateDeclCafInfos decls (Just (NonCaffySet non_cafs)) = map update_decl decls where update_decl decl | IfaceId nm ty details infos <- decl ===================================== compiler/GHC/Types/Var/Set.hs ===================================== @@ -42,6 +42,9 @@ module GHC.Types.Var.Set ( sizeDVarSet, seqDVarSet, partitionDVarSet, dVarSetToVarSet, + + -- ** non-CAFfy sets + NonCaffySet(..) ) where #include "HsVersions.h" @@ -352,3 +355,8 @@ transCloDVarSet fn seeds | otherwise = go (acc `unionDVarSet` new_vs) new_vs where new_vs = fn candidates `minusDVarSet` acc + +-- | 'Id's which have no CAF references. This is a result of analysis of C--. +-- It is always safe to use an empty 'NonCaffySet'. TODO Refer to Note. +newtype NonCaffySet = NonCaffySet NameSet + deriving (Semigroup, Monoid) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f5c3ea832be002ad9fad95f96446ac5275fbff87 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f5c3ea832be002ad9fad95f96446ac5275fbff87 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 10 00:42:19 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 09 May 2020 20:42:19 -0400 Subject: [Git][ghc/ghc][wip/sjakobi/nondetfolds] 175 commits: Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie Message-ID: <5eb74debd0c82_6167119142e899217e7@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/sjakobi/nondetfolds at Glasgow Haskell Compiler / GHC Commits: ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.0.0 This requires bumping the `exceptions` and `text` submodules to bring in commits that bump their respective upper version bounds on `template-haskell`. Fixes #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - ffd7eef2 by Takenobu Tani at 2020-04-22T23:09:50-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - e8a5d81b by Jonathan DK Gibbons at 2020-04-22T23:10:28-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - dcb7fe5a by John Ericson at 2020-04-22T23:10:28-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - cde23cd4 by John Ericson at 2020-04-22T23:10:28-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - 72cb6bcc by John Ericson at 2020-04-22T23:10:28-04:00 Generalize type of `matchCanFail` - - - - - 401f7bb3 by John Ericson at 2020-04-22T23:10:28-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 6c9fae23 by Alexis King at 2020-04-22T23:11:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 48b8951e by Roland Senn at 2020-04-22T23:11:51-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 34a45ee6 by Peter Trommler at 2020-04-22T23:12:27-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - ffde2348 by Simon Peyton Jones at 2020-04-22T23:13:06-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 6f84aca3 by Ben Gamari at 2020-04-22T23:13:43-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - c29f0fa6 by Andreas Klebinger at 2020-04-22T23:14:21-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 4b4a8b60 by Ben Gamari at 2020-04-22T23:14:57-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 831b6642 by Moritz Angermann at 2020-04-22T23:15:33-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - c409961a by Ryan Scott at 2020-04-22T23:16:12-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 125aa2b8 by Ömer Sinan Ağacan at 2020-04-22T23:16:51-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - 8ea37b01 by Sylvain Henry at 2020-04-22T23:17:34-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - cd8409c2 by Ryan Scott at 2020-04-23T11:39:24-04:00 Create di_scoped_tvs for associated data family instances properly See `Note [Associated data family instances and di_scoped_tvs]` in `GHC.Tc.TyCl.Instance`, which explains all of the moving parts. Fixes #18055. - - - - - 339e8ece by Ben Gamari at 2020-04-23T11:40:02-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 5946c85a by Ben Gamari at 2020-04-23T11:40:38-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - c42754d5 by John Ericson at 2020-04-23T18:32:43-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 72da0c29 by mniip at 2020-04-23T18:33:21-04:00 Add :doc to GHC.Prim - - - - - 2c23e2e3 by mniip at 2020-04-23T18:33:21-04:00 Include docs for non-primop entries in primops.txt as well - - - - - 0ac29c88 by mniip at 2020-04-23T18:33:21-04:00 GHC.Prim docs: note and test - - - - - b0fbfc75 by John Ericson at 2020-04-24T12:07:14-04:00 Switch order on `GhcMake.IsBoot` In !1798 we were requested to replace many `Bool`s with this data type. But those bools had `False` meaning `NotBoot`, so the `Ord` instance would be flipped if we use this data-type as-is. Since the planned formally-`Bool` occurrences vastly outnumber the current occurrences, we figured it would be better to conform the `Ord` instance to how the `Bool` is used now, fixing any issues, rather than fix them currently with the bigger refactor later in !1798. That way, !1798 can be a "pure" refactor with no behavioral changes. - - - - - af332442 by Sylvain Henry at 2020-04-26T13:55:14-04:00 Modules: Utils and Data (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - cd4434c8 by Sylvain Henry at 2020-04-26T13:55:16-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 22bf5c73 by Ömer Sinan Ağacan at 2020-04-26T13:55:22-04:00 Tweak includes in non-moving GC headers We don't use hash tables in non-moving GC so remove the includes. This breaks Compact.c as existing includes no longer include Hash.h, so include Hash.h explicitly in Compact.c. - - - - - 99823ed2 by Sylvain Henry at 2020-04-27T20:24:46-04:00 TH: fix Show/Eq/Ord instances for Bytes (#16457) We shouldn't compare pointer values but the actual bytes. - - - - - c62271a2 by Alp Mestanogullari at 2020-04-27T20:25:33-04:00 hadrian: always capture both stdout and stderr when running a builder fails The idea being that when a builder('s command) fails, we quite likely want to have all the information available to figure out why. Depending on the builder _and_ the particular problem, the useful bits of information can be printed on stdout or stderr. We accomplish this by defining a simple wrapper for Shake's `cmd` function, that just _always_ captures both streams in case the command returns a non-zero exit code, and by using this wrapper everywhere in `hadrian/src/Builder.hs`. Fixes #18089. - - - - - 4b9764db by Ryan Scott at 2020-04-28T15:40:04-04:00 Define a Quote IO instance Fixes #18103. - - - - - 518a63d4 by Ryan Scott at 2020-04-28T15:40:42-04:00 Make boxed 1-tuples have known keys Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. - - - - - 2cfc4ab9 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Document backpack fields in DynFlags - - - - - 10a2ba90 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 69562e34 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 9e2c8e0e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - ea717aa4 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 10d15f1e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 8bfb0219 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - 71484b09 by Alexis King at 2020-04-30T01:57:35-04:00 Allow block arguments in arrow control operators Arrow control operators have their own entries in the grammar, so they did not cooperate with BlockArguments. This was just a minor oversight, so this patch adjusts the grammar to add the desired behavior. fixes #18050 - - - - - a48cd2a0 by Alexis King at 2020-04-30T01:57:35-04:00 Allow LambdaCase to be used as a command in proc notation - - - - - f4d3773c by Alexis King at 2020-04-30T01:57:35-04:00 Document BlockArguments/LambdaCase support in arrow notation - - - - - 5bdfdd13 by Simon Peyton Jones at 2020-04-30T01:58:15-04:00 Add tests for #17873 - - - - - 19b701c2 by Simon Peyton Jones at 2020-04-30T07:30:13-04:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - 014ef4a3 by Matthew Pickering at 2020-04-30T07:30:50-04:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 2aa67611 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - 54dad3cf by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - 99ff8145 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 05b0a9fd by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 Remove OneShotInfo field of LFReEntrant, document OneShotInfo The field is only used in withNewTickyCounterFun and it's easier to directly pass a parameter for one-shot info to withNewTickyCounterFun instead of passing it via LFReEntrant. This also makes !2842 simpler. Other changes: - New Note (by SPJ) [OneShotInfo overview] added. - Arity argument of thunkCode removed as it's always 0. - - - - - a43620c6 by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 GHC.StgToCmm.Ticky: remove a few unused stuff - - - - - 780de9e1 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Use platform in Iface Binary - - - - - f8386c7b by Sylvain Henry at 2020-05-01T10:37:39-04:00 Refactor PprDebug handling If `-dppr-debug` is set, then PprUser and PprDump styles are silently replaced with PprDebug style. This was done in `mkUserStyle` and `mkDumpStyle` smart constructors. As a consequence they needed a DynFlags parameter. Now we keep the original PprUser and PprDump styles until they are used to create an `SDocContext`. I.e. the substitution is only performed in `initSDocContext`. - - - - - b3df9e78 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Remove PprStyle param of logging actions Use `withPprStyle` instead to apply a specific style to a SDoc. - - - - - de9fc995 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Fully remove PprDebug PprDebug was a pain to deal with consistently as it is implied by `-dppr-debug` but it isn't really a PprStyle. We remove it completely and query the appropriate SDoc flag instead (`sdocPprDebug`) via helpers (`getPprDebug` and its friends). - - - - - 8b51fcbd by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Only call checkSingle if we would report warnings - - - - - fd7ea0fe by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 7bfe9ac5 by Ben Gamari at 2020-05-03T04:41:33-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. - - - - - c560dd07 by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Move eventlog documentation users guide - - - - - 02543d5e by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Add documentation for non-moving GC events - - - - - b465dd45 by Alexis King at 2020-05-03T04:42:12-04:00 Flatten nested casts in the simple optimizer Normally, we aren’t supposed to generated any nested casts, since mkCast takes care to flatten them, but the simple optimizer didn’t use mkCast, so they could show up after inlining. This isn’t really a problem, since the simplifier will clean them up immediately anyway, but it can clutter the -ddump-ds output, and it’s an extremely easy fix. closes #18112 - - - - - 8bdc03d6 by Simon Peyton Jones at 2020-05-04T01:56:59-04:00 Don't return a panic in tcNestedSplice In GHC.Tc.Gen.Splice.tcNestedSplice we were returning a typechecked expression of "panic". That is usually OK, because the result is discarded. But it happens that tcApp now looks at the typechecked expression, trivially, to ask if it is tagToEnum. So being bottom is bad. Moreover a debug-trace might print it out. So better to return a civilised expression, even though it is usually discarded. - - - - - 0bf640b1 by Baldur Blöndal at 2020-05-04T01:57:36-04:00 Don't require parentheses around via type (`-XDerivingVia'). Fixes #18130". - - - - - 30272412 by Artem Pelenitsyn at 2020-05-04T13:19:59-04:00 Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) - - - - - b9f7c08f by jneira at 2020-05-04T13:20:37-04:00 Remove unused hs-boot file - - - - - 1d8f80cd by Sylvain Henry at 2020-05-05T03:22:46-04:00 Remove references to -package-key * remove references to `-package-key` which has been removed in 2016 (240ddd7c39536776e955e881d709bbb039b48513) * remove support for `-this-package-key` which has been deprecated at the same time - - - - - 7bc3a65b by Sylvain Henry at 2020-05-05T03:23:31-04:00 Remove SpecConstrAnnotation (#13681) This has been deprecated since 2013. Use GHC.Types.SPEC instead. Make GHC.Exts "not-home" for haddock Metric Decrease: haddock.base - - - - - 3c862f63 by DenisFrezzato at 2020-05-05T03:24:15-04:00 Fix Haskell98 short description in documentation - - - - - 2420c555 by Ryan Scott at 2020-05-05T03:24:53-04:00 Add regression tests for #16244, #16245, #16758 Commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70 ended up fixing quite a few bugs: * This commit fixes #16244 completely. A regression test has been added. * This commit fixes one program from #16245. (The program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211369 still panics, and the program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211400 still loops infinitely.) A regression test has been added for this program. * This commit fixes #16758. Accordingly, this patch removes the `expect_broken` label from the `T16758` test case, moves it from `should_compile` to `should_fail` (as it should produce an error message), and checks in the expected stderr. - - - - - 40c71c2c by Sylvain Henry at 2020-05-05T03:25:31-04:00 Fix colorized error messages (#18128) In b3df9e780fb2f5658412c644849cd0f1e6f50331 I broke colorized messages by using "dump" style instead of "user" style. This commits fixes it. - - - - - 7ab6ab09 by Richard Eisenberg at 2020-05-06T04:39:32-04:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG ------------------------- - - - - - 420b957d by Ben Gamari at 2020-05-06T04:40:08-04:00 rts: Zero block flags with -DZ Block flags are very useful for determining the state of a block. However, some block allocator users don't touch them, leading to misleading values. Ensure that we zero then when zero-on-gc is set. This is safe and makes the flags more useful during debugging. - - - - - 740b3b8d by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix incorrect failed_to_evac value during deadlock gc Previously we would incorrectly set the failed_to_evac flag if we evacuated a value due to a deadlock GC. This would cause us to mark more things as dirty than strictly necessary. It also turned up a nasty but which I will fix next. - - - - - b2d72c75 by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - 9f3e6884 by Zubin Duggal at 2020-05-06T04:41:08-04:00 Allow atomic update of NameCache in readHieFile The situation arises in ghcide where multiple different threads may need to update the name cache, therefore with the older interface it could happen that you start reading a hie file with name cache A and produce name cache A + B, but another thread in the meantime updated the namecache to A + C. Therefore if you write the new namecache you will lose the A' updates from the second thread. Updates haddock submodule - - - - - edec6a6c by Ryan Scott at 2020-05-06T04:41:57-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _)`. Fixes #18127. - - - - - a95e7fe0 by Ömer Sinan Ağacan at 2020-05-06T04:42:39-04:00 ELF linker: increment curSymbol after filling in fields of current entry The bug was introduced in a8b7cef4d45 which added a field to the `symbols` array elements and then updated this code incorrectly: - oc->symbols[curSymbol++] = nm; + oc->symbols[curSymbol++].name = nm; + oc->symbols[curSymbol].addr = symbol->addr; - - - - - cab1871a by Sylvain Henry at 2020-05-06T04:43:21-04:00 Move LeadingUnderscore into Platform (#17957) Avoid direct use of DynFlags to know if symbols must be prefixed by an underscore. - - - - - 94e7c563 by Sylvain Henry at 2020-05-06T04:43:21-04:00 Don't use DynFlags in showLinkerState (#17957) - - - - - 9afd9251 by Ryan Scott at 2020-05-06T04:43:58-04:00 Refactoring: Use bindSigTyVarsFV in rnMethodBinds `rnMethodBinds` was explicitly using `xoptM` to determine if `ScopedTypeVariables` is enabled before bringing type variables bound by the class/instance header into scope. However, this `xoptM` logic is already performed by the `bindSigTyVarsFV` function. This patch uses `bindSigTyVarsFV` in `rnMethodBinds` to reduce the number of places where we need to consult if `ScopedTypeVariables` is on. This is purely refactoring, and there should be no user-visible change in behavior. - - - - - 6f6d72b2 by Brian Foley at 2020-05-08T15:29:25-04:00 Remove further dead code found by a simple Python script. Avoid removing some functions that are part of an API even though they're not used in-tree at the moment. - - - - - 78bf8bf9 by Julien Debon at 2020-05-08T15:29:28-04:00 Add doc examples for Bifoldable See #17929 - - - - - 66f0a847 by Julien Debon at 2020-05-08T15:29:29-04:00 doc (Bitraversable): Add examples to Bitraversable * Add examples to Data.Bitraversable * Fix formatting for (,) in Bitraversable and Bifoldable * Fix mistake on bimapAccumR documentation See #17929 - - - - - 9749fe12 by Baldur Blöndal at 2020-05-08T15:29:32-04:00 Specify kind variables for inferred kinds in base. - - - - - 4e9aef9e by John Ericson at 2020-05-08T15:29:36-04:00 HsSigWcTypeScoping: Pull in documentation from stray location - - - - - f4d5c6df by John Ericson at 2020-05-08T15:29:36-04:00 Rename local `real_fvs` to `implicit_vs` It doesn't make sense to call the "free" variables we are about to implicitly bind the real ones. - - - - - 20570b4b by John Ericson at 2020-05-08T15:29:36-04:00 A few tiny style nits with renaming - Use case rather than guards that repeatedly scrutenize same thing. - No need for view pattern when `L` is fine. - Use type synnonym to convey the intent like elsewhere. - - - - - 09ac8de5 by John Ericson at 2020-05-08T15:29:36-04:00 Add `forAllOrNothing` function with note - - - - - bb35c0e5 by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Document lawlessness of Ap's Num instance - - - - - cdd229ff by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply suggestion to libraries/base/Data/Monoid.hs - - - - - 926d2aab by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply more suggestions from Simon Jakobi - - - - - 7a763cff by Adam Gundry at 2020-05-08T15:29:41-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. - - - - - 88e3c815 by Simon Peyton Jones at 2020-05-08T15:29:41-04:00 Fix specialisation for DFuns When specialising a DFun we must take care to saturate the unfolding. See Note [Specialising DFuns] in Specialise. Fixes #18120 - - - - - 86c77b36 by Greg Steuck at 2020-05-08T15:29:45-04:00 Remove unused SEGMENT_PROT_RWX It's been unused for a year and is problematic on any OS which requires W^X for security. - - - - - 9d97f4b5 by nineonine at 2020-05-08T15:30:03-04:00 Add test for #16167 - - - - - aa318338 by Ryan Scott at 2020-05-08T15:30:04-04:00 Bump exceptions submodule so that dist-boot is .gitignore'd `exceptions` is a stage-0 boot library as of commit 30272412fa437ab8e7a8035db94a278e10513413, which means that building `exceptions` in a GHC tree will generate a `dist-boot` directory. However, this directory was not specified in `exceptions`' `.gitignore` file, which causes it to dirty up the current `git` working directory. Accordingly, this bumps the `exceptions` submodule to commit ghc/packages/exceptions at 23c0b8a50d7592af37ca09beeec16b93080df98f, which adds `dist-boot` to the `.gitignore` file. - - - - - ea86360f by Ömer Sinan Ağacan at 2020-05-08T15:30:30-04:00 Linker.c: initialize n_symbols of ObjectCode with other fields - - - - - c64b94c6 by Simon Jakobi at 2020-05-09T20:42:08-04:00 Improve some folds over Uniq[D]FM * Replace some non-deterministic lazy folds with strict folds. * Replace some O(n log n) folds in deterministic order with O(n) non-deterministic folds. * Replace some folds with set-operations on the underlying IntMaps. This reduces max residency when compiling `nofib/spectral/simple/Main.hs` with -O0 by about 1%. Maximum residency when compiling Cabal also seems reduced on the order of 3-9%. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - CODEOWNERS - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - compiler/prelude/PrelNames.hs-boot → compiler/GHC/Builtin/Names.hs-boot - compiler/prelude/THNames.hs → compiler/GHC/Builtin/Names/TH.hs - compiler/prelude/PrimOp.hs → compiler/GHC/Builtin/PrimOps.hs - + compiler/GHC/Builtin/PrimOps.hs-boot - compiler/prelude/TysWiredIn.hs → compiler/GHC/Builtin/Types.hs - compiler/prelude/TysWiredIn.hs-boot → compiler/GHC/Builtin/Types.hs-boot - compiler/typecheck/TcTypeNats.hs → compiler/GHC/Builtin/Types/Literals.hs - compiler/prelude/TysPrim.hs → compiler/GHC/Builtin/Types/Prim.hs - compiler/prelude/KnownUniques.hs → compiler/GHC/Builtin/Uniques.hs - compiler/prelude/KnownUniques.hs-boot → compiler/GHC/Builtin/Uniques.hs-boot - compiler/prelude/PrelInfo.hs → compiler/GHC/Builtin/Utils.hs - compiler/prelude/primops.txt.pp → compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.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/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Block.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5006a7e1088511af71ef009debcbf97bb7e801a4...c64b94c63d4d1f3f9f81cda1122e6fc13b60476d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5006a7e1088511af71ef009debcbf97bb7e801a4...c64b94c63d4d1f3f9f81cda1122e6fc13b60476d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 10 00:53:54 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 09 May 2020 20:53:54 -0400 Subject: [Git][ghc/ghc][wip/T16806] 175 commits: Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie Message-ID: <5eb750a2a33b1_61673f81a3bd711c99337e1@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T16806 at Glasgow Haskell Compiler / GHC Commits: ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.0.0 This requires bumping the `exceptions` and `text` submodules to bring in commits that bump their respective upper version bounds on `template-haskell`. Fixes #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - ffd7eef2 by Takenobu Tani at 2020-04-22T23:09:50-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - e8a5d81b by Jonathan DK Gibbons at 2020-04-22T23:10:28-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - dcb7fe5a by John Ericson at 2020-04-22T23:10:28-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - cde23cd4 by John Ericson at 2020-04-22T23:10:28-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - 72cb6bcc by John Ericson at 2020-04-22T23:10:28-04:00 Generalize type of `matchCanFail` - - - - - 401f7bb3 by John Ericson at 2020-04-22T23:10:28-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 6c9fae23 by Alexis King at 2020-04-22T23:11:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 48b8951e by Roland Senn at 2020-04-22T23:11:51-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 34a45ee6 by Peter Trommler at 2020-04-22T23:12:27-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - ffde2348 by Simon Peyton Jones at 2020-04-22T23:13:06-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 6f84aca3 by Ben Gamari at 2020-04-22T23:13:43-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - c29f0fa6 by Andreas Klebinger at 2020-04-22T23:14:21-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 4b4a8b60 by Ben Gamari at 2020-04-22T23:14:57-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 831b6642 by Moritz Angermann at 2020-04-22T23:15:33-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - c409961a by Ryan Scott at 2020-04-22T23:16:12-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 125aa2b8 by Ömer Sinan Ağacan at 2020-04-22T23:16:51-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - 8ea37b01 by Sylvain Henry at 2020-04-22T23:17:34-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - cd8409c2 by Ryan Scott at 2020-04-23T11:39:24-04:00 Create di_scoped_tvs for associated data family instances properly See `Note [Associated data family instances and di_scoped_tvs]` in `GHC.Tc.TyCl.Instance`, which explains all of the moving parts. Fixes #18055. - - - - - 339e8ece by Ben Gamari at 2020-04-23T11:40:02-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 5946c85a by Ben Gamari at 2020-04-23T11:40:38-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - c42754d5 by John Ericson at 2020-04-23T18:32:43-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 72da0c29 by mniip at 2020-04-23T18:33:21-04:00 Add :doc to GHC.Prim - - - - - 2c23e2e3 by mniip at 2020-04-23T18:33:21-04:00 Include docs for non-primop entries in primops.txt as well - - - - - 0ac29c88 by mniip at 2020-04-23T18:33:21-04:00 GHC.Prim docs: note and test - - - - - b0fbfc75 by John Ericson at 2020-04-24T12:07:14-04:00 Switch order on `GhcMake.IsBoot` In !1798 we were requested to replace many `Bool`s with this data type. But those bools had `False` meaning `NotBoot`, so the `Ord` instance would be flipped if we use this data-type as-is. Since the planned formally-`Bool` occurrences vastly outnumber the current occurrences, we figured it would be better to conform the `Ord` instance to how the `Bool` is used now, fixing any issues, rather than fix them currently with the bigger refactor later in !1798. That way, !1798 can be a "pure" refactor with no behavioral changes. - - - - - af332442 by Sylvain Henry at 2020-04-26T13:55:14-04:00 Modules: Utils and Data (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - cd4434c8 by Sylvain Henry at 2020-04-26T13:55:16-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 22bf5c73 by Ömer Sinan Ağacan at 2020-04-26T13:55:22-04:00 Tweak includes in non-moving GC headers We don't use hash tables in non-moving GC so remove the includes. This breaks Compact.c as existing includes no longer include Hash.h, so include Hash.h explicitly in Compact.c. - - - - - 99823ed2 by Sylvain Henry at 2020-04-27T20:24:46-04:00 TH: fix Show/Eq/Ord instances for Bytes (#16457) We shouldn't compare pointer values but the actual bytes. - - - - - c62271a2 by Alp Mestanogullari at 2020-04-27T20:25:33-04:00 hadrian: always capture both stdout and stderr when running a builder fails The idea being that when a builder('s command) fails, we quite likely want to have all the information available to figure out why. Depending on the builder _and_ the particular problem, the useful bits of information can be printed on stdout or stderr. We accomplish this by defining a simple wrapper for Shake's `cmd` function, that just _always_ captures both streams in case the command returns a non-zero exit code, and by using this wrapper everywhere in `hadrian/src/Builder.hs`. Fixes #18089. - - - - - 4b9764db by Ryan Scott at 2020-04-28T15:40:04-04:00 Define a Quote IO instance Fixes #18103. - - - - - 518a63d4 by Ryan Scott at 2020-04-28T15:40:42-04:00 Make boxed 1-tuples have known keys Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. - - - - - 2cfc4ab9 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Document backpack fields in DynFlags - - - - - 10a2ba90 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 69562e34 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 9e2c8e0e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - ea717aa4 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 10d15f1e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 8bfb0219 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - 71484b09 by Alexis King at 2020-04-30T01:57:35-04:00 Allow block arguments in arrow control operators Arrow control operators have their own entries in the grammar, so they did not cooperate with BlockArguments. This was just a minor oversight, so this patch adjusts the grammar to add the desired behavior. fixes #18050 - - - - - a48cd2a0 by Alexis King at 2020-04-30T01:57:35-04:00 Allow LambdaCase to be used as a command in proc notation - - - - - f4d3773c by Alexis King at 2020-04-30T01:57:35-04:00 Document BlockArguments/LambdaCase support in arrow notation - - - - - 5bdfdd13 by Simon Peyton Jones at 2020-04-30T01:58:15-04:00 Add tests for #17873 - - - - - 19b701c2 by Simon Peyton Jones at 2020-04-30T07:30:13-04:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - 014ef4a3 by Matthew Pickering at 2020-04-30T07:30:50-04:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 2aa67611 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - 54dad3cf by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - 99ff8145 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 05b0a9fd by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 Remove OneShotInfo field of LFReEntrant, document OneShotInfo The field is only used in withNewTickyCounterFun and it's easier to directly pass a parameter for one-shot info to withNewTickyCounterFun instead of passing it via LFReEntrant. This also makes !2842 simpler. Other changes: - New Note (by SPJ) [OneShotInfo overview] added. - Arity argument of thunkCode removed as it's always 0. - - - - - a43620c6 by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 GHC.StgToCmm.Ticky: remove a few unused stuff - - - - - 780de9e1 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Use platform in Iface Binary - - - - - f8386c7b by Sylvain Henry at 2020-05-01T10:37:39-04:00 Refactor PprDebug handling If `-dppr-debug` is set, then PprUser and PprDump styles are silently replaced with PprDebug style. This was done in `mkUserStyle` and `mkDumpStyle` smart constructors. As a consequence they needed a DynFlags parameter. Now we keep the original PprUser and PprDump styles until they are used to create an `SDocContext`. I.e. the substitution is only performed in `initSDocContext`. - - - - - b3df9e78 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Remove PprStyle param of logging actions Use `withPprStyle` instead to apply a specific style to a SDoc. - - - - - de9fc995 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Fully remove PprDebug PprDebug was a pain to deal with consistently as it is implied by `-dppr-debug` but it isn't really a PprStyle. We remove it completely and query the appropriate SDoc flag instead (`sdocPprDebug`) via helpers (`getPprDebug` and its friends). - - - - - 8b51fcbd by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Only call checkSingle if we would report warnings - - - - - fd7ea0fe by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 7bfe9ac5 by Ben Gamari at 2020-05-03T04:41:33-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. - - - - - c560dd07 by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Move eventlog documentation users guide - - - - - 02543d5e by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Add documentation for non-moving GC events - - - - - b465dd45 by Alexis King at 2020-05-03T04:42:12-04:00 Flatten nested casts in the simple optimizer Normally, we aren’t supposed to generated any nested casts, since mkCast takes care to flatten them, but the simple optimizer didn’t use mkCast, so they could show up after inlining. This isn’t really a problem, since the simplifier will clean them up immediately anyway, but it can clutter the -ddump-ds output, and it’s an extremely easy fix. closes #18112 - - - - - 8bdc03d6 by Simon Peyton Jones at 2020-05-04T01:56:59-04:00 Don't return a panic in tcNestedSplice In GHC.Tc.Gen.Splice.tcNestedSplice we were returning a typechecked expression of "panic". That is usually OK, because the result is discarded. But it happens that tcApp now looks at the typechecked expression, trivially, to ask if it is tagToEnum. So being bottom is bad. Moreover a debug-trace might print it out. So better to return a civilised expression, even though it is usually discarded. - - - - - 0bf640b1 by Baldur Blöndal at 2020-05-04T01:57:36-04:00 Don't require parentheses around via type (`-XDerivingVia'). Fixes #18130". - - - - - 30272412 by Artem Pelenitsyn at 2020-05-04T13:19:59-04:00 Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) - - - - - b9f7c08f by jneira at 2020-05-04T13:20:37-04:00 Remove unused hs-boot file - - - - - 1d8f80cd by Sylvain Henry at 2020-05-05T03:22:46-04:00 Remove references to -package-key * remove references to `-package-key` which has been removed in 2016 (240ddd7c39536776e955e881d709bbb039b48513) * remove support for `-this-package-key` which has been deprecated at the same time - - - - - 7bc3a65b by Sylvain Henry at 2020-05-05T03:23:31-04:00 Remove SpecConstrAnnotation (#13681) This has been deprecated since 2013. Use GHC.Types.SPEC instead. Make GHC.Exts "not-home" for haddock Metric Decrease: haddock.base - - - - - 3c862f63 by DenisFrezzato at 2020-05-05T03:24:15-04:00 Fix Haskell98 short description in documentation - - - - - 2420c555 by Ryan Scott at 2020-05-05T03:24:53-04:00 Add regression tests for #16244, #16245, #16758 Commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70 ended up fixing quite a few bugs: * This commit fixes #16244 completely. A regression test has been added. * This commit fixes one program from #16245. (The program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211369 still panics, and the program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211400 still loops infinitely.) A regression test has been added for this program. * This commit fixes #16758. Accordingly, this patch removes the `expect_broken` label from the `T16758` test case, moves it from `should_compile` to `should_fail` (as it should produce an error message), and checks in the expected stderr. - - - - - 40c71c2c by Sylvain Henry at 2020-05-05T03:25:31-04:00 Fix colorized error messages (#18128) In b3df9e780fb2f5658412c644849cd0f1e6f50331 I broke colorized messages by using "dump" style instead of "user" style. This commits fixes it. - - - - - 7ab6ab09 by Richard Eisenberg at 2020-05-06T04:39:32-04:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG ------------------------- - - - - - 420b957d by Ben Gamari at 2020-05-06T04:40:08-04:00 rts: Zero block flags with -DZ Block flags are very useful for determining the state of a block. However, some block allocator users don't touch them, leading to misleading values. Ensure that we zero then when zero-on-gc is set. This is safe and makes the flags more useful during debugging. - - - - - 740b3b8d by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix incorrect failed_to_evac value during deadlock gc Previously we would incorrectly set the failed_to_evac flag if we evacuated a value due to a deadlock GC. This would cause us to mark more things as dirty than strictly necessary. It also turned up a nasty but which I will fix next. - - - - - b2d72c75 by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - 9f3e6884 by Zubin Duggal at 2020-05-06T04:41:08-04:00 Allow atomic update of NameCache in readHieFile The situation arises in ghcide where multiple different threads may need to update the name cache, therefore with the older interface it could happen that you start reading a hie file with name cache A and produce name cache A + B, but another thread in the meantime updated the namecache to A + C. Therefore if you write the new namecache you will lose the A' updates from the second thread. Updates haddock submodule - - - - - edec6a6c by Ryan Scott at 2020-05-06T04:41:57-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _)`. Fixes #18127. - - - - - a95e7fe0 by Ömer Sinan Ağacan at 2020-05-06T04:42:39-04:00 ELF linker: increment curSymbol after filling in fields of current entry The bug was introduced in a8b7cef4d45 which added a field to the `symbols` array elements and then updated this code incorrectly: - oc->symbols[curSymbol++] = nm; + oc->symbols[curSymbol++].name = nm; + oc->symbols[curSymbol].addr = symbol->addr; - - - - - cab1871a by Sylvain Henry at 2020-05-06T04:43:21-04:00 Move LeadingUnderscore into Platform (#17957) Avoid direct use of DynFlags to know if symbols must be prefixed by an underscore. - - - - - 94e7c563 by Sylvain Henry at 2020-05-06T04:43:21-04:00 Don't use DynFlags in showLinkerState (#17957) - - - - - 9afd9251 by Ryan Scott at 2020-05-06T04:43:58-04:00 Refactoring: Use bindSigTyVarsFV in rnMethodBinds `rnMethodBinds` was explicitly using `xoptM` to determine if `ScopedTypeVariables` is enabled before bringing type variables bound by the class/instance header into scope. However, this `xoptM` logic is already performed by the `bindSigTyVarsFV` function. This patch uses `bindSigTyVarsFV` in `rnMethodBinds` to reduce the number of places where we need to consult if `ScopedTypeVariables` is on. This is purely refactoring, and there should be no user-visible change in behavior. - - - - - 6f6d72b2 by Brian Foley at 2020-05-08T15:29:25-04:00 Remove further dead code found by a simple Python script. Avoid removing some functions that are part of an API even though they're not used in-tree at the moment. - - - - - 78bf8bf9 by Julien Debon at 2020-05-08T15:29:28-04:00 Add doc examples for Bifoldable See #17929 - - - - - 66f0a847 by Julien Debon at 2020-05-08T15:29:29-04:00 doc (Bitraversable): Add examples to Bitraversable * Add examples to Data.Bitraversable * Fix formatting for (,) in Bitraversable and Bifoldable * Fix mistake on bimapAccumR documentation See #17929 - - - - - 9749fe12 by Baldur Blöndal at 2020-05-08T15:29:32-04:00 Specify kind variables for inferred kinds in base. - - - - - 4e9aef9e by John Ericson at 2020-05-08T15:29:36-04:00 HsSigWcTypeScoping: Pull in documentation from stray location - - - - - f4d5c6df by John Ericson at 2020-05-08T15:29:36-04:00 Rename local `real_fvs` to `implicit_vs` It doesn't make sense to call the "free" variables we are about to implicitly bind the real ones. - - - - - 20570b4b by John Ericson at 2020-05-08T15:29:36-04:00 A few tiny style nits with renaming - Use case rather than guards that repeatedly scrutenize same thing. - No need for view pattern when `L` is fine. - Use type synnonym to convey the intent like elsewhere. - - - - - 09ac8de5 by John Ericson at 2020-05-08T15:29:36-04:00 Add `forAllOrNothing` function with note - - - - - bb35c0e5 by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Document lawlessness of Ap's Num instance - - - - - cdd229ff by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply suggestion to libraries/base/Data/Monoid.hs - - - - - 926d2aab by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply more suggestions from Simon Jakobi - - - - - 7a763cff by Adam Gundry at 2020-05-08T15:29:41-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. - - - - - 88e3c815 by Simon Peyton Jones at 2020-05-08T15:29:41-04:00 Fix specialisation for DFuns When specialising a DFun we must take care to saturate the unfolding. See Note [Specialising DFuns] in Specialise. Fixes #18120 - - - - - 86c77b36 by Greg Steuck at 2020-05-08T15:29:45-04:00 Remove unused SEGMENT_PROT_RWX It's been unused for a year and is problematic on any OS which requires W^X for security. - - - - - 9d97f4b5 by nineonine at 2020-05-08T15:30:03-04:00 Add test for #16167 - - - - - aa318338 by Ryan Scott at 2020-05-08T15:30:04-04:00 Bump exceptions submodule so that dist-boot is .gitignore'd `exceptions` is a stage-0 boot library as of commit 30272412fa437ab8e7a8035db94a278e10513413, which means that building `exceptions` in a GHC tree will generate a `dist-boot` directory. However, this directory was not specified in `exceptions`' `.gitignore` file, which causes it to dirty up the current `git` working directory. Accordingly, this bumps the `exceptions` submodule to commit ghc/packages/exceptions at 23c0b8a50d7592af37ca09beeec16b93080df98f, which adds `dist-boot` to the `.gitignore` file. - - - - - ea86360f by Ömer Sinan Ağacan at 2020-05-08T15:30:30-04:00 Linker.c: initialize n_symbols of ObjectCode with other fields - - - - - 118a779c by Simon Jakobi at 2020-05-09T20:53:34-04:00 Use Data.IntMap.disjoint Data.IntMap gained a dedicated `disjoint` function in containers-0.6.2.1. This patch applies this function where appropriate in hopes of modest compiler performance improvements. Closes #16806. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - CODEOWNERS - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - compiler/prelude/PrelNames.hs-boot → compiler/GHC/Builtin/Names.hs-boot - compiler/prelude/THNames.hs → compiler/GHC/Builtin/Names/TH.hs - compiler/prelude/PrimOp.hs → compiler/GHC/Builtin/PrimOps.hs - + compiler/GHC/Builtin/PrimOps.hs-boot - compiler/prelude/TysWiredIn.hs → compiler/GHC/Builtin/Types.hs - compiler/prelude/TysWiredIn.hs-boot → compiler/GHC/Builtin/Types.hs-boot - compiler/typecheck/TcTypeNats.hs → compiler/GHC/Builtin/Types/Literals.hs - compiler/prelude/TysPrim.hs → compiler/GHC/Builtin/Types/Prim.hs - compiler/prelude/KnownUniques.hs → compiler/GHC/Builtin/Uniques.hs - compiler/prelude/KnownUniques.hs-boot → compiler/GHC/Builtin/Uniques.hs-boot - compiler/prelude/PrelInfo.hs → compiler/GHC/Builtin/Utils.hs - compiler/prelude/primops.txt.pp → compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.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/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Block.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e102273dd00d25453270e9d81df57047b1f9183f...118a779c6e4cbc64a3381a3de1db249b070ed2b9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e102273dd00d25453270e9d81df57047b1f9183f...118a779c6e4cbc64a3381a3de1db249b070ed2b9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 10 01:20:13 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 09 May 2020 21:20:13 -0400 Subject: [Git][ghc/ghc][wip/T18101] 4 commits: Add test for #16167 Message-ID: <5eb756cdf08ad_616711922e9c9965018@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18101 at Glasgow Haskell Compiler / GHC Commits: 9d97f4b5 by nineonine at 2020-05-08T15:30:03-04:00 Add test for #16167 - - - - - aa318338 by Ryan Scott at 2020-05-08T15:30:04-04:00 Bump exceptions submodule so that dist-boot is .gitignore'd `exceptions` is a stage-0 boot library as of commit 30272412fa437ab8e7a8035db94a278e10513413, which means that building `exceptions` in a GHC tree will generate a `dist-boot` directory. However, this directory was not specified in `exceptions`' `.gitignore` file, which causes it to dirty up the current `git` working directory. Accordingly, this bumps the `exceptions` submodule to commit ghc/packages/exceptions at 23c0b8a50d7592af37ca09beeec16b93080df98f, which adds `dist-boot` to the `.gitignore` file. - - - - - ea86360f by Ömer Sinan Ağacan at 2020-05-08T15:30:30-04:00 Linker.c: initialize n_symbols of ObjectCode with other fields - - - - - 48a80c91 by Ben Gamari at 2020-05-10T01:19:54+00:00 testsuite: Add test for #18101 - - - - - 9 changed files: - libraries/exceptions - rts/Linker.c - + testsuite/tests/driver/T16167.hs - + testsuite/tests/driver/T16167.stdout - testsuite/tests/driver/all.T - + testsuite/tests/generics/T18101/T18101.hs - + testsuite/tests/generics/T18101/T18101.script - + testsuite/tests/generics/T18101/T18101.stdout - + testsuite/tests/generics/T18101/all.T Changes: ===================================== libraries/exceptions ===================================== @@ -1 +1 @@ -Subproject commit fe4166f8d23d8288ef2cbbf9e36118b6b99e0d7d +Subproject commit 23c0b8a50d7592af37ca09beeec16b93080df98f ===================================== rts/Linker.c ===================================== @@ -1326,6 +1326,7 @@ mkOc( pathchar *path, char *image, int imageSize, setOcInitialStatus( oc ); oc->fileSize = imageSize; + oc->n_symbols = 0; oc->symbols = NULL; oc->n_sections = 0; oc->sections = NULL; ===================================== testsuite/tests/driver/T16167.hs ===================================== @@ -0,0 +1 @@ +module f ===================================== testsuite/tests/driver/T16167.stdout ===================================== @@ -0,0 +1 @@ +{"span": {"file": "T16167.hs","startLine": 1,"startCol": 8,"endLine": 1,"endCol": 9},"doc": "parse error on input \u2018f\u2019","severity": "SevError","reason": null} ===================================== testsuite/tests/driver/all.T ===================================== @@ -261,6 +261,8 @@ test('T12955', normal, makefile_test, []) test('T12971', [when(opsys('mingw32'), expect_broken(17945)), ignore_stdout], makefile_test, []) test('json', normal, compile_fail, ['-ddump-json']) test('json2', normalise_version('base','ghc-prim'), compile, ['-ddump-types -ddump-json']) +test('T16167', exit_code(1), run_command, + ['{compiler} -x hs -e ":set prog T16167.hs" -ddump-json T16167.hs']) test('T13604', [], makefile_test, []) test('T13604a', [], makefile_test, []) # omitting hpc and profasm because they affect the ===================================== testsuite/tests/generics/T18101/T18101.hs ===================================== @@ -0,0 +1,5 @@ +module T18101 where + +infixr 5 :* + +data List a = a :* List a ===================================== testsuite/tests/generics/T18101/T18101.script ===================================== @@ -0,0 +1,5 @@ +:load T18101 +:set -XStandaloneDeriving -XDeriveGeneric -XFlexibleInstances +import GHC.Generics +deriving instance Generic (List Int) +:kind! (Rep (List Int)) ===================================== testsuite/tests/generics/T18101/T18101.stdout ===================================== @@ -0,0 +1,13 @@ +(Rep (List Int)) :: * -> * += D1 + ('MetaData "List" "T18101" "main" 'False) + (C1 + ('MetaCons ":*" ('InfixI 'RightAssociative 5) 'False) + (S1 + ('MetaSel + 'Nothing 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) + (Rec0 Int) + :*: S1 + ('MetaSel + 'Nothing 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) + (Rec0 (List Int)))) ===================================== testsuite/tests/generics/T18101/all.T ===================================== @@ -0,0 +1,4 @@ +# This test verifies that fixity is correctly reflected in Generic instances +# derived for types living outside the current module. + +test('T18101', expect_broken(18101), ghci_script, ['T18101.script']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/35e3b0ba3f197c1716021267952598bf3aa39934...48a80c91b067a205e285204a24baf5cf0f753a32 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/35e3b0ba3f197c1716021267952598bf3aa39934...48a80c91b067a205e285204a24baf5cf0f753a32 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 10 01:46:51 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 09 May 2020 21:46:51 -0400 Subject: [Git][ghc/ghc][master] Fix unboxed-sums GC ptr-slot rubbish value (#17791) Message-ID: <5eb75d0bd008e_61673f81cd539dbc9991886@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 951c1fb0 by Sylvain Henry at 2020-05-09T21:46:38-04:00 Fix unboxed-sums GC ptr-slot rubbish value (#17791) This patch allows boot libraries to use unboxed sums without implicitly depending on `base` package because of `absentSumFieldError`. See updated Note [aBSENT_SUM_FIELD_ERROR_ID] in GHC.Core.Make - - - - - 14 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Stg/Unarise.hs - includes/stg/MiscClosures.h - libraries/base/Control/Exception/Base.hs - + libraries/ghc-prim/GHC/Prim/Panic.hs - libraries/ghc-prim/ghc-prim.cabal - rts/Exception.cmm - rts/Prelude.h - rts/RtsStartup.c - rts/RtsSymbols.c - rts/package.conf.in - rts/rts.cabal.in - rts/win32/libHSbase.def Changes: ===================================== compiler/GHC/Builtin/Names.hs ===================================== @@ -511,7 +511,7 @@ genericTyConNames = [ pRELUDE :: Module pRELUDE = mkBaseModule_ pRELUDE_NAME -gHC_PRIM, gHC_TYPES, gHC_GENERICS, gHC_MAGIC, +gHC_PRIM, gHC_PRIM_PANIC, gHC_TYPES, gHC_GENERICS, gHC_MAGIC, gHC_CLASSES, gHC_PRIMOPWRAPPERS, gHC_BASE, gHC_ENUM, gHC_GHCI, gHC_GHCI_HELPERS, gHC_CSTRING, gHC_SHOW, gHC_READ, gHC_NUM, gHC_MAYBE, gHC_INTEGER_TYPE, gHC_NATURAL, @@ -527,6 +527,7 @@ gHC_PRIM, gHC_TYPES, gHC_GENERICS, gHC_MAGIC, dATA_COERCE, dEBUG_TRACE, uNSAFE_COERCE :: Module gHC_PRIM = mkPrimModule (fsLit "GHC.Prim") -- Primitive types and values +gHC_PRIM_PANIC = mkPrimModule (fsLit "GHC.Prim.Panic") gHC_TYPES = mkPrimModule (fsLit "GHC.Types") gHC_MAGIC = mkPrimModule (fsLit "GHC.Magic") gHC_CSTRING = mkPrimModule (fsLit "GHC.CString") ===================================== compiler/GHC/Core/Make.hs ===================================== @@ -735,6 +735,7 @@ errorIds rEC_CON_ERROR_ID, rEC_SEL_ERROR_ID, aBSENT_ERROR_ID, + aBSENT_SUM_FIELD_ERROR_ID, tYPE_ERROR_ID -- Used with Opt_DeferTypeErrors, see #10284 ] @@ -746,8 +747,6 @@ absentSumFieldErrorName :: Name recSelErrorName = err_nm "recSelError" recSelErrorIdKey rEC_SEL_ERROR_ID absentErrorName = err_nm "absentError" absentErrorIdKey aBSENT_ERROR_ID -absentSumFieldErrorName = err_nm "absentSumFieldError" absentSumFieldErrorIdKey - aBSENT_SUM_FIELD_ERROR_ID runtimeErrorName = err_nm "runtimeError" runtimeErrorIdKey rUNTIME_ERROR_ID recConErrorName = err_nm "recConError" recConErrorIdKey rEC_CON_ERROR_ID patErrorName = err_nm "patError" patErrorIdKey pAT_ERROR_ID @@ -774,25 +773,68 @@ tYPE_ERROR_ID = mkRuntimeErrorId typeErrorName -- Note [aBSENT_SUM_FIELD_ERROR_ID] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --- Absent argument error for unused unboxed sum fields are different than absent --- error used in dummy worker functions (see `mkAbsentErrorApp`): -- --- - `absentSumFieldError` can't take arguments because it's used in unarise for --- unused pointer fields in unboxed sums, and applying an argument would --- require allocating a thunk. +-- Unboxed sums are transformed into unboxed tuples in GHC.Stg.Unarise.mkUbxSum +-- and fields that can't be reached are filled with rubbish values. It's easy to +-- come up with rubbish literal values: we use 0 (ints/words) and 0.0 +-- (floats/doubles). Coming up with a rubbish pointer value is more delicate: -- --- - `absentSumFieldError` can't be CAFFY because that would mean making some --- non-CAFFY definitions that use unboxed sums CAFFY in unarise. +-- 1. it needs to be a valid closure pointer for the GC (not a NULL pointer) -- --- To make `absentSumFieldError` non-CAFFY we get a stable pointer to it in --- RtsStartup.c and mark it as non-CAFFY here. +-- 2. it is never used in Core, only in STG; and even then only for filling a +-- GC-ptr slot in an unboxed sum (see GHC.Stg.Unarise.ubxSumRubbishArg). +-- So all we need is a pointer, and its levity doesn't matter. Hence we +-- can safely give it the (lifted) type: -- --- Getting this wrong causes hard-to-debug runtime issues, see #15038. +-- absentSumFieldError :: forall a. a -- --- TODO: Remove stable pointer hack after fixing #9718. --- However, we should still be careful about not making things CAFFY just --- because they use unboxed sums. Unboxed objects are supposed to be --- efficient, and none of the other unboxed literals make things CAFFY. +-- despite the fact that Unarise might instantiate it at non-lifted +-- types. +-- +-- 3. it can't take arguments because it's used in unarise and applying an +-- argument would require allocating a thunk. +-- +-- 4. it can't be CAFFY because that would mean making some non-CAFFY +-- definitions that use unboxed sums CAFFY in unarise. +-- +-- Getting this wrong causes hard-to-debug runtime issues, see #15038. +-- +-- 5. it can't be defined in `base` package. +-- +-- Defining `absentSumFieldError` in `base` package introduces a +-- dependency on `base` for any code using unboxed sums. It became an +-- issue when we wanted to use unboxed sums in boot libraries used by +-- `base`, see #17791. +-- +-- +-- * Most runtime-error functions throw a proper Haskell exception, which can be +-- caught in the usual way. But these functions are defined in +-- `base:Control.Exception.Base`, hence, they cannot be directly invoked in +-- any library compiled before `base`. Only exceptions that have been wired +-- in the RTS can be thrown (indirectly, via a call into the RTS) by libraries +-- compiled before `base`. +-- +-- However wiring exceptions in the RTS is a bit annoying because we need to +-- explicitly import exception closures via their mangled symbol name (e.g. +-- `import CLOSURE base_GHCziIOziException_heapOverflow_closure`) in Cmm files +-- and every imported symbol must be indicated to the linker in a few files +-- (`package.conf`, `rts.cabal`, `win32/libHSbase.def`, `Prelude.h`...). It +-- explains why exceptions are only wired in the RTS when necessary. +-- +-- * `absentSumFieldError` is defined in ghc-prim:GHC.Prim.Panic, hence, it can +-- be invoked in libraries compiled before `base`. It does not throw a Haskell +-- exception; instead, it calls `stg_panic#`, which immediately halts +-- execution. A runtime invocation of `absentSumFieldError` indicates a GHC +-- bug. Unlike (say) pattern-match errors, it cannot be caused by a user +-- error. That's why it is OK for it to be un-catchable. +-- + +absentSumFieldErrorName + = mkWiredInIdName + gHC_PRIM_PANIC + (fsLit "absentSumFieldError") + absentSumFieldErrorIdKey + aBSENT_SUM_FIELD_ERROR_ID aBSENT_SUM_FIELD_ERROR_ID = mkVanillaGlobalWithInfo absentSumFieldErrorName ===================================== compiler/GHC/Stg/Unarise.hs ===================================== @@ -577,18 +577,26 @@ mkUbxSum dc ty_args args0 | Just stg_arg <- IM.lookup arg_idx arg_map = stg_arg : mkTupArgs (arg_idx + 1) slots_left arg_map | otherwise - = slotRubbishArg slot : mkTupArgs (arg_idx + 1) slots_left arg_map - - slotRubbishArg :: SlotTy -> StgArg - slotRubbishArg PtrSlot = StgVarArg aBSENT_SUM_FIELD_ERROR_ID - -- See Note [aBSENT_SUM_FIELD_ERROR_ID] in GHC.Core.Make - slotRubbishArg WordSlot = StgLitArg (LitNumber LitNumWord 0 wordPrimTy) - slotRubbishArg Word64Slot = StgLitArg (LitNumber LitNumWord64 0 word64PrimTy) - slotRubbishArg FloatSlot = StgLitArg (LitFloat 0) - slotRubbishArg DoubleSlot = StgLitArg (LitDouble 0) + = ubxSumRubbishArg slot : mkTupArgs (arg_idx + 1) slots_left arg_map in tag_arg : mkTupArgs 0 sum_slots arg_idxs + +-- | Return a rubbish value for the given slot type. +-- +-- We use the following rubbish values: +-- * Literals: 0 or 0.0 +-- * Pointers: `ghc-prim:GHC.Prim.Panic.absentSumFieldError` +-- +-- See Note [aBSENT_SUM_FIELD_ERROR_ID] in GHC.Core.Make +-- +ubxSumRubbishArg :: SlotTy -> StgArg +ubxSumRubbishArg PtrSlot = StgVarArg aBSENT_SUM_FIELD_ERROR_ID +ubxSumRubbishArg WordSlot = StgLitArg (LitNumber LitNumWord 0 wordPrimTy) +ubxSumRubbishArg Word64Slot = StgLitArg (LitNumber LitNumWord64 0 word64PrimTy) +ubxSumRubbishArg FloatSlot = StgLitArg (LitFloat 0) +ubxSumRubbishArg DoubleSlot = StgLitArg (LitDouble 0) + -------------------------------------------------------------------------------- {- ===================================== includes/stg/MiscClosures.h ===================================== @@ -418,6 +418,7 @@ RTS_FUN_DECL(stg_raiseDivZZerozh); RTS_FUN_DECL(stg_raiseUnderflowzh); RTS_FUN_DECL(stg_raiseOverflowzh); RTS_FUN_DECL(stg_raiseIOzh); +RTS_FUN_DECL(stg_paniczh); RTS_FUN_DECL(stg_makeStableNamezh); RTS_FUN_DECL(stg_makeStablePtrzh); ===================================== libraries/base/Control/Exception/Base.hs ===================================== @@ -95,7 +95,7 @@ module Control.Exception.Base ( -- * Calls for GHC runtime recSelError, recConError, runtimeError, nonExhaustiveGuardsError, patError, noMethodBindingError, - absentError, absentSumFieldError, typeError, + absentError, typeError, nonTermination, nestedAtomically, ) where @@ -398,7 +398,3 @@ nonTermination = toException NonTermination -- GHC's RTS calls this nestedAtomically :: SomeException nestedAtomically = toException NestedAtomically - --- Introduced by unarise for unused unboxed sum fields -absentSumFieldError :: a -absentSumFieldError = absentError " in unboxed sum."# ===================================== libraries/ghc-prim/GHC/Prim/Panic.hs ===================================== @@ -0,0 +1,45 @@ +{-# LANGUAGE GHCForeignImportPrim #-} +{-# LANGUAGE UnliftedFFITypes #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE EmptyCase #-} + +-- | Primitive panics. +module GHC.Prim.Panic + ( absentSumFieldError + , panicError + ) +where + +import GHC.Prim +import GHC.Magic + +default () -- Double and Integer aren't available yet + +-- `stg_panic#` never returns but it can't just return `State# RealWorld` so we +-- indicate that it returns `Void#` too to make the compiler happy. +foreign import prim "stg_paniczh" panic# :: Addr# -> State# RealWorld -> (# State# RealWorld, Void# #) + +-- | Display the CString whose address is given as an argument and exit. +panicError :: Addr# -> a +panicError errmsg = + runRW# (\s -> + case panic# errmsg s of + (# _, _ #) -> -- This bottom is unreachable but we can't + -- use an empty case lest the pattern match + -- checker squawks. + let x = x in x) + +-- | Closure introduced by GHC.Stg.Unarise for unused unboxed sum fields. +-- +-- See Note [aBSENT_SUM_FIELD_ERROR_ID] in GHC.Core.Make +absentSumFieldError :: a +absentSumFieldError = panicError "entered absent sum field!"# + +-- GHC.Core.Make.aBSENT_SUM_FIELD_ERROR_ID gives absentSumFieldError a bottoming +-- demand signature. But if we ever inlined it (to a call to panicError) we'd +-- lose that information. Should not happen because absentSumFieldError is only +-- introduced in Stg.Unarise, long after inlining has stopped, but it seems +-- more direct simply to give it a NOINLINE pragma +{-# NOINLINE absentSumFieldError #-} ===================================== libraries/ghc-prim/ghc-prim.cabal ===================================== @@ -46,6 +46,7 @@ Library GHC.IntWord64 GHC.Magic GHC.Prim.Ext + GHC.Prim.Panic GHC.PrimopWrappers GHC.Tuple GHC.Types ===================================== rts/Exception.cmm ===================================== @@ -632,3 +632,12 @@ stg_raiseIOzh (P_ exception) { jump stg_raisezh (exception); } + +/* The FFI doesn't support variadic C functions so we can't directly expose + * `barf` to Haskell code. Instead we define "stg_panic#" and it is exposed to + * Haskell programs in GHC.Prim.Panic. + */ +stg_paniczh (W_ str) +{ + ccall barf(str) never returns; +} ===================================== rts/Prelude.h ===================================== @@ -45,7 +45,6 @@ PRELUDE_CLOSURE(base_GHCziIOziException_cannotCompactPinned_closure); PRELUDE_CLOSURE(base_GHCziIOziException_cannotCompactMutable_closure); PRELUDE_CLOSURE(base_ControlziExceptionziBase_nonTermination_closure); PRELUDE_CLOSURE(base_ControlziExceptionziBase_nestedAtomically_closure); -PRELUDE_CLOSURE(base_ControlziExceptionziBase_absentSumFieldError_closure); PRELUDE_CLOSURE(base_GHCziEventziThread_blockedOnBadFD_closure); PRELUDE_CLOSURE(base_GHCziExceptionziType_divZZeroException_closure); PRELUDE_CLOSURE(base_GHCziExceptionziType_underflowException_closure); @@ -103,7 +102,6 @@ PRELUDE_INFO(base_GHCziStable_StablePtr_con_info); #define nonTermination_closure DLL_IMPORT_DATA_REF(base_ControlziExceptionziBase_nonTermination_closure) #define nestedAtomically_closure DLL_IMPORT_DATA_REF(base_ControlziExceptionziBase_nestedAtomically_closure) #define blockedOnBadFD_closure DLL_IMPORT_DATA_REF(base_GHCziEventziThread_blockedOnBadFD_closure) -#define absentSumFieldError_closure DLL_IMPORT_DATA_REF(base_ControlziExceptionziBase_absentSumFieldError_closure) #define Czh_con_info DLL_IMPORT_DATA_REF(ghczmprim_GHCziTypes_Czh_con_info) #define Izh_con_info DLL_IMPORT_DATA_REF(ghczmprim_GHCziTypes_Izh_con_info) ===================================== rts/RtsStartup.c ===================================== @@ -275,10 +275,6 @@ hs_init_ghc(int *argc, char **argv[], RtsConfig rts_config) getStablePtr((StgPtr)cannotCompactPinned_closure); getStablePtr((StgPtr)cannotCompactMutable_closure); getStablePtr((StgPtr)nestedAtomically_closure); - getStablePtr((StgPtr)absentSumFieldError_closure); - // `Id` for this closure is marked as non-CAFFY, - // see Note [aBSENT_SUM_FIELD_ERROR_ID] in GHC.Core.Make. - getStablePtr((StgPtr)runSparks_closure); getStablePtr((StgPtr)ensureIOManagerIsRunning_closure); getStablePtr((StgPtr)ioManagerCapabilitiesChanged_closure); ===================================== rts/RtsSymbols.c ===================================== @@ -732,6 +732,7 @@ SymI_HasProto(stg_raiseUnderflowzh) \ SymI_HasProto(stg_raiseOverflowzh) \ SymI_HasProto(stg_raiseIOzh) \ + SymI_HasProto(stg_paniczh) \ SymI_HasProto(stg_readTVarzh) \ SymI_HasProto(stg_readTVarIOzh) \ SymI_HasProto(resumeThread) \ ===================================== rts/package.conf.in ===================================== @@ -97,7 +97,6 @@ ld-options: , "-Wl,-u,_base_GHCziIOziException_cannotCompactFunction_closure" , "-Wl,-u,_base_GHCziIOziException_cannotCompactPinned_closure" , "-Wl,-u,_base_GHCziIOziException_cannotCompactMutable_closure" - , "-Wl,-u,_base_ControlziExceptionziBase_absentSumFieldError_closure" , "-Wl,-u,_base_ControlziExceptionziBase_nonTermination_closure" , "-Wl,-u,_base_ControlziExceptionziBase_nestedAtomically_closure" , "-Wl,-u,_base_GHCziEventziThread_blockedOnBadFD_closure" @@ -203,7 +202,6 @@ ld-options: , "-Wl,-u,base_GHCziIOziException_cannotCompactFunction_closure" , "-Wl,-u,base_GHCziIOziException_cannotCompactPinned_closure" , "-Wl,-u,base_GHCziIOziException_cannotCompactMutable_closure" - , "-Wl,-u,base_ControlziExceptionziBase_absentSumFieldError_closure" , "-Wl,-u,base_ControlziExceptionziBase_nonTermination_closure" , "-Wl,-u,base_ControlziExceptionziBase_nestedAtomically_closure" , "-Wl,-u,base_GHCziEventziThread_blockedOnBadFD_closure" ===================================== rts/rts.cabal.in ===================================== @@ -218,7 +218,6 @@ library "-Wl,-u,_base_GHCziIOziException_cannotCompactFunction_closure" "-Wl,-u,_base_GHCziIOziException_cannotCompactPinned_closure" "-Wl,-u,_base_GHCziIOziException_cannotCompactMutable_closure" - "-Wl,-u,_base_ControlziExceptionziBase_absentSumFieldError_closure" "-Wl,-u,_base_ControlziExceptionziBase_nonTermination_closure" "-Wl,-u,_base_ControlziExceptionziBase_nestedAtomically_closure" "-Wl,-u,_base_GHCziEventziThread_blockedOnBadFD_closure" @@ -294,7 +293,6 @@ library "-Wl,-u,base_GHCziIOziException_cannotCompactFunction_closure" "-Wl,-u,base_GHCziIOziException_cannotCompactPinned_closure" "-Wl,-u,base_GHCziIOziException_cannotCompactMutable_closure" - "-Wl,-u,base_ControlziExceptionziBase_absentSumFieldError_closure" "-Wl,-u,base_ControlziExceptionziBase_nonTermination_closure" "-Wl,-u,base_ControlziExceptionziBase_nestedAtomically_closure" "-Wl,-u,base_GHCziEventziThread_blockedOnBadFD_closure" ===================================== rts/win32/libHSbase.def ===================================== @@ -42,7 +42,6 @@ EXPORTS base_GHCziIOziException_cannotCompactPinned_closure base_GHCziIOziException_cannotCompactMutable_closure - base_ControlziExceptionziBase_absentSumFieldError_closure base_ControlziExceptionziBase_nonTermination_closure base_ControlziExceptionziBase_nestedAtomically_closure base_GHCziEventziThread_blockedOnBadFD_closure View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/951c1fb03d80094c8b0d9bcc463d86fa71695b3a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/951c1fb03d80094c8b0d9bcc463d86fa71695b3a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 10 01:47:28 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 09 May 2020 21:47:28 -0400 Subject: [Git][ghc/ghc][master] rts: Make non-existent linker search path merely a warning Message-ID: <5eb75d3020cd8_61673f8103f8794c99960fa@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: b352d63c by Ben Gamari at 2020-05-09T21:47:14-04:00 rts: Make non-existent linker search path merely a warning As noted in #18105, previously this resulted in a rather intrusive error message. This is in contrast to the general expectation that search paths are merely places to look, not places that must exist. Fixes #18105. - - - - - 1 changed file: - rts/linker/PEi386.c Changes: ===================================== rts/linker/PEi386.c ===================================== @@ -776,12 +776,12 @@ HsPtr addLibrarySearchPath_PEi386(pathchar* dll_path) WCHAR* abs_path = malloc(sizeof(WCHAR) * init_buf_size); DWORD wResult = GetFullPathNameW(dll_path, bufsize, abs_path, NULL); if (!wResult){ - sysErrorBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError()); + IF_DEBUG(linker, debugBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError())); } else if (wResult > init_buf_size) { abs_path = realloc(abs_path, sizeof(WCHAR) * wResult); if (!GetFullPathNameW(dll_path, bufsize, abs_path, NULL)) { - sysErrorBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError()); + IF_DEBUG(linker, debugBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError())); } } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b352d63cbbfbee69358c198edd876fe7ef9d63ef -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b352d63cbbfbee69358c198edd876fe7ef9d63ef You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 10 01:48:19 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 09 May 2020 21:48:19 -0400 Subject: [Git][ghc/ghc][wip/T17609] 73 commits: Switch order on `GhcMake.IsBoot` Message-ID: <5eb75d63cc081_6167119ebbd09996471@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T17609 at Glasgow Haskell Compiler / GHC Commits: b0fbfc75 by John Ericson at 2020-04-24T12:07:14-04:00 Switch order on `GhcMake.IsBoot` In !1798 we were requested to replace many `Bool`s with this data type. But those bools had `False` meaning `NotBoot`, so the `Ord` instance would be flipped if we use this data-type as-is. Since the planned formally-`Bool` occurrences vastly outnumber the current occurrences, we figured it would be better to conform the `Ord` instance to how the `Bool` is used now, fixing any issues, rather than fix them currently with the bigger refactor later in !1798. That way, !1798 can be a "pure" refactor with no behavioral changes. - - - - - af332442 by Sylvain Henry at 2020-04-26T13:55:14-04:00 Modules: Utils and Data (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - cd4434c8 by Sylvain Henry at 2020-04-26T13:55:16-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 22bf5c73 by Ömer Sinan Ağacan at 2020-04-26T13:55:22-04:00 Tweak includes in non-moving GC headers We don't use hash tables in non-moving GC so remove the includes. This breaks Compact.c as existing includes no longer include Hash.h, so include Hash.h explicitly in Compact.c. - - - - - 99823ed2 by Sylvain Henry at 2020-04-27T20:24:46-04:00 TH: fix Show/Eq/Ord instances for Bytes (#16457) We shouldn't compare pointer values but the actual bytes. - - - - - c62271a2 by Alp Mestanogullari at 2020-04-27T20:25:33-04:00 hadrian: always capture both stdout and stderr when running a builder fails The idea being that when a builder('s command) fails, we quite likely want to have all the information available to figure out why. Depending on the builder _and_ the particular problem, the useful bits of information can be printed on stdout or stderr. We accomplish this by defining a simple wrapper for Shake's `cmd` function, that just _always_ captures both streams in case the command returns a non-zero exit code, and by using this wrapper everywhere in `hadrian/src/Builder.hs`. Fixes #18089. - - - - - 4b9764db by Ryan Scott at 2020-04-28T15:40:04-04:00 Define a Quote IO instance Fixes #18103. - - - - - 518a63d4 by Ryan Scott at 2020-04-28T15:40:42-04:00 Make boxed 1-tuples have known keys Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. - - - - - 2cfc4ab9 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Document backpack fields in DynFlags - - - - - 10a2ba90 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 69562e34 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 9e2c8e0e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - ea717aa4 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 10d15f1e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 8bfb0219 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - 71484b09 by Alexis King at 2020-04-30T01:57:35-04:00 Allow block arguments in arrow control operators Arrow control operators have their own entries in the grammar, so they did not cooperate with BlockArguments. This was just a minor oversight, so this patch adjusts the grammar to add the desired behavior. fixes #18050 - - - - - a48cd2a0 by Alexis King at 2020-04-30T01:57:35-04:00 Allow LambdaCase to be used as a command in proc notation - - - - - f4d3773c by Alexis King at 2020-04-30T01:57:35-04:00 Document BlockArguments/LambdaCase support in arrow notation - - - - - 5bdfdd13 by Simon Peyton Jones at 2020-04-30T01:58:15-04:00 Add tests for #17873 - - - - - 19b701c2 by Simon Peyton Jones at 2020-04-30T07:30:13-04:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - 014ef4a3 by Matthew Pickering at 2020-04-30T07:30:50-04:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 2aa67611 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - 54dad3cf by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - 99ff8145 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 05b0a9fd by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 Remove OneShotInfo field of LFReEntrant, document OneShotInfo The field is only used in withNewTickyCounterFun and it's easier to directly pass a parameter for one-shot info to withNewTickyCounterFun instead of passing it via LFReEntrant. This also makes !2842 simpler. Other changes: - New Note (by SPJ) [OneShotInfo overview] added. - Arity argument of thunkCode removed as it's always 0. - - - - - a43620c6 by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 GHC.StgToCmm.Ticky: remove a few unused stuff - - - - - 780de9e1 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Use platform in Iface Binary - - - - - f8386c7b by Sylvain Henry at 2020-05-01T10:37:39-04:00 Refactor PprDebug handling If `-dppr-debug` is set, then PprUser and PprDump styles are silently replaced with PprDebug style. This was done in `mkUserStyle` and `mkDumpStyle` smart constructors. As a consequence they needed a DynFlags parameter. Now we keep the original PprUser and PprDump styles until they are used to create an `SDocContext`. I.e. the substitution is only performed in `initSDocContext`. - - - - - b3df9e78 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Remove PprStyle param of logging actions Use `withPprStyle` instead to apply a specific style to a SDoc. - - - - - de9fc995 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Fully remove PprDebug PprDebug was a pain to deal with consistently as it is implied by `-dppr-debug` but it isn't really a PprStyle. We remove it completely and query the appropriate SDoc flag instead (`sdocPprDebug`) via helpers (`getPprDebug` and its friends). - - - - - 8b51fcbd by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Only call checkSingle if we would report warnings - - - - - fd7ea0fe by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 7bfe9ac5 by Ben Gamari at 2020-05-03T04:41:33-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. - - - - - c560dd07 by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Move eventlog documentation users guide - - - - - 02543d5e by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Add documentation for non-moving GC events - - - - - b465dd45 by Alexis King at 2020-05-03T04:42:12-04:00 Flatten nested casts in the simple optimizer Normally, we aren’t supposed to generated any nested casts, since mkCast takes care to flatten them, but the simple optimizer didn’t use mkCast, so they could show up after inlining. This isn’t really a problem, since the simplifier will clean them up immediately anyway, but it can clutter the -ddump-ds output, and it’s an extremely easy fix. closes #18112 - - - - - 8bdc03d6 by Simon Peyton Jones at 2020-05-04T01:56:59-04:00 Don't return a panic in tcNestedSplice In GHC.Tc.Gen.Splice.tcNestedSplice we were returning a typechecked expression of "panic". That is usually OK, because the result is discarded. But it happens that tcApp now looks at the typechecked expression, trivially, to ask if it is tagToEnum. So being bottom is bad. Moreover a debug-trace might print it out. So better to return a civilised expression, even though it is usually discarded. - - - - - 0bf640b1 by Baldur Blöndal at 2020-05-04T01:57:36-04:00 Don't require parentheses around via type (`-XDerivingVia'). Fixes #18130". - - - - - 30272412 by Artem Pelenitsyn at 2020-05-04T13:19:59-04:00 Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) - - - - - b9f7c08f by jneira at 2020-05-04T13:20:37-04:00 Remove unused hs-boot file - - - - - 1d8f80cd by Sylvain Henry at 2020-05-05T03:22:46-04:00 Remove references to -package-key * remove references to `-package-key` which has been removed in 2016 (240ddd7c39536776e955e881d709bbb039b48513) * remove support for `-this-package-key` which has been deprecated at the same time - - - - - 7bc3a65b by Sylvain Henry at 2020-05-05T03:23:31-04:00 Remove SpecConstrAnnotation (#13681) This has been deprecated since 2013. Use GHC.Types.SPEC instead. Make GHC.Exts "not-home" for haddock Metric Decrease: haddock.base - - - - - 3c862f63 by DenisFrezzato at 2020-05-05T03:24:15-04:00 Fix Haskell98 short description in documentation - - - - - 2420c555 by Ryan Scott at 2020-05-05T03:24:53-04:00 Add regression tests for #16244, #16245, #16758 Commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70 ended up fixing quite a few bugs: * This commit fixes #16244 completely. A regression test has been added. * This commit fixes one program from #16245. (The program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211369 still panics, and the program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211400 still loops infinitely.) A regression test has been added for this program. * This commit fixes #16758. Accordingly, this patch removes the `expect_broken` label from the `T16758` test case, moves it from `should_compile` to `should_fail` (as it should produce an error message), and checks in the expected stderr. - - - - - 40c71c2c by Sylvain Henry at 2020-05-05T03:25:31-04:00 Fix colorized error messages (#18128) In b3df9e780fb2f5658412c644849cd0f1e6f50331 I broke colorized messages by using "dump" style instead of "user" style. This commits fixes it. - - - - - 7ab6ab09 by Richard Eisenberg at 2020-05-06T04:39:32-04:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG ------------------------- - - - - - 420b957d by Ben Gamari at 2020-05-06T04:40:08-04:00 rts: Zero block flags with -DZ Block flags are very useful for determining the state of a block. However, some block allocator users don't touch them, leading to misleading values. Ensure that we zero then when zero-on-gc is set. This is safe and makes the flags more useful during debugging. - - - - - 740b3b8d by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix incorrect failed_to_evac value during deadlock gc Previously we would incorrectly set the failed_to_evac flag if we evacuated a value due to a deadlock GC. This would cause us to mark more things as dirty than strictly necessary. It also turned up a nasty but which I will fix next. - - - - - b2d72c75 by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - 9f3e6884 by Zubin Duggal at 2020-05-06T04:41:08-04:00 Allow atomic update of NameCache in readHieFile The situation arises in ghcide where multiple different threads may need to update the name cache, therefore with the older interface it could happen that you start reading a hie file with name cache A and produce name cache A + B, but another thread in the meantime updated the namecache to A + C. Therefore if you write the new namecache you will lose the A' updates from the second thread. Updates haddock submodule - - - - - edec6a6c by Ryan Scott at 2020-05-06T04:41:57-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _)`. Fixes #18127. - - - - - a95e7fe0 by Ömer Sinan Ağacan at 2020-05-06T04:42:39-04:00 ELF linker: increment curSymbol after filling in fields of current entry The bug was introduced in a8b7cef4d45 which added a field to the `symbols` array elements and then updated this code incorrectly: - oc->symbols[curSymbol++] = nm; + oc->symbols[curSymbol++].name = nm; + oc->symbols[curSymbol].addr = symbol->addr; - - - - - cab1871a by Sylvain Henry at 2020-05-06T04:43:21-04:00 Move LeadingUnderscore into Platform (#17957) Avoid direct use of DynFlags to know if symbols must be prefixed by an underscore. - - - - - 94e7c563 by Sylvain Henry at 2020-05-06T04:43:21-04:00 Don't use DynFlags in showLinkerState (#17957) - - - - - 9afd9251 by Ryan Scott at 2020-05-06T04:43:58-04:00 Refactoring: Use bindSigTyVarsFV in rnMethodBinds `rnMethodBinds` was explicitly using `xoptM` to determine if `ScopedTypeVariables` is enabled before bringing type variables bound by the class/instance header into scope. However, this `xoptM` logic is already performed by the `bindSigTyVarsFV` function. This patch uses `bindSigTyVarsFV` in `rnMethodBinds` to reduce the number of places where we need to consult if `ScopedTypeVariables` is on. This is purely refactoring, and there should be no user-visible change in behavior. - - - - - 6f6d72b2 by Brian Foley at 2020-05-08T15:29:25-04:00 Remove further dead code found by a simple Python script. Avoid removing some functions that are part of an API even though they're not used in-tree at the moment. - - - - - 78bf8bf9 by Julien Debon at 2020-05-08T15:29:28-04:00 Add doc examples for Bifoldable See #17929 - - - - - 66f0a847 by Julien Debon at 2020-05-08T15:29:29-04:00 doc (Bitraversable): Add examples to Bitraversable * Add examples to Data.Bitraversable * Fix formatting for (,) in Bitraversable and Bifoldable * Fix mistake on bimapAccumR documentation See #17929 - - - - - 9749fe12 by Baldur Blöndal at 2020-05-08T15:29:32-04:00 Specify kind variables for inferred kinds in base. - - - - - 4e9aef9e by John Ericson at 2020-05-08T15:29:36-04:00 HsSigWcTypeScoping: Pull in documentation from stray location - - - - - f4d5c6df by John Ericson at 2020-05-08T15:29:36-04:00 Rename local `real_fvs` to `implicit_vs` It doesn't make sense to call the "free" variables we are about to implicitly bind the real ones. - - - - - 20570b4b by John Ericson at 2020-05-08T15:29:36-04:00 A few tiny style nits with renaming - Use case rather than guards that repeatedly scrutenize same thing. - No need for view pattern when `L` is fine. - Use type synnonym to convey the intent like elsewhere. - - - - - 09ac8de5 by John Ericson at 2020-05-08T15:29:36-04:00 Add `forAllOrNothing` function with note - - - - - bb35c0e5 by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Document lawlessness of Ap's Num instance - - - - - cdd229ff by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply suggestion to libraries/base/Data/Monoid.hs - - - - - 926d2aab by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply more suggestions from Simon Jakobi - - - - - 7a763cff by Adam Gundry at 2020-05-08T15:29:41-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. - - - - - 88e3c815 by Simon Peyton Jones at 2020-05-08T15:29:41-04:00 Fix specialisation for DFuns When specialising a DFun we must take care to saturate the unfolding. See Note [Specialising DFuns] in Specialise. Fixes #18120 - - - - - 86c77b36 by Greg Steuck at 2020-05-08T15:29:45-04:00 Remove unused SEGMENT_PROT_RWX It's been unused for a year and is problematic on any OS which requires W^X for security. - - - - - 9d97f4b5 by nineonine at 2020-05-08T15:30:03-04:00 Add test for #16167 - - - - - aa318338 by Ryan Scott at 2020-05-08T15:30:04-04:00 Bump exceptions submodule so that dist-boot is .gitignore'd `exceptions` is a stage-0 boot library as of commit 30272412fa437ab8e7a8035db94a278e10513413, which means that building `exceptions` in a GHC tree will generate a `dist-boot` directory. However, this directory was not specified in `exceptions`' `.gitignore` file, which causes it to dirty up the current `git` working directory. Accordingly, this bumps the `exceptions` submodule to commit ghc/packages/exceptions at 23c0b8a50d7592af37ca09beeec16b93080df98f, which adds `dist-boot` to the `.gitignore` file. - - - - - ea86360f by Ömer Sinan Ağacan at 2020-05-08T15:30:30-04:00 Linker.c: initialize n_symbols of ObjectCode with other fields - - - - - 17d5cd57 by Ben Gamari at 2020-05-09T21:48:11-04:00 nativeGen: Deduplicate DWARF strings As noted in #17609, we previously made no attempt to deduplicate strings. This resulted in unnecessarily long compile times and large object files. Fix this. Fixes #17609. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/PrimOps.hs-boot - 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/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/ByteCode/Asm.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/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Block.hs - compiler/GHC/Cmm/Dataflow/Collections.hs - compiler/GHC/Cmm/Dataflow/Graph.hs - compiler/GHC/Cmm/Dataflow/Label.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Expr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a78ef103f9c95f28929082f4fa402c684445b81f...17d5cd579a2c2958e5ecba7311ed6030923127ef -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a78ef103f9c95f28929082f4fa402c684445b81f...17d5cd579a2c2958e5ecba7311ed6030923127ef You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 10 02:19:29 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 09 May 2020 22:19:29 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 11 commits: Fix unboxed-sums GC ptr-slot rubbish value (#17791) Message-ID: <5eb764b1d47b8_61673f8103f8794c10002912@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 951c1fb0 by Sylvain Henry at 2020-05-09T21:46:38-04:00 Fix unboxed-sums GC ptr-slot rubbish value (#17791) This patch allows boot libraries to use unboxed sums without implicitly depending on `base` package because of `absentSumFieldError`. See updated Note [aBSENT_SUM_FIELD_ERROR_ID] in GHC.Core.Make - - - - - b352d63c by Ben Gamari at 2020-05-09T21:47:14-04:00 rts: Make non-existent linker search path merely a warning As noted in #18105, previously this resulted in a rather intrusive error message. This is in contrast to the general expectation that search paths are merely places to look, not places that must exist. Fixes #18105. - - - - - 372a94be by Ben Gamari at 2020-05-09T22:18:51-04:00 rts/CNF: Fix fixup comparison function Previously we would implicitly convert the difference between two words to an int, resulting in an integer overflow on 64-bit machines. Fixes #16992 - - - - - 8e257ba1 by Ben Gamari at 2020-05-09T22:18:52-04:00 get-win32-tarballs: Fix base URL Revert a change previously made for testing purposes. - - - - - a1bf383e by Ben Gamari at 2020-05-09T22:18:52-04:00 get-win32-tarballs: Improve diagnostics output - - - - - 76b7072e by Simon Jakobi at 2020-05-09T22:18:53-04:00 docs: Add examples for Data.Semigroup.Arg{Min,Max} Context: #17153 - - - - - 086df18d by Baldur Blöndal at 2020-05-09T22:18:57-04:00 Predicate, Equivalence derive via `.. -> a -> All' - - - - - 4b0ca8d8 by Richard Eisenberg at 2020-05-09T22:18:58-04:00 Improve Note [The flattening story] - - - - - 63588886 by Hécate at 2020-05-09T22:19:02-04:00 fix(documentation): Fix the RST links to GHC.Prim - - - - - c4869ad9 by Takenobu Tani at 2020-05-09T22:19:18-04:00 Tweak man page for ghc command This commit updates the ghc command's man page as followings: * Enable `man_show_urls` to show URL addresses in the `DESCRIPTION` section of ghc.rst, because sphinx currently removes hyperlinks for man pages. * Add a `SEE ALSO` section to point to the GHC homepage - - - - - f016ecd3 by Takenobu Tani at 2020-05-09T22:19:20-04:00 GHCi: Add link to the user's guide in help message This commit adds a link to the user's guide in ghci's `:help` message. Newcomers could easily reach to details of ghci. - - - - - 29 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/Tc/Solver/Flatten.hs - docs/users_guide/conf.py - docs/users_guide/editing-guide.rst - docs/users_guide/exts/ffi.rst - docs/users_guide/exts/primitives.rst - docs/users_guide/ghc.rst - ghc/GHCi/UI.hs - includes/stg/MiscClosures.h - libraries/base/Control/Exception/Base.hs - libraries/base/Data/Functor/Contravariant.hs - libraries/base/Data/Semigroup.hs - + libraries/ghc-compact/tests/T16992.hs - + libraries/ghc-compact/tests/T16992.stdout - libraries/ghc-compact/tests/all.T - + libraries/ghc-prim/GHC/Prim/Panic.hs - libraries/ghc-prim/ghc-prim.cabal - mk/get-win32-tarballs.py - rts/Exception.cmm - rts/Prelude.h - rts/RtsStartup.c - rts/RtsSymbols.c - rts/linker/PEi386.c - rts/package.conf.in - rts/rts.cabal.in - rts/sm/CNF.c - rts/win32/libHSbase.def Changes: ===================================== compiler/GHC/Builtin/Names.hs ===================================== @@ -511,7 +511,7 @@ genericTyConNames = [ pRELUDE :: Module pRELUDE = mkBaseModule_ pRELUDE_NAME -gHC_PRIM, gHC_TYPES, gHC_GENERICS, gHC_MAGIC, +gHC_PRIM, gHC_PRIM_PANIC, gHC_TYPES, gHC_GENERICS, gHC_MAGIC, gHC_CLASSES, gHC_PRIMOPWRAPPERS, gHC_BASE, gHC_ENUM, gHC_GHCI, gHC_GHCI_HELPERS, gHC_CSTRING, gHC_SHOW, gHC_READ, gHC_NUM, gHC_MAYBE, gHC_INTEGER_TYPE, gHC_NATURAL, @@ -527,6 +527,7 @@ gHC_PRIM, gHC_TYPES, gHC_GENERICS, gHC_MAGIC, dATA_COERCE, dEBUG_TRACE, uNSAFE_COERCE :: Module gHC_PRIM = mkPrimModule (fsLit "GHC.Prim") -- Primitive types and values +gHC_PRIM_PANIC = mkPrimModule (fsLit "GHC.Prim.Panic") gHC_TYPES = mkPrimModule (fsLit "GHC.Types") gHC_MAGIC = mkPrimModule (fsLit "GHC.Magic") gHC_CSTRING = mkPrimModule (fsLit "GHC.CString") ===================================== compiler/GHC/Core/Make.hs ===================================== @@ -735,6 +735,7 @@ errorIds rEC_CON_ERROR_ID, rEC_SEL_ERROR_ID, aBSENT_ERROR_ID, + aBSENT_SUM_FIELD_ERROR_ID, tYPE_ERROR_ID -- Used with Opt_DeferTypeErrors, see #10284 ] @@ -746,8 +747,6 @@ absentSumFieldErrorName :: Name recSelErrorName = err_nm "recSelError" recSelErrorIdKey rEC_SEL_ERROR_ID absentErrorName = err_nm "absentError" absentErrorIdKey aBSENT_ERROR_ID -absentSumFieldErrorName = err_nm "absentSumFieldError" absentSumFieldErrorIdKey - aBSENT_SUM_FIELD_ERROR_ID runtimeErrorName = err_nm "runtimeError" runtimeErrorIdKey rUNTIME_ERROR_ID recConErrorName = err_nm "recConError" recConErrorIdKey rEC_CON_ERROR_ID patErrorName = err_nm "patError" patErrorIdKey pAT_ERROR_ID @@ -774,25 +773,68 @@ tYPE_ERROR_ID = mkRuntimeErrorId typeErrorName -- Note [aBSENT_SUM_FIELD_ERROR_ID] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --- Absent argument error for unused unboxed sum fields are different than absent --- error used in dummy worker functions (see `mkAbsentErrorApp`): -- --- - `absentSumFieldError` can't take arguments because it's used in unarise for --- unused pointer fields in unboxed sums, and applying an argument would --- require allocating a thunk. +-- Unboxed sums are transformed into unboxed tuples in GHC.Stg.Unarise.mkUbxSum +-- and fields that can't be reached are filled with rubbish values. It's easy to +-- come up with rubbish literal values: we use 0 (ints/words) and 0.0 +-- (floats/doubles). Coming up with a rubbish pointer value is more delicate: -- --- - `absentSumFieldError` can't be CAFFY because that would mean making some --- non-CAFFY definitions that use unboxed sums CAFFY in unarise. +-- 1. it needs to be a valid closure pointer for the GC (not a NULL pointer) -- --- To make `absentSumFieldError` non-CAFFY we get a stable pointer to it in --- RtsStartup.c and mark it as non-CAFFY here. +-- 2. it is never used in Core, only in STG; and even then only for filling a +-- GC-ptr slot in an unboxed sum (see GHC.Stg.Unarise.ubxSumRubbishArg). +-- So all we need is a pointer, and its levity doesn't matter. Hence we +-- can safely give it the (lifted) type: -- --- Getting this wrong causes hard-to-debug runtime issues, see #15038. +-- absentSumFieldError :: forall a. a -- --- TODO: Remove stable pointer hack after fixing #9718. --- However, we should still be careful about not making things CAFFY just --- because they use unboxed sums. Unboxed objects are supposed to be --- efficient, and none of the other unboxed literals make things CAFFY. +-- despite the fact that Unarise might instantiate it at non-lifted +-- types. +-- +-- 3. it can't take arguments because it's used in unarise and applying an +-- argument would require allocating a thunk. +-- +-- 4. it can't be CAFFY because that would mean making some non-CAFFY +-- definitions that use unboxed sums CAFFY in unarise. +-- +-- Getting this wrong causes hard-to-debug runtime issues, see #15038. +-- +-- 5. it can't be defined in `base` package. +-- +-- Defining `absentSumFieldError` in `base` package introduces a +-- dependency on `base` for any code using unboxed sums. It became an +-- issue when we wanted to use unboxed sums in boot libraries used by +-- `base`, see #17791. +-- +-- +-- * Most runtime-error functions throw a proper Haskell exception, which can be +-- caught in the usual way. But these functions are defined in +-- `base:Control.Exception.Base`, hence, they cannot be directly invoked in +-- any library compiled before `base`. Only exceptions that have been wired +-- in the RTS can be thrown (indirectly, via a call into the RTS) by libraries +-- compiled before `base`. +-- +-- However wiring exceptions in the RTS is a bit annoying because we need to +-- explicitly import exception closures via their mangled symbol name (e.g. +-- `import CLOSURE base_GHCziIOziException_heapOverflow_closure`) in Cmm files +-- and every imported symbol must be indicated to the linker in a few files +-- (`package.conf`, `rts.cabal`, `win32/libHSbase.def`, `Prelude.h`...). It +-- explains why exceptions are only wired in the RTS when necessary. +-- +-- * `absentSumFieldError` is defined in ghc-prim:GHC.Prim.Panic, hence, it can +-- be invoked in libraries compiled before `base`. It does not throw a Haskell +-- exception; instead, it calls `stg_panic#`, which immediately halts +-- execution. A runtime invocation of `absentSumFieldError` indicates a GHC +-- bug. Unlike (say) pattern-match errors, it cannot be caused by a user +-- error. That's why it is OK for it to be un-catchable. +-- + +absentSumFieldErrorName + = mkWiredInIdName + gHC_PRIM_PANIC + (fsLit "absentSumFieldError") + absentSumFieldErrorIdKey + aBSENT_SUM_FIELD_ERROR_ID aBSENT_SUM_FIELD_ERROR_ID = mkVanillaGlobalWithInfo absentSumFieldErrorName ===================================== compiler/GHC/Stg/Unarise.hs ===================================== @@ -577,18 +577,26 @@ mkUbxSum dc ty_args args0 | Just stg_arg <- IM.lookup arg_idx arg_map = stg_arg : mkTupArgs (arg_idx + 1) slots_left arg_map | otherwise - = slotRubbishArg slot : mkTupArgs (arg_idx + 1) slots_left arg_map - - slotRubbishArg :: SlotTy -> StgArg - slotRubbishArg PtrSlot = StgVarArg aBSENT_SUM_FIELD_ERROR_ID - -- See Note [aBSENT_SUM_FIELD_ERROR_ID] in GHC.Core.Make - slotRubbishArg WordSlot = StgLitArg (LitNumber LitNumWord 0 wordPrimTy) - slotRubbishArg Word64Slot = StgLitArg (LitNumber LitNumWord64 0 word64PrimTy) - slotRubbishArg FloatSlot = StgLitArg (LitFloat 0) - slotRubbishArg DoubleSlot = StgLitArg (LitDouble 0) + = ubxSumRubbishArg slot : mkTupArgs (arg_idx + 1) slots_left arg_map in tag_arg : mkTupArgs 0 sum_slots arg_idxs + +-- | Return a rubbish value for the given slot type. +-- +-- We use the following rubbish values: +-- * Literals: 0 or 0.0 +-- * Pointers: `ghc-prim:GHC.Prim.Panic.absentSumFieldError` +-- +-- See Note [aBSENT_SUM_FIELD_ERROR_ID] in GHC.Core.Make +-- +ubxSumRubbishArg :: SlotTy -> StgArg +ubxSumRubbishArg PtrSlot = StgVarArg aBSENT_SUM_FIELD_ERROR_ID +ubxSumRubbishArg WordSlot = StgLitArg (LitNumber LitNumWord 0 wordPrimTy) +ubxSumRubbishArg Word64Slot = StgLitArg (LitNumber LitNumWord64 0 word64PrimTy) +ubxSumRubbishArg FloatSlot = StgLitArg (LitFloat 0) +ubxSumRubbishArg DoubleSlot = StgLitArg (LitDouble 0) + -------------------------------------------------------------------------------- {- ===================================== compiler/GHC/Tc/Solver/Flatten.hs ===================================== @@ -41,7 +41,7 @@ import Control.Arrow ( first ) {- Note [The flattening story] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~ * A CFunEqCan is either of form [G] : F xis ~ fsk -- fsk is a FlatSkolTv [W] x : F xis ~ fmv -- fmv is a FlatMetaTv @@ -62,7 +62,8 @@ Note [The flattening story] - A unification flatten-skolem, fmv, stands for the as-yet-unknown type to which (F xis) will eventually reduce. It is filled in - + by dischargeFunEq, which calls unflattenFmv; this step will + happen during the interaction phase, after flattening. - All fsk/fmv variables are "untouchable". To make it simple to test, we simply give them TcLevel=0. This means that in a CTyVarEq, say, @@ -73,7 +74,7 @@ Note [The flattening story] a) The CFunEqCan takes a step, using an axiom b) By unflattenWanteds They are never unified in any other form of equality. - For example [W] ffmv ~ Int is stuck; it does not unify with fmv. + For example [W] fmv ~ Int is stuck; it does not unify with fmv. * We *never* substitute in the RHS (i.e. the fsk/fmv) of a CFunEqCan. That would destroy the invariant about the shape of a CFunEqCan, ===================================== docs/users_guide/conf.py ===================================== @@ -135,7 +135,7 @@ man_pages = [ ] # If true, show URL addresses after external links. -#man_show_urls = False +man_show_urls = True # -- Options for Texinfo output ------------------------------------------- ===================================== docs/users_guide/editing-guide.rst ===================================== @@ -228,7 +228,7 @@ For instance, .. code-block:: rest - See the documentation for :base-ref:`Control.Applicative ` + See the documentation for :base-ref:`Control.Applicative.` for details. Math ===================================== docs/users_guide/exts/ffi.rst ===================================== @@ -1027,7 +1027,7 @@ Pinned Byte Arrays A pinned byte array is one that the garbage collector is not allowed to move. Consequently, it has a stable address that can be safely requested with ``byteArrayContents#``. There are a handful of -primitive functions in :ghc-prim-ref:`GHC.Prim ` +primitive functions in :ghc-prim-ref:`GHC.Prim.` used to enforce or check for pinnedness: ``isByteArrayPinned#``, ``isMutableByteArrayPinned#``, and ``newPinnedByteArray#``. A byte array can be pinned as a result of three possible causes: ===================================== docs/users_guide/exts/primitives.rst ===================================== @@ -12,9 +12,8 @@ you write will be optimised to the efficient unboxed version in any case. And if it isn't, we'd like to know about it. All these primitive data types and operations are exported by the -library ``GHC.Prim``, for which there is -:ghc-prim-ref:`detailed online documentation `. (This -documentation is generated from the file ``compiler/GHC/Builtin/primops.txt.pp``.) +library :ghc-prim-ref:`GHC.Prim.`. (This documentation is generated from +the file ``compiler/GHC/Builtin/primops.txt.pp``.) If you want to mention any of the primitive data types or operations in your program, you must first import ``GHC.Prim`` to bring them into ===================================== docs/users_guide/ghc.rst ===================================== @@ -379,3 +379,8 @@ Copyright Copyright 2015. The University Court of the University of Glasgow. All rights reserved. + +See also +-------- + +https://www.haskell.org/ghc the GHC homepage ===================================== ghc/GHCi/UI.hs ===================================== @@ -403,6 +403,10 @@ defFullHelpText = " :show show value of , which is one of\n" ++ " [args, prog, editor, stop]\n" ++ " :showi language show language flags for interactive evaluation\n" ++ + "\n" ++ + " The User's Guide has more information. An online copy can be found here:\n" ++ + "\n" ++ + " https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ghci.html\n" ++ "\n" findEditor :: IO String ===================================== includes/stg/MiscClosures.h ===================================== @@ -418,6 +418,7 @@ RTS_FUN_DECL(stg_raiseDivZZerozh); RTS_FUN_DECL(stg_raiseUnderflowzh); RTS_FUN_DECL(stg_raiseOverflowzh); RTS_FUN_DECL(stg_raiseIOzh); +RTS_FUN_DECL(stg_paniczh); RTS_FUN_DECL(stg_makeStableNamezh); RTS_FUN_DECL(stg_makeStablePtrzh); ===================================== libraries/base/Control/Exception/Base.hs ===================================== @@ -95,7 +95,7 @@ module Control.Exception.Base ( -- * Calls for GHC runtime recSelError, recConError, runtimeError, nonExhaustiveGuardsError, patError, noMethodBindingError, - absentError, absentSumFieldError, typeError, + absentError, typeError, nonTermination, nestedAtomically, ) where @@ -398,7 +398,3 @@ nonTermination = toException NonTermination -- GHC's RTS calls this nestedAtomically :: SomeException nestedAtomically = toException NestedAtomically - --- Introduced by unarise for unused unboxed sum fields -absentSumFieldError :: a -absentSumFieldError = absentError " in unboxed sum."# ===================================== libraries/base/Data/Functor/Contravariant.hs ===================================== @@ -1,5 +1,8 @@ +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE DerivingVia #-} {-# LANGUAGE EmptyCase #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} +{-# LANGUAGE InstanceSigs #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE Trustworthy #-} {-# LANGUAGE TypeOperators #-} @@ -53,11 +56,11 @@ import Data.Functor.Product import Data.Functor.Sum import Data.Functor.Compose -import Data.Monoid (Alt(..)) +import Data.Monoid (Alt(..), All(..)) import Data.Proxy import GHC.Generics -import Prelude hiding ((.),id) +import Prelude hiding ((.), id) -- | The class of contravariant functors. -- @@ -76,6 +79,7 @@ import Prelude hiding ((.),id) -- newtype Predicate a = Predicate { getPredicate :: a -> Bool } -- -- instance Contravariant Predicate where +-- contramap :: (a' -> a) -> (Predicate a -> Predicate a') -- contramap f (Predicate p) = Predicate (p . f) -- | `- First, map the input... -- `----- then apply the predicate. @@ -86,7 +90,7 @@ import Prelude hiding ((.),id) -- -- Any instance should be subject to the following laws: -- --- [Identity] @'contramap' 'id' = 'id'@ +-- [Identity] @'contramap' 'id' = 'id'@ -- [Composition] @'contramap' (g . f) = 'contramap' f . 'contramap' g@ -- -- Note, that the second law follows from the free theorem of the type of @@ -94,7 +98,7 @@ import Prelude hiding ((.),id) -- condition holds. class Contravariant f where - contramap :: (a -> b) -> f b -> f a + contramap :: (a' -> a) -> (f a -> f a') -- | Replace all locations in the output with the same value. -- The default definition is @'contramap' . 'const'@, but this may be @@ -110,7 +114,7 @@ class Contravariant f where -- lawful we have the following laws: -- -- @ --- 'fmap' f ≡ 'phantom' +-- 'fmap' f ≡ 'phantom' -- 'contramap' f ≡ 'phantom' -- @ phantom :: (Functor f, Contravariant f) => f a -> f b @@ -123,79 +127,134 @@ infixl 4 >$, $<, >$<, >$$< ($<) = flip (>$) -- | This is an infix alias for 'contramap'. -(>$<) :: Contravariant f => (a -> b) -> f b -> f a +(>$<) :: Contravariant f => (a -> b) -> (f b -> f a) (>$<) = contramap -- | This is an infix version of 'contramap' with the arguments flipped. (>$$<) :: Contravariant f => f b -> (a -> b) -> f a (>$$<) = flip contramap -deriving instance Contravariant f => Contravariant (Alt f) -deriving instance Contravariant f => Contravariant (Rec1 f) -deriving instance Contravariant f => Contravariant (M1 i c f) +deriving newtype instance Contravariant f => Contravariant (Alt f) +deriving newtype instance Contravariant f => Contravariant (Rec1 f) +deriving newtype instance Contravariant f => Contravariant (M1 i c f) instance Contravariant V1 where + contramap :: (a' -> a) -> (V1 a -> V1 a') contramap _ x = case x of instance Contravariant U1 where + contramap :: (a' -> a) -> (U1 a -> U1 a') contramap _ _ = U1 instance Contravariant (K1 i c) where + contramap :: (a' -> a) -> (K1 i c a -> K1 i c a') contramap _ (K1 c) = K1 c instance (Contravariant f, Contravariant g) => Contravariant (f :*: g) where + contramap :: (a' -> a) -> ((f :*: g) a -> (f :*: g) a') contramap f (xs :*: ys) = contramap f xs :*: contramap f ys instance (Functor f, Contravariant g) => Contravariant (f :.: g) where + contramap :: (a' -> a) -> ((f :.: g) a -> (f :.: g) a') contramap f (Comp1 fg) = Comp1 (fmap (contramap f) fg) instance (Contravariant f, Contravariant g) => Contravariant (f :+: g) where + contramap :: (a' -> a) -> ((f :+: g) a -> (f :+: g) a') contramap f (L1 xs) = L1 (contramap f xs) contramap f (R1 ys) = R1 (contramap f ys) instance (Contravariant f, Contravariant g) => Contravariant (Sum f g) where + contramap :: (a' -> a) -> (Sum f g a -> Sum f g a') contramap f (InL xs) = InL (contramap f xs) contramap f (InR ys) = InR (contramap f ys) instance (Contravariant f, Contravariant g) - => Contravariant (Product f g) where - contramap f (Pair a b) = Pair (contramap f a) (contramap f b) + => Contravariant (Product f g) where + contramap :: (a' -> a) -> (Product f g a -> Product f g a') + contramap f (Pair a b) = Pair (contramap f a) (contramap f b) instance Contravariant (Const a) where + contramap :: (b' -> b) -> (Const a b -> Const a b') contramap _ (Const a) = Const a instance (Functor f, Contravariant g) => Contravariant (Compose f g) where + contramap :: (a' -> a) -> (Compose f g a -> Compose f g a') contramap f (Compose fga) = Compose (fmap (contramap f) fga) instance Contravariant Proxy where + contramap :: (a' -> a) -> (Proxy a -> Proxy a') contramap _ _ = Proxy newtype Predicate a = Predicate { getPredicate :: a -> Bool } - --- | A 'Predicate' is a 'Contravariant' 'Functor', because 'contramap' can --- apply its function argument to the input of the predicate. -instance Contravariant Predicate where - contramap f g = Predicate $ getPredicate g . f - -instance Semigroup (Predicate a) where - Predicate p <> Predicate q = Predicate $ \a -> p a && q a - -instance Monoid (Predicate a) where - mempty = Predicate $ const True + deriving + ( -- | @('<>')@ on predicates uses logical conjunction @('&&')@ on + -- the results. Without newtypes this equals @'liftA2' (&&)@. + -- + -- @ + -- (<>) :: Predicate a -> Predicate a -> Predicate a + -- Predicate pred <> Predicate pred' = Predicate \a -> + -- pred a && pred' a + -- @ + Semigroup + , -- | @'mempty'@ on predicates always returns @True at . Without + -- newtypes this equals @'pure' True at . + -- + -- @ + -- mempty :: Predicate a + -- mempty = \_ -> True + -- @ + Monoid + ) + via a -> All + + deriving + ( -- | A 'Predicate' is a 'Contravariant' 'Functor', because + -- 'contramap' can apply its function argument to the input of + -- the predicate. + -- + -- Without newtypes @'contramap' f@ equals precomposing with @f@ + -- (= @(. f)@). + -- + -- @ + -- contramap :: (a' -> a) -> (Predicate a -> Predicate a') + -- contramap f (Predicate g) = Predicate (g . f) + -- @ + Contravariant + ) + via Op Bool -- | Defines a total ordering on a type as per 'compare'. -- -- This condition is not checked by the types. You must ensure that the -- supplied values are valid total orderings yourself. newtype Comparison a = Comparison { getComparison :: a -> a -> Ordering } - -deriving instance Semigroup (Comparison a) -deriving instance Monoid (Comparison a) + deriving + newtype + ( -- | @('<>')@ on comparisons combines results with @('<>') + -- \@Ordering at . Without newtypes this equals @'liftA2' ('liftA2' + -- ('<>'))@. + -- + -- @ + -- (<>) :: Comparison a -> Comparison a -> Comparison a + -- Comparison cmp <> Comparison cmp' = Comparison \a a' -> + -- cmp a a' <> cmp a a' + -- @ + Semigroup + , -- | @'mempty'@ on comparisons always returns @EQ at . Without + -- newtypes this equals @'pure' ('pure' EQ)@. + -- + -- @ + -- mempty :: Comparison a + -- mempty = Comparison \_ _ -> EQ + -- @ + Monoid + ) -- | A 'Comparison' is a 'Contravariant' 'Functor', because 'contramap' can -- apply its function argument to each input of the comparison function. instance Contravariant Comparison where - contramap f g = Comparison $ on (getComparison g) f + contramap :: (a' -> a) -> (Comparison a -> Comparison a') + contramap f (Comparison g) = Comparison (on g f) -- | Compare using 'compare'. defaultComparison :: Ord a => Comparison a @@ -214,18 +273,34 @@ defaultComparison = Comparison compare -- The types alone do not enforce these laws, so you'll have to check them -- yourself. newtype Equivalence a = Equivalence { getEquivalence :: a -> a -> Bool } + deriving + ( -- | @('<>')@ on equivalences uses logical conjunction @('&&')@ + -- on the results. Without newtypes this equals @'liftA2' + -- ('liftA2' (&&))@. + -- + -- @ + -- (<>) :: Equivalence a -> Equivalence a -> Equivalence a + -- Equivalence equiv <> Equivalence equiv' = Equivalence \a b -> + -- equiv a b && equiv a b + -- @ + Semigroup + , -- | @'mempty'@ on equivalences always returns @True at . Without + -- newtypes this equals @'pure' ('pure' True)@. + -- + -- @ + -- mempty :: Equivalence a + -- mempty = Equivalence \_ _ -> True + -- @ + Monoid + ) + via a -> a -> All -- | Equivalence relations are 'Contravariant', because you can -- apply the contramapped function to each input to the equivalence -- relation. instance Contravariant Equivalence where - contramap f g = Equivalence $ on (getEquivalence g) f - -instance Semigroup (Equivalence a) where - Equivalence p <> Equivalence q = Equivalence $ \a b -> p a b && q a b - -instance Monoid (Equivalence a) where - mempty = Equivalence (\_ _ -> True) + contramap :: (a' -> a) -> (Equivalence a -> Equivalence a') + contramap f (Equivalence g) = Equivalence (on g f) -- | Check for equivalence with '=='. -- @@ -238,15 +313,36 @@ comparisonEquivalence (Comparison p) = Equivalence $ \a b -> p a b == EQ -- | Dual function arrows. newtype Op a b = Op { getOp :: b -> a } - -deriving instance Semigroup a => Semigroup (Op a b) -deriving instance Monoid a => Monoid (Op a b) + deriving + newtype + ( -- | @('<>') \@(Op a b)@ without newtypes is @('<>') \@(b->a)@ = + -- @liftA2 ('<>')@. This lifts the 'Semigroup' operation + -- @('<>')@ over the output of @a at . + -- + -- @ + -- (<>) :: Op a b -> Op a b -> Op a b + -- Op f <> Op g = Op \a -> f a <> g a + -- @ + Semigroup + , -- | @'mempty' \@(Op a b)@ without newtypes is @mempty \@(b->a)@ + -- = @\_ -> mempty at . + -- + -- @ + -- mempty :: Op a b + -- mempty = Op \_ -> mempty + -- @ + Monoid + ) instance Category Op where + id :: Op a a id = Op id + + (.) :: Op b c -> Op a b -> Op a c Op f . Op g = Op (g . f) instance Contravariant (Op a) where + contramap :: (b' -> b) -> (Op a b -> Op a b') contramap f g = Op (getOp g . f) instance Num a => Num (Op a b) where ===================================== libraries/base/Data/Semigroup.hs ===================================== @@ -302,7 +302,14 @@ data Arg a b = Arg , Generic1 -- ^ @since 4.9.0.0 ) +-- | +-- >>> Min (Arg 0 ()) <> Min (Arg 1 ()) +-- Min {getMin = Arg 0 ()} type ArgMin a b = Min (Arg a b) + +-- | +-- >>> Max (Arg 0 ()) <> Max (Arg 1 ()) +-- Max {getMax = Arg 1 ()} type ArgMax a b = Max (Arg a b) -- | @since 4.9.0.0 ===================================== libraries/ghc-compact/tests/T16992.hs ===================================== @@ -0,0 +1,22 @@ +import Data.Bifunctor +import Foreign.Ptr +import qualified Data.ByteString as BS +import qualified Data.ByteString.Unsafe as BS +import qualified GHC.Compact as Compact +import qualified GHC.Compact.Serialized as CompactSerialize + +-- | Minimal test case for reproducing compactFixupPointers# bug for large compact regions. +-- See Issue #16992. +main :: IO () +main = do + let + large = 1024 * 1024 * 128 + largeString = replicate large 'A' + + region <- Compact.compact largeString + + Just deserialized <- CompactSerialize.withSerializedCompact region $ \s -> do + blks <- mapM (BS.unsafePackCStringLen . bimap castPtr fromIntegral) (CompactSerialize.serializedCompactBlockList s) + CompactSerialize.importCompactByteStrings s blks + + print (Compact.getCompact deserialized == largeString) ===================================== libraries/ghc-compact/tests/T16992.stdout ===================================== @@ -0,0 +1 @@ +True ===================================== libraries/ghc-compact/tests/all.T ===================================== @@ -22,3 +22,8 @@ test('compact_share', omit_ways(['ghci', 'profasm', 'profthreaded']), test('compact_bench', [ ignore_stdout, extra_run_opts('100') ], compile_and_run, ['']) test('T17044', normal, compile_and_run, ['']) +# N.B. Sanity check times out due to large list. +test('T16992', [when(wordsize(32), skip), # Resource limit exceeded on 32-bit + high_memory_usage, + run_timeout_multiplier(5), + omit_ways(['sanity'])], compile_and_run, ['']) ===================================== libraries/ghc-prim/GHC/Prim/Panic.hs ===================================== @@ -0,0 +1,45 @@ +{-# LANGUAGE GHCForeignImportPrim #-} +{-# LANGUAGE UnliftedFFITypes #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} +{-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE EmptyCase #-} + +-- | Primitive panics. +module GHC.Prim.Panic + ( absentSumFieldError + , panicError + ) +where + +import GHC.Prim +import GHC.Magic + +default () -- Double and Integer aren't available yet + +-- `stg_panic#` never returns but it can't just return `State# RealWorld` so we +-- indicate that it returns `Void#` too to make the compiler happy. +foreign import prim "stg_paniczh" panic# :: Addr# -> State# RealWorld -> (# State# RealWorld, Void# #) + +-- | Display the CString whose address is given as an argument and exit. +panicError :: Addr# -> a +panicError errmsg = + runRW# (\s -> + case panic# errmsg s of + (# _, _ #) -> -- This bottom is unreachable but we can't + -- use an empty case lest the pattern match + -- checker squawks. + let x = x in x) + +-- | Closure introduced by GHC.Stg.Unarise for unused unboxed sum fields. +-- +-- See Note [aBSENT_SUM_FIELD_ERROR_ID] in GHC.Core.Make +absentSumFieldError :: a +absentSumFieldError = panicError "entered absent sum field!"# + +-- GHC.Core.Make.aBSENT_SUM_FIELD_ERROR_ID gives absentSumFieldError a bottoming +-- demand signature. But if we ever inlined it (to a call to panicError) we'd +-- lose that information. Should not happen because absentSumFieldError is only +-- introduced in Stg.Unarise, long after inlining has stopped, but it seems +-- more direct simply to give it a NOINLINE pragma +{-# NOINLINE absentSumFieldError #-} ===================================== libraries/ghc-prim/ghc-prim.cabal ===================================== @@ -46,6 +46,7 @@ Library GHC.IntWord64 GHC.Magic GHC.Prim.Ext + GHC.Prim.Panic GHC.PrimopWrappers GHC.Tuple GHC.Types ===================================== mk/get-win32-tarballs.py ===================================== @@ -5,10 +5,10 @@ from pathlib import Path import urllib.request import subprocess import argparse +from sys import stderr TARBALL_VERSION = '0.1' BASE_URL = "https://downloads.haskell.org/ghc/mingw/{}".format(TARBALL_VERSION) -BASE_URL = "http://home.smart-cactus.org/~ben/ghc/mingw/{}".format(TARBALL_VERSION) DEST = Path('ghc-tarballs/mingw-w64') ARCHS = ['i686', 'x86_64', 'sources'] @@ -19,11 +19,13 @@ def file_url(arch: str, fname: str) -> str: fname=fname) def fetch(url: str, dest: Path): - print('Fetching', url, '=>', dest) + print('Fetching', url, '=>', dest, file=stderr) urllib.request.urlretrieve(url, dest) def fetch_arch(arch: str): - req = urllib.request.urlopen(file_url(arch, 'MANIFEST')) + manifest_url = file_url(arch, 'MANIFEST') + print('Fetching', manifest_url, file=stderr) + req = urllib.request.urlopen(manifest_url) files = req.read().decode('UTF-8').split('\n') d = DEST / arch if not d.is_dir(): @@ -36,6 +38,9 @@ def fetch_arch(arch: str): verify(arch) def verify(arch: str): + if not Path(DEST / arch / "SHA256SUMS").is_file(): + raise IOError("SHA256SUMS doesn't exist; have you fetched?") + cmd = ['sha256sum', '--quiet', '--check', '--ignore-missing', 'SHA256SUMS'] subprocess.check_call(cmd, cwd=DEST / arch) ===================================== rts/Exception.cmm ===================================== @@ -632,3 +632,12 @@ stg_raiseIOzh (P_ exception) { jump stg_raisezh (exception); } + +/* The FFI doesn't support variadic C functions so we can't directly expose + * `barf` to Haskell code. Instead we define "stg_panic#" and it is exposed to + * Haskell programs in GHC.Prim.Panic. + */ +stg_paniczh (W_ str) +{ + ccall barf(str) never returns; +} ===================================== rts/Prelude.h ===================================== @@ -45,7 +45,6 @@ PRELUDE_CLOSURE(base_GHCziIOziException_cannotCompactPinned_closure); PRELUDE_CLOSURE(base_GHCziIOziException_cannotCompactMutable_closure); PRELUDE_CLOSURE(base_ControlziExceptionziBase_nonTermination_closure); PRELUDE_CLOSURE(base_ControlziExceptionziBase_nestedAtomically_closure); -PRELUDE_CLOSURE(base_ControlziExceptionziBase_absentSumFieldError_closure); PRELUDE_CLOSURE(base_GHCziEventziThread_blockedOnBadFD_closure); PRELUDE_CLOSURE(base_GHCziExceptionziType_divZZeroException_closure); PRELUDE_CLOSURE(base_GHCziExceptionziType_underflowException_closure); @@ -103,7 +102,6 @@ PRELUDE_INFO(base_GHCziStable_StablePtr_con_info); #define nonTermination_closure DLL_IMPORT_DATA_REF(base_ControlziExceptionziBase_nonTermination_closure) #define nestedAtomically_closure DLL_IMPORT_DATA_REF(base_ControlziExceptionziBase_nestedAtomically_closure) #define blockedOnBadFD_closure DLL_IMPORT_DATA_REF(base_GHCziEventziThread_blockedOnBadFD_closure) -#define absentSumFieldError_closure DLL_IMPORT_DATA_REF(base_ControlziExceptionziBase_absentSumFieldError_closure) #define Czh_con_info DLL_IMPORT_DATA_REF(ghczmprim_GHCziTypes_Czh_con_info) #define Izh_con_info DLL_IMPORT_DATA_REF(ghczmprim_GHCziTypes_Izh_con_info) ===================================== rts/RtsStartup.c ===================================== @@ -275,10 +275,6 @@ hs_init_ghc(int *argc, char **argv[], RtsConfig rts_config) getStablePtr((StgPtr)cannotCompactPinned_closure); getStablePtr((StgPtr)cannotCompactMutable_closure); getStablePtr((StgPtr)nestedAtomically_closure); - getStablePtr((StgPtr)absentSumFieldError_closure); - // `Id` for this closure is marked as non-CAFFY, - // see Note [aBSENT_SUM_FIELD_ERROR_ID] in GHC.Core.Make. - getStablePtr((StgPtr)runSparks_closure); getStablePtr((StgPtr)ensureIOManagerIsRunning_closure); getStablePtr((StgPtr)ioManagerCapabilitiesChanged_closure); ===================================== rts/RtsSymbols.c ===================================== @@ -732,6 +732,7 @@ SymI_HasProto(stg_raiseUnderflowzh) \ SymI_HasProto(stg_raiseOverflowzh) \ SymI_HasProto(stg_raiseIOzh) \ + SymI_HasProto(stg_paniczh) \ SymI_HasProto(stg_readTVarzh) \ SymI_HasProto(stg_readTVarIOzh) \ SymI_HasProto(resumeThread) \ ===================================== rts/linker/PEi386.c ===================================== @@ -776,12 +776,12 @@ HsPtr addLibrarySearchPath_PEi386(pathchar* dll_path) WCHAR* abs_path = malloc(sizeof(WCHAR) * init_buf_size); DWORD wResult = GetFullPathNameW(dll_path, bufsize, abs_path, NULL); if (!wResult){ - sysErrorBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError()); + IF_DEBUG(linker, debugBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError())); } else if (wResult > init_buf_size) { abs_path = realloc(abs_path, sizeof(WCHAR) * wResult); if (!GetFullPathNameW(dll_path, bufsize, abs_path, NULL)) { - sysErrorBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError()); + IF_DEBUG(linker, debugBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError())); } } ===================================== rts/package.conf.in ===================================== @@ -97,7 +97,6 @@ ld-options: , "-Wl,-u,_base_GHCziIOziException_cannotCompactFunction_closure" , "-Wl,-u,_base_GHCziIOziException_cannotCompactPinned_closure" , "-Wl,-u,_base_GHCziIOziException_cannotCompactMutable_closure" - , "-Wl,-u,_base_ControlziExceptionziBase_absentSumFieldError_closure" , "-Wl,-u,_base_ControlziExceptionziBase_nonTermination_closure" , "-Wl,-u,_base_ControlziExceptionziBase_nestedAtomically_closure" , "-Wl,-u,_base_GHCziEventziThread_blockedOnBadFD_closure" @@ -203,7 +202,6 @@ ld-options: , "-Wl,-u,base_GHCziIOziException_cannotCompactFunction_closure" , "-Wl,-u,base_GHCziIOziException_cannotCompactPinned_closure" , "-Wl,-u,base_GHCziIOziException_cannotCompactMutable_closure" - , "-Wl,-u,base_ControlziExceptionziBase_absentSumFieldError_closure" , "-Wl,-u,base_ControlziExceptionziBase_nonTermination_closure" , "-Wl,-u,base_ControlziExceptionziBase_nestedAtomically_closure" , "-Wl,-u,base_GHCziEventziThread_blockedOnBadFD_closure" ===================================== rts/rts.cabal.in ===================================== @@ -218,7 +218,6 @@ library "-Wl,-u,_base_GHCziIOziException_cannotCompactFunction_closure" "-Wl,-u,_base_GHCziIOziException_cannotCompactPinned_closure" "-Wl,-u,_base_GHCziIOziException_cannotCompactMutable_closure" - "-Wl,-u,_base_ControlziExceptionziBase_absentSumFieldError_closure" "-Wl,-u,_base_ControlziExceptionziBase_nonTermination_closure" "-Wl,-u,_base_ControlziExceptionziBase_nestedAtomically_closure" "-Wl,-u,_base_GHCziEventziThread_blockedOnBadFD_closure" @@ -294,7 +293,6 @@ library "-Wl,-u,base_GHCziIOziException_cannotCompactFunction_closure" "-Wl,-u,base_GHCziIOziException_cannotCompactPinned_closure" "-Wl,-u,base_GHCziIOziException_cannotCompactMutable_closure" - "-Wl,-u,base_ControlziExceptionziBase_absentSumFieldError_closure" "-Wl,-u,base_ControlziExceptionziBase_nonTermination_closure" "-Wl,-u,base_ControlziExceptionziBase_nestedAtomically_closure" "-Wl,-u,base_GHCziEventziThread_blockedOnBadFD_closure" ===================================== rts/sm/CNF.c ===================================== @@ -1020,8 +1020,9 @@ cmp_fixup_table_item (const void *e1, const void *e2) { const StgWord *w1 = e1; const StgWord *w2 = e2; - - return *w1 - *w2; + if (*w1 > *w2) return +1; + else if (*w1 < *w2) return -1; + else return 0; } static StgWord * ===================================== rts/win32/libHSbase.def ===================================== @@ -42,7 +42,6 @@ EXPORTS base_GHCziIOziException_cannotCompactPinned_closure base_GHCziIOziException_cannotCompactMutable_closure - base_ControlziExceptionziBase_absentSumFieldError_closure base_ControlziExceptionziBase_nonTermination_closure base_ControlziExceptionziBase_nestedAtomically_closure base_GHCziEventziThread_blockedOnBadFD_closure View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9f31062daa7140fb2603c9de2f17f7d957258a21...f016ecd34bf8bd6c714bc9bfa13d534ea720dd49 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9f31062daa7140fb2603c9de2f17f7d957258a21...f016ecd34bf8bd6c714bc9bfa13d534ea720dd49 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 10 10:23:47 2020 From: gitlab at gitlab.haskell.org (Matthew Pickering) Date: Sun, 10 May 2020 06:23:47 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/add-back-uniqmap Message-ID: <5eb7d63361042_6167119f8560100477ba@gitlab.haskell.org.mail> Matthew Pickering pushed new branch wip/add-back-uniqmap at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/add-back-uniqmap You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 10 11:35:46 2020 From: gitlab at gitlab.haskell.org (Matthew Pickering) Date: Sun, 10 May 2020 07:35:46 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/con-info Message-ID: <5eb7e71258b88_6167119f856010054078@gitlab.haskell.org.mail> Matthew Pickering pushed new branch wip/con-info at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/con-info You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 10 15:28:41 2020 From: gitlab at gitlab.haskell.org (Sven Tennie) Date: Sun, 10 May 2020 11:28:41 -0400 Subject: [Git][ghc/ghc][wip/ghc-debug] Decode more StgTSO fields in ghc-heap Message-ID: <5eb81da9bfe53_616711922e9c10062868@gitlab.haskell.org.mail> Sven Tennie pushed to branch wip/ghc-debug at Glasgow Haskell Compiler / GHC Commits: 203cbc02 by Sven Tennie at 2020-05-10T17:27:51+02:00 Decode more StgTSO fields in ghc-heap - - - - - 4 changed files: - includes/rts/storage/TSO.h - libraries/ghc-heap/GHC/Exts/Heap.hs - libraries/ghc-heap/GHC/Exts/Heap/Closures.hs - rts/Heap.c Changes: ===================================== includes/rts/storage/TSO.h ===================================== @@ -107,6 +107,22 @@ typedef struct StgTSO_ { */ struct StgStack_ *stackobj; + struct InCall_ *bound; + struct Capability_ *cap; + + struct StgTRecHeader_ *trec; /* STM transaction record */ + + /* + * A list of threads blocked on this TSO waiting to throw exceptions. + */ + struct MessageThrowTo_ *blocked_exceptions; + + /* + * A list of StgBlockingQueue objects, representing threads + * blocked on thunks that are under evaluation by this thread. + */ + struct StgBlockingQueue_ *bq; + /* * The tso->dirty flag indicates that this TSO's stack should be * scanned during garbage collection. It also indicates that this @@ -128,21 +144,6 @@ typedef struct StgTSO_ { StgThreadID id; StgWord32 saved_errno; StgWord32 dirty; /* non-zero => dirty */ - struct InCall_* bound; - struct Capability_* cap; - - struct StgTRecHeader_ * trec; /* STM transaction record */ - - /* - * A list of threads blocked on this TSO waiting to throw exceptions. - */ - struct MessageThrowTo_ * blocked_exceptions; - - /* - * A list of StgBlockingQueue objects, representing threads - * blocked on thunks that are under evaluation by this thread. - */ - struct StgBlockingQueue_ *bq; /* * The allocation limit for this thread, which is updated as the ===================================== libraries/ghc-heap/GHC/Exts/Heap.hs ===================================== @@ -287,10 +287,18 @@ getClosureX get_closure_raw x = do , link = pts !! 4 } TSO -> do - unless (length pts >= 1) $ - fail $ "Expected at least 1 ptr argument to TSO, found " + unless (length pts == 6) $ + fail $ "Expected 6 ptr arguments to TSO, found " ++ show (length pts) - pure $ TSOClosure itbl (pts !! 0) + pure $ TSOClosure + { info = itbl + , _link = (pts !! 0) + , global_link = (pts !! 1) + , tsoStack = (pts !! 2) + , trec = (pts !! 3) + , blocked_exceptions = (pts !! 4) + , bq = (pts !! 5) + } STACK -> do unless (length pts >= 1) $ fail $ "Expected at least 1 ptr argument to STACK, found " ===================================== libraries/ghc-heap/GHC/Exts/Heap/Closures.hs ===================================== @@ -262,9 +262,16 @@ data GenClosure b -- TODO: There are many more fields in a TSO closure which -- are not yet implemented + + -- | StgTSO | TSOClosure { info :: !StgInfoTable - , tsoStack :: !b + , _link :: !b + , global_link :: !b + , tsoStack :: !b -- ^ stackobj from StgTSO + , trec :: !b + , blocked_exceptions :: !b + , bq :: !b } | StackClosure ===================================== rts/Heap.c ===================================== @@ -206,8 +206,23 @@ static StgWord collect_pointers(StgClosure *closure, StgWord size, StgClosure *p ptrs[nptrs++] = ((StgMVar *)closure)->value; break; case TSO: - // TODO: Not complete + ASSERT((StgClosure *)((StgTSO *)closure)->_link != NULL); + ptrs[nptrs++] = (StgClosure *)((StgTSO *)closure)->_link; + + ASSERT((StgClosure *)((StgTSO *)closure)->global_link != NULL); + ptrs[nptrs++] = (StgClosure *)((StgTSO *)closure)->global_link; + + ASSERT((StgClosure *)((StgTSO *)closure)->stackobj != NULL); ptrs[nptrs++] = (StgClosure *)((StgTSO *)closure)->stackobj; + + ASSERT((StgClosure *)((StgTSO *)closure)->trec != NULL); + ptrs[nptrs++] = (StgClosure *)((StgTSO *)closure)->trec; + + ASSERT((StgClosure *)((StgTSO *)closure)->blocked_exceptions != NULL); + ptrs[nptrs++] = (StgClosure *)((StgTSO *)closure)->blocked_exceptions; + + ASSERT((StgClosure *)((StgTSO *)closure)->bq != NULL); + ptrs[nptrs++] = (StgClosure *)((StgTSO *)closure)->bq; break; case STACK: ptrs[nptrs++] = (StgClosure *)((StgStack *)closure)->sp; View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/203cbc02fe3358a5d2300eacce59666b7a4c699a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/203cbc02fe3358a5d2300eacce59666b7a4c699a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 10 16:13:20 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 10 May 2020 12:13:20 -0400 Subject: [Git][ghc/ghc][wip/T18074] users-guide: Add discussion of shared object naming Message-ID: <5eb82820ca5a1_6167119ebbd01007235e@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18074 at Glasgow Haskell Compiler / GHC Commits: c802f8d5 by Ben Gamari at 2020-05-10T12:13:14-04:00 users-guide: Add discussion of shared object naming Fixes #18074. - - - - - 2 changed files: - docs/users_guide/packages.rst - docs/users_guide/phases.rst Changes: ===================================== docs/users_guide/packages.rst ===================================== @@ -1061,6 +1061,14 @@ extra indirection). its output in place of ⟨GHCVersion⟩. See also :ref:`options-codegen` on how object files must be prepared for shared object linking. +- When building a shared library, care must be taken to ensure that the + resulting object is named appropriately. In particular, GHC expects the + name of a shared object to have the form ``libHS-ghc.`` where *unit id* is the unit ID given during compilation via + the :ghc-flag:`-package-id ⟨unit-id⟩` flag, *ghc version* is the version of + GHC that produced/consumes the object and *ext* is the host system's usual + file extension for shared objects. + To compile a module which is to be part of a new package, use the ``-package-name`` (to identify the name of the package) and ``-library-name`` (to identify the version and the version hashes of its ===================================== docs/users_guide/phases.rst ===================================== @@ -807,7 +807,8 @@ for example). When creating shared objects for Haskell packages, the shared object must be named properly, so that GHC recognizes the shared object - when linked against this package. See shared object name mangling. + when linking against this package. + See :ref:`shared object name mangling ` for details. .. ghc-flag:: -dynload :shortdesc: Selects one of a number of modes for finding shared libraries at runtime. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c802f8d56cf5737b0a355ab01e1a8ffc42f483c0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c802f8d56cf5737b0a355ab01e1a8ffc42f483c0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 10 16:32:53 2020 From: gitlab at gitlab.haskell.org (Sven Tennie) Date: Sun, 10 May 2020 12:32:53 -0400 Subject: [Git][ghc/ghc][wip/ghc-debug] Lint Message-ID: <5eb82cb57753f_616711a31edc100764fc@gitlab.haskell.org.mail> Sven Tennie pushed to branch wip/ghc-debug at Glasgow Haskell Compiler / GHC Commits: a7b07308 by Sven Tennie at 2020-05-10T18:32:33+02:00 Lint - - - - - 2 changed files: - libraries/ghc-heap/GHC/Exts/Heap.hs - libraries/ghc-heap/GHC/Exts/Heap/Closures.hs Changes: ===================================== libraries/ghc-heap/GHC/Exts/Heap.hs ===================================== @@ -290,7 +290,7 @@ getClosureX get_closure_raw x = do unless (length pts == 6) $ fail $ "Expected 6 ptr arguments to TSO, found " ++ show (length pts) - pure $ TSOClosure + pure $ TSOClosure { info = itbl , _link = (pts !! 0) , global_link = (pts !! 1) @@ -298,7 +298,7 @@ getClosureX get_closure_raw x = do , trec = (pts !! 3) , blocked_exceptions = (pts !! 4) , bq = (pts !! 5) - } + } STACK -> do unless (length pts >= 1) $ fail $ "Expected at least 1 ptr argument to STACK, found " ===================================== libraries/ghc-heap/GHC/Exts/Heap/Closures.hs ===================================== @@ -262,7 +262,7 @@ data GenClosure b -- TODO: There are many more fields in a TSO closure which -- are not yet implemented - + -- | StgTSO | TSOClosure { info :: !StgInfoTable View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a7b07308a43857bca90a898bacee41f65c78c5ab -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a7b07308a43857bca90a898bacee41f65c78c5ab You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 10 16:52:57 2020 From: gitlab at gitlab.haskell.org (Sven Tennie) Date: Sun, 10 May 2020 12:52:57 -0400 Subject: [Git][ghc/ghc][wip/ghc-debug] Decode more StgTSO fields in ghc-heap Message-ID: <5eb8316986b47_61673f81a3bd711c100795fc@gitlab.haskell.org.mail> Sven Tennie pushed to branch wip/ghc-debug at Glasgow Haskell Compiler / GHC Commits: 5d9864a5 by Sven Tennie at 2020-05-10T18:51:11+02:00 Decode more StgTSO fields in ghc-heap - - - - - 4 changed files: - includes/rts/storage/TSO.h - libraries/ghc-heap/GHC/Exts/Heap.hs - libraries/ghc-heap/GHC/Exts/Heap/Closures.hs - rts/Heap.c Changes: ===================================== includes/rts/storage/TSO.h ===================================== @@ -107,6 +107,22 @@ typedef struct StgTSO_ { */ struct StgStack_ *stackobj; + struct InCall_ *bound; + struct Capability_ *cap; + + struct StgTRecHeader_ *trec; /* STM transaction record */ + + /* + * A list of threads blocked on this TSO waiting to throw exceptions. + */ + struct MessageThrowTo_ *blocked_exceptions; + + /* + * A list of StgBlockingQueue objects, representing threads + * blocked on thunks that are under evaluation by this thread. + */ + struct StgBlockingQueue_ *bq; + /* * The tso->dirty flag indicates that this TSO's stack should be * scanned during garbage collection. It also indicates that this @@ -128,21 +144,6 @@ typedef struct StgTSO_ { StgThreadID id; StgWord32 saved_errno; StgWord32 dirty; /* non-zero => dirty */ - struct InCall_* bound; - struct Capability_* cap; - - struct StgTRecHeader_ * trec; /* STM transaction record */ - - /* - * A list of threads blocked on this TSO waiting to throw exceptions. - */ - struct MessageThrowTo_ * blocked_exceptions; - - /* - * A list of StgBlockingQueue objects, representing threads - * blocked on thunks that are under evaluation by this thread. - */ - struct StgBlockingQueue_ *bq; /* * The allocation limit for this thread, which is updated as the ===================================== libraries/ghc-heap/GHC/Exts/Heap.hs ===================================== @@ -287,10 +287,18 @@ getClosureX get_closure_raw x = do , link = pts !! 4 } TSO -> do - unless (length pts >= 1) $ - fail $ "Expected at least 1 ptr argument to TSO, found " + unless (length pts == 6) $ + fail $ "Expected 6 ptr arguments to TSO, found " ++ show (length pts) - pure $ TSOClosure itbl (pts !! 0) + pure $ TSOClosure + { info = itbl + , _link = (pts !! 0) + , global_link = (pts !! 1) + , tsoStack = (pts !! 2) + , trec = (pts !! 3) + , blocked_exceptions = (pts !! 4) + , bq = (pts !! 5) + } STACK -> do unless (length pts >= 1) $ fail $ "Expected at least 1 ptr argument to STACK, found " ===================================== libraries/ghc-heap/GHC/Exts/Heap/Closures.hs ===================================== @@ -262,9 +262,16 @@ data GenClosure b -- TODO: There are many more fields in a TSO closure which -- are not yet implemented + + -- | StgTSO | TSOClosure { info :: !StgInfoTable - , tsoStack :: !b + , _link :: !b + , global_link :: !b + , tsoStack :: !b -- ^ stackobj from StgTSO + , trec :: !b + , blocked_exceptions :: !b + , bq :: !b } | StackClosure ===================================== rts/Heap.c ===================================== @@ -206,8 +206,23 @@ static StgWord collect_pointers(StgClosure *closure, StgWord size, StgClosure *p ptrs[nptrs++] = ((StgMVar *)closure)->value; break; case TSO: - // TODO: Not complete + ASSERT((StgClosure *)((StgTSO *)closure)->_link != NULL); + ptrs[nptrs++] = (StgClosure *)((StgTSO *)closure)->_link; + + ASSERT((StgClosure *)((StgTSO *)closure)->global_link != NULL); + ptrs[nptrs++] = (StgClosure *)((StgTSO *)closure)->global_link; + + ASSERT((StgClosure *)((StgTSO *)closure)->stackobj != NULL); ptrs[nptrs++] = (StgClosure *)((StgTSO *)closure)->stackobj; + + ASSERT((StgClosure *)((StgTSO *)closure)->trec != NULL); + ptrs[nptrs++] = (StgClosure *)((StgTSO *)closure)->trec; + + ASSERT((StgClosure *)((StgTSO *)closure)->blocked_exceptions != NULL); + ptrs[nptrs++] = (StgClosure *)((StgTSO *)closure)->blocked_exceptions; + + ASSERT((StgClosure *)((StgTSO *)closure)->bq != NULL); + ptrs[nptrs++] = (StgClosure *)((StgTSO *)closure)->bq; break; case STACK: ptrs[nptrs++] = (StgClosure *)((StgStack *)closure)->sp; View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5d9864a55d2c7c7446ed15e1cc609abfdf8b9f65 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5d9864a55d2c7c7446ed15e1cc609abfdf8b9f65 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 10 16:57:46 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 10 May 2020 12:57:46 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/gc/parallel-marking Message-ID: <5eb8328a9eefd_61673f8103f8794c10080668@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/gc/parallel-marking at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/gc/parallel-marking You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 10 18:40:44 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 10 May 2020 14:40:44 -0400 Subject: [Git][ghc/ghc][wip/T14781] 5 commits: Add test for #16167 Message-ID: <5eb84aacefa63_6167119ebbd010110233@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T14781 at Glasgow Haskell Compiler / GHC Commits: 9d97f4b5 by nineonine at 2020-05-08T15:30:03-04:00 Add test for #16167 - - - - - aa318338 by Ryan Scott at 2020-05-08T15:30:04-04:00 Bump exceptions submodule so that dist-boot is .gitignore'd `exceptions` is a stage-0 boot library as of commit 30272412fa437ab8e7a8035db94a278e10513413, which means that building `exceptions` in a GHC tree will generate a `dist-boot` directory. However, this directory was not specified in `exceptions`' `.gitignore` file, which causes it to dirty up the current `git` working directory. Accordingly, this bumps the `exceptions` submodule to commit ghc/packages/exceptions at 23c0b8a50d7592af37ca09beeec16b93080df98f, which adds `dist-boot` to the `.gitignore` file. - - - - - ea86360f by Ömer Sinan Ağacan at 2020-05-08T15:30:30-04:00 Linker.c: initialize n_symbols of ObjectCode with other fields - - - - - 3c15cd45 by Ben Gamari at 2020-05-10T14:40:37-04:00 rts: Teach getNumProcessors to return available processors Previously we would report the number of physical processors, which can be quite wrong in a containerized setting. Now we rather return how many processors are in our affinity mask when possible. I also refactored the code to prefer platform-specific since this will report logical CPUs instead of physical (using `machdep.cpu.thread_count` on Darwin and `cpuset_getaffinity` on FreeBSD). Fixes #14781. - - - - - ce8bca8d by Ben Gamari at 2020-05-10T14:40:37-04:00 rts: Drop compatibility shims for Windows Vista We can now assume that the thread and processor group interfaces are available. - - - - - 8 changed files: - configure.ac - libraries/exceptions - rts/Linker.c - rts/posix/OSThreads.c - rts/win32/OSThreads.c - + testsuite/tests/driver/T16167.hs - + testsuite/tests/driver/T16167.stdout - testsuite/tests/driver/all.T Changes: ===================================== configure.ac ===================================== @@ -964,7 +964,7 @@ FP_CHECK_FUNC([GetModuleFileName], dnl ** check for more functions dnl ** The following have been verified to be used in ghc/, but might be used somewhere else, too. -AC_CHECK_FUNCS([getclock getrusage gettimeofday setitimer siginterrupt sysconf times ctime_r sched_setaffinity setlocale]) +AC_CHECK_FUNCS([getclock getrusage gettimeofday setitimer siginterrupt sysconf times ctime_r sched_setaffinity sched_getaffinity setlocale]) dnl ** On OS X 10.4 (at least), time.h doesn't declare ctime_r if dnl ** _POSIX_C_SOURCE is defined ===================================== libraries/exceptions ===================================== @@ -1 +1 @@ -Subproject commit fe4166f8d23d8288ef2cbbf9e36118b6b99e0d7d +Subproject commit 23c0b8a50d7592af37ca09beeec16b93080df98f ===================================== rts/Linker.c ===================================== @@ -1326,6 +1326,7 @@ mkOc( pathchar *path, char *image, int imageSize, setOcInitialStatus( oc ); oc->fileSize = imageSize; + oc->n_symbols = 0; oc->symbols = NULL; oc->n_sections = 0; oc->sections = NULL; ===================================== rts/posix/OSThreads.c ===================================== @@ -240,26 +240,50 @@ forkOS_createThread ( HsStablePtr entry ) void freeThreadingResources (void) { /* nothing */ } +// Get the number of logical CPU cores available to us. Note that this is +// different from the number of physical cores (see #14781). uint32_t getNumberOfProcessors (void) { static uint32_t nproc = 0; if (nproc == 0) { -#if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN) - nproc = sysconf(_SC_NPROCESSORS_ONLN); -#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_CONF) - nproc = sysconf(_SC_NPROCESSORS_CONF); -#elif defined(darwin_HOST_OS) +#if defined(HAVE_SCHED_GETAFFINITY) + cpu_set_t mask; + CPU_ZERO(&mask); + if (sched_getaffinity(0, sizeof(mask), &mask) == 0) { + for (int i = 0; i < CPU_SETSIZE; i++) { + if (CPU_ISSET(i, &mask)) + nproc++; + } + return nproc; + } +#endif + +#if defined(darwin_HOST_OS) size_t size = sizeof(uint32_t); - if(sysctlbyname("hw.logicalcpu",&nproc,&size,NULL,0) != 0) { + if (sysctlbyname("machdep.cpu.thread_count",&nproc,&size,NULL,0) != 0) { + if (sysctlbyname("hw.logicalcpu",&nproc,&size,NULL,0) != 0) { + if (sysctlbyname("hw.ncpu",&nproc,&size,NULL,0) != 0) + nproc = 1; + } + } +#elif defined(freebsd_HOST_OS) + cpuset_t mask; + CPU_ZERO(&mask); + if(cpuset_getaffinity(CPU_LEVEL_CPUSET, CPU_WHICH_PID, -1, sizeof(mask), &mask) == 0) { + return CPU_COUNT(&mask); + } else { + size_t size = sizeof(uint32_t); if(sysctlbyname("hw.ncpu",&nproc,&size,NULL,0) != 0) nproc = 1; } -#elif defined(freebsd_HOST_OS) - size_t size = sizeof(uint32_t); - if(sysctlbyname("hw.ncpu",&nproc,&size,NULL,0) != 0) - nproc = 1; +#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN) + // N.B. This is the number of physical processors. + nproc = sysconf(_SC_NPROCESSORS_ONLN); +#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_CONF) + // N.B. This is the number of physical processors. + nproc = sysconf(_SC_NPROCESSORS_CONF); #else nproc = 1; #endif ===================================== rts/win32/OSThreads.c ===================================== @@ -252,17 +252,6 @@ forkOS_createThread ( HsStablePtr entry ) (unsigned*)&pId) == 0); } -#if defined(x86_64_HOST_ARCH) -/* We still support Windows Vista, so we can't depend on it - and must manually resolve these. */ -typedef DWORD(WINAPI *GetItemCountProc)(WORD); -typedef DWORD(WINAPI *GetGroupCountProc)(void); -typedef BOOL(WINAPI *SetThreadGroupAffinityProc)(HANDLE, const GROUP_AFFINITY*, PGROUP_AFFINITY); -#if !defined(ALL_PROCESSOR_GROUPS) -#define ALL_PROCESSOR_GROUPS 0xffff -#endif -#endif - void freeThreadingResources (void) { if (cpuGroupCache) @@ -310,13 +299,6 @@ getNumberOfProcessorsGroups (void) #if defined(x86_64_HOST_ARCH) if (!n_groups) { - /* We still support Windows Vista. Which means we can't rely - on the API being available. So we'll have to resolve manually. */ - HMODULE kernel = GetModuleHandleW(L"kernel32"); - - GetGroupCountProc GetActiveProcessorGroupCount - = (GetGroupCountProc)(void*) - GetProcAddress(kernel, "GetActiveProcessorGroupCount"); n_groups = GetActiveProcessorGroupCount(); IF_DEBUG(scheduler, debugBelch("[*] Number of processor groups detected: %u\n", n_groups)); @@ -346,21 +328,10 @@ getProcessorsDistribution (void) cpuGroupDistCache = malloc(n_groups * sizeof(uint8_t)); memset(cpuGroupDistCache, MAXIMUM_PROCESSORS, n_groups * sizeof(uint8_t)); - /* We still support Windows Vista. Which means we can't rely - on the API being available. So we'll have to resolve manually. */ - HMODULE kernel = GetModuleHandleW(L"kernel32"); - - GetItemCountProc GetActiveProcessorCount - = (GetItemCountProc)(void*) - GetProcAddress(kernel, "GetActiveProcessorCount"); - - if (GetActiveProcessorCount) + for (int i = 0; i < n_groups; i++) { - for (int i = 0; i < n_groups; i++) - { - cpuGroupDistCache[i] = GetActiveProcessorCount(i); - IF_DEBUG(scheduler, debugBelch("[*] Number of active processors in group %u detected: %u\n", i, cpuGroupDistCache[i])); - } + cpuGroupDistCache[i] = GetActiveProcessorCount(i); + IF_DEBUG(scheduler, debugBelch("[*] Number of active processors in group %u detected: %u\n", i, cpuGroupDistCache[i])); } } @@ -449,14 +420,7 @@ getNumberOfProcessors (void) static uint32_t nproc = 0; #if defined(x86_64_HOST_ARCH) - /* We still support Windows Vista. Which means we can't rely - on the API being available. So we'll have to resolve manually. */ - HMODULE kernel = GetModuleHandleW(L"kernel32"); - - GetItemCountProc GetActiveProcessorCount - = (GetItemCountProc)(void*) - GetProcAddress(kernel, "GetActiveProcessorCount"); - if (GetActiveProcessorCount && !nproc) + if (!nproc) { nproc = GetActiveProcessorCount(ALL_PROCESSOR_GROUPS); @@ -517,21 +481,11 @@ setThreadAffinity (uint32_t n, uint32_t m) // cap N of M mask[group] |= 1 << ix; } -#if defined(x86_64_HOST_ARCH) - /* We still support Windows Vista. Which means we can't rely - on the API being available. So we'll have to resolve manually. */ - HMODULE kernel = GetModuleHandleW(L"kernel32"); - - SetThreadGroupAffinityProc SetThreadGroupAffinity - = (SetThreadGroupAffinityProc)(void*) - GetProcAddress(kernel, "SetThreadGroupAffinity"); -#endif - for (i = 0; i < n_groups; i++) { #if defined(x86_64_HOST_ARCH) // If we support the new API, use it. - if (mask[i] > 0 && SetThreadGroupAffinity) + if (mask[i] > 0) { GROUP_AFFINITY hGroup; ZeroMemory(&hGroup, sizeof(hGroup)); ===================================== testsuite/tests/driver/T16167.hs ===================================== @@ -0,0 +1 @@ +module f ===================================== testsuite/tests/driver/T16167.stdout ===================================== @@ -0,0 +1 @@ +{"span": {"file": "T16167.hs","startLine": 1,"startCol": 8,"endLine": 1,"endCol": 9},"doc": "parse error on input \u2018f\u2019","severity": "SevError","reason": null} ===================================== testsuite/tests/driver/all.T ===================================== @@ -261,6 +261,8 @@ test('T12955', normal, makefile_test, []) test('T12971', [when(opsys('mingw32'), expect_broken(17945)), ignore_stdout], makefile_test, []) test('json', normal, compile_fail, ['-ddump-json']) test('json2', normalise_version('base','ghc-prim'), compile, ['-ddump-types -ddump-json']) +test('T16167', exit_code(1), run_command, + ['{compiler} -x hs -e ":set prog T16167.hs" -ddump-json T16167.hs']) test('T13604', [], makefile_test, []) test('T13604a', [], makefile_test, []) # omitting hpc and profasm because they affect the View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8332ea70d330e8eb9a085337229f8454ea411e1c...ce8bca8d5388bfb92e6765d3703c20e62d37781c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8332ea70d330e8eb9a085337229f8454ea411e1c...ce8bca8d5388bfb92e6765d3703c20e62d37781c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 10 18:41:56 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 10 May 2020 14:41:56 -0400 Subject: [Git][ghc/ghc][wip/lower-tc-tracing-cost] Avoid unnecessary allocations due to tracing utilities Message-ID: <5eb84af4e7d96_61673f819aad978c1011077a@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/lower-tc-tracing-cost at Glasgow Haskell Compiler / GHC Commits: fd41f8cd by Ben Gamari at 2020-05-10T14:41:13-04:00 Avoid unnecessary allocations due to tracing utilities While ticky-profiling the typechecker I noticed that hundreds of millions of SDocs are being allocated just in case -ddump-*-trace is enabled. This is awful. We avoid this by ensuring that the dump flag check is inlined into the call site, ensuring that the tracing document needn't be allocated unless it's actually needed. See Note [INLINE conditional tracing utilities] for details. Fixes #18168. - - - - - 7 changed files: - compiler/GHC/Core/Opt/Simplify/Monad.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/Tc/Solver/Flatten.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Utils/Error.hs Changes: ===================================== compiler/GHC/Core/Opt/Simplify/Monad.hs ===================================== @@ -143,6 +143,7 @@ traceSmpl herald doc ; liftIO $ Err.dumpIfSet_dyn dflags Opt_D_dump_simpl_trace "Simpl Trace" FormatText (hang (text herald) 2 doc) } +{-# INLINE traceSmpl #-} -- see Note [INLINE conditional tracing utilities] {- ************************************************************************ ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -1280,6 +1280,9 @@ callSiteInline dflags id active_unfolding lone_variable arg_infos cont_info -- | Report the inlining of an identifier's RHS to the user, if requested. traceInline :: DynFlags -> Id -> String -> SDoc -> a -> a traceInline dflags inline_id str doc result = + -- We take care to ensure that doc is used in only one branch, ensuring that + -- the simplifier can push its allocation into the branch. See Note [INLINE + -- conditional tracing utilities]. | enable = traceAction dflags str doc result | otherwise = result where @@ -1288,6 +1291,7 @@ traceInline dflags inline_id str doc result = = True | Just prefix <- inlineCheck dflags = prefix `isPrefixOf` occNameString (getOccName inline_id) +{-# INLINE traceInline #-} -- see Note [INLINE conditional tracing utilities] tryUnfolding :: DynFlags -> Id -> Bool -> [ArgSummary] -> CallCtxt -> CoreExpr -> Bool -> Bool -> UnfoldingGuidance ===================================== compiler/GHC/HsToCore/PmCheck/Oracle.hs ===================================== @@ -89,6 +89,7 @@ tracePm herald doc = do printer <- mkPrintUnqualifiedDs liftIO $ dumpIfSet_dyn_printer printer dflags Opt_D_dump_ec_trace "" FormatText (text herald $$ (nest 2 doc)) +{-# INLINE tracePm #-} -- see Note [INLINE conditional tracing utilities] -- | Generate a fresh `Id` of a given type mkPmId :: Type -> DsM Id ===================================== compiler/GHC/Tc/Solver/Flatten.hs ===================================== @@ -543,6 +543,7 @@ runFlatten mode loc flav eq_rel thing_inside traceFlat :: String -> SDoc -> FlatM () traceFlat herald doc = liftTcS $ traceTcS herald doc +{-# INLINE traceFlat #-} -- see Note [INLINE conditional tracing utilities] getFlatEnvField :: (FlattenEnv -> a) -> FlatM a getFlatEnvField accessor ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -2733,6 +2733,7 @@ panicTcS doc = pprPanic "GHC.Tc.Solver.Canonical" doc traceTcS :: String -> SDoc -> TcS () traceTcS herald doc = wrapTcS (TcM.traceTc herald doc) +{-# INLINE traceTcS #-} -- see Note [INLINE conditional tracing utilities] runTcPluginTcS :: TcPluginM a -> TcS a runTcPluginTcS m = wrapTcS . runTcPluginM m =<< getTcEvBindsVar @@ -2751,6 +2752,7 @@ bumpStepCountTcS = TcS $ \env -> do { let ref = tcs_count env csTraceTcS :: SDoc -> TcS () csTraceTcS doc = wrapTcS $ csTraceTcM (return doc) +{-# INLINE csTraceTcS #-} -- see Note [INLINE conditional tracing utilities] traceFireTcS :: CtEvidence -> SDoc -> TcS () -- Dump a rule-firing trace @@ -2763,6 +2765,7 @@ traceFireTcS ev doc text "d:" <> ppr (ctLocDepth (ctEvLoc ev))) <+> doc <> colon) 4 (ppr ev)) } +{-# INLINE traceFireTcS #-} -- see Note [INLINE conditional tracing utilities] csTraceTcM :: TcM SDoc -> TcM () -- Constraint-solver tracing, -ddump-cs-trace @@ -2775,6 +2778,7 @@ csTraceTcM mk_doc (dumpOptionsFromFlag Opt_D_dump_cs_trace) "" FormatText msg }) } +{-# INLINE csTraceTcM #-} -- see Note [INLINE conditional tracing utilities] runTcS :: TcS a -- What to run -> TcM (a, EvBindMap) ===================================== compiler/GHC/Tc/Utils/Monad.hs ===================================== @@ -490,22 +490,28 @@ unsetWOptM flag = whenDOptM :: DumpFlag -> TcRnIf gbl lcl () -> TcRnIf gbl lcl () whenDOptM flag thing_inside = do b <- doptM flag when b thing_inside +{-# INLINE whenDOptM #-} -- see Note [INLINE conditional tracing utilities] + whenGOptM :: GeneralFlag -> TcRnIf gbl lcl () -> TcRnIf gbl lcl () whenGOptM flag thing_inside = do b <- goptM flag when b thing_inside +{-# INLINE whenGOptM #-} -- see Note [INLINE conditional tracing utilities] whenWOptM :: WarningFlag -> TcRnIf gbl lcl () -> TcRnIf gbl lcl () whenWOptM flag thing_inside = do b <- woptM flag when b thing_inside +{-# INLINE whenWOptM #-} -- see Note [INLINE conditional tracing utilities] whenXOptM :: LangExt.Extension -> TcRnIf gbl lcl () -> TcRnIf gbl lcl () whenXOptM flag thing_inside = do b <- xoptM flag when b thing_inside +{-# INLINE whenXOptM #-} -- see Note [INLINE conditional tracing utilities] unlessXOptM :: LangExt.Extension -> TcRnIf gbl lcl () -> TcRnIf gbl lcl () unlessXOptM flag thing_inside = do b <- xoptM flag unless b thing_inside +{-# INLINE unlessXOptM #-} -- see Note [INLINE conditional tracing utilities] getGhcMode :: TcRnIf gbl lcl GhcMode getGhcMode = do { env <- getTopEnv; return (ghcMode (hsc_dflags env)) } @@ -662,39 +668,64 @@ updTcRef ref fn = liftIO $ do { old <- readIORef ref ************************************************************************ -} +-- Note [INLINE conditional tracing utilities] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- In general we want to optimise for the case where tracing is not enabled. +-- To ensure this happens, we ensure that traceTc and friends are inlined; this +-- ensures that the allocation of the document can be pushed into the tracing +-- path, keeping the non-traced path free of this extraneous work. For +-- instance, instead of +-- +-- let thunk = ... +-- in if doTracing +-- then emitTraceMsg thunk +-- else return () +-- +-- where the conditional is buried in a non-inlined utility function (e.g. +-- traceTc), we would rather have: +-- +-- if doTracing +-- then let thunk = ... +-- in emitTraceMsg thunk +-- else return () +-- +-- See #18168. +-- -- Typechecker trace traceTc :: String -> SDoc -> TcRn () -traceTc = - labelledTraceOptTcRn Opt_D_dump_tc_trace +traceTc herald doc = + labelledTraceOptTcRn Opt_D_dump_tc_trace herald doc +{-# INLINE traceTc #-} -- see Note [INLINE conditional tracing utilities] -- Renamer Trace traceRn :: String -> SDoc -> TcRn () -traceRn = - labelledTraceOptTcRn Opt_D_dump_rn_trace +traceRn herald doc = + labelledTraceOptTcRn Opt_D_dump_rn_trace herald doc +{-# INLINE traceRn #-} -- see Note [INLINE conditional tracing utilities] -- | Trace when a certain flag is enabled. This is like `traceOptTcRn` -- but accepts a string as a label and formats the trace message uniformly. labelledTraceOptTcRn :: DumpFlag -> String -> SDoc -> TcRn () -labelledTraceOptTcRn flag herald doc = do - traceOptTcRn flag (formatTraceMsg herald doc) +labelledTraceOptTcRn flag herald doc = + traceOptTcRn flag (formatTraceMsg herald doc) +{-# INLINE labelledTraceOptTcRn #-} -- see Note [INLINE conditional tracing utilities] formatTraceMsg :: String -> SDoc -> SDoc formatTraceMsg herald doc = hang (text herald) 2 doc --- | Trace if the given 'DumpFlag' is set. traceOptTcRn :: DumpFlag -> SDoc -> TcRn () traceOptTcRn flag doc = do - dflags <- getDynFlags - when (dopt flag dflags) $ + whenDOptM flag $ dumpTcRn False (dumpOptionsFromFlag flag) "" FormatText doc +{-# INLINE traceOptTcRn #-} -- see Note [INLINE conditional tracing utilities] -- | Dump if the given 'DumpFlag' is set. dumpOptTcRn :: DumpFlag -> String -> DumpFormat -> SDoc -> TcRn () dumpOptTcRn flag title fmt doc = do - dflags <- getDynFlags - when (dopt flag dflags) $ + whenDOptM flag $ dumpTcRn False (dumpOptionsFromFlag flag) title fmt doc +{-# INLINE dumpOptTcRn #-} -- see Note [INLINE conditional tracing utilities] -- | Unconditionally dump some trace output -- @@ -746,13 +777,16 @@ e.g. are unaffected by -dump-to-file. traceIf, traceHiDiffs :: SDoc -> TcRnIf m n () traceIf = traceOptIf Opt_D_dump_if_trace traceHiDiffs = traceOptIf Opt_D_dump_hi_diffs - +{-# INLINE traceIf #-} +{-# INLINE traceHiDiffs #-} + -- see Note [INLINE conditional tracing utilities] traceOptIf :: DumpFlag -> SDoc -> TcRnIf m n () traceOptIf flag doc = whenDOptM flag $ -- No RdrEnv available, so qualify everything do { dflags <- getDynFlags ; liftIO (putMsg dflags doc) } +{-# INLINE traceOptIf #-} -- see Note [INLINE conditional tracing utilities] {- ************************************************************************ ===================================== compiler/GHC/Utils/Error.hs ===================================== @@ -438,20 +438,27 @@ doIfSet_dyn dflags flag action | gopt flag dflags = action dumpIfSet :: DynFlags -> Bool -> String -> SDoc -> IO () dumpIfSet dflags flag hdr doc | not flag = return () - | otherwise = putLogMsg dflags - NoReason - SevDump - noSrcSpan - (withPprStyle defaultDumpStyle - (mkDumpDoc hdr doc)) - --- | a wrapper around 'dumpAction'. + | otherwise = doDump dflags flag hdr doc + where + -- Explicitly bind this so we don't duplicate this code needlessly due to + -- the INLINE below. + doDump dflags flag hdr doc = + putLogMsg dflags + NoReason + SevDump + noSrcSpan + (withPprStyle defaultDumpStyle + (mkDumpDoc hdr doc)) +{-# INLINE dumpIfSet #-} -- see Note [INLINE conditional tracing utilities] + +-- | A wrapper around 'dumpAction'. -- First check whether the dump flag is set -- Do nothing if it is unset dumpIfSet_dyn :: DynFlags -> DumpFlag -> String -> DumpFormat -> SDoc -> IO () dumpIfSet_dyn = dumpIfSet_dyn_printer alwaysQualify +{-# INLINE dumpIfSet_dyn #-} -- see Note [INLINE conditional tracing utilities] --- | a wrapper around 'dumpAction'. +-- | A wrapper around 'dumpAction'. -- First check whether the dump flag is set -- Do nothing if it is unset -- @@ -462,6 +469,7 @@ dumpIfSet_dyn_printer printer dflags flag hdr fmt doc = when (dopt flag dflags) $ do let sty = mkDumpStyle printer dumpAction dflags sty (dumpOptionsFromFlag flag) hdr fmt doc +{-# INLINE dumpIfSet_dyn_printer #-} -- see Note [INLINE conditional tracing utilities] mkDumpDoc :: String -> SDoc -> SDoc mkDumpDoc hdr doc @@ -608,6 +616,7 @@ ifVerbose :: DynFlags -> Int -> IO () -> IO () ifVerbose dflags val act | verbosity dflags >= val = act | otherwise = return () +{-# INLINE ifVerbose #-} -- see Note [INLINE conditional tracing utilities] errorMsg :: DynFlags -> MsgDoc -> IO () errorMsg dflags msg @@ -778,6 +787,7 @@ debugTraceMsg :: DynFlags -> Int -> MsgDoc -> IO () debugTraceMsg dflags val msg = ifVerbose dflags val $ logInfo dflags (withPprStyle defaultDumpStyle msg) +{-# INLINE debugTraceMsg #-} -- see Note [INLINE conditional tracing utilities] putMsg :: DynFlags -> MsgDoc -> IO () putMsg dflags msg = logInfo dflags (withPprStyle defaultUserStyle msg) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fd41f8cd3c64c2c59c27db0241128033d82a47ec -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fd41f8cd3c64c2c59c27db0241128033d82a47ec You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 10 18:44:56 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 10 May 2020 14:44:56 -0400 Subject: [Git][ghc/ghc][wip/lower-tc-tracing-cost] Avoid unnecessary allocations due to tracing utilities Message-ID: <5eb84ba8bbbcc_6167119ebbd01011145e@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/lower-tc-tracing-cost at Glasgow Haskell Compiler / GHC Commits: 5b0f50a8 by Ben Gamari at 2020-05-10T14:43:40-04:00 Avoid unnecessary allocations due to tracing utilities While ticky-profiling the typechecker I noticed that hundreds of millions of SDocs are being allocated just in case -ddump-*-trace is enabled. This is awful. We avoid this by ensuring that the dump flag check is inlined into the call site, ensuring that the tracing document needn't be allocated unless it's actually needed. See Note [INLINE conditional tracing utilities] for details. Fixes #18168. - - - - - 7 changed files: - compiler/GHC/Core/Opt/Simplify/Monad.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/Tc/Solver/Flatten.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Utils/Error.hs Changes: ===================================== compiler/GHC/Core/Opt/Simplify/Monad.hs ===================================== @@ -143,6 +143,7 @@ traceSmpl herald doc ; liftIO $ Err.dumpIfSet_dyn dflags Opt_D_dump_simpl_trace "Simpl Trace" FormatText (hang (text herald) 2 doc) } +{-# INLINE traceSmpl #-} -- see Note [INLINE conditional tracing utilities] {- ************************************************************************ ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -1279,7 +1279,10 @@ callSiteInline dflags id active_unfolding lone_variable arg_infos cont_info -- | Report the inlining of an identifier's RHS to the user, if requested. traceInline :: DynFlags -> Id -> String -> SDoc -> a -> a -traceInline dflags inline_id str doc result = +traceInline dflags inline_id str doc result + -- We take care to ensure that doc is used in only one branch, ensuring that + -- the simplifier can push its allocation into the branch. See Note [INLINE + -- conditional tracing utilities]. | enable = traceAction dflags str doc result | otherwise = result where @@ -1288,6 +1291,9 @@ traceInline dflags inline_id str doc result = = True | Just prefix <- inlineCheck dflags = prefix `isPrefixOf` occNameString (getOccName inline_id) + | otherwise + = False +{-# INLINE traceInline #-} -- see Note [INLINE conditional tracing utilities] tryUnfolding :: DynFlags -> Id -> Bool -> [ArgSummary] -> CallCtxt -> CoreExpr -> Bool -> Bool -> UnfoldingGuidance ===================================== compiler/GHC/HsToCore/PmCheck/Oracle.hs ===================================== @@ -89,6 +89,7 @@ tracePm herald doc = do printer <- mkPrintUnqualifiedDs liftIO $ dumpIfSet_dyn_printer printer dflags Opt_D_dump_ec_trace "" FormatText (text herald $$ (nest 2 doc)) +{-# INLINE tracePm #-} -- see Note [INLINE conditional tracing utilities] -- | Generate a fresh `Id` of a given type mkPmId :: Type -> DsM Id ===================================== compiler/GHC/Tc/Solver/Flatten.hs ===================================== @@ -543,6 +543,7 @@ runFlatten mode loc flav eq_rel thing_inside traceFlat :: String -> SDoc -> FlatM () traceFlat herald doc = liftTcS $ traceTcS herald doc +{-# INLINE traceFlat #-} -- see Note [INLINE conditional tracing utilities] getFlatEnvField :: (FlattenEnv -> a) -> FlatM a getFlatEnvField accessor ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -2733,6 +2733,7 @@ panicTcS doc = pprPanic "GHC.Tc.Solver.Canonical" doc traceTcS :: String -> SDoc -> TcS () traceTcS herald doc = wrapTcS (TcM.traceTc herald doc) +{-# INLINE traceTcS #-} -- see Note [INLINE conditional tracing utilities] runTcPluginTcS :: TcPluginM a -> TcS a runTcPluginTcS m = wrapTcS . runTcPluginM m =<< getTcEvBindsVar @@ -2751,6 +2752,7 @@ bumpStepCountTcS = TcS $ \env -> do { let ref = tcs_count env csTraceTcS :: SDoc -> TcS () csTraceTcS doc = wrapTcS $ csTraceTcM (return doc) +{-# INLINE csTraceTcS #-} -- see Note [INLINE conditional tracing utilities] traceFireTcS :: CtEvidence -> SDoc -> TcS () -- Dump a rule-firing trace @@ -2763,6 +2765,7 @@ traceFireTcS ev doc text "d:" <> ppr (ctLocDepth (ctEvLoc ev))) <+> doc <> colon) 4 (ppr ev)) } +{-# INLINE traceFireTcS #-} -- see Note [INLINE conditional tracing utilities] csTraceTcM :: TcM SDoc -> TcM () -- Constraint-solver tracing, -ddump-cs-trace @@ -2775,6 +2778,7 @@ csTraceTcM mk_doc (dumpOptionsFromFlag Opt_D_dump_cs_trace) "" FormatText msg }) } +{-# INLINE csTraceTcM #-} -- see Note [INLINE conditional tracing utilities] runTcS :: TcS a -- What to run -> TcM (a, EvBindMap) ===================================== compiler/GHC/Tc/Utils/Monad.hs ===================================== @@ -490,22 +490,28 @@ unsetWOptM flag = whenDOptM :: DumpFlag -> TcRnIf gbl lcl () -> TcRnIf gbl lcl () whenDOptM flag thing_inside = do b <- doptM flag when b thing_inside +{-# INLINE whenDOptM #-} -- see Note [INLINE conditional tracing utilities] + whenGOptM :: GeneralFlag -> TcRnIf gbl lcl () -> TcRnIf gbl lcl () whenGOptM flag thing_inside = do b <- goptM flag when b thing_inside +{-# INLINE whenGOptM #-} -- see Note [INLINE conditional tracing utilities] whenWOptM :: WarningFlag -> TcRnIf gbl lcl () -> TcRnIf gbl lcl () whenWOptM flag thing_inside = do b <- woptM flag when b thing_inside +{-# INLINE whenWOptM #-} -- see Note [INLINE conditional tracing utilities] whenXOptM :: LangExt.Extension -> TcRnIf gbl lcl () -> TcRnIf gbl lcl () whenXOptM flag thing_inside = do b <- xoptM flag when b thing_inside +{-# INLINE whenXOptM #-} -- see Note [INLINE conditional tracing utilities] unlessXOptM :: LangExt.Extension -> TcRnIf gbl lcl () -> TcRnIf gbl lcl () unlessXOptM flag thing_inside = do b <- xoptM flag unless b thing_inside +{-# INLINE unlessXOptM #-} -- see Note [INLINE conditional tracing utilities] getGhcMode :: TcRnIf gbl lcl GhcMode getGhcMode = do { env <- getTopEnv; return (ghcMode (hsc_dflags env)) } @@ -662,39 +668,64 @@ updTcRef ref fn = liftIO $ do { old <- readIORef ref ************************************************************************ -} +-- Note [INLINE conditional tracing utilities] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- In general we want to optimise for the case where tracing is not enabled. +-- To ensure this happens, we ensure that traceTc and friends are inlined; this +-- ensures that the allocation of the document can be pushed into the tracing +-- path, keeping the non-traced path free of this extraneous work. For +-- instance, instead of +-- +-- let thunk = ... +-- in if doTracing +-- then emitTraceMsg thunk +-- else return () +-- +-- where the conditional is buried in a non-inlined utility function (e.g. +-- traceTc), we would rather have: +-- +-- if doTracing +-- then let thunk = ... +-- in emitTraceMsg thunk +-- else return () +-- +-- See #18168. +-- -- Typechecker trace traceTc :: String -> SDoc -> TcRn () -traceTc = - labelledTraceOptTcRn Opt_D_dump_tc_trace +traceTc herald doc = + labelledTraceOptTcRn Opt_D_dump_tc_trace herald doc +{-# INLINE traceTc #-} -- see Note [INLINE conditional tracing utilities] -- Renamer Trace traceRn :: String -> SDoc -> TcRn () -traceRn = - labelledTraceOptTcRn Opt_D_dump_rn_trace +traceRn herald doc = + labelledTraceOptTcRn Opt_D_dump_rn_trace herald doc +{-# INLINE traceRn #-} -- see Note [INLINE conditional tracing utilities] -- | Trace when a certain flag is enabled. This is like `traceOptTcRn` -- but accepts a string as a label and formats the trace message uniformly. labelledTraceOptTcRn :: DumpFlag -> String -> SDoc -> TcRn () -labelledTraceOptTcRn flag herald doc = do - traceOptTcRn flag (formatTraceMsg herald doc) +labelledTraceOptTcRn flag herald doc = + traceOptTcRn flag (formatTraceMsg herald doc) +{-# INLINE labelledTraceOptTcRn #-} -- see Note [INLINE conditional tracing utilities] formatTraceMsg :: String -> SDoc -> SDoc formatTraceMsg herald doc = hang (text herald) 2 doc --- | Trace if the given 'DumpFlag' is set. traceOptTcRn :: DumpFlag -> SDoc -> TcRn () traceOptTcRn flag doc = do - dflags <- getDynFlags - when (dopt flag dflags) $ + whenDOptM flag $ dumpTcRn False (dumpOptionsFromFlag flag) "" FormatText doc +{-# INLINE traceOptTcRn #-} -- see Note [INLINE conditional tracing utilities] -- | Dump if the given 'DumpFlag' is set. dumpOptTcRn :: DumpFlag -> String -> DumpFormat -> SDoc -> TcRn () dumpOptTcRn flag title fmt doc = do - dflags <- getDynFlags - when (dopt flag dflags) $ + whenDOptM flag $ dumpTcRn False (dumpOptionsFromFlag flag) title fmt doc +{-# INLINE dumpOptTcRn #-} -- see Note [INLINE conditional tracing utilities] -- | Unconditionally dump some trace output -- @@ -746,13 +777,16 @@ e.g. are unaffected by -dump-to-file. traceIf, traceHiDiffs :: SDoc -> TcRnIf m n () traceIf = traceOptIf Opt_D_dump_if_trace traceHiDiffs = traceOptIf Opt_D_dump_hi_diffs - +{-# INLINE traceIf #-} +{-# INLINE traceHiDiffs #-} + -- see Note [INLINE conditional tracing utilities] traceOptIf :: DumpFlag -> SDoc -> TcRnIf m n () traceOptIf flag doc = whenDOptM flag $ -- No RdrEnv available, so qualify everything do { dflags <- getDynFlags ; liftIO (putMsg dflags doc) } +{-# INLINE traceOptIf #-} -- see Note [INLINE conditional tracing utilities] {- ************************************************************************ ===================================== compiler/GHC/Utils/Error.hs ===================================== @@ -438,20 +438,27 @@ doIfSet_dyn dflags flag action | gopt flag dflags = action dumpIfSet :: DynFlags -> Bool -> String -> SDoc -> IO () dumpIfSet dflags flag hdr doc | not flag = return () - | otherwise = putLogMsg dflags - NoReason - SevDump - noSrcSpan - (withPprStyle defaultDumpStyle - (mkDumpDoc hdr doc)) - --- | a wrapper around 'dumpAction'. + | otherwise = doDump dflags flag hdr doc + where + -- Explicitly bind this so we don't duplicate this code needlessly due to + -- the INLINE below. + doDump dflags flag hdr doc = + putLogMsg dflags + NoReason + SevDump + noSrcSpan + (withPprStyle defaultDumpStyle + (mkDumpDoc hdr doc)) +{-# INLINE dumpIfSet #-} -- see Note [INLINE conditional tracing utilities] + +-- | A wrapper around 'dumpAction'. -- First check whether the dump flag is set -- Do nothing if it is unset dumpIfSet_dyn :: DynFlags -> DumpFlag -> String -> DumpFormat -> SDoc -> IO () dumpIfSet_dyn = dumpIfSet_dyn_printer alwaysQualify +{-# INLINE dumpIfSet_dyn #-} -- see Note [INLINE conditional tracing utilities] --- | a wrapper around 'dumpAction'. +-- | A wrapper around 'dumpAction'. -- First check whether the dump flag is set -- Do nothing if it is unset -- @@ -462,6 +469,7 @@ dumpIfSet_dyn_printer printer dflags flag hdr fmt doc = when (dopt flag dflags) $ do let sty = mkDumpStyle printer dumpAction dflags sty (dumpOptionsFromFlag flag) hdr fmt doc +{-# INLINE dumpIfSet_dyn_printer #-} -- see Note [INLINE conditional tracing utilities] mkDumpDoc :: String -> SDoc -> SDoc mkDumpDoc hdr doc @@ -608,6 +616,7 @@ ifVerbose :: DynFlags -> Int -> IO () -> IO () ifVerbose dflags val act | verbosity dflags >= val = act | otherwise = return () +{-# INLINE ifVerbose #-} -- see Note [INLINE conditional tracing utilities] errorMsg :: DynFlags -> MsgDoc -> IO () errorMsg dflags msg @@ -778,6 +787,7 @@ debugTraceMsg :: DynFlags -> Int -> MsgDoc -> IO () debugTraceMsg dflags val msg = ifVerbose dflags val $ logInfo dflags (withPprStyle defaultDumpStyle msg) +{-# INLINE debugTraceMsg #-} -- see Note [INLINE conditional tracing utilities] putMsg :: DynFlags -> MsgDoc -> IO () putMsg dflags msg = logInfo dflags (withPprStyle defaultUserStyle msg) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5b0f50a8926cf7f5774685ca405a8b597a2f9d9a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5b0f50a8926cf7f5774685ca405a8b597a2f9d9a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 10 19:01:43 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 10 May 2020 15:01:43 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 21 commits: rts/CNF: Fix fixup comparison function Message-ID: <5eb84f97743db_616712a9b7f010114728@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: fa2252df by Ben Gamari at 2020-05-10T15:00:37-04:00 rts/CNF: Fix fixup comparison function Previously we would implicitly convert the difference between two words to an int, resulting in an integer overflow on 64-bit machines. Fixes #16992 - - - - - ac3d1104 by Simon Peyton Jones at 2020-05-10T15:00:38-04:00 Avoid useless w/w split This patch is just a tidy-up for the post-strictness-analysis worker wrapper split. Consider f x = x Strictnesss analysis does not lead to a w/w split, so the obvious thing is to leave it 100% alone. But actually, because the RHS is small, we ended up adding a StableUnfolding for it. There is some reason to do this if we choose /not/ do to w/w on the grounds that the function is small. See Note [Don't w/w inline small non-loop-breaker things] But there is no reason if we would not have done w/w anyway. This patch just moves the conditional to later. Easy. This does move soem -ddump-simpl printouts around a bit. I also discovered that the previous code was overwritten an InlineCompulsory with InlineStable, which is utterly wrong. That in turn meant that some default methods (marked InlineCompulsory) were getting their InlineCompulsory squashed. This patch fixes that bug --- but of course that does mean a bit more inlining! Metric Decrease: T9233 T9675 Metric Increase: T12707 T3064 T4029 T9872b T9872d haddock.Cabal - - - - - f399a94c by Ben Gamari at 2020-05-10T15:00:39-04:00 get-win32-tarballs: Fix base URL Revert a change previously made for testing purposes. - - - - - e9e6db8f by Ben Gamari at 2020-05-10T15:00:39-04:00 get-win32-tarballs: Improve diagnostics output - - - - - 7c9a3bfa by Simon Jakobi at 2020-05-10T15:00:40-04:00 docs: Add examples for Data.Semigroup.Arg{Min,Max} Context: #17153 - - - - - d5c5f8fe by Simon Jakobi at 2020-05-10T15:00:41-04:00 Improve some folds over Uniq[D]FM * Replace some non-deterministic lazy folds with strict folds. * Replace some O(n log n) folds in deterministic order with O(n) non-deterministic folds. * Replace some folds with set-operations on the underlying IntMaps. This reduces max residency when compiling `nofib/spectral/simple/Main.hs` with -O0 by about 1%. Maximum residency when compiling Cabal also seems reduced on the order of 3-9%. - - - - - 926f926d by Simon Jakobi at 2020-05-10T15:00:41-04:00 Use Data.IntMap.disjoint Data.IntMap gained a dedicated `disjoint` function in containers-0.6.2.1. This patch applies this function where appropriate in hopes of modest compiler performance improvements. Closes #16806. - - - - - 2a5c34fd by Baldur Blöndal at 2020-05-10T15:00:44-04:00 Predicate, Equivalence derive via `.. -> a -> All' - - - - - 38521427 by Emeka Nkurumeh at 2020-05-10T15:00:47-04:00 fix printf warning when using with ghc with clang on mingw - - - - - 010ae077 by Daniel Gröber at 2020-05-10T15:01:00-04:00 Fix non power-of-two Storable.alignment in Capi_Ctype tests Alignments passed to alloca and friends must be a power of two for the code in allocatePinned to work properly. Commit 41230e2601 ("Zero out pinned block alignment slop when profiling") introduced an ASSERT for this but this test was still violating it. - - - - - 3cd80d06 by Daniel Gröber at 2020-05-10T15:01:00-04:00 Improve ByteArray# documentation regarding alignment - - - - - 79331469 by Daniel Gröber at 2020-05-10T15:01:00-04:00 Document word-size rounding of ByteArray# memory (Fix #14731) - - - - - de9fff04 by Daniel Gröber at 2020-05-10T15:01:00-04:00 Throw IOError when allocaBytesAligned gets non-power-of-two align - - - - - b66630cf by Richard Eisenberg at 2020-05-10T15:01:01-04:00 Improve Note [The flattening story] - - - - - c76d6346 by Artem Pelenitsyn at 2020-05-10T15:01:13-04:00 Don't reload environment files on every setSessionDynFlags Makes `interpretPackageEnv` (which loads envirinment files) a part of `parseDynamicFlags` (parsing command-line arguments, which is typically done once) instead of `setSessionDynFlags` (which is typically called several times). Making several (transitive) calls to `interpretPackageEnv`, as before, caused #18125 #16318, which should be fixed now. - - - - - a328dfb8 by Hécate at 2020-05-10T15:01:16-04:00 fix(documentation): Fix the RST links to GHC.Prim - - - - - 728e1025 by Baldur Blöndal at 2020-05-10T15:01:17-04:00 Document (->) using inferred quantification for its runtime representations. Fixes #18142. - - - - - edbeee42 by Takenobu Tani at 2020-05-10T15:01:19-04:00 Tweak man page for ghc command This commit updates the ghc command's man page as followings: * Enable `man_show_urls` to show URL addresses in the `DESCRIPTION` section of ghc.rst, because sphinx currently removes hyperlinks for man pages. * Add a `SEE ALSO` section to point to the GHC homepage - - - - - 375a28b7 by Takenobu Tani at 2020-05-10T15:01:24-04:00 GHCi: Add link to the user's guide in help message This commit adds a link to the user's guide in ghci's `:help` message. Newcomers could easily reach to details of ghci. - - - - - 77503e24 by Jeff Happily at 2020-05-10T15:01:26-04:00 Handle single unused import - - - - - 7578a90d by Ben Gamari at 2020-05-10T15:01:27-04:00 hadrian: Tell testsuite driver about LLVM availability This reflects the logic present in the Make build system into Hadrian. Fixes #18167. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/Data/Graph/Ops.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Stg/Lift/Analysis.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/Solver/Flatten.hs - compiler/GHC/Tc/TyCl/Build.hs - compiler/GHC/Tc/Types/Evidence.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Name/Env.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f016ecd34bf8bd6c714bc9bfa13d534ea720dd49...7578a90de2e3c2b3c1e81a54618afe0c26a218ee -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f016ecd34bf8bd6c714bc9bfa13d534ea720dd49...7578a90de2e3c2b3c1e81a54618afe0c26a218ee You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 10 19:01:48 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 10 May 2020 15:01:48 -0400 Subject: [Git][ghc/ghc][wip/caf-cleanups] Add few cleanups of the CAF logic Message-ID: <5eb84f9c8b6b0_6167119ebbd010115624@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/caf-cleanups at Glasgow Haskell Compiler / GHC Commits: 0edf15e8 by Ben Gamari at 2020-05-10T15:01:01-04:00 Add few cleanups of the CAF logic Give the NameSet of non-CAFfy names a proper newtype to distinguish it from all of the other NameSets floating about. - - - - - 5 changed files: - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/UpdateCafInfos.hs - compiler/GHC/Types/Name/Set.hs Changes: ===================================== compiler/GHC/Cmm/Info/Build.hs ===================================== @@ -459,7 +459,7 @@ type CAFSet = Set CAFLabel type CAFEnv = LabelMap CAFSet mkCAFLabel :: CLabel -> CAFLabel -mkCAFLabel lbl = CAFLabel $! toClosureLbl lbl +mkCAFLabel lbl = CAFLabel (toClosureLbl lbl) -- This is a label that we can put in an SRT. It *must* be a closure label, -- pointing to either a FUN_STATIC, THUNK_STATIC, or CONSTR. @@ -736,10 +736,11 @@ getStaticFuns decls = type SRTMap = Map CAFLabel (Maybe SRTEntry) --- | Given SRTMap of a module returns the set of non-CAFFY names in the module. --- Any Names not in the set are CAFFY. -srtMapNonCAFs :: SRTMap -> NameSet -srtMapNonCAFs srtMap = mkNameSet (mapMaybe get_name (Map.toList srtMap)) +-- | Given 'SRTMap' of a module, returns the set of non-CAFFY names in the +-- module. Any 'Name's not in the set are CAFFY. +srtMapNonCAFs :: SRTMap -> NonCaffySet +srtMapNonCAFs srtMap = + NonCaffySet $ mkNameSet (mapMaybe get_name (Map.toList srtMap)) where get_name (CAFLabel l, Nothing) = hasHaskellName l get_name (_l, Just _srt_entry) = Nothing ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -1384,7 +1384,7 @@ hscWriteIface dflags iface no_change mod_location = do -- | Compile to hard-code. hscGenHardCode :: HscEnv -> CgGuts -> ModLocation -> FilePath - -> IO (FilePath, Maybe FilePath, [(ForeignSrcLang, FilePath)], NameSet) + -> IO (FilePath, Maybe FilePath, [(ForeignSrcLang, FilePath)], NonCaffySet) -- ^ @Just f@ <=> _stub.c is f hscGenHardCode hsc_env cgguts location output_filename = do let CgGuts{ -- This is the last use of the ModGuts in a compilation. @@ -1541,7 +1541,7 @@ doCodeGen :: HscEnv -> Module -> [TyCon] -> CollectedCCs -> [StgTopBinding] -> HpcInfo - -> IO (Stream IO CmmGroupSRTs NameSet) + -> IO (Stream IO CmmGroupSRTs NonCaffySet) -- Note we produce a 'Stream' of CmmGroups, so that the -- backend can be run incrementally. Otherwise it generates all -- the C-- up front, which has a significant space cost. ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -100,7 +100,7 @@ mkPartialIface hsc_env mod_details -- | Fully instantiate a interface -- Adds fingerprints and potentially code generator produced information. -mkFullIface :: HscEnv -> PartialModIface -> Maybe NameSet -> IO ModIface +mkFullIface :: HscEnv -> PartialModIface -> Maybe NonCaffySet -> IO ModIface mkFullIface hsc_env partial_iface mb_non_cafs = do let decls | gopt Opt_OmitInterfacePragmas (hsc_dflags hsc_env) @@ -117,9 +117,9 @@ mkFullIface hsc_env partial_iface mb_non_cafs = do return full_iface -updateDeclCafInfos :: [IfaceDecl] -> Maybe NameSet -> [IfaceDecl] +updateDeclCafInfos :: [IfaceDecl] -> Maybe NonCaffySet -> [IfaceDecl] updateDeclCafInfos decls Nothing = decls -updateDeclCafInfos decls (Just non_cafs) = map update_decl decls +updateDeclCafInfos decls (Just (NonCaffySet non_cafs)) = map update_decl decls where update_decl decl | IfaceId nm ty details infos <- decl ===================================== compiler/GHC/Iface/UpdateCafInfos.hs ===================================== @@ -23,7 +23,7 @@ import GHC.Utils.Outputable -- | Update CafInfos of all occurences (in rules, unfoldings, class instances) updateModDetailsCafInfos :: DynFlags - -> NameSet -- ^ Non-CAFFY names in the module. Names not in this set are CAFFY. + -> NonCaffySet -- ^ Non-CAFFY names in the module. Names not in this set are CAFFY. -> ModDetails -- ^ ModDetails to update -> ModDetails @@ -31,7 +31,7 @@ updateModDetailsCafInfos dflags _ mod_details | gopt Opt_OmitInterfacePragmas dflags = mod_details -updateModDetailsCafInfos _ non_cafs mod_details = +updateModDetailsCafInfos _ (NonCaffySet non_cafs) mod_details = {- pprTrace "updateModDetailsCafInfos" (text "non_cafs:" <+> ppr non_cafs) $ -} let ModDetails{ md_types = type_env -- for unfoldings ===================================== compiler/GHC/Types/Name/Set.hs ===================================== @@ -4,6 +4,7 @@ -} {-# LANGUAGE CPP #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} module GHC.Types.Name.Set ( -- * Names set type NameSet, @@ -28,7 +29,10 @@ module GHC.Types.Name.Set ( -- ** Manipulating defs and uses emptyDUs, usesOnly, mkDUs, plusDU, - findUses, duDefs, duUses, allUses + findUses, duDefs, duUses, allUses, + + -- * Non-CAFfy names + NonCaffySet(..) ) where #include "HsVersions.h" @@ -213,3 +217,8 @@ findUses dus uses = rhs_uses `unionNameSet` uses | otherwise -- No def is used = uses + +-- | 'Id's which have no CAF references. This is a result of analysis of C--. +-- It is always safe to use an empty 'NonCaffySet'. TODO Refer to Note. +newtype NonCaffySet = NonCaffySet NameSet + deriving (Semigroup, Monoid) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0edf15e8092033c5f74f37308489a49a4e00ce3e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0edf15e8092033c5f74f37308489a49a4e00ce3e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 10 19:02:49 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 10 May 2020 15:02:49 -0400 Subject: [Git][ghc/ghc][wip/T17609] nativeGen: Deduplicate DWARF strings Message-ID: <5eb84fd986bd6_61673f8103f8794c101420f2@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T17609 at Glasgow Haskell Compiler / GHC Commits: 92c7a720 by Ben Gamari at 2020-05-10T12:10:41-04:00 nativeGen: Deduplicate DWARF strings As noted in #17609, we previously made no attempt to deduplicate strings. This resulted in unnecessarily long compile times and large object files. Fix this. Fixes #17609. - - - - - 3 changed files: - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/CmmToAsm/Dwarf/Constants.hs - compiler/GHC/CmmToAsm/Dwarf/Types.hs Changes: ===================================== compiler/GHC/CmmToAsm/Dwarf.hs ===================================== @@ -10,9 +10,10 @@ import Config ( cProjectName, cProjectVersion ) import GHC.Core ( Tickish(..) ) import GHC.Cmm.DebugBlock import GHC.Driver.Session -import GHC.Unit.Module import GHC.Utils.Outputable import GHC.Platform +import GHC.Unit.Module +import GHC.Types.SrcLoc import GHC.Types.Unique import GHC.Types.Unique.Supply @@ -47,11 +48,12 @@ dwarfGen df modLoc us blocks = do compPath <- getCurrentDirectory let lowLabel = dblCLabel $ head procs highLabel = mkAsmTempEndLabel $ dblCLabel $ last procs + producer = dwarfStringFromString $ cProjectName ++ " " ++ cProjectVersion dwarfUnit = DwarfCompileUnit { dwChildren = map (procToDwarf df) (map stripBlocks procs) - , dwName = fromMaybe "" (ml_hs_file modLoc) - , dwCompDir = addTrailingPathSeparator compPath - , dwProducer = cProjectName ++ " " ++ cProjectVersion + , dwName = dwarfStringFromString $ fromMaybe "" (ml_hs_file modLoc) + , dwCompDir = dwarfStringFromString $ addTrailingPathSeparator compPath + , dwProducer = producer , dwLowLabel = lowLabel , dwHighLabel = highLabel , dwLineLabel = dwarfLineLabel @@ -77,6 +79,9 @@ dwarfGen df modLoc us blocks = do , compileUnitFooter unitU ] + -- .debug_str section: Strings + let stringsSct = dwarfStringsSection (dwarfInfoStrings dwarfUnit) + -- .debug_line section: Generated mainly by the assembler, but we -- need to label it let lineSct = dwarfLineSection platform $$ @@ -93,7 +98,7 @@ dwarfGen df modLoc us blocks = do | otherwise = [DwarfARange lowLabel highLabel] let aranges = dwarfARangesSection platform $$ pprDwarfARanges platform aranges' unitU - return (infoSct $$ abbrevSct $$ lineSct $$ frameSct $$ aranges, us'') + return (infoSct $$ stringsSct $$ abbrevSct $$ lineSct $$ frameSct $$ aranges, us'') -- | Build an address range entry for one proc. -- With split sections, each proc needs its own entry, since they may get @@ -178,7 +183,7 @@ parent, B. procToDwarf :: DynFlags -> DebugBlock -> DwarfInfo procToDwarf df prc = DwarfSubprogram { dwChildren = map blockToDwarf (dblBlocks prc) - , dwName = case dblSourceTick prc of + , dwName = dwarfStringFromString $ case dblSourceTick prc of Just s at SourceNote{} -> sourceName s _otherwise -> showSDocDump df $ ppr $ dblLabel prc , dwLabel = dblCLabel prc @@ -209,7 +214,13 @@ blockToDwarf blk | otherwise = Nothing -- block was optimized out tickToDwarf :: Tickish () -> [DwarfInfo] -tickToDwarf (SourceNote ss _) = [DwarfSrcNote ss] +tickToDwarf (SourceNote ss _) = + [DwarfSrcNote { dwSpanFile = dwarfStringFromFastString (srcSpanFile ss) + , dwSpanStartLine = srcSpanStartLine ss + , dwSpanStartCol = srcSpanStartCol ss + , dwSpanEndLine = srcSpanEndLine ss + , dwSpanEndCol = srcSpanEndCol ss + }] tickToDwarf _ = [] -- | Generates the data for the debug frame section, which encodes the ===================================== compiler/GHC/CmmToAsm/Dwarf/Constants.hs ===================================== @@ -86,12 +86,14 @@ dW_CHILDREN_no, dW_CHILDREN_yes :: Word8 dW_CHILDREN_no = 0 dW_CHILDREN_yes = 1 -dW_FORM_addr, dW_FORM_data2, dW_FORM_data4, dW_FORM_string, dW_FORM_flag, +dW_FORM_addr, dW_FORM_data2, dW_FORM_data4, + dW_FORM_strp,dW_FORM_string, dW_FORM_flag, dW_FORM_block1, dW_FORM_ref4, dW_FORM_ref_addr, dW_FORM_flag_present :: Word dW_FORM_addr = 0x01 dW_FORM_data2 = 0x05 dW_FORM_data4 = 0x06 dW_FORM_string = 0x08 +dW_FORM_strp = 0x0e dW_FORM_flag = 0x0c dW_FORM_block1 = 0x0a dW_FORM_ref_addr = 0x10 ===================================== compiler/GHC/CmmToAsm/Dwarf/Types.hs ===================================== @@ -1,8 +1,16 @@ +{-# LANGUAGE RecordWildCards #-} + module GHC.CmmToAsm.Dwarf.Types ( -- * Dwarf information DwarfInfo(..) , pprDwarfInfo , pprAbbrevDecls + , dwarfInfoStrings + -- * Dwarf Strings section + , DwarfString + , dwarfStringsSection + , dwarfStringFromString + , dwarfStringFromFastString -- * Dwarf address range table , DwarfARange(..) , pprDwarfARanges @@ -24,21 +32,18 @@ module GHC.CmmToAsm.Dwarf.Types import GHC.Prelude +import GHC.Types.Unique.Set import GHC.Cmm.DebugBlock import GHC.Cmm.CLabel import GHC.Cmm.Expr ( GlobalReg(..) ) -import GHC.Utils.Encoding import GHC.Data.FastString import GHC.Utils.Outputable import GHC.Platform import GHC.Types.Unique import GHC.Platform.Reg -import GHC.Types.SrcLoc -import GHC.Utils.Misc import GHC.CmmToAsm.Dwarf.Constants -import qualified Data.ByteString as BS import qualified Control.Monad.Trans.State.Strict as S import Control.Monad (zipWithM, join) import Data.Bits @@ -48,18 +53,51 @@ import Data.Char import GHC.Platform.Regs +-- | A string in the DWARF @.debug_str@ section. +newtype DwarfString = DwarfString FastString + +instance Uniquable DwarfString where + getUnique (DwarfString fs) = getUnique fs + +dwarfStringFromString :: String -> DwarfString +dwarfStringFromString = dwarfStringFromFastString . fsLit + +dwarfStringFromFastString :: FastString -> DwarfString +dwarfStringFromFastString = DwarfString + +dwarfStringSymbol :: DwarfString -> SDoc +dwarfStringSymbol (DwarfString fs) = + text "_dbgstr_" <> ppr (uniqueOfFS fs) + +debugStrSection :: SDoc +debugStrSection = text ".debug_str" + +pprDwarfString :: Platform -> DwarfString -> SDoc +pprDwarfString plat s = + sectionOffset plat (dwarfStringSymbol s) debugStrSection + +dwarfStringsSection :: UniqSet DwarfString -> SDoc +dwarfStringsSection xs = + text ".section" <+> debugStrSection $$ vcat (map string $ nonDetEltsUniqSet xs) + -- N.B. The order here will be non-deterministic but that's okay; we + -- currently don't guarantee determinism of object code. + where + string :: DwarfString -> SDoc + string dstr@(DwarfString fstr) = + dwarfStringSymbol dstr <> colon $$ pprFastString fstr + -- | Individual dwarf records. Each one will be encoded as an entry in -- the @.debug_info@ section. data DwarfInfo = DwarfCompileUnit { dwChildren :: [DwarfInfo] - , dwName :: String - , dwProducer :: String - , dwCompDir :: String + , dwName :: DwarfString + , dwProducer :: DwarfString + , dwCompDir :: DwarfString , dwLowLabel :: CLabel , dwHighLabel :: CLabel , dwLineLabel :: PtrString } | DwarfSubprogram { dwChildren :: [DwarfInfo] - , dwName :: String + , dwName :: DwarfString , dwLabel :: CLabel , dwParent :: Maybe CLabel -- ^ label of DIE belonging to the parent tick @@ -68,9 +106,23 @@ data DwarfInfo , dwLabel :: CLabel , dwMarker :: Maybe CLabel } - | DwarfSrcNote { dwSrcSpan :: RealSrcSpan + | DwarfSrcNote { dwSpanFile :: !DwarfString + , dwSpanStartLine :: !Int + , dwSpanStartCol :: !Int + , dwSpanEndLine :: !Int + , dwSpanEndCol :: !Int } +-- | 'DwarfStrings' mentioned by the given 'DwarfInfo'. +dwarfInfoStrings :: DwarfInfo -> UniqSet DwarfString +dwarfInfoStrings dwinfo = + case dwinfo of + DwarfCompileUnit {..} -> addListToUniqSet (foldMap dwarfInfoStrings dwChildren) [dwName, dwProducer, dwCompDir] + DwarfSubprogram {..} -> addListToUniqSet (foldMap dwarfInfoStrings dwChildren) [dwName] + DwarfBlock {..} -> foldMap dwarfInfoStrings dwChildren + DwarfSrcNote {..} -> unitUniqSet dwSpanFile + + -- | Abbreviation codes used for encoding above records in the -- @.debug_info@ section. data DwarfAbbrev @@ -133,7 +185,7 @@ pprAbbrevDecls platform haveDebugLine = , (dW_AT_high_pc, dW_FORM_addr) ] $$ mkAbbrev DwAbbrGhcSrcNote dW_TAG_ghc_src_note dW_CHILDREN_no - [ (dW_AT_ghc_span_file, dW_FORM_string) + [ (dW_AT_ghc_span_file, dW_FORM_strp) , (dW_AT_ghc_span_start_line, dW_FORM_data4) , (dW_AT_ghc_span_start_col, dW_FORM_data2) , (dW_AT_ghc_span_end_line, dW_FORM_data4) @@ -163,10 +215,10 @@ pprDwarfInfoOpen :: Platform -> Bool -> DwarfInfo -> SDoc pprDwarfInfoOpen platform haveSrc (DwarfCompileUnit _ name producer compDir lowLabel highLabel lineLbl) = pprAbbrev DwAbbrCompileUnit - $$ pprString name - $$ pprString producer + $$ pprDwarfString platform name + $$ pprDwarfString platform producer $$ pprData4 dW_LANG_Haskell - $$ pprString compDir + $$ pprDwarfString platform compDir $$ pprWord platform (ppr lowLabel) $$ pprWord platform (ppr highLabel) $$ if haveSrc @@ -176,7 +228,7 @@ pprDwarfInfoOpen platform _ (DwarfSubprogram _ name label parent) = sdocWithDynFlags $ \df -> ppr (mkAsmTempDieLabel label) <> colon $$ pprAbbrev abbrev - $$ pprString name + $$ pprDwarfString platform name $$ pprString (renderWithStyle (initSDocContext df (mkCodeStyle CStyle)) (ppr label)) $$ pprFlag (externallyVisibleCLabel label) $$ pprWord platform (ppr label) @@ -199,13 +251,13 @@ pprDwarfInfoOpen platform _ (DwarfBlock _ label (Just marker)) = sdocWithDynFlag $$ pprString (renderWithStyle (initSDocContext df (mkCodeStyle CStyle)) (ppr label)) $$ pprWord platform (ppr marker) $$ pprWord platform (ppr $ mkAsmTempEndLabel marker) -pprDwarfInfoOpen _ _ (DwarfSrcNote ss) = +pprDwarfInfoOpen platform _ (DwarfSrcNote {..}) = pprAbbrev DwAbbrGhcSrcNote - $$ pprString' (ftext $ srcSpanFile ss) - $$ pprData4 (fromIntegral $ srcSpanStartLine ss) - $$ pprHalf (fromIntegral $ srcSpanStartCol ss) - $$ pprData4 (fromIntegral $ srcSpanEndLine ss) - $$ pprHalf (fromIntegral $ srcSpanEndCol ss) + $$ pprDwarfString platform dwSpanFile + $$ pprData4 (fromIntegral dwSpanStartLine) + $$ pprHalf (fromIntegral dwSpanStartCol) + $$ pprData4 (fromIntegral dwSpanEndLine) + $$ pprHalf (fromIntegral dwSpanEndCol) -- | Close a DWARF info record with children pprDwarfInfoClose :: SDoc @@ -573,13 +625,13 @@ pprLEBInt x | x >= -64 && x < 64 pprString' :: SDoc -> SDoc pprString' str = text "\t.asciz \"" <> str <> char '"' +-- | Generate a string constant. We take care to escape the string. +pprFastString :: FastString -> SDoc +pprFastString = pprString' . hcat . map escapeChar . unpackFS + -- | Generate a string constant. We take care to escape the string. pprString :: String -> SDoc -pprString str - = pprString' $ hcat $ map escapeChar $ - if str `lengthIs` utf8EncodedLength str - then str - else map (chr . fromIntegral) $ BS.unpack $ bytesFS $ mkFastString str +pprString = pprFastString . mkFastString -- | Escape a single non-unicode character escapeChar :: Char -> SDoc View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/92c7a720b306a40cb238c2eef7e1e4a74e82ffaa -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/92c7a720b306a40cb238c2eef7e1e4a74e82ffaa You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 10 19:06:03 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 10 May 2020 15:06:03 -0400 Subject: [Git][ghc/ghc][wip/lower-tc-tracing-cost] Avoid unnecessary allocations due to tracing utilities Message-ID: <5eb8509b3af26_616711a31edc10143673@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/lower-tc-tracing-cost at Glasgow Haskell Compiler / GHC Commits: 2207bc45 by Ben Gamari at 2020-05-10T15:05:32-04:00 Avoid unnecessary allocations due to tracing utilities While ticky-profiling the typechecker I noticed that hundreds of millions of SDocs are being allocated just in case -ddump-*-trace is enabled. This is awful. We avoid this by ensuring that the dump flag check is inlined into the call site, ensuring that the tracing document needn't be allocated unless it's actually needed. See Note [INLINE conditional tracing utilities] for details. Fixes #18168. - - - - - 7 changed files: - compiler/GHC/Core/Opt/Simplify/Monad.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/Tc/Solver/Flatten.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Utils/Error.hs Changes: ===================================== compiler/GHC/Core/Opt/Simplify/Monad.hs ===================================== @@ -143,6 +143,7 @@ traceSmpl herald doc ; liftIO $ Err.dumpIfSet_dyn dflags Opt_D_dump_simpl_trace "Simpl Trace" FormatText (hang (text herald) 2 doc) } +{-# INLINE traceSmpl #-} -- see Note [INLINE conditional tracing utilities] {- ************************************************************************ ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -1279,7 +1279,10 @@ callSiteInline dflags id active_unfolding lone_variable arg_infos cont_info -- | Report the inlining of an identifier's RHS to the user, if requested. traceInline :: DynFlags -> Id -> String -> SDoc -> a -> a -traceInline dflags inline_id str doc result = +traceInline dflags inline_id str doc result + -- We take care to ensure that doc is used in only one branch, ensuring that + -- the simplifier can push its allocation into the branch. See Note [INLINE + -- conditional tracing utilities]. | enable = traceAction dflags str doc result | otherwise = result where @@ -1288,6 +1291,9 @@ traceInline dflags inline_id str doc result = = True | Just prefix <- inlineCheck dflags = prefix `isPrefixOf` occNameString (getOccName inline_id) + | otherwise + = False +{-# INLINE traceInline #-} -- see Note [INLINE conditional tracing utilities] tryUnfolding :: DynFlags -> Id -> Bool -> [ArgSummary] -> CallCtxt -> CoreExpr -> Bool -> Bool -> UnfoldingGuidance ===================================== compiler/GHC/HsToCore/PmCheck/Oracle.hs ===================================== @@ -89,6 +89,7 @@ tracePm herald doc = do printer <- mkPrintUnqualifiedDs liftIO $ dumpIfSet_dyn_printer printer dflags Opt_D_dump_ec_trace "" FormatText (text herald $$ (nest 2 doc)) +{-# INLINE tracePm #-} -- see Note [INLINE conditional tracing utilities] -- | Generate a fresh `Id` of a given type mkPmId :: Type -> DsM Id ===================================== compiler/GHC/Tc/Solver/Flatten.hs ===================================== @@ -543,6 +543,7 @@ runFlatten mode loc flav eq_rel thing_inside traceFlat :: String -> SDoc -> FlatM () traceFlat herald doc = liftTcS $ traceTcS herald doc +{-# INLINE traceFlat #-} -- see Note [INLINE conditional tracing utilities] getFlatEnvField :: (FlattenEnv -> a) -> FlatM a getFlatEnvField accessor ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -2733,6 +2733,7 @@ panicTcS doc = pprPanic "GHC.Tc.Solver.Canonical" doc traceTcS :: String -> SDoc -> TcS () traceTcS herald doc = wrapTcS (TcM.traceTc herald doc) +{-# INLINE traceTcS #-} -- see Note [INLINE conditional tracing utilities] runTcPluginTcS :: TcPluginM a -> TcS a runTcPluginTcS m = wrapTcS . runTcPluginM m =<< getTcEvBindsVar @@ -2751,6 +2752,7 @@ bumpStepCountTcS = TcS $ \env -> do { let ref = tcs_count env csTraceTcS :: SDoc -> TcS () csTraceTcS doc = wrapTcS $ csTraceTcM (return doc) +{-# INLINE csTraceTcS #-} -- see Note [INLINE conditional tracing utilities] traceFireTcS :: CtEvidence -> SDoc -> TcS () -- Dump a rule-firing trace @@ -2763,6 +2765,7 @@ traceFireTcS ev doc text "d:" <> ppr (ctLocDepth (ctEvLoc ev))) <+> doc <> colon) 4 (ppr ev)) } +{-# INLINE traceFireTcS #-} -- see Note [INLINE conditional tracing utilities] csTraceTcM :: TcM SDoc -> TcM () -- Constraint-solver tracing, -ddump-cs-trace @@ -2775,6 +2778,7 @@ csTraceTcM mk_doc (dumpOptionsFromFlag Opt_D_dump_cs_trace) "" FormatText msg }) } +{-# INLINE csTraceTcM #-} -- see Note [INLINE conditional tracing utilities] runTcS :: TcS a -- What to run -> TcM (a, EvBindMap) ===================================== compiler/GHC/Tc/Utils/Monad.hs ===================================== @@ -490,22 +490,28 @@ unsetWOptM flag = whenDOptM :: DumpFlag -> TcRnIf gbl lcl () -> TcRnIf gbl lcl () whenDOptM flag thing_inside = do b <- doptM flag when b thing_inside +{-# INLINE whenDOptM #-} -- see Note [INLINE conditional tracing utilities] + whenGOptM :: GeneralFlag -> TcRnIf gbl lcl () -> TcRnIf gbl lcl () whenGOptM flag thing_inside = do b <- goptM flag when b thing_inside +{-# INLINE whenGOptM #-} -- see Note [INLINE conditional tracing utilities] whenWOptM :: WarningFlag -> TcRnIf gbl lcl () -> TcRnIf gbl lcl () whenWOptM flag thing_inside = do b <- woptM flag when b thing_inside +{-# INLINE whenWOptM #-} -- see Note [INLINE conditional tracing utilities] whenXOptM :: LangExt.Extension -> TcRnIf gbl lcl () -> TcRnIf gbl lcl () whenXOptM flag thing_inside = do b <- xoptM flag when b thing_inside +{-# INLINE whenXOptM #-} -- see Note [INLINE conditional tracing utilities] unlessXOptM :: LangExt.Extension -> TcRnIf gbl lcl () -> TcRnIf gbl lcl () unlessXOptM flag thing_inside = do b <- xoptM flag unless b thing_inside +{-# INLINE unlessXOptM #-} -- see Note [INLINE conditional tracing utilities] getGhcMode :: TcRnIf gbl lcl GhcMode getGhcMode = do { env <- getTopEnv; return (ghcMode (hsc_dflags env)) } @@ -662,39 +668,64 @@ updTcRef ref fn = liftIO $ do { old <- readIORef ref ************************************************************************ -} +-- Note [INLINE conditional tracing utilities] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- In general we want to optimise for the case where tracing is not enabled. +-- To ensure this happens, we ensure that traceTc and friends are inlined; this +-- ensures that the allocation of the document can be pushed into the tracing +-- path, keeping the non-traced path free of this extraneous work. For +-- instance, instead of +-- +-- let thunk = ... +-- in if doTracing +-- then emitTraceMsg thunk +-- else return () +-- +-- where the conditional is buried in a non-inlined utility function (e.g. +-- traceTc), we would rather have: +-- +-- if doTracing +-- then let thunk = ... +-- in emitTraceMsg thunk +-- else return () +-- +-- See #18168. +-- -- Typechecker trace traceTc :: String -> SDoc -> TcRn () -traceTc = - labelledTraceOptTcRn Opt_D_dump_tc_trace +traceTc herald doc = + labelledTraceOptTcRn Opt_D_dump_tc_trace herald doc +{-# INLINE traceTc #-} -- see Note [INLINE conditional tracing utilities] -- Renamer Trace traceRn :: String -> SDoc -> TcRn () -traceRn = - labelledTraceOptTcRn Opt_D_dump_rn_trace +traceRn herald doc = + labelledTraceOptTcRn Opt_D_dump_rn_trace herald doc +{-# INLINE traceRn #-} -- see Note [INLINE conditional tracing utilities] -- | Trace when a certain flag is enabled. This is like `traceOptTcRn` -- but accepts a string as a label and formats the trace message uniformly. labelledTraceOptTcRn :: DumpFlag -> String -> SDoc -> TcRn () -labelledTraceOptTcRn flag herald doc = do - traceOptTcRn flag (formatTraceMsg herald doc) +labelledTraceOptTcRn flag herald doc = + traceOptTcRn flag (formatTraceMsg herald doc) +{-# INLINE labelledTraceOptTcRn #-} -- see Note [INLINE conditional tracing utilities] formatTraceMsg :: String -> SDoc -> SDoc formatTraceMsg herald doc = hang (text herald) 2 doc --- | Trace if the given 'DumpFlag' is set. traceOptTcRn :: DumpFlag -> SDoc -> TcRn () traceOptTcRn flag doc = do - dflags <- getDynFlags - when (dopt flag dflags) $ + whenDOptM flag $ dumpTcRn False (dumpOptionsFromFlag flag) "" FormatText doc +{-# INLINE traceOptTcRn #-} -- see Note [INLINE conditional tracing utilities] -- | Dump if the given 'DumpFlag' is set. dumpOptTcRn :: DumpFlag -> String -> DumpFormat -> SDoc -> TcRn () dumpOptTcRn flag title fmt doc = do - dflags <- getDynFlags - when (dopt flag dflags) $ + whenDOptM flag $ dumpTcRn False (dumpOptionsFromFlag flag) title fmt doc +{-# INLINE dumpOptTcRn #-} -- see Note [INLINE conditional tracing utilities] -- | Unconditionally dump some trace output -- @@ -746,13 +777,16 @@ e.g. are unaffected by -dump-to-file. traceIf, traceHiDiffs :: SDoc -> TcRnIf m n () traceIf = traceOptIf Opt_D_dump_if_trace traceHiDiffs = traceOptIf Opt_D_dump_hi_diffs - +{-# INLINE traceIf #-} +{-# INLINE traceHiDiffs #-} + -- see Note [INLINE conditional tracing utilities] traceOptIf :: DumpFlag -> SDoc -> TcRnIf m n () traceOptIf flag doc = whenDOptM flag $ -- No RdrEnv available, so qualify everything do { dflags <- getDynFlags ; liftIO (putMsg dflags doc) } +{-# INLINE traceOptIf #-} -- see Note [INLINE conditional tracing utilities] {- ************************************************************************ ===================================== compiler/GHC/Utils/Error.hs ===================================== @@ -438,20 +438,27 @@ doIfSet_dyn dflags flag action | gopt flag dflags = action dumpIfSet :: DynFlags -> Bool -> String -> SDoc -> IO () dumpIfSet dflags flag hdr doc | not flag = return () - | otherwise = putLogMsg dflags - NoReason - SevDump - noSrcSpan - (withPprStyle defaultDumpStyle - (mkDumpDoc hdr doc)) - --- | a wrapper around 'dumpAction'. + | otherwise = doDump dflags hdr doc + where + -- Explicitly bind this so it can float out and we don't duplicate this code + -- needlessly due to the INLINE below. + doDump dflags hdr doc = + putLogMsg dflags + NoReason + SevDump + noSrcSpan + (withPprStyle defaultDumpStyle + (mkDumpDoc hdr doc)) +{-# INLINE dumpIfSet #-} -- see Note [INLINE conditional tracing utilities] + +-- | A wrapper around 'dumpAction'. -- First check whether the dump flag is set -- Do nothing if it is unset dumpIfSet_dyn :: DynFlags -> DumpFlag -> String -> DumpFormat -> SDoc -> IO () dumpIfSet_dyn = dumpIfSet_dyn_printer alwaysQualify +{-# INLINE dumpIfSet_dyn #-} -- see Note [INLINE conditional tracing utilities] --- | a wrapper around 'dumpAction'. +-- | A wrapper around 'dumpAction'. -- First check whether the dump flag is set -- Do nothing if it is unset -- @@ -462,6 +469,7 @@ dumpIfSet_dyn_printer printer dflags flag hdr fmt doc = when (dopt flag dflags) $ do let sty = mkDumpStyle printer dumpAction dflags sty (dumpOptionsFromFlag flag) hdr fmt doc +{-# INLINE dumpIfSet_dyn_printer #-} -- see Note [INLINE conditional tracing utilities] mkDumpDoc :: String -> SDoc -> SDoc mkDumpDoc hdr doc @@ -608,6 +616,7 @@ ifVerbose :: DynFlags -> Int -> IO () -> IO () ifVerbose dflags val act | verbosity dflags >= val = act | otherwise = return () +{-# INLINE ifVerbose #-} -- see Note [INLINE conditional tracing utilities] errorMsg :: DynFlags -> MsgDoc -> IO () errorMsg dflags msg @@ -778,6 +787,7 @@ debugTraceMsg :: DynFlags -> Int -> MsgDoc -> IO () debugTraceMsg dflags val msg = ifVerbose dflags val $ logInfo dflags (withPprStyle defaultDumpStyle msg) +{-# INLINE debugTraceMsg #-} -- see Note [INLINE conditional tracing utilities] putMsg :: DynFlags -> MsgDoc -> IO () putMsg dflags msg = logInfo dflags (withPprStyle defaultUserStyle msg) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2207bc4503ec3ba421cdf53256d3752c38155191 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2207bc4503ec3ba421cdf53256d3752c38155191 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 10 19:17:06 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 10 May 2020 15:17:06 -0400 Subject: [Git][ghc/ghc][wip/T18074] users-guide: Add discussion of shared object naming Message-ID: <5eb85332c0ed1_616711a31edc10150068@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18074 at Glasgow Haskell Compiler / GHC Commits: df3a7950 by Ben Gamari at 2020-05-10T15:16:58-04:00 users-guide: Add discussion of shared object naming Fixes #18074. - - - - - 2 changed files: - docs/users_guide/packages.rst - docs/users_guide/phases.rst Changes: ===================================== docs/users_guide/packages.rst ===================================== @@ -1061,6 +1061,14 @@ extra indirection). its output in place of ⟨GHCVersion⟩. See also :ref:`options-codegen` on how object files must be prepared for shared object linking. +- When building a shared library, care must be taken to ensure that the + resulting object is named appropriately. In particular, GHC expects the + name of a shared object to have the form ``libHS-ghc.`` where *unit id* is the unit ID given during compilation via + the :ghc-flag:`-this-unit-id ⟨unit-id⟩` flag, *ghc version* is the version of + GHC that produced/consumes the object and *ext* is the host system's usual + file extension for shared objects. + To compile a module which is to be part of a new package, use the ``-package-name`` (to identify the name of the package) and ``-library-name`` (to identify the version and the version hashes of its ===================================== docs/users_guide/phases.rst ===================================== @@ -807,7 +807,8 @@ for example). When creating shared objects for Haskell packages, the shared object must be named properly, so that GHC recognizes the shared object - when linked against this package. See shared object name mangling. + when linking against this package. + See :ref:`shared object name mangling ` for details. .. ghc-flag:: -dynload :shortdesc: Selects one of a number of modes for finding shared libraries at runtime. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/df3a7950f10ea2247707b3789e6fdfe301726343 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/df3a7950f10ea2247707b3789e6fdfe301726343 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 10 19:43:08 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 10 May 2020 15:43:08 -0400 Subject: [Git][ghc/ghc][wip/dataToTag-opt] 258 commits: base: add strict IO functions: readFile', getContents', hGetContents' Message-ID: <5eb8594cb269a_616711a31edc10157769@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/dataToTag-opt at Glasgow Haskell Compiler / GHC Commits: 818b3c38 by Lysxia at 2020-03-16T23:52:42-04:00 base: add strict IO functions: readFile', getContents', hGetContents' - - - - - 18a346a4 by Sylvain Henry at 2020-03-16T23:53:24-04:00 Modules: Core (#13009) Update submodule: haddock - - - - - 92327e3a by Ömer Sinan Ağacan at 2020-03-16T23:54:04-04:00 Update sanity checking for TSOs: - Remove an invalid assumption about GC checking what_next field. The GC doesn't care about what_next at all, if a TSO is reachable then all its pointers are followed (other than global_tso, which is only followed by compacting GC). - Remove checkSTACK in checkTSO: TSO stacks will be visited in checkHeapChain, or checkLargeObjects etc. - Add an assertion in checkTSO to check that the global_link field is sane. - Did some refactor to remove forward decls in checkGlobalTSOList and added braces around single-statement if statements. - - - - - e1aa4052 by PHO at 2020-03-17T07:36:09-04:00 Don't use non-portable operator "==" in configure.ac The test operator "==" is a Bash extension and produces a wrong result if /bin/sh is not Bash. - - - - - 89f034dd by Maximilian Tagher at 2020-03-17T07:36:48-04:00 Document the units of -ddump-timings Right now, in the output of -ddump-timings to a file, you can't tell what the units are: ``` CodeGen [TemplateTestImports]: alloc=22454880 time=14.597 ``` I believe bytes/milliseconds are the correct units, but confirmation would be appreciated. I'm basing it off of this snippet from `withTiming'`: ``` when (verbosity dflags >= 2 && prtimings == PrintTimings) $ liftIO $ logInfo dflags (defaultUserStyle dflags) (text "!!!" <+> what <> colon <+> text "finished in" <+> doublePrec 2 time <+> text "milliseconds" <> comma <+> text "allocated" <+> doublePrec 3 (realToFrac alloc / 1024 / 1024) <+> text "megabytes") ``` which implies time is in milliseconds, and allocations in bytes (which divided by 1024 would be KB, and again would be MB) - - - - - beffa147 by Simon Peyton Jones at 2020-03-17T07:37:25-04:00 Implement mapTyCo like foldTyCo This patch makes mapType use the successful idiom described in TyCoRep Note [Specialising foldType] I have not yet changed any functions to use mapType, though there may be some suitable candidates. This patch should be a no-op in terms of functionality but, because it inlines the mapper itself, I'm hoping that there may be some modest perf improvements. Metric Decrease: T5631 T5642 T3064 T9020 T14683 hie002 haddock.Cabal haddock.base haddock.compiler - - - - - 5800ebfe by Ömer Sinan Ağacan at 2020-03-17T07:38:08-04:00 Don't update ModDetails with CafInfos when opts are disabled This is consistent with the interface file behavior where we omit HsNoCafRefs annotations with -fomit-interface-pragmas (implied by -O0). ModDetails and ModIface are just different representations of the same thing, so they really need to be in sync. This patch does the right thing and does not need too much explanation, but here's an example of a problem not doing this causes in !2842: -- MyInteger.hs module MyInteger ( MyInteger (MyInteger) , ToMyInteger (toMyInteger) ) where newtype MyInteger = MyInteger Integer class ToMyInteger a where toMyInteger :: a -> MyInteger instance ToMyInteger Integer where toMyInteger = MyInteger {- . succ -} -- Main.hs module Main ( main ) where import MyInteger (MyInteger (MyInteger), toMyInteger) main :: IO () main = do let (MyInteger i) = (id . toMyInteger) (41 :: Integer) print i If I build this with -O0, without this fix, we generate a ModDetails with accurate LFInfo for toMyInteger (MyInteger.$fToMyIntegerInteger) which says that it's a LFReEntrant with arity 1. This means in the use site (Main) we tag the value: R3 = MyInteger.$fToMyIntegerInteger_closure + 1; R2 = GHC.Base.id_closure; R1 = GHC.Base.._closure; Sp = Sp - 16; call stg_ap_ppp_fast(R4, R3, R2, R1) args: 24, res: 0, upd: 24; Now we change the definition by uncommenting the `succ` part and it becomes a thunk: MyInteger.$fToMyIntegerInteger [InlPrag=INLINE (sat-args=0)] :: MyInteger.ToMyInteger GHC.Integer.Type.Integer [GblId[DFunId(nt)]] = {} \u [] $ctoMyInteger_rEA; and its LFInfo is now LFThunk. This change in LFInfo makes a difference in the use site: we can no longer tag it. But becuase the interface fingerprint does not change (because ModIface does not change) we don't rebuild Main and tag the thunk. (1.2% increase in allocations when building T12545 on armv7 because we generate more code without CafInfos) Metric Increase: T12545 - - - - - 5b632dad by Paavo at 2020-03-17T07:38:48-04:00 Add example for Data.Semigroup.diff - - - - - 4d85d68b by Paavo at 2020-03-17T07:38:48-04:00 Clean up - - - - - 75168d07 by Paavo at 2020-03-17T07:38:48-04:00 Make example collapsible - - - - - 53ff2cd0 by Richard Eisenberg at 2020-03-17T13:46:57+00:00 Fix #17021 by checking more return kinds All the details are in new Note [Datatype return kinds] in TcTyClsDecls. Test case: typecheck/should_fail/T17021{,b} typecheck/should_compile/T17021a Updates haddock submodule - - - - - 528df8ec by Sylvain Henry at 2020-03-18T10:06:43-04:00 Modules: Core operations (#13009) - - - - - 4e8a71c1 by Richard Eisenberg at 2020-03-18T10:07:19-04:00 Add release note about fix to #16502. We thought we needed to update the manual, but the fix for #16502 actually brings the implementation in line with the manual. So we just alert users of how to update their code. - - - - - 5cbf9934 by Andreas Klebinger at 2020-03-19T00:39:27-04:00 Update "GHC differences to the FFI Chapter" in user guide. The old entry had a heavy focus on how things had been. Which is not what I generally look for in a user guide. I also added a small section on behaviour of nested safe ffi calls. [skip-ci] - - - - - b03fd3bc by Sebastian Graf at 2020-03-19T00:40:06-04:00 PmCheck: Use ConLikeSet to model negative info In #17911, Simon recognised many warnings stemming from over-long list unions while coverage checking Cabal's `LicenseId` module. This patch introduces a new `PmAltConSet` type which uses a `UniqDSet` instead of an association list for `ConLike`s. For `PmLit`s, it will still use an assocation list, though, because a similar map data structure would entail a lot of busy work. Fixes #17911. - - - - - 64f20756 by Sylvain Henry at 2020-03-19T12:16:49-04:00 Refactoring: use Platform instead of DynFlags when possible Metric Decrease: ManyConstructors T12707 T13035 T1969 - - - - - cb1785d9 by Ömer Sinan Ağacan at 2020-03-19T12:16:54-04:00 FastString: fix eager reading of string ptr in hashStr This read causes NULL dereferencing when len is 0. Fixes #17909 In the reproducer in #17909 this bug is triggered as follows: - SimplOpt.dealWithStringLiteral is called with a single-char string ("=" in #17909) - tailFS gets called on the FastString of the single-char string. - tailFS checks the length of the string, which is 1, and calls mkFastStringByteString on the tail of the ByteString, which is an empty ByteString as the original ByteString has only one char. - ByteString's unsafeUseAsCStringLen returns (NULL, 0) for the empty ByteString, which is passed to mkFastStringWith. - mkFastStringWith gets hash of the NULL pointer via hashStr, which fails on empty strings because of this bug. - - - - - 73a7383e by Richard Eisenberg at 2020-03-20T20:42:56-04:00 Simplify treatment of heterogeneous equality Previously, if we had a [W] (a :: k1) ~ (rhs :: k2), we would spit out a [D] k1 ~ k2 and part the W as irreducible, hoping for a unification. But we needn't do this. Instead, we now spit out a [W] co :: k2 ~ k1 and then use co to cast the rhs of the original Wanted. This means that we retain the connection between the spat-out constraint and the original. The problem with this new approach is that we cannot use the casted equality for substitution; it's too like wanteds-rewriting- wanteds. So, we forbid CTyEqCans that mention coercion holes. All the details are in Note [Equalities with incompatible kinds] in TcCanonical. There are a few knock-on effects, documented where they occur. While debugging an error in this patch, Simon and I ran into infelicities in how patterns and matches are printed; we made small improvements. This patch includes mitigations for #17828, which causes spurious pattern-match warnings. When #17828 is fixed, these lines should be removed. - - - - - faa36e5b by Sylvain Henry at 2020-03-20T20:43:41-04:00 Hadrian: ignore in-tree GMP objects with ``--lint`` - - - - - 9a96ff6b by Richard Eisenberg at 2020-03-20T20:44:17-04:00 Update core spec to reflect changes to Core. Key changes: * Adds a new rule for forall-coercions over coercion variables, which was implemented but conspicuously missing from the spec. * Adds treatment for FunCo. * Adds treatment for ForAllTy over coercion variables. * Improves commentary (including restoring a Note lost in 03d4852658e1b7407abb4da84b1b03bfa6f6db3b) in the source. No changes to running code. - - - - - 7e0451c6 by Sergej Jaskiewicz at 2020-03-20T20:44:55-04:00 Fix event message in withTiming' This typo caused generating 'end' events without the corresponding 'begin' events. - - - - - 1542a626 by Ben Gamari at 2020-03-22T22:37:47-04:00 fs.h: Add missing declarations on Windows - - - - - 3bcf2ccd by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump process submodule Avoids redundant case alternative warning. - - - - - 3b363ef9 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Normalize slashes in ghc-api annotations output Enable `normalise_slashes` on `annotations`, `listcomps`, and `parseTree` to fix Windows failures. - - - - - 25fc9429 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - 7f58ec6d by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Fix TOP of T17786 - - - - - aadcd909 by GHC GitLab CI at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - dc1eb10d by GHC GitLab CI at 2020-03-22T22:37:47-04:00 hadrian: Fix executable extension passed to testsuite driver - - - - - 58f62e2c by GHC GitLab CI at 2020-03-22T22:37:47-04:00 gitlab-ci: Require that Windows-hadrian job passes - - - - - 8dd2415d by Ben Gamari at 2020-03-22T22:37:47-04:00 hadrian: Eliminate redundant .exe from GHC path Previously we were invoking: bash -c "c:/GitLabRunner/builds/eEQrxK4p/0/ghc/ghc/toolchain/bin/ghc.exe.exe testsuite/mk/ghc-config.hs -o _build/test/bin/ghc-config.exe" - - - - - 373621f6 by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump hsc2hs submodule - - - - - abc02b40 by Hécate at 2020-03-22T22:38:33-04:00 Annotate the non-total function in Data.Foldable as such - - - - - 19f12557 by Josef Svenningsson at 2020-03-23T14:05:33-04:00 Fix ApplicativeDo regression #17835 A previous fix for #15344 made sure that monadic 'fail' is used properly when translating ApplicativeDo. However, it didn't properly account for when a 'fail' will be inserted which resulted in some programs failing with a type error. - - - - - 2643ba46 by Paavo at 2020-03-24T08:31:32-04:00 Add example and doc for Arg (Fixes #17153) - - - - - 703221f4 by Roland Senn at 2020-03-25T14:45:04-04:00 Use export list of Main module in function TcRnDriver.hs:check_main (Fix #16453) - Provide the export list of the `Main` module as parameter to the `compiler/typecheck/TcRnDriver.hs:check_main` function. - Instead of `lookupOccRn_maybe` call the function `lookupInfoOccRn`. It returns the list `mains_all` of all the main functions in scope. - Select from this list `mains_all` all `main` functions that are in the export list of the `Main` module. - If this new list contains exactly one single `main` function, then typechecking continues. - Otherwise issue an appropriate error message. - - - - - 3e27205a by Sebastian Graf at 2020-03-25T14:45:40-04:00 Remove -fkill-absence and -fkill-one-shot flags They seem to be a benchmarking vestige of the Cardinality paper and probably shouldn't have been merged to HEAD in the first place. - - - - - 262e42aa by Peter Trommler at 2020-03-25T22:41:39-04:00 Do not panic on linker errors - - - - - 0de03cd7 by Sylvain Henry at 2020-03-25T22:42:02-04:00 DynFlags refactoring III Use Platform instead of DynFlags when possible: * `tARGET_MIN_INT` et al. replaced with `platformMinInt` et al. * no more DynFlags in PreRules: added a new `RuleOpts` datatype * don't use `wORD_SIZE` in the compiler * make `wordAlignment` use `Platform` * make `dOUBLE_SIZE` a constant Metric Decrease: T13035 T1969 - - - - - 7a04920b by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: fix a typo in liftA doc This change removes an extra '|' that should not be rendered in the liftA documentation. Tracking: #17929 - - - - - 1c5a15f7 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add Control.Applicative optional example This change adds an optional example. Tracking: #17929 - - - - - 6d172e63 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add markup around Except - - - - - eb2162c8 by John Ericson at 2020-03-26T12:37:08-04:00 Remove unused `ghciTablesNextToCode` from compiler proper - - - - - f51efc4b by Joachim Breitner at 2020-03-26T12:37:09-04:00 Prepare to use run-time tablesNextToCode in compiler exclusively Factor out CPP as much as possible to prepare for runtime determinattion. Progress towards #15548 - - - - - 1c446220 by Joachim Breitner at 2020-03-26T12:37:09-04:00 Use run-time tablesNextToCode in compiler exclusively (#15548) Summary: - There is no more use of the TABLES_NEXT_TO_CODE CPP macro in `compiler/`. GHCI_TABLES_NEXT_TO_CODE is also removed entirely. The field within `PlatformMisc` within `DynFlags` is used instead. - The field is still not exposed as a CLI flag. We might consider some way to ensure the right RTS / libraries are used before doing that. Original reviewers: Original subscribers: TerrorJack, rwbarton, carter Original Differential Revision: https://phabricator.haskell.org/D5082 - - - - - 1941ef4f by Sylvain Henry at 2020-03-29T17:28:51-04:00 Modules: Types (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - 1c7c6f1a by Sylvain Henry at 2020-03-29T17:28:51-04:00 Remove GHC.Types.Unique.Map module This module isn't used anywhere in GHC. - - - - - f1a6c73d by Sylvain Henry at 2020-03-29T17:28:51-04:00 Merge GHC.Types.CostCentre.Init into GHC.Driver.CodeOutput - - - - - 54250f2d by Simon Peyton Jones at 2020-03-29T17:29:30-04:00 Demand analysis: simplify the demand for a RHS Ticket #17932 showed that we were using a stupid demand for the RHS of a let-binding, when the result is a product. This was the result of a "fix" in 2013, which (happily) turns out to no longer be necessary. So I just deleted the code, which simplifies the demand analyser, and fixes #17932. That in turn uncovered that the anticipation of worker/wrapper in CPR analysis was inaccurate, hence the logic that decides whether to unbox an argument in WW was extracted into a function `wantToUnbox`, now consulted by CPR analysis. I tried nofib, and got 0.0% perf changes. All this came up when messing about with !2873 (ticket #17917), but is idependent of it. Unfortunately, this patch regresses #4267 and realised that it is now blocked on #16335. - - - - - 03060b2f by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 on Windows Fixes line ending normalization issue. - - - - - 1f7995ba by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 Fix missing quoting and expected exit code. - - - - - ef9c608e by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Mark T12971 as broken on Windows Due to #17945. - - - - - e54500c1 by Sylvain Henry at 2020-03-29T17:30:47-04:00 Store ComponentId details As far as GHC is concerned, installed package components ("units") are identified by an opaque ComponentId string provided by Cabal. But we don't want to display it to users (as it contains a hash) so GHC queries the database to retrieve some infos about the original source package (name, version, component name). This patch caches these infos in the ComponentId itself so that we don't need to provide DynFlags (which contains installed package informations) to print a ComponentId. In the future we want GHC to support several independent package states (e.g. for plugins and for target code), hence we need to avoid implicitly querying a single global package state. - - - - - 7e7cb714 by Marius Bakke at 2020-03-29T17:31:27-04:00 testsuite: Remove test that dlopens a PIE object. glibc 2.30 disallowed dlopening PIE objects, so just remove the test. Fixes #17952. - - - - - 6c8f80d8 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Correct haddocks for testBit in Data.Bits It conflated the nth bit with the bit at offset n. Now we instead give the definition in terms of `bit and `.&.` on top of clearer phrasing. - - - - - c916f190 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Apply suggestion to libraries/base/Data/Bits.hs - - - - - 64bf7f51 by Ben Gamari at 2020-03-29T17:32:41-04:00 gitlab-ci: Add FreeBSD release job - - - - - a0d8e92e by Ryan Scott at 2020-03-29T17:33:20-04:00 Run checkNewDataCon before constraint-solving newtype constructors Within `checkValidDataCon`, we used to run `checkValidType` on the argument types of a newtype constructor before running `checkNewDataCon`, which ensures that the user does not attempt non-sensical things such as newtypes with multiple arguments or constraints. This works out in most situations, but this falls over on a corner case revealed in #17955: ```hs newtype T = Coercible () T => T () ``` `checkValidType`, among other things, peforms an ambiguity check on the context of a data constructor, and that it turn invokes the constraint solver. It turns out that there is a special case in the constraint solver for representational equalities (read: `Coercible` constraints) that causes newtypes to be unwrapped (see `Note [Unwrap newtypes first]` in `TcCanonical`). This special case does not know how to cope with an ill formed newtype like `T`, so it ends up panicking. The solution is surprisingly simple: just invoke `checkNewDataCon` before `checkValidType` to ensure that the illicit newtype constructor context is detected before the constraint solver can run amok with it. Fixes #17955. - - - - - 45eb9d8c by Krzysztof Gogolewski at 2020-03-29T17:33:59-04:00 Minor cleanup - Simplify mkBuildExpr, the function newTyVars was called only on a one-element list. - TTG: use noExtCon in more places. This is more future-proof. - In zonkExpr, panic instead of printing a warning. - - - - - f024b6e3 by Sylvain Henry at 2020-03-30T12:48:39+02:00 Expect T4267 to pass Since 54250f2d8de910b094070c1b48f086030df634b1 we expected T4267 to fail, but it passes on CI. - - - - - 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.0.0 This requires bumping the `exceptions` and `text` submodules to bring in commits that bump their respective upper version bounds on `template-haskell`. Fixes #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - ffd7eef2 by Takenobu Tani at 2020-04-22T23:09:50-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - e8a5d81b by Jonathan DK Gibbons at 2020-04-22T23:10:28-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - dcb7fe5a by John Ericson at 2020-04-22T23:10:28-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - cde23cd4 by John Ericson at 2020-04-22T23:10:28-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - 72cb6bcc by John Ericson at 2020-04-22T23:10:28-04:00 Generalize type of `matchCanFail` - - - - - 401f7bb3 by John Ericson at 2020-04-22T23:10:28-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 6c9fae23 by Alexis King at 2020-04-22T23:11:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 48b8951e by Roland Senn at 2020-04-22T23:11:51-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 34a45ee6 by Peter Trommler at 2020-04-22T23:12:27-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - ffde2348 by Simon Peyton Jones at 2020-04-22T23:13:06-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 6f84aca3 by Ben Gamari at 2020-04-22T23:13:43-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - c29f0fa6 by Andreas Klebinger at 2020-04-22T23:14:21-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 4b4a8b60 by Ben Gamari at 2020-04-22T23:14:57-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 831b6642 by Moritz Angermann at 2020-04-22T23:15:33-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - c409961a by Ryan Scott at 2020-04-22T23:16:12-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 125aa2b8 by Ömer Sinan Ağacan at 2020-04-22T23:16:51-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - 8ea37b01 by Sylvain Henry at 2020-04-22T23:17:34-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - cd8409c2 by Ryan Scott at 2020-04-23T11:39:24-04:00 Create di_scoped_tvs for associated data family instances properly See `Note [Associated data family instances and di_scoped_tvs]` in `GHC.Tc.TyCl.Instance`, which explains all of the moving parts. Fixes #18055. - - - - - 339e8ece by Ben Gamari at 2020-04-23T11:40:02-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 5946c85a by Ben Gamari at 2020-04-23T11:40:38-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - c42754d5 by John Ericson at 2020-04-23T18:32:43-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 72da0c29 by mniip at 2020-04-23T18:33:21-04:00 Add :doc to GHC.Prim - - - - - 2c23e2e3 by mniip at 2020-04-23T18:33:21-04:00 Include docs for non-primop entries in primops.txt as well - - - - - 0ac29c88 by mniip at 2020-04-23T18:33:21-04:00 GHC.Prim docs: note and test - - - - - b0fbfc75 by John Ericson at 2020-04-24T12:07:14-04:00 Switch order on `GhcMake.IsBoot` In !1798 we were requested to replace many `Bool`s with this data type. But those bools had `False` meaning `NotBoot`, so the `Ord` instance would be flipped if we use this data-type as-is. Since the planned formally-`Bool` occurrences vastly outnumber the current occurrences, we figured it would be better to conform the `Ord` instance to how the `Bool` is used now, fixing any issues, rather than fix them currently with the bigger refactor later in !1798. That way, !1798 can be a "pure" refactor with no behavioral changes. - - - - - af332442 by Sylvain Henry at 2020-04-26T13:55:14-04:00 Modules: Utils and Data (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - cd4434c8 by Sylvain Henry at 2020-04-26T13:55:16-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 22bf5c73 by Ömer Sinan Ağacan at 2020-04-26T13:55:22-04:00 Tweak includes in non-moving GC headers We don't use hash tables in non-moving GC so remove the includes. This breaks Compact.c as existing includes no longer include Hash.h, so include Hash.h explicitly in Compact.c. - - - - - 99823ed2 by Sylvain Henry at 2020-04-27T20:24:46-04:00 TH: fix Show/Eq/Ord instances for Bytes (#16457) We shouldn't compare pointer values but the actual bytes. - - - - - c62271a2 by Alp Mestanogullari at 2020-04-27T20:25:33-04:00 hadrian: always capture both stdout and stderr when running a builder fails The idea being that when a builder('s command) fails, we quite likely want to have all the information available to figure out why. Depending on the builder _and_ the particular problem, the useful bits of information can be printed on stdout or stderr. We accomplish this by defining a simple wrapper for Shake's `cmd` function, that just _always_ captures both streams in case the command returns a non-zero exit code, and by using this wrapper everywhere in `hadrian/src/Builder.hs`. Fixes #18089. - - - - - 4b9764db by Ryan Scott at 2020-04-28T15:40:04-04:00 Define a Quote IO instance Fixes #18103. - - - - - 518a63d4 by Ryan Scott at 2020-04-28T15:40:42-04:00 Make boxed 1-tuples have known keys Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. - - - - - 2cfc4ab9 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Document backpack fields in DynFlags - - - - - 10a2ba90 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 69562e34 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 9e2c8e0e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - ea717aa4 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 10d15f1e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 8bfb0219 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - 71484b09 by Alexis King at 2020-04-30T01:57:35-04:00 Allow block arguments in arrow control operators Arrow control operators have their own entries in the grammar, so they did not cooperate with BlockArguments. This was just a minor oversight, so this patch adjusts the grammar to add the desired behavior. fixes #18050 - - - - - a48cd2a0 by Alexis King at 2020-04-30T01:57:35-04:00 Allow LambdaCase to be used as a command in proc notation - - - - - f4d3773c by Alexis King at 2020-04-30T01:57:35-04:00 Document BlockArguments/LambdaCase support in arrow notation - - - - - 5bdfdd13 by Simon Peyton Jones at 2020-04-30T01:58:15-04:00 Add tests for #17873 - - - - - 19b701c2 by Simon Peyton Jones at 2020-04-30T07:30:13-04:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - 014ef4a3 by Matthew Pickering at 2020-04-30T07:30:50-04:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 2aa67611 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - 54dad3cf by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - 99ff8145 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 05b0a9fd by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 Remove OneShotInfo field of LFReEntrant, document OneShotInfo The field is only used in withNewTickyCounterFun and it's easier to directly pass a parameter for one-shot info to withNewTickyCounterFun instead of passing it via LFReEntrant. This also makes !2842 simpler. Other changes: - New Note (by SPJ) [OneShotInfo overview] added. - Arity argument of thunkCode removed as it's always 0. - - - - - a43620c6 by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 GHC.StgToCmm.Ticky: remove a few unused stuff - - - - - 780de9e1 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Use platform in Iface Binary - - - - - f8386c7b by Sylvain Henry at 2020-05-01T10:37:39-04:00 Refactor PprDebug handling If `-dppr-debug` is set, then PprUser and PprDump styles are silently replaced with PprDebug style. This was done in `mkUserStyle` and `mkDumpStyle` smart constructors. As a consequence they needed a DynFlags parameter. Now we keep the original PprUser and PprDump styles until they are used to create an `SDocContext`. I.e. the substitution is only performed in `initSDocContext`. - - - - - b3df9e78 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Remove PprStyle param of logging actions Use `withPprStyle` instead to apply a specific style to a SDoc. - - - - - de9fc995 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Fully remove PprDebug PprDebug was a pain to deal with consistently as it is implied by `-dppr-debug` but it isn't really a PprStyle. We remove it completely and query the appropriate SDoc flag instead (`sdocPprDebug`) via helpers (`getPprDebug` and its friends). - - - - - 8b51fcbd by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Only call checkSingle if we would report warnings - - - - - fd7ea0fe by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 7bfe9ac5 by Ben Gamari at 2020-05-03T04:41:33-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. - - - - - c560dd07 by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Move eventlog documentation users guide - - - - - 02543d5e by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Add documentation for non-moving GC events - - - - - b465dd45 by Alexis King at 2020-05-03T04:42:12-04:00 Flatten nested casts in the simple optimizer Normally, we aren’t supposed to generated any nested casts, since mkCast takes care to flatten them, but the simple optimizer didn’t use mkCast, so they could show up after inlining. This isn’t really a problem, since the simplifier will clean them up immediately anyway, but it can clutter the -ddump-ds output, and it’s an extremely easy fix. closes #18112 - - - - - 8bdc03d6 by Simon Peyton Jones at 2020-05-04T01:56:59-04:00 Don't return a panic in tcNestedSplice In GHC.Tc.Gen.Splice.tcNestedSplice we were returning a typechecked expression of "panic". That is usually OK, because the result is discarded. But it happens that tcApp now looks at the typechecked expression, trivially, to ask if it is tagToEnum. So being bottom is bad. Moreover a debug-trace might print it out. So better to return a civilised expression, even though it is usually discarded. - - - - - 0bf640b1 by Baldur Blöndal at 2020-05-04T01:57:36-04:00 Don't require parentheses around via type (`-XDerivingVia'). Fixes #18130". - - - - - 30272412 by Artem Pelenitsyn at 2020-05-04T13:19:59-04:00 Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) - - - - - b9f7c08f by jneira at 2020-05-04T13:20:37-04:00 Remove unused hs-boot file - - - - - 1d8f80cd by Sylvain Henry at 2020-05-05T03:22:46-04:00 Remove references to -package-key * remove references to `-package-key` which has been removed in 2016 (240ddd7c39536776e955e881d709bbb039b48513) * remove support for `-this-package-key` which has been deprecated at the same time - - - - - 7bc3a65b by Sylvain Henry at 2020-05-05T03:23:31-04:00 Remove SpecConstrAnnotation (#13681) This has been deprecated since 2013. Use GHC.Types.SPEC instead. Make GHC.Exts "not-home" for haddock Metric Decrease: haddock.base - - - - - 3c862f63 by DenisFrezzato at 2020-05-05T03:24:15-04:00 Fix Haskell98 short description in documentation - - - - - 2420c555 by Ryan Scott at 2020-05-05T03:24:53-04:00 Add regression tests for #16244, #16245, #16758 Commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70 ended up fixing quite a few bugs: * This commit fixes #16244 completely. A regression test has been added. * This commit fixes one program from #16245. (The program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211369 still panics, and the program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211400 still loops infinitely.) A regression test has been added for this program. * This commit fixes #16758. Accordingly, this patch removes the `expect_broken` label from the `T16758` test case, moves it from `should_compile` to `should_fail` (as it should produce an error message), and checks in the expected stderr. - - - - - 40c71c2c by Sylvain Henry at 2020-05-05T03:25:31-04:00 Fix colorized error messages (#18128) In b3df9e780fb2f5658412c644849cd0f1e6f50331 I broke colorized messages by using "dump" style instead of "user" style. This commits fixes it. - - - - - 7ab6ab09 by Richard Eisenberg at 2020-05-06T04:39:32-04:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG ------------------------- - - - - - 420b957d by Ben Gamari at 2020-05-06T04:40:08-04:00 rts: Zero block flags with -DZ Block flags are very useful for determining the state of a block. However, some block allocator users don't touch them, leading to misleading values. Ensure that we zero then when zero-on-gc is set. This is safe and makes the flags more useful during debugging. - - - - - 740b3b8d by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix incorrect failed_to_evac value during deadlock gc Previously we would incorrectly set the failed_to_evac flag if we evacuated a value due to a deadlock GC. This would cause us to mark more things as dirty than strictly necessary. It also turned up a nasty but which I will fix next. - - - - - b2d72c75 by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - 9f3e6884 by Zubin Duggal at 2020-05-06T04:41:08-04:00 Allow atomic update of NameCache in readHieFile The situation arises in ghcide where multiple different threads may need to update the name cache, therefore with the older interface it could happen that you start reading a hie file with name cache A and produce name cache A + B, but another thread in the meantime updated the namecache to A + C. Therefore if you write the new namecache you will lose the A' updates from the second thread. Updates haddock submodule - - - - - edec6a6c by Ryan Scott at 2020-05-06T04:41:57-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _)`. Fixes #18127. - - - - - a95e7fe0 by Ömer Sinan Ağacan at 2020-05-06T04:42:39-04:00 ELF linker: increment curSymbol after filling in fields of current entry The bug was introduced in a8b7cef4d45 which added a field to the `symbols` array elements and then updated this code incorrectly: - oc->symbols[curSymbol++] = nm; + oc->symbols[curSymbol++].name = nm; + oc->symbols[curSymbol].addr = symbol->addr; - - - - - cab1871a by Sylvain Henry at 2020-05-06T04:43:21-04:00 Move LeadingUnderscore into Platform (#17957) Avoid direct use of DynFlags to know if symbols must be prefixed by an underscore. - - - - - 94e7c563 by Sylvain Henry at 2020-05-06T04:43:21-04:00 Don't use DynFlags in showLinkerState (#17957) - - - - - 9afd9251 by Ryan Scott at 2020-05-06T04:43:58-04:00 Refactoring: Use bindSigTyVarsFV in rnMethodBinds `rnMethodBinds` was explicitly using `xoptM` to determine if `ScopedTypeVariables` is enabled before bringing type variables bound by the class/instance header into scope. However, this `xoptM` logic is already performed by the `bindSigTyVarsFV` function. This patch uses `bindSigTyVarsFV` in `rnMethodBinds` to reduce the number of places where we need to consult if `ScopedTypeVariables` is on. This is purely refactoring, and there should be no user-visible change in behavior. - - - - - 6f6d72b2 by Brian Foley at 2020-05-08T15:29:25-04:00 Remove further dead code found by a simple Python script. Avoid removing some functions that are part of an API even though they're not used in-tree at the moment. - - - - - 78bf8bf9 by Julien Debon at 2020-05-08T15:29:28-04:00 Add doc examples for Bifoldable See #17929 - - - - - 66f0a847 by Julien Debon at 2020-05-08T15:29:29-04:00 doc (Bitraversable): Add examples to Bitraversable * Add examples to Data.Bitraversable * Fix formatting for (,) in Bitraversable and Bifoldable * Fix mistake on bimapAccumR documentation See #17929 - - - - - 9749fe12 by Baldur Blöndal at 2020-05-08T15:29:32-04:00 Specify kind variables for inferred kinds in base. - - - - - 4e9aef9e by John Ericson at 2020-05-08T15:29:36-04:00 HsSigWcTypeScoping: Pull in documentation from stray location - - - - - f4d5c6df by John Ericson at 2020-05-08T15:29:36-04:00 Rename local `real_fvs` to `implicit_vs` It doesn't make sense to call the "free" variables we are about to implicitly bind the real ones. - - - - - 20570b4b by John Ericson at 2020-05-08T15:29:36-04:00 A few tiny style nits with renaming - Use case rather than guards that repeatedly scrutenize same thing. - No need for view pattern when `L` is fine. - Use type synnonym to convey the intent like elsewhere. - - - - - 09ac8de5 by John Ericson at 2020-05-08T15:29:36-04:00 Add `forAllOrNothing` function with note - - - - - bb35c0e5 by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Document lawlessness of Ap's Num instance - - - - - cdd229ff by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply suggestion to libraries/base/Data/Monoid.hs - - - - - 926d2aab by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply more suggestions from Simon Jakobi - - - - - 7a763cff by Adam Gundry at 2020-05-08T15:29:41-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. - - - - - 88e3c815 by Simon Peyton Jones at 2020-05-08T15:29:41-04:00 Fix specialisation for DFuns When specialising a DFun we must take care to saturate the unfolding. See Note [Specialising DFuns] in Specialise. Fixes #18120 - - - - - 86c77b36 by Greg Steuck at 2020-05-08T15:29:45-04:00 Remove unused SEGMENT_PROT_RWX It's been unused for a year and is problematic on any OS which requires W^X for security. - - - - - 9d97f4b5 by nineonine at 2020-05-08T15:30:03-04:00 Add test for #16167 - - - - - aa318338 by Ryan Scott at 2020-05-08T15:30:04-04:00 Bump exceptions submodule so that dist-boot is .gitignore'd `exceptions` is a stage-0 boot library as of commit 30272412fa437ab8e7a8035db94a278e10513413, which means that building `exceptions` in a GHC tree will generate a `dist-boot` directory. However, this directory was not specified in `exceptions`' `.gitignore` file, which causes it to dirty up the current `git` working directory. Accordingly, this bumps the `exceptions` submodule to commit ghc/packages/exceptions at 23c0b8a50d7592af37ca09beeec16b93080df98f, which adds `dist-boot` to the `.gitignore` file. - - - - - ea86360f by Ömer Sinan Ağacan at 2020-05-08T15:30:30-04:00 Linker.c: initialize n_symbols of ObjectCode with other fields - - - - - 7e69652d by Andreas Klebinger at 2020-05-10T15:35:44-04:00 When deriving Eq always use tag based comparisons for nullary constructors - - - - - 5dffe2a6 by Andreas Klebinger at 2020-05-10T15:35:45-04:00 Use dataToTag# instead of getTag in deriving code. getTag resides in base so is not useable in ghc-prim. Where we need it. - - - - - 9827d3a3 by Andreas Klebinger at 2020-05-10T15:39:01-04:00 Eliminate generated Con2Tag bindings completely - - - - - d8765105 by Ben Gamari at 2020-05-10T15:39:01-04:00 Use pointer tag in dataToTag# While looking at !2873 I noticed that dataToTag# previously didn't look at a pointer's tag to determine its constructor. To be fair, there is a bit of a trade-off here: using the pointer tag requires a bit more code and another branch. On the other hand, it allows us to eliminate looking at the info table in many cases (especially now since we tag large constructor families; see #14373). - - - - - 71e8849e by Ben Gamari at 2020-05-10T15:39:01-04:00 Avoid unnecessary entry - - - - - c5130822 by Ben Gamari at 2020-05-10T15:42:32-04:00 hi - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/linters/check-cpp.py - CODEOWNERS - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - compiler/prelude/PrelNames.hs-boot → compiler/GHC/Builtin/Names.hs-boot - compiler/prelude/THNames.hs → compiler/GHC/Builtin/Names/TH.hs - compiler/prelude/PrimOp.hs → compiler/GHC/Builtin/PrimOps.hs - + compiler/GHC/Builtin/PrimOps.hs-boot - compiler/prelude/TysWiredIn.hs → compiler/GHC/Builtin/Types.hs - compiler/prelude/TysWiredIn.hs-boot → compiler/GHC/Builtin/Types.hs-boot - compiler/typecheck/TcTypeNats.hs → compiler/GHC/Builtin/Types/Literals.hs - compiler/prelude/TysPrim.hs → compiler/GHC/Builtin/Types/Prim.hs - compiler/prelude/KnownUniques.hs → compiler/GHC/Builtin/Uniques.hs - compiler/prelude/KnownUniques.hs-boot → compiler/GHC/Builtin/Uniques.hs-boot - compiler/prelude/PrelInfo.hs → compiler/GHC/Builtin/Utils.hs - compiler/prelude/primops.txt.pp → compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.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/BlockId.hs-boot - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8f26e408397dcb09d994bda807750a1de07f6a48...c51308222f031c0dbf997ef5edcc8799e3287bc4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8f26e408397dcb09d994bda807750a1de07f6a48...c51308222f031c0dbf997ef5edcc8799e3287bc4 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 11 00:33:37 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 10 May 2020 20:33:37 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 23 commits: rts/CNF: Fix fixup comparison function Message-ID: <5eb89d61701ce_6167119f856010235648@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: bfd49c8d by Ben Gamari at 2020-05-10T20:32:22-04:00 rts/CNF: Fix fixup comparison function Previously we would implicitly convert the difference between two words to an int, resulting in an integer overflow on 64-bit machines. Fixes #16992 - - - - - f6dd77d6 by Ömer Sinan Ağacan at 2020-05-10T20:32:38-04:00 Pack some of IdInfo fields into a bit field This reduces residency of compiler quite a bit on some programs. Example stats when building T10370: Before: 2,871,242,832 bytes allocated in the heap 4,693,328,008 bytes copied during GC 33,941,448 bytes maximum residency (276 sample(s)) 375,976 bytes maximum slop 83 MiB total memory in use (0 MB lost due to fragmentation) After: 2,858,897,344 bytes allocated in the heap 4,629,255,440 bytes copied during GC 32,616,624 bytes maximum residency (278 sample(s)) 314,400 bytes maximum slop 80 MiB total memory in use (0 MB lost due to fragmentation) So -3.9% residency, -1.3% bytes copied and -0.4% allocations. Fixes #17497 Metric Decrease: T9233 T9675 - - - - - 9e064973 by Simon Peyton Jones at 2020-05-10T20:32:39-04:00 Avoid useless w/w split This patch is just a tidy-up for the post-strictness-analysis worker wrapper split. Consider f x = x Strictnesss analysis does not lead to a w/w split, so the obvious thing is to leave it 100% alone. But actually, because the RHS is small, we ended up adding a StableUnfolding for it. There is some reason to do this if we choose /not/ do to w/w on the grounds that the function is small. See Note [Don't w/w inline small non-loop-breaker things] But there is no reason if we would not have done w/w anyway. This patch just moves the conditional to later. Easy. This does move soem -ddump-simpl printouts around a bit. I also discovered that the previous code was overwritten an InlineCompulsory with InlineStable, which is utterly wrong. That in turn meant that some default methods (marked InlineCompulsory) were getting their InlineCompulsory squashed. This patch fixes that bug --- but of course that does mean a bit more inlining! Metric Decrease: T9233 T9675 Metric Increase: T12707 T3064 T4029 T9872b T9872d haddock.Cabal - - - - - cc9445e3 by Ben Gamari at 2020-05-10T20:32:40-04:00 get-win32-tarballs: Fix base URL Revert a change previously made for testing purposes. - - - - - 6e42decb by Ben Gamari at 2020-05-10T20:32:40-04:00 get-win32-tarballs: Improve diagnostics output - - - - - 71d99c90 by Simon Jakobi at 2020-05-10T20:32:41-04:00 docs: Add examples for Data.Semigroup.Arg{Min,Max} Context: #17153 - - - - - 7e57d5ed by Baldur Blöndal at 2020-05-10T20:32:43-04:00 Predicate, Equivalence derive via `.. -> a -> All' - - - - - 19d1024b by Emeka Nkurumeh at 2020-05-10T20:32:45-04:00 fix printf warning when using with ghc with clang on mingw - - - - - 951e10e1 by Daniel Gröber at 2020-05-10T20:32:48-04:00 Fix non power-of-two Storable.alignment in Capi_Ctype tests Alignments passed to alloca and friends must be a power of two for the code in allocatePinned to work properly. Commit 41230e2601 ("Zero out pinned block alignment slop when profiling") introduced an ASSERT for this but this test was still violating it. - - - - - 5fca6bcd by Daniel Gröber at 2020-05-10T20:32:48-04:00 Improve ByteArray# documentation regarding alignment - - - - - 1ca53bf3 by Daniel Gröber at 2020-05-10T20:32:48-04:00 Document word-size rounding of ByteArray# memory (Fix #14731) - - - - - acfe00ef by Daniel Gröber at 2020-05-10T20:32:49-04:00 Throw IOError when allocaBytesAligned gets non-power-of-two align - - - - - b776404d by Richard Eisenberg at 2020-05-10T20:32:49-04:00 Improve Note [The flattening story] - - - - - b373a2d5 by Artem Pelenitsyn at 2020-05-10T20:32:53-04:00 Don't reload environment files on every setSessionDynFlags Makes `interpretPackageEnv` (which loads envirinment files) a part of `parseDynamicFlags` (parsing command-line arguments, which is typically done once) instead of `setSessionDynFlags` (which is typically called several times). Making several (transitive) calls to `interpretPackageEnv`, as before, caused #18125 #16318, which should be fixed now. - - - - - c1cb92cb by Ben Gamari at 2020-05-10T20:32:53-04:00 GHC.Cmm.Opt: Handle MO_XX_Conv This MachOp was introduced by 2c959a1894311e59cd2fd469c1967491c1e488f3 but a wildcard match in cmmMachOpFoldM hid the fact that it wasn't handled. Ideally we would eliminate the match but this appears to be a larger task. Fixes #18141. - - - - - dc1708b5 by Hécate at 2020-05-10T20:33:01-04:00 fix(documentation): Fix the RST links to GHC.Prim - - - - - 2fc92c0c by Baldur Blöndal at 2020-05-10T20:33:07-04:00 Document (->) using inferred quantification for its runtime representations. Fixes #18142. - - - - - 00966e51 by Takenobu Tani at 2020-05-10T20:33:13-04:00 Tweak man page for ghc command This commit updates the ghc command's man page as followings: * Enable `man_show_urls` to show URL addresses in the `DESCRIPTION` section of ghc.rst, because sphinx currently removes hyperlinks for man pages. * Add a `SEE ALSO` section to point to the GHC homepage - - - - - 66244728 by Takenobu Tani at 2020-05-10T20:33:22-04:00 GHCi: Add link to the user's guide in help message This commit adds a link to the user's guide in ghci's `:help` message. Newcomers could easily reach to details of ghci. - - - - - 13f900b2 by Jeff Happily at 2020-05-10T20:33:26-04:00 Handle single unused import - - - - - 6df1ceec by Ben Gamari at 2020-05-10T20:33:27-04:00 Ensure that printMinimalImports closes handle Fixes #18166. - - - - - b2377822 by Ben Gamari at 2020-05-10T20:33:27-04:00 testsuite: Print sign of performance changes Executes the minor formatting change in the tabulated performance changes suggested in #18135. - - - - - b1a4f386 by Ben Gamari at 2020-05-10T20:33:28-04:00 hadrian: Tell testsuite driver about LLVM availability This reflects the logic present in the Make build system into Hadrian. Fixes #18167. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Opt/WorkWrap.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Tc/Solver/Flatten.hs - compiler/GHC/Types/Id/Info.hs - docs/users_guide/conf.py - docs/users_guide/editing-guide.rst - docs/users_guide/exts/ffi.rst - docs/users_guide/exts/primitives.rst - docs/users_guide/ghc.rst - ghc/GHCi/UI.hs - hadrian/src/Settings/Builders/RunTest.hs - includes/rts/Messages.h - libraries/base/Data/Functor/Contravariant.hs - libraries/base/Data/Semigroup.hs - libraries/base/Foreign/Marshal/Alloc.hs - libraries/base/Foreign/Storable.hs - libraries/base/changelog.md - + libraries/ghc-compact/tests/T16992.hs - + libraries/ghc-compact/tests/T16992.stdout - libraries/ghc-compact/tests/all.T - mk/get-win32-tarballs.py - rts/sm/CNF.c The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7578a90de2e3c2b3c1e81a54618afe0c26a218ee...b1a4f3868b469cddb4bd198089b4075c184d9eb3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7578a90de2e3c2b3c1e81a54618afe0c26a218ee...b1a4f3868b469cddb4bd198089b4075c184d9eb3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 11 00:46:47 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 10 May 2020 20:46:47 -0400 Subject: [Git][ghc/ghc][wip/lower-tc-tracing-cost] Avoid unnecessary allocations due to tracing utilities Message-ID: <5eb8a0773a4ea_616711a31edc102664ce@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/lower-tc-tracing-cost at Glasgow Haskell Compiler / GHC Commits: 8be2fb78 by Ben Gamari at 2020-05-10T20:46:27-04:00 Avoid unnecessary allocations due to tracing utilities While ticky-profiling the typechecker I noticed that hundreds of millions of SDocs are being allocated just in case -ddump-*-trace is enabled. This is awful. We avoid this by ensuring that the dump flag check is inlined into the call site, ensuring that the tracing document needn't be allocated unless it's actually needed. See Note [INLINE conditional tracing utilities] for details. Fixes #18168. Metric Decrease: T9961 - - - - - 7 changed files: - compiler/GHC/Core/Opt/Simplify/Monad.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/Tc/Solver/Flatten.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Utils/Error.hs Changes: ===================================== compiler/GHC/Core/Opt/Simplify/Monad.hs ===================================== @@ -143,6 +143,7 @@ traceSmpl herald doc ; liftIO $ Err.dumpIfSet_dyn dflags Opt_D_dump_simpl_trace "Simpl Trace" FormatText (hang (text herald) 2 doc) } +{-# INLINE traceSmpl #-} -- see Note [INLINE conditional tracing utilities] {- ************************************************************************ ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -1279,7 +1279,10 @@ callSiteInline dflags id active_unfolding lone_variable arg_infos cont_info -- | Report the inlining of an identifier's RHS to the user, if requested. traceInline :: DynFlags -> Id -> String -> SDoc -> a -> a -traceInline dflags inline_id str doc result = +traceInline dflags inline_id str doc result + -- We take care to ensure that doc is used in only one branch, ensuring that + -- the simplifier can push its allocation into the branch. See Note [INLINE + -- conditional tracing utilities]. | enable = traceAction dflags str doc result | otherwise = result where @@ -1288,6 +1291,9 @@ traceInline dflags inline_id str doc result = = True | Just prefix <- inlineCheck dflags = prefix `isPrefixOf` occNameString (getOccName inline_id) + | otherwise + = False +{-# INLINE traceInline #-} -- see Note [INLINE conditional tracing utilities] tryUnfolding :: DynFlags -> Id -> Bool -> [ArgSummary] -> CallCtxt -> CoreExpr -> Bool -> Bool -> UnfoldingGuidance ===================================== compiler/GHC/HsToCore/PmCheck/Oracle.hs ===================================== @@ -89,6 +89,7 @@ tracePm herald doc = do printer <- mkPrintUnqualifiedDs liftIO $ dumpIfSet_dyn_printer printer dflags Opt_D_dump_ec_trace "" FormatText (text herald $$ (nest 2 doc)) +{-# INLINE tracePm #-} -- see Note [INLINE conditional tracing utilities] -- | Generate a fresh `Id` of a given type mkPmId :: Type -> DsM Id ===================================== compiler/GHC/Tc/Solver/Flatten.hs ===================================== @@ -543,6 +543,7 @@ runFlatten mode loc flav eq_rel thing_inside traceFlat :: String -> SDoc -> FlatM () traceFlat herald doc = liftTcS $ traceTcS herald doc +{-# INLINE traceFlat #-} -- see Note [INLINE conditional tracing utilities] getFlatEnvField :: (FlattenEnv -> a) -> FlatM a getFlatEnvField accessor ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -2733,6 +2733,7 @@ panicTcS doc = pprPanic "GHC.Tc.Solver.Canonical" doc traceTcS :: String -> SDoc -> TcS () traceTcS herald doc = wrapTcS (TcM.traceTc herald doc) +{-# INLINE traceTcS #-} -- see Note [INLINE conditional tracing utilities] runTcPluginTcS :: TcPluginM a -> TcS a runTcPluginTcS m = wrapTcS . runTcPluginM m =<< getTcEvBindsVar @@ -2751,6 +2752,7 @@ bumpStepCountTcS = TcS $ \env -> do { let ref = tcs_count env csTraceTcS :: SDoc -> TcS () csTraceTcS doc = wrapTcS $ csTraceTcM (return doc) +{-# INLINE csTraceTcS #-} -- see Note [INLINE conditional tracing utilities] traceFireTcS :: CtEvidence -> SDoc -> TcS () -- Dump a rule-firing trace @@ -2763,6 +2765,7 @@ traceFireTcS ev doc text "d:" <> ppr (ctLocDepth (ctEvLoc ev))) <+> doc <> colon) 4 (ppr ev)) } +{-# INLINE traceFireTcS #-} -- see Note [INLINE conditional tracing utilities] csTraceTcM :: TcM SDoc -> TcM () -- Constraint-solver tracing, -ddump-cs-trace @@ -2775,6 +2778,7 @@ csTraceTcM mk_doc (dumpOptionsFromFlag Opt_D_dump_cs_trace) "" FormatText msg }) } +{-# INLINE csTraceTcM #-} -- see Note [INLINE conditional tracing utilities] runTcS :: TcS a -- What to run -> TcM (a, EvBindMap) ===================================== compiler/GHC/Tc/Utils/Monad.hs ===================================== @@ -490,22 +490,28 @@ unsetWOptM flag = whenDOptM :: DumpFlag -> TcRnIf gbl lcl () -> TcRnIf gbl lcl () whenDOptM flag thing_inside = do b <- doptM flag when b thing_inside +{-# INLINE whenDOptM #-} -- see Note [INLINE conditional tracing utilities] + whenGOptM :: GeneralFlag -> TcRnIf gbl lcl () -> TcRnIf gbl lcl () whenGOptM flag thing_inside = do b <- goptM flag when b thing_inside +{-# INLINE whenGOptM #-} -- see Note [INLINE conditional tracing utilities] whenWOptM :: WarningFlag -> TcRnIf gbl lcl () -> TcRnIf gbl lcl () whenWOptM flag thing_inside = do b <- woptM flag when b thing_inside +{-# INLINE whenWOptM #-} -- see Note [INLINE conditional tracing utilities] whenXOptM :: LangExt.Extension -> TcRnIf gbl lcl () -> TcRnIf gbl lcl () whenXOptM flag thing_inside = do b <- xoptM flag when b thing_inside +{-# INLINE whenXOptM #-} -- see Note [INLINE conditional tracing utilities] unlessXOptM :: LangExt.Extension -> TcRnIf gbl lcl () -> TcRnIf gbl lcl () unlessXOptM flag thing_inside = do b <- xoptM flag unless b thing_inside +{-# INLINE unlessXOptM #-} -- see Note [INLINE conditional tracing utilities] getGhcMode :: TcRnIf gbl lcl GhcMode getGhcMode = do { env <- getTopEnv; return (ghcMode (hsc_dflags env)) } @@ -662,39 +668,64 @@ updTcRef ref fn = liftIO $ do { old <- readIORef ref ************************************************************************ -} +-- Note [INLINE conditional tracing utilities] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- In general we want to optimise for the case where tracing is not enabled. +-- To ensure this happens, we ensure that traceTc and friends are inlined; this +-- ensures that the allocation of the document can be pushed into the tracing +-- path, keeping the non-traced path free of this extraneous work. For +-- instance, instead of +-- +-- let thunk = ... +-- in if doTracing +-- then emitTraceMsg thunk +-- else return () +-- +-- where the conditional is buried in a non-inlined utility function (e.g. +-- traceTc), we would rather have: +-- +-- if doTracing +-- then let thunk = ... +-- in emitTraceMsg thunk +-- else return () +-- +-- See #18168. +-- -- Typechecker trace traceTc :: String -> SDoc -> TcRn () -traceTc = - labelledTraceOptTcRn Opt_D_dump_tc_trace +traceTc herald doc = + labelledTraceOptTcRn Opt_D_dump_tc_trace herald doc +{-# INLINE traceTc #-} -- see Note [INLINE conditional tracing utilities] -- Renamer Trace traceRn :: String -> SDoc -> TcRn () -traceRn = - labelledTraceOptTcRn Opt_D_dump_rn_trace +traceRn herald doc = + labelledTraceOptTcRn Opt_D_dump_rn_trace herald doc +{-# INLINE traceRn #-} -- see Note [INLINE conditional tracing utilities] -- | Trace when a certain flag is enabled. This is like `traceOptTcRn` -- but accepts a string as a label and formats the trace message uniformly. labelledTraceOptTcRn :: DumpFlag -> String -> SDoc -> TcRn () -labelledTraceOptTcRn flag herald doc = do - traceOptTcRn flag (formatTraceMsg herald doc) +labelledTraceOptTcRn flag herald doc = + traceOptTcRn flag (formatTraceMsg herald doc) +{-# INLINE labelledTraceOptTcRn #-} -- see Note [INLINE conditional tracing utilities] formatTraceMsg :: String -> SDoc -> SDoc formatTraceMsg herald doc = hang (text herald) 2 doc --- | Trace if the given 'DumpFlag' is set. traceOptTcRn :: DumpFlag -> SDoc -> TcRn () traceOptTcRn flag doc = do - dflags <- getDynFlags - when (dopt flag dflags) $ + whenDOptM flag $ dumpTcRn False (dumpOptionsFromFlag flag) "" FormatText doc +{-# INLINE traceOptTcRn #-} -- see Note [INLINE conditional tracing utilities] -- | Dump if the given 'DumpFlag' is set. dumpOptTcRn :: DumpFlag -> String -> DumpFormat -> SDoc -> TcRn () dumpOptTcRn flag title fmt doc = do - dflags <- getDynFlags - when (dopt flag dflags) $ + whenDOptM flag $ dumpTcRn False (dumpOptionsFromFlag flag) title fmt doc +{-# INLINE dumpOptTcRn #-} -- see Note [INLINE conditional tracing utilities] -- | Unconditionally dump some trace output -- @@ -746,13 +777,16 @@ e.g. are unaffected by -dump-to-file. traceIf, traceHiDiffs :: SDoc -> TcRnIf m n () traceIf = traceOptIf Opt_D_dump_if_trace traceHiDiffs = traceOptIf Opt_D_dump_hi_diffs - +{-# INLINE traceIf #-} +{-# INLINE traceHiDiffs #-} + -- see Note [INLINE conditional tracing utilities] traceOptIf :: DumpFlag -> SDoc -> TcRnIf m n () traceOptIf flag doc = whenDOptM flag $ -- No RdrEnv available, so qualify everything do { dflags <- getDynFlags ; liftIO (putMsg dflags doc) } +{-# INLINE traceOptIf #-} -- see Note [INLINE conditional tracing utilities] {- ************************************************************************ ===================================== compiler/GHC/Utils/Error.hs ===================================== @@ -438,20 +438,27 @@ doIfSet_dyn dflags flag action | gopt flag dflags = action dumpIfSet :: DynFlags -> Bool -> String -> SDoc -> IO () dumpIfSet dflags flag hdr doc | not flag = return () - | otherwise = putLogMsg dflags - NoReason - SevDump - noSrcSpan - (withPprStyle defaultDumpStyle - (mkDumpDoc hdr doc)) - --- | a wrapper around 'dumpAction'. + | otherwise = doDump dflags hdr doc + where + -- Explicitly bind this so it can float out and we don't duplicate this code + -- needlessly due to the INLINE below. + doDump dflags hdr doc = + putLogMsg dflags + NoReason + SevDump + noSrcSpan + (withPprStyle defaultDumpStyle + (mkDumpDoc hdr doc)) +{-# INLINE dumpIfSet #-} -- see Note [INLINE conditional tracing utilities] + +-- | A wrapper around 'dumpAction'. -- First check whether the dump flag is set -- Do nothing if it is unset dumpIfSet_dyn :: DynFlags -> DumpFlag -> String -> DumpFormat -> SDoc -> IO () dumpIfSet_dyn = dumpIfSet_dyn_printer alwaysQualify +{-# INLINE dumpIfSet_dyn #-} -- see Note [INLINE conditional tracing utilities] --- | a wrapper around 'dumpAction'. +-- | A wrapper around 'dumpAction'. -- First check whether the dump flag is set -- Do nothing if it is unset -- @@ -462,6 +469,7 @@ dumpIfSet_dyn_printer printer dflags flag hdr fmt doc = when (dopt flag dflags) $ do let sty = mkDumpStyle printer dumpAction dflags sty (dumpOptionsFromFlag flag) hdr fmt doc +{-# INLINE dumpIfSet_dyn_printer #-} -- see Note [INLINE conditional tracing utilities] mkDumpDoc :: String -> SDoc -> SDoc mkDumpDoc hdr doc @@ -608,6 +616,7 @@ ifVerbose :: DynFlags -> Int -> IO () -> IO () ifVerbose dflags val act | verbosity dflags >= val = act | otherwise = return () +{-# INLINE ifVerbose #-} -- see Note [INLINE conditional tracing utilities] errorMsg :: DynFlags -> MsgDoc -> IO () errorMsg dflags msg @@ -778,6 +787,7 @@ debugTraceMsg :: DynFlags -> Int -> MsgDoc -> IO () debugTraceMsg dflags val msg = ifVerbose dflags val $ logInfo dflags (withPprStyle defaultDumpStyle msg) +{-# INLINE debugTraceMsg #-} -- see Note [INLINE conditional tracing utilities] putMsg :: DynFlags -> MsgDoc -> IO () putMsg dflags msg = logInfo dflags (withPprStyle defaultUserStyle msg) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8be2fb78b08d8a5741f07588cef65100d32a455c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8be2fb78b08d8a5741f07588cef65100d32a455c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 11 01:25:14 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 10 May 2020 21:25:14 -0400 Subject: [Git][ghc/ghc][wip/T18151] 2 commits: testsuite: Add test for #18151 Message-ID: <5eb8a97a76254_61673f8103f8794c102749b5@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18151 at Glasgow Haskell Compiler / GHC Commits: c32cbf39 by Ben Gamari at 2020-05-10T21:24:20-04:00 testsuite: Add test for #18151 - - - - - e4ec8175 by Ben Gamari at 2020-05-10T21:24:59-04:00 HsToCore: Eta expand left sections Strangely, the comment next to this code already alluded to the fact that even simply eta-expanding will sacrifice laziness. It's quite unclear how we regressed so far. See #18151. - - - - - 4 changed files: - compiler/GHC/HsToCore/Expr.hs - + testsuite/tests/deSugar/should_run/T18151.hs - + testsuite/tests/deSugar/should_run/T18151.stdout - testsuite/tests/deSugar/should_run/all.T Changes: ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -338,26 +338,25 @@ Then we get That 'g' in the 'in' part is an evidence variable, and when converting to core it must become a CO. + +Note [Desugaring operator sections] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Operator sections. At first it looks as if we can convert -\begin{verbatim} - (expr op) -\end{verbatim} + (expr op) to -\begin{verbatim} - \x -> op expr x -\end{verbatim} + \x -> op expr x But no! expr might be a redex, and we can lose laziness badly this way. Consider -\begin{verbatim} - map (expr op) xs -\end{verbatim} -for example. So we convert instead to -\begin{verbatim} - let y = expr in \x -> op y x -\end{verbatim} + map (expr op) xs +for example. + +So we convert instead to + let y = expr in \x -> op y x If \tr{expr} is actually just a variable, say, then the simplifier will sort it out. + +See #18151. -} dsExpr e@(OpApp _ e1 op e2) @@ -366,17 +365,24 @@ dsExpr e@(OpApp _ e1 op e2) ; dsWhenNoErrs (mapM dsLExprNoLP [e1, e2]) (\exprs' -> mkCoreAppsDs (text "opapp" <+> ppr e) op' exprs') } -dsExpr (SectionL _ expr op) -- Desugar (e !) to ((!) e) - = do { op' <- dsLExpr op - ; dsWhenNoErrs (dsLExprNoLP expr) - (\expr' -> mkCoreAppDs (text "sectionl" <+> ppr expr) op' expr') } +-- dsExpr (SectionL op expr) === (expr `op`) ~> \y -> op expr y +-- +-- See Note [Desugaring operator sections] +dsExpr (SectionL _ expr op) = do + core_op <- dsLExpr op + let (x_ty:y_ty:_, _) = splitFunTys (exprType core_op) + x_core <- dsLExpr expr + dsWhenNoErrs (mapM newSysLocalDsNoLP [x_ty, y_ty]) + (\[x_id, y_id] -> bindNonRec x_id x_core $ + Lam y_id (mkCoreAppsDs (text "sectionl" <+> ppr e) + core_op [Var x_id, Var y_id])) --- dsLExpr (SectionR op expr) -- \ x -> op x expr +-- dsExpr (SectionR op expr) === (`op` expr) ~> \x -> op x expr +-- +-- See Note [Desugaring operator sections] dsExpr e@(SectionR _ op expr) = do core_op <- dsLExpr op - -- for the type of x, we need the type of op's 2nd argument let (x_ty:y_ty:_, _) = splitFunTys (exprType core_op) - -- See comment with SectionL y_core <- dsLExpr expr dsWhenNoErrs (mapM newSysLocalDsNoLP [x_ty, y_ty]) (\[x_id, y_id] -> bindNonRec y_id y_core $ ===================================== testsuite/tests/deSugar/should_run/T18151.hs ===================================== @@ -0,0 +1,10 @@ +-- According to the Report this should reduce to (). However, in #18151 it was +-- reported that GHC bottoms. +x :: () +x = seq (True `undefined`) () +{-# NOINLINE x #-} + +main :: IO () +main = do + print x + ===================================== testsuite/tests/deSugar/should_run/T18151.stdout ===================================== @@ -0,0 +1 @@ +() \ No newline at end of file ===================================== testsuite/tests/deSugar/should_run/all.T ===================================== @@ -63,3 +63,4 @@ test('T11601', exit_code(1), compile_and_run, ['']) test('T11747', normal, compile_and_run, ['-dcore-lint']) test('T12595', normal, compile_and_run, ['']) test('T13285', normal, compile_and_run, ['']) +test('T18151', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/75efdfd8994f0c6d19112a22e0b651271fd10053...e4ec81757288d7003eb8407e529d0a1a64ebc040 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/75efdfd8994f0c6d19112a22e0b651271fd10053...e4ec81757288d7003eb8407e529d0a1a64ebc040 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 11 01:53:44 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 10 May 2020 21:53:44 -0400 Subject: [Git][ghc/ghc][wip/T18151] HsToCore: Eta expand left sections Message-ID: <5eb8b028dcdde_616711922e9c102783a8@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18151 at Glasgow Haskell Compiler / GHC Commits: 9ccb4dba by Ben Gamari at 2020-05-10T21:53:34-04:00 HsToCore: Eta expand left sections Strangely, the comment next to this code already alluded to the fact that even simply eta-expanding will sacrifice laziness. It's quite unclear how we regressed so far. See #18151. - - - - - 2 changed files: - compiler/GHC/HsToCore/Expr.hs - testsuite/tests/deSugar/should_run/all.T Changes: ===================================== compiler/GHC/HsToCore/Expr.hs ===================================== @@ -338,26 +338,25 @@ Then we get That 'g' in the 'in' part is an evidence variable, and when converting to core it must become a CO. + +Note [Desugaring operator sections] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Operator sections. At first it looks as if we can convert -\begin{verbatim} - (expr op) -\end{verbatim} + (expr op) to -\begin{verbatim} - \x -> op expr x -\end{verbatim} + \x -> op expr x But no! expr might be a redex, and we can lose laziness badly this way. Consider -\begin{verbatim} - map (expr op) xs -\end{verbatim} -for example. So we convert instead to -\begin{verbatim} - let y = expr in \x -> op y x -\end{verbatim} + map (expr op) xs +for example. + +So we convert instead to + let y = expr in \x -> op y x If \tr{expr} is actually just a variable, say, then the simplifier will sort it out. + +See #18151. -} dsExpr e@(OpApp _ e1 op e2) @@ -366,17 +365,24 @@ dsExpr e@(OpApp _ e1 op e2) ; dsWhenNoErrs (mapM dsLExprNoLP [e1, e2]) (\exprs' -> mkCoreAppsDs (text "opapp" <+> ppr e) op' exprs') } -dsExpr (SectionL _ expr op) -- Desugar (e !) to ((!) e) - = do { op' <- dsLExpr op - ; dsWhenNoErrs (dsLExprNoLP expr) - (\expr' -> mkCoreAppDs (text "sectionl" <+> ppr expr) op' expr') } +-- dsExpr (SectionL op expr) === (expr `op`) ~> \y -> op expr y +-- +-- See Note [Desugaring operator sections] +dsExpr e@(SectionL _ expr op) = do + core_op <- dsLExpr op + let (x_ty:y_ty:_, _) = splitFunTys (exprType core_op) + x_core <- dsLExpr expr + dsWhenNoErrs (mapM newSysLocalDsNoLP [x_ty, y_ty]) + (\[x_id, y_id] -> bindNonRec x_id x_core $ + Lam y_id (mkCoreAppsDs (text "sectionl" <+> ppr e) + core_op [Var x_id, Var y_id])) --- dsLExpr (SectionR op expr) -- \ x -> op x expr +-- dsExpr (SectionR op expr) === (`op` expr) ~> \x -> op x expr +-- +-- See Note [Desugaring operator sections] dsExpr e@(SectionR _ op expr) = do core_op <- dsLExpr op - -- for the type of x, we need the type of op's 2nd argument let (x_ty:y_ty:_, _) = splitFunTys (exprType core_op) - -- See comment with SectionL y_core <- dsLExpr expr dsWhenNoErrs (mapM newSysLocalDsNoLP [x_ty, y_ty]) (\[x_id, y_id] -> bindNonRec y_id y_core $ ===================================== testsuite/tests/deSugar/should_run/all.T ===================================== @@ -63,4 +63,4 @@ test('T11601', exit_code(1), compile_and_run, ['']) test('T11747', normal, compile_and_run, ['-dcore-lint']) test('T12595', normal, compile_and_run, ['']) test('T13285', normal, compile_and_run, ['']) -test('T18151', expect_broken(18151), compile_and_run, ['']) +test('T18151', normal, compile_and_run, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9ccb4dbafcf433e6bc2ec62ae08827309ee66582 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9ccb4dbafcf433e6bc2ec62ae08827309ee66582 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 11 06:04:59 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Mon, 11 May 2020 02:04:59 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 26 commits: rts/CNF: Fix fixup comparison function Message-ID: <5eb8eb0b1af80_61673f819aad978c1031476c@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 7363965a by Ben Gamari at 2020-05-11T02:04:24-04:00 rts/CNF: Fix fixup comparison function Previously we would implicitly convert the difference between two words to an int, resulting in an integer overflow on 64-bit machines. Fixes #16992 - - - - - 146a9287 by Ömer Sinan Ağacan at 2020-05-11T02:04:26-04:00 Pack some of IdInfo fields into a bit field This reduces residency of compiler quite a bit on some programs. Example stats when building T10370: Before: 2,871,242,832 bytes allocated in the heap 4,693,328,008 bytes copied during GC 33,941,448 bytes maximum residency (276 sample(s)) 375,976 bytes maximum slop 83 MiB total memory in use (0 MB lost due to fragmentation) After: 2,858,897,344 bytes allocated in the heap 4,629,255,440 bytes copied during GC 32,616,624 bytes maximum residency (278 sample(s)) 314,400 bytes maximum slop 80 MiB total memory in use (0 MB lost due to fragmentation) So -3.9% residency, -1.3% bytes copied and -0.4% allocations. Fixes #17497 Metric Decrease: T9233 T9675 - - - - - e5f269f1 by Simon Peyton Jones at 2020-05-11T02:04:27-04:00 Avoid useless w/w split This patch is just a tidy-up for the post-strictness-analysis worker wrapper split. Consider f x = x Strictnesss analysis does not lead to a w/w split, so the obvious thing is to leave it 100% alone. But actually, because the RHS is small, we ended up adding a StableUnfolding for it. There is some reason to do this if we choose /not/ do to w/w on the grounds that the function is small. See Note [Don't w/w inline small non-loop-breaker things] But there is no reason if we would not have done w/w anyway. This patch just moves the conditional to later. Easy. This does move soem -ddump-simpl printouts around a bit. I also discovered that the previous code was overwritten an InlineCompulsory with InlineStable, which is utterly wrong. That in turn meant that some default methods (marked InlineCompulsory) were getting their InlineCompulsory squashed. This patch fixes that bug --- but of course that does mean a bit more inlining! Metric Decrease: T9233 T9675 Metric Increase: T12707 T3064 T4029 T9872b T9872d haddock.Cabal - - - - - 81ef116a by Ben Gamari at 2020-05-11T02:04:28-04:00 get-win32-tarballs: Fix base URL Revert a change previously made for testing purposes. - - - - - ad148c76 by Ben Gamari at 2020-05-11T02:04:28-04:00 get-win32-tarballs: Improve diagnostics output - - - - - 5370ccbb by Simon Jakobi at 2020-05-11T02:04:29-04:00 docs: Add examples for Data.Semigroup.Arg{Min,Max} Context: #17153 - - - - - f2c06dc3 by Baldur Blöndal at 2020-05-11T02:04:30-04:00 Predicate, Equivalence derive via `.. -> a -> All' - - - - - a865c756 by Emeka Nkurumeh at 2020-05-11T02:04:32-04:00 fix printf warning when using with ghc with clang on mingw - - - - - a1bd3e50 by Daniel Gröber at 2020-05-11T02:04:37-04:00 Fix non power-of-two Storable.alignment in Capi_Ctype tests Alignments passed to alloca and friends must be a power of two for the code in allocatePinned to work properly. Commit 41230e2601 ("Zero out pinned block alignment slop when profiling") introduced an ASSERT for this but this test was still violating it. - - - - - 335e66d7 by Daniel Gröber at 2020-05-11T02:04:37-04:00 Improve ByteArray# documentation regarding alignment - - - - - 21123bb2 by Daniel Gröber at 2020-05-11T02:04:37-04:00 Document word-size rounding of ByteArray# memory (Fix #14731) - - - - - fb6d3e12 by Daniel Gröber at 2020-05-11T02:04:37-04:00 Throw IOError when allocaBytesAligned gets non-power-of-two align - - - - - de9e1eff by Richard Eisenberg at 2020-05-11T02:04:38-04:00 Improve Note [The flattening story] - - - - - 9878e607 by Artem Pelenitsyn at 2020-05-11T02:04:39-04:00 Don't reload environment files on every setSessionDynFlags Makes `interpretPackageEnv` (which loads envirinment files) a part of `parseDynamicFlags` (parsing command-line arguments, which is typically done once) instead of `setSessionDynFlags` (which is typically called several times). Making several (transitive) calls to `interpretPackageEnv`, as before, caused #18125 #16318, which should be fixed now. - - - - - b83468f9 by Ben Gamari at 2020-05-11T02:04:40-04:00 GHC.Cmm.Opt: Handle MO_XX_Conv This MachOp was introduced by 2c959a1894311e59cd2fd469c1967491c1e488f3 but a wildcard match in cmmMachOpFoldM hid the fact that it wasn't handled. Ideally we would eliminate the match but this appears to be a larger task. Fixes #18141. - - - - - 2cddee1c by Hécate at 2020-05-11T02:04:43-04:00 fix(documentation): Fix the RST links to GHC.Prim - - - - - 65946ceb by Baldur Blöndal at 2020-05-11T02:04:45-04:00 Document (->) using inferred quantification for its runtime representations. Fixes #18142. - - - - - 3da4c5fc by Takenobu Tani at 2020-05-11T02:04:47-04:00 Tweak man page for ghc command This commit updates the ghc command's man page as followings: * Enable `man_show_urls` to show URL addresses in the `DESCRIPTION` section of ghc.rst, because sphinx currently removes hyperlinks for man pages. * Add a `SEE ALSO` section to point to the GHC homepage - - - - - f6508948 by Takenobu Tani at 2020-05-11T02:04:49-04:00 GHCi: Add link to the user's guide in help message This commit adds a link to the user's guide in ghci's `:help` message. Newcomers could easily reach to details of ghci. - - - - - 9630b694 by Jeff Happily at 2020-05-11T02:04:51-04:00 Handle single unused import - - - - - 9fc8ec54 by Ben Gamari at 2020-05-11T02:04:51-04:00 users-guide: Add discussion of shared object naming Fixes #18074. - - - - - 76da3225 by Ben Gamari at 2020-05-11T02:04:52-04:00 Ensure that printMinimalImports closes handle Fixes #18166. - - - - - bca08e53 by Ben Gamari at 2020-05-11T02:04:52-04:00 testsuite: Print sign of performance changes Executes the minor formatting change in the tabulated performance changes suggested in #18135. - - - - - 37ba34eb by Ben Gamari at 2020-05-11T02:04:52-04:00 hadrian: Tell testsuite driver about LLVM availability This reflects the logic present in the Make build system into Hadrian. Fixes #18167. - - - - - 9b81750a by Ben Gamari at 2020-05-11T02:04:53-04:00 testsuite: Add testcase for #18129 - - - - - 7988c647 by Ben Gamari at 2020-05-11T02:04:53-04:00 Revert "Specify kind variables for inferred kinds in base." As noted in !3132, this has rather severe knock-on consequences in user-code. We'll need to revisit this before merging something along these lines. This reverts commit 9749fe1223d182b1f8e7e4f7378df661c509f396. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Opt/WorkWrap.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Tc/Solver/Flatten.hs - compiler/GHC/Types/Id/Info.hs - docs/users_guide/conf.py - docs/users_guide/editing-guide.rst - docs/users_guide/exts/ffi.rst - docs/users_guide/exts/primitives.rst - docs/users_guide/ghc.rst - docs/users_guide/packages.rst - docs/users_guide/phases.rst - ghc/GHCi/UI.hs - hadrian/src/Settings/Builders/RunTest.hs - includes/rts/Messages.h - libraries/base/Control/Arrow.hs - libraries/base/Control/Category.hs - libraries/base/Data/Data.hs - libraries/base/Data/Dynamic.hs - libraries/base/Data/Fixed.hs - libraries/base/Data/Functor/Compose.hs - libraries/base/Data/Functor/Const.hs - libraries/base/Data/Functor/Contravariant.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b1a4f3868b469cddb4bd198089b4075c184d9eb3...7988c647706dfb0bb9f9132c29ff89493ccfdf96 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b1a4f3868b469cddb4bd198089b4075c184d9eb3...7988c647706dfb0bb9f9132c29ff89493ccfdf96 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 11 09:31:08 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Mon, 11 May 2020 05:31:08 -0400 Subject: [Git][ghc/ghc][wip/andreask/elem_rule_fix] Fix "build/elem" RULE. Message-ID: <5eb91b5c2ccea_6167119ebbd01035875b@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/elem_rule_fix at Glasgow Haskell Compiler / GHC Commits: 34e37ad3 by Andreas Klebinger at 2020-05-11T11:30:49+02:00 Fix "build/elem" RULE. An redundant constraint prevented the rule from matching. Fixing this allows a call to elem on a known list to be translated into a series of equality checks, and eventually a simple case expression. Surprisingly this seems to regress elem for strings. To avoid this we now also allow foldrCString to inline and add an UTF8 variant. This results in elem being compiled to a tight non-allocating loop over the primitive string literal which performs a linear search. In the process this commit adds UTF8 variants for some of the functions in GHC.CString. This is required to make this work for both ASCII and UTF8 strings. There are also small tweaks to the CString related rules. We now allow ourselfes the luxury to compare the folding function via eqExpr, which helps to ensure the rule fires before we inline foldrCString*. Together with a few changes to allow matching on both the UTF8 and ASCII variants of the CString functions. - - - - - 11 changed files: - compiler/GHC/Core/Op/ConstantFold.hs - compiler/prelude/PrelNames.hs - libraries/base/GHC/Base.hs - libraries/base/GHC/List.hs - libraries/base/changelog.md - + libraries/base/tests/perf/Makefile - + libraries/base/tests/perf/T17752.hs - + libraries/base/tests/perf/T17752.stdout - + libraries/base/tests/perf/all.T - libraries/ghc-prim/GHC/CString.hs - libraries/ghc-prim/changelog.md Changes: ===================================== compiler/GHC/Core/Op/ConstantFold.hs ===================================== @@ -43,10 +43,13 @@ import GHC.Core.TyCon , isNewTyCon, unwrapNewTyCon_maybe, tyConDataCons , tyConFamilySize ) import GHC.Core.DataCon ( dataConTagZ, dataConTyCon, dataConWrapId, dataConWorkId ) -import GHC.Core.Utils ( cheapEqExpr, cheapEqExpr', exprIsHNF, exprType +import GHC.Core.Utils ( eqExpr, cheapEqExpr, exprIsHNF, exprType , stripTicksTop, stripTicksTopT, mkTicks ) import GHC.Core.Unfold ( exprIsConApp_maybe ) +import GHC.Core.FVs import GHC.Core.Type +import GHC.Types.Var.Set +import GHC.Types.Var.Env import GHC.Types.Name.Occurrence ( occNameFS ) import PrelNames import Maybes ( orElse ) @@ -1254,7 +1257,10 @@ builtinRules :: [CoreRule] builtinRules = [BuiltinRule { ru_name = fsLit "AppendLitString", ru_fn = unpackCStringFoldrName, - ru_nargs = 4, ru_try = match_append_lit }, + ru_nargs = 4, ru_try = match_append_lit_C }, + BuiltinRule { ru_name = fsLit "AppendLitStringUtf8", + ru_fn = unpackCStringFoldrUtf8Name, + ru_nargs = 4, ru_try = match_append_lit_utf8 }, BuiltinRule { ru_name = fsLit "EqString", ru_fn = eqStringName, ru_nargs = 2, ru_try = match_eq_string }, BuiltinRule { ru_name = fsLit "Inline", ru_fn = inlineIdName, @@ -1430,11 +1436,22 @@ builtinNaturalRules = --------------------------------------------------- -- The rule is this: --- unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n) --- = unpackFoldrCString# "foobaz" c n +-- unpackFoldrCString*# "foo"# c (unpackFoldrCString*# "baz"# c n) +-- = unpackFoldrCString*# "foobaz"# c n +-- +-- See also Note [String literals in GHC] in CString.hs + +-- CString version +match_append_lit_C :: RuleFun +match_append_lit_C = match_append_lit unpackCStringFoldrIdKey -match_append_lit :: RuleFun -match_append_lit _ id_unf _ +-- CStringUTF8 version +match_append_lit_utf8 :: RuleFun +match_append_lit_utf8 = match_append_lit unpackCStringFoldrUtf8IdKey + +{-# INLINE match_append_lit #-} +match_append_lit :: Unique -> RuleFun +match_append_lit foldVariant _ id_unf _ [ Type ty1 , lit1 , c1 @@ -1447,12 +1464,13 @@ match_append_lit _ id_unf _ `App` lit2 `App` c2 `App` n) <- stripTicksTop tickishFloatable e2 - , unpk `hasKey` unpackCStringFoldrIdKey - , cheapEqExpr' tickishFloatable c1 c2 - , (c1Ticks, c1') <- stripTicksTop tickishFloatable c1 - , c2Ticks <- stripTicksTopT tickishFloatable c2 + , unpk `hasKey` foldVariant , Just (LitString s1) <- exprIsLiteral_maybe id_unf lit1 , Just (LitString s2) <- exprIsLiteral_maybe id_unf lit2 + , let freeVars = (mkInScopeSet (exprFreeVars c1 `unionVarSet` exprFreeVars c2)) + in eqExpr freeVars c1 c2 + , (c1Ticks, c1') <- stripTicksTop tickishFloatable c1 + , c2Ticks <- stripTicksTopT tickishFloatable c2 = ASSERT( ty1 `eqType` ty2 ) Just $ mkTicks strTicks $ Var unpk `App` Type ty1 @@ -1460,24 +1478,29 @@ match_append_lit _ id_unf _ `App` mkTicks (c1Ticks ++ c2Ticks) c1' `App` n -match_append_lit _ _ _ _ = Nothing +match_append_lit _ _ _ _ _ = Nothing --------------------------------------------------- -- The rule is this: -- eqString (unpackCString# (Lit s1)) (unpackCString# (Lit s2)) = s1==s2 +-- Also matches unpackCStringUtf8# match_eq_string :: RuleFun match_eq_string _ id_unf _ [Var unpk1 `App` lit1, Var unpk2 `App` lit2] - | unpk1 `hasKey` unpackCStringIdKey - , unpk2 `hasKey` unpackCStringIdKey + | unpk_key1 <- getUnique unpk1 + , unpk_key2 <- getUnique unpk2 + , unpk_key1 == unpk_key2 + -- For now we insist the literals have to agree in their encoding + -- to keep the rule simple. But we could check if the decoded strings + -- compare equal in here as well. + , unpk_key1 `elem` [unpackCStringUtf8IdKey, unpackCStringIdKey] , Just (LitString s1) <- exprIsLiteral_maybe id_unf lit1 , Just (LitString s2) <- exprIsLiteral_maybe id_unf lit2 = Just (if s1 == s2 then trueValBool else falseValBool) match_eq_string _ _ _ _ = Nothing - --------------------------------------------------- -- The rule is this: -- inline f_ty (f a b c) = a b c ===================================== compiler/prelude/PrelNames.hs ===================================== @@ -340,8 +340,8 @@ basicKnownKeyNames groupWithName, -- Strings and lists - unpackCStringName, - unpackCStringFoldrName, unpackCStringUtf8Name, + unpackCStringName, unpackCStringUtf8Name, + unpackCStringFoldrName, unpackCStringFoldrUtf8Name, -- Overloaded lists isListClassName, @@ -712,11 +712,12 @@ ioDataCon_RDR :: RdrName ioDataCon_RDR = nameRdrName ioDataConName eqString_RDR, unpackCString_RDR, unpackCStringFoldr_RDR, - unpackCStringUtf8_RDR :: RdrName + unpackCStringFoldrUtf8_RDR, unpackCStringUtf8_RDR :: RdrName eqString_RDR = nameRdrName eqStringName unpackCString_RDR = nameRdrName unpackCStringName unpackCStringFoldr_RDR = nameRdrName unpackCStringFoldrName unpackCStringUtf8_RDR = nameRdrName unpackCStringUtf8Name +unpackCStringFoldrUtf8_RDR = nameRdrName unpackCStringFoldrUtf8Name newStablePtr_RDR :: RdrName newStablePtr_RDR = nameRdrName newStablePtrName @@ -1006,11 +1007,12 @@ modIntName = varQual gHC_CLASSES (fsLit "modInt#") modIntIdKey -- Base strings Strings unpackCStringName, unpackCStringFoldrName, - unpackCStringUtf8Name, eqStringName :: Name + unpackCStringUtf8Name, unpackCStringFoldrUtf8Name,eqStringName :: Name unpackCStringName = varQual gHC_CSTRING (fsLit "unpackCString#") unpackCStringIdKey unpackCStringFoldrName = varQual gHC_CSTRING (fsLit "unpackFoldrCString#") unpackCStringFoldrIdKey unpackCStringUtf8Name = varQual gHC_CSTRING (fsLit "unpackCStringUtf8#") unpackCStringUtf8IdKey eqStringName = varQual gHC_BASE (fsLit "eqString") eqStringIdKey +unpackCStringFoldrUtf8Name = varQual gHC_CSTRING (fsLit "unpackFoldrCStringUtf8#") unpackCStringFoldrUtf8IdKey -- The 'inline' function inlineIdName :: Name @@ -2087,7 +2089,8 @@ wildCardKey, absentErrorIdKey, augmentIdKey, appendIdKey, runtimeErrorIdKey, patErrorIdKey, voidPrimIdKey, realWorldPrimIdKey, recConErrorIdKey, unpackCStringUtf8IdKey, unpackCStringAppendIdKey, - unpackCStringFoldrIdKey, unpackCStringIdKey, + unpackCStringFoldrIdKey, unpackCStringFoldrUtf8IdKey, + unpackCStringIdKey, typeErrorIdKey, divIntIdKey, modIntIdKey, absentSumFieldErrorIdKey :: Unique @@ -2111,11 +2114,12 @@ recConErrorIdKey = mkPreludeMiscIdUnique 16 unpackCStringUtf8IdKey = mkPreludeMiscIdUnique 17 unpackCStringAppendIdKey = mkPreludeMiscIdUnique 18 unpackCStringFoldrIdKey = mkPreludeMiscIdUnique 19 -unpackCStringIdKey = mkPreludeMiscIdUnique 20 -voidPrimIdKey = mkPreludeMiscIdUnique 21 -typeErrorIdKey = mkPreludeMiscIdUnique 22 -divIntIdKey = mkPreludeMiscIdUnique 23 -modIntIdKey = mkPreludeMiscIdUnique 24 +unpackCStringFoldrUtf8IdKey = mkPreludeMiscIdUnique 20 +unpackCStringIdKey = mkPreludeMiscIdUnique 21 +voidPrimIdKey = mkPreludeMiscIdUnique 22 +typeErrorIdKey = mkPreludeMiscIdUnique 23 +divIntIdKey = mkPreludeMiscIdUnique 24 +modIntIdKey = mkPreludeMiscIdUnique 25 concatIdKey, filterIdKey, zipIdKey, bindIOIdKey, returnIOIdKey, newStablePtrIdKey, ===================================== libraries/base/GHC/Base.hs ===================================== @@ -1624,7 +1624,13 @@ a `iShiftRL#` b | isTrue# (b >=# WORD_SIZE_IN_BITS#) = 0# "unpack-list" [1] forall a . unpackFoldrCString# a (:) [] = unpackCString# a "unpack-append" forall a n . unpackFoldrCString# a (:) n = unpackAppendCString# a n +"unpack-utf8" [~1] forall a . unpackCStringUtf8# a = build (unpackFoldrCStringUtf8# a) +"unpack-list-utf8" [1] forall a . unpackFoldrCStringUtf8# a (:) [] = unpackCStringUtf8# a +"unpack-append-utf8" forall a n . unpackFoldrCStringUtf8# a (:) n = unpackAppendCStringUtf8# a n + -- There's a built-in rule (in GHC.Core.Op.ConstantFold) for -- unpackFoldr "foo" c (unpackFoldr "baz" c n) = unpackFoldr "foobaz" c n +-- See also the Note [String literals in GHC] in CString.hs + #-} ===================================== libraries/base/GHC/List.hs ===================================== @@ -1149,7 +1149,7 @@ elem _ [] = False elem x (y:ys) = x==y || elem x ys {-# NOINLINE [1] elem #-} {-# RULES -"elem/build" forall x (g :: forall b . Eq a => (a -> b -> b) -> b -> b) +"elem/build" forall x (g :: forall b . (a -> b -> b) -> b -> b) . elem x (build g) = g (\ y r -> (x == y) || r) False #-} #endif @@ -1174,7 +1174,7 @@ notElem _ [] = True notElem x (y:ys)= x /= y && notElem x ys {-# NOINLINE [1] notElem #-} {-# RULES -"notElem/build" forall x (g :: forall b . Eq a => (a -> b -> b) -> b -> b) +"notElem/build" forall x (g :: forall b . (a -> b -> b) -> b -> b) . notElem x (build g) = g (\ y r -> (x /= y) && r) True #-} #endif ===================================== libraries/base/changelog.md ===================================== @@ -11,7 +11,13 @@ * Add `singleton` function for `Data.List.NonEmpty`. + * Add rules `unpackUtf8`, `unpack-listUtf8` and `unpack-appendUtf8` to `GHC.Base`. + They correspond to their ascii versions and hopefully make it easier + for libraries to handle utf8 encoded strings efficiently. + * An issue with list fusion and `elem` was fixed. `elem` applied to known + small lists will now compile to a simple case statement more often. + ## 4.14.0.0 *TBA* * Bundled with GHC 8.10.1 ===================================== libraries/base/tests/perf/Makefile ===================================== @@ -0,0 +1,15 @@ +# This Makefile runs the tests using GHC's testsuite framework. It +# assumes the package is part of a GHC build tree with the testsuite +# installed in ../../../testsuite. + +TOP=../../../../testsuite +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + + +T17752: + '$(TEST_HC)' $(TEST_HC_OPTS) -O --make T17752 -rtsopts -ddump-simpl -ddump-to-file -dsuppress-uniques -dsuppress-all + # All occurences of elem should be optimized away. + # For strings these should result in loops after inlining foldCString. + # For lists it should result in a case expression. + echo $$(cat T17752.dump-simpl | grep "elem" -A4 ) ===================================== libraries/base/tests/perf/T17752.hs ===================================== @@ -0,0 +1,18 @@ +module T17752 where + +-- All occurences of elem should be optimized away. +-- For strings these should result in loops after inlining foldCString. +-- For lists it should result in a case expression. + +-- Should compile to a pattern match if the rules fire +isElemList x = x `elem` ['a','b','c'] +isNotElemList x = x `elem` ['x','y','z'] + +isOneOfThese x = x `elem` [1,2,3,4,5::Int] +isNotOneOfThese x = x `notElem` [1,2,3,4,5::Int] + +isElemString x = elem x "foo" +isNotElemString x = notElem x "bar" + +isElemStringUtf x = elem x "foö" +isNotElemStringUtf x = notElem x "bär" ===================================== libraries/base/tests/perf/T17752.stdout ===================================== @@ -0,0 +1,2 @@ +[1 of 1] Compiling T17752 ( T17752.hs, T17752.o ) + ===================================== libraries/base/tests/perf/all.T ===================================== @@ -0,0 +1,5 @@ +#-------------------------------------- +# Check specialization of elem via rules +#-------------------------------------- + +test('T17752', [only_ways(['normal'])] , makefile_test, ['T17752']) ===================================== libraries/ghc-prim/GHC/CString.hs ===================================== @@ -17,13 +17,77 @@ ----------------------------------------------------------------------------- module GHC.CString ( + -- * Ascii variants unpackCString#, unpackAppendCString#, unpackFoldrCString#, - unpackCStringUtf8#, unpackNBytes# + + -- * Utf variants + unpackCStringUtf8#, unpackAppendCStringUtf8#, unpackFoldrCStringUtf8#, + + -- * Other + unpackNBytes#, ) where import GHC.Types import GHC.Prim +{- +Note [String literals in GHC] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +String literals get quite a bit of special handling in GHC. This Note +summarises the moving parts. + +* Desugaring: see GHC.HsToCore.Match.Literal.dsLit, which in + turn calls GHC.Core.Make.mkStringExprFS. + + The desugarer desugars the Haskell literal "foo" into Core + GHC.CString.unpackCString# "foo"# + where "foo"# is primitive string literal (of type Addr#). + + When the string cannot be encoded as a C string, we use UTF8: + GHC.CString.unpackCStringUtf8# "foo"# + +* The library module ghc-prim:GHC.CString has a bunch of functions that + work over primitive strings, including GHC.CString.unpackCString# + +* GHC.Core.Op.ConstantFold has some RULES that optimise certain string + operations on literal strings. For example: + + + Constant folding the desugared form of ("foo" ++ "bar") + into ("foobar") + + Comparing strings + + and more + +* GHC.Base has a number of regular rules for String literals. + + + a rule "eqString": (==) @String = eqString + where GHC.Base.eqString :: String -> String -> Bool + + ConstantFold has a RULE for eqString on literals: + eqString (Lit "foo"#) (Lit "bar"#) --> False + + This allows compile time evaluation of things like "foo" == "bar" + + + A bunch of rules to promote fusion: + + "unpack" [~1] forall a . unpackCString# a = build (unpackFoldrCString# a) + "unpack-list" [1] forall a . unpackFoldrCString# a (:) [] = unpackCString# a + "unpack-append" forall a n . unpackFoldrCString# a (:) n = unpackAppendCString# a n + + And UTF8 variants of these rules. + +* We allow primitive (unlifted) literal strings to be top-level + bindings, breaking out usual rule. See GHC.Core + Note [Core top-level string literals] + +* TODO: There is work on a special code-gen path for top-level boxed strings + str :: [Char] + str = unpackCString# "foo"# + so that they can all share a common code pointer + + There is a WIP MR on gitlab for this: !3012 + +-} + ----------------------------------------------------------------------------- -- Unpacking C strings ----------------------------------------------------------------------------- @@ -71,8 +135,27 @@ Moreover, we want to make it CONLIKE, so that: All of this goes for unpackCStringUtf8# too. -} -{- Note [unpackCString# iterating over addr] - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [Inlining of unpackFoldrCString] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Usually the unpack-list rule turns unpackFoldrCString# into unpackCString# +It also has a BuiltInRule in PrelRules.hs: + unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n) + = unpackFoldrCString# "foobaz" c n + +We use NOINLINE [0] on the grounds that, unlike +unpackCString#, there *is* some point in inlining +unpackFoldrCString#, because we get better code for the +higher-order function call. + +This can cause a code size increase but it was minimal +when looking at nofib. + +This is especially important for elem which then results in an +allocation free loop. + + Note [unpackCString# iterating over addr] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When unpacking unpackCString# and friends repeatedly return a cons cell containing: @@ -89,6 +172,10 @@ This works since these two expressions will read from the same address. This way we avoid the need for the thunks to close over both the start of the string and the current offset, saving a word for each character unpacked. + +This has the additional advantage the we can guarantee that only the +increment will happen in the loop. + -} unpackCString# :: Addr# -> [Char] @@ -111,28 +198,17 @@ unpackAppendCString# addr rest -- See Note [unpackCString# iterating over addr] !ch = indexCharOffAddr# addr 0# -unpackFoldrCString# :: Addr# -> (Char -> a -> a) -> a -> a - --- Usually the unpack-list rule turns unpackFoldrCString# into unpackCString# - --- It also has a BuiltInRule in GHC.Core.Op.ConstantFold: --- unpackFoldrCString# "foo" c (unpackFoldrCString# "baz" c n) --- = unpackFoldrCString# "foobaz" c n - -{-# NOINLINE unpackFoldrCString# #-} --- At one stage I had NOINLINE [0] on the grounds that, unlike --- unpackCString#, there *is* some point in inlining --- unpackFoldrCString#, because we get better code for the --- higher-order function call. BUT there may be a lot of --- literal strings, and making a separate 'unpack' loop for --- each is highly gratuitous. See nofib/real/anna/PrettyPrint. - -unpackFoldrCString# addr f z - | isTrue# (ch `eqChar#` '\0'#) = z - | True = C# ch `f` unpackFoldrCString# (addr `plusAddr#` 1#) f z +-- See [Inlining of unpackFoldrCString] +{-# NOINLINE[0] unpackFoldrCString# #-} +unpackFoldrCString# :: Addr# -> (Char -> a -> a) -> a -> a +unpackFoldrCString# str f z_init = go str z_init where - -- See Note [unpackCString# iterating over addr] - !ch = indexCharOffAddr# addr 0# + go addr z + | isTrue# (ch `eqChar#` '\0'#) = z + | True = C# ch `f` go (addr `plusAddr#` 1#) z + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# -- There's really no point in inlining this for the same reasons as -- unpackCString. See Note [Inlining unpackCString#] above for details. @@ -140,22 +216,43 @@ unpackCStringUtf8# :: Addr# -> [Char] {-# NOINLINE CONLIKE unpackCStringUtf8# #-} unpackCStringUtf8# addr | isTrue# (ch `eqChar#` '\0'# ) = [] - | isTrue# (ch `leChar#` '\x7F'#) = C# ch : unpackCStringUtf8# (addr `plusAddr#` 1#) - | isTrue# (ch `leChar#` '\xDF'#) = - let !c = C# (chr# (((ord# ch -# 0xC0#) `uncheckedIShiftL#` 6#) +# - (ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#))) - in c : unpackCStringUtf8# (addr `plusAddr#` 2#) - | isTrue# (ch `leChar#` '\xEF'#) = - let !c = C# (chr# (((ord# ch -# 0xE0#) `uncheckedIShiftL#` 12#) +# - ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# - (ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#))) - in c : unpackCStringUtf8# (addr `plusAddr#` 3#) - | True = - let !c = C# (chr# (((ord# ch -# 0xF0#) `uncheckedIShiftL#` 18#) +# - ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 12#) +# - ((ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# - (ord# (indexCharOffAddr# (addr `plusAddr#` 3#) 0#) -# 0x80#))) - in c : unpackCStringUtf8# (addr `plusAddr#` 4#) + | True = + let !byte_count = getByteCount ch + !utf_ch = unpackUtf8Char# byte_count ch addr + !addr' = addr `plusBytes` byte_count + in C# utf_ch : unpackCStringUtf8# addr' + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# + + +unpackAppendCStringUtf8# :: Addr# -> [Char] -> [Char] +{-# NOINLINE unpackAppendCStringUtf8# #-} + -- See the NOINLINE note on unpackCString# +unpackAppendCStringUtf8# addr rest + | isTrue# (ch `eqChar#` '\0'#) = rest + | True = + let !byte_count = getByteCount ch + !utf_ch = unpackUtf8Char# byte_count ch addr + !addr' = (addr `plusBytes` byte_count) + in C# utf_ch : unpackAppendCStringUtf8# addr' rest + where + -- See Note [unpackCString# iterating over addr] + !ch = indexCharOffAddr# addr 0# + +-- See Note [Inlining of unpackFoldrCString] +{-# NOINLINE[0] unpackFoldrCStringUtf8# #-} +unpackFoldrCStringUtf8# :: Addr# -> (Char -> a -> a) -> a -> a +unpackFoldrCStringUtf8# addr_init f z_init + = go addr_init z_init + where + go addr z + | isTrue# (ch `eqChar#` '\0'#) = z + | True = + let !byte_count = getByteCount ch + !utf_ch = unpackUtf8Char# byte_count ch addr + !addr' = (addr `plusBytes` byte_count) + in C# utf_ch `f` go addr' z where -- See Note [unpackCString# iterating over addr] !ch = indexCharOffAddr# addr 0# @@ -174,3 +271,61 @@ unpackNBytes# addr len# = unpack [] (len# -# 1#) case indexCharOffAddr# addr i# of ch -> unpack (C# ch : acc) (i# -# 1#) + + +------------------------------ +--- UTF8 decoding utilities +------------------------------ +-- +-- These functions make explicit the logic that was originally +-- part of unpackCStringUtf8. Since we want the same support for ascii +-- and non-ascii a variety of functions needs the same logic. Instead +-- of C&P'in the decoding logic all over we have it here once, and then +-- force GHC to inline it. +-- +-- All the overhead of the Bytes argument and calls goes away once all is +-- said and done. And what remains is readable code in Haskell land and +-- performant code in the resulting binary. + +data Bytes = One | Two | Three | Four + +{-# INLINE getByteCount #-} +getByteCount :: Char# -> Bytes +getByteCount ch + | isTrue# (ch `leChar#` '\x7F'#) = One + | isTrue# (ch `leChar#` '\xDF'#) = Two + | isTrue# (ch `leChar#` '\xEF'#) = Three + | True = Four + +{-# INLINE plusBytes #-} +plusBytes :: Addr# -> Bytes -> Addr# +plusBytes addr bytes = + case bytes of + One -> addr `plusAddr#` 1# + Two -> addr `plusAddr#` 2# + Three -> addr `plusAddr#` 3# + Four -> addr `plusAddr#` 4# + +-- | Take the current address, read unicode char of the given size. +-- We obviously want the number of bytes, but we have to read one +-- byte to determine the number of bytes for the current codepoint +-- so we might as well reuse it and avoid a read. +-- +-- Side Note: We don't dare to decode all 4 possibilities at once. +-- Reading past the end of the addr might trigger an exception. +-- For this reason we really have to check the width first and only +-- decode after. +{-# INLINE unpackUtf8Char# #-} +unpackUtf8Char# :: Bytes -> Char# -> Addr# -> Char# +unpackUtf8Char# bytes ch addr = + case bytes of + One -> ch + Two -> (chr# (((ord# ch -# 0xC0#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#))) + Three -> (chr# (((ord# ch -# 0xE0#) `uncheckedIShiftL#` 12#) +# + ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#))) + Four -> (chr# (((ord# ch -# 0xF0#) `uncheckedIShiftL#` 18#) +# + ((ord# (indexCharOffAddr# (addr `plusAddr#` 1#) 0#) -# 0x80#) `uncheckedIShiftL#` 12#) +# + ((ord# (indexCharOffAddr# (addr `plusAddr#` 2#) 0#) -# 0x80#) `uncheckedIShiftL#` 6#) +# + (ord# (indexCharOffAddr# (addr `plusAddr#` 3#) 0#) -# 0x80#))) ===================================== libraries/ghc-prim/changelog.md ===================================== @@ -1,3 +1,18 @@ +## 0.6.2 (edit as necessary) + +- Shipped with GHC 8.12.1 + +- In order to support unicode better the following functions in `GHC.CString` + gained UTF8 counterparts: + + unpackAppendCStringUtf8# :: Addr# -> [Char] -> [Char] + unpackFoldrCStringUtf8# :: Addr# -> (Char -> a -> a) -> a -> a + +- unpackFoldrCString* variants can now inline in phase [0]. + + If the folding function is known this allows for unboxing of the + Char argument resulting in much faster code. + ## 0.6.1 (edit as necessary) - Shipped with GHC 8.10.1 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/34e37ad3b77b4d62f14e872426a7d8c78a9f6063 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/34e37ad3b77b4d62f14e872426a7d8c78a9f6063 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 11 09:41:19 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Mon, 11 May 2020 05:41:19 -0400 Subject: [Git][ghc/ghc][wip/andreask/elem_rule_fix] 141 commits: Change zipWith to zipWithEqual in a few places Message-ID: <5eb91dbfc330a_61671288ff4c1036797@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/elem_rule_fix at Glasgow Haskell Compiler / GHC Commits: 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.0.0 This requires bumping the `exceptions` and `text` submodules to bring in commits that bump their respective upper version bounds on `template-haskell`. Fixes #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - ffd7eef2 by Takenobu Tani at 2020-04-22T23:09:50-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - e8a5d81b by Jonathan DK Gibbons at 2020-04-22T23:10:28-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - dcb7fe5a by John Ericson at 2020-04-22T23:10:28-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - cde23cd4 by John Ericson at 2020-04-22T23:10:28-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - 72cb6bcc by John Ericson at 2020-04-22T23:10:28-04:00 Generalize type of `matchCanFail` - - - - - 401f7bb3 by John Ericson at 2020-04-22T23:10:28-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 6c9fae23 by Alexis King at 2020-04-22T23:11:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 48b8951e by Roland Senn at 2020-04-22T23:11:51-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 34a45ee6 by Peter Trommler at 2020-04-22T23:12:27-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - ffde2348 by Simon Peyton Jones at 2020-04-22T23:13:06-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 6f84aca3 by Ben Gamari at 2020-04-22T23:13:43-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - c29f0fa6 by Andreas Klebinger at 2020-04-22T23:14:21-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 4b4a8b60 by Ben Gamari at 2020-04-22T23:14:57-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 831b6642 by Moritz Angermann at 2020-04-22T23:15:33-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - c409961a by Ryan Scott at 2020-04-22T23:16:12-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 125aa2b8 by Ömer Sinan Ağacan at 2020-04-22T23:16:51-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - 8ea37b01 by Sylvain Henry at 2020-04-22T23:17:34-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - cd8409c2 by Ryan Scott at 2020-04-23T11:39:24-04:00 Create di_scoped_tvs for associated data family instances properly See `Note [Associated data family instances and di_scoped_tvs]` in `GHC.Tc.TyCl.Instance`, which explains all of the moving parts. Fixes #18055. - - - - - 339e8ece by Ben Gamari at 2020-04-23T11:40:02-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 5946c85a by Ben Gamari at 2020-04-23T11:40:38-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - c42754d5 by John Ericson at 2020-04-23T18:32:43-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 72da0c29 by mniip at 2020-04-23T18:33:21-04:00 Add :doc to GHC.Prim - - - - - 2c23e2e3 by mniip at 2020-04-23T18:33:21-04:00 Include docs for non-primop entries in primops.txt as well - - - - - 0ac29c88 by mniip at 2020-04-23T18:33:21-04:00 GHC.Prim docs: note and test - - - - - b0fbfc75 by John Ericson at 2020-04-24T12:07:14-04:00 Switch order on `GhcMake.IsBoot` In !1798 we were requested to replace many `Bool`s with this data type. But those bools had `False` meaning `NotBoot`, so the `Ord` instance would be flipped if we use this data-type as-is. Since the planned formally-`Bool` occurrences vastly outnumber the current occurrences, we figured it would be better to conform the `Ord` instance to how the `Bool` is used now, fixing any issues, rather than fix them currently with the bigger refactor later in !1798. That way, !1798 can be a "pure" refactor with no behavioral changes. - - - - - af332442 by Sylvain Henry at 2020-04-26T13:55:14-04:00 Modules: Utils and Data (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - cd4434c8 by Sylvain Henry at 2020-04-26T13:55:16-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 22bf5c73 by Ömer Sinan Ağacan at 2020-04-26T13:55:22-04:00 Tweak includes in non-moving GC headers We don't use hash tables in non-moving GC so remove the includes. This breaks Compact.c as existing includes no longer include Hash.h, so include Hash.h explicitly in Compact.c. - - - - - 99823ed2 by Sylvain Henry at 2020-04-27T20:24:46-04:00 TH: fix Show/Eq/Ord instances for Bytes (#16457) We shouldn't compare pointer values but the actual bytes. - - - - - c62271a2 by Alp Mestanogullari at 2020-04-27T20:25:33-04:00 hadrian: always capture both stdout and stderr when running a builder fails The idea being that when a builder('s command) fails, we quite likely want to have all the information available to figure out why. Depending on the builder _and_ the particular problem, the useful bits of information can be printed on stdout or stderr. We accomplish this by defining a simple wrapper for Shake's `cmd` function, that just _always_ captures both streams in case the command returns a non-zero exit code, and by using this wrapper everywhere in `hadrian/src/Builder.hs`. Fixes #18089. - - - - - 4b9764db by Ryan Scott at 2020-04-28T15:40:04-04:00 Define a Quote IO instance Fixes #18103. - - - - - 518a63d4 by Ryan Scott at 2020-04-28T15:40:42-04:00 Make boxed 1-tuples have known keys Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. - - - - - 2cfc4ab9 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Document backpack fields in DynFlags - - - - - 10a2ba90 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 69562e34 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 9e2c8e0e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - ea717aa4 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 10d15f1e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 8bfb0219 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - 71484b09 by Alexis King at 2020-04-30T01:57:35-04:00 Allow block arguments in arrow control operators Arrow control operators have their own entries in the grammar, so they did not cooperate with BlockArguments. This was just a minor oversight, so this patch adjusts the grammar to add the desired behavior. fixes #18050 - - - - - a48cd2a0 by Alexis King at 2020-04-30T01:57:35-04:00 Allow LambdaCase to be used as a command in proc notation - - - - - f4d3773c by Alexis King at 2020-04-30T01:57:35-04:00 Document BlockArguments/LambdaCase support in arrow notation - - - - - 5bdfdd13 by Simon Peyton Jones at 2020-04-30T01:58:15-04:00 Add tests for #17873 - - - - - 19b701c2 by Simon Peyton Jones at 2020-04-30T07:30:13-04:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - 014ef4a3 by Matthew Pickering at 2020-04-30T07:30:50-04:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 2aa67611 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - 54dad3cf by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - 99ff8145 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 05b0a9fd by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 Remove OneShotInfo field of LFReEntrant, document OneShotInfo The field is only used in withNewTickyCounterFun and it's easier to directly pass a parameter for one-shot info to withNewTickyCounterFun instead of passing it via LFReEntrant. This also makes !2842 simpler. Other changes: - New Note (by SPJ) [OneShotInfo overview] added. - Arity argument of thunkCode removed as it's always 0. - - - - - a43620c6 by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 GHC.StgToCmm.Ticky: remove a few unused stuff - - - - - 780de9e1 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Use platform in Iface Binary - - - - - f8386c7b by Sylvain Henry at 2020-05-01T10:37:39-04:00 Refactor PprDebug handling If `-dppr-debug` is set, then PprUser and PprDump styles are silently replaced with PprDebug style. This was done in `mkUserStyle` and `mkDumpStyle` smart constructors. As a consequence they needed a DynFlags parameter. Now we keep the original PprUser and PprDump styles until they are used to create an `SDocContext`. I.e. the substitution is only performed in `initSDocContext`. - - - - - b3df9e78 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Remove PprStyle param of logging actions Use `withPprStyle` instead to apply a specific style to a SDoc. - - - - - de9fc995 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Fully remove PprDebug PprDebug was a pain to deal with consistently as it is implied by `-dppr-debug` but it isn't really a PprStyle. We remove it completely and query the appropriate SDoc flag instead (`sdocPprDebug`) via helpers (`getPprDebug` and its friends). - - - - - 8b51fcbd by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Only call checkSingle if we would report warnings - - - - - fd7ea0fe by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 7bfe9ac5 by Ben Gamari at 2020-05-03T04:41:33-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. - - - - - c560dd07 by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Move eventlog documentation users guide - - - - - 02543d5e by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Add documentation for non-moving GC events - - - - - b465dd45 by Alexis King at 2020-05-03T04:42:12-04:00 Flatten nested casts in the simple optimizer Normally, we aren’t supposed to generated any nested casts, since mkCast takes care to flatten them, but the simple optimizer didn’t use mkCast, so they could show up after inlining. This isn’t really a problem, since the simplifier will clean them up immediately anyway, but it can clutter the -ddump-ds output, and it’s an extremely easy fix. closes #18112 - - - - - 8bdc03d6 by Simon Peyton Jones at 2020-05-04T01:56:59-04:00 Don't return a panic in tcNestedSplice In GHC.Tc.Gen.Splice.tcNestedSplice we were returning a typechecked expression of "panic". That is usually OK, because the result is discarded. But it happens that tcApp now looks at the typechecked expression, trivially, to ask if it is tagToEnum. So being bottom is bad. Moreover a debug-trace might print it out. So better to return a civilised expression, even though it is usually discarded. - - - - - 0bf640b1 by Baldur Blöndal at 2020-05-04T01:57:36-04:00 Don't require parentheses around via type (`-XDerivingVia'). Fixes #18130". - - - - - 30272412 by Artem Pelenitsyn at 2020-05-04T13:19:59-04:00 Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) - - - - - b9f7c08f by jneira at 2020-05-04T13:20:37-04:00 Remove unused hs-boot file - - - - - 1d8f80cd by Sylvain Henry at 2020-05-05T03:22:46-04:00 Remove references to -package-key * remove references to `-package-key` which has been removed in 2016 (240ddd7c39536776e955e881d709bbb039b48513) * remove support for `-this-package-key` which has been deprecated at the same time - - - - - 7bc3a65b by Sylvain Henry at 2020-05-05T03:23:31-04:00 Remove SpecConstrAnnotation (#13681) This has been deprecated since 2013. Use GHC.Types.SPEC instead. Make GHC.Exts "not-home" for haddock Metric Decrease: haddock.base - - - - - 3c862f63 by DenisFrezzato at 2020-05-05T03:24:15-04:00 Fix Haskell98 short description in documentation - - - - - 2420c555 by Ryan Scott at 2020-05-05T03:24:53-04:00 Add regression tests for #16244, #16245, #16758 Commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70 ended up fixing quite a few bugs: * This commit fixes #16244 completely. A regression test has been added. * This commit fixes one program from #16245. (The program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211369 still panics, and the program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211400 still loops infinitely.) A regression test has been added for this program. * This commit fixes #16758. Accordingly, this patch removes the `expect_broken` label from the `T16758` test case, moves it from `should_compile` to `should_fail` (as it should produce an error message), and checks in the expected stderr. - - - - - 40c71c2c by Sylvain Henry at 2020-05-05T03:25:31-04:00 Fix colorized error messages (#18128) In b3df9e780fb2f5658412c644849cd0f1e6f50331 I broke colorized messages by using "dump" style instead of "user" style. This commits fixes it. - - - - - 7ab6ab09 by Richard Eisenberg at 2020-05-06T04:39:32-04:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG ------------------------- - - - - - 420b957d by Ben Gamari at 2020-05-06T04:40:08-04:00 rts: Zero block flags with -DZ Block flags are very useful for determining the state of a block. However, some block allocator users don't touch them, leading to misleading values. Ensure that we zero then when zero-on-gc is set. This is safe and makes the flags more useful during debugging. - - - - - 740b3b8d by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix incorrect failed_to_evac value during deadlock gc Previously we would incorrectly set the failed_to_evac flag if we evacuated a value due to a deadlock GC. This would cause us to mark more things as dirty than strictly necessary. It also turned up a nasty but which I will fix next. - - - - - b2d72c75 by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - 9f3e6884 by Zubin Duggal at 2020-05-06T04:41:08-04:00 Allow atomic update of NameCache in readHieFile The situation arises in ghcide where multiple different threads may need to update the name cache, therefore with the older interface it could happen that you start reading a hie file with name cache A and produce name cache A + B, but another thread in the meantime updated the namecache to A + C. Therefore if you write the new namecache you will lose the A' updates from the second thread. Updates haddock submodule - - - - - edec6a6c by Ryan Scott at 2020-05-06T04:41:57-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _)`. Fixes #18127. - - - - - a95e7fe0 by Ömer Sinan Ağacan at 2020-05-06T04:42:39-04:00 ELF linker: increment curSymbol after filling in fields of current entry The bug was introduced in a8b7cef4d45 which added a field to the `symbols` array elements and then updated this code incorrectly: - oc->symbols[curSymbol++] = nm; + oc->symbols[curSymbol++].name = nm; + oc->symbols[curSymbol].addr = symbol->addr; - - - - - cab1871a by Sylvain Henry at 2020-05-06T04:43:21-04:00 Move LeadingUnderscore into Platform (#17957) Avoid direct use of DynFlags to know if symbols must be prefixed by an underscore. - - - - - 94e7c563 by Sylvain Henry at 2020-05-06T04:43:21-04:00 Don't use DynFlags in showLinkerState (#17957) - - - - - 9afd9251 by Ryan Scott at 2020-05-06T04:43:58-04:00 Refactoring: Use bindSigTyVarsFV in rnMethodBinds `rnMethodBinds` was explicitly using `xoptM` to determine if `ScopedTypeVariables` is enabled before bringing type variables bound by the class/instance header into scope. However, this `xoptM` logic is already performed by the `bindSigTyVarsFV` function. This patch uses `bindSigTyVarsFV` in `rnMethodBinds` to reduce the number of places where we need to consult if `ScopedTypeVariables` is on. This is purely refactoring, and there should be no user-visible change in behavior. - - - - - 6f6d72b2 by Brian Foley at 2020-05-08T15:29:25-04:00 Remove further dead code found by a simple Python script. Avoid removing some functions that are part of an API even though they're not used in-tree at the moment. - - - - - 78bf8bf9 by Julien Debon at 2020-05-08T15:29:28-04:00 Add doc examples for Bifoldable See #17929 - - - - - 66f0a847 by Julien Debon at 2020-05-08T15:29:29-04:00 doc (Bitraversable): Add examples to Bitraversable * Add examples to Data.Bitraversable * Fix formatting for (,) in Bitraversable and Bifoldable * Fix mistake on bimapAccumR documentation See #17929 - - - - - 9749fe12 by Baldur Blöndal at 2020-05-08T15:29:32-04:00 Specify kind variables for inferred kinds in base. - - - - - 4e9aef9e by John Ericson at 2020-05-08T15:29:36-04:00 HsSigWcTypeScoping: Pull in documentation from stray location - - - - - f4d5c6df by John Ericson at 2020-05-08T15:29:36-04:00 Rename local `real_fvs` to `implicit_vs` It doesn't make sense to call the "free" variables we are about to implicitly bind the real ones. - - - - - 20570b4b by John Ericson at 2020-05-08T15:29:36-04:00 A few tiny style nits with renaming - Use case rather than guards that repeatedly scrutenize same thing. - No need for view pattern when `L` is fine. - Use type synnonym to convey the intent like elsewhere. - - - - - 09ac8de5 by John Ericson at 2020-05-08T15:29:36-04:00 Add `forAllOrNothing` function with note - - - - - bb35c0e5 by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Document lawlessness of Ap's Num instance - - - - - cdd229ff by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply suggestion to libraries/base/Data/Monoid.hs - - - - - 926d2aab by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply more suggestions from Simon Jakobi - - - - - 7a763cff by Adam Gundry at 2020-05-08T15:29:41-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. - - - - - 88e3c815 by Simon Peyton Jones at 2020-05-08T15:29:41-04:00 Fix specialisation for DFuns When specialising a DFun we must take care to saturate the unfolding. See Note [Specialising DFuns] in Specialise. Fixes #18120 - - - - - 86c77b36 by Greg Steuck at 2020-05-08T15:29:45-04:00 Remove unused SEGMENT_PROT_RWX It's been unused for a year and is problematic on any OS which requires W^X for security. - - - - - 9d97f4b5 by nineonine at 2020-05-08T15:30:03-04:00 Add test for #16167 - - - - - aa318338 by Ryan Scott at 2020-05-08T15:30:04-04:00 Bump exceptions submodule so that dist-boot is .gitignore'd `exceptions` is a stage-0 boot library as of commit 30272412fa437ab8e7a8035db94a278e10513413, which means that building `exceptions` in a GHC tree will generate a `dist-boot` directory. However, this directory was not specified in `exceptions`' `.gitignore` file, which causes it to dirty up the current `git` working directory. Accordingly, this bumps the `exceptions` submodule to commit ghc/packages/exceptions at 23c0b8a50d7592af37ca09beeec16b93080df98f, which adds `dist-boot` to the `.gitignore` file. - - - - - ea86360f by Ömer Sinan Ağacan at 2020-05-08T15:30:30-04:00 Linker.c: initialize n_symbols of ObjectCode with other fields - - - - - 951c1fb0 by Sylvain Henry at 2020-05-09T21:46:38-04:00 Fix unboxed-sums GC ptr-slot rubbish value (#17791) This patch allows boot libraries to use unboxed sums without implicitly depending on `base` package because of `absentSumFieldError`. See updated Note [aBSENT_SUM_FIELD_ERROR_ID] in GHC.Core.Make - - - - - b352d63c by Ben Gamari at 2020-05-09T21:47:14-04:00 rts: Make non-existent linker search path merely a warning As noted in #18105, previously this resulted in a rather intrusive error message. This is in contrast to the general expectation that search paths are merely places to look, not places that must exist. Fixes #18105. - - - - - 4a98f14f by Andreas Klebinger at 2020-05-11T11:41:04+02:00 Fix "build/elem" RULE. An redundant constraint prevented the rule from matching. Fixing this allows a call to elem on a known list to be translated into a series of equality checks, and eventually a simple case expression. Surprisingly this seems to regress elem for strings. To avoid this we now also allow foldrCString to inline and add an UTF8 variant. This results in elem being compiled to a tight non-allocating loop over the primitive string literal which performs a linear search. In the process this commit adds UTF8 variants for some of the functions in GHC.CString. This is required to make this work for both ASCII and UTF8 strings. There are also small tweaks to the CString related rules. We now allow ourselfes the luxury to compare the folding function via eqExpr, which helps to ensure the rule fires before we inline foldrCString*. Together with a few changes to allow matching on both the UTF8 and ASCII variants of the CString functions. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - compiler/prelude/PrelNames.hs-boot → compiler/GHC/Builtin/Names.hs-boot - compiler/prelude/THNames.hs → compiler/GHC/Builtin/Names/TH.hs - compiler/prelude/PrimOp.hs → compiler/GHC/Builtin/PrimOps.hs - + compiler/GHC/Builtin/PrimOps.hs-boot - compiler/prelude/TysWiredIn.hs → compiler/GHC/Builtin/Types.hs - compiler/prelude/TysWiredIn.hs-boot → compiler/GHC/Builtin/Types.hs-boot - compiler/typecheck/TcTypeNats.hs → compiler/GHC/Builtin/Types/Literals.hs - compiler/prelude/TysPrim.hs → compiler/GHC/Builtin/Types/Prim.hs - compiler/prelude/KnownUniques.hs → compiler/GHC/Builtin/Uniques.hs - compiler/prelude/KnownUniques.hs-boot → compiler/GHC/Builtin/Uniques.hs-boot - compiler/prelude/PrelInfo.hs → compiler/GHC/Builtin/Utils.hs - compiler/prelude/primops.txt.pp → compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.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/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Block.hs - compiler/GHC/Cmm/Dataflow/Collections.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/34e37ad3b77b4d62f14e872426a7d8c78a9f6063...4a98f14feed2c29c76f019675247255aa0c6f5fc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/34e37ad3b77b4d62f14e872426a7d8c78a9f6063...4a98f14feed2c29c76f019675247255aa0c6f5fc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 11 11:36:23 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Mon, 11 May 2020 07:36:23 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 26 commits: rts/CNF: Fix fixup comparison function Message-ID: <5eb938b737d30_61673f81a3bd711c10434746@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 4df3fc58 by Ben Gamari at 2020-05-11T07:35:36-04:00 rts/CNF: Fix fixup comparison function Previously we would implicitly convert the difference between two words to an int, resulting in an integer overflow on 64-bit machines. Fixes #16992 - - - - - 3bfd9f37 by Ömer Sinan Ağacan at 2020-05-11T07:35:42-04:00 Pack some of IdInfo fields into a bit field This reduces residency of compiler quite a bit on some programs. Example stats when building T10370: Before: 2,871,242,832 bytes allocated in the heap 4,693,328,008 bytes copied during GC 33,941,448 bytes maximum residency (276 sample(s)) 375,976 bytes maximum slop 83 MiB total memory in use (0 MB lost due to fragmentation) After: 2,858,897,344 bytes allocated in the heap 4,629,255,440 bytes copied during GC 32,616,624 bytes maximum residency (278 sample(s)) 314,400 bytes maximum slop 80 MiB total memory in use (0 MB lost due to fragmentation) So -3.9% residency, -1.3% bytes copied and -0.4% allocations. Fixes #17497 Metric Decrease: T9233 T9675 - - - - - 3f82ae6e by Simon Peyton Jones at 2020-05-11T07:35:42-04:00 Avoid useless w/w split This patch is just a tidy-up for the post-strictness-analysis worker wrapper split. Consider f x = x Strictnesss analysis does not lead to a w/w split, so the obvious thing is to leave it 100% alone. But actually, because the RHS is small, we ended up adding a StableUnfolding for it. There is some reason to do this if we choose /not/ do to w/w on the grounds that the function is small. See Note [Don't w/w inline small non-loop-breaker things] But there is no reason if we would not have done w/w anyway. This patch just moves the conditional to later. Easy. This does move soem -ddump-simpl printouts around a bit. I also discovered that the previous code was overwritten an InlineCompulsory with InlineStable, which is utterly wrong. That in turn meant that some default methods (marked InlineCompulsory) were getting their InlineCompulsory squashed. This patch fixes that bug --- but of course that does mean a bit more inlining! Metric Decrease: T9233 T9675 Metric Increase: T12707 T3064 T4029 T9872b T9872d haddock.Cabal - - - - - 6d6b6152 by Ben Gamari at 2020-05-11T07:35:43-04:00 get-win32-tarballs: Fix base URL Revert a change previously made for testing purposes. - - - - - 89eadf1e by Ben Gamari at 2020-05-11T07:35:43-04:00 get-win32-tarballs: Improve diagnostics output - - - - - 2617473a by Simon Jakobi at 2020-05-11T07:35:44-04:00 docs: Add examples for Data.Semigroup.Arg{Min,Max} Context: #17153 - - - - - e3344eb6 by Baldur Blöndal at 2020-05-11T07:35:47-04:00 Predicate, Equivalence derive via `.. -> a -> All' - - - - - 7f3197a8 by Ben Gamari at 2020-05-11T07:35:48-04:00 Add few cleanups of the CAF logic Give the NameSet of non-CAFfy names a proper newtype to distinguish it from all of the other NameSets floating about. - - - - - 762d6c2e by Emeka Nkurumeh at 2020-05-11T07:35:50-04:00 fix printf warning when using with ghc with clang on mingw - - - - - 4f2f9952 by Daniel Gröber at 2020-05-11T07:35:56-04:00 Fix non power-of-two Storable.alignment in Capi_Ctype tests Alignments passed to alloca and friends must be a power of two for the code in allocatePinned to work properly. Commit 41230e2601 ("Zero out pinned block alignment slop when profiling") introduced an ASSERT for this but this test was still violating it. - - - - - d8eedfb5 by Daniel Gröber at 2020-05-11T07:35:56-04:00 Improve ByteArray# documentation regarding alignment - - - - - 695e0866 by Daniel Gröber at 2020-05-11T07:35:56-04:00 Document word-size rounding of ByteArray# memory (Fix #14731) - - - - - 0ea9ea4a by Daniel Gröber at 2020-05-11T07:35:56-04:00 Throw IOError when allocaBytesAligned gets non-power-of-two align - - - - - 8f9179c3 by Artem Pelenitsyn at 2020-05-11T07:35:58-04:00 Don't reload environment files on every setSessionDynFlags Makes `interpretPackageEnv` (which loads envirinment files) a part of `parseDynamicFlags` (parsing command-line arguments, which is typically done once) instead of `setSessionDynFlags` (which is typically called several times). Making several (transitive) calls to `interpretPackageEnv`, as before, caused #18125 #16318, which should be fixed now. - - - - - cc4da761 by Ben Gamari at 2020-05-11T07:35:59-04:00 GHC.Cmm.Opt: Handle MO_XX_Conv This MachOp was introduced by 2c959a1894311e59cd2fd469c1967491c1e488f3 but a wildcard match in cmmMachOpFoldM hid the fact that it wasn't handled. Ideally we would eliminate the match but this appears to be a larger task. Fixes #18141. - - - - - 86c69d54 by Hécate at 2020-05-11T07:36:02-04:00 fix(documentation): Fix the RST links to GHC.Prim - - - - - c7bf65b0 by Baldur Blöndal at 2020-05-11T07:36:03-04:00 Document (->) using inferred quantification for its runtime representations. Fixes #18142. - - - - - 112214cb by Takenobu Tani at 2020-05-11T07:36:06-04:00 Tweak man page for ghc command This commit updates the ghc command's man page as followings: * Enable `man_show_urls` to show URL addresses in the `DESCRIPTION` section of ghc.rst, because sphinx currently removes hyperlinks for man pages. * Add a `SEE ALSO` section to point to the GHC homepage - - - - - 53a04549 by Takenobu Tani at 2020-05-11T07:36:08-04:00 GHCi: Add link to the user's guide in help message This commit adds a link to the user's guide in ghci's `:help` message. Newcomers could easily reach to details of ghci. - - - - - 806c84aa by Jeff Happily at 2020-05-11T07:36:10-04:00 Handle single unused import - - - - - 756a5a96 by Ben Gamari at 2020-05-11T07:36:10-04:00 users-guide: Add discussion of shared object naming Fixes #18074. - - - - - 06e4f445 by Ben Gamari at 2020-05-11T07:36:11-04:00 Ensure that printMinimalImports closes handle Fixes #18166. - - - - - de5a0d55 by Ben Gamari at 2020-05-11T07:36:11-04:00 testsuite: Print sign of performance changes Executes the minor formatting change in the tabulated performance changes suggested in #18135. - - - - - 678d3246 by Ben Gamari at 2020-05-11T07:36:12-04:00 hadrian: Tell testsuite driver about LLVM availability This reflects the logic present in the Make build system into Hadrian. Fixes #18167. - - - - - 82efb5ae by Ben Gamari at 2020-05-11T07:36:12-04:00 testsuite: Add testcase for #18129 - - - - - df0c5d4e by Ben Gamari at 2020-05-11T07:36:13-04:00 Revert "Specify kind variables for inferred kinds in base." As noted in !3132, this has rather severe knock-on consequences in user-code. We'll need to revisit this before merging something along these lines. This reverts commit 9749fe1223d182b1f8e7e4f7378df661c509f396. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Opt/WorkWrap.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/UpdateCafInfos.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Name/Set.hs - docs/users_guide/conf.py - docs/users_guide/editing-guide.rst - docs/users_guide/exts/ffi.rst - docs/users_guide/exts/primitives.rst - docs/users_guide/ghc.rst - docs/users_guide/packages.rst - docs/users_guide/phases.rst - ghc/GHCi/UI.hs - hadrian/src/Settings/Builders/RunTest.hs - includes/rts/Messages.h - libraries/base/Control/Arrow.hs - libraries/base/Control/Category.hs - libraries/base/Data/Data.hs - libraries/base/Data/Dynamic.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7988c647706dfb0bb9f9132c29ff89493ccfdf96...df0c5d4e8d76cefe793dfd0a8d6f698f51681e6c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7988c647706dfb0bb9f9132c29ff89493ccfdf96...df0c5d4e8d76cefe793dfd0a8d6f698f51681e6c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 11 12:50:46 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Mon, 11 May 2020 08:50:46 -0400 Subject: [Git][ghc/ghc][wip/andreask/refactor_cmm_weights] Refactor linear reg alloc to remember past assignments. Message-ID: <5eb94a26375ab_61673f819aad978c10480838@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/refactor_cmm_weights at Glasgow Haskell Compiler / GHC Commits: 04831c6d by Andreas Klebinger at 2020-05-11T14:48:30+02:00 Refactor linear reg alloc to remember past assignments. When assigning registers we now first try registers we assigned to in the past, instead of picking the "first" one. This is in extremely helpful when dealing with loops for which variables are dead for part of the loop. This is important for patterns like this: foo = arg1 loop: use(foo) ... foo = getVal() goto loop; There we: * assign foo to the register of arg1. * use foo, it's dead after this use as it's overwritten after. * do other things. * look for a register to put foo in. If we pick an arbitrary one it might differ from the register the start of the loop expect's foo to be in. To fix this we simply look for past register assignments for the given variable. If we find one and the register is free we use that register. This reduces the need for fixup blocks which match the register assignment between blocks. In the example above between the end and the head of the loop. This patch also moves branch weight estimation ahead of register allocation and adds a flag to control it (cmm-static-pred). * It means the linear allocator is more likely to assign the hotter code paths first. * If it assign these first we are: + Less likely to spill on the hot path. + Less likely to introduce fixup blocks on the hot path. These two measure combined are surprisingly effective. Based on nofib we get in the mean: * -0.9% instructions executed * -0.1% reads/writes * -0.2% code size. * -0.1% compiler allocations. * -0.9% compile time. * -0.8% runtime. Most of the benefits are simply a result of removing redundant moves and spills. Reduced compiler allocations likely are the result of less code being generated. (The added lookup is mostly non-allocating). - - - - - 15 changed files: - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Reg/Linear.hs - compiler/GHC/CmmToAsm/Reg/Linear/Base.hs - compiler/GHC/CmmToAsm/Reg/Linear/PPC.hs - compiler/GHC/CmmToAsm/Reg/Linear/SPARC.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/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/utils/Outputable.hs - docs/users_guide/using-optimisation.rst Changes: ===================================== compiler/GHC/CmmToAsm.hs ===================================== @@ -729,7 +729,7 @@ cmmNativeGen dflags this_mod modLoc ncgImpl us fileIds dbgMap cmm count let optimizedCFG :: Maybe CFG optimizedCFG = - optimizeCFG (cfgWeightInfo dflags) cmm <$!> postShortCFG + optimizeCFG (gopt Opt_CmmStaticPred dflags) (cfgWeightInfo dflags) cmm <$!> postShortCFG maybeDumpCfg dflags optimizedCFG "CFG Weights - Final" proc_name ===================================== compiler/GHC/CmmToAsm/BlockLayout.hs ===================================== @@ -636,22 +636,8 @@ sequenceChain :: forall a i. (Instruction i, Outputable i) -> [GenBasicBlock i] -- ^ Blocks placed in sequence. sequenceChain _info _weights [] = [] sequenceChain _info _weights [x] = [x] -sequenceChain info weights' blocks@((BasicBlock entry _):_) = - let weights :: CFG - weights = --pprTrace "cfg'" (pprEdgeWeights cfg') - cfg' - where - (_, globalEdgeWeights) = {-# SCC mkGlobalWeights #-} mkGlobalWeights entry weights' - cfg' = {-# SCC rewriteEdges #-} - mapFoldlWithKey - (\cfg from m -> - mapFoldlWithKey - (\cfg to w -> setEdgeWeight cfg (EdgeWeight w) from to ) - cfg m ) - weights' - globalEdgeWeights - - directEdges :: [CfgEdge] +sequenceChain info weights blocks@((BasicBlock entry _):_) = + let directEdges :: [CfgEdge] directEdges = sortBy (flip compare) $ catMaybes . map relevantWeight $ (infoEdgeList weights) where relevantWeight :: CfgEdge -> Maybe CfgEdge ===================================== compiler/GHC/CmmToAsm/CFG.hs ===================================== @@ -670,11 +670,21 @@ findBackEdges root cfg = typedEdges = classifyEdges root getSuccs edges :: [((BlockId,BlockId),EdgeType)] - -optimizeCFG :: D.CfgWeights -> RawCmmDecl -> CFG -> CFG -optimizeCFG _ (CmmData {}) cfg = cfg -optimizeCFG weights (CmmProc info _lab _live graph) cfg = - {-# SCC optimizeCFG #-} +optimizeCFG :: Bool -> D.CfgWeights -> RawCmmDecl -> CFG -> CFG +optimizeCFG _ _ (CmmData {}) cfg = cfg +optimizeCFG doStaticPred weights proc@(CmmProc _info _lab _live graph) cfg = + (if doStaticPred then staticPredCfg (g_entry graph) else id) $ + optHsPatterns weights proc $ cfg + +-- | Modify branch weights based on educated guess on +-- patterns GHC tends to produce and how they affect +-- performance. +-- +-- Most importantly we penalize jumps across info tables. +optHsPatterns :: D.CfgWeights -> RawCmmDecl -> CFG -> CFG +optHsPatterns _ (CmmData {}) cfg = cfg +optHsPatterns weights (CmmProc info _lab _live graph) cfg = + {-# SCC optHsPatterns #-} -- pprTrace "Initial:" (pprEdgeWeights cfg) $ -- pprTrace "Initial:" (ppr $ mkGlobalWeights (g_entry graph) cfg) $ @@ -749,6 +759,21 @@ optimizeCFG weights (CmmProc info _lab _live graph) cfg = | CmmSource { trans_cmmNode = CmmCondBranch {} } <- source = True | otherwise = False +-- | +staticPredCfg :: BlockId -> CFG -> CFG +staticPredCfg entry cfg = cfg' + where + (_, globalEdgeWeights) = {-# SCC mkGlobalWeights #-} + mkGlobalWeights entry cfg + cfg' = {-# SCC rewriteEdges #-} + mapFoldlWithKey + (\cfg from m -> + mapFoldlWithKey + (\cfg to w -> setEdgeWeight cfg (EdgeWeight w) from to ) + cfg m ) + cfg + globalEdgeWeights + -- | Determine loop membership of blocks based on SCC analysis -- This is faster but only gives yes/no answers. loopMembers :: HasDebugCallStack => CFG -> LabelMap Bool @@ -922,6 +947,10 @@ revPostorderFrom cfg root = -- reverse post order. Which is required for diamond control flow to work probably. -- -- We also apply a few prediction heuristics (based on the same paper) +-- +-- The returned result represents frequences. +-- For blocks it's the expected number of executions and +-- for edges is the number of traversals. {-# NOINLINE mkGlobalWeights #-} {-# SCC mkGlobalWeights #-} ===================================== compiler/GHC/CmmToAsm/Instr.hs ===================================== @@ -37,7 +37,10 @@ import GHC.CmmToAsm.Config -- (for allocation purposes, anyway). -- data RegUsage - = RU [Reg] [Reg] + = RU { + reads :: [Reg], + writes :: [Reg] + } -- | No regs read or written to. noUsage :: RegUsage ===================================== compiler/GHC/CmmToAsm/Reg/Linear.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE BangPatterns, CPP, ScopedTypeVariables #-} +{-# LANGUAGE ConstraintKinds #-} {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} @@ -137,6 +138,7 @@ import GHC.Platform import Data.Maybe import Data.List import Control.Monad +import Control.Applicative -- ----------------------------------------------------------------------------- -- Top level of the register allocator @@ -229,8 +231,12 @@ linearRegAlloc config entry_ids block_live sccs go f = linearRegAlloc' config f entry_ids block_live sccs platform = ncgPlatform config +-- | +type OutputableRegConstraint freeRegs instr = + (FR freeRegs, Outputable freeRegs, Outputable instr, Instruction instr) + linearRegAlloc' - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => NCGConfig -> freeRegs -> [BlockId] -- ^ entry points @@ -246,7 +252,7 @@ linearRegAlloc' config initFreeRegs entry_ids block_live sccs return (blocks, stats, getStackUse stack) -linearRA_SCCs :: (FR freeRegs, Instruction instr, Outputable instr) +linearRA_SCCs :: OutputableRegConstraint freeRegs instr => [BlockId] -> BlockMap RegSet -> [NatBasicBlock instr] @@ -281,7 +287,7 @@ linearRA_SCCs entry_ids block_live blocksAcc (CyclicSCC blocks : sccs) more sanity checking to guard against this eventuality. -} -process :: (FR freeRegs, Instruction instr, Outputable instr) +process :: OutputableRegConstraint freeRegs instr => [BlockId] -> BlockMap RegSet -> [GenBasicBlock (LiveInstr instr)] @@ -325,15 +331,21 @@ process entry_ids block_live (b@(BasicBlock id _) : blocks) -- | Do register allocation on this basic block -- processBlock - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ live regs on entry to each basic block -> LiveBasicBlock instr -- ^ block to do register allocation on -> RegM freeRegs [NatBasicBlock instr] -- ^ block with registers allocated processBlock block_live (BasicBlock id instrs) - = do initBlock id block_live + = do -- pprTraceM "processBlock" $ text "" $$ ppr (BasicBlock id instrs) + initBlock id block_live + + -- assig <- getBlockAssigR + -- pprTraceM "assignment" $ ppr assig + (instrs', fixups) <- linearRA block_live [] [] id instrs + -- pprTraceM "blockResult" $ ppr (instrs', fixups) return $ BasicBlock id instrs' : fixups @@ -369,7 +381,7 @@ initBlock id block_live -- | Do allocation for a sequence of instructions. linearRA - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ map of what vregs are live on entry to each block. -> [instr] -- ^ accumulator for instructions already processed. -> [NatBasicBlock instr] -- ^ accumulator for blocks of fixup code. @@ -396,7 +408,7 @@ linearRA block_live accInstr accFixups id (instr:instrs) -- | Do allocation for a single instruction. raInsn - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ 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 @@ -476,7 +488,7 @@ isInReg src assig | Just (InReg _) <- lookupUFM assig src = True | otherwise = False -genRaInsn :: (FR freeRegs, Instruction instr, Outputable instr) +genRaInsn :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -> [instr] -> BlockId @@ -486,6 +498,7 @@ genRaInsn :: (FR freeRegs, Instruction instr, Outputable instr) -> RegM freeRegs ([instr], [NatBasicBlock instr]) genRaInsn block_live new_instrs block_id instr r_dying w_dying = do +-- pprTraceM "genRaInsn" $ ppr (block_id, instr) platform <- getPlatform case regUsageOfInstr platform instr of { RU read written -> do @@ -525,10 +538,12 @@ genRaInsn block_live new_instrs block_id instr r_dying w_dying = do (fixup_blocks, adjusted_instr) <- joinToTargets block_live block_id instr +-- when (not $ null fixup_blocks) $ pprTraceM "genRA:FixBlocks" $ ppr fixup_blocks + -- Debugging - show places where the reg alloc inserted -- assignment fixup blocks. - -- when (not $ null fixup_blocks) $ - -- pprTrace "fixup_blocks" (ppr fixup_blocks) (return ()) +-- when (not $ null fixup_blocks) $ +-- pprTrace "fixup_blocks" (ppr fixup_blocks) (return ()) -- (e) Delete all register assignments for temps which are read -- (only) and die here. Update the free register list. @@ -737,7 +752,7 @@ data SpillLoc = ReadMem StackSlot -- reading from register only in memory -- the list of free registers and free stack slots. allocateRegsAndSpill - :: (FR freeRegs, Outputable instr, Instruction instr) + :: forall freeRegs instr. (FR freeRegs, Outputable instr, Instruction instr) => Bool -- True <=> reading (load up spilled regs) -> [VirtualReg] -- don't push these out -> [instr] -- spill insns @@ -749,7 +764,8 @@ allocateRegsAndSpill _ _ spills alloc [] = return (spills, reverse alloc) allocateRegsAndSpill reading keep spills alloc (r:rs) - = do assig <- getAssigR + = do assig <- getAssigR :: RegM freeRegs (RegMap Loc) + -- pprTraceM "allocateRegsAndSpill:assig" (ppr (r:rs) $$ ppr assig) let doSpill = allocRegsAndSpill_spill reading keep spills alloc r rs assig case lookupUFM assig r of -- case (1a): already in a register @@ -779,6 +795,22 @@ allocateRegsAndSpill reading keep spills alloc (r:rs) | otherwise -> doSpill WriteNew +-- | Given a virtual reg find a preferred real register. +-- Note: I tried returning a list of registers, but that +-- turned out to barely matter but added a few tenths of +-- a percent to compile time. +findPrefRealReg :: forall freeRegs u. Uniquable u + => u -> RegM freeRegs (Maybe RealReg) +findPrefRealReg vreg = do + bassig <- getBlockAssigR :: RegM freeRegs (BlockMap (freeRegs,RegMap Loc)) + return $ foldr (findVirtRegAssig) Nothing bassig + where + findVirtRegAssig :: (freeRegs,RegMap Loc) -> Maybe RealReg -> Maybe RealReg + findVirtRegAssig assig z = + z <|> case lookupUFM (snd assig) vreg of + Just (InReg real_reg) -> Just real_reg + Just (InBoth real_reg _) -> Just real_reg + _ -> z -- reading is redundant with reason, but we keep it around because it's -- convenient and it maintains the recursive structure of the allocator. -- EZY @@ -795,18 +827,26 @@ allocRegsAndSpill_spill :: (FR freeRegs, Instruction instr, Outputable instr) allocRegsAndSpill_spill reading keep spills alloc r rs assig spill_loc = do platform <- getPlatform freeRegs <- getFreeRegsR - let freeRegs_thisClass = frGetFreeRegs platform (classOfVirtualReg r) freeRegs + let freeRegs_thisClass = frGetFreeRegs platform (classOfVirtualReg r) freeRegs :: [RealReg] - case freeRegs_thisClass of + -- Can we put the variable into a register it already was? + pref_reg <- findPrefRealReg r + case freeRegs_thisClass of -- case (2): we have a free register - (my_reg : _) -> - do spills' <- loadTemp r spill_loc my_reg spills + (first_free : _) -> + do let final_reg + | Just reg <- pref_reg + , reg `elem` freeRegs_thisClass + = reg + | otherwise + = first_free + spills' <- loadTemp r spill_loc final_reg spills - setAssigR (addToUFM assig r $! newLocation spill_loc my_reg) - setFreeRegsR $ frAllocateReg platform my_reg freeRegs + setAssigR (addToUFM assig r $! newLocation spill_loc final_reg) + setFreeRegsR $ frAllocateReg platform final_reg freeRegs - allocateRegsAndSpill reading keep spills' (my_reg : alloc) rs + allocateRegsAndSpill reading keep spills' (final_reg : alloc) rs -- case (3): we need to push something out to free up a register @@ -814,7 +854,8 @@ allocRegsAndSpill_spill reading keep spills alloc r rs assig spill_loc do let inRegOrBoth (InReg _) = True inRegOrBoth (InBoth _ _) = True inRegOrBoth _ = False - let candidates' = + let candidates' :: UniqFM Loc + candidates' = flip delListFromUFM keep $ filterUFM inRegOrBoth $ assig ===================================== compiler/GHC/CmmToAsm/Reg/Linear/Base.hs ===================================== @@ -30,6 +30,7 @@ import GHC.Types.Unique.FM import GHC.Types.Unique.Supply import GHC.Cmm.BlockId +data ReadingOrWriting = Reading | Writing deriving (Eq,Ord) -- | Used to store the register assignment on entry to a basic block. -- We use this to handle join points, where multiple branch instructions @@ -138,6 +139,8 @@ data RA_State freeRegs , ra_config :: !NCGConfig -- | (from,fixup,to) : We inserted fixup code between from and to - , ra_fixups :: [(BlockId,BlockId,BlockId)] } + , ra_fixups :: [(BlockId,BlockId,BlockId)] + + } ===================================== compiler/GHC/CmmToAsm/Reg/Linear/PPC.hs ===================================== @@ -1,3 +1,5 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} + -- | Free regs map for PowerPC module GHC.CmmToAsm.Reg.Linear.PPC where @@ -27,6 +29,9 @@ import Data.Bits data FreeRegs = FreeRegs !Word32 !Word32 deriving( Show ) -- The Show is used in an ASSERT +instance Outputable FreeRegs where + ppr = text . show + noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/SPARC.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for SPARC module GHC.CmmToAsm.Reg.Linear.SPARC where @@ -38,6 +39,9 @@ data FreeRegs instance Show FreeRegs where show = showFreeRegs +instance Outputable FreeRegs where + ppr = text . showFreeRegs + -- | A reg map where no regs are free to be allocated. noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 0 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/State.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE CPP, PatternSynonyms, DeriveFunctor #-} +{-# LANGUAGE ScopedTypeVariables #-} #if !defined(GHC_LOADED_INTO_GHCI) {-# LANGUAGE UnboxedTuples #-} ===================================== compiler/GHC/CmmToAsm/Reg/Linear/X86.hs ===================================== @@ -1,3 +1,4 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for i386 module GHC.CmmToAsm.Reg.Linear.X86 where @@ -9,12 +10,13 @@ import GHC.Platform.Reg.Class import GHC.Platform.Reg import Panic import GHC.Platform +import Outputable import Data.Word import Data.Bits newtype FreeRegs = FreeRegs Word32 - deriving Show + deriving (Show,Outputable) noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/X86_64.hs ===================================== @@ -1,3 +1,4 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for x86_64 module GHC.CmmToAsm.Reg.Linear.X86_64 where @@ -9,12 +10,13 @@ import GHC.Platform.Reg.Class import GHC.Platform.Reg import Panic import GHC.Platform +import Outputable import Data.Word import Data.Bits newtype FreeRegs = FreeRegs Word64 - deriving Show + deriving (Show,Outputable) noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -181,6 +181,7 @@ data GeneralFlag | Opt_LlvmFillUndefWithGarbage -- Testing for undef bugs (hidden flag) | Opt_IrrefutableTuples | Opt_CmmSink + | Opt_CmmStaticPred | Opt_CmmElimCommonBlocks | Opt_AsmShortcutting | Opt_OmitYields ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -3523,6 +3523,7 @@ fFlagsDeps = [ flagSpec "case-folding" Opt_CaseFolding, flagSpec "cmm-elim-common-blocks" Opt_CmmElimCommonBlocks, flagSpec "cmm-sink" Opt_CmmSink, + flagSpec "cmm-static-pred" Opt_CmmStaticPred, flagSpec "cse" Opt_CSE, flagSpec "stg-cse" Opt_StgCSE, flagSpec "stg-lift-lams" Opt_StgLiftLams, @@ -4074,6 +4075,7 @@ optLevelFlags -- see Note [Documenting optimisation flags] , ([1,2], Opt_CmmElimCommonBlocks) , ([2], Opt_AsmShortcutting) , ([1,2], Opt_CmmSink) + , ([1,2], Opt_CmmStaticPred) , ([1,2], Opt_CSE) , ([1,2], Opt_StgCSE) , ([2], Opt_StgLiftLams) ===================================== compiler/utils/Outputable.hs ===================================== @@ -847,6 +847,9 @@ instance Outputable Word16 where instance Outputable Word32 where ppr n = integer $ fromIntegral n +instance Outputable Word64 where + ppr n = integer $ fromIntegral n + instance Outputable Word where ppr n = integer $ fromIntegral n ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -214,6 +214,19 @@ by saying ``-fno-wombat``. to their usage sites. It also inlines simple expressions like literals or registers. +.. ghc-flag:: -fcmm-static-pred + :shortdesc: Enable static control flow prediction :ghc-flag:`-O`. + :type: dynamic + :reverse: -fno-cmm-static-pred + :category: + + :default: off but enabled with :ghc-flag:`-O`. + + This enables static control flow prediction on the final Cmm + code. If enabled GHC will apply certain heuristics to identify + loops and hot code paths. This information is then used by the + register allocation and code layout passes. + .. ghc-flag:: -fasm-shortcutting :shortdesc: Enable shortcutting on assembly. Implied by :ghc-flag:`-O2`. :type: dynamic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/04831c6d1ace8eb951b1045eb9a526ed51bc4fad -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/04831c6d1ace8eb951b1045eb9a526ed51bc4fad You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 11 13:02:37 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Mon, 11 May 2020 09:02:37 -0400 Subject: [Git][ghc/ghc][wip/andreask/refactor_cmm_weights] 168 commits: Revert accidental change in 9462452 Message-ID: <5eb94cededed4_616712a9b7f0104875c9@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/refactor_cmm_weights at Glasgow Haskell Compiler / GHC Commits: 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.0.0 This requires bumping the `exceptions` and `text` submodules to bring in commits that bump their respective upper version bounds on `template-haskell`. Fixes #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - ffd7eef2 by Takenobu Tani at 2020-04-22T23:09:50-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - e8a5d81b by Jonathan DK Gibbons at 2020-04-22T23:10:28-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - dcb7fe5a by John Ericson at 2020-04-22T23:10:28-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - cde23cd4 by John Ericson at 2020-04-22T23:10:28-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - 72cb6bcc by John Ericson at 2020-04-22T23:10:28-04:00 Generalize type of `matchCanFail` - - - - - 401f7bb3 by John Ericson at 2020-04-22T23:10:28-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 6c9fae23 by Alexis King at 2020-04-22T23:11:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 48b8951e by Roland Senn at 2020-04-22T23:11:51-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 34a45ee6 by Peter Trommler at 2020-04-22T23:12:27-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - ffde2348 by Simon Peyton Jones at 2020-04-22T23:13:06-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 6f84aca3 by Ben Gamari at 2020-04-22T23:13:43-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - c29f0fa6 by Andreas Klebinger at 2020-04-22T23:14:21-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 4b4a8b60 by Ben Gamari at 2020-04-22T23:14:57-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 831b6642 by Moritz Angermann at 2020-04-22T23:15:33-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - c409961a by Ryan Scott at 2020-04-22T23:16:12-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 125aa2b8 by Ömer Sinan Ağacan at 2020-04-22T23:16:51-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - 8ea37b01 by Sylvain Henry at 2020-04-22T23:17:34-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - cd8409c2 by Ryan Scott at 2020-04-23T11:39:24-04:00 Create di_scoped_tvs for associated data family instances properly See `Note [Associated data family instances and di_scoped_tvs]` in `GHC.Tc.TyCl.Instance`, which explains all of the moving parts. Fixes #18055. - - - - - 339e8ece by Ben Gamari at 2020-04-23T11:40:02-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 5946c85a by Ben Gamari at 2020-04-23T11:40:38-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - c42754d5 by John Ericson at 2020-04-23T18:32:43-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 72da0c29 by mniip at 2020-04-23T18:33:21-04:00 Add :doc to GHC.Prim - - - - - 2c23e2e3 by mniip at 2020-04-23T18:33:21-04:00 Include docs for non-primop entries in primops.txt as well - - - - - 0ac29c88 by mniip at 2020-04-23T18:33:21-04:00 GHC.Prim docs: note and test - - - - - b0fbfc75 by John Ericson at 2020-04-24T12:07:14-04:00 Switch order on `GhcMake.IsBoot` In !1798 we were requested to replace many `Bool`s with this data type. But those bools had `False` meaning `NotBoot`, so the `Ord` instance would be flipped if we use this data-type as-is. Since the planned formally-`Bool` occurrences vastly outnumber the current occurrences, we figured it would be better to conform the `Ord` instance to how the `Bool` is used now, fixing any issues, rather than fix them currently with the bigger refactor later in !1798. That way, !1798 can be a "pure" refactor with no behavioral changes. - - - - - af332442 by Sylvain Henry at 2020-04-26T13:55:14-04:00 Modules: Utils and Data (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - cd4434c8 by Sylvain Henry at 2020-04-26T13:55:16-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 22bf5c73 by Ömer Sinan Ağacan at 2020-04-26T13:55:22-04:00 Tweak includes in non-moving GC headers We don't use hash tables in non-moving GC so remove the includes. This breaks Compact.c as existing includes no longer include Hash.h, so include Hash.h explicitly in Compact.c. - - - - - 99823ed2 by Sylvain Henry at 2020-04-27T20:24:46-04:00 TH: fix Show/Eq/Ord instances for Bytes (#16457) We shouldn't compare pointer values but the actual bytes. - - - - - c62271a2 by Alp Mestanogullari at 2020-04-27T20:25:33-04:00 hadrian: always capture both stdout and stderr when running a builder fails The idea being that when a builder('s command) fails, we quite likely want to have all the information available to figure out why. Depending on the builder _and_ the particular problem, the useful bits of information can be printed on stdout or stderr. We accomplish this by defining a simple wrapper for Shake's `cmd` function, that just _always_ captures both streams in case the command returns a non-zero exit code, and by using this wrapper everywhere in `hadrian/src/Builder.hs`. Fixes #18089. - - - - - 4b9764db by Ryan Scott at 2020-04-28T15:40:04-04:00 Define a Quote IO instance Fixes #18103. - - - - - 518a63d4 by Ryan Scott at 2020-04-28T15:40:42-04:00 Make boxed 1-tuples have known keys Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. - - - - - 2cfc4ab9 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Document backpack fields in DynFlags - - - - - 10a2ba90 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 69562e34 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 9e2c8e0e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - ea717aa4 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 10d15f1e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 8bfb0219 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - 71484b09 by Alexis King at 2020-04-30T01:57:35-04:00 Allow block arguments in arrow control operators Arrow control operators have their own entries in the grammar, so they did not cooperate with BlockArguments. This was just a minor oversight, so this patch adjusts the grammar to add the desired behavior. fixes #18050 - - - - - a48cd2a0 by Alexis King at 2020-04-30T01:57:35-04:00 Allow LambdaCase to be used as a command in proc notation - - - - - f4d3773c by Alexis King at 2020-04-30T01:57:35-04:00 Document BlockArguments/LambdaCase support in arrow notation - - - - - 5bdfdd13 by Simon Peyton Jones at 2020-04-30T01:58:15-04:00 Add tests for #17873 - - - - - 19b701c2 by Simon Peyton Jones at 2020-04-30T07:30:13-04:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - 014ef4a3 by Matthew Pickering at 2020-04-30T07:30:50-04:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 2aa67611 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - 54dad3cf by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - 99ff8145 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 05b0a9fd by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 Remove OneShotInfo field of LFReEntrant, document OneShotInfo The field is only used in withNewTickyCounterFun and it's easier to directly pass a parameter for one-shot info to withNewTickyCounterFun instead of passing it via LFReEntrant. This also makes !2842 simpler. Other changes: - New Note (by SPJ) [OneShotInfo overview] added. - Arity argument of thunkCode removed as it's always 0. - - - - - a43620c6 by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 GHC.StgToCmm.Ticky: remove a few unused stuff - - - - - 780de9e1 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Use platform in Iface Binary - - - - - f8386c7b by Sylvain Henry at 2020-05-01T10:37:39-04:00 Refactor PprDebug handling If `-dppr-debug` is set, then PprUser and PprDump styles are silently replaced with PprDebug style. This was done in `mkUserStyle` and `mkDumpStyle` smart constructors. As a consequence they needed a DynFlags parameter. Now we keep the original PprUser and PprDump styles until they are used to create an `SDocContext`. I.e. the substitution is only performed in `initSDocContext`. - - - - - b3df9e78 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Remove PprStyle param of logging actions Use `withPprStyle` instead to apply a specific style to a SDoc. - - - - - de9fc995 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Fully remove PprDebug PprDebug was a pain to deal with consistently as it is implied by `-dppr-debug` but it isn't really a PprStyle. We remove it completely and query the appropriate SDoc flag instead (`sdocPprDebug`) via helpers (`getPprDebug` and its friends). - - - - - 8b51fcbd by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Only call checkSingle if we would report warnings - - - - - fd7ea0fe by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 7bfe9ac5 by Ben Gamari at 2020-05-03T04:41:33-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. - - - - - c560dd07 by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Move eventlog documentation users guide - - - - - 02543d5e by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Add documentation for non-moving GC events - - - - - b465dd45 by Alexis King at 2020-05-03T04:42:12-04:00 Flatten nested casts in the simple optimizer Normally, we aren’t supposed to generated any nested casts, since mkCast takes care to flatten them, but the simple optimizer didn’t use mkCast, so they could show up after inlining. This isn’t really a problem, since the simplifier will clean them up immediately anyway, but it can clutter the -ddump-ds output, and it’s an extremely easy fix. closes #18112 - - - - - 8bdc03d6 by Simon Peyton Jones at 2020-05-04T01:56:59-04:00 Don't return a panic in tcNestedSplice In GHC.Tc.Gen.Splice.tcNestedSplice we were returning a typechecked expression of "panic". That is usually OK, because the result is discarded. But it happens that tcApp now looks at the typechecked expression, trivially, to ask if it is tagToEnum. So being bottom is bad. Moreover a debug-trace might print it out. So better to return a civilised expression, even though it is usually discarded. - - - - - 0bf640b1 by Baldur Blöndal at 2020-05-04T01:57:36-04:00 Don't require parentheses around via type (`-XDerivingVia'). Fixes #18130". - - - - - 30272412 by Artem Pelenitsyn at 2020-05-04T13:19:59-04:00 Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) - - - - - b9f7c08f by jneira at 2020-05-04T13:20:37-04:00 Remove unused hs-boot file - - - - - 1d8f80cd by Sylvain Henry at 2020-05-05T03:22:46-04:00 Remove references to -package-key * remove references to `-package-key` which has been removed in 2016 (240ddd7c39536776e955e881d709bbb039b48513) * remove support for `-this-package-key` which has been deprecated at the same time - - - - - 7bc3a65b by Sylvain Henry at 2020-05-05T03:23:31-04:00 Remove SpecConstrAnnotation (#13681) This has been deprecated since 2013. Use GHC.Types.SPEC instead. Make GHC.Exts "not-home" for haddock Metric Decrease: haddock.base - - - - - 3c862f63 by DenisFrezzato at 2020-05-05T03:24:15-04:00 Fix Haskell98 short description in documentation - - - - - 2420c555 by Ryan Scott at 2020-05-05T03:24:53-04:00 Add regression tests for #16244, #16245, #16758 Commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70 ended up fixing quite a few bugs: * This commit fixes #16244 completely. A regression test has been added. * This commit fixes one program from #16245. (The program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211369 still panics, and the program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211400 still loops infinitely.) A regression test has been added for this program. * This commit fixes #16758. Accordingly, this patch removes the `expect_broken` label from the `T16758` test case, moves it from `should_compile` to `should_fail` (as it should produce an error message), and checks in the expected stderr. - - - - - 40c71c2c by Sylvain Henry at 2020-05-05T03:25:31-04:00 Fix colorized error messages (#18128) In b3df9e780fb2f5658412c644849cd0f1e6f50331 I broke colorized messages by using "dump" style instead of "user" style. This commits fixes it. - - - - - 7ab6ab09 by Richard Eisenberg at 2020-05-06T04:39:32-04:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG ------------------------- - - - - - 420b957d by Ben Gamari at 2020-05-06T04:40:08-04:00 rts: Zero block flags with -DZ Block flags are very useful for determining the state of a block. However, some block allocator users don't touch them, leading to misleading values. Ensure that we zero then when zero-on-gc is set. This is safe and makes the flags more useful during debugging. - - - - - 740b3b8d by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix incorrect failed_to_evac value during deadlock gc Previously we would incorrectly set the failed_to_evac flag if we evacuated a value due to a deadlock GC. This would cause us to mark more things as dirty than strictly necessary. It also turned up a nasty but which I will fix next. - - - - - b2d72c75 by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - 9f3e6884 by Zubin Duggal at 2020-05-06T04:41:08-04:00 Allow atomic update of NameCache in readHieFile The situation arises in ghcide where multiple different threads may need to update the name cache, therefore with the older interface it could happen that you start reading a hie file with name cache A and produce name cache A + B, but another thread in the meantime updated the namecache to A + C. Therefore if you write the new namecache you will lose the A' updates from the second thread. Updates haddock submodule - - - - - edec6a6c by Ryan Scott at 2020-05-06T04:41:57-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _)`. Fixes #18127. - - - - - a95e7fe0 by Ömer Sinan Ağacan at 2020-05-06T04:42:39-04:00 ELF linker: increment curSymbol after filling in fields of current entry The bug was introduced in a8b7cef4d45 which added a field to the `symbols` array elements and then updated this code incorrectly: - oc->symbols[curSymbol++] = nm; + oc->symbols[curSymbol++].name = nm; + oc->symbols[curSymbol].addr = symbol->addr; - - - - - cab1871a by Sylvain Henry at 2020-05-06T04:43:21-04:00 Move LeadingUnderscore into Platform (#17957) Avoid direct use of DynFlags to know if symbols must be prefixed by an underscore. - - - - - 94e7c563 by Sylvain Henry at 2020-05-06T04:43:21-04:00 Don't use DynFlags in showLinkerState (#17957) - - - - - 9afd9251 by Ryan Scott at 2020-05-06T04:43:58-04:00 Refactoring: Use bindSigTyVarsFV in rnMethodBinds `rnMethodBinds` was explicitly using `xoptM` to determine if `ScopedTypeVariables` is enabled before bringing type variables bound by the class/instance header into scope. However, this `xoptM` logic is already performed by the `bindSigTyVarsFV` function. This patch uses `bindSigTyVarsFV` in `rnMethodBinds` to reduce the number of places where we need to consult if `ScopedTypeVariables` is on. This is purely refactoring, and there should be no user-visible change in behavior. - - - - - 6f6d72b2 by Brian Foley at 2020-05-08T15:29:25-04:00 Remove further dead code found by a simple Python script. Avoid removing some functions that are part of an API even though they're not used in-tree at the moment. - - - - - 78bf8bf9 by Julien Debon at 2020-05-08T15:29:28-04:00 Add doc examples for Bifoldable See #17929 - - - - - 66f0a847 by Julien Debon at 2020-05-08T15:29:29-04:00 doc (Bitraversable): Add examples to Bitraversable * Add examples to Data.Bitraversable * Fix formatting for (,) in Bitraversable and Bifoldable * Fix mistake on bimapAccumR documentation See #17929 - - - - - 9749fe12 by Baldur Blöndal at 2020-05-08T15:29:32-04:00 Specify kind variables for inferred kinds in base. - - - - - 4e9aef9e by John Ericson at 2020-05-08T15:29:36-04:00 HsSigWcTypeScoping: Pull in documentation from stray location - - - - - f4d5c6df by John Ericson at 2020-05-08T15:29:36-04:00 Rename local `real_fvs` to `implicit_vs` It doesn't make sense to call the "free" variables we are about to implicitly bind the real ones. - - - - - 20570b4b by John Ericson at 2020-05-08T15:29:36-04:00 A few tiny style nits with renaming - Use case rather than guards that repeatedly scrutenize same thing. - No need for view pattern when `L` is fine. - Use type synnonym to convey the intent like elsewhere. - - - - - 09ac8de5 by John Ericson at 2020-05-08T15:29:36-04:00 Add `forAllOrNothing` function with note - - - - - bb35c0e5 by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Document lawlessness of Ap's Num instance - - - - - cdd229ff by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply suggestion to libraries/base/Data/Monoid.hs - - - - - 926d2aab by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply more suggestions from Simon Jakobi - - - - - 7a763cff by Adam Gundry at 2020-05-08T15:29:41-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. - - - - - 88e3c815 by Simon Peyton Jones at 2020-05-08T15:29:41-04:00 Fix specialisation for DFuns When specialising a DFun we must take care to saturate the unfolding. See Note [Specialising DFuns] in Specialise. Fixes #18120 - - - - - 86c77b36 by Greg Steuck at 2020-05-08T15:29:45-04:00 Remove unused SEGMENT_PROT_RWX It's been unused for a year and is problematic on any OS which requires W^X for security. - - - - - 9d97f4b5 by nineonine at 2020-05-08T15:30:03-04:00 Add test for #16167 - - - - - aa318338 by Ryan Scott at 2020-05-08T15:30:04-04:00 Bump exceptions submodule so that dist-boot is .gitignore'd `exceptions` is a stage-0 boot library as of commit 30272412fa437ab8e7a8035db94a278e10513413, which means that building `exceptions` in a GHC tree will generate a `dist-boot` directory. However, this directory was not specified in `exceptions`' `.gitignore` file, which causes it to dirty up the current `git` working directory. Accordingly, this bumps the `exceptions` submodule to commit ghc/packages/exceptions at 23c0b8a50d7592af37ca09beeec16b93080df98f, which adds `dist-boot` to the `.gitignore` file. - - - - - ea86360f by Ömer Sinan Ağacan at 2020-05-08T15:30:30-04:00 Linker.c: initialize n_symbols of ObjectCode with other fields - - - - - 951c1fb0 by Sylvain Henry at 2020-05-09T21:46:38-04:00 Fix unboxed-sums GC ptr-slot rubbish value (#17791) This patch allows boot libraries to use unboxed sums without implicitly depending on `base` package because of `absentSumFieldError`. See updated Note [aBSENT_SUM_FIELD_ERROR_ID] in GHC.Core.Make - - - - - b352d63c by Ben Gamari at 2020-05-09T21:47:14-04:00 rts: Make non-existent linker search path merely a warning As noted in #18105, previously this resulted in a rather intrusive error message. This is in contrast to the general expectation that search paths are merely places to look, not places that must exist. Fixes #18105. - - - - - 5e3fee26 by Andreas Klebinger at 2020-05-11T15:01:34+02:00 Refactor linear reg alloc to remember past assignments. When assigning registers we now first try registers we assigned to in the past, instead of picking the "first" one. This is in extremely helpful when dealing with loops for which variables are dead for part of the loop. This is important for patterns like this: foo = arg1 loop: use(foo) ... foo = getVal() goto loop; There we: * assign foo to the register of arg1. * use foo, it's dead after this use as it's overwritten after. * do other things. * look for a register to put foo in. If we pick an arbitrary one it might differ from the register the start of the loop expect's foo to be in. To fix this we simply look for past register assignments for the given variable. If we find one and the register is free we use that register. This reduces the need for fixup blocks which match the register assignment between blocks. In the example above between the end and the head of the loop. This patch also moves branch weight estimation ahead of register allocation and adds a flag to control it (cmm-static-pred). * It means the linear allocator is more likely to assign the hotter code paths first. * If it assign these first we are: + Less likely to spill on the hot path. + Less likely to introduce fixup blocks on the hot path. These two measure combined are surprisingly effective. Based on nofib we get in the mean: * -0.9% instructions executed * -0.1% reads/writes * -0.2% code size. * -0.1% compiler allocations. * -0.9% compile time. * -0.8% runtime. Most of the benefits are simply a result of removing redundant moves and spills. Reduced compiler allocations likely are the result of less code being generated. (The added lookup is mostly non-allocating). - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - CODEOWNERS - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - compiler/prelude/PrelNames.hs-boot → compiler/GHC/Builtin/Names.hs-boot - compiler/prelude/THNames.hs → compiler/GHC/Builtin/Names/TH.hs - compiler/prelude/PrimOp.hs → compiler/GHC/Builtin/PrimOps.hs - + compiler/GHC/Builtin/PrimOps.hs-boot - compiler/prelude/TysWiredIn.hs → compiler/GHC/Builtin/Types.hs - compiler/prelude/TysWiredIn.hs-boot → compiler/GHC/Builtin/Types.hs-boot - compiler/typecheck/TcTypeNats.hs → compiler/GHC/Builtin/Types/Literals.hs - compiler/prelude/TysPrim.hs → compiler/GHC/Builtin/Types/Prim.hs - compiler/prelude/KnownUniques.hs → compiler/GHC/Builtin/Uniques.hs - compiler/prelude/KnownUniques.hs-boot → compiler/GHC/Builtin/Uniques.hs-boot - compiler/prelude/PrelInfo.hs → compiler/GHC/Builtin/Utils.hs - compiler/prelude/primops.txt.pp → compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.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/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Block.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/04831c6d1ace8eb951b1045eb9a526ed51bc4fad...5e3fee26e3791807ff7b99a4feecfe2da41ee316 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/04831c6d1ace8eb951b1045eb9a526ed51bc4fad...5e3fee26e3791807ff7b99a4feecfe2da41ee316 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 11 14:43:24 2020 From: gitlab at gitlab.haskell.org (John Ericson) Date: Mon, 11 May 2020 10:43:24 -0400 Subject: [Git][ghc/ghc] Deleted branch wip/remove-compiler-ghciTablesNextToCode Message-ID: <5eb9648c806f8_616711922e9c105186a8@gitlab.haskell.org.mail> John Ericson deleted branch wip/remove-compiler-ghciTablesNextToCode at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 11 16:15:39 2020 From: gitlab at gitlab.haskell.org (Sven Tennie) Date: Mon, 11 May 2020 12:15:39 -0400 Subject: [Git][ghc/ghc][wip/ghc-debug] Export StgTSO fields with the help of hsc2hs Message-ID: <5eb97a2be3f12_61673f819aad978c10537482@gitlab.haskell.org.mail> Sven Tennie pushed to branch wip/ghc-debug at Glasgow Haskell Compiler / GHC Commits: 2d912809 by Sven Tennie at 2020-05-11T18:15:23+02:00 Export StgTSO fields with the help of hsc2hs - - - - - 5 changed files: - libraries/ghc-heap/GHC/Exts/Heap.hs - libraries/ghc-heap/GHC/Exts/Heap/Closures.hs - + libraries/ghc-heap/GHC/Exts/Heap/FFIClosures.hsc - libraries/ghc-heap/ghc-heap.cabal.in - rts/Heap.c Changes: ===================================== libraries/ghc-heap/GHC/Exts/Heap.hs ===================================== @@ -58,6 +58,7 @@ import GHC.Exts.Heap.InfoTableProf import GHC.Exts.Heap.InfoTable #endif import GHC.Exts.Heap.Utils +import GHC.Exts.Heap.FFIClosures import Control.Monad import Data.Bits @@ -66,6 +67,8 @@ import GHC.Exts import GHC.Int import GHC.Word +import Foreign + #include "ghcconfig.h" class HasHeapRep (a :: TYPE rep) where @@ -290,6 +293,18 @@ getClosureX get_closure_raw x = do unless (length pts == 6) $ fail $ "Expected 6 ptr arguments to TSO, found " ++ show (length pts) + + threadId' <- allocaArray (length wds) (\ptr -> do + pokeArray ptr wds + id <- peekStgThreadID ptr + return id + ) + alloc_limit' <- allocaArray (length wds) (\ptr -> do + pokeArray ptr wds + alloc_limit <- peekAllocLimit ptr + return alloc_limit + ) + pure $ TSOClosure { info = itbl , _link = (pts !! 0) @@ -298,6 +313,8 @@ getClosureX get_closure_raw x = do , trec = (pts !! 3) , blocked_exceptions = (pts !! 4) , bq = (pts !! 5) + , threadId = threadId' + , alloc_limit = alloc_limit' } STACK -> do unless (length pts >= 1) $ ===================================== libraries/ghc-heap/GHC/Exts/Heap/Closures.hs ===================================== @@ -266,12 +266,16 @@ data GenClosure b -- | StgTSO | TSOClosure { info :: !StgInfoTable + -- pointers , _link :: !b , global_link :: !b , tsoStack :: !b -- ^ stackobj from StgTSO , trec :: !b , blocked_exceptions :: !b , bq :: !b + -- values + , threadId :: Word64 + , alloc_limit :: Int64 } | StackClosure ===================================== libraries/ghc-heap/GHC/Exts/Heap/FFIClosures.hsc ===================================== @@ -0,0 +1,20 @@ +module GHC.Exts.Heap.FFIClosures where + +#include "Rts.h" + +import Prelude +import Foreign +import Foreign.Ptr +import Data.Int + +import GHC.Exts.Heap.Closures + +peekStgThreadID :: Ptr a -> IO Word64 +peekStgThreadID ptr = do + id <- (#peek struct StgTSO_, id) ptr + return id + +peekAllocLimit :: Ptr a -> IO Int64 +peekAllocLimit ptr = do + alloc_limit <- (#peek struct StgTSO_, alloc_limit) ptr + return alloc_limit \ No newline at end of file ===================================== libraries/ghc-heap/ghc-heap.cabal.in ===================================== @@ -39,3 +39,4 @@ library GHC.Exts.Heap.InfoTable.Types GHC.Exts.Heap.InfoTableProf GHC.Exts.Heap.Utils + GHC.Exts.Heap.FFIClosures ===================================== rts/Heap.c ===================================== @@ -223,6 +223,13 @@ static StgWord collect_pointers(StgClosure *closure, StgWord size, StgClosure *p ASSERT((StgClosure *)((StgTSO *)closure)->bq != NULL); ptrs[nptrs++] = (StgClosure *)((StgTSO *)closure)->bq; + + int threadId = ((StgTSO *)closure)->id; + debugBelch("threadId : %u", threadId); + + int alloc_limit = ((StgTSO *)closure)->alloc_limit; + debugBelch("alloc_limit : %d", alloc_limit); + break; case STACK: ptrs[nptrs++] = (StgClosure *)((StgStack *)closure)->sp; View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2d912809c597916ebb686347f5ed808a50e9e0f8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2d912809c597916ebb686347f5ed808a50e9e0f8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 11 16:22:01 2020 From: gitlab at gitlab.haskell.org (Sven Tennie) Date: Mon, 11 May 2020 12:22:01 -0400 Subject: [Git][ghc/ghc][wip/ghc-debug] Export StgTSO fields with the help of hsc2hs Message-ID: <5eb97ba916d8f_61671288ff4c10543349@gitlab.haskell.org.mail> Sven Tennie pushed to branch wip/ghc-debug at Glasgow Haskell Compiler / GHC Commits: 5ff7b12d by Sven Tennie at 2020-05-11T18:21:27+02:00 Export StgTSO fields with the help of hsc2hs - - - - - 5 changed files: - libraries/ghc-heap/GHC/Exts/Heap.hs - libraries/ghc-heap/GHC/Exts/Heap/Closures.hs - + libraries/ghc-heap/GHC/Exts/Heap/FFIClosures.hsc - libraries/ghc-heap/ghc-heap.cabal.in - rts/Heap.c Changes: ===================================== libraries/ghc-heap/GHC/Exts/Heap.hs ===================================== @@ -58,6 +58,7 @@ import GHC.Exts.Heap.InfoTableProf import GHC.Exts.Heap.InfoTable #endif import GHC.Exts.Heap.Utils +import GHC.Exts.Heap.FFIClosures import Control.Monad import Data.Bits @@ -66,6 +67,8 @@ import GHC.Exts import GHC.Int import GHC.Word +import Foreign + #include "ghcconfig.h" class HasHeapRep (a :: TYPE rep) where @@ -290,6 +293,18 @@ getClosureX get_closure_raw x = do unless (length pts == 6) $ fail $ "Expected 6 ptr arguments to TSO, found " ++ show (length pts) + + threadId' <- allocaArray (length wds) (\ptr -> do + pokeArray ptr wds + id <- peekStgThreadID ptr + return id + ) + alloc_limit' <- allocaArray (length wds) (\ptr -> do + pokeArray ptr wds + alloc_limit <- peekAllocLimit ptr + return alloc_limit + ) + pure $ TSOClosure { info = itbl , _link = (pts !! 0) @@ -298,6 +313,8 @@ getClosureX get_closure_raw x = do , trec = (pts !! 3) , blocked_exceptions = (pts !! 4) , bq = (pts !! 5) + , threadId = threadId' + , alloc_limit = alloc_limit' } STACK -> do unless (length pts >= 1) $ ===================================== libraries/ghc-heap/GHC/Exts/Heap/Closures.hs ===================================== @@ -266,12 +266,16 @@ data GenClosure b -- | StgTSO | TSOClosure { info :: !StgInfoTable + -- pointers , _link :: !b , global_link :: !b , tsoStack :: !b -- ^ stackobj from StgTSO , trec :: !b , blocked_exceptions :: !b , bq :: !b + -- values + , threadId :: Word64 + , alloc_limit :: Int64 } | StackClosure ===================================== libraries/ghc-heap/GHC/Exts/Heap/FFIClosures.hsc ===================================== @@ -0,0 +1,20 @@ +module GHC.Exts.Heap.FFIClosures where + +#include "Rts.h" + +import Prelude +import Foreign +import Foreign.Ptr +import Data.Int + +import GHC.Exts.Heap.Closures + +peekStgThreadID :: Ptr a -> IO Word64 +peekStgThreadID ptr = do + id <- (#peek struct StgTSO_, id) ptr + return id + +peekAllocLimit :: Ptr a -> IO Int64 +peekAllocLimit ptr = do + alloc_limit <- (#peek struct StgTSO_, alloc_limit) ptr + return alloc_limit \ No newline at end of file ===================================== libraries/ghc-heap/ghc-heap.cabal.in ===================================== @@ -39,3 +39,4 @@ library GHC.Exts.Heap.InfoTable.Types GHC.Exts.Heap.InfoTableProf GHC.Exts.Heap.Utils + GHC.Exts.Heap.FFIClosures ===================================== rts/Heap.c ===================================== @@ -223,6 +223,13 @@ static StgWord collect_pointers(StgClosure *closure, StgWord size, StgClosure *p ASSERT((StgClosure *)((StgTSO *)closure)->bq != NULL); ptrs[nptrs++] = (StgClosure *)((StgTSO *)closure)->bq; + + int threadId = ((StgTSO *)closure)->id; + debugBelch("threadId : %u", threadId); + + int alloc_limit = ((StgTSO *)closure)->alloc_limit; + debugBelch("alloc_limit : %d", alloc_limit); + break; case STACK: ptrs[nptrs++] = (StgClosure *)((StgStack *)closure)->sp; View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5ff7b12d7f2d43745e7cbf024221235f501c3ac3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5ff7b12d7f2d43745e7cbf024221235f501c3ac3 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 11 16:25:45 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Mon, 11 May 2020 12:25:45 -0400 Subject: [Git][ghc/ghc][wip/nested-cpr-2019] 4 commits: Accept testuite output Message-ID: <5eb97c89740e4_616712a9b7f010551719@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/nested-cpr-2019 at Glasgow Haskell Compiler / GHC Commits: 3eb58822 by Sebastian Graf at 2020-05-06T16:28:23+02:00 Accept testuite output - - - - - 1e11fa0e by Sebastian Graf at 2020-05-06T16:29:11+02:00 Don't attach CPR sigs to expandable bindings; transform their unfoldings instead - - - - - 8d6128c3 by Sebastian Graf at 2020-05-06T16:47:34+02:00 Revert "Don't give the case binder the CPR property" This reverts commit 910edd76d5fe68b58c74f3805112f9faef4f2788. It seems we broke too much with this change. We lost our big win in `fish`. - - - - - c015b648 by Sebastian Graf at 2020-05-11T18:25:36+02:00 A more modular and configurable approach to optimistic case binder CPR - - - - - 10 changed files: - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Types/Cpr.hs - testsuite/tests/cpranal/sigs/DataConWrapperCpr.stderr - testsuite/tests/simplCore/should_compile/T7360.stderr - testsuite/tests/stranal/sigs/DmdAnalGADTs.stderr - testsuite/tests/stranal/sigs/NewtypeArity.stderr - testsuite/tests/stranal/sigs/T17932.stderr - testsuite/tests/stranal/sigs/T8569.stderr Changes: ===================================== compiler/GHC/Core/Opt/CprAnal.hs ===================================== @@ -27,12 +27,13 @@ import GHC.Core.DataCon import GHC.Types.Id import GHC.Types.Id.Info import GHC.Core.Utils ( exprIsHNF, dumpIdInfoOfProgram ) +import GHC.Core.TyCon import GHC.Core.Type import GHC.Core.FamInstEnv import GHC.Core.Opt.WorkWrap.Utils import GHC.Utils.Misc import GHC.Utils.Error ( dumpIfSet_dyn, DumpFormat (..) ) -import GHC.Data.Maybe ( isNothing ) +import GHC.Data.Maybe ( isJust, isNothing ) {- Note [Constructed Product Result] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -104,7 +105,7 @@ So currently we have cprAnalProgram :: DynFlags -> FamInstEnvs -> CoreProgram -> IO CoreProgram cprAnalProgram dflags fam_envs binds = do - let env = emptyAnalEnv fam_envs + let env = emptyAnalEnv dflags fam_envs let binds_plus_cpr = snd $ mapAccumL cprAnalTopBind env binds dumpIfSet_dyn dflags Opt_D_dump_cpr_signatures "Cpr signatures" FormatText $ dumpIdInfoOfProgram (ppr . cprInfo) binds_plus_cpr @@ -204,8 +205,8 @@ cprAnal' env args (Case scrut case_bndr ty alts) -- head strictness. (scrut_ty, scrut') = cprAnal env [] scrut (whnf_flag, case_bndr_ty) = forceCprTy (getStrDmd seqDmd) scrut_ty - (alt_tys, alts') = mapAndUnzip (cprAnalAlt env args case_bndr case_bndr_ty) alts - res_ty = lubCprTypes alt_tys `bothCprType` whnf_flag + (alt_tys, alts') = mapAndUnzip (cprAnalAlt env args case_bndr case_bndr_ty) alts + res_ty = lubCprTypes alt_tys `bothCprType` whnf_flag cprAnal' env args (Let (NonRec id rhs) body) = (body_ty, Let (NonRec id' rhs') body') @@ -255,6 +256,8 @@ cprTransform env args id sig | Just con <- isDataConWorkId_maybe id -- Data constructor = cprTransformDataConSig con args + | Just rhs <- lookupExpandableUnfolding id + = fst $ cprAnal env args rhs | isGlobalId id -- imported function or data con worker = cprTransformSig (idStrictness id) (idCprInfo id) args | Just sig <- lookupSigEnv env id -- local let-bound @@ -378,11 +381,14 @@ cprAnalBind top_lvl env args id rhs | stays_thunk = trimCprTy rhs_ty -- See Note [CPR for sum types] | returns_sum = trimCprTy rhs_ty + -- See Note [CPR for expandable unfoldings] + | will_expand = topCprType | otherwise = rhs_ty -- See Note [Arity trimming for CPR signatures] -- We prune so that we discard too deep info on e.g. TyCon bindings - sig = pruneSig mAX_DEPTH $ mkCprSigForArity (idArity id) rhs_ty' + dflags = ae_dflags env + sig = pruneSig mAX_DEPTH $ mkCprSigForArity dflags (idArity id) rhs_ty' id' = -- pprTrace "cprAnalBind" (ppr id $$ ppr sig) $ setIdCprInfo id sig @@ -394,6 +400,19 @@ cprAnalBind top_lvl env args id rhs (_, ret_ty) = splitPiTys (idType id) not_a_prod = isNothing (deepSplitProductType_maybe (ae_fam_envs env) ret_ty) returns_sum = not (isTopLevel top_lvl) && not_a_prod + -- See Note [CPR for expandable unfoldings] + will_expand = isJust (lookupExpandableUnfolding id) + +lookupExpandableUnfolding :: Id -> Maybe CoreExpr +lookupExpandableUnfolding id + | idArity id == 0 = expandUnfolding_maybe (cprIdUnfolding id) + | otherwise = Nothing + +cprIdUnfolding :: IdUnfoldingFun +cprIdUnfolding id + -- There will only be phase 0 Simplifier runs after CprAnal + | isActiveIn 0 (idInlineActivation id) = idUnfolding id + | otherwise = noUnfolding {- Note [Arity trimming for CPR signatures] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -434,6 +453,8 @@ data AnalEnv , ae_virgin :: Bool -- ^ True only on every first iteration in a fixed-point -- iteration. See Note [Initialising strictness] in "DmdAnal" + , ae_dflags :: DynFlags + -- ^ For 'caseBinderCprDepth'. , ae_fam_envs :: FamInstEnvs -- ^ Needed when expanding type families and synonyms of product types. } @@ -446,11 +467,12 @@ instance Outputable AnalEnv where [ text "ae_virgin =" <+> ppr virgin , text "ae_sigs =" <+> ppr env ]) -emptyAnalEnv :: FamInstEnvs -> AnalEnv -emptyAnalEnv fam_envs +emptyAnalEnv :: DynFlags -> FamInstEnvs -> AnalEnv +emptyAnalEnv dflags fam_envs = AE { ae_sigs = emptyVarEnv , ae_virgin = True + , ae_dflags = dflags , ae_fam_envs = fam_envs } @@ -478,10 +500,19 @@ nonVirgin env = env { ae_virgin = False } extendEnvForDataAlt :: AnalEnv -> Id -> CprType -> DataCon -> [Var] -> AnalEnv -- See Note [CPR in a DataAlt case alternative] extendEnvForDataAlt env case_bndr case_bndr_ty dc bndrs - = extendAnalEnv env' case_bndr (CprSig case_bndr_ty) + = extendAnalEnv env' case_bndr (CprSig case_bndr_ty') where + tycon = dataConTyCon dc + is_product = isJust (isDataProductTyCon_maybe tycon) + is_sum = isJust (isDataSumTyCon_maybe tycon) + case_bndr_ty' + | is_product || is_sum = markOptimisticConCprType dc case_bndr_ty + -- Any of the constructors had existentials. This is a little too + -- conservative (after all, we only care about the particular data con), + -- but there is no easy way to write is_sum and this won't happen much. + | otherwise = case_bndr_ty env' - | Just fields <- splitConCprTy dc case_bndr_ty + | Just fields <- splitConCprTy dc case_bndr_ty' , let ids = filter isId bndrs , let cpr_tys = map (CprSig . CprType 0) fields = extendAnalEnvList env (zipEqual "extendEnvForDataAlt" ids cpr_tys) @@ -673,6 +704,28 @@ fac won't have the CPR property here when we trim every thunk! But the assumption is that error cases are rarely entered and we are diverging anyway, so WW doesn't hurt. +Should we also trim CPR on DataCon bindings? +See Note [CPR for expandable unfoldings]! + +Note [CPR for expandable unfoldings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +GHC generates a lot of TyCon and KindRep bindings, one for each new data +declaration. Attaching CPR signatures to each of them is quite wasteful. +In general, DataCon application bindings + * Never get WW'd, so their CPR signature should be irrelevant after analysis + * Would need to be inlined to see their CPR + * Recording (Nested!) CPR on them blows up interface file sizes +But we can't just stop giving DataCon application bindings the CPR property, +for example + fac 0 = 1 + fac n = n * fac (n-1) +fac certainly has the CPR property and should be WW'd! But FloatOut will +transform the first clause to + lvl = 1 + fac 0 = lvl +If lvl doesn't have the CPR property, fac won't either. So instead we keep on +looking through *expandable* unfoldings for these arity 0 bindings. + Note [CPR examples] ~~~~~~~~~~~~~~~~~~~~ Here are some examples (stranal/should_compile/T10482a) of the ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -191,6 +191,7 @@ data GeneralFlag | Opt_CfgBlocklayout -- ^ Use the cfg based block layout algorithm. | Opt_WeightlessBlocklayout -- ^ Layout based on last instruction per block. | Opt_CprAnal + | Opt_CaseBinderCpr -- ^ Optimistically give returned case binders the CPR property | Opt_WorkerWrapper | Opt_SolveConstantDicts | Opt_AlignmentSanitisation ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -497,6 +497,9 @@ data DynFlags = DynFlags { specConstrCount :: Maybe Int, -- ^ Max number of specialisations for any one function specConstrRecursive :: Int, -- ^ Max number of specialisations for recursive types -- Not optional; otherwise ForceSpecConstr can diverge. + caseBinderCprDepth :: Int, -- ^ How many levels deep a case binder + -- should optimistically get the CPR property. + binBlobThreshold :: Word, -- ^ Binary literals (e.g. strings) whose size is above -- this threshold will be dumped in a binary file -- by the assembler code generator (0 to disable) @@ -1303,6 +1306,7 @@ defaultDynFlags mySettings llvmConfig = specConstrCount = Just 3, specConstrRecursive = 3, liberateCaseThreshold = Just 2000, + caseBinderCprDepth = 1, -- The default prior to Nested CPR floatLamArgs = Just 0, -- Default: float only if no fvs liftLamsRecArgs = Just 5, -- Default: the number of available argument hardware registers on x86_64 liftLamsNonRecArgs = Just 5, -- Default: the number of available argument hardware registers on x86_64 @@ -2971,6 +2975,8 @@ dynamic_flags_deps = [ (intSuffix (\n d -> d { liberateCaseThreshold = Just n })) , make_ord_flag defFlag "fno-liberate-case-threshold" (noArg (\d -> d { liberateCaseThreshold = Nothing })) + , make_ord_flag defFlag "fcase-binder-cpr-depth" + (intSuffix (\n d -> d { caseBinderCprDepth = n })) , make_ord_flag defFlag "drule-check" (sepArg (\s d -> d { ruleCheck = Just s })) , make_ord_flag defFlag "dinline-check" @@ -3526,6 +3532,7 @@ fFlagsDeps = [ flagSpec "stg-cse" Opt_StgCSE, flagSpec "stg-lift-lams" Opt_StgLiftLams, flagSpec "cpr-anal" Opt_CprAnal, + flagSpec "case-binder-cpr" Opt_CaseBinderCpr, flagSpec "defer-diagnostics" Opt_DeferDiagnostics, flagSpec "defer-type-errors" Opt_DeferTypeErrors, flagSpec "defer-typed-holes" Opt_DeferTypedHoles, @@ -4094,6 +4101,7 @@ optLevelFlags -- see Note [Documenting optimisation flags] , ([1,2], Opt_Strictness) , ([1,2], Opt_UnboxSmallStrictFields) , ([1,2], Opt_CprAnal) + , ([1,2], Opt_CaseBinderCpr) , ([1,2], Opt_WorkerWrapper) , ([1,2], Opt_SolveConstantDicts) , ([1,2], Opt_NumConstantFolding) ===================================== compiler/GHC/Types/Cpr.hs ===================================== @@ -12,7 +12,7 @@ module GHC.Types.Cpr ( TerminationFlag (Terminates), Cpr, topCpr, conCpr, whnfTermCpr, divergeCpr, lubCpr, asConCpr, CprType (..), topCprType, whnfTermCprType, conCprType, lubCprType, lubCprTypes, - pruneDeepCpr, splitConCprTy, applyCprTy, abstractCprTy, + pruneDeepCpr, markOptimisticConCprType, splitConCprTy, applyCprTy, abstractCprTy, abstractCprTyNTimes, ensureCprTyArity, trimCprTy, forceCprTy, forceCpr, bothCprType, cprTransformDataConSig, UnboxingStrategy, cprTransformSig, argCprTypesFromStrictSig, @@ -28,6 +28,7 @@ import GHC.Types.Basic import GHC.Types.Demand import GHC.Core.DataCon import GHC.Core.Type +import GHC.Driver.Session import GHC.Utils.Binary import GHC.Utils.Misc import GHC.Utils.Outputable @@ -82,8 +83,17 @@ pruneKnownShape _ 0 _ = Top pruneKnownShape prune_r depth (Con t args) = Levitate (Con t (map (prune_r (depth - 1)) args)) --------------- --- * Termination +-- * Optimism + +data Optimism + = Conservative + | Optimistic + deriving Eq +lubOptimism :: Optimism -> Optimism -> Optimism +lubOptimism Optimistic _ = Optimistic +lubOptimism _ Optimistic = Optimistic +lubOptimism Conservative Conservative = Conservative ---------------- -- * Termination @@ -171,7 +181,7 @@ seqTerm (Term _ l) = seqLevitated (seqKnownShape seqTerm) l -- * Cpr data Cpr - = Cpr !TerminationFlag !(Levitated (KnownShape Cpr)) + = Cpr !Optimism !TerminationFlag !(Levitated (KnownShape Cpr)) | NoMoreCpr_ !Termination deriving Eq @@ -185,13 +195,13 @@ pattern NoMoreCpr t <- (NoMoreCpr_ t) {-# COMPLETE Cpr, NoMoreCpr #-} botCpr :: Cpr -botCpr = Cpr Terminates Bot +botCpr = Cpr Conservative Terminates Bot topCpr :: Cpr -topCpr = Cpr MightDiverge Top +topCpr = Cpr Conservative MightDiverge Top whnfTermCpr :: Cpr -whnfTermCpr = Cpr Terminates Top +whnfTermCpr = Cpr Conservative Terminates Top -- | Used as -- @@ -203,41 +213,45 @@ whnfTermCpr = Cpr Terminates Top -- assume that returned tuple components terminate rapidly and construct a -- product. divergeCpr :: Cpr -divergeCpr = Cpr MightDiverge Bot +divergeCpr = Cpr Conservative MightDiverge Bot conCpr :: ConTag -> [Cpr] -> Cpr -conCpr t fs = Cpr Terminates (Levitate (Con t fs)) +conCpr t fs = Cpr Conservative Terminates (Levitate (Con t fs)) + +optimisticConCpr :: ConTag -> [Cpr] -> Cpr +optimisticConCpr t fs = Cpr Optimistic Terminates (Levitate (Con t fs)) -- | Forget encoded CPR info, but keep termination info. forgetCpr :: Cpr -> Termination forgetCpr (NoMoreCpr t) = t -forgetCpr (Cpr tf l_sh) = Term tf (normTermShape (liftLevitated go l_sh)) +forgetCpr (Cpr _ tf l_sh) = Term tf (normTermShape (liftLevitated go l_sh)) where go (Con t fields) = Levitate (Con t (map forgetCpr fields)) lubCpr :: Cpr -> Cpr -> Cpr -lubCpr (Cpr tf1 l_sh1) (Cpr tf2 l_sh2) - = Cpr (lubTermFlag tf1 tf2) +lubCpr (Cpr op1 tf1 l_sh1) (Cpr op2 tf2 l_sh2) + = Cpr (lubOptimism op1 op2) + (lubTermFlag tf1 tf2) (lubLevitated (lubKnownShape lubCpr) l_sh1 l_sh2) lubCpr cpr1 cpr2 = NoMoreCpr (lubTerm (forgetCpr cpr1) (forgetCpr cpr2)) trimCpr :: Cpr -> Cpr -trimCpr cpr@(Cpr _ Bot) = cpr -- don't trim away bottom (we didn't do so before Nested CPR) TODO: Explain; CPR'ing for the error case -trimCpr cpr = NoMoreCpr (forgetCpr cpr) +trimCpr cpr@(Cpr _ _ Bot) = cpr -- don't trim away bottom (we didn't do so before Nested CPR) TODO: Explain; CPR'ing for the error case +trimCpr cpr = NoMoreCpr (forgetCpr cpr) pruneDeepCpr :: Int -> Cpr -> Cpr -pruneDeepCpr depth (Cpr tf (Levitate sh)) = Cpr tf (pruneKnownShape pruneDeepCpr depth sh) -pruneDeepCpr depth (NoMoreCpr t) = NoMoreCpr (pruneDeepTerm depth t) -pruneDeepCpr _ cpr = cpr +pruneDeepCpr depth (Cpr op tf (Levitate sh)) = Cpr op tf (pruneKnownShape pruneDeepCpr depth sh) +pruneDeepCpr depth (NoMoreCpr t) = NoMoreCpr (pruneDeepTerm depth t) +pruneDeepCpr _ cpr = cpr asConCpr :: Cpr -> Maybe (ConTag, [Cpr]) -asConCpr (Cpr tf (Levitate (Con t fields))) +asConCpr (Cpr _ tf (Levitate (Con t fields))) | Terminates <- tf = Just (t, fields) asConCpr _ = Nothing seqCpr :: Cpr -> () -seqCpr (Cpr _ l) = seqLevitated (seqKnownShape seqCpr) l +seqCpr (Cpr _ _ l) = seqLevitated (seqKnownShape seqCpr) l seqCpr (NoMoreCpr t) = seqTerm t ------------ @@ -302,8 +316,23 @@ conCprType con_tag args = CprType 0 (conCpr con_tag cprs) where cprs = extractArgCprAndTermination args +markOptimisticConCprType :: DataCon -> CprType -> CprType +markOptimisticConCprType dc _ty@(CprType n cpr) + = ASSERT2( n == 0, ppr _ty ) CprType 0 (optimisticConCpr con_tag fields) + where + con_tag = dataConTag dc + wkr_arity = dataConRepArity dc + fields = case cpr of + NoMoreCpr (Term _ (Levitate (Con t terms))) + | con_tag == t -> map NoMoreCpr terms + NoMoreCpr (Term _ Bot) -> replicate wkr_arity (NoMoreCpr botTerm) + Cpr _ _ (Levitate (Con t cprs)) + | con_tag == t -> cprs + Cpr _ _ Bot -> replicate wkr_arity botCpr + _ -> replicate wkr_arity topCpr + splitConCprTy :: DataCon -> CprType -> Maybe [Cpr] -splitConCprTy dc (CprType 0 (Cpr _ l)) +splitConCprTy dc (CprType 0 (Cpr _ _ l)) | Bot <- l = Just (replicate (dataConRepArity dc) botCpr) | Levitate (Con t fields) <- l @@ -334,6 +363,22 @@ ensureCprTyArity n ty@(CprType m _) trimCprTy :: CprType -> CprType trimCprTy (CprType arty cpr) = CprType arty (trimCpr cpr) +zonkOptimisticCprTy :: Int -> CprType -> CprType +zonkOptimisticCprTy max_depth (CprType arty cpr) + = CprType arty (zonk max_depth cpr) + where + -- | The Int is the amount of "fuel" left; when it reaches 0, we no longer + -- turn OptimisticCpr into Cpr, but into NoMoreCpr. + zonk :: Int -> Cpr -> Cpr + zonk n (Cpr op tf sh) + | n > 0 || op == Conservative + = Cpr Conservative tf (liftLevitated (Levitate . zonk_sh (n-1)) sh) + zonk _ cpr + = NoMoreCpr (forgetCpr cpr) + + zonk_sh :: Int -> KnownShape Cpr -> KnownShape Cpr + zonk_sh n (Con t fields) = Con t (map (zonk n) fields) + -- | Abusing the Monoid instance of 'Semigroup.Any' to track a -- 'TerminationFlag'. newtype TerminationM a = TerminationM (Writer Semigroup.Any a) @@ -364,9 +409,9 @@ forceCprTyM arg_str ty = go (toStrDmd arg_str) ty abstractCprTy <$> go (swap (peelStrCall str)) (applyCprTy ty) forceCprM :: ArgStr -> Cpr -> TerminationM Cpr -forceCprM Lazy t = return t -forceCprM arg_str (NoMoreCpr t) = NoMoreCpr <$> forceTermM arg_str t -forceCprM (Str str) (Cpr tf l_sh) = do +forceCprM Lazy t = return t +forceCprM arg_str (NoMoreCpr t) = NoMoreCpr <$> forceTermM arg_str t +forceCprM (Str str) (Cpr op tf l_sh) = do -- 1. discharge head strictness by noting the term flag noteTermFlag tf -- 2. discharge *nested* strictness on available nested info @@ -393,7 +438,7 @@ forceCprM (Str str) (Cpr tf l_sh) = do #endif fields' <- zipWithM forceCprM args fields return (Levitate (Con fIRST_TAG fields')) - return (Cpr Terminates l_sh') + return (Cpr op Terminates l_sh') forceTermM :: ArgStr -> Termination -> TerminationM Termination forceTermM Lazy t = return t @@ -439,7 +484,7 @@ bothCprType ct MightDiverge = ct { ct_cpr = shallowDivCpr (ct_cpr ct) } shallowDivCpr :: Cpr -> Cpr shallowDivCpr (NoMoreCpr (Term _ l_sh)) = NoMoreCpr (Term MightDiverge l_sh) -shallowDivCpr (Cpr _ l_sh) = Cpr MightDiverge l_sh +shallowDivCpr (Cpr op _ l_sh) = Cpr op MightDiverge l_sh seqCprType :: CprType -> () seqCprType (CprType _ cpr) = seqCpr cpr @@ -449,14 +494,18 @@ seqCprType (CprType _ cpr) = seqCpr cpr -- | The arity of the wrapped 'CprType' is the arity at which it is safe -- to unleash. See Note [Understanding DmdType and StrictSig] in GHC.Types.Demand +-- INVARIANT: The wrapped CprType never has 'OptimisticCpr' somewhere. newtype CprSig = CprSig { getCprSig :: CprType } deriving (Eq, Binary) -- | Turns a 'CprType' computed for the particular 'Arity' into a 'CprSig' -- unleashable at that arity. See Note [Understanding DmdType and StrictSig] in -- Demand -mkCprSigForArity :: Arity -> CprType -> CprSig -mkCprSigForArity arty ty = CprSig (ensureCprTyArity arty ty) +mkCprSigForArity :: DynFlags -> Arity -> CprType -> CprSig +mkCprSigForArity dflags arty + = CprSig + . ensureCprTyArity arty + . zonkOptimisticCprTy (caseBinderCprDepth dflags) topCprSig :: CprSig topCprSig = CprSig topCprType @@ -559,15 +608,19 @@ instance Outputable Termination where Bot -> text "(#..)" Levitate shape -> ppr shape +instance Outputable Optimism where + ppr Optimistic = char '?' + ppr Conservative = empty + instance Outputable Cpr where ppr (NoMoreCpr t) = ppr t -- I like it better without the special case -- ppr (Cpr MightDiverge Top) = empty -- ppr (Cpr Terminates Bot) = char 'b' - ppr (Cpr tf l) = ppr tf <> case l of + ppr (Cpr op tf l) = ppr tf <> case l of Top -> empty Bot -> char 'b' - Levitate shape -> char 'c' <> ppr shape + Levitate shape -> char 'c' <> ppr op <> ppr shape instance Outputable CprType where ppr (CprType arty cpr) = ppr arty <+> ppr cpr @@ -604,17 +657,28 @@ instance Binary TerminationFlag where then pure Terminates else pure MightDiverge +-- | In practice, we should never need to serialise an 'Optimistic' because of +-- the invariant attached to 'CprSig'. +instance Binary Optimism where + put_ bh Conservative = put_ bh True + put_ bh Optimistic = put_ bh False + get bh = do + b <- get bh + if b + then pure Conservative + else pure Optimistic + instance Binary Termination where put_ bh (Term tf l) = put_ bh tf >> put_ bh l get bh = Term <$> get bh <*> get bh instance Binary Cpr where - put_ bh (Cpr tf l) = put_ bh True >> put_ bh tf >> put_ bh l + put_ bh (Cpr op tf l) = put_ bh True >> put_ bh op >> put_ bh tf >> put_ bh l put_ bh (NoMoreCpr t) = put_ bh False >> put_ bh t get bh = do b <- get bh if b - then Cpr <$> get bh <*> get bh + then Cpr <$> get bh <*> get bh <*> get bh else NoMoreCpr <$> get bh instance Binary CprType where ===================================== testsuite/tests/cpranal/sigs/DataConWrapperCpr.stderr ===================================== @@ -2,8 +2,7 @@ ==================== Cpr signatures ==================== DataConWrapperCpr.$tc'Foo: #c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, - #c4(#c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)), *), - #c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)), *))) + #c4(#c1(#c1(#, #, #, #, #, #), *), #c1(#c1(#, #, #, #, #, #), *))) DataConWrapperCpr.$tcFoo: #c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)) DataConWrapperCpr.$trModule: #c1(#c1(#), #c1(#)) ===================================== testsuite/tests/simplCore/should_compile/T7360.stderr ===================================== @@ -164,7 +164,7 @@ T7360.$tc'Foo5 = GHC.Types.TrNameS T7360.$tc'Foo6 T7360.$tc'Foo1 :: GHC.Types.TyCon [GblId, Cpr=#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, - #c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)), *)), + #c1(#c1(#, #, #c1(#, #), #c1(#), #, #c5(*)), *)), Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 70}] T7360.$tc'Foo1 @@ -196,7 +196,7 @@ T7360.$tc'Foo7 = GHC.Types.TrNameS T7360.$tc'Foo8 T7360.$tc'Foo2 :: GHC.Types.TyCon [GblId, Cpr=#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, - #c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)), *)), + #c1(#c1(#, #, #c1(#, #), #c1(#), #, #c5(*)), *)), Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 70}] T7360.$tc'Foo2 @@ -211,8 +211,8 @@ T7360.$tc'Foo2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo9 [InlPrag=NOUSERINLINE[~]] :: GHC.Types.KindRep [GblId, - Cpr=#c4(#c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)), *), - #c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)), *)), + Cpr=#c4(#c1(#c1(#, #, #c1(#, #), #c1(#), #, #c5(*)), *), + #c1(#c1(#, #, #c1(#, #), #c1(#), #, #c5(*)), *)), Unf=OtherCon []] T7360.$tc'Foo9 = GHC.Types.KindRepFun $krep T7360.$tc'Foo4 @@ -236,8 +236,7 @@ T7360.$tc'Foo10 = GHC.Types.TrNameS T7360.$tc'Foo11 T7360.$tc'Foo3 :: GHC.Types.TyCon [GblId, Cpr=#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, - #c4(#c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)), *), - #c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)), *))), + #c4(#c1(#c1(#, #, #, #, #, #), *), #c1(#c1(#, #, #, #, #, #), *))), Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 70}] T7360.$tc'Foo3 ===================================== testsuite/tests/stranal/sigs/DmdAnalGADTs.stderr ===================================== @@ -15,13 +15,9 @@ DmdAnalGADTs.hasStrSig: ==================== Cpr signatures ==================== DmdAnalGADTs.$tc'A: #c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, - #c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c4(#c5(*), #c5(*))), - #c2(#c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)), *), *))) + #c1(#c1(#, #, #c1(#, #), #c1(#), #, #c4(#, #)), #c2(#c1(#, *), *))) DmdAnalGADTs.$tc'B: #c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, - #c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c4(#c5(*), #c5(*))), - #c2(#c4(#c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)), *), - #c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)), *)), - *))) + #c1(#c1(#, #, #c1(#, #), #c1(#), #, #c4(#, #)), #c2(#c4(#, #), *))) DmdAnalGADTs.$tcD: #c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c4(#c5(*), #c5(*))) DmdAnalGADTs.$trModule: #c1(#c1(#), #c1(#)) ===================================== testsuite/tests/stranal/sigs/NewtypeArity.stderr ===================================== @@ -10,10 +10,7 @@ Test.t2: ==================== Cpr signatures ==================== Test.$tc'MkT: #c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, - #c4(#c4(#c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)), *), - #c4(#c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)), *), - #c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)), *))), - #c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)), *))) + #c4(#c4(#c1(#, *), #c4(#, #)), #c1(#c1(#, #, #, #, #, #), *))) Test.$tcT: #c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)) Test.$trModule: #c1(#c1(#), #c1(#)) Test.t: #c1(#) ===================================== testsuite/tests/stranal/sigs/T17932.stderr ===================================== @@ -11,22 +11,10 @@ T17932.flags: ==================== Cpr signatures ==================== T17932.$tc'Options: #c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, - #c4(#c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)), *), - #c4(#c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, - #c4(#c5(*), #c5(*))), - #c2(#c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)), *), - *)), - #c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)), *)))) + #c4(#c1(#c1(#, #, #, #, #, #), *), #c4(#c1(#, #), #c1(#, *)))) T17932.$tc'X: #c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, - #c4(#c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, - #c4(#c5(*), #c5(*))), - #c2(#c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)), *), *)), - #c4(#c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)), *), - #c4(#c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)), *), - #c4(#c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)), *), - #c4(#c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)), *), - #c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)), - *))))))) + #c4(#c1(#c1(#, #, #, #, #, #), #c2(#, *)), + #c4(#c1(#, *), #c4(#, #)))) T17932.$tcOptions: #c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)) T17932.$tcX: #c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)) ===================================== testsuite/tests/stranal/sigs/T8569.stderr ===================================== @@ -10,15 +10,10 @@ T8569.addUp: ==================== Cpr signatures ==================== T8569.$tc'Rdata: #c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, - #c4(#c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, - #c4(#c5(*), #c5(*))), - #c2(#c2(#), *)), - #c4(#c4(#c2(#), #c2(#)), - #c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c4(#c5(*), #c5(*))), - #c2(#c2(#), *))))) + #c4(#c1(#c1(#, #, #, #, #, #), #c2(#, *)), + #c4(#c4(#, #), #c1(#, #)))) T8569.$tc'Rint: #c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, - #c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c4(#c5(*), #c5(*))), - #c2(#c1(#c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c5(*)), *), *))) + #c1(#c1(#, #, #c1(#, #), #c1(#), #, #c4(#, #)), #c2(#c1(#, *), *))) T8569.$tcRep: #c1(#, #, #c1(#c1(#), #c1(#)), #c1(#), #, #c4(#c5(*), #c5(*))) T8569.$trModule: #c1(#c1(#), #c1(#)) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/75867eac718bdc371d286c92c3a66797e0eef505...c015b648580edf071e10dd197fda5727dca66750 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/75867eac718bdc371d286c92c3a66797e0eef505...c015b648580edf071e10dd197fda5727dca66750 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 11 16:25:58 2020 From: gitlab at gitlab.haskell.org (Sven Tennie) Date: Mon, 11 May 2020 12:25:58 -0400 Subject: [Git][ghc/ghc][wip/ghc-debug] Export StgTSO fields with the help of hsc2hs Message-ID: <5eb97c963be95_616712a9b7f0105541fe@gitlab.haskell.org.mail> Sven Tennie pushed to branch wip/ghc-debug at Glasgow Haskell Compiler / GHC Commits: aa8bd1d7 by Sven Tennie at 2020-05-11T18:25:38+02:00 Export StgTSO fields with the help of hsc2hs - - - - - 5 changed files: - libraries/ghc-heap/GHC/Exts/Heap.hs - libraries/ghc-heap/GHC/Exts/Heap/Closures.hs - + libraries/ghc-heap/GHC/Exts/Heap/FFIClosures.hsc - libraries/ghc-heap/ghc-heap.cabal.in - rts/Heap.c Changes: ===================================== libraries/ghc-heap/GHC/Exts/Heap.hs ===================================== @@ -58,6 +58,7 @@ import GHC.Exts.Heap.InfoTableProf import GHC.Exts.Heap.InfoTable #endif import GHC.Exts.Heap.Utils +import GHC.Exts.Heap.FFIClosures import Control.Monad import Data.Bits @@ -66,6 +67,8 @@ import GHC.Exts import GHC.Int import GHC.Word +import Foreign + #include "ghcconfig.h" class HasHeapRep (a :: TYPE rep) where @@ -290,6 +293,18 @@ getClosureX get_closure_raw x = do unless (length pts == 6) $ fail $ "Expected 6 ptr arguments to TSO, found " ++ show (length pts) + + threadId' <- allocaArray (length wds) (\ptr -> do + pokeArray ptr wds + id <- peekStgThreadID ptr + return id + ) + alloc_limit' <- allocaArray (length wds) (\ptr -> do + pokeArray ptr wds + alloc_limit <- peekAllocLimit ptr + return alloc_limit + ) + pure $ TSOClosure { info = itbl , _link = (pts !! 0) @@ -298,6 +313,8 @@ getClosureX get_closure_raw x = do , trec = (pts !! 3) , blocked_exceptions = (pts !! 4) , bq = (pts !! 5) + , threadId = threadId' + , alloc_limit = alloc_limit' } STACK -> do unless (length pts >= 1) $ ===================================== libraries/ghc-heap/GHC/Exts/Heap/Closures.hs ===================================== @@ -266,12 +266,16 @@ data GenClosure b -- | StgTSO | TSOClosure { info :: !StgInfoTable + -- pointers , _link :: !b , global_link :: !b , tsoStack :: !b -- ^ stackobj from StgTSO , trec :: !b , blocked_exceptions :: !b , bq :: !b + -- values + , threadId :: Word64 + , alloc_limit :: Int64 } | StackClosure ===================================== libraries/ghc-heap/GHC/Exts/Heap/FFIClosures.hsc ===================================== @@ -0,0 +1,20 @@ +module GHC.Exts.Heap.FFIClosures where + +#include "Rts.h" + +import Prelude +import Foreign +import Foreign.Ptr +import Data.Int + +import GHC.Exts.Heap.Closures + +peekStgThreadID :: Ptr a -> IO Word64 +peekStgThreadID ptr = do + id <- (#peek struct StgTSO_, id) ptr + return id + +peekAllocLimit :: Ptr a -> IO Int64 +peekAllocLimit ptr = do + alloc_limit <- (#peek struct StgTSO_, alloc_limit) ptr + return alloc_limit ===================================== libraries/ghc-heap/ghc-heap.cabal.in ===================================== @@ -39,3 +39,4 @@ library GHC.Exts.Heap.InfoTable.Types GHC.Exts.Heap.InfoTableProf GHC.Exts.Heap.Utils + GHC.Exts.Heap.FFIClosures ===================================== rts/Heap.c ===================================== @@ -223,6 +223,13 @@ static StgWord collect_pointers(StgClosure *closure, StgWord size, StgClosure *p ASSERT((StgClosure *)((StgTSO *)closure)->bq != NULL); ptrs[nptrs++] = (StgClosure *)((StgTSO *)closure)->bq; + + int threadId = ((StgTSO *)closure)->id; + debugBelch("threadId : %u", threadId); + + int alloc_limit = ((StgTSO *)closure)->alloc_limit; + debugBelch("alloc_limit : %d", alloc_limit); + break; case STACK: ptrs[nptrs++] = (StgClosure *)((StgStack *)closure)->sp; View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/aa8bd1d7f49f0290be0c62763231d95c55be3b8c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/aa8bd1d7f49f0290be0c62763231d95c55be3b8c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 11 16:27:45 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Mon, 11 May 2020 12:27:45 -0400 Subject: [Git][ghc/ghc][wip/andreask/refactor_cmm_weights] Refactor linear reg alloc to remember past assignments. Message-ID: <5eb97d0197721_616711922e9c105554c3@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/refactor_cmm_weights at Glasgow Haskell Compiler / GHC Commits: b89a7d6c by Andreas Klebinger at 2020-05-11T18:27:18+02:00 Refactor linear reg alloc to remember past assignments. When assigning registers we now first try registers we assigned to in the past, instead of picking the "first" one. This is in extremely helpful when dealing with loops for which variables are dead for part of the loop. This is important for patterns like this: foo = arg1 loop: use(foo) ... foo = getVal() goto loop; There we: * assign foo to the register of arg1. * use foo, it's dead after this use as it's overwritten after. * do other things. * look for a register to put foo in. If we pick an arbitrary one it might differ from the register the start of the loop expect's foo to be in. To fix this we simply look for past register assignments for the given variable. If we find one and the register is free we use that register. This reduces the need for fixup blocks which match the register assignment between blocks. In the example above between the end and the head of the loop. This patch also moves branch weight estimation ahead of register allocation and adds a flag to control it (cmm-static-pred). * It means the linear allocator is more likely to assign the hotter code paths first. * If it assign these first we are: + Less likely to spill on the hot path. + Less likely to introduce fixup blocks on the hot path. These two measure combined are surprisingly effective. Based on nofib we get in the mean: * -0.9% instructions executed * -0.1% reads/writes * -0.2% code size. * -0.1% compiler allocations. * -0.9% compile time. * -0.8% runtime. Most of the benefits are simply a result of removing redundant moves and spills. Reduced compiler allocations likely are the result of less code being generated. (The added lookup is mostly non-allocating). - - - - - 15 changed files: - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Reg/Linear.hs - compiler/GHC/CmmToAsm/Reg/Linear/Base.hs - compiler/GHC/CmmToAsm/Reg/Linear/PPC.hs - compiler/GHC/CmmToAsm/Reg/Linear/SPARC.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/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Utils/Outputable.hs - docs/users_guide/using-optimisation.rst Changes: ===================================== compiler/GHC/CmmToAsm.hs ===================================== @@ -728,7 +728,7 @@ cmmNativeGen dflags this_mod modLoc ncgImpl us fileIds dbgMap cmm count let optimizedCFG :: Maybe CFG optimizedCFG = - optimizeCFG (cfgWeightInfo dflags) cmm <$!> postShortCFG + optimizeCFG (gopt Opt_CmmStaticPred dflags) (cfgWeightInfo dflags) cmm <$!> postShortCFG maybeDumpCfg dflags optimizedCFG "CFG Weights - Final" proc_name ===================================== compiler/GHC/CmmToAsm/BlockLayout.hs ===================================== @@ -636,22 +636,8 @@ sequenceChain :: forall a i. (Instruction i, Outputable i) -> [GenBasicBlock i] -- ^ Blocks placed in sequence. sequenceChain _info _weights [] = [] sequenceChain _info _weights [x] = [x] -sequenceChain info weights' blocks@((BasicBlock entry _):_) = - let weights :: CFG - weights = --pprTrace "cfg'" (pprEdgeWeights cfg') - cfg' - where - (_, globalEdgeWeights) = {-# SCC mkGlobalWeights #-} mkGlobalWeights entry weights' - cfg' = {-# SCC rewriteEdges #-} - mapFoldlWithKey - (\cfg from m -> - mapFoldlWithKey - (\cfg to w -> setEdgeWeight cfg (EdgeWeight w) from to ) - cfg m ) - weights' - globalEdgeWeights - - directEdges :: [CfgEdge] +sequenceChain info weights blocks@((BasicBlock entry _):_) = + let directEdges :: [CfgEdge] directEdges = sortBy (flip compare) $ catMaybes . map relevantWeight $ (infoEdgeList weights) where relevantWeight :: CfgEdge -> Maybe CfgEdge ===================================== compiler/GHC/CmmToAsm/CFG.hs ===================================== @@ -670,11 +670,21 @@ findBackEdges root cfg = typedEdges = classifyEdges root getSuccs edges :: [((BlockId,BlockId),EdgeType)] - -optimizeCFG :: D.CfgWeights -> RawCmmDecl -> CFG -> CFG -optimizeCFG _ (CmmData {}) cfg = cfg -optimizeCFG weights (CmmProc info _lab _live graph) cfg = - {-# SCC optimizeCFG #-} +optimizeCFG :: Bool -> D.CfgWeights -> RawCmmDecl -> CFG -> CFG +optimizeCFG _ _ (CmmData {}) cfg = cfg +optimizeCFG doStaticPred weights proc@(CmmProc _info _lab _live graph) cfg = + (if doStaticPred then staticPredCfg (g_entry graph) else id) $ + optHsPatterns weights proc $ cfg + +-- | Modify branch weights based on educated guess on +-- patterns GHC tends to produce and how they affect +-- performance. +-- +-- Most importantly we penalize jumps across info tables. +optHsPatterns :: D.CfgWeights -> RawCmmDecl -> CFG -> CFG +optHsPatterns _ (CmmData {}) cfg = cfg +optHsPatterns weights (CmmProc info _lab _live graph) cfg = + {-# SCC optHsPatterns #-} -- pprTrace "Initial:" (pprEdgeWeights cfg) $ -- pprTrace "Initial:" (ppr $ mkGlobalWeights (g_entry graph) cfg) $ @@ -749,6 +759,21 @@ optimizeCFG weights (CmmProc info _lab _live graph) cfg = | CmmSource { trans_cmmNode = CmmCondBranch {} } <- source = True | otherwise = False +-- | Convert block-local branch weights to global weights. +staticPredCfg :: BlockId -> CFG -> CFG +staticPredCfg entry cfg = cfg' + where + (_, globalEdgeWeights) = {-# SCC mkGlobalWeights #-} + mkGlobalWeights entry cfg + cfg' = {-# SCC rewriteEdges #-} + mapFoldlWithKey + (\cfg from m -> + mapFoldlWithKey + (\cfg to w -> setEdgeWeight cfg (EdgeWeight w) from to ) + cfg m ) + cfg + globalEdgeWeights + -- | Determine loop membership of blocks based on SCC analysis -- This is faster but only gives yes/no answers. loopMembers :: HasDebugCallStack => CFG -> LabelMap Bool @@ -922,6 +947,10 @@ revPostorderFrom cfg root = -- reverse post order. Which is required for diamond control flow to work probably. -- -- We also apply a few prediction heuristics (based on the same paper) +-- +-- The returned result represents frequences. +-- For blocks it's the expected number of executions and +-- for edges is the number of traversals. {-# NOINLINE mkGlobalWeights #-} {-# SCC mkGlobalWeights #-} ===================================== compiler/GHC/CmmToAsm/Instr.hs ===================================== @@ -37,7 +37,10 @@ import GHC.CmmToAsm.Config -- (for allocation purposes, anyway). -- data RegUsage - = RU [Reg] [Reg] + = RU { + reads :: [Reg], + writes :: [Reg] + } -- | No regs read or written to. noUsage :: RegUsage ===================================== compiler/GHC/CmmToAsm/Reg/Linear.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE BangPatterns, CPP, ScopedTypeVariables #-} +{-# LANGUAGE ConstraintKinds #-} {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} @@ -137,6 +138,7 @@ import GHC.Platform import Data.Maybe import Data.List import Control.Monad +import Control.Applicative -- ----------------------------------------------------------------------------- -- Top level of the register allocator @@ -229,8 +231,13 @@ linearRegAlloc config entry_ids block_live sccs go f = linearRegAlloc' config f entry_ids block_live sccs platform = ncgPlatform config +-- | Constraints on the instruction instances used by the +-- linear allocator. +type OutputableRegConstraint freeRegs instr = + (FR freeRegs, Outputable freeRegs, Outputable instr, Instruction instr) + linearRegAlloc' - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => NCGConfig -> freeRegs -> [BlockId] -- ^ entry points @@ -246,7 +253,7 @@ linearRegAlloc' config initFreeRegs entry_ids block_live sccs return (blocks, stats, getStackUse stack) -linearRA_SCCs :: (FR freeRegs, Instruction instr, Outputable instr) +linearRA_SCCs :: OutputableRegConstraint freeRegs instr => [BlockId] -> BlockMap RegSet -> [NatBasicBlock instr] @@ -281,7 +288,7 @@ linearRA_SCCs entry_ids block_live blocksAcc (CyclicSCC blocks : sccs) more sanity checking to guard against this eventuality. -} -process :: (FR freeRegs, Instruction instr, Outputable instr) +process :: OutputableRegConstraint freeRegs instr => [BlockId] -> BlockMap RegSet -> [GenBasicBlock (LiveInstr instr)] @@ -325,15 +332,18 @@ process entry_ids block_live (b@(BasicBlock id _) : blocks) -- | Do register allocation on this basic block -- processBlock - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ live regs on entry to each basic block -> LiveBasicBlock instr -- ^ block to do register allocation on -> RegM freeRegs [NatBasicBlock instr] -- ^ block with registers allocated processBlock block_live (BasicBlock id instrs) - = do initBlock id block_live + = do -- pprTraceM "processBlock" $ text "" $$ ppr (BasicBlock id instrs) + initBlock id block_live + (instrs', fixups) <- linearRA block_live [] [] id instrs + -- pprTraceM "blockResult" $ ppr (instrs', fixups) return $ BasicBlock id instrs' : fixups @@ -369,7 +379,7 @@ initBlock id block_live -- | Do allocation for a sequence of instructions. linearRA - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ map of what vregs are live on entry to each block. -> [instr] -- ^ accumulator for instructions already processed. -> [NatBasicBlock instr] -- ^ accumulator for blocks of fixup code. @@ -396,7 +406,7 @@ linearRA block_live accInstr accFixups id (instr:instrs) -- | Do allocation for a single instruction. raInsn - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ 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 @@ -476,7 +486,7 @@ isInReg src assig | Just (InReg _) <- lookupUFM assig src = True | otherwise = False -genRaInsn :: (FR freeRegs, Instruction instr, Outputable instr) +genRaInsn :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -> [instr] -> BlockId @@ -486,6 +496,7 @@ genRaInsn :: (FR freeRegs, Instruction instr, Outputable instr) -> RegM freeRegs ([instr], [NatBasicBlock instr]) genRaInsn block_live new_instrs block_id instr r_dying w_dying = do +-- pprTraceM "genRaInsn" $ ppr (block_id, instr) platform <- getPlatform case regUsageOfInstr platform instr of { RU read written -> do @@ -525,6 +536,8 @@ genRaInsn block_live new_instrs block_id instr r_dying w_dying = do (fixup_blocks, adjusted_instr) <- joinToTargets block_live block_id instr +-- when (not $ null fixup_blocks) $ pprTraceM "genRA:FixBlocks" $ ppr fixup_blocks + -- Debugging - show places where the reg alloc inserted -- assignment fixup blocks. -- when (not $ null fixup_blocks) $ @@ -737,7 +750,7 @@ data SpillLoc = ReadMem StackSlot -- reading from register only in memory -- the list of free registers and free stack slots. allocateRegsAndSpill - :: (FR freeRegs, Outputable instr, Instruction instr) + :: forall freeRegs instr. (FR freeRegs, Outputable instr, Instruction instr) => Bool -- True <=> reading (load up spilled regs) -> [VirtualReg] -- don't push these out -> [instr] -- spill insns @@ -749,7 +762,8 @@ allocateRegsAndSpill _ _ spills alloc [] = return (spills, reverse alloc) allocateRegsAndSpill reading keep spills alloc (r:rs) - = do assig <- getAssigR + = do assig <- getAssigR :: RegM freeRegs (RegMap Loc) + -- pprTraceM "allocateRegsAndSpill:assig" (ppr (r:rs) $$ ppr assig) let doSpill = allocRegsAndSpill_spill reading keep spills alloc r rs assig case lookupUFM assig r of -- case (1a): already in a register @@ -779,6 +793,22 @@ allocateRegsAndSpill reading keep spills alloc (r:rs) | otherwise -> doSpill WriteNew +-- | Given a virtual reg find a preferred real register. +-- Note: I tried returning a list of registers, but that +-- turned out to barely matter but added a few tenths of +-- a percent to compile time. +findPrefRealReg :: forall freeRegs u. Uniquable u + => u -> RegM freeRegs (Maybe RealReg) +findPrefRealReg vreg = do + bassig <- getBlockAssigR :: RegM freeRegs (BlockMap (freeRegs,RegMap Loc)) + return $ foldr (findVirtRegAssig) Nothing bassig + where + findVirtRegAssig :: (freeRegs,RegMap Loc) -> Maybe RealReg -> Maybe RealReg + findVirtRegAssig assig z = + z <|> case lookupUFM (snd assig) vreg of + Just (InReg real_reg) -> Just real_reg + Just (InBoth real_reg _) -> Just real_reg + _ -> z -- reading is redundant with reason, but we keep it around because it's -- convenient and it maintains the recursive structure of the allocator. -- EZY @@ -795,18 +825,26 @@ allocRegsAndSpill_spill :: (FR freeRegs, Instruction instr, Outputable instr) allocRegsAndSpill_spill reading keep spills alloc r rs assig spill_loc = do platform <- getPlatform freeRegs <- getFreeRegsR - let freeRegs_thisClass = frGetFreeRegs platform (classOfVirtualReg r) freeRegs + let freeRegs_thisClass = frGetFreeRegs platform (classOfVirtualReg r) freeRegs :: [RealReg] - case freeRegs_thisClass of + -- Can we put the variable into a register it already was? + pref_reg <- findPrefRealReg r + case freeRegs_thisClass of -- case (2): we have a free register - (my_reg : _) -> - do spills' <- loadTemp r spill_loc my_reg spills + (first_free : _) -> + do let final_reg + | Just reg <- pref_reg + , reg `elem` freeRegs_thisClass + = reg + | otherwise + = first_free + spills' <- loadTemp r spill_loc final_reg spills - setAssigR (addToUFM assig r $! newLocation spill_loc my_reg) - setFreeRegsR $ frAllocateReg platform my_reg freeRegs + setAssigR (addToUFM assig r $! newLocation spill_loc final_reg) + setFreeRegsR $ frAllocateReg platform final_reg freeRegs - allocateRegsAndSpill reading keep spills' (my_reg : alloc) rs + allocateRegsAndSpill reading keep spills' (final_reg : alloc) rs -- case (3): we need to push something out to free up a register @@ -814,7 +852,8 @@ allocRegsAndSpill_spill reading keep spills alloc r rs assig spill_loc do let inRegOrBoth (InReg _) = True inRegOrBoth (InBoth _ _) = True inRegOrBoth _ = False - let candidates' = + let candidates' :: UniqFM Loc + candidates' = flip delListFromUFM keep $ filterUFM inRegOrBoth $ assig ===================================== compiler/GHC/CmmToAsm/Reg/Linear/Base.hs ===================================== @@ -30,6 +30,7 @@ import GHC.Types.Unique.FM import GHC.Types.Unique.Supply import GHC.Cmm.BlockId +data ReadingOrWriting = Reading | Writing deriving (Eq,Ord) -- | Used to store the register assignment on entry to a basic block. -- We use this to handle join points, where multiple branch instructions @@ -138,6 +139,8 @@ data RA_State freeRegs , ra_config :: !NCGConfig -- | (from,fixup,to) : We inserted fixup code between from and to - , ra_fixups :: [(BlockId,BlockId,BlockId)] } + , ra_fixups :: [(BlockId,BlockId,BlockId)] + + } ===================================== compiler/GHC/CmmToAsm/Reg/Linear/PPC.hs ===================================== @@ -1,3 +1,5 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} + -- | Free regs map for PowerPC module GHC.CmmToAsm.Reg.Linear.PPC where @@ -27,6 +29,9 @@ import Data.Bits data FreeRegs = FreeRegs !Word32 !Word32 deriving( Show ) -- The Show is used in an ASSERT +instance Outputable FreeRegs where + ppr = text . show + noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/SPARC.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for SPARC module GHC.CmmToAsm.Reg.Linear.SPARC where @@ -38,6 +39,9 @@ data FreeRegs instance Show FreeRegs where show = showFreeRegs +instance Outputable FreeRegs where + ppr = text . showFreeRegs + -- | A reg map where no regs are free to be allocated. noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 0 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/State.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE CPP, PatternSynonyms, DeriveFunctor #-} +{-# LANGUAGE ScopedTypeVariables #-} #if !defined(GHC_LOADED_INTO_GHCI) {-# LANGUAGE UnboxedTuples #-} ===================================== compiler/GHC/CmmToAsm/Reg/Linear/X86.hs ===================================== @@ -1,3 +1,4 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for i386 module GHC.CmmToAsm.Reg.Linear.X86 where @@ -9,12 +10,13 @@ import GHC.Platform.Reg.Class import GHC.Platform.Reg import GHC.Utils.Panic import GHC.Platform +import GHC.Utils.Outputable import Data.Word import Data.Bits newtype FreeRegs = FreeRegs Word32 - deriving Show + deriving (Show,Outputable) noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/X86_64.hs ===================================== @@ -1,3 +1,4 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for x86_64 module GHC.CmmToAsm.Reg.Linear.X86_64 where @@ -9,12 +10,13 @@ import GHC.Platform.Reg.Class import GHC.Platform.Reg import GHC.Utils.Panic import GHC.Platform +import GHC.Utils.Outputable import Data.Word import Data.Bits newtype FreeRegs = FreeRegs Word64 - deriving Show + deriving (Show,Outputable) noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -181,6 +181,7 @@ data GeneralFlag | Opt_LlvmFillUndefWithGarbage -- Testing for undef bugs (hidden flag) | Opt_IrrefutableTuples | Opt_CmmSink + | Opt_CmmStaticPred | Opt_CmmElimCommonBlocks | Opt_AsmShortcutting | Opt_OmitYields ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -3514,6 +3514,7 @@ fFlagsDeps = [ flagSpec "case-folding" Opt_CaseFolding, flagSpec "cmm-elim-common-blocks" Opt_CmmElimCommonBlocks, flagSpec "cmm-sink" Opt_CmmSink, + flagSpec "cmm-static-pred" Opt_CmmStaticPred, flagSpec "cse" Opt_CSE, flagSpec "stg-cse" Opt_StgCSE, flagSpec "stg-lift-lams" Opt_StgLiftLams, @@ -4065,6 +4066,7 @@ optLevelFlags -- see Note [Documenting optimisation flags] , ([1,2], Opt_CmmElimCommonBlocks) , ([2], Opt_AsmShortcutting) , ([1,2], Opt_CmmSink) + , ([1,2], Opt_CmmStaticPred) , ([1,2], Opt_CSE) , ([1,2], Opt_StgCSE) , ([2], Opt_StgLiftLams) ===================================== compiler/GHC/Utils/Outputable.hs ===================================== @@ -837,6 +837,9 @@ instance Outputable Word16 where instance Outputable Word32 where ppr n = integer $ fromIntegral n +instance Outputable Word64 where + ppr n = integer $ fromIntegral n + instance Outputable Word where ppr n = integer $ fromIntegral n ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -214,6 +214,19 @@ by saying ``-fno-wombat``. to their usage sites. It also inlines simple expressions like literals or registers. +.. ghc-flag:: -fcmm-static-pred + :shortdesc: Enable static control flow prediction :ghc-flag:`-O`. + :type: dynamic + :reverse: -fno-cmm-static-pred + :category: + + :default: off but enabled with :ghc-flag:`-O`. + + This enables static control flow prediction on the final Cmm + code. If enabled GHC will apply certain heuristics to identify + loops and hot code paths. This information is then used by the + register allocation and code layout passes. + .. ghc-flag:: -fasm-shortcutting :shortdesc: Enable shortcutting on assembly. Implied by :ghc-flag:`-O2`. :type: dynamic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b89a7d6cdcfd8e72b9c630e3172b5ed37f124c51 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b89a7d6cdcfd8e72b9c630e3172b5ed37f124c51 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 11 16:40:23 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Mon, 11 May 2020 12:40:23 -0400 Subject: [Git][ghc/ghc][wip/cpr-expandable-unfoldings] CprAnal: Don't attach CPR sigs to expandable bindings (#18154) Message-ID: <5eb97ff777ed9_616712a9b7f010596841@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/cpr-expandable-unfoldings at Glasgow Haskell Compiler / GHC Commits: b971d0ba by Sebastian Graf at 2020-05-11T18:40:12+02:00 CprAnal: Don't attach CPR sigs to expandable bindings (#18154) Instead, look through expandable unfoldings in `cprTransform`. See the new Note [CPR for expandable unfoldings]: ``` Long static data structures (whether top-level or not) like xs = x1 : xs1 xs1 = x2 : xs2 xs2 = x3 : xs3 should not get CPR signatures, because they * Never get WW'd, so their CPR signature should be irrelevant after analysis (in fact the signature might even be harmful for that reason) * Would need to be inlined/expanded to see their constructed product * Recording CPR on them blows up interface file sizes and is redundant with their unfolding. In case of Nested CPR, this blow-up can be quadratic! But we can't just stop giving DataCon application bindings the CPR property, for example fac 0 = 1 fac n = n * fac (n-1) fac certainly has the CPR property and should be WW'd! But FloatOut will transform the first clause to lvl = 1 fac 0 = lvl If lvl doesn't have the CPR property, fac won't either. But lvl doesn't have a CPR signature to extrapolate into a CPR transformer ('cprTransform'). So instead we keep on cprAnal'ing through *expandable* unfoldings for these arity 0 bindings via 'cprExpandUnfolding_maybe'. In practice, GHC generates a lot of (nested) TyCon and KindRep bindings, one for each data declaration. It's wasteful to attach CPR signatures to each of them (and intractable in case of Nested CPR). ``` Fixes #18154. - - - - - 29 changed files: - compiler/GHC/Core/Opt/CprAnal.hs - testsuite/tests/numeric/should_compile/T14170.stdout - testsuite/tests/numeric/should_compile/T14465.stdout - testsuite/tests/numeric/should_compile/T7116.stdout - testsuite/tests/simplCore/should_compile/T13143.stderr - testsuite/tests/simplCore/should_compile/T13543.stderr - testsuite/tests/simplCore/should_compile/T18013.stderr - testsuite/tests/simplCore/should_compile/T3717.stderr - testsuite/tests/simplCore/should_compile/T3772.stdout - testsuite/tests/simplCore/should_compile/T4908.stderr - testsuite/tests/simplCore/should_compile/T4930.stderr - testsuite/tests/simplCore/should_compile/T7360.stderr - testsuite/tests/simplCore/should_compile/noinline01.stderr - testsuite/tests/simplCore/should_compile/par01.stderr - testsuite/tests/simplCore/should_compile/spec-inline.stderr - testsuite/tests/stranal/should_compile/T10694.stderr - testsuite/tests/stranal/sigs/BottomFromInnerLambda.stderr - testsuite/tests/stranal/sigs/CaseBinderCPR.stderr - testsuite/tests/stranal/sigs/DmdAnalGADTs.hs - testsuite/tests/stranal/sigs/DmdAnalGADTs.stderr - testsuite/tests/stranal/sigs/HyperStrUse.stderr - testsuite/tests/stranal/sigs/NewtypeArity.stderr - testsuite/tests/stranal/sigs/StrAnalExample.stderr - testsuite/tests/stranal/sigs/T12370.stderr - testsuite/tests/stranal/sigs/T17932.stderr - testsuite/tests/stranal/sigs/T5075.stderr - testsuite/tests/stranal/sigs/T8569.stderr - testsuite/tests/stranal/sigs/T8598.stderr - testsuite/tests/stranal/sigs/UnsatFun.stderr Changes: ===================================== compiler/GHC/Core/Opt/CprAnal.hs ===================================== @@ -21,7 +21,6 @@ import GHC.Core.Seq import GHC.Utils.Outputable import GHC.Types.Var.Env import GHC.Types.Basic -import Data.List import GHC.Core.DataCon import GHC.Types.Id import GHC.Types.Id.Info @@ -34,6 +33,9 @@ import GHC.Utils.Misc import GHC.Utils.Error ( dumpIfSet_dyn, DumpFormat (..) ) import GHC.Data.Maybe ( isJust, isNothing ) +import Control.Monad ( guard ) +import Data.List + {- Note [Constructed Product Result] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The goal of Constructed Product Result analysis is to identify functions that @@ -231,9 +233,14 @@ cprTransform env id sig where sig - | isGlobalId id -- imported function or data con worker + -- See Note [CPR for expandable unfoldings] + | Just rhs <- cprExpandUnfolding_maybe id + = fst $ cprAnal env rhs + -- Imported function or data con worker + | isGlobalId id = getCprSig (idCprInfo id) - | Just sig <- lookupSigEnv env id -- local let-bound + -- Local let-bound + | Just sig <- lookupSigEnv env id = getCprSig sig | otherwise = topCprType @@ -303,6 +310,8 @@ cprAnalBind top_lvl env id rhs | stays_thunk = trimCprTy rhs_ty -- See Note [CPR for sum types] | returns_sum = trimCprTy rhs_ty + -- See Note [CPR for expandable unfoldings] + | will_expand = topCprType | otherwise = rhs_ty -- See Note [Arity trimming for CPR signatures] sig = mkCprSigForArity (idArity id) rhs_ty' @@ -316,6 +325,15 @@ cprAnalBind top_lvl env id rhs (_, ret_ty) = splitPiTys (idType id) not_a_prod = isNothing (deepSplitProductType_maybe (ae_fam_envs env) ret_ty) returns_sum = not (isTopLevel top_lvl) && not_a_prod + -- See Note [CPR for expandable unfoldings] + will_expand = isJust (cprExpandUnfolding_maybe id) + +cprExpandUnfolding_maybe :: Id -> Maybe CoreExpr +cprExpandUnfolding_maybe id = do + guard (idArity id == 0) + -- There are only phase 0 Simplifier runs after CPR analysis + guard (isActiveIn 0 (idInlineActivation id)) + expandUnfolding_maybe (idUnfolding id) {- Note [Arity trimming for CPR signatures] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -626,6 +644,48 @@ fac won't have the CPR property here when we trim every thunk! But the assumption is that error cases are rarely entered and we are diverging anyway, so WW doesn't hurt. +Should we also trim CPR on DataCon application bindings? +See Note [CPR for expandable unfoldings]! + +Note [CPR for expandable unfoldings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Long static data structures (whether top-level or not) like + + xs = x1 : xs1 + xs1 = x2 : xs2 + xs2 = x3 : xs3 + +should not get CPR signatures, because they + + * Never get WW'd, so their CPR signature should be irrelevant after analysis + (in fact the signature might even be harmful for that reason) + * Would need to be inlined/expanded to see their constructed product + * Recording CPR on them blows up interface file sizes and is redundant with + their unfolding. In case of Nested CPR, this blow-up can be quadratic! + +But we can't just stop giving DataCon application bindings the CPR property, +for example + + fac 0 = 1 + fac n = n * fac (n-1) + +fac certainly has the CPR property and should be WW'd! But FloatOut will +transform the first clause to + + lvl = 1 + fac 0 = lvl + +If lvl doesn't have the CPR property, fac won't either. But lvl doesn't have a +CPR signature to extrapolate into a CPR transformer ('cprTransform'). So +instead we keep on cprAnal'ing through *expandable* unfoldings for these arity +0 bindings via 'cprExpandUnfolding_maybe'. + +In practice, GHC generates a lot of (nested) TyCon and KindRep bindings, one +for each data declaration. It's wasteful to attach CPR signatures to each of +them (and intractable in case of Nested CPR). + +Tracked by #18154. + Note [CPR examples] ~~~~~~~~~~~~~~~~~~~~ Here are some examples (stranal/should_compile/T10482a) of the ===================================== testsuite/tests/numeric/should_compile/T14170.stdout ===================================== @@ -13,7 +13,6 @@ NatVal.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} NatVal.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] NatVal.$trModule3 = GHC.Types.TrNameS NatVal.$trModule4 @@ -28,7 +27,6 @@ NatVal.$trModule2 = "NatVal"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} NatVal.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] NatVal.$trModule1 = GHC.Types.TrNameS NatVal.$trModule2 @@ -36,7 +34,6 @@ NatVal.$trModule1 = GHC.Types.TrNameS NatVal.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} NatVal.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] NatVal.$trModule ===================================== testsuite/tests/numeric/should_compile/T14465.stdout ===================================== @@ -20,7 +20,6 @@ M.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} M.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] M.$trModule3 = GHC.Types.TrNameS M.$trModule4 @@ -35,7 +34,6 @@ M.$trModule2 = "M"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} M.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] M.$trModule1 = GHC.Types.TrNameS M.$trModule2 @@ -43,7 +41,6 @@ M.$trModule1 = GHC.Types.TrNameS M.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} M.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] M.$trModule = GHC.Types.Module M.$trModule3 M.$trModule1 ===================================== testsuite/tests/numeric/should_compile/T7116.stdout ===================================== @@ -13,7 +13,6 @@ T7116.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7116.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7116.$trModule3 = GHC.Types.TrNameS T7116.$trModule4 @@ -28,7 +27,6 @@ T7116.$trModule2 = "T7116"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7116.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7116.$trModule1 = GHC.Types.TrNameS T7116.$trModule2 @@ -36,7 +34,6 @@ T7116.$trModule1 = GHC.Types.TrNameS T7116.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T7116.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T7116.$trModule ===================================== testsuite/tests/simplCore/should_compile/T13143.stderr ===================================== @@ -33,7 +33,6 @@ T13143.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T13143.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T13143.$trModule3 = GHC.Types.TrNameS T13143.$trModule4 @@ -48,7 +47,6 @@ T13143.$trModule2 = "T13143"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T13143.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T13143.$trModule1 = GHC.Types.TrNameS T13143.$trModule2 @@ -56,7 +54,6 @@ T13143.$trModule1 = GHC.Types.TrNameS T13143.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T13143.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T13143.$trModule ===================================== testsuite/tests/simplCore/should_compile/T13543.stderr ===================================== @@ -7,7 +7,7 @@ Foo.g: ==================== Cpr signatures ==================== -Foo.$trModule: m1 +Foo.$trModule: Foo.f: m1 Foo.g: m1 ===================================== testsuite/tests/simplCore/should_compile/T18013.stderr ===================================== @@ -177,7 +177,6 @@ T18013.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T18013.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T18013.$trModule3 = GHC.Types.TrNameS T18013.$trModule4 @@ -192,7 +191,6 @@ T18013.$trModule2 = "T18013"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T18013.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T18013.$trModule1 = GHC.Types.TrNameS T18013.$trModule2 @@ -200,7 +198,6 @@ T18013.$trModule1 = GHC.Types.TrNameS T18013.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T18013.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T18013.$trModule ===================================== testsuite/tests/simplCore/should_compile/T3717.stderr ===================================== @@ -13,7 +13,6 @@ T3717.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T3717.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T3717.$trModule3 = GHC.Types.TrNameS T3717.$trModule4 @@ -28,7 +27,6 @@ T3717.$trModule2 = "T3717"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T3717.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T3717.$trModule1 = GHC.Types.TrNameS T3717.$trModule2 @@ -36,7 +34,6 @@ T3717.$trModule1 = GHC.Types.TrNameS T3717.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T3717.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T3717.$trModule ===================================== testsuite/tests/simplCore/should_compile/T3772.stdout ===================================== @@ -13,7 +13,6 @@ T3772.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T3772.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T3772.$trModule3 = GHC.Types.TrNameS T3772.$trModule4 @@ -28,7 +27,6 @@ T3772.$trModule2 = "T3772"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T3772.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T3772.$trModule1 = GHC.Types.TrNameS T3772.$trModule2 @@ -36,7 +34,6 @@ T3772.$trModule1 = GHC.Types.TrNameS T3772.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T3772.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T3772.$trModule ===================================== testsuite/tests/simplCore/should_compile/T4908.stderr ===================================== @@ -13,7 +13,6 @@ T4908.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T4908.$trModule3 :: TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T4908.$trModule3 = GHC.Types.TrNameS T4908.$trModule4 @@ -28,7 +27,6 @@ T4908.$trModule2 = "T4908"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T4908.$trModule1 :: TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T4908.$trModule1 = GHC.Types.TrNameS T4908.$trModule2 @@ -36,7 +34,6 @@ T4908.$trModule1 = GHC.Types.TrNameS T4908.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T4908.$trModule :: Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T4908.$trModule ===================================== testsuite/tests/simplCore/should_compile/T4930.stderr ===================================== @@ -13,7 +13,6 @@ T4930.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T4930.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T4930.$trModule3 = GHC.Types.TrNameS T4930.$trModule4 @@ -28,7 +27,6 @@ T4930.$trModule2 = "T4930"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T4930.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T4930.$trModule1 = GHC.Types.TrNameS T4930.$trModule2 @@ -36,7 +34,6 @@ T4930.$trModule1 = GHC.Types.TrNameS T4930.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T4930.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T4930.$trModule ===================================== testsuite/tests/simplCore/should_compile/T7360.stderr ===================================== @@ -64,7 +64,6 @@ T7360.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$trModule3 = GHC.Types.TrNameS T7360.$trModule4 @@ -79,7 +78,6 @@ T7360.$trModule2 = "T7360"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$trModule1 = GHC.Types.TrNameS T7360.$trModule2 @@ -87,7 +85,6 @@ T7360.$trModule1 = GHC.Types.TrNameS T7360.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T7360.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T7360.$trModule @@ -110,7 +107,6 @@ T7360.$tcFoo2 = "Foo"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$tcFoo1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$tcFoo1 = GHC.Types.TrNameS T7360.$tcFoo2 @@ -118,7 +114,6 @@ T7360.$tcFoo1 = GHC.Types.TrNameS T7360.$tcFoo2 -- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} T7360.$tcFoo :: GHC.Types.TyCon [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 70}] T7360.$tcFoo @@ -147,7 +142,6 @@ T7360.$tc'Foo6 = "'Foo1"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo5 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$tc'Foo5 = GHC.Types.TrNameS T7360.$tc'Foo6 @@ -155,7 +149,6 @@ T7360.$tc'Foo5 = GHC.Types.TrNameS T7360.$tc'Foo6 -- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo1 :: GHC.Types.TyCon [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 70}] T7360.$tc'Foo1 @@ -177,7 +170,6 @@ T7360.$tc'Foo8 = "'Foo2"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo7 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$tc'Foo7 = GHC.Types.TrNameS T7360.$tc'Foo8 @@ -185,7 +177,6 @@ T7360.$tc'Foo7 = GHC.Types.TrNameS T7360.$tc'Foo8 -- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo2 :: GHC.Types.TyCon [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 70}] T7360.$tc'Foo2 @@ -212,7 +203,6 @@ T7360.$tc'Foo11 = "'Foo3"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo10 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$tc'Foo10 = GHC.Types.TrNameS T7360.$tc'Foo11 @@ -220,7 +210,6 @@ T7360.$tc'Foo10 = GHC.Types.TrNameS T7360.$tc'Foo11 -- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo3 :: GHC.Types.TyCon [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 70}] T7360.$tc'Foo3 ===================================== testsuite/tests/simplCore/should_compile/noinline01.stderr ===================================== @@ -14,7 +14,7 @@ Noinline01.$trModule4 :: GHC.Prim.Addr# "main"#; Noinline01.$trModule3 :: GHC.Types.TrName -[GblId, Cpr=m1, Unf=OtherCon []] = +[GblId, Unf=OtherCon []] = CCS_DONT_CARE GHC.Types.TrNameS! [Noinline01.$trModule4]; Noinline01.$trModule2 :: GHC.Prim.Addr# @@ -22,11 +22,11 @@ Noinline01.$trModule2 :: GHC.Prim.Addr# "Noinline01"#; Noinline01.$trModule1 :: GHC.Types.TrName -[GblId, Cpr=m1, Unf=OtherCon []] = +[GblId, Unf=OtherCon []] = CCS_DONT_CARE GHC.Types.TrNameS! [Noinline01.$trModule2]; Noinline01.$trModule :: GHC.Types.Module -[GblId, Cpr=m1, Unf=OtherCon []] = +[GblId, Unf=OtherCon []] = CCS_DONT_CARE GHC.Types.Module! [Noinline01.$trModule3 Noinline01.$trModule1]; ===================================== testsuite/tests/simplCore/should_compile/par01.stderr ===================================== @@ -21,7 +21,7 @@ Par01.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Par01.$trModule3 :: GHC.Types.TrName -[GblId, Cpr=m1, Unf=OtherCon []] +[GblId, Unf=OtherCon []] Par01.$trModule3 = GHC.Types.TrNameS Par01.$trModule4 -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} @@ -31,12 +31,12 @@ Par01.$trModule2 = "Par01"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Par01.$trModule1 :: GHC.Types.TrName -[GblId, Cpr=m1, Unf=OtherCon []] +[GblId, Unf=OtherCon []] Par01.$trModule1 = GHC.Types.TrNameS Par01.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} Par01.$trModule :: GHC.Types.Module -[GblId, Cpr=m1, Unf=OtherCon []] +[GblId, Unf=OtherCon []] Par01.$trModule = GHC.Types.Module Par01.$trModule3 Par01.$trModule1 ===================================== testsuite/tests/simplCore/should_compile/spec-inline.stderr ===================================== @@ -13,7 +13,6 @@ Roman.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Roman.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] Roman.$trModule3 = GHC.Types.TrNameS Roman.$trModule4 @@ -28,7 +27,6 @@ Roman.$trModule2 = "Roman"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Roman.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] Roman.$trModule1 = GHC.Types.TrNameS Roman.$trModule2 @@ -36,7 +34,6 @@ Roman.$trModule1 = GHC.Types.TrNameS Roman.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} Roman.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] Roman.$trModule @@ -132,7 +129,6 @@ Roman.foo_go -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Roman.foo2 :: Int [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] Roman.foo2 = GHC.Types.I# 6# @@ -140,7 +136,6 @@ Roman.foo2 = GHC.Types.I# 6# -- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0} Roman.foo1 :: Maybe Int [GblId, - Cpr=m2, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] Roman.foo1 = GHC.Maybe.Just @Int Roman.foo2 ===================================== testsuite/tests/stranal/should_compile/T10694.stderr ===================================== @@ -6,26 +6,26 @@ Result size of Tidy Core = {terms: 74, types: 65, coercions: 0, joins: 0/4} T10694.$wpm [InlPrag=NOINLINE] :: Int -> Int -> (# Int, Int #) [GblId, Arity=2, Str=, Unf=OtherCon []] T10694.$wpm - = \ (w_s1vj :: Int) (w1_s1vk :: Int) -> + = \ (w_s1v1 :: Int) (w1_s1v2 :: Int) -> let { - l_s1uR :: Int + l_s1uz :: Int [LclId] - l_s1uR - = case w_s1vj of { GHC.Types.I# x_aJ9 -> case w1_s1vk of { GHC.Types.I# y_aJc -> GHC.Types.I# (GHC.Prim.+# x_aJ9 y_aJc) } } } in + l_s1uz + = case w_s1v1 of { GHC.Types.I# x_aJ0 -> case w1_s1v2 of { GHC.Types.I# y_aJ3 -> GHC.Types.I# (GHC.Prim.+# x_aJ0 y_aJ3) } } } in let { - l1_s1uS :: Int + l1_s1uA :: Int [LclId] - l1_s1uS - = case w_s1vj of { GHC.Types.I# x_aJh -> case w1_s1vk of { GHC.Types.I# y_aJk -> GHC.Types.I# (GHC.Prim.-# x_aJh y_aJk) } } } in + l1_s1uA + = case w_s1v1 of { GHC.Types.I# x_aJ8 -> case w1_s1v2 of { GHC.Types.I# y_aJb -> GHC.Types.I# (GHC.Prim.-# x_aJ8 y_aJb) } } } in let { - l2_s1uT :: [Int] + l2_s1uB :: [Int] [LclId, Unf=OtherCon []] - l2_s1uT = GHC.Types.: @Int l1_s1uS (GHC.Types.[] @Int) } in + l2_s1uB = GHC.Types.: @Int l1_s1uA (GHC.Types.[] @Int) } in let { - l3_sJv :: [Int] + l3_sJm :: [Int] [LclId, Unf=OtherCon []] - l3_sJv = GHC.Types.: @Int l_s1uR l2_s1uT } in - (# GHC.List.$w!! @Int l3_sJv 0#, GHC.List.$w!! @Int l3_sJv 1# #) + l3_sJm = GHC.Types.: @Int l_s1uz l2_s1uB } in + (# GHC.List.$w!! @Int l3_sJm 0#, GHC.List.$w!! @Int l3_sJm 1# #) -- RHS size: {terms: 10, types: 11, coercions: 0, joins: 0/0} pm [InlPrag=NOUSERINLINE[0]] :: Int -> Int -> (Int, Int) @@ -35,9 +35,9 @@ pm [InlPrag=NOUSERINLINE[0]] :: Int -> Int -> (Int, Int) Cpr=m1, Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=2,unsat_ok=True,boring_ok=False) - Tmpl= \ (w_s1vj [Occ=Once] :: Int) (w1_s1vk [Occ=Once] :: Int) -> - case T10694.$wpm w_s1vj w1_s1vk of { (# ww1_s1vp [Occ=Once], ww2_s1vq [Occ=Once] #) -> (ww1_s1vp, ww2_s1vq) }}] -pm = \ (w_s1vj :: Int) (w1_s1vk :: Int) -> case T10694.$wpm w_s1vj w1_s1vk of { (# ww1_s1vp, ww2_s1vq #) -> (ww1_s1vp, ww2_s1vq) } + Tmpl= \ (w_s1v1 [Occ=Once] :: Int) (w1_s1v2 [Occ=Once] :: Int) -> + case T10694.$wpm w_s1v1 w1_s1v2 of { (# ww1_s1v7 [Occ=Once], ww2_s1v8 [Occ=Once] #) -> (ww1_s1v7, ww2_s1v8) }}] +pm = \ (w_s1v1 :: Int) (w1_s1v2 :: Int) -> case T10694.$wpm w_s1v1 w1_s1v2 of { (# ww1_s1v7, ww2_s1v8 #) -> (ww1_s1v7, ww2_s1v8) } -- RHS size: {terms: 8, types: 9, coercions: 0, joins: 0/0} m :: Int -> Int -> Int @@ -46,9 +46,9 @@ m :: Int -> Int -> Int Str=, Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=2,unsat_ok=True,boring_ok=False) - Tmpl= \ (x_awt [Occ=Once] :: Int) (y_awu [Occ=Once] :: Int) -> - case pm x_awt y_awu of { (_ [Occ=Dead], mr_aww [Occ=Once]) -> mr_aww }}] -m = \ (x_awt :: Int) (y_awu :: Int) -> case T10694.$wpm x_awt y_awu of { (# ww1_s1vp, ww2_s1vq #) -> ww2_s1vq } + Tmpl= \ (x_awo [Occ=Once] :: Int) (y_awp [Occ=Once] :: Int) -> + case pm x_awo y_awp of { (_ [Occ=Dead], mr_awr [Occ=Once]) -> mr_awr }}] +m = \ (x_awo :: Int) (y_awp :: Int) -> case T10694.$wpm x_awo y_awp of { (# ww1_s1v7, ww2_s1v8 #) -> ww2_s1v8 } -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T10694.$trModule4 :: GHC.Prim.Addr# @@ -57,9 +57,7 @@ T10694.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T10694.$trModule3 :: GHC.Types.TrName -[GblId, - Cpr=m1, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T10694.$trModule3 = GHC.Types.TrNameS T10694.$trModule4 -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} @@ -69,17 +67,13 @@ T10694.$trModule2 = "T10694"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T10694.$trModule1 :: GHC.Types.TrName -[GblId, - Cpr=m1, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T10694.$trModule1 = GHC.Types.TrNameS T10694.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} -T10694.$trModule :: GHC.Unit.Module -[GblId, - Cpr=m1, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] -T10694.$trModule = GHC.Unit.Module T10694.$trModule3 T10694.$trModule1 +T10694.$trModule :: GHC.Types.Module +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] +T10694.$trModule = GHC.Types.Module T10694.$trModule3 T10694.$trModule1 ===================================== testsuite/tests/stranal/sigs/BottomFromInnerLambda.stderr ===================================== @@ -7,7 +7,7 @@ BottomFromInnerLambda.f: ==================== Cpr signatures ==================== -BottomFromInnerLambda.$trModule: m1 +BottomFromInnerLambda.$trModule: BottomFromInnerLambda.expensive: m1 BottomFromInnerLambda.f: ===================================== testsuite/tests/stranal/sigs/CaseBinderCPR.stderr ===================================== @@ -6,7 +6,7 @@ CaseBinderCPR.f_list_cmp: ==================== Cpr signatures ==================== -CaseBinderCPR.$trModule: m1 +CaseBinderCPR.$trModule: CaseBinderCPR.f_list_cmp: m1 ===================================== testsuite/tests/stranal/sigs/DmdAnalGADTs.hs ===================================== @@ -7,11 +7,13 @@ data D a where A :: D Int B :: D (Int -> Int) +-- Doesn't have the CPR property anymore (#18154), but an expandable unfolding. +-- The point of this test is that f' has the CPR property. hasCPR :: Int hasCPR = 1 hasStrSig :: Int -> Int -hasStrSig x = x +hasStrSig x = x + 1 diverges :: Int diverges = diverges ===================================== testsuite/tests/stranal/sigs/DmdAnalGADTs.stderr ===================================== @@ -9,21 +9,21 @@ DmdAnalGADTs.f: DmdAnalGADTs.f': DmdAnalGADTs.g: DmdAnalGADTs.hasCPR: -DmdAnalGADTs.hasStrSig: +DmdAnalGADTs.hasStrSig: ==================== Cpr signatures ==================== -DmdAnalGADTs.$tc'A: m1 -DmdAnalGADTs.$tc'B: m1 -DmdAnalGADTs.$tcD: m1 -DmdAnalGADTs.$trModule: m1 +DmdAnalGADTs.$tc'A: +DmdAnalGADTs.$tc'B: +DmdAnalGADTs.$tcD: +DmdAnalGADTs.$trModule: DmdAnalGADTs.diverges: b DmdAnalGADTs.f: DmdAnalGADTs.f': m1 DmdAnalGADTs.g: -DmdAnalGADTs.hasCPR: m1 -DmdAnalGADTs.hasStrSig: +DmdAnalGADTs.hasCPR: +DmdAnalGADTs.hasStrSig: m1 @@ -37,6 +37,6 @@ DmdAnalGADTs.f: DmdAnalGADTs.f': DmdAnalGADTs.g: DmdAnalGADTs.hasCPR: -DmdAnalGADTs.hasStrSig: +DmdAnalGADTs.hasStrSig: ===================================== testsuite/tests/stranal/sigs/HyperStrUse.stderr ===================================== @@ -6,7 +6,7 @@ HyperStrUse.f: ==================== Cpr signatures ==================== -HyperStrUse.$trModule: m1 +HyperStrUse.$trModule: HyperStrUse.f: m1 ===================================== testsuite/tests/stranal/sigs/NewtypeArity.stderr ===================================== @@ -9,9 +9,9 @@ Test.t2: ==================== Cpr signatures ==================== -Test.$tc'MkT: m1 -Test.$tcT: m1 -Test.$trModule: m1 +Test.$tc'MkT: +Test.$tcT: +Test.$trModule: Test.t: m1 Test.t2: m1 ===================================== testsuite/tests/stranal/sigs/StrAnalExample.stderr ===================================== @@ -6,7 +6,7 @@ StrAnalExample.foo: ==================== Cpr signatures ==================== -StrAnalExample.$trModule: m1 +StrAnalExample.$trModule: StrAnalExample.foo: ===================================== testsuite/tests/stranal/sigs/T12370.stderr ===================================== @@ -7,7 +7,7 @@ T12370.foo: ==================== Cpr signatures ==================== -T12370.$trModule: m1 +T12370.$trModule: T12370.bar: m1 T12370.foo: m1 ===================================== testsuite/tests/stranal/sigs/T17932.stderr ===================================== @@ -10,11 +10,11 @@ T17932.flags: ==================== Cpr signatures ==================== -T17932.$tc'Options: m1 -T17932.$tc'X: m1 -T17932.$tcOptions: m1 -T17932.$tcX: m1 -T17932.$trModule: m1 +T17932.$tc'Options: +T17932.$tc'X: +T17932.$tcOptions: +T17932.$tcX: +T17932.$trModule: T17932.flags: ===================================== testsuite/tests/stranal/sigs/T5075.stderr ===================================== @@ -6,7 +6,7 @@ T5075.loop: ==================== Cpr signatures ==================== -T8569.$tc'Rdata: m1 -T8569.$tc'Rint: m1 -T8569.$tcRep: m1 -T8569.$trModule: m1 +T8569.$tc'Rdata: +T8569.$tc'Rint: +T8569.$tcRep: +T8569.$trModule: T8569.addUp: ===================================== testsuite/tests/stranal/sigs/T8598.stderr ===================================== @@ -6,7 +6,7 @@ T8598.fun: ==================== Cpr signatures ==================== -T8598.$trModule: m1 +T8598.$trModule: T8598.fun: m1 ===================================== testsuite/tests/stranal/sigs/UnsatFun.stderr ===================================== @@ -12,7 +12,7 @@ UnsatFun.h3: ==================== Cpr signatures ==================== -UnsatFun.$trModule: m1 +UnsatFun.$trModule: UnsatFun.f: b UnsatFun.g: UnsatFun.g': View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b971d0ba91afa44ba6085dc58845759aa872cc82 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b971d0ba91afa44ba6085dc58845759aa872cc82 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 11 16:48:46 2020 From: gitlab at gitlab.haskell.org (John Ericson) Date: Mon, 11 May 2020 12:48:46 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/hswrapper-safe-elim Message-ID: <5eb981eeb0975_61673f819aad978c106107c8@gitlab.haskell.org.mail> John Ericson pushed new branch wip/hswrapper-safe-elim at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/hswrapper-safe-elim You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 11 17:07:48 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Mon, 11 May 2020 13:07:48 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 25 commits: rts/CNF: Fix fixup comparison function Message-ID: <5eb986645194f_6167119ebbd01061987a@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 444903c1 by Ben Gamari at 2020-05-11T13:07:11-04:00 rts/CNF: Fix fixup comparison function Previously we would implicitly convert the difference between two words to an int, resulting in an integer overflow on 64-bit machines. Fixes #16992 - - - - - 4eeb9b65 by Ömer Sinan Ağacan at 2020-05-11T13:07:17-04:00 Pack some of IdInfo fields into a bit field This reduces residency of compiler quite a bit on some programs. Example stats when building T10370: Before: 2,871,242,832 bytes allocated in the heap 4,693,328,008 bytes copied during GC 33,941,448 bytes maximum residency (276 sample(s)) 375,976 bytes maximum slop 83 MiB total memory in use (0 MB lost due to fragmentation) After: 2,858,897,344 bytes allocated in the heap 4,629,255,440 bytes copied during GC 32,616,624 bytes maximum residency (278 sample(s)) 314,400 bytes maximum slop 80 MiB total memory in use (0 MB lost due to fragmentation) So -3.9% residency, -1.3% bytes copied and -0.4% allocations. Fixes #17497 Metric Decrease: T9233 T9675 - - - - - fea9ddfa by Ben Gamari at 2020-05-11T13:07:18-04:00 get-win32-tarballs: Fix base URL Revert a change previously made for testing purposes. - - - - - 972bfffb by Ben Gamari at 2020-05-11T13:07:18-04:00 get-win32-tarballs: Improve diagnostics output - - - - - 2aa29e91 by Simon Jakobi at 2020-05-11T13:07:19-04:00 docs: Add examples for Data.Semigroup.Arg{Min,Max} Context: #17153 - - - - - 0cbdbe6e by Baldur Blöndal at 2020-05-11T13:07:21-04:00 Predicate, Equivalence derive via `.. -> a -> All' - - - - - 0d6fac36 by Ben Gamari at 2020-05-11T13:07:22-04:00 Add few cleanups of the CAF logic Give the NameSet of non-CAFfy names a proper newtype to distinguish it from all of the other NameSets floating about. - - - - - 1ba0ab26 by Emeka Nkurumeh at 2020-05-11T13:07:23-04:00 fix printf warning when using with ghc with clang on mingw - - - - - 117ec613 by Daniel Gröber at 2020-05-11T13:07:24-04:00 Fix non power-of-two Storable.alignment in Capi_Ctype tests Alignments passed to alloca and friends must be a power of two for the code in allocatePinned to work properly. Commit 41230e2601 ("Zero out pinned block alignment slop when profiling") introduced an ASSERT for this but this test was still violating it. - - - - - 40d6382a by Daniel Gröber at 2020-05-11T13:07:24-04:00 Improve ByteArray# documentation regarding alignment - - - - - c2ec0908 by Daniel Gröber at 2020-05-11T13:07:24-04:00 Document word-size rounding of ByteArray# memory (Fix #14731) - - - - - 864fd8ee by Daniel Gröber at 2020-05-11T13:07:24-04:00 Throw IOError when allocaBytesAligned gets non-power-of-two align - - - - - d15847db by Artem Pelenitsyn at 2020-05-11T13:07:26-04:00 Don't reload environment files on every setSessionDynFlags Makes `interpretPackageEnv` (which loads envirinment files) a part of `parseDynamicFlags` (parsing command-line arguments, which is typically done once) instead of `setSessionDynFlags` (which is typically called several times). Making several (transitive) calls to `interpretPackageEnv`, as before, caused #18125 #16318, which should be fixed now. - - - - - 2749d171 by Ben Gamari at 2020-05-11T13:07:26-04:00 GHC.Cmm.Opt: Handle MO_XX_Conv This MachOp was introduced by 2c959a1894311e59cd2fd469c1967491c1e488f3 but a wildcard match in cmmMachOpFoldM hid the fact that it wasn't handled. Ideally we would eliminate the match but this appears to be a larger task. Fixes #18141. - - - - - 0adabe86 by Hécate at 2020-05-11T13:07:27-04:00 fix(documentation): Fix the RST links to GHC.Prim - - - - - a463175e by Baldur Blöndal at 2020-05-11T13:07:28-04:00 Document (->) using inferred quantification for its runtime representations. Fixes #18142. - - - - - ba16cedb by Takenobu Tani at 2020-05-11T13:07:30-04:00 Tweak man page for ghc command This commit updates the ghc command's man page as followings: * Enable `man_show_urls` to show URL addresses in the `DESCRIPTION` section of ghc.rst, because sphinx currently removes hyperlinks for man pages. * Add a `SEE ALSO` section to point to the GHC homepage - - - - - 7fd05a7a by Takenobu Tani at 2020-05-11T13:07:32-04:00 GHCi: Add link to the user's guide in help message This commit adds a link to the user's guide in ghci's `:help` message. Newcomers could easily reach to details of ghci. - - - - - 90d55045 by Jeff Happily at 2020-05-11T13:07:33-04:00 Handle single unused import - - - - - 2cacab4b by Ben Gamari at 2020-05-11T13:07:34-04:00 users-guide: Add discussion of shared object naming Fixes #18074. - - - - - 838f95a6 by Ben Gamari at 2020-05-11T13:07:34-04:00 Ensure that printMinimalImports closes handle Fixes #18166. - - - - - 7c430d00 by Ben Gamari at 2020-05-11T13:07:35-04:00 testsuite: Print sign of performance changes Executes the minor formatting change in the tabulated performance changes suggested in #18135. - - - - - 9a2bc5d6 by Ben Gamari at 2020-05-11T13:07:35-04:00 hadrian: Tell testsuite driver about LLVM availability This reflects the logic present in the Make build system into Hadrian. Fixes #18167. - - - - - 7a881582 by Ben Gamari at 2020-05-11T13:07:36-04:00 testsuite: Add testcase for #18129 - - - - - 65d40bd5 by Ben Gamari at 2020-05-11T13:07:36-04:00 Revert "Specify kind variables for inferred kinds in base." As noted in !3132, this has rather severe knock-on consequences in user-code. We'll need to revisit this before merging something along these lines. This reverts commit 9749fe1223d182b1f8e7e4f7378df661c509f396. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/UpdateCafInfos.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Name/Set.hs - docs/users_guide/conf.py - docs/users_guide/editing-guide.rst - docs/users_guide/exts/ffi.rst - docs/users_guide/exts/primitives.rst - docs/users_guide/ghc.rst - docs/users_guide/packages.rst - docs/users_guide/phases.rst - ghc/GHCi/UI.hs - hadrian/src/Settings/Builders/RunTest.hs - includes/rts/Messages.h - libraries/base/Control/Arrow.hs - libraries/base/Control/Category.hs - libraries/base/Data/Data.hs - libraries/base/Data/Dynamic.hs - libraries/base/Data/Fixed.hs - libraries/base/Data/Functor/Compose.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/df0c5d4e8d76cefe793dfd0a8d6f698f51681e6c...65d40bd5c9a5d890328855cf1693ccda38e187f7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/df0c5d4e8d76cefe793dfd0a8d6f698f51681e6c...65d40bd5c9a5d890328855cf1693ccda38e187f7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 11 17:09:14 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 11 May 2020 13:09:14 -0400 Subject: [Git][ghc/ghc][wip/lower-tc-tracing-cost] Avoid unnecessary allocations due to tracing utilities Message-ID: <5eb986baf3642_616712a9b7f01065165c@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/lower-tc-tracing-cost at Glasgow Haskell Compiler / GHC Commits: a0b49468 by Ben Gamari at 2020-05-11T13:08:49-04:00 Avoid unnecessary allocations due to tracing utilities While ticky-profiling the typechecker I noticed that hundreds of millions of SDocs are being allocated just in case -ddump-*-trace is enabled. This is awful. We avoid this by ensuring that the dump flag check is inlined into the call site, ensuring that the tracing document needn't be allocated unless it's actually needed. See Note [INLINE conditional tracing utilities] for details. Fixes #18168. Metric Decrease: T9961 - - - - - 7 changed files: - compiler/GHC/Core/Opt/Simplify/Monad.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/Tc/Solver/Flatten.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Utils/Error.hs Changes: ===================================== compiler/GHC/Core/Opt/Simplify/Monad.hs ===================================== @@ -143,6 +143,7 @@ traceSmpl herald doc ; liftIO $ Err.dumpIfSet_dyn dflags Opt_D_dump_simpl_trace "Simpl Trace" FormatText (hang (text herald) 2 doc) } +{-# INLINE traceSmpl #-} -- see Note [INLINE conditional tracing utilities] {- ************************************************************************ ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -1279,7 +1279,10 @@ callSiteInline dflags id active_unfolding lone_variable arg_infos cont_info -- | Report the inlining of an identifier's RHS to the user, if requested. traceInline :: DynFlags -> Id -> String -> SDoc -> a -> a -traceInline dflags inline_id str doc result = +traceInline dflags inline_id str doc result + -- We take care to ensure that doc is used in only one branch, ensuring that + -- the simplifier can push its allocation into the branch. See Note [INLINE + -- conditional tracing utilities]. | enable = traceAction dflags str doc result | otherwise = result where @@ -1288,6 +1291,9 @@ traceInline dflags inline_id str doc result = = True | Just prefix <- inlineCheck dflags = prefix `isPrefixOf` occNameString (getOccName inline_id) + | otherwise + = False +{-# INLINE traceInline #-} -- see Note [INLINE conditional tracing utilities] tryUnfolding :: DynFlags -> Id -> Bool -> [ArgSummary] -> CallCtxt -> CoreExpr -> Bool -> Bool -> UnfoldingGuidance ===================================== compiler/GHC/HsToCore/PmCheck/Oracle.hs ===================================== @@ -89,6 +89,7 @@ tracePm herald doc = do printer <- mkPrintUnqualifiedDs liftIO $ dumpIfSet_dyn_printer printer dflags Opt_D_dump_ec_trace "" FormatText (text herald $$ (nest 2 doc)) +{-# INLINE tracePm #-} -- see Note [INLINE conditional tracing utilities] -- | Generate a fresh `Id` of a given type mkPmId :: Type -> DsM Id ===================================== compiler/GHC/Tc/Solver/Flatten.hs ===================================== @@ -543,6 +543,7 @@ runFlatten mode loc flav eq_rel thing_inside traceFlat :: String -> SDoc -> FlatM () traceFlat herald doc = liftTcS $ traceTcS herald doc +{-# INLINE traceFlat #-} -- see Note [INLINE conditional tracing utilities] getFlatEnvField :: (FlattenEnv -> a) -> FlatM a getFlatEnvField accessor ===================================== compiler/GHC/Tc/Solver/Monad.hs ===================================== @@ -2733,6 +2733,7 @@ panicTcS doc = pprPanic "GHC.Tc.Solver.Canonical" doc traceTcS :: String -> SDoc -> TcS () traceTcS herald doc = wrapTcS (TcM.traceTc herald doc) +{-# INLINE traceTcS #-} -- see Note [INLINE conditional tracing utilities] runTcPluginTcS :: TcPluginM a -> TcS a runTcPluginTcS m = wrapTcS . runTcPluginM m =<< getTcEvBindsVar @@ -2751,6 +2752,7 @@ bumpStepCountTcS = TcS $ \env -> do { let ref = tcs_count env csTraceTcS :: SDoc -> TcS () csTraceTcS doc = wrapTcS $ csTraceTcM (return doc) +{-# INLINE csTraceTcS #-} -- see Note [INLINE conditional tracing utilities] traceFireTcS :: CtEvidence -> SDoc -> TcS () -- Dump a rule-firing trace @@ -2763,6 +2765,7 @@ traceFireTcS ev doc text "d:" <> ppr (ctLocDepth (ctEvLoc ev))) <+> doc <> colon) 4 (ppr ev)) } +{-# INLINE traceFireTcS #-} -- see Note [INLINE conditional tracing utilities] csTraceTcM :: TcM SDoc -> TcM () -- Constraint-solver tracing, -ddump-cs-trace @@ -2775,6 +2778,7 @@ csTraceTcM mk_doc (dumpOptionsFromFlag Opt_D_dump_cs_trace) "" FormatText msg }) } +{-# INLINE csTraceTcM #-} -- see Note [INLINE conditional tracing utilities] runTcS :: TcS a -- What to run -> TcM (a, EvBindMap) ===================================== compiler/GHC/Tc/Utils/Monad.hs ===================================== @@ -490,22 +490,28 @@ unsetWOptM flag = whenDOptM :: DumpFlag -> TcRnIf gbl lcl () -> TcRnIf gbl lcl () whenDOptM flag thing_inside = do b <- doptM flag when b thing_inside +{-# INLINE whenDOptM #-} -- see Note [INLINE conditional tracing utilities] + whenGOptM :: GeneralFlag -> TcRnIf gbl lcl () -> TcRnIf gbl lcl () whenGOptM flag thing_inside = do b <- goptM flag when b thing_inside +{-# INLINE whenGOptM #-} -- see Note [INLINE conditional tracing utilities] whenWOptM :: WarningFlag -> TcRnIf gbl lcl () -> TcRnIf gbl lcl () whenWOptM flag thing_inside = do b <- woptM flag when b thing_inside +{-# INLINE whenWOptM #-} -- see Note [INLINE conditional tracing utilities] whenXOptM :: LangExt.Extension -> TcRnIf gbl lcl () -> TcRnIf gbl lcl () whenXOptM flag thing_inside = do b <- xoptM flag when b thing_inside +{-# INLINE whenXOptM #-} -- see Note [INLINE conditional tracing utilities] unlessXOptM :: LangExt.Extension -> TcRnIf gbl lcl () -> TcRnIf gbl lcl () unlessXOptM flag thing_inside = do b <- xoptM flag unless b thing_inside +{-# INLINE unlessXOptM #-} -- see Note [INLINE conditional tracing utilities] getGhcMode :: TcRnIf gbl lcl GhcMode getGhcMode = do { env <- getTopEnv; return (ghcMode (hsc_dflags env)) } @@ -662,39 +668,64 @@ updTcRef ref fn = liftIO $ do { old <- readIORef ref ************************************************************************ -} +-- Note [INLINE conditional tracing utilities] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- In general we want to optimise for the case where tracing is not enabled. +-- To ensure this happens, we ensure that traceTc and friends are inlined; this +-- ensures that the allocation of the document can be pushed into the tracing +-- path, keeping the non-traced path free of this extraneous work. For +-- instance, instead of +-- +-- let thunk = ... +-- in if doTracing +-- then emitTraceMsg thunk +-- else return () +-- +-- where the conditional is buried in a non-inlined utility function (e.g. +-- traceTc), we would rather have: +-- +-- if doTracing +-- then let thunk = ... +-- in emitTraceMsg thunk +-- else return () +-- +-- See #18168. +-- -- Typechecker trace traceTc :: String -> SDoc -> TcRn () -traceTc = - labelledTraceOptTcRn Opt_D_dump_tc_trace +traceTc herald doc = + labelledTraceOptTcRn Opt_D_dump_tc_trace herald doc +{-# INLINE traceTc #-} -- see Note [INLINE conditional tracing utilities] -- Renamer Trace traceRn :: String -> SDoc -> TcRn () -traceRn = - labelledTraceOptTcRn Opt_D_dump_rn_trace +traceRn herald doc = + labelledTraceOptTcRn Opt_D_dump_rn_trace herald doc +{-# INLINE traceRn #-} -- see Note [INLINE conditional tracing utilities] -- | Trace when a certain flag is enabled. This is like `traceOptTcRn` -- but accepts a string as a label and formats the trace message uniformly. labelledTraceOptTcRn :: DumpFlag -> String -> SDoc -> TcRn () -labelledTraceOptTcRn flag herald doc = do - traceOptTcRn flag (formatTraceMsg herald doc) +labelledTraceOptTcRn flag herald doc = + traceOptTcRn flag (formatTraceMsg herald doc) +{-# INLINE labelledTraceOptTcRn #-} -- see Note [INLINE conditional tracing utilities] formatTraceMsg :: String -> SDoc -> SDoc formatTraceMsg herald doc = hang (text herald) 2 doc --- | Trace if the given 'DumpFlag' is set. traceOptTcRn :: DumpFlag -> SDoc -> TcRn () traceOptTcRn flag doc = do - dflags <- getDynFlags - when (dopt flag dflags) $ + whenDOptM flag $ dumpTcRn False (dumpOptionsFromFlag flag) "" FormatText doc +{-# INLINE traceOptTcRn #-} -- see Note [INLINE conditional tracing utilities] -- | Dump if the given 'DumpFlag' is set. dumpOptTcRn :: DumpFlag -> String -> DumpFormat -> SDoc -> TcRn () dumpOptTcRn flag title fmt doc = do - dflags <- getDynFlags - when (dopt flag dflags) $ + whenDOptM flag $ dumpTcRn False (dumpOptionsFromFlag flag) title fmt doc +{-# INLINE dumpOptTcRn #-} -- see Note [INLINE conditional tracing utilities] -- | Unconditionally dump some trace output -- @@ -746,13 +777,16 @@ e.g. are unaffected by -dump-to-file. traceIf, traceHiDiffs :: SDoc -> TcRnIf m n () traceIf = traceOptIf Opt_D_dump_if_trace traceHiDiffs = traceOptIf Opt_D_dump_hi_diffs - +{-# INLINE traceIf #-} +{-# INLINE traceHiDiffs #-} + -- see Note [INLINE conditional tracing utilities] traceOptIf :: DumpFlag -> SDoc -> TcRnIf m n () traceOptIf flag doc = whenDOptM flag $ -- No RdrEnv available, so qualify everything do { dflags <- getDynFlags ; liftIO (putMsg dflags doc) } +{-# INLINE traceOptIf #-} -- see Note [INLINE conditional tracing utilities] {- ************************************************************************ ===================================== compiler/GHC/Utils/Error.hs ===================================== @@ -438,20 +438,28 @@ doIfSet_dyn dflags flag action | gopt flag dflags = action dumpIfSet :: DynFlags -> Bool -> String -> SDoc -> IO () dumpIfSet dflags flag hdr doc | not flag = return () - | otherwise = putLogMsg dflags - NoReason - SevDump - noSrcSpan - (withPprStyle defaultDumpStyle - (mkDumpDoc hdr doc)) - --- | a wrapper around 'dumpAction'. + | otherwise = doDump dflags hdr doc +{-# INLINE dumpIfSet #-} -- see Note [INLINE conditional tracing utilities] + +-- | This is a helper for 'dumpIfSet' to ensure that it's not duplicated +-- despite the fact that 'dumpIfSet' has an @INLINE at . +doDump :: DynFlags -> String -> SDoc -> IO () +doDump dflags hdr doc = + putLogMsg dflags + NoReason + SevDump + noSrcSpan + (withPprStyle defaultDumpStyle + (mkDumpDoc hdr doc)) + +-- | A wrapper around 'dumpAction'. -- First check whether the dump flag is set -- Do nothing if it is unset dumpIfSet_dyn :: DynFlags -> DumpFlag -> String -> DumpFormat -> SDoc -> IO () dumpIfSet_dyn = dumpIfSet_dyn_printer alwaysQualify +{-# INLINE dumpIfSet_dyn #-} -- see Note [INLINE conditional tracing utilities] --- | a wrapper around 'dumpAction'. +-- | A wrapper around 'dumpAction'. -- First check whether the dump flag is set -- Do nothing if it is unset -- @@ -462,6 +470,7 @@ dumpIfSet_dyn_printer printer dflags flag hdr fmt doc = when (dopt flag dflags) $ do let sty = mkDumpStyle printer dumpAction dflags sty (dumpOptionsFromFlag flag) hdr fmt doc +{-# INLINE dumpIfSet_dyn_printer #-} -- see Note [INLINE conditional tracing utilities] mkDumpDoc :: String -> SDoc -> SDoc mkDumpDoc hdr doc @@ -608,6 +617,7 @@ ifVerbose :: DynFlags -> Int -> IO () -> IO () ifVerbose dflags val act | verbosity dflags >= val = act | otherwise = return () +{-# INLINE ifVerbose #-} -- see Note [INLINE conditional tracing utilities] errorMsg :: DynFlags -> MsgDoc -> IO () errorMsg dflags msg @@ -778,6 +788,7 @@ debugTraceMsg :: DynFlags -> Int -> MsgDoc -> IO () debugTraceMsg dflags val msg = ifVerbose dflags val $ logInfo dflags (withPprStyle defaultDumpStyle msg) +{-# INLINE debugTraceMsg #-} -- see Note [INLINE conditional tracing utilities] putMsg :: DynFlags -> MsgDoc -> IO () putMsg dflags msg = logInfo dflags (withPprStyle defaultUserStyle msg) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a0b49468a7a486d7afaa7422ad68e0cffdd40c0a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a0b49468a7a486d7afaa7422ad68e0cffdd40c0a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 11 17:36:47 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 11 May 2020 13:36:47 -0400 Subject: [Git][ghc/ghc][wip/runRW] 78 commits: Switch order on `GhcMake.IsBoot` Message-ID: <5eb98d2f813dd_6167119ebbd0106565f8@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/runRW at Glasgow Haskell Compiler / GHC Commits: b0fbfc75 by John Ericson at 2020-04-24T12:07:14-04:00 Switch order on `GhcMake.IsBoot` In !1798 we were requested to replace many `Bool`s with this data type. But those bools had `False` meaning `NotBoot`, so the `Ord` instance would be flipped if we use this data-type as-is. Since the planned formally-`Bool` occurrences vastly outnumber the current occurrences, we figured it would be better to conform the `Ord` instance to how the `Bool` is used now, fixing any issues, rather than fix them currently with the bigger refactor later in !1798. That way, !1798 can be a "pure" refactor with no behavioral changes. - - - - - af332442 by Sylvain Henry at 2020-04-26T13:55:14-04:00 Modules: Utils and Data (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - cd4434c8 by Sylvain Henry at 2020-04-26T13:55:16-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 22bf5c73 by Ömer Sinan Ağacan at 2020-04-26T13:55:22-04:00 Tweak includes in non-moving GC headers We don't use hash tables in non-moving GC so remove the includes. This breaks Compact.c as existing includes no longer include Hash.h, so include Hash.h explicitly in Compact.c. - - - - - 99823ed2 by Sylvain Henry at 2020-04-27T20:24:46-04:00 TH: fix Show/Eq/Ord instances for Bytes (#16457) We shouldn't compare pointer values but the actual bytes. - - - - - c62271a2 by Alp Mestanogullari at 2020-04-27T20:25:33-04:00 hadrian: always capture both stdout and stderr when running a builder fails The idea being that when a builder('s command) fails, we quite likely want to have all the information available to figure out why. Depending on the builder _and_ the particular problem, the useful bits of information can be printed on stdout or stderr. We accomplish this by defining a simple wrapper for Shake's `cmd` function, that just _always_ captures both streams in case the command returns a non-zero exit code, and by using this wrapper everywhere in `hadrian/src/Builder.hs`. Fixes #18089. - - - - - 4b9764db by Ryan Scott at 2020-04-28T15:40:04-04:00 Define a Quote IO instance Fixes #18103. - - - - - 518a63d4 by Ryan Scott at 2020-04-28T15:40:42-04:00 Make boxed 1-tuples have known keys Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. - - - - - 2cfc4ab9 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Document backpack fields in DynFlags - - - - - 10a2ba90 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 69562e34 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 9e2c8e0e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - ea717aa4 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 10d15f1e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 8bfb0219 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - 71484b09 by Alexis King at 2020-04-30T01:57:35-04:00 Allow block arguments in arrow control operators Arrow control operators have their own entries in the grammar, so they did not cooperate with BlockArguments. This was just a minor oversight, so this patch adjusts the grammar to add the desired behavior. fixes #18050 - - - - - a48cd2a0 by Alexis King at 2020-04-30T01:57:35-04:00 Allow LambdaCase to be used as a command in proc notation - - - - - f4d3773c by Alexis King at 2020-04-30T01:57:35-04:00 Document BlockArguments/LambdaCase support in arrow notation - - - - - 5bdfdd13 by Simon Peyton Jones at 2020-04-30T01:58:15-04:00 Add tests for #17873 - - - - - 19b701c2 by Simon Peyton Jones at 2020-04-30T07:30:13-04:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - 014ef4a3 by Matthew Pickering at 2020-04-30T07:30:50-04:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 2aa67611 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - 54dad3cf by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - 99ff8145 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 05b0a9fd by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 Remove OneShotInfo field of LFReEntrant, document OneShotInfo The field is only used in withNewTickyCounterFun and it's easier to directly pass a parameter for one-shot info to withNewTickyCounterFun instead of passing it via LFReEntrant. This also makes !2842 simpler. Other changes: - New Note (by SPJ) [OneShotInfo overview] added. - Arity argument of thunkCode removed as it's always 0. - - - - - a43620c6 by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 GHC.StgToCmm.Ticky: remove a few unused stuff - - - - - 780de9e1 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Use platform in Iface Binary - - - - - f8386c7b by Sylvain Henry at 2020-05-01T10:37:39-04:00 Refactor PprDebug handling If `-dppr-debug` is set, then PprUser and PprDump styles are silently replaced with PprDebug style. This was done in `mkUserStyle` and `mkDumpStyle` smart constructors. As a consequence they needed a DynFlags parameter. Now we keep the original PprUser and PprDump styles until they are used to create an `SDocContext`. I.e. the substitution is only performed in `initSDocContext`. - - - - - b3df9e78 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Remove PprStyle param of logging actions Use `withPprStyle` instead to apply a specific style to a SDoc. - - - - - de9fc995 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Fully remove PprDebug PprDebug was a pain to deal with consistently as it is implied by `-dppr-debug` but it isn't really a PprStyle. We remove it completely and query the appropriate SDoc flag instead (`sdocPprDebug`) via helpers (`getPprDebug` and its friends). - - - - - 8b51fcbd by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Only call checkSingle if we would report warnings - - - - - fd7ea0fe by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 7bfe9ac5 by Ben Gamari at 2020-05-03T04:41:33-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. - - - - - c560dd07 by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Move eventlog documentation users guide - - - - - 02543d5e by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Add documentation for non-moving GC events - - - - - b465dd45 by Alexis King at 2020-05-03T04:42:12-04:00 Flatten nested casts in the simple optimizer Normally, we aren’t supposed to generated any nested casts, since mkCast takes care to flatten them, but the simple optimizer didn’t use mkCast, so they could show up after inlining. This isn’t really a problem, since the simplifier will clean them up immediately anyway, but it can clutter the -ddump-ds output, and it’s an extremely easy fix. closes #18112 - - - - - 8bdc03d6 by Simon Peyton Jones at 2020-05-04T01:56:59-04:00 Don't return a panic in tcNestedSplice In GHC.Tc.Gen.Splice.tcNestedSplice we were returning a typechecked expression of "panic". That is usually OK, because the result is discarded. But it happens that tcApp now looks at the typechecked expression, trivially, to ask if it is tagToEnum. So being bottom is bad. Moreover a debug-trace might print it out. So better to return a civilised expression, even though it is usually discarded. - - - - - 0bf640b1 by Baldur Blöndal at 2020-05-04T01:57:36-04:00 Don't require parentheses around via type (`-XDerivingVia'). Fixes #18130". - - - - - 30272412 by Artem Pelenitsyn at 2020-05-04T13:19:59-04:00 Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) - - - - - b9f7c08f by jneira at 2020-05-04T13:20:37-04:00 Remove unused hs-boot file - - - - - 1d8f80cd by Sylvain Henry at 2020-05-05T03:22:46-04:00 Remove references to -package-key * remove references to `-package-key` which has been removed in 2016 (240ddd7c39536776e955e881d709bbb039b48513) * remove support for `-this-package-key` which has been deprecated at the same time - - - - - 7bc3a65b by Sylvain Henry at 2020-05-05T03:23:31-04:00 Remove SpecConstrAnnotation (#13681) This has been deprecated since 2013. Use GHC.Types.SPEC instead. Make GHC.Exts "not-home" for haddock Metric Decrease: haddock.base - - - - - 3c862f63 by DenisFrezzato at 2020-05-05T03:24:15-04:00 Fix Haskell98 short description in documentation - - - - - 2420c555 by Ryan Scott at 2020-05-05T03:24:53-04:00 Add regression tests for #16244, #16245, #16758 Commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70 ended up fixing quite a few bugs: * This commit fixes #16244 completely. A regression test has been added. * This commit fixes one program from #16245. (The program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211369 still panics, and the program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211400 still loops infinitely.) A regression test has been added for this program. * This commit fixes #16758. Accordingly, this patch removes the `expect_broken` label from the `T16758` test case, moves it from `should_compile` to `should_fail` (as it should produce an error message), and checks in the expected stderr. - - - - - 40c71c2c by Sylvain Henry at 2020-05-05T03:25:31-04:00 Fix colorized error messages (#18128) In b3df9e780fb2f5658412c644849cd0f1e6f50331 I broke colorized messages by using "dump" style instead of "user" style. This commits fixes it. - - - - - 7ab6ab09 by Richard Eisenberg at 2020-05-06T04:39:32-04:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG ------------------------- - - - - - 420b957d by Ben Gamari at 2020-05-06T04:40:08-04:00 rts: Zero block flags with -DZ Block flags are very useful for determining the state of a block. However, some block allocator users don't touch them, leading to misleading values. Ensure that we zero then when zero-on-gc is set. This is safe and makes the flags more useful during debugging. - - - - - 740b3b8d by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix incorrect failed_to_evac value during deadlock gc Previously we would incorrectly set the failed_to_evac flag if we evacuated a value due to a deadlock GC. This would cause us to mark more things as dirty than strictly necessary. It also turned up a nasty but which I will fix next. - - - - - b2d72c75 by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - 9f3e6884 by Zubin Duggal at 2020-05-06T04:41:08-04:00 Allow atomic update of NameCache in readHieFile The situation arises in ghcide where multiple different threads may need to update the name cache, therefore with the older interface it could happen that you start reading a hie file with name cache A and produce name cache A + B, but another thread in the meantime updated the namecache to A + C. Therefore if you write the new namecache you will lose the A' updates from the second thread. Updates haddock submodule - - - - - edec6a6c by Ryan Scott at 2020-05-06T04:41:57-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _)`. Fixes #18127. - - - - - a95e7fe0 by Ömer Sinan Ağacan at 2020-05-06T04:42:39-04:00 ELF linker: increment curSymbol after filling in fields of current entry The bug was introduced in a8b7cef4d45 which added a field to the `symbols` array elements and then updated this code incorrectly: - oc->symbols[curSymbol++] = nm; + oc->symbols[curSymbol++].name = nm; + oc->symbols[curSymbol].addr = symbol->addr; - - - - - cab1871a by Sylvain Henry at 2020-05-06T04:43:21-04:00 Move LeadingUnderscore into Platform (#17957) Avoid direct use of DynFlags to know if symbols must be prefixed by an underscore. - - - - - 94e7c563 by Sylvain Henry at 2020-05-06T04:43:21-04:00 Don't use DynFlags in showLinkerState (#17957) - - - - - 9afd9251 by Ryan Scott at 2020-05-06T04:43:58-04:00 Refactoring: Use bindSigTyVarsFV in rnMethodBinds `rnMethodBinds` was explicitly using `xoptM` to determine if `ScopedTypeVariables` is enabled before bringing type variables bound by the class/instance header into scope. However, this `xoptM` logic is already performed by the `bindSigTyVarsFV` function. This patch uses `bindSigTyVarsFV` in `rnMethodBinds` to reduce the number of places where we need to consult if `ScopedTypeVariables` is on. This is purely refactoring, and there should be no user-visible change in behavior. - - - - - 6f6d72b2 by Brian Foley at 2020-05-08T15:29:25-04:00 Remove further dead code found by a simple Python script. Avoid removing some functions that are part of an API even though they're not used in-tree at the moment. - - - - - 78bf8bf9 by Julien Debon at 2020-05-08T15:29:28-04:00 Add doc examples for Bifoldable See #17929 - - - - - 66f0a847 by Julien Debon at 2020-05-08T15:29:29-04:00 doc (Bitraversable): Add examples to Bitraversable * Add examples to Data.Bitraversable * Fix formatting for (,) in Bitraversable and Bifoldable * Fix mistake on bimapAccumR documentation See #17929 - - - - - 9749fe12 by Baldur Blöndal at 2020-05-08T15:29:32-04:00 Specify kind variables for inferred kinds in base. - - - - - 4e9aef9e by John Ericson at 2020-05-08T15:29:36-04:00 HsSigWcTypeScoping: Pull in documentation from stray location - - - - - f4d5c6df by John Ericson at 2020-05-08T15:29:36-04:00 Rename local `real_fvs` to `implicit_vs` It doesn't make sense to call the "free" variables we are about to implicitly bind the real ones. - - - - - 20570b4b by John Ericson at 2020-05-08T15:29:36-04:00 A few tiny style nits with renaming - Use case rather than guards that repeatedly scrutenize same thing. - No need for view pattern when `L` is fine. - Use type synnonym to convey the intent like elsewhere. - - - - - 09ac8de5 by John Ericson at 2020-05-08T15:29:36-04:00 Add `forAllOrNothing` function with note - - - - - bb35c0e5 by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Document lawlessness of Ap's Num instance - - - - - cdd229ff by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply suggestion to libraries/base/Data/Monoid.hs - - - - - 926d2aab by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply more suggestions from Simon Jakobi - - - - - 7a763cff by Adam Gundry at 2020-05-08T15:29:41-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. - - - - - 88e3c815 by Simon Peyton Jones at 2020-05-08T15:29:41-04:00 Fix specialisation for DFuns When specialising a DFun we must take care to saturate the unfolding. See Note [Specialising DFuns] in Specialise. Fixes #18120 - - - - - 86c77b36 by Greg Steuck at 2020-05-08T15:29:45-04:00 Remove unused SEGMENT_PROT_RWX It's been unused for a year and is problematic on any OS which requires W^X for security. - - - - - 9d97f4b5 by nineonine at 2020-05-08T15:30:03-04:00 Add test for #16167 - - - - - aa318338 by Ryan Scott at 2020-05-08T15:30:04-04:00 Bump exceptions submodule so that dist-boot is .gitignore'd `exceptions` is a stage-0 boot library as of commit 30272412fa437ab8e7a8035db94a278e10513413, which means that building `exceptions` in a GHC tree will generate a `dist-boot` directory. However, this directory was not specified in `exceptions`' `.gitignore` file, which causes it to dirty up the current `git` working directory. Accordingly, this bumps the `exceptions` submodule to commit ghc/packages/exceptions at 23c0b8a50d7592af37ca09beeec16b93080df98f, which adds `dist-boot` to the `.gitignore` file. - - - - - ea86360f by Ömer Sinan Ağacan at 2020-05-08T15:30:30-04:00 Linker.c: initialize n_symbols of ObjectCode with other fields - - - - - 951c1fb0 by Sylvain Henry at 2020-05-09T21:46:38-04:00 Fix unboxed-sums GC ptr-slot rubbish value (#17791) This patch allows boot libraries to use unboxed sums without implicitly depending on `base` package because of `absentSumFieldError`. See updated Note [aBSENT_SUM_FIELD_ERROR_ID] in GHC.Core.Make - - - - - b352d63c by Ben Gamari at 2020-05-09T21:47:14-04:00 rts: Make non-existent linker search path merely a warning As noted in #18105, previously this resulted in a rather intrusive error message. This is in contrast to the general expectation that search paths are merely places to look, not places that must exist. Fixes #18105. - - - - - e8c7e2aa by Ben Gamari at 2020-05-11T13:32:58-04:00 CoreToStg: Add Outputable ArgInfo instance - - - - - f8bcce5d by Simon Peyton Jones at 2020-05-11T13:32:58-04:00 Make Lint check return type of a join point Consider join x = rhs in body It's important that the type of 'rhs' is the same as the type of 'body', but Lint wasn't checking that invariant. Now it does! This was exposed by investigation into !3113. - - - - - dde75f8b by Simon Peyton Jones at 2020-05-11T13:32:58-04:00 Do not float join points in exprIsConApp_maybe We hvae been making exprIsConApp_maybe cleverer in recent times: commit b78cc64e923716ac0512c299f42d4d0012306c05 Date: Thu Nov 15 17:14:31 2018 +0100 Make constructor wrappers inline only during the final phase commit 7833cf407d1f608bebb1d38bb99d3035d8d735e6 Date: Thu Jan 24 17:58:50 2019 +0100 Look through newtype wrappers (Trac #16254) commit c25b135ff5b9c69a90df0ccf51b04952c2dc6ee1 Date: Thu Feb 21 12:03:22 2019 +0000 Fix exprIsConApp_maybe But alas there was still a bug, now immortalised in Note [Don't float join points] in SimpleOpt. It's quite hard to trigger because it requires a dead join point, but it came up when compiling Cabal Cabal.Distribution.Fields.Lexer.hs, when working on !3113. Happily, the fix is extremly easy. Finding the bug was not so easy. - - - - - 0f2f1060 by Ben Gamari at 2020-05-11T13:35:31-04:00 Allow simplification through runRW# Because runRW# inlines so late, we were previously able to do very little simplification across it. For instance, given even a simple program like case runRW# (\s -> let n = I# 42# in n) of I# n# -> f n# we previously had no way to avoid the allocation of the I#. This patch allows the simplifier to push strict contexts into the continuation of a runRW# application, as explained in in Note [Simplification of runRW#] in GHC.CoreToStg.Prep. Fixes #15127. Metric Increase: T9961 Co-Authored-By: Simon Peyton-Jone <simonpj at microsoft.com> - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/PrimOps.hs-boot - 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/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/ByteCode/Asm.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/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Block.hs - compiler/GHC/Cmm/Dataflow/Collections.hs - compiler/GHC/Cmm/Dataflow/Graph.hs - compiler/GHC/Cmm/Dataflow/Label.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Expr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8d548e8304ea7d8f3955681597be0c655ab6fb2d...0f2f1060a5d13b0fcfb1226ec8ca44643f1eb205 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8d548e8304ea7d8f3955681597be0c655ab6fb2d...0f2f1060a5d13b0fcfb1226ec8ca44643f1eb205 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 11 17:45:26 2020 From: gitlab at gitlab.haskell.org (Sven Tennie) Date: Mon, 11 May 2020 13:45:26 -0400 Subject: [Git][ghc/ghc][wip/ghc-debug] Fix lint Message-ID: <5eb98f3616632_61673f81a3bd711c106618e8@gitlab.haskell.org.mail> Sven Tennie pushed to branch wip/ghc-debug at Glasgow Haskell Compiler / GHC Commits: 65567212 by Sven Tennie at 2020-05-11T19:45:09+02:00 Fix lint - - - - - 1 changed file: - libraries/ghc-heap/GHC/Exts/Heap/FFIClosures.hsc Changes: ===================================== libraries/ghc-heap/GHC/Exts/Heap/FFIClosures.hsc ===================================== @@ -4,17 +4,10 @@ module GHC.Exts.Heap.FFIClosures where import Prelude import Foreign -import Foreign.Ptr -import Data.Int - -import GHC.Exts.Heap.Closures peekStgThreadID :: Ptr a -> IO Word64 -peekStgThreadID ptr = do - id <- (#peek struct StgTSO_, id) ptr - return id +peekStgThreadID ptr = (#peek struct StgTSO_, id) ptr + peekAllocLimit :: Ptr a -> IO Int64 -peekAllocLimit ptr = do - alloc_limit <- (#peek struct StgTSO_, alloc_limit) ptr - return alloc_limit +peekAllocLimit ptr = (#peek struct StgTSO_, alloc_limit) ptr View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/65567212a3d9c5471a5f05076519c58a4fcfabdd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/65567212a3d9c5471a5f05076519c58a4fcfabdd You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 11 17:54:03 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Mon, 11 May 2020 13:54:03 -0400 Subject: [Git][ghc/ghc][wip/nested-cpr-2019] 61 commits: Don't return a panic in tcNestedSplice Message-ID: <5eb9913bc94f_616711922e9c10674477@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/nested-cpr-2019 at Glasgow Haskell Compiler / GHC Commits: 8bdc03d6 by Simon Peyton Jones at 2020-05-04T01:56:59-04:00 Don't return a panic in tcNestedSplice In GHC.Tc.Gen.Splice.tcNestedSplice we were returning a typechecked expression of "panic". That is usually OK, because the result is discarded. But it happens that tcApp now looks at the typechecked expression, trivially, to ask if it is tagToEnum. So being bottom is bad. Moreover a debug-trace might print it out. So better to return a civilised expression, even though it is usually discarded. - - - - - 0bf640b1 by Baldur Blöndal at 2020-05-04T01:57:36-04:00 Don't require parentheses around via type (`-XDerivingVia'). Fixes #18130". - - - - - 30272412 by Artem Pelenitsyn at 2020-05-04T13:19:59-04:00 Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) - - - - - b9f7c08f by jneira at 2020-05-04T13:20:37-04:00 Remove unused hs-boot file - - - - - 1d8f80cd by Sylvain Henry at 2020-05-05T03:22:46-04:00 Remove references to -package-key * remove references to `-package-key` which has been removed in 2016 (240ddd7c39536776e955e881d709bbb039b48513) * remove support for `-this-package-key` which has been deprecated at the same time - - - - - 7bc3a65b by Sylvain Henry at 2020-05-05T03:23:31-04:00 Remove SpecConstrAnnotation (#13681) This has been deprecated since 2013. Use GHC.Types.SPEC instead. Make GHC.Exts "not-home" for haddock Metric Decrease: haddock.base - - - - - 3c862f63 by DenisFrezzato at 2020-05-05T03:24:15-04:00 Fix Haskell98 short description in documentation - - - - - 2420c555 by Ryan Scott at 2020-05-05T03:24:53-04:00 Add regression tests for #16244, #16245, #16758 Commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70 ended up fixing quite a few bugs: * This commit fixes #16244 completely. A regression test has been added. * This commit fixes one program from #16245. (The program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211369 still panics, and the program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211400 still loops infinitely.) A regression test has been added for this program. * This commit fixes #16758. Accordingly, this patch removes the `expect_broken` label from the `T16758` test case, moves it from `should_compile` to `should_fail` (as it should produce an error message), and checks in the expected stderr. - - - - - 40c71c2c by Sylvain Henry at 2020-05-05T03:25:31-04:00 Fix colorized error messages (#18128) In b3df9e780fb2f5658412c644849cd0f1e6f50331 I broke colorized messages by using "dump" style instead of "user" style. This commits fixes it. - - - - - 7ab6ab09 by Richard Eisenberg at 2020-05-06T04:39:32-04:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG ------------------------- - - - - - 420b957d by Ben Gamari at 2020-05-06T04:40:08-04:00 rts: Zero block flags with -DZ Block flags are very useful for determining the state of a block. However, some block allocator users don't touch them, leading to misleading values. Ensure that we zero then when zero-on-gc is set. This is safe and makes the flags more useful during debugging. - - - - - 740b3b8d by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix incorrect failed_to_evac value during deadlock gc Previously we would incorrectly set the failed_to_evac flag if we evacuated a value due to a deadlock GC. This would cause us to mark more things as dirty than strictly necessary. It also turned up a nasty but which I will fix next. - - - - - b2d72c75 by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - 9f3e6884 by Zubin Duggal at 2020-05-06T04:41:08-04:00 Allow atomic update of NameCache in readHieFile The situation arises in ghcide where multiple different threads may need to update the name cache, therefore with the older interface it could happen that you start reading a hie file with name cache A and produce name cache A + B, but another thread in the meantime updated the namecache to A + C. Therefore if you write the new namecache you will lose the A' updates from the second thread. Updates haddock submodule - - - - - edec6a6c by Ryan Scott at 2020-05-06T04:41:57-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _)`. Fixes #18127. - - - - - a95e7fe0 by Ömer Sinan Ağacan at 2020-05-06T04:42:39-04:00 ELF linker: increment curSymbol after filling in fields of current entry The bug was introduced in a8b7cef4d45 which added a field to the `symbols` array elements and then updated this code incorrectly: - oc->symbols[curSymbol++] = nm; + oc->symbols[curSymbol++].name = nm; + oc->symbols[curSymbol].addr = symbol->addr; - - - - - cab1871a by Sylvain Henry at 2020-05-06T04:43:21-04:00 Move LeadingUnderscore into Platform (#17957) Avoid direct use of DynFlags to know if symbols must be prefixed by an underscore. - - - - - 94e7c563 by Sylvain Henry at 2020-05-06T04:43:21-04:00 Don't use DynFlags in showLinkerState (#17957) - - - - - 9afd9251 by Ryan Scott at 2020-05-06T04:43:58-04:00 Refactoring: Use bindSigTyVarsFV in rnMethodBinds `rnMethodBinds` was explicitly using `xoptM` to determine if `ScopedTypeVariables` is enabled before bringing type variables bound by the class/instance header into scope. However, this `xoptM` logic is already performed by the `bindSigTyVarsFV` function. This patch uses `bindSigTyVarsFV` in `rnMethodBinds` to reduce the number of places where we need to consult if `ScopedTypeVariables` is on. This is purely refactoring, and there should be no user-visible change in behavior. - - - - - 6f6d72b2 by Brian Foley at 2020-05-08T15:29:25-04:00 Remove further dead code found by a simple Python script. Avoid removing some functions that are part of an API even though they're not used in-tree at the moment. - - - - - 78bf8bf9 by Julien Debon at 2020-05-08T15:29:28-04:00 Add doc examples for Bifoldable See #17929 - - - - - 66f0a847 by Julien Debon at 2020-05-08T15:29:29-04:00 doc (Bitraversable): Add examples to Bitraversable * Add examples to Data.Bitraversable * Fix formatting for (,) in Bitraversable and Bifoldable * Fix mistake on bimapAccumR documentation See #17929 - - - - - 9749fe12 by Baldur Blöndal at 2020-05-08T15:29:32-04:00 Specify kind variables for inferred kinds in base. - - - - - 4e9aef9e by John Ericson at 2020-05-08T15:29:36-04:00 HsSigWcTypeScoping: Pull in documentation from stray location - - - - - f4d5c6df by John Ericson at 2020-05-08T15:29:36-04:00 Rename local `real_fvs` to `implicit_vs` It doesn't make sense to call the "free" variables we are about to implicitly bind the real ones. - - - - - 20570b4b by John Ericson at 2020-05-08T15:29:36-04:00 A few tiny style nits with renaming - Use case rather than guards that repeatedly scrutenize same thing. - No need for view pattern when `L` is fine. - Use type synnonym to convey the intent like elsewhere. - - - - - 09ac8de5 by John Ericson at 2020-05-08T15:29:36-04:00 Add `forAllOrNothing` function with note - - - - - bb35c0e5 by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Document lawlessness of Ap's Num instance - - - - - cdd229ff by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply suggestion to libraries/base/Data/Monoid.hs - - - - - 926d2aab by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply more suggestions from Simon Jakobi - - - - - 7a763cff by Adam Gundry at 2020-05-08T15:29:41-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. - - - - - 88e3c815 by Simon Peyton Jones at 2020-05-08T15:29:41-04:00 Fix specialisation for DFuns When specialising a DFun we must take care to saturate the unfolding. See Note [Specialising DFuns] in Specialise. Fixes #18120 - - - - - 86c77b36 by Greg Steuck at 2020-05-08T15:29:45-04:00 Remove unused SEGMENT_PROT_RWX It's been unused for a year and is problematic on any OS which requires W^X for security. - - - - - 9d97f4b5 by nineonine at 2020-05-08T15:30:03-04:00 Add test for #16167 - - - - - aa318338 by Ryan Scott at 2020-05-08T15:30:04-04:00 Bump exceptions submodule so that dist-boot is .gitignore'd `exceptions` is a stage-0 boot library as of commit 30272412fa437ab8e7a8035db94a278e10513413, which means that building `exceptions` in a GHC tree will generate a `dist-boot` directory. However, this directory was not specified in `exceptions`' `.gitignore` file, which causes it to dirty up the current `git` working directory. Accordingly, this bumps the `exceptions` submodule to commit ghc/packages/exceptions at 23c0b8a50d7592af37ca09beeec16b93080df98f, which adds `dist-boot` to the `.gitignore` file. - - - - - ea86360f by Ömer Sinan Ağacan at 2020-05-08T15:30:30-04:00 Linker.c: initialize n_symbols of ObjectCode with other fields - - - - - 951c1fb0 by Sylvain Henry at 2020-05-09T21:46:38-04:00 Fix unboxed-sums GC ptr-slot rubbish value (#17791) This patch allows boot libraries to use unboxed sums without implicitly depending on `base` package because of `absentSumFieldError`. See updated Note [aBSENT_SUM_FIELD_ERROR_ID] in GHC.Core.Make - - - - - b352d63c by Ben Gamari at 2020-05-09T21:47:14-04:00 rts: Make non-existent linker search path merely a warning As noted in #18105, previously this resulted in a rather intrusive error message. This is in contrast to the general expectation that search paths are merely places to look, not places that must exist. Fixes #18105. - - - - - 6bb3d743 by Sebastian Graf at 2020-05-11T18:29:37+02:00 Nested CPR - - - - - 6693487f by Sebastian Graf at 2020-05-11T18:29:37+02:00 Move tests from stranal to cpranal - - - - - cff2cf58 by Sebastian Graf at 2020-05-11T18:29:37+02:00 Accept FacState - - - - - 504b3963 by Sebastian Graf at 2020-05-11T18:29:37+02:00 Factor Cpr and Termination into a joint lattice As a result, we don't even have to export Termination from Cpr. Neat! Also I realised there is a simpler and more sound way to generate and unleash CPR signatures. - - - - - 6628835a by Sebastian Graf at 2020-05-11T18:29:37+02:00 Consider unboxing effects of WW better and get rid of hack - - - - - 442932e1 by Sebastian Graf at 2020-05-11T18:29:37+02:00 stuff - - - - - 7d8dc710 by Sebastian Graf at 2020-05-11T18:29:37+02:00 Debug output - - - - - 7dc0a59c by Sebastian Graf at 2020-05-11T18:29:37+02:00 A slew of testsuite changes - - - - - f88112d5 by Sebastian Graf at 2020-05-11T18:29:38+02:00 Fix T1600 - - - - - 5979ad8e by Sebastian Graf at 2020-05-11T18:29:38+02:00 Inline `decodeDoubleInteger` and constant-fold `decodeDouble_Int64#` instead Currently, `decodeDoubleInteger` is known-key so that it can be recognised in constant folding. But that is very brittle and doesn't survive worker/wrapper, which we even do for `NOINLINE`/`CONSTANT_FOLDED` things since #13143. Also it is a trade-off: The implementation of `decodeDoubleInteger` allocates an `Integer` box that never cancels aways if we don't inline it. Hence we recognise the `decodeDouble_Int64#` primop instead in constant folding, so that we can inline `decodeDoubleInteger`. You may wonder how this affects performance of code using `integer-simple`; Apparently, according to @hsyl20 this is not a concern since we will hopefully land !2231 soon. Fixes #18092. - - - - - b0d0af47 by Sebastian Graf at 2020-05-11T18:29:38+02:00 Fix primop termination - - - - - aa64acdc by Sebastian Graf at 2020-05-11T18:29:38+02:00 Test for DataCon wrapper CPR - - - - - 679a90bd by Sebastian Graf at 2020-05-11T18:29:38+02:00 Fix CPR of bottoming functions/primops - - - - - a1428068 by Sebastian Graf at 2020-05-11T18:29:38+02:00 Fix DataConWrapperCpr and accept other test outputs - - - - - 7815c1a9 by Sebastian Graf at 2020-05-11T18:29:38+02:00 Accept two more changed test outputs - - - - - 231205ea by Sebastian Graf at 2020-05-11T18:29:38+02:00 Update CaseBinderCPR with a new function - - - - - e0208eed by Sebastian Graf at 2020-05-11T18:29:38+02:00 Don't give the case binder the CPR property - - - - - 27c2e9ef by Sebastian Graf at 2020-05-11T18:29:38+02:00 Prune CPR sigs to constant depth on all bindings - - - - - e20f97eb by Sebastian Graf at 2020-05-11T18:29:38+02:00 Use variable length coding for ConTags - - - - - 73a270b9 by Sebastian Graf at 2020-05-11T18:29:38+02:00 Accept testuite output - - - - - 360fd117 by Sebastian Graf at 2020-05-11T18:29:38+02:00 Don't attach CPR sigs to expandable bindings; transform their unfoldings instead - - - - - 16cbed0f by Sebastian Graf at 2020-05-11T18:29:38+02:00 Revert "Don't give the case binder the CPR property" This reverts commit 910edd76d5fe68b58c74f3805112f9faef4f2788. It seems we broke too much with this change. We lost our big win in `fish`. - - - - - f0d83bab by Sebastian Graf at 2020-05-11T19:53:54+02:00 A more modular and configurable approach to optimistic case binder CPR - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/PPC/Cond.hs - compiler/GHC/CmmToAsm/SPARC/Cond.hs - compiler/GHC/CmmToAsm/X86/Cond.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/IOEnv.hs - compiler/GHC/Data/Maybe.hs - compiler/GHC/Driver/Finder.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/Monad.hs - compiler/GHC/Driver/Pipeline.hs - compiler/GHC/Driver/Session.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c015b648580edf071e10dd197fda5727dca66750...f0d83bab1f471fb9f0b8ff8cd1aa75ec6c6a4a20 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c015b648580edf071e10dd197fda5727dca66750...f0d83bab1f471fb9f0b8ff8cd1aa75ec6c6a4a20 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 11 18:20:11 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 11 May 2020 14:20:11 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T17926 Message-ID: <5eb9975b5f4e9_6167119f8560106835b7@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/T17926 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T17926 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 11 22:06:46 2020 From: gitlab at gitlab.haskell.org (Vilem-Benjamin Liepelt) Date: Mon, 11 May 2020 18:06:46 -0400 Subject: [Git][ghc/ghc][wip/buggymcbugfix/15185-enum-int] 2 commits: Fix spelling mistakes and typos Message-ID: <5eb9cc763a4b1_616711a31edc106989de@gitlab.haskell.org.mail> Vilem-Benjamin Liepelt pushed to branch wip/buggymcbugfix/15185-enum-int at Glasgow Haskell Compiler / GHC Commits: 0214db8f by Vilem Liepelt at 2020-05-12T00:59:28+03:00 Fix spelling mistakes and typos - - - - - 9cbab25f by Vilem Liepelt at 2020-05-12T01:06:00+03:00 Add inline pragmas to Enum methods - - - - - 3 changed files: - docs/users_guide/debugging.rst - libraries/base/GHC/Enum.hs - libraries/base/GHC/List.hs Changes: ===================================== docs/users_guide/debugging.rst ===================================== @@ -301,7 +301,7 @@ subexpression elimination pass. Rules are filtered by the user provided string, a rule is kept if a prefix of its name matches the string. The pass then checks whether any of these rules could apply to - the program but which didn't file for some reason. For example, specifying + the program but which didn't fire for some reason. For example, specifying ``-drule-check=SPEC`` will check whether there are any applications which might be subject to a rule created by specialisation. ===================================== libraries/base/GHC/Enum.hs ===================================== @@ -139,11 +139,22 @@ class Enum a where -- * @enumFromThenTo 6 8 2 :: [Int] = []@ enumFromThenTo :: a -> a -> a -> [a] - succ = toEnum . (+ 1) . fromEnum - pred = toEnum . (subtract 1) . fromEnum - enumFrom x = map toEnum [fromEnum x ..] - enumFromThen x y = map toEnum [fromEnum x, fromEnum y ..] - enumFromTo x y = map toEnum [fromEnum x .. fromEnum y] + {-# INLINE succ #-} + succ = toEnum . (+ 1) . fromEnum + + {-# INLINE pred #-} + pred = toEnum . (subtract 1) . fromEnum + + {-# INLINE enumFrom #-} + enumFrom x = map toEnum [fromEnum x ..] + + {-# INLINE enumFromThen #-} + enumFromThen x y = map toEnum [fromEnum x, fromEnum y ..] + + {-# INLINE enumFromTo #-} + enumFromTo x y = map toEnum [fromEnum x .. fromEnum y] + + {-# INLINE enumFromThenTo #-} enumFromThenTo x1 x2 y = map toEnum [fromEnum x1, fromEnum x2 .. fromEnum y] -- Default methods for bounded enumerations ===================================== libraries/base/GHC/List.hs ===================================== @@ -277,10 +277,10 @@ to list-producing functions abstracted over cons and nil. Here we call them FB functions because their names usually end with 'FB'. It's a good idea to inline FB functions because: -* They are higher-order functions and therefore benefits from inlining. +* They are higher-order functions and therefore benefit from inlining. * When the final consumer is a left fold, inlining the FB functions is the only - way to make arity expansion to happen. See Note [Left fold via right fold]. + way to make arity expansion happen. See Note [Left fold via right fold]. For this reason we mark all FB functions INLINE [0]. The [0] phase-specifier ensures that calls to FB functions can be written back to the original form View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e8029816fda7602a8163c4d2703ff02982a3e48c...9cbab25f196232e5b30395b5c07d6f27229162ea -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e8029816fda7602a8163c4d2703ff02982a3e48c...9cbab25f196232e5b30395b5c07d6f27229162ea You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 11 22:13:26 2020 From: gitlab at gitlab.haskell.org (Vilem-Benjamin Liepelt) Date: Mon, 11 May 2020 18:13:26 -0400 Subject: [Git][ghc/ghc][wip/buggymcbugfix/15185-enum-int] Add inline pragmas to Enum methods Message-ID: <5eb9ce06d948b_61673f819aad978c10699182@gitlab.haskell.org.mail> Vilem-Benjamin Liepelt pushed to branch wip/buggymcbugfix/15185-enum-int at Glasgow Haskell Compiler / GHC Commits: 951b8eda by Vilem Liepelt at 2020-05-12T01:12:53+03:00 Add inline pragmas to Enum methods Fixes t15185 - - - - - 1 changed file: - libraries/base/GHC/Enum.hs Changes: ===================================== libraries/base/GHC/Enum.hs ===================================== @@ -139,11 +139,22 @@ class Enum a where -- * @enumFromThenTo 6 8 2 :: [Int] = []@ enumFromThenTo :: a -> a -> a -> [a] - succ = toEnum . (+ 1) . fromEnum - pred = toEnum . (subtract 1) . fromEnum - enumFrom x = map toEnum [fromEnum x ..] - enumFromThen x y = map toEnum [fromEnum x, fromEnum y ..] - enumFromTo x y = map toEnum [fromEnum x .. fromEnum y] + {-# INLINE succ #-} + succ = toEnum . (+ 1) . fromEnum + + {-# INLINE pred #-} + pred = toEnum . (subtract 1) . fromEnum + + {-# INLINE enumFrom #-} + enumFrom x = map toEnum [fromEnum x ..] + + {-# INLINE enumFromThen #-} + enumFromThen x y = map toEnum [fromEnum x, fromEnum y ..] + + {-# INLINE enumFromTo #-} + enumFromTo x y = map toEnum [fromEnum x .. fromEnum y] + + {-# INLINE enumFromThenTo #-} enumFromThenTo x1 x2 y = map toEnum [fromEnum x1, fromEnum x2 .. fromEnum y] -- Default methods for bounded enumerations View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/951b8eda5a1326415a5ef5db23f00e16f70fccab -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/951b8eda5a1326415a5ef5db23f00e16f70fccab You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 11 22:20:00 2020 From: gitlab at gitlab.haskell.org (Vilem-Benjamin Liepelt) Date: Mon, 11 May 2020 18:20:00 -0400 Subject: [Git][ghc/ghc][wip/buggymcbugfix/15185-enum-int] 2 commits: Fix spelling mistakes and typos Message-ID: <5eb9cf90bd9b1_61673f8103f8794c107036c7@gitlab.haskell.org.mail> Vilem-Benjamin Liepelt pushed to branch wip/buggymcbugfix/15185-enum-int at Glasgow Haskell Compiler / GHC Commits: f0a86479 by buggymcbugfix at 2020-05-12T01:18:08+03:00 Fix spelling mistakes and typos - - - - - d7c52e1a by buggymcbugfix at 2020-05-12T01:18:18+03:00 Add inline pragmas to Enum methods Fixes t15185 - - - - - 3 changed files: - docs/users_guide/debugging.rst - libraries/base/GHC/Enum.hs - libraries/base/GHC/List.hs Changes: ===================================== docs/users_guide/debugging.rst ===================================== @@ -301,7 +301,7 @@ subexpression elimination pass. Rules are filtered by the user provided string, a rule is kept if a prefix of its name matches the string. The pass then checks whether any of these rules could apply to - the program but which didn't file for some reason. For example, specifying + the program but which didn't fire for some reason. For example, specifying ``-drule-check=SPEC`` will check whether there are any applications which might be subject to a rule created by specialisation. ===================================== libraries/base/GHC/Enum.hs ===================================== @@ -139,11 +139,22 @@ class Enum a where -- * @enumFromThenTo 6 8 2 :: [Int] = []@ enumFromThenTo :: a -> a -> a -> [a] - succ = toEnum . (+ 1) . fromEnum - pred = toEnum . (subtract 1) . fromEnum - enumFrom x = map toEnum [fromEnum x ..] - enumFromThen x y = map toEnum [fromEnum x, fromEnum y ..] - enumFromTo x y = map toEnum [fromEnum x .. fromEnum y] + {-# INLINE succ #-} + succ = toEnum . (+ 1) . fromEnum + + {-# INLINE pred #-} + pred = toEnum . (subtract 1) . fromEnum + + {-# INLINE enumFrom #-} + enumFrom x = map toEnum [fromEnum x ..] + + {-# INLINE enumFromThen #-} + enumFromThen x y = map toEnum [fromEnum x, fromEnum y ..] + + {-# INLINE enumFromTo #-} + enumFromTo x y = map toEnum [fromEnum x .. fromEnum y] + + {-# INLINE enumFromThenTo #-} enumFromThenTo x1 x2 y = map toEnum [fromEnum x1, fromEnum x2 .. fromEnum y] -- Default methods for bounded enumerations ===================================== libraries/base/GHC/List.hs ===================================== @@ -277,10 +277,10 @@ to list-producing functions abstracted over cons and nil. Here we call them FB functions because their names usually end with 'FB'. It's a good idea to inline FB functions because: -* They are higher-order functions and therefore benefits from inlining. +* They are higher-order functions and therefore benefit from inlining. * When the final consumer is a left fold, inlining the FB functions is the only - way to make arity expansion to happen. See Note [Left fold via right fold]. + way to make arity expansion happen. See Note [Left fold via right fold]. For this reason we mark all FB functions INLINE [0]. The [0] phase-specifier ensures that calls to FB functions can be written back to the original form View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/951b8eda5a1326415a5ef5db23f00e16f70fccab...d7c52e1a848a7a1adf92132aae566db21d7b4232 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/951b8eda5a1326415a5ef5db23f00e16f70fccab...d7c52e1a848a7a1adf92132aae566db21d7b4232 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 12 00:18:07 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Mon, 11 May 2020 20:18:07 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 16 commits: rts/CNF: Fix fixup comparison function Message-ID: <5eb9eb3fa973f_6167119f85601076474f@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: d1f21122 by Ben Gamari at 2020-05-11T20:17:26-04:00 rts/CNF: Fix fixup comparison function Previously we would implicitly convert the difference between two words to an int, resulting in an integer overflow on 64-bit machines. Fixes #16992 - - - - - 0587f4f5 by Ömer Sinan Ağacan at 2020-05-11T20:17:31-04:00 Pack some of IdInfo fields into a bit field This reduces residency of compiler quite a bit on some programs. Example stats when building T10370: Before: 2,871,242,832 bytes allocated in the heap 4,693,328,008 bytes copied during GC 33,941,448 bytes maximum residency (276 sample(s)) 375,976 bytes maximum slop 83 MiB total memory in use (0 MB lost due to fragmentation) After: 2,858,897,344 bytes allocated in the heap 4,629,255,440 bytes copied during GC 32,616,624 bytes maximum residency (278 sample(s)) 314,400 bytes maximum slop 80 MiB total memory in use (0 MB lost due to fragmentation) So -3.9% residency, -1.3% bytes copied and -0.4% allocations. Fixes #17497 Metric Decrease: T9233 T9675 - - - - - 4efb3a5e by Ben Gamari at 2020-05-11T20:17:32-04:00 get-win32-tarballs: Fix base URL Revert a change previously made for testing purposes. - - - - - 79f8ed93 by Ben Gamari at 2020-05-11T20:17:32-04:00 get-win32-tarballs: Improve diagnostics output - - - - - 6b22d223 by Simon Jakobi at 2020-05-11T20:17:33-04:00 docs: Add examples for Data.Semigroup.Arg{Min,Max} Context: #17153 - - - - - 02af41a4 by Baldur Blöndal at 2020-05-11T20:17:37-04:00 Predicate, Equivalence derive via `.. -> a -> All' - - - - - 73297567 by Ben Gamari at 2020-05-11T20:17:38-04:00 Add few cleanups of the CAF logic Give the NameSet of non-CAFfy names a proper newtype to distinguish it from all of the other NameSets floating about. - - - - - 4f7c3951 by Emeka Nkurumeh at 2020-05-11T20:17:41-04:00 fix printf warning when using with ghc with clang on mingw - - - - - e8319bae by Daniel Gröber at 2020-05-11T20:17:49-04:00 Fix non power-of-two Storable.alignment in Capi_Ctype tests Alignments passed to alloca and friends must be a power of two for the code in allocatePinned to work properly. Commit 41230e2601 ("Zero out pinned block alignment slop when profiling") introduced an ASSERT for this but this test was still violating it. - - - - - d3b7fcaa by Daniel Gröber at 2020-05-11T20:17:49-04:00 Improve ByteArray# documentation regarding alignment - - - - - 1c03346c by Daniel Gröber at 2020-05-11T20:17:49-04:00 Document word-size rounding of ByteArray# memory (Fix #14731) - - - - - 0e1d00e3 by Daniel Gröber at 2020-05-11T20:17:49-04:00 Throw IOError when allocaBytesAligned gets non-power-of-two align - - - - - ec020520 by Ben Gamari at 2020-05-11T20:17:49-04:00 users-guide: Add discussion of shared object naming Fixes #18074. - - - - - 5bda3daf by Ben Gamari at 2020-05-11T20:17:49-04:00 testsuite: Print sign of performance changes Executes the minor formatting change in the tabulated performance changes suggested in #18135. - - - - - 243c76ec by Ben Gamari at 2020-05-11T20:17:50-04:00 testsuite: Add testcase for #18129 - - - - - 9e4bca9f by Ivan-Yudin at 2020-05-11T20:17:51-04:00 doc: Reformulate the opening paragraph of Ch. 4 in User's guide Removes mentioning of Hugs (it is not helpful for new users anymore). Changes the wording for the rest of the paragraph. Fixes #18132. - - - - - 27 changed files: - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/UpdateCafInfos.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Name/Set.hs - docs/users_guide/ghci.rst - docs/users_guide/packages.rst - docs/users_guide/phases.rst - includes/rts/Messages.h - libraries/base/Data/Functor/Contravariant.hs - libraries/base/Data/Semigroup.hs - libraries/base/Foreign/Marshal/Alloc.hs - libraries/base/Foreign/Storable.hs - libraries/base/changelog.md - + libraries/ghc-compact/tests/T16992.hs - + libraries/ghc-compact/tests/T16992.stdout - libraries/ghc-compact/tests/all.T - mk/get-win32-tarballs.py - rts/sm/CNF.c - testsuite/driver/runtests.py - testsuite/tests/ffi/should_run/Capi_Ctype_001.hsc - testsuite/tests/ffi/should_run/Capi_Ctype_A_001.hsc - testsuite/tests/ffi/should_run/Capi_Ctype_A_002.hsc - + testsuite/tests/typecheck/should_compile/T18129.hs - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== compiler/GHC/Builtin/primops.txt.pp ===================================== @@ -1413,19 +1413,21 @@ primtype MutableByteArray# s primop NewByteArrayOp_Char "newByteArray#" GenPrimOp Int# -> State# s -> (# State# s, MutableByteArray# s #) {Create a new mutable byte array of specified size (in bytes), in - the specified state thread.} + the specified state thread. The size of the memory underlying the + array will be rounded up to the platform's word size.} with out_of_line = True has_side_effects = True primop NewPinnedByteArrayOp_Char "newPinnedByteArray#" GenPrimOp Int# -> State# s -> (# State# s, MutableByteArray# s #) - {Create a mutable byte array that the GC guarantees not to move.} + {Like 'newByteArray#' but GC guarantees not to move it.} with out_of_line = True has_side_effects = True primop NewAlignedPinnedByteArrayOp_Char "newAlignedPinnedByteArray#" GenPrimOp Int# -> Int# -> State# s -> (# State# s, MutableByteArray# s #) - {Create a mutable byte array, aligned by the specified amount, that the GC guarantees not to move.} + {Like 'newPinnedByteArray#' but allow specifying an arbitrary + alignment, which must be a power of two.} with out_of_line = True has_side_effects = True ===================================== compiler/GHC/Cmm/Info/Build.hs ===================================== @@ -459,7 +459,7 @@ type CAFSet = Set CAFLabel type CAFEnv = LabelMap CAFSet mkCAFLabel :: CLabel -> CAFLabel -mkCAFLabel lbl = CAFLabel $! toClosureLbl lbl +mkCAFLabel lbl = CAFLabel (toClosureLbl lbl) -- This is a label that we can put in an SRT. It *must* be a closure label, -- pointing to either a FUN_STATIC, THUNK_STATIC, or CONSTR. @@ -736,10 +736,11 @@ getStaticFuns decls = type SRTMap = Map CAFLabel (Maybe SRTEntry) --- | Given SRTMap of a module returns the set of non-CAFFY names in the module. --- Any Names not in the set are CAFFY. -srtMapNonCAFs :: SRTMap -> NameSet -srtMapNonCAFs srtMap = mkNameSet (mapMaybe get_name (Map.toList srtMap)) +-- | Given 'SRTMap' of a module, returns the set of non-CAFFY names in the +-- module. Any 'Name's not in the set are CAFFY. +srtMapNonCAFs :: SRTMap -> NonCaffySet +srtMapNonCAFs srtMap = + NonCaffySet $ mkNameSet (mapMaybe get_name (Map.toList srtMap)) where get_name (CAFLabel l, Nothing) = hasHaskellName l get_name (_l, Just _srt_entry) = Nothing ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -1384,7 +1384,7 @@ hscWriteIface dflags iface no_change mod_location = do -- | Compile to hard-code. hscGenHardCode :: HscEnv -> CgGuts -> ModLocation -> FilePath - -> IO (FilePath, Maybe FilePath, [(ForeignSrcLang, FilePath)], NameSet) + -> IO (FilePath, Maybe FilePath, [(ForeignSrcLang, FilePath)], NonCaffySet) -- ^ @Just f@ <=> _stub.c is f hscGenHardCode hsc_env cgguts location output_filename = do let CgGuts{ -- This is the last use of the ModGuts in a compilation. @@ -1541,7 +1541,7 @@ doCodeGen :: HscEnv -> Module -> [TyCon] -> CollectedCCs -> [StgTopBinding] -> HpcInfo - -> IO (Stream IO CmmGroupSRTs NameSet) + -> IO (Stream IO CmmGroupSRTs NonCaffySet) -- Note we produce a 'Stream' of CmmGroups, so that the -- backend can be run incrementally. Otherwise it generates all -- the C-- up front, which has a significant space cost. ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -100,7 +100,7 @@ mkPartialIface hsc_env mod_details -- | Fully instantiate a interface -- Adds fingerprints and potentially code generator produced information. -mkFullIface :: HscEnv -> PartialModIface -> Maybe NameSet -> IO ModIface +mkFullIface :: HscEnv -> PartialModIface -> Maybe NonCaffySet -> IO ModIface mkFullIface hsc_env partial_iface mb_non_cafs = do let decls | gopt Opt_OmitInterfacePragmas (hsc_dflags hsc_env) @@ -117,9 +117,9 @@ mkFullIface hsc_env partial_iface mb_non_cafs = do return full_iface -updateDeclCafInfos :: [IfaceDecl] -> Maybe NameSet -> [IfaceDecl] +updateDeclCafInfos :: [IfaceDecl] -> Maybe NonCaffySet -> [IfaceDecl] updateDeclCafInfos decls Nothing = decls -updateDeclCafInfos decls (Just non_cafs) = map update_decl decls +updateDeclCafInfos decls (Just (NonCaffySet non_cafs)) = map update_decl decls where update_decl decl | IfaceId nm ty details infos <- decl ===================================== compiler/GHC/Iface/UpdateCafInfos.hs ===================================== @@ -23,7 +23,7 @@ import GHC.Utils.Outputable -- | Update CafInfos of all occurences (in rules, unfoldings, class instances) updateModDetailsCafInfos :: DynFlags - -> NameSet -- ^ Non-CAFFY names in the module. Names not in this set are CAFFY. + -> NonCaffySet -- ^ Non-CAFFY names in the module. Names not in this set are CAFFY. -> ModDetails -- ^ ModDetails to update -> ModDetails @@ -31,7 +31,7 @@ updateModDetailsCafInfos dflags _ mod_details | gopt Opt_OmitInterfacePragmas dflags = mod_details -updateModDetailsCafInfos _ non_cafs mod_details = +updateModDetailsCafInfos _ (NonCaffySet non_cafs) mod_details = {- pprTrace "updateModDetailsCafInfos" (text "non_cafs:" <+> ppr non_cafs) $ -} let ModDetails{ md_types = type_env -- for unfoldings ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -10,6 +10,7 @@ Haskell. [WDP 94/11]) {-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE BinaryLiterals #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -105,6 +106,9 @@ import GHC.Types.Demand import GHC.Types.Cpr import GHC.Utils.Misc +import Data.Word +import Data.Bits + -- infixl so you can say (id `set` a `set` b) infixl 1 `setRuleInfo`, `setArityInfo`, @@ -242,19 +246,11 @@ pprIdDetails other = brackets (pp other) -- too big. data IdInfo = IdInfo { - arityInfo :: !ArityInfo, - -- ^ 'Id' arity, as computed by 'GHC.Core.Arity'. Specifies how many - -- arguments this 'Id' has to be applied to before it doesn any - -- meaningful work. ruleInfo :: RuleInfo, -- ^ Specialisations of the 'Id's function which exist. -- See Note [Specialisations and RULES in IdInfo] unfoldingInfo :: Unfolding, -- ^ The 'Id's unfolding - cafInfo :: CafInfo, - -- ^ 'Id' CAF info - oneShotInfo :: OneShotInfo, - -- ^ Info about a lambda-bound variable, if the 'Id' is one inlinePragInfo :: InlinePragma, -- ^ Any inline pragma attached to the 'Id' occInfo :: OccInfo, @@ -267,14 +263,103 @@ data IdInfo -- freshly allocated constructor. demandInfo :: Demand, -- ^ ID demand information - callArityInfo :: !ArityInfo, - -- ^ How this is called. This is the number of arguments to which a - -- binding can be eta-expanded without losing any sharing. - -- n <=> all calls have at least n arguments - levityInfo :: LevityInfo - -- ^ when applied, will this Id ever have a levity-polymorphic type? + bitfield :: {-# UNPACK #-} !BitField + -- ^ Bitfield packs CafInfo, OneShotInfo, arity info, LevityInfo, and + -- call arity info in one 64-bit word. Packing these fields reduces size + -- of `IdInfo` from 12 words to 7 words and reduces residency by almost + -- 4% in some programs. + -- + -- See documentation of the getters for what these packed fields mean. } +-- | Encodes arities, OneShotInfo, CafInfo and LevityInfo. +-- From least-significant to most-significant bits: +-- +-- - Bit 0 (1): OneShotInfo +-- - Bit 1 (1): CafInfo +-- - Bit 2 (1): LevityInfo +-- - Bits 3-32(30): Call Arity info +-- - Bits 33-62(30): Arity info +-- +newtype BitField = BitField Word64 + +emptyBitField :: BitField +emptyBitField = BitField 0 + +bitfieldGetOneShotInfo :: BitField -> OneShotInfo +bitfieldGetOneShotInfo (BitField bits) = + if testBit bits 0 then OneShotLam else NoOneShotInfo + +bitfieldGetCafInfo :: BitField -> CafInfo +bitfieldGetCafInfo (BitField bits) = + if testBit bits 1 then NoCafRefs else MayHaveCafRefs + +bitfieldGetLevityInfo :: BitField -> LevityInfo +bitfieldGetLevityInfo (BitField bits) = + if testBit bits 2 then NeverLevityPolymorphic else NoLevityInfo + +bitfieldGetCallArityInfo :: BitField -> ArityInfo +bitfieldGetCallArityInfo (BitField bits) = + fromIntegral (bits `shiftR` 3) .&. ((1 `shiftL` 30) - 1) + +bitfieldGetArityInfo :: BitField -> ArityInfo +bitfieldGetArityInfo (BitField bits) = + fromIntegral (bits `shiftR` 33) + +bitfieldSetOneShotInfo :: OneShotInfo -> BitField -> BitField +bitfieldSetOneShotInfo info (BitField bits) = + case info of + NoOneShotInfo -> BitField (clearBit bits 0) + OneShotLam -> BitField (setBit bits 0) + +bitfieldSetCafInfo :: CafInfo -> BitField -> BitField +bitfieldSetCafInfo info (BitField bits) = + case info of + MayHaveCafRefs -> BitField (clearBit bits 1) + NoCafRefs -> BitField (setBit bits 1) + +bitfieldSetLevityInfo :: LevityInfo -> BitField -> BitField +bitfieldSetLevityInfo info (BitField bits) = + case info of + NoLevityInfo -> BitField (clearBit bits 2) + NeverLevityPolymorphic -> BitField (setBit bits 2) + +bitfieldSetCallArityInfo :: ArityInfo -> BitField -> BitField +bitfieldSetCallArityInfo info bf@(BitField bits) = + ASSERT(info < 2^(30 :: Int) - 1) + bitfieldSetArityInfo (bitfieldGetArityInfo bf) $ + BitField ((fromIntegral info `shiftL` 3) .|. (bits .&. 0b111)) + +bitfieldSetArityInfo :: ArityInfo -> BitField -> BitField +bitfieldSetArityInfo info (BitField bits) = + ASSERT(info < 2^(30 :: Int) - 1) + BitField ((fromIntegral info `shiftL` 33) .|. (bits .&. ((1 `shiftL` 33) - 1))) + +-- Getters + +-- | When applied, will this Id ever have a levity-polymorphic type? +levityInfo :: IdInfo -> LevityInfo +levityInfo = bitfieldGetLevityInfo . bitfield + +-- | Info about a lambda-bound variable, if the 'Id' is one +oneShotInfo :: IdInfo -> OneShotInfo +oneShotInfo = bitfieldGetOneShotInfo . bitfield + +-- | 'Id' arity, as computed by 'GHC.Core.Arity'. Specifies how many arguments +-- this 'Id' has to be applied to before it doesn any meaningful work. +arityInfo :: IdInfo -> ArityInfo +arityInfo = bitfieldGetArityInfo . bitfield + +-- | 'Id' CAF info +cafInfo :: IdInfo -> CafInfo +cafInfo = bitfieldGetCafInfo . bitfield + +-- | How this is called. This is the number of arguments to which a binding can +-- be eta-expanded without losing any sharing. n <=> all calls have at least n +-- arguments +callArityInfo :: IdInfo -> ArityInfo +callArityInfo = bitfieldGetCallArityInfo . bitfield + -- Setters setRuleInfo :: IdInfo -> RuleInfo -> IdInfo @@ -294,14 +379,20 @@ setUnfoldingInfo info uf info { unfoldingInfo = uf } setArityInfo :: IdInfo -> ArityInfo -> IdInfo -setArityInfo info ar = info { arityInfo = ar } +setArityInfo info ar = + info { bitfield = bitfieldSetArityInfo ar (bitfield info) } + setCallArityInfo :: IdInfo -> ArityInfo -> IdInfo -setCallArityInfo info ar = info { callArityInfo = ar } +setCallArityInfo info ar = + info { bitfield = bitfieldSetCallArityInfo ar (bitfield info) } + setCafInfo :: IdInfo -> CafInfo -> IdInfo -setCafInfo info caf = info { cafInfo = caf } +setCafInfo info caf = + info { bitfield = bitfieldSetCafInfo caf (bitfield info) } setOneShotInfo :: IdInfo -> OneShotInfo -> IdInfo -setOneShotInfo info lb = {-lb `seq`-} info { oneShotInfo = lb } +setOneShotInfo info lb = + info { bitfield = bitfieldSetOneShotInfo lb (bitfield info) } setDemandInfo :: IdInfo -> Demand -> IdInfo setDemandInfo info dd = dd `seq` info { demandInfo = dd } @@ -316,18 +407,19 @@ setCprInfo info cpr = cpr `seq` info { cprInfo = cpr } vanillaIdInfo :: IdInfo vanillaIdInfo = IdInfo { - cafInfo = vanillaCafInfo, - arityInfo = unknownArity, ruleInfo = emptyRuleInfo, unfoldingInfo = noUnfolding, - oneShotInfo = NoOneShotInfo, inlinePragInfo = defaultInlinePragma, occInfo = noOccInfo, demandInfo = topDmd, strictnessInfo = nopSig, cprInfo = topCprSig, - callArityInfo = unknownArity, - levityInfo = NoLevityInfo + bitfield = bitfieldSetCafInfo vanillaCafInfo $ + bitfieldSetArityInfo unknownArity $ + bitfieldSetCallArityInfo unknownArity $ + bitfieldSetOneShotInfo NoOneShotInfo $ + bitfieldSetLevityInfo NoLevityInfo $ + emptyBitField } -- | More informative 'IdInfo' we can use when we know the 'Id' has no CAF references @@ -638,12 +730,12 @@ instance Outputable LevityInfo where setNeverLevPoly :: HasDebugCallStack => IdInfo -> Type -> IdInfo setNeverLevPoly info ty = ASSERT2( not (resultIsLevPoly ty), ppr ty ) - info { levityInfo = NeverLevityPolymorphic } + info { bitfield = bitfieldSetLevityInfo NeverLevityPolymorphic (bitfield info) } setLevityInfoWithType :: IdInfo -> Type -> IdInfo setLevityInfoWithType info ty | not (resultIsLevPoly ty) - = info { levityInfo = NeverLevityPolymorphic } + = info { bitfield = bitfieldSetLevityInfo NeverLevityPolymorphic (bitfield info) } | otherwise = info ===================================== compiler/GHC/Types/Name/Set.hs ===================================== @@ -4,6 +4,7 @@ -} {-# LANGUAGE CPP #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} module GHC.Types.Name.Set ( -- * Names set type NameSet, @@ -28,7 +29,10 @@ module GHC.Types.Name.Set ( -- ** Manipulating defs and uses emptyDUs, usesOnly, mkDUs, plusDU, - findUses, duDefs, duUses, allUses + findUses, duDefs, duUses, allUses, + + -- * Non-CAFfy names + NonCaffySet(..) ) where #include "HsVersions.h" @@ -213,3 +217,8 @@ findUses dus uses = rhs_uses `unionNameSet` uses | otherwise -- No def is used = uses + +-- | 'Id's which have no CAF references. This is a result of analysis of C--. +-- It is always safe to use an empty 'NonCaffySet'. TODO Refer to Note. +newtype NonCaffySet = NonCaffySet NameSet + deriving (Semigroup, Monoid) ===================================== docs/users_guide/ghci.rst ===================================== @@ -7,23 +7,25 @@ Using GHCi single: GHCi single: interpreter single: interactive - single: Hugs single: Foreign Function Interface; GHCi support single: FFI; GHCi support -GHCi [1]_ is GHC's interactive environment, in which Haskell expressions -can be interactively evaluated and programs can be interpreted. If -you're familiar with `Hugs `__, then -you'll be right at home with GHCi. However, GHCi also has support for -interactively loading compiled code, as well as supporting all [2]_ the -language extensions that GHC provides. GHCi also includes an interactive +GHCi [1]_ is GHC's interactive environment that includes an interactive debugger (see :ref:`ghci-debugger`). +GHCi can + +- interactively evaluate Haskell expressions +- interpret Haskell programs +- load GHC-compiled modules. + +At the moment GHCi supports most of GHC's language extensions. + + .. [1] The "i" stands for “Interactive” -.. [2] - except ``foreign export``, at the moment + .. _ghci-introduction: ===================================== docs/users_guide/packages.rst ===================================== @@ -1061,6 +1061,14 @@ extra indirection). its output in place of ⟨GHCVersion⟩. See also :ref:`options-codegen` on how object files must be prepared for shared object linking. +- When building a shared library, care must be taken to ensure that the + resulting object is named appropriately. In particular, GHC expects the + name of a shared object to have the form ``libHS-ghc.`` where *unit id* is the unit ID given during compilation via + the :ghc-flag:`-this-unit-id ⟨unit-id⟩` flag, *ghc version* is the version of + GHC that produced/consumes the object and *ext* is the host system's usual + file extension for shared objects. + To compile a module which is to be part of a new package, use the ``-package-name`` (to identify the name of the package) and ``-library-name`` (to identify the version and the version hashes of its ===================================== docs/users_guide/phases.rst ===================================== @@ -807,7 +807,8 @@ for example). When creating shared objects for Haskell packages, the shared object must be named properly, so that GHC recognizes the shared object - when linked against this package. See shared object name mangling. + when linking against this package. + See :ref:`shared object name mangling ` for details. .. ghc-flag:: -dynload :shortdesc: Selects one of a number of modes for finding shared libraries at runtime. ===================================== includes/rts/Messages.h ===================================== @@ -18,7 +18,7 @@ #include -#if defined(mingw32_HOST_OS) +#if defined(mingw32_HOST_OS) && !defined(__clang__) /* On Win64, if we say "printf" then gcc thinks we are going to use MS format specifiers like %I64d rather than %llu */ #define PRINTF gnu_printf ===================================== libraries/base/Data/Functor/Contravariant.hs ===================================== @@ -1,5 +1,8 @@ +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE DerivingVia #-} {-# LANGUAGE EmptyCase #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} +{-# LANGUAGE InstanceSigs #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE Trustworthy #-} {-# LANGUAGE TypeOperators #-} @@ -53,11 +56,11 @@ import Data.Functor.Product import Data.Functor.Sum import Data.Functor.Compose -import Data.Monoid (Alt(..)) +import Data.Monoid (Alt(..), All(..)) import Data.Proxy import GHC.Generics -import Prelude hiding ((.),id) +import Prelude hiding ((.), id) -- | The class of contravariant functors. -- @@ -76,6 +79,7 @@ import Prelude hiding ((.),id) -- newtype Predicate a = Predicate { getPredicate :: a -> Bool } -- -- instance Contravariant Predicate where +-- contramap :: (a' -> a) -> (Predicate a -> Predicate a') -- contramap f (Predicate p) = Predicate (p . f) -- | `- First, map the input... -- `----- then apply the predicate. @@ -86,7 +90,7 @@ import Prelude hiding ((.),id) -- -- Any instance should be subject to the following laws: -- --- [Identity] @'contramap' 'id' = 'id'@ +-- [Identity] @'contramap' 'id' = 'id'@ -- [Composition] @'contramap' (g . f) = 'contramap' f . 'contramap' g@ -- -- Note, that the second law follows from the free theorem of the type of @@ -94,7 +98,7 @@ import Prelude hiding ((.),id) -- condition holds. class Contravariant f where - contramap :: (a -> b) -> f b -> f a + contramap :: (a' -> a) -> (f a -> f a') -- | Replace all locations in the output with the same value. -- The default definition is @'contramap' . 'const'@, but this may be @@ -110,7 +114,7 @@ class Contravariant f where -- lawful we have the following laws: -- -- @ --- 'fmap' f ≡ 'phantom' +-- 'fmap' f ≡ 'phantom' -- 'contramap' f ≡ 'phantom' -- @ phantom :: (Functor f, Contravariant f) => f a -> f b @@ -123,79 +127,134 @@ infixl 4 >$, $<, >$<, >$$< ($<) = flip (>$) -- | This is an infix alias for 'contramap'. -(>$<) :: Contravariant f => (a -> b) -> f b -> f a +(>$<) :: Contravariant f => (a -> b) -> (f b -> f a) (>$<) = contramap -- | This is an infix version of 'contramap' with the arguments flipped. (>$$<) :: Contravariant f => f b -> (a -> b) -> f a (>$$<) = flip contramap -deriving instance Contravariant f => Contravariant (Alt f) -deriving instance Contravariant f => Contravariant (Rec1 f) -deriving instance Contravariant f => Contravariant (M1 i c f) +deriving newtype instance Contravariant f => Contravariant (Alt f) +deriving newtype instance Contravariant f => Contravariant (Rec1 f) +deriving newtype instance Contravariant f => Contravariant (M1 i c f) instance Contravariant V1 where + contramap :: (a' -> a) -> (V1 a -> V1 a') contramap _ x = case x of instance Contravariant U1 where + contramap :: (a' -> a) -> (U1 a -> U1 a') contramap _ _ = U1 instance Contravariant (K1 i c) where + contramap :: (a' -> a) -> (K1 i c a -> K1 i c a') contramap _ (K1 c) = K1 c instance (Contravariant f, Contravariant g) => Contravariant (f :*: g) where + contramap :: (a' -> a) -> ((f :*: g) a -> (f :*: g) a') contramap f (xs :*: ys) = contramap f xs :*: contramap f ys instance (Functor f, Contravariant g) => Contravariant (f :.: g) where + contramap :: (a' -> a) -> ((f :.: g) a -> (f :.: g) a') contramap f (Comp1 fg) = Comp1 (fmap (contramap f) fg) instance (Contravariant f, Contravariant g) => Contravariant (f :+: g) where + contramap :: (a' -> a) -> ((f :+: g) a -> (f :+: g) a') contramap f (L1 xs) = L1 (contramap f xs) contramap f (R1 ys) = R1 (contramap f ys) instance (Contravariant f, Contravariant g) => Contravariant (Sum f g) where + contramap :: (a' -> a) -> (Sum f g a -> Sum f g a') contramap f (InL xs) = InL (contramap f xs) contramap f (InR ys) = InR (contramap f ys) instance (Contravariant f, Contravariant g) - => Contravariant (Product f g) where - contramap f (Pair a b) = Pair (contramap f a) (contramap f b) + => Contravariant (Product f g) where + contramap :: (a' -> a) -> (Product f g a -> Product f g a') + contramap f (Pair a b) = Pair (contramap f a) (contramap f b) instance Contravariant (Const a) where + contramap :: (b' -> b) -> (Const a b -> Const a b') contramap _ (Const a) = Const a instance (Functor f, Contravariant g) => Contravariant (Compose f g) where + contramap :: (a' -> a) -> (Compose f g a -> Compose f g a') contramap f (Compose fga) = Compose (fmap (contramap f) fga) instance Contravariant Proxy where + contramap :: (a' -> a) -> (Proxy a -> Proxy a') contramap _ _ = Proxy newtype Predicate a = Predicate { getPredicate :: a -> Bool } - --- | A 'Predicate' is a 'Contravariant' 'Functor', because 'contramap' can --- apply its function argument to the input of the predicate. -instance Contravariant Predicate where - contramap f g = Predicate $ getPredicate g . f - -instance Semigroup (Predicate a) where - Predicate p <> Predicate q = Predicate $ \a -> p a && q a - -instance Monoid (Predicate a) where - mempty = Predicate $ const True + deriving + ( -- | @('<>')@ on predicates uses logical conjunction @('&&')@ on + -- the results. Without newtypes this equals @'liftA2' (&&)@. + -- + -- @ + -- (<>) :: Predicate a -> Predicate a -> Predicate a + -- Predicate pred <> Predicate pred' = Predicate \a -> + -- pred a && pred' a + -- @ + Semigroup + , -- | @'mempty'@ on predicates always returns @True at . Without + -- newtypes this equals @'pure' True at . + -- + -- @ + -- mempty :: Predicate a + -- mempty = \_ -> True + -- @ + Monoid + ) + via a -> All + + deriving + ( -- | A 'Predicate' is a 'Contravariant' 'Functor', because + -- 'contramap' can apply its function argument to the input of + -- the predicate. + -- + -- Without newtypes @'contramap' f@ equals precomposing with @f@ + -- (= @(. f)@). + -- + -- @ + -- contramap :: (a' -> a) -> (Predicate a -> Predicate a') + -- contramap f (Predicate g) = Predicate (g . f) + -- @ + Contravariant + ) + via Op Bool -- | Defines a total ordering on a type as per 'compare'. -- -- This condition is not checked by the types. You must ensure that the -- supplied values are valid total orderings yourself. newtype Comparison a = Comparison { getComparison :: a -> a -> Ordering } - -deriving instance Semigroup (Comparison a) -deriving instance Monoid (Comparison a) + deriving + newtype + ( -- | @('<>')@ on comparisons combines results with @('<>') + -- \@Ordering at . Without newtypes this equals @'liftA2' ('liftA2' + -- ('<>'))@. + -- + -- @ + -- (<>) :: Comparison a -> Comparison a -> Comparison a + -- Comparison cmp <> Comparison cmp' = Comparison \a a' -> + -- cmp a a' <> cmp a a' + -- @ + Semigroup + , -- | @'mempty'@ on comparisons always returns @EQ at . Without + -- newtypes this equals @'pure' ('pure' EQ)@. + -- + -- @ + -- mempty :: Comparison a + -- mempty = Comparison \_ _ -> EQ + -- @ + Monoid + ) -- | A 'Comparison' is a 'Contravariant' 'Functor', because 'contramap' can -- apply its function argument to each input of the comparison function. instance Contravariant Comparison where - contramap f g = Comparison $ on (getComparison g) f + contramap :: (a' -> a) -> (Comparison a -> Comparison a') + contramap f (Comparison g) = Comparison (on g f) -- | Compare using 'compare'. defaultComparison :: Ord a => Comparison a @@ -214,18 +273,34 @@ defaultComparison = Comparison compare -- The types alone do not enforce these laws, so you'll have to check them -- yourself. newtype Equivalence a = Equivalence { getEquivalence :: a -> a -> Bool } + deriving + ( -- | @('<>')@ on equivalences uses logical conjunction @('&&')@ + -- on the results. Without newtypes this equals @'liftA2' + -- ('liftA2' (&&))@. + -- + -- @ + -- (<>) :: Equivalence a -> Equivalence a -> Equivalence a + -- Equivalence equiv <> Equivalence equiv' = Equivalence \a b -> + -- equiv a b && equiv a b + -- @ + Semigroup + , -- | @'mempty'@ on equivalences always returns @True at . Without + -- newtypes this equals @'pure' ('pure' True)@. + -- + -- @ + -- mempty :: Equivalence a + -- mempty = Equivalence \_ _ -> True + -- @ + Monoid + ) + via a -> a -> All -- | Equivalence relations are 'Contravariant', because you can -- apply the contramapped function to each input to the equivalence -- relation. instance Contravariant Equivalence where - contramap f g = Equivalence $ on (getEquivalence g) f - -instance Semigroup (Equivalence a) where - Equivalence p <> Equivalence q = Equivalence $ \a b -> p a b && q a b - -instance Monoid (Equivalence a) where - mempty = Equivalence (\_ _ -> True) + contramap :: (a' -> a) -> (Equivalence a -> Equivalence a') + contramap f (Equivalence g) = Equivalence (on g f) -- | Check for equivalence with '=='. -- @@ -238,15 +313,36 @@ comparisonEquivalence (Comparison p) = Equivalence $ \a b -> p a b == EQ -- | Dual function arrows. newtype Op a b = Op { getOp :: b -> a } - -deriving instance Semigroup a => Semigroup (Op a b) -deriving instance Monoid a => Monoid (Op a b) + deriving + newtype + ( -- | @('<>') \@(Op a b)@ without newtypes is @('<>') \@(b->a)@ = + -- @liftA2 ('<>')@. This lifts the 'Semigroup' operation + -- @('<>')@ over the output of @a at . + -- + -- @ + -- (<>) :: Op a b -> Op a b -> Op a b + -- Op f <> Op g = Op \a -> f a <> g a + -- @ + Semigroup + , -- | @'mempty' \@(Op a b)@ without newtypes is @mempty \@(b->a)@ + -- = @\_ -> mempty at . + -- + -- @ + -- mempty :: Op a b + -- mempty = Op \_ -> mempty + -- @ + Monoid + ) instance Category Op where + id :: Op a a id = Op id + + (.) :: Op b c -> Op a b -> Op a c Op f . Op g = Op (g . f) instance Contravariant (Op a) where + contramap :: (b' -> b) -> (Op a b -> Op a b') contramap f g = Op (getOp g . f) instance Num a => Num (Op a b) where ===================================== libraries/base/Data/Semigroup.hs ===================================== @@ -302,7 +302,14 @@ data Arg a b = Arg , Generic1 -- ^ @since 4.9.0.0 ) +-- | +-- >>> Min (Arg 0 ()) <> Min (Arg 1 ()) +-- Min {getMin = Arg 0 ()} type ArgMin a b = Min (Arg a b) + +-- | +-- >>> Max (Arg 0 ()) <> Max (Arg 1 ()) +-- Max {getMax = Arg 1 ()} type ArgMax a b = Max (Arg a b) -- | @since 4.9.0.0 ===================================== libraries/base/Foreign/Marshal/Alloc.hs ===================================== @@ -60,12 +60,15 @@ module Foreign.Marshal.Alloc ( finalizerFree ) where +import Data.Bits ( Bits, (.&.) ) import Data.Maybe import Foreign.C.Types ( CSize(..) ) import Foreign.Storable ( Storable(sizeOf,alignment) ) import Foreign.ForeignPtr ( FinalizerPtr ) import GHC.IO.Exception +import GHC.Num import GHC.Real +import GHC.Show import GHC.Ptr import GHC.Base @@ -150,7 +153,25 @@ allocaBytes (I# size) action = IO $ \ s0 -> -- See Note [NOINLINE for touch#] {-# NOINLINE allocaBytes #-} +-- |@'allocaBytesAligned' size align f@ executes the computation @f@, +-- passing as argument a pointer to a temporarily allocated block of memory +-- of @size@ bytes and aligned to @align@ bytes. The value of @align@ must +-- be a power of two. +-- +-- The memory is freed when @f@ terminates (either normally or via an +-- exception), so the pointer passed to @f@ must /not/ be used after this. +-- allocaBytesAligned :: Int -> Int -> (Ptr a -> IO b) -> IO b +allocaBytesAligned _size align _action + | not $ isPowerOfTwo align = + ioError $ + IOError Nothing InvalidArgument + "allocaBytesAligned" + ("alignment (="++show align++") must be a power of two!") + Nothing Nothing + where + isPowerOfTwo :: (Bits i, Integral i) => i -> Bool + isPowerOfTwo x = x .&. (x-1) == 0 allocaBytesAligned (I# size) (I# align) action = IO $ \ s0 -> case newAlignedPinnedByteArray# size align s0 of { (# s1, mbarr# #) -> case unsafeFreezeByteArray# mbarr# s1 of { (# s2, barr# #) -> ===================================== libraries/base/Foreign/Storable.hs ===================================== @@ -84,7 +84,9 @@ class Storable a where alignment :: a -> Int -- ^ Computes the alignment constraint of the argument. An -- alignment constraint @x@ is fulfilled by any address divisible - -- by @x at . The value of the argument is not used. + -- by @x at . The alignment must be a power of two if this instance + -- is to be used with 'alloca' or 'allocaArray'. The value of + -- the argument is not used. peekElemOff :: Ptr a -> Int -> IO a -- ^ Read a value from a memory area regarded as an array ===================================== libraries/base/changelog.md ===================================== @@ -19,6 +19,10 @@ * Add `singleton` function for `Data.List.NonEmpty`. + * Make `allocaBytesAligned` and `alloca` throw an IOError when the + alignment is not a power-of-two. The underlying primop + `newAlignedPinnedByteArray#` actually always assumed this but we didn't + document this fact in the user facing API until now. ## 4.14.0.0 *TBA* * Bundled with GHC 8.10.1 ===================================== libraries/ghc-compact/tests/T16992.hs ===================================== @@ -0,0 +1,22 @@ +import Data.Bifunctor +import Foreign.Ptr +import qualified Data.ByteString as BS +import qualified Data.ByteString.Unsafe as BS +import qualified GHC.Compact as Compact +import qualified GHC.Compact.Serialized as CompactSerialize + +-- | Minimal test case for reproducing compactFixupPointers# bug for large compact regions. +-- See Issue #16992. +main :: IO () +main = do + let + large = 1024 * 1024 * 128 + largeString = replicate large 'A' + + region <- Compact.compact largeString + + Just deserialized <- CompactSerialize.withSerializedCompact region $ \s -> do + blks <- mapM (BS.unsafePackCStringLen . bimap castPtr fromIntegral) (CompactSerialize.serializedCompactBlockList s) + CompactSerialize.importCompactByteStrings s blks + + print (Compact.getCompact deserialized == largeString) ===================================== libraries/ghc-compact/tests/T16992.stdout ===================================== @@ -0,0 +1 @@ +True ===================================== libraries/ghc-compact/tests/all.T ===================================== @@ -22,3 +22,8 @@ test('compact_share', omit_ways(['ghci', 'profasm', 'profthreaded']), test('compact_bench', [ ignore_stdout, extra_run_opts('100') ], compile_and_run, ['']) test('T17044', normal, compile_and_run, ['']) +# N.B. Sanity check times out due to large list. +test('T16992', [when(wordsize(32), skip), # Resource limit exceeded on 32-bit + high_memory_usage, + run_timeout_multiplier(5), + omit_ways(['sanity'])], compile_and_run, ['']) ===================================== mk/get-win32-tarballs.py ===================================== @@ -5,10 +5,10 @@ from pathlib import Path import urllib.request import subprocess import argparse +from sys import stderr TARBALL_VERSION = '0.1' BASE_URL = "https://downloads.haskell.org/ghc/mingw/{}".format(TARBALL_VERSION) -BASE_URL = "http://home.smart-cactus.org/~ben/ghc/mingw/{}".format(TARBALL_VERSION) DEST = Path('ghc-tarballs/mingw-w64') ARCHS = ['i686', 'x86_64', 'sources'] @@ -19,11 +19,13 @@ def file_url(arch: str, fname: str) -> str: fname=fname) def fetch(url: str, dest: Path): - print('Fetching', url, '=>', dest) + print('Fetching', url, '=>', dest, file=stderr) urllib.request.urlretrieve(url, dest) def fetch_arch(arch: str): - req = urllib.request.urlopen(file_url(arch, 'MANIFEST')) + manifest_url = file_url(arch, 'MANIFEST') + print('Fetching', manifest_url, file=stderr) + req = urllib.request.urlopen(manifest_url) files = req.read().decode('UTF-8').split('\n') d = DEST / arch if not d.is_dir(): @@ -36,6 +38,9 @@ def fetch_arch(arch: str): verify(arch) def verify(arch: str): + if not Path(DEST / arch / "SHA256SUMS").is_file(): + raise IOError("SHA256SUMS doesn't exist; have you fetched?") + cmd = ['sha256sum', '--quiet', '--check', '--ignore-missing', 'SHA256SUMS'] subprocess.check_call(cmd, cwd=DEST / arch) ===================================== rts/sm/CNF.c ===================================== @@ -1020,8 +1020,9 @@ cmp_fixup_table_item (const void *e1, const void *e2) { const StgWord *w1 = e1; const StgWord *w2 = e2; - - return *w1 - *w2; + if (*w1 > *w2) return +1; + else if (*w1 < *w2) return -1; + else return 0; } static StgWord * ===================================== testsuite/driver/runtests.py ===================================== @@ -349,13 +349,13 @@ def tabulate_metrics(metrics: List[PerfMetric]) -> None: val0 = metric.baseline.perfStat.value val1 = metric.stat.value rel = 100 * (val1 - val0) / val0 - print("{space:24} {herald:40} {value:15.3f} [{direction} {rel:2.1f}%]".format( + print("{space:24} {herald:40} {value:15.3f} [{direction}, {rel:2.1f}%]".format( space = "", herald = "(baseline @ HEAD~{depth})".format( depth = metric.baseline.commitDepth), value = val0, direction = metric.change, - rel = abs(rel) + rel = rel )) # First collect all the tests to be run ===================================== testsuite/tests/ffi/should_run/Capi_Ctype_001.hsc ===================================== @@ -35,7 +35,7 @@ foreign import capi unsafe "capi_ctype_001.h g" instance Storable Foo where sizeOf _ = #size Foo - alignment = sizeOf + alignment _ = #alignment Foo peek p = do i <- (# peek Foo, i) p j <- (# peek Foo, j) p k <- (# peek Foo, k) p ===================================== testsuite/tests/ffi/should_run/Capi_Ctype_A_001.hsc ===================================== @@ -16,7 +16,7 @@ data FooA = FooA { instance Storable FooA where sizeOf _ = #size Foo - alignment = sizeOf + alignment _ = #alignment Foo peek p = do i <- (# peek Foo, i) p j <- (# peek Foo, j) p k <- (# peek Foo, k) p ===================================== testsuite/tests/ffi/should_run/Capi_Ctype_A_002.hsc ===================================== @@ -17,7 +17,7 @@ data {-# CTYPE "capi_ctype_002_A.h" "Foo" #-} instance Storable Foo where sizeOf _ = #size Foo - alignment = sizeOf + alignment _ = #alignment Foo peek p = do i <- (# peek Foo, i) p j <- (# peek Foo, j) p k <- (# peek Foo, k) p ===================================== testsuite/tests/typecheck/should_compile/T18129.hs ===================================== @@ -0,0 +1,52 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE ConstraintKinds #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE TypeOperators #-} +{-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE UndecidableSuperClasses #-} + +module T18129 where + +import Data.Kind (Constraint) +import Data.Proxy (Proxy) +import Data.Typeable (Typeable) + +-- First, `generics-sop` code, intact. +-- +type family + AllF (c :: k -> Constraint) (xs :: [k]) :: Constraint where + AllF _c '[] = () + AllF c (x ': xs) = (c x, All c xs) + +class (AllF c xs, SListI xs) => All (c :: k -> Constraint) (xs :: [k]) +instance All c '[] +instance (c x, All c xs) => All c (x ': xs) where + +class Top x +instance Top x + +type SListI = All Top + +-- Next, user code, minimised. +-- +data GADT + = forall (xs :: [*]) (a :: *) + . (Top a, All Typeable xs) + => GADT + +withSomePipe' + :: GADT + -> (forall (xs :: [*]) + . (Proxy xs -> GADT) + -> GADT) + -> GADT +withSomePipe' GADT f = f (const GADT) + ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -706,3 +706,4 @@ test('T18023', normal, compile, ['']) test('T18036', normal, compile, ['']) test('T18036a', normal, compile, ['']) test('T17873', normal, compile, ['']) +test('T18129', expect_broken(18129), compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/65d40bd5c9a5d890328855cf1693ccda38e187f7...9e4bca9fb1d556cbc553aae5a6fb81b896fe8d11 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/65d40bd5c9a5d890328855cf1693ccda38e187f7...9e4bca9fb1d556cbc553aae5a6fb81b896fe8d11 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 12 06:38:54 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 12 May 2020 02:38:54 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 17 commits: rts/CNF: Fix fixup comparison function Message-ID: <5eba447e9a008_61671288ff4c108117c0@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: a09add85 by Ben Gamari at 2020-05-12T02:38:30-04:00 rts/CNF: Fix fixup comparison function Previously we would implicitly convert the difference between two words to an int, resulting in an integer overflow on 64-bit machines. Fixes #16992 - - - - - 131d388f by Ömer Sinan Ağacan at 2020-05-12T02:38:33-04:00 Pack some of IdInfo fields into a bit field This reduces residency of compiler quite a bit on some programs. Example stats when building T10370: Before: 2,871,242,832 bytes allocated in the heap 4,693,328,008 bytes copied during GC 33,941,448 bytes maximum residency (276 sample(s)) 375,976 bytes maximum slop 83 MiB total memory in use (0 MB lost due to fragmentation) After: 2,858,897,344 bytes allocated in the heap 4,629,255,440 bytes copied during GC 32,616,624 bytes maximum residency (278 sample(s)) 314,400 bytes maximum slop 80 MiB total memory in use (0 MB lost due to fragmentation) So -3.9% residency, -1.3% bytes copied and -0.4% allocations. Fixes #17497 Metric Decrease: T9233 T9675 - - - - - 1d2aaa2e by Ben Gamari at 2020-05-12T02:38:34-04:00 get-win32-tarballs: Fix base URL Revert a change previously made for testing purposes. - - - - - bd136bb7 by Ben Gamari at 2020-05-12T02:38:34-04:00 get-win32-tarballs: Improve diagnostics output - - - - - 156f801b by Simon Jakobi at 2020-05-12T02:38:35-04:00 docs: Add examples for Data.Semigroup.Arg{Min,Max} Context: #17153 - - - - - 9f0bc0fa by Baldur Blöndal at 2020-05-12T02:38:37-04:00 Predicate, Equivalence derive via `.. -> a -> All' - - - - - 80263d69 by Ben Gamari at 2020-05-12T02:38:38-04:00 Add few cleanups of the CAF logic Give the NameSet of non-CAFfy names a proper newtype to distinguish it from all of the other NameSets floating about. - - - - - da42dc1d by Emeka Nkurumeh at 2020-05-12T02:38:40-04:00 fix printf warning when using with ghc with clang on mingw - - - - - 0855c928 by Daniel Gröber at 2020-05-12T02:38:42-04:00 Fix non power-of-two Storable.alignment in Capi_Ctype tests Alignments passed to alloca and friends must be a power of two for the code in allocatePinned to work properly. Commit 41230e2601 ("Zero out pinned block alignment slop when profiling") introduced an ASSERT for this but this test was still violating it. - - - - - 392cc02c by Daniel Gröber at 2020-05-12T02:38:42-04:00 Improve ByteArray# documentation regarding alignment - - - - - edaec729 by Daniel Gröber at 2020-05-12T02:38:42-04:00 Document word-size rounding of ByteArray# memory (Fix #14731) - - - - - c1e4d284 by Daniel Gröber at 2020-05-12T02:38:42-04:00 Throw IOError when allocaBytesAligned gets non-power-of-two align - - - - - 80614bd8 by Sebastian Graf at 2020-05-12T02:38:42-04:00 CprAnal: Don't attach CPR sigs to expandable bindings (#18154) Instead, look through expandable unfoldings in `cprTransform`. See the new Note [CPR for expandable unfoldings]: ``` Long static data structures (whether top-level or not) like xs = x1 : xs1 xs1 = x2 : xs2 xs2 = x3 : xs3 should not get CPR signatures, because they * Never get WW'd, so their CPR signature should be irrelevant after analysis (in fact the signature might even be harmful for that reason) * Would need to be inlined/expanded to see their constructed product * Recording CPR on them blows up interface file sizes and is redundant with their unfolding. In case of Nested CPR, this blow-up can be quadratic! But we can't just stop giving DataCon application bindings the CPR property, for example fac 0 = 1 fac n = n * fac (n-1) fac certainly has the CPR property and should be WW'd! But FloatOut will transform the first clause to lvl = 1 fac 0 = lvl If lvl doesn't have the CPR property, fac won't either. But lvl doesn't have a CPR signature to extrapolate into a CPR transformer ('cprTransform'). So instead we keep on cprAnal'ing through *expandable* unfoldings for these arity 0 bindings via 'cprExpandUnfolding_maybe'. In practice, GHC generates a lot of (nested) TyCon and KindRep bindings, one for each data declaration. It's wasteful to attach CPR signatures to each of them (and intractable in case of Nested CPR). ``` Fixes #18154. - - - - - 5888e85a by Ben Gamari at 2020-05-12T02:38:43-04:00 users-guide: Add discussion of shared object naming Fixes #18074. - - - - - b9f092dd by Ben Gamari at 2020-05-12T02:38:43-04:00 testsuite: Print sign of performance changes Executes the minor formatting change in the tabulated performance changes suggested in #18135. - - - - - 16abaa9b by Ben Gamari at 2020-05-12T02:38:44-04:00 testsuite: Add testcase for #18129 - - - - - 8c19b8d0 by Ivan-Yudin at 2020-05-12T02:38:45-04:00 doc: Reformulate the opening paragraph of Ch. 4 in User's guide Removes mentioning of Hugs (it is not helpful for new users anymore). Changes the wording for the rest of the paragraph. Fixes #18132. - - - - - 30 changed files: - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/UpdateCafInfos.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Name/Set.hs - docs/users_guide/ghci.rst - docs/users_guide/packages.rst - docs/users_guide/phases.rst - includes/rts/Messages.h - libraries/base/Data/Functor/Contravariant.hs - libraries/base/Data/Semigroup.hs - libraries/base/Foreign/Marshal/Alloc.hs - libraries/base/Foreign/Storable.hs - libraries/base/changelog.md - + libraries/ghc-compact/tests/T16992.hs - + libraries/ghc-compact/tests/T16992.stdout - libraries/ghc-compact/tests/all.T - mk/get-win32-tarballs.py - rts/sm/CNF.c - testsuite/driver/runtests.py - testsuite/tests/ffi/should_run/Capi_Ctype_001.hsc - testsuite/tests/ffi/should_run/Capi_Ctype_A_001.hsc - testsuite/tests/ffi/should_run/Capi_Ctype_A_002.hsc - testsuite/tests/numeric/should_compile/T14170.stdout - testsuite/tests/numeric/should_compile/T14465.stdout - testsuite/tests/numeric/should_compile/T7116.stdout - testsuite/tests/simplCore/should_compile/T13143.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9e4bca9fb1d556cbc553aae5a6fb81b896fe8d11...8c19b8d0b68c1f7d05fdf3ccd53d00e0916d0d8b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9e4bca9fb1d556cbc553aae5a6fb81b896fe8d11...8c19b8d0b68c1f7d05fdf3ccd53d00e0916d0d8b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 12 07:06:41 2020 From: gitlab at gitlab.haskell.org (Sven Tennie) Date: Tue, 12 May 2020 03:06:41 -0400 Subject: [Git][ghc/ghc][wip/ghc-debug] Cleanup getClosureX Message-ID: <5eba4b019a994_616711a31edc108336e6@gitlab.haskell.org.mail> Sven Tennie pushed to branch wip/ghc-debug at Glasgow Haskell Compiler / GHC Commits: 8eea2214 by Sven Tennie at 2020-05-12T09:04:59+02:00 Cleanup getClosureX Compiler warnings make the CI build fail. - - - - - 1 changed file: - libraries/ghc-heap/GHC/Exts/Heap.hs Changes: ===================================== libraries/ghc-heap/GHC/Exts/Heap.hs ===================================== @@ -294,28 +294,24 @@ getClosureX get_closure_raw x = do fail $ "Expected 6 ptr arguments to TSO, found " ++ show (length pts) - threadId' <- allocaArray (length wds) (\ptr -> do + allocaArray (length wds) (\ptr -> do pokeArray ptr wds - id <- peekStgThreadID ptr - return id - ) - alloc_limit' <- allocaArray (length wds) (\ptr -> do - pokeArray ptr wds - alloc_limit <- peekAllocLimit ptr - return alloc_limit - ) - pure $ TSOClosure - { info = itbl - , _link = (pts !! 0) - , global_link = (pts !! 1) - , tsoStack = (pts !! 2) - , trec = (pts !! 3) - , blocked_exceptions = (pts !! 4) - , bq = (pts !! 5) - , threadId = threadId' - , alloc_limit = alloc_limit' - } + threadId' <- peekStgThreadID ptr + alloc_limit' <- peekAllocLimit ptr + + pure $ TSOClosure + { info = itbl + , _link = (pts !! 0) + , global_link = (pts !! 1) + , tsoStack = (pts !! 2) + , trec = (pts !! 3) + , blocked_exceptions = (pts !! 4) + , bq = (pts !! 5) + , threadId = threadId' + , alloc_limit = alloc_limit' + } + ) STACK -> do unless (length pts >= 1) $ fail $ "Expected at least 1 ptr argument to STACK, found " @@ -338,4 +334,3 @@ getClosureX get_closure_raw x = do -- | Like 'getClosureDataX', but taking a 'Box', so it is easier to work with. getBoxedClosureData :: Box -> IO Closure getBoxedClosureData (Box a) = getClosureData a - View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8eea22144a0f22df1c7a6e500b99458101d8570e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8eea22144a0f22df1c7a6e500b99458101d8570e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 12 11:15:45 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Tue, 12 May 2020 07:15:45 -0400 Subject: [Git][ghc/ghc][wip/T16762-chunks-2-and-3] 6 commits: Add test for #16167 Message-ID: <5eba856122040_6167119ebbd01085986f@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T16762-chunks-2-and-3 at Glasgow Haskell Compiler / GHC Commits: 9d97f4b5 by nineonine at 2020-05-08T15:30:03-04:00 Add test for #16167 - - - - - aa318338 by Ryan Scott at 2020-05-08T15:30:04-04:00 Bump exceptions submodule so that dist-boot is .gitignore'd `exceptions` is a stage-0 boot library as of commit 30272412fa437ab8e7a8035db94a278e10513413, which means that building `exceptions` in a GHC tree will generate a `dist-boot` directory. However, this directory was not specified in `exceptions`' `.gitignore` file, which causes it to dirty up the current `git` working directory. Accordingly, this bumps the `exceptions` submodule to commit ghc/packages/exceptions at 23c0b8a50d7592af37ca09beeec16b93080df98f, which adds `dist-boot` to the `.gitignore` file. - - - - - ea86360f by Ömer Sinan Ağacan at 2020-05-08T15:30:30-04:00 Linker.c: initialize n_symbols of ObjectCode with other fields - - - - - 951c1fb0 by Sylvain Henry at 2020-05-09T21:46:38-04:00 Fix unboxed-sums GC ptr-slot rubbish value (#17791) This patch allows boot libraries to use unboxed sums without implicitly depending on `base` package because of `absentSumFieldError`. See updated Note [aBSENT_SUM_FIELD_ERROR_ID] in GHC.Core.Make - - - - - b352d63c by Ben Gamari at 2020-05-09T21:47:14-04:00 rts: Make non-existent linker search path merely a warning As noted in #18105, previously this resulted in a rather intrusive error message. This is in contrast to the general expectation that search paths are merely places to look, not places that must exist. Fixes #18105. - - - - - e77ceadc by Ryan Scott at 2020-05-12T07:13:53-04:00 Factor out HsPatSigType for pat sigs/RULE term sigs (#16762) This implements chunks (2) and (3) of https://gitlab.haskell.org/ghc/ghc/issues/16762#note_270170. Namely, it introduces a dedicated `HsPatSigType` AST type, which represents the types that can appear in pattern signatures and term-level `RULE` binders. Previously, these were represented with `LHsSigWcType`. Although `LHsSigWcType` is isomorphic to `HsPatSigType`, the intended semantics of the two types are slightly different, as evidenced by the fact that they have different code paths in the renamer and typechecker. See also the new `Note [Pattern signature binders and scoping]` in `GHC.Hs.Types`. - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Extension.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Types.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Stg/Unarise.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/Gen/Rule.hs - compiler/GHC/ThToHs.hs - includes/stg/MiscClosures.h - libraries/base/Control/Exception/Base.hs - libraries/exceptions - + libraries/ghc-prim/GHC/Prim/Panic.hs - libraries/ghc-prim/ghc-prim.cabal - rts/Exception.cmm - rts/Linker.c - rts/Prelude.h - rts/RtsStartup.c - rts/RtsSymbols.c The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2c845e8579d22f4d6aed8a8eb8e22e4f1ed5ec28...e77ceadc78375fcdb81b94f559328af0dca95cb1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2c845e8579d22f4d6aed8a8eb8e22e4f1ed5ec28...e77ceadc78375fcdb81b94f559328af0dca95cb1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 12 16:42:38 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Tue, 12 May 2020 12:42:38 -0400 Subject: [Git][ghc/ghc][ghc-8.10] configure.ac: Reset RELEASE to NO Message-ID: <5ebad1fead836_6167119ebbd0109147d1@gitlab.haskell.org.mail> Ben Gamari pushed to branch ghc-8.10 at Glasgow Haskell Compiler / GHC Commits: 584c3b05 by Ben Gamari at 2020-05-12T12:42:34-04:00 configure.ac: Reset RELEASE to NO - - - - - 1 changed file: - configure.ac Changes: ===================================== configure.ac ===================================== @@ -16,7 +16,7 @@ dnl AC_INIT([The Glorious Glasgow Haskell Compilation System], [8.10.1], [glasgow-haskell-bugs at haskell.org], [ghc-AC_PACKAGE_VERSION]) # Set this to YES for a released version, otherwise NO -: ${RELEASE=YES} +: ${RELEASE=NO} # The primary version (e.g. 7.5, 7.4.1) is set in the AC_INIT line # above. If this is not a released version, then we will append the View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/584c3b0564d5e572282dde7d173b9c67599e9dd2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/584c3b0564d5e572282dde7d173b9c67599e9dd2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 12 17:01:33 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 12 May 2020 13:01:33 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 12 commits: rts/CNF: Fix fixup comparison function Message-ID: <5ebad66db07d9_6167119ebbd0109227d0@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 7c14efd7 by Ben Gamari at 2020-05-12T13:01:06-04:00 rts/CNF: Fix fixup comparison function Previously we would implicitly convert the difference between two words to an int, resulting in an integer overflow on 64-bit machines. Fixes #16992 - - - - - aa9e5453 by Ömer Sinan Ağacan at 2020-05-12T13:01:11-04:00 Pack some of IdInfo fields into a bit field This reduces residency of compiler quite a bit on some programs. Example stats when building T10370: Before: 2,871,242,832 bytes allocated in the heap 4,693,328,008 bytes copied during GC 33,941,448 bytes maximum residency (276 sample(s)) 375,976 bytes maximum slop 83 MiB total memory in use (0 MB lost due to fragmentation) After: 2,858,897,344 bytes allocated in the heap 4,629,255,440 bytes copied during GC 32,616,624 bytes maximum residency (278 sample(s)) 314,400 bytes maximum slop 80 MiB total memory in use (0 MB lost due to fragmentation) So -3.9% residency, -1.3% bytes copied and -0.4% allocations. Fixes #17497 Metric Decrease: T9233 T9675 - - - - - 1a54fc5e by Ben Gamari at 2020-05-12T13:01:12-04:00 get-win32-tarballs: Fix base URL Revert a change previously made for testing purposes. - - - - - ba93714b by Ben Gamari at 2020-05-12T13:01:12-04:00 get-win32-tarballs: Improve diagnostics output - - - - - d23e530b by Simon Jakobi at 2020-05-12T13:01:13-04:00 docs: Add examples for Data.Semigroup.Arg{Min,Max} Context: #17153 - - - - - 74460ea2 by Ben Gamari at 2020-05-12T13:01:14-04:00 Add few cleanups of the CAF logic Give the NameSet of non-CAFfy names a proper newtype to distinguish it from all of the other NameSets floating about. - - - - - ba8d6479 by Emeka Nkurumeh at 2020-05-12T13:01:20-04:00 fix printf warning when using with ghc with clang on mingw - - - - - 20589299 by Sebastian Graf at 2020-05-12T13:01:21-04:00 CprAnal: Don't attach CPR sigs to expandable bindings (#18154) Instead, look through expandable unfoldings in `cprTransform`. See the new Note [CPR for expandable unfoldings]: ``` Long static data structures (whether top-level or not) like xs = x1 : xs1 xs1 = x2 : xs2 xs2 = x3 : xs3 should not get CPR signatures, because they * Never get WW'd, so their CPR signature should be irrelevant after analysis (in fact the signature might even be harmful for that reason) * Would need to be inlined/expanded to see their constructed product * Recording CPR on them blows up interface file sizes and is redundant with their unfolding. In case of Nested CPR, this blow-up can be quadratic! But we can't just stop giving DataCon application bindings the CPR property, for example fac 0 = 1 fac n = n * fac (n-1) fac certainly has the CPR property and should be WW'd! But FloatOut will transform the first clause to lvl = 1 fac 0 = lvl If lvl doesn't have the CPR property, fac won't either. But lvl doesn't have a CPR signature to extrapolate into a CPR transformer ('cprTransform'). So instead we keep on cprAnal'ing through *expandable* unfoldings for these arity 0 bindings via 'cprExpandUnfolding_maybe'. In practice, GHC generates a lot of (nested) TyCon and KindRep bindings, one for each data declaration. It's wasteful to attach CPR signatures to each of them (and intractable in case of Nested CPR). ``` Fixes #18154. - - - - - a72be48a by Ben Gamari at 2020-05-12T13:01:21-04:00 users-guide: Add discussion of shared object naming Fixes #18074. - - - - - 4ded7e6c by Ben Gamari at 2020-05-12T13:01:22-04:00 testsuite: Print sign of performance changes Executes the minor formatting change in the tabulated performance changes suggested in #18135. - - - - - 64094a46 by Ben Gamari at 2020-05-12T13:01:22-04:00 testsuite: Add testcase for #18129 - - - - - 2523ce32 by Ivan-Yudin at 2020-05-12T13:01:25-04:00 doc: Reformulate the opening paragraph of Ch. 4 in User's guide Removes mentioning of Hugs (it is not helpful for new users anymore). Changes the wording for the rest of the paragraph. Fixes #18132. - - - - - 30 changed files: - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/UpdateCafInfos.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Name/Set.hs - docs/users_guide/ghci.rst - docs/users_guide/packages.rst - docs/users_guide/phases.rst - includes/rts/Messages.h - libraries/base/Data/Semigroup.hs - + libraries/ghc-compact/tests/T16992.hs - + libraries/ghc-compact/tests/T16992.stdout - libraries/ghc-compact/tests/all.T - mk/get-win32-tarballs.py - rts/sm/CNF.c - testsuite/driver/runtests.py - testsuite/tests/numeric/should_compile/T14170.stdout - testsuite/tests/numeric/should_compile/T14465.stdout - testsuite/tests/numeric/should_compile/T7116.stdout - testsuite/tests/simplCore/should_compile/T13143.stderr - testsuite/tests/simplCore/should_compile/T13543.stderr - testsuite/tests/simplCore/should_compile/T18013.stderr - testsuite/tests/simplCore/should_compile/T3717.stderr - testsuite/tests/simplCore/should_compile/T3772.stdout - testsuite/tests/simplCore/should_compile/T4908.stderr - testsuite/tests/simplCore/should_compile/T4930.stderr - testsuite/tests/simplCore/should_compile/T7360.stderr - testsuite/tests/simplCore/should_compile/noinline01.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8c19b8d0b68c1f7d05fdf3ccd53d00e0916d0d8b...2523ce32679761361e0313b85aece7e66f0b0b75 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8c19b8d0b68c1f7d05fdf3ccd53d00e0916d0d8b...2523ce32679761361e0313b85aece7e66f0b0b75 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 12 22:32:15 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 12 May 2020 18:32:15 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 12 commits: rts/CNF: Fix fixup comparison function Message-ID: <5ebb23ef7d59c_61673f81a3bd711c109661a4@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: b57594c3 by Ben Gamari at 2020-05-12T18:32:00-04:00 rts/CNF: Fix fixup comparison function Previously we would implicitly convert the difference between two words to an int, resulting in an integer overflow on 64-bit machines. Fixes #16992 - - - - - ea1264db by Ömer Sinan Ağacan at 2020-05-12T18:32:02-04:00 Pack some of IdInfo fields into a bit field This reduces residency of compiler quite a bit on some programs. Example stats when building T10370: Before: 2,871,242,832 bytes allocated in the heap 4,693,328,008 bytes copied during GC 33,941,448 bytes maximum residency (276 sample(s)) 375,976 bytes maximum slop 83 MiB total memory in use (0 MB lost due to fragmentation) After: 2,858,897,344 bytes allocated in the heap 4,629,255,440 bytes copied during GC 32,616,624 bytes maximum residency (278 sample(s)) 314,400 bytes maximum slop 80 MiB total memory in use (0 MB lost due to fragmentation) So -3.9% residency, -1.3% bytes copied and -0.4% allocations. Fixes #17497 Metric Decrease: T9233 T9675 - - - - - 460a60cf by Ben Gamari at 2020-05-12T18:32:03-04:00 get-win32-tarballs: Fix base URL Revert a change previously made for testing purposes. - - - - - 767796fa by Ben Gamari at 2020-05-12T18:32:03-04:00 get-win32-tarballs: Improve diagnostics output - - - - - 59587dee by Simon Jakobi at 2020-05-12T18:32:04-04:00 docs: Add examples for Data.Semigroup.Arg{Min,Max} Context: #17153 - - - - - 9d690898 by Ben Gamari at 2020-05-12T18:32:05-04:00 Add few cleanups of the CAF logic Give the NameSet of non-CAFfy names a proper newtype to distinguish it from all of the other NameSets floating about. - - - - - 61e16cbc by Emeka Nkurumeh at 2020-05-12T18:32:08-04:00 fix printf warning when using with ghc with clang on mingw - - - - - b1704686 by Sebastian Graf at 2020-05-12T18:32:08-04:00 CprAnal: Don't attach CPR sigs to expandable bindings (#18154) Instead, look through expandable unfoldings in `cprTransform`. See the new Note [CPR for expandable unfoldings]: ``` Long static data structures (whether top-level or not) like xs = x1 : xs1 xs1 = x2 : xs2 xs2 = x3 : xs3 should not get CPR signatures, because they * Never get WW'd, so their CPR signature should be irrelevant after analysis (in fact the signature might even be harmful for that reason) * Would need to be inlined/expanded to see their constructed product * Recording CPR on them blows up interface file sizes and is redundant with their unfolding. In case of Nested CPR, this blow-up can be quadratic! But we can't just stop giving DataCon application bindings the CPR property, for example fac 0 = 1 fac n = n * fac (n-1) fac certainly has the CPR property and should be WW'd! But FloatOut will transform the first clause to lvl = 1 fac 0 = lvl If lvl doesn't have the CPR property, fac won't either. But lvl doesn't have a CPR signature to extrapolate into a CPR transformer ('cprTransform'). So instead we keep on cprAnal'ing through *expandable* unfoldings for these arity 0 bindings via 'cprExpandUnfolding_maybe'. In practice, GHC generates a lot of (nested) TyCon and KindRep bindings, one for each data declaration. It's wasteful to attach CPR signatures to each of them (and intractable in case of Nested CPR). ``` Fixes #18154. - - - - - 8a2e894d by Ben Gamari at 2020-05-12T18:32:09-04:00 users-guide: Add discussion of shared object naming Fixes #18074. - - - - - 4e04d525 by Ben Gamari at 2020-05-12T18:32:09-04:00 testsuite: Print sign of performance changes Executes the minor formatting change in the tabulated performance changes suggested in #18135. - - - - - 710edf96 by Ben Gamari at 2020-05-12T18:32:09-04:00 testsuite: Add testcase for #18129 - - - - - bef5dc3e by Ivan-Yudin at 2020-05-12T18:32:11-04:00 doc: Reformulate the opening paragraph of Ch. 4 in User's guide Removes mentioning of Hugs (it is not helpful for new users anymore). Changes the wording for the rest of the paragraph. Fixes #18132. - - - - - 30 changed files: - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/UpdateCafInfos.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Name/Set.hs - docs/users_guide/ghci.rst - docs/users_guide/packages.rst - docs/users_guide/phases.rst - includes/rts/Messages.h - libraries/base/Data/Semigroup.hs - + libraries/ghc-compact/tests/T16992.hs - + libraries/ghc-compact/tests/T16992.stdout - libraries/ghc-compact/tests/all.T - mk/get-win32-tarballs.py - rts/sm/CNF.c - testsuite/driver/runtests.py - testsuite/tests/numeric/should_compile/T14170.stdout - testsuite/tests/numeric/should_compile/T14465.stdout - testsuite/tests/numeric/should_compile/T7116.stdout - testsuite/tests/simplCore/should_compile/T13143.stderr - testsuite/tests/simplCore/should_compile/T13543.stderr - testsuite/tests/simplCore/should_compile/T18013.stderr - testsuite/tests/simplCore/should_compile/T3717.stderr - testsuite/tests/simplCore/should_compile/T3772.stdout - testsuite/tests/simplCore/should_compile/T4908.stderr - testsuite/tests/simplCore/should_compile/T4930.stderr - testsuite/tests/simplCore/should_compile/T7360.stderr - testsuite/tests/simplCore/should_compile/noinline01.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2523ce32679761361e0313b85aece7e66f0b0b75...bef5dc3e525f80612206eb792833a54566f688ad -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2523ce32679761361e0313b85aece7e66f0b0b75...bef5dc3e525f80612206eb792833a54566f688ad You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 13 06:02:43 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 13 May 2020 02:02:43 -0400 Subject: [Git][ghc/ghc][master] rts/CNF: Fix fixup comparison function Message-ID: <5ebb8d8380241_616712a9b7f0109921ca@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: cf4f1e2f by Ben Gamari at 2020-05-13T02:02:33-04:00 rts/CNF: Fix fixup comparison function Previously we would implicitly convert the difference between two words to an int, resulting in an integer overflow on 64-bit machines. Fixes #16992 - - - - - 4 changed files: - + libraries/ghc-compact/tests/T16992.hs - + libraries/ghc-compact/tests/T16992.stdout - libraries/ghc-compact/tests/all.T - rts/sm/CNF.c Changes: ===================================== libraries/ghc-compact/tests/T16992.hs ===================================== @@ -0,0 +1,22 @@ +import Data.Bifunctor +import Foreign.Ptr +import qualified Data.ByteString as BS +import qualified Data.ByteString.Unsafe as BS +import qualified GHC.Compact as Compact +import qualified GHC.Compact.Serialized as CompactSerialize + +-- | Minimal test case for reproducing compactFixupPointers# bug for large compact regions. +-- See Issue #16992. +main :: IO () +main = do + let + large = 1024 * 1024 * 128 + largeString = replicate large 'A' + + region <- Compact.compact largeString + + Just deserialized <- CompactSerialize.withSerializedCompact region $ \s -> do + blks <- mapM (BS.unsafePackCStringLen . bimap castPtr fromIntegral) (CompactSerialize.serializedCompactBlockList s) + CompactSerialize.importCompactByteStrings s blks + + print (Compact.getCompact deserialized == largeString) ===================================== libraries/ghc-compact/tests/T16992.stdout ===================================== @@ -0,0 +1 @@ +True ===================================== libraries/ghc-compact/tests/all.T ===================================== @@ -22,3 +22,8 @@ test('compact_share', omit_ways(['ghci', 'profasm', 'profthreaded']), test('compact_bench', [ ignore_stdout, extra_run_opts('100') ], compile_and_run, ['']) test('T17044', normal, compile_and_run, ['']) +# N.B. Sanity check times out due to large list. +test('T16992', [when(wordsize(32), skip), # Resource limit exceeded on 32-bit + high_memory_usage, + run_timeout_multiplier(5), + omit_ways(['sanity'])], compile_and_run, ['']) ===================================== rts/sm/CNF.c ===================================== @@ -1020,8 +1020,9 @@ cmp_fixup_table_item (const void *e1, const void *e2) { const StgWord *w1 = e1; const StgWord *w2 = e2; - - return *w1 - *w2; + if (*w1 > *w2) return +1; + else if (*w1 < *w2) return -1; + else return 0; } static StgWord * View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cf4f1e2f78840d25b132de55bce1e02256334ace -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cf4f1e2f78840d25b132de55bce1e02256334ace You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 13 06:03:27 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 13 May 2020 02:03:27 -0400 Subject: [Git][ghc/ghc][master] Pack some of IdInfo fields into a bit field Message-ID: <5ebb8daf7e9af_61673f819aad978c10996485@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: a03da9bf by Ömer Sinan Ağacan at 2020-05-13T02:03:16-04:00 Pack some of IdInfo fields into a bit field This reduces residency of compiler quite a bit on some programs. Example stats when building T10370: Before: 2,871,242,832 bytes allocated in the heap 4,693,328,008 bytes copied during GC 33,941,448 bytes maximum residency (276 sample(s)) 375,976 bytes maximum slop 83 MiB total memory in use (0 MB lost due to fragmentation) After: 2,858,897,344 bytes allocated in the heap 4,629,255,440 bytes copied during GC 32,616,624 bytes maximum residency (278 sample(s)) 314,400 bytes maximum slop 80 MiB total memory in use (0 MB lost due to fragmentation) So -3.9% residency, -1.3% bytes copied and -0.4% allocations. Fixes #17497 Metric Decrease: T9233 T9675 - - - - - 1 changed file: - compiler/GHC/Types/Id/Info.hs Changes: ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -10,6 +10,7 @@ Haskell. [WDP 94/11]) {-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE BinaryLiterals #-} {-# OPTIONS_GHC -Wno-incomplete-record-updates #-} @@ -105,6 +106,9 @@ import GHC.Types.Demand import GHC.Types.Cpr import GHC.Utils.Misc +import Data.Word +import Data.Bits + -- infixl so you can say (id `set` a `set` b) infixl 1 `setRuleInfo`, `setArityInfo`, @@ -242,19 +246,11 @@ pprIdDetails other = brackets (pp other) -- too big. data IdInfo = IdInfo { - arityInfo :: !ArityInfo, - -- ^ 'Id' arity, as computed by 'GHC.Core.Arity'. Specifies how many - -- arguments this 'Id' has to be applied to before it doesn any - -- meaningful work. ruleInfo :: RuleInfo, -- ^ Specialisations of the 'Id's function which exist. -- See Note [Specialisations and RULES in IdInfo] unfoldingInfo :: Unfolding, -- ^ The 'Id's unfolding - cafInfo :: CafInfo, - -- ^ 'Id' CAF info - oneShotInfo :: OneShotInfo, - -- ^ Info about a lambda-bound variable, if the 'Id' is one inlinePragInfo :: InlinePragma, -- ^ Any inline pragma attached to the 'Id' occInfo :: OccInfo, @@ -267,14 +263,103 @@ data IdInfo -- freshly allocated constructor. demandInfo :: Demand, -- ^ ID demand information - callArityInfo :: !ArityInfo, - -- ^ How this is called. This is the number of arguments to which a - -- binding can be eta-expanded without losing any sharing. - -- n <=> all calls have at least n arguments - levityInfo :: LevityInfo - -- ^ when applied, will this Id ever have a levity-polymorphic type? + bitfield :: {-# UNPACK #-} !BitField + -- ^ Bitfield packs CafInfo, OneShotInfo, arity info, LevityInfo, and + -- call arity info in one 64-bit word. Packing these fields reduces size + -- of `IdInfo` from 12 words to 7 words and reduces residency by almost + -- 4% in some programs. + -- + -- See documentation of the getters for what these packed fields mean. } +-- | Encodes arities, OneShotInfo, CafInfo and LevityInfo. +-- From least-significant to most-significant bits: +-- +-- - Bit 0 (1): OneShotInfo +-- - Bit 1 (1): CafInfo +-- - Bit 2 (1): LevityInfo +-- - Bits 3-32(30): Call Arity info +-- - Bits 33-62(30): Arity info +-- +newtype BitField = BitField Word64 + +emptyBitField :: BitField +emptyBitField = BitField 0 + +bitfieldGetOneShotInfo :: BitField -> OneShotInfo +bitfieldGetOneShotInfo (BitField bits) = + if testBit bits 0 then OneShotLam else NoOneShotInfo + +bitfieldGetCafInfo :: BitField -> CafInfo +bitfieldGetCafInfo (BitField bits) = + if testBit bits 1 then NoCafRefs else MayHaveCafRefs + +bitfieldGetLevityInfo :: BitField -> LevityInfo +bitfieldGetLevityInfo (BitField bits) = + if testBit bits 2 then NeverLevityPolymorphic else NoLevityInfo + +bitfieldGetCallArityInfo :: BitField -> ArityInfo +bitfieldGetCallArityInfo (BitField bits) = + fromIntegral (bits `shiftR` 3) .&. ((1 `shiftL` 30) - 1) + +bitfieldGetArityInfo :: BitField -> ArityInfo +bitfieldGetArityInfo (BitField bits) = + fromIntegral (bits `shiftR` 33) + +bitfieldSetOneShotInfo :: OneShotInfo -> BitField -> BitField +bitfieldSetOneShotInfo info (BitField bits) = + case info of + NoOneShotInfo -> BitField (clearBit bits 0) + OneShotLam -> BitField (setBit bits 0) + +bitfieldSetCafInfo :: CafInfo -> BitField -> BitField +bitfieldSetCafInfo info (BitField bits) = + case info of + MayHaveCafRefs -> BitField (clearBit bits 1) + NoCafRefs -> BitField (setBit bits 1) + +bitfieldSetLevityInfo :: LevityInfo -> BitField -> BitField +bitfieldSetLevityInfo info (BitField bits) = + case info of + NoLevityInfo -> BitField (clearBit bits 2) + NeverLevityPolymorphic -> BitField (setBit bits 2) + +bitfieldSetCallArityInfo :: ArityInfo -> BitField -> BitField +bitfieldSetCallArityInfo info bf@(BitField bits) = + ASSERT(info < 2^(30 :: Int) - 1) + bitfieldSetArityInfo (bitfieldGetArityInfo bf) $ + BitField ((fromIntegral info `shiftL` 3) .|. (bits .&. 0b111)) + +bitfieldSetArityInfo :: ArityInfo -> BitField -> BitField +bitfieldSetArityInfo info (BitField bits) = + ASSERT(info < 2^(30 :: Int) - 1) + BitField ((fromIntegral info `shiftL` 33) .|. (bits .&. ((1 `shiftL` 33) - 1))) + +-- Getters + +-- | When applied, will this Id ever have a levity-polymorphic type? +levityInfo :: IdInfo -> LevityInfo +levityInfo = bitfieldGetLevityInfo . bitfield + +-- | Info about a lambda-bound variable, if the 'Id' is one +oneShotInfo :: IdInfo -> OneShotInfo +oneShotInfo = bitfieldGetOneShotInfo . bitfield + +-- | 'Id' arity, as computed by 'GHC.Core.Arity'. Specifies how many arguments +-- this 'Id' has to be applied to before it doesn any meaningful work. +arityInfo :: IdInfo -> ArityInfo +arityInfo = bitfieldGetArityInfo . bitfield + +-- | 'Id' CAF info +cafInfo :: IdInfo -> CafInfo +cafInfo = bitfieldGetCafInfo . bitfield + +-- | How this is called. This is the number of arguments to which a binding can +-- be eta-expanded without losing any sharing. n <=> all calls have at least n +-- arguments +callArityInfo :: IdInfo -> ArityInfo +callArityInfo = bitfieldGetCallArityInfo . bitfield + -- Setters setRuleInfo :: IdInfo -> RuleInfo -> IdInfo @@ -294,14 +379,20 @@ setUnfoldingInfo info uf info { unfoldingInfo = uf } setArityInfo :: IdInfo -> ArityInfo -> IdInfo -setArityInfo info ar = info { arityInfo = ar } +setArityInfo info ar = + info { bitfield = bitfieldSetArityInfo ar (bitfield info) } + setCallArityInfo :: IdInfo -> ArityInfo -> IdInfo -setCallArityInfo info ar = info { callArityInfo = ar } +setCallArityInfo info ar = + info { bitfield = bitfieldSetCallArityInfo ar (bitfield info) } + setCafInfo :: IdInfo -> CafInfo -> IdInfo -setCafInfo info caf = info { cafInfo = caf } +setCafInfo info caf = + info { bitfield = bitfieldSetCafInfo caf (bitfield info) } setOneShotInfo :: IdInfo -> OneShotInfo -> IdInfo -setOneShotInfo info lb = {-lb `seq`-} info { oneShotInfo = lb } +setOneShotInfo info lb = + info { bitfield = bitfieldSetOneShotInfo lb (bitfield info) } setDemandInfo :: IdInfo -> Demand -> IdInfo setDemandInfo info dd = dd `seq` info { demandInfo = dd } @@ -316,18 +407,19 @@ setCprInfo info cpr = cpr `seq` info { cprInfo = cpr } vanillaIdInfo :: IdInfo vanillaIdInfo = IdInfo { - cafInfo = vanillaCafInfo, - arityInfo = unknownArity, ruleInfo = emptyRuleInfo, unfoldingInfo = noUnfolding, - oneShotInfo = NoOneShotInfo, inlinePragInfo = defaultInlinePragma, occInfo = noOccInfo, demandInfo = topDmd, strictnessInfo = nopSig, cprInfo = topCprSig, - callArityInfo = unknownArity, - levityInfo = NoLevityInfo + bitfield = bitfieldSetCafInfo vanillaCafInfo $ + bitfieldSetArityInfo unknownArity $ + bitfieldSetCallArityInfo unknownArity $ + bitfieldSetOneShotInfo NoOneShotInfo $ + bitfieldSetLevityInfo NoLevityInfo $ + emptyBitField } -- | More informative 'IdInfo' we can use when we know the 'Id' has no CAF references @@ -638,12 +730,12 @@ instance Outputable LevityInfo where setNeverLevPoly :: HasDebugCallStack => IdInfo -> Type -> IdInfo setNeverLevPoly info ty = ASSERT2( not (resultIsLevPoly ty), ppr ty ) - info { levityInfo = NeverLevityPolymorphic } + info { bitfield = bitfieldSetLevityInfo NeverLevityPolymorphic (bitfield info) } setLevityInfoWithType :: IdInfo -> Type -> IdInfo setLevityInfoWithType info ty | not (resultIsLevPoly ty) - = info { levityInfo = NeverLevityPolymorphic } + = info { bitfield = bitfieldSetLevityInfo NeverLevityPolymorphic (bitfield info) } | otherwise = info View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a03da9bfcf130bec616e0f77bbefbf62022753de -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a03da9bfcf130bec616e0f77bbefbf62022753de You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 13 06:04:03 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 13 May 2020 02:04:03 -0400 Subject: [Git][ghc/ghc][master] 2 commits: get-win32-tarballs: Fix base URL Message-ID: <5ebb8dd370b31_61673f81a3bd711c1099918c@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 670c3e5c by Ben Gamari at 2020-05-13T02:03:54-04:00 get-win32-tarballs: Fix base URL Revert a change previously made for testing purposes. - - - - - 8ad8dc41 by Ben Gamari at 2020-05-13T02:03:54-04:00 get-win32-tarballs: Improve diagnostics output - - - - - 1 changed file: - mk/get-win32-tarballs.py Changes: ===================================== mk/get-win32-tarballs.py ===================================== @@ -5,10 +5,10 @@ from pathlib import Path import urllib.request import subprocess import argparse +from sys import stderr TARBALL_VERSION = '0.1' BASE_URL = "https://downloads.haskell.org/ghc/mingw/{}".format(TARBALL_VERSION) -BASE_URL = "http://home.smart-cactus.org/~ben/ghc/mingw/{}".format(TARBALL_VERSION) DEST = Path('ghc-tarballs/mingw-w64') ARCHS = ['i686', 'x86_64', 'sources'] @@ -19,11 +19,13 @@ def file_url(arch: str, fname: str) -> str: fname=fname) def fetch(url: str, dest: Path): - print('Fetching', url, '=>', dest) + print('Fetching', url, '=>', dest, file=stderr) urllib.request.urlretrieve(url, dest) def fetch_arch(arch: str): - req = urllib.request.urlopen(file_url(arch, 'MANIFEST')) + manifest_url = file_url(arch, 'MANIFEST') + print('Fetching', manifest_url, file=stderr) + req = urllib.request.urlopen(manifest_url) files = req.read().decode('UTF-8').split('\n') d = DEST / arch if not d.is_dir(): @@ -36,6 +38,9 @@ def fetch_arch(arch: str): verify(arch) def verify(arch: str): + if not Path(DEST / arch / "SHA256SUMS").is_file(): + raise IOError("SHA256SUMS doesn't exist; have you fetched?") + cmd = ['sha256sum', '--quiet', '--check', '--ignore-missing', 'SHA256SUMS'] subprocess.check_call(cmd, cwd=DEST / arch) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a03da9bfcf130bec616e0f77bbefbf62022753de...8ad8dc412f0b070df63e42e68468df08ac0f559a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a03da9bfcf130bec616e0f77bbefbf62022753de...8ad8dc412f0b070df63e42e68468df08ac0f559a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 13 06:04:42 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 13 May 2020 02:04:42 -0400 Subject: [Git][ghc/ghc][master] docs: Add examples for Data.Semigroup.Arg{Min,Max} Message-ID: <5ebb8dfae0658_616711a31edc1100222a@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 8c0740b7 by Simon Jakobi at 2020-05-13T02:04:33-04:00 docs: Add examples for Data.Semigroup.Arg{Min,Max} Context: #17153 - - - - - 1 changed file: - libraries/base/Data/Semigroup.hs Changes: ===================================== libraries/base/Data/Semigroup.hs ===================================== @@ -302,7 +302,14 @@ data Arg a b = Arg , Generic1 -- ^ @since 4.9.0.0 ) +-- | +-- >>> Min (Arg 0 ()) <> Min (Arg 1 ()) +-- Min {getMin = Arg 0 ()} type ArgMin a b = Min (Arg a b) + +-- | +-- >>> Max (Arg 0 ()) <> Max (Arg 1 ()) +-- Max {getMax = Arg 1 ()} type ArgMax a b = Max (Arg a b) -- | @since 4.9.0.0 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8c0740b7c38184378aedefdca8fff35707c80de9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8c0740b7c38184378aedefdca8fff35707c80de9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 13 06:05:21 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 13 May 2020 02:05:21 -0400 Subject: [Git][ghc/ghc][master] Add few cleanups of the CAF logic Message-ID: <5ebb8e218904a_6167119ebbd01100451d@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: cb22348f by Ben Gamari at 2020-05-13T02:05:11-04:00 Add few cleanups of the CAF logic Give the NameSet of non-CAFfy names a proper newtype to distinguish it from all of the other NameSets floating about. - - - - - 5 changed files: - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/UpdateCafInfos.hs - compiler/GHC/Types/Name/Set.hs Changes: ===================================== compiler/GHC/Cmm/Info/Build.hs ===================================== @@ -459,7 +459,7 @@ type CAFSet = Set CAFLabel type CAFEnv = LabelMap CAFSet mkCAFLabel :: CLabel -> CAFLabel -mkCAFLabel lbl = CAFLabel $! toClosureLbl lbl +mkCAFLabel lbl = CAFLabel (toClosureLbl lbl) -- This is a label that we can put in an SRT. It *must* be a closure label, -- pointing to either a FUN_STATIC, THUNK_STATIC, or CONSTR. @@ -736,10 +736,11 @@ getStaticFuns decls = type SRTMap = Map CAFLabel (Maybe SRTEntry) --- | Given SRTMap of a module returns the set of non-CAFFY names in the module. --- Any Names not in the set are CAFFY. -srtMapNonCAFs :: SRTMap -> NameSet -srtMapNonCAFs srtMap = mkNameSet (mapMaybe get_name (Map.toList srtMap)) +-- | Given 'SRTMap' of a module, returns the set of non-CAFFY names in the +-- module. Any 'Name's not in the set are CAFFY. +srtMapNonCAFs :: SRTMap -> NonCaffySet +srtMapNonCAFs srtMap = + NonCaffySet $ mkNameSet (mapMaybe get_name (Map.toList srtMap)) where get_name (CAFLabel l, Nothing) = hasHaskellName l get_name (_l, Just _srt_entry) = Nothing ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -1384,7 +1384,7 @@ hscWriteIface dflags iface no_change mod_location = do -- | Compile to hard-code. hscGenHardCode :: HscEnv -> CgGuts -> ModLocation -> FilePath - -> IO (FilePath, Maybe FilePath, [(ForeignSrcLang, FilePath)], NameSet) + -> IO (FilePath, Maybe FilePath, [(ForeignSrcLang, FilePath)], NonCaffySet) -- ^ @Just f@ <=> _stub.c is f hscGenHardCode hsc_env cgguts location output_filename = do let CgGuts{ -- This is the last use of the ModGuts in a compilation. @@ -1541,7 +1541,7 @@ doCodeGen :: HscEnv -> Module -> [TyCon] -> CollectedCCs -> [StgTopBinding] -> HpcInfo - -> IO (Stream IO CmmGroupSRTs NameSet) + -> IO (Stream IO CmmGroupSRTs NonCaffySet) -- Note we produce a 'Stream' of CmmGroups, so that the -- backend can be run incrementally. Otherwise it generates all -- the C-- up front, which has a significant space cost. ===================================== compiler/GHC/Iface/Make.hs ===================================== @@ -100,7 +100,7 @@ mkPartialIface hsc_env mod_details -- | Fully instantiate a interface -- Adds fingerprints and potentially code generator produced information. -mkFullIface :: HscEnv -> PartialModIface -> Maybe NameSet -> IO ModIface +mkFullIface :: HscEnv -> PartialModIface -> Maybe NonCaffySet -> IO ModIface mkFullIface hsc_env partial_iface mb_non_cafs = do let decls | gopt Opt_OmitInterfacePragmas (hsc_dflags hsc_env) @@ -117,9 +117,9 @@ mkFullIface hsc_env partial_iface mb_non_cafs = do return full_iface -updateDeclCafInfos :: [IfaceDecl] -> Maybe NameSet -> [IfaceDecl] +updateDeclCafInfos :: [IfaceDecl] -> Maybe NonCaffySet -> [IfaceDecl] updateDeclCafInfos decls Nothing = decls -updateDeclCafInfos decls (Just non_cafs) = map update_decl decls +updateDeclCafInfos decls (Just (NonCaffySet non_cafs)) = map update_decl decls where update_decl decl | IfaceId nm ty details infos <- decl ===================================== compiler/GHC/Iface/UpdateCafInfos.hs ===================================== @@ -23,7 +23,7 @@ import GHC.Utils.Outputable -- | Update CafInfos of all occurences (in rules, unfoldings, class instances) updateModDetailsCafInfos :: DynFlags - -> NameSet -- ^ Non-CAFFY names in the module. Names not in this set are CAFFY. + -> NonCaffySet -- ^ Non-CAFFY names in the module. Names not in this set are CAFFY. -> ModDetails -- ^ ModDetails to update -> ModDetails @@ -31,7 +31,7 @@ updateModDetailsCafInfos dflags _ mod_details | gopt Opt_OmitInterfacePragmas dflags = mod_details -updateModDetailsCafInfos _ non_cafs mod_details = +updateModDetailsCafInfos _ (NonCaffySet non_cafs) mod_details = {- pprTrace "updateModDetailsCafInfos" (text "non_cafs:" <+> ppr non_cafs) $ -} let ModDetails{ md_types = type_env -- for unfoldings ===================================== compiler/GHC/Types/Name/Set.hs ===================================== @@ -4,6 +4,7 @@ -} {-# LANGUAGE CPP #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} module GHC.Types.Name.Set ( -- * Names set type NameSet, @@ -28,7 +29,10 @@ module GHC.Types.Name.Set ( -- ** Manipulating defs and uses emptyDUs, usesOnly, mkDUs, plusDU, - findUses, duDefs, duUses, allUses + findUses, duDefs, duUses, allUses, + + -- * Non-CAFfy names + NonCaffySet(..) ) where #include "HsVersions.h" @@ -213,3 +217,8 @@ findUses dus uses = rhs_uses `unionNameSet` uses | otherwise -- No def is used = uses + +-- | 'Id's which have no CAF references. This is a result of analysis of C--. +-- It is always safe to use an empty 'NonCaffySet'. TODO Refer to Note. +newtype NonCaffySet = NonCaffySet NameSet + deriving (Semigroup, Monoid) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cb22348fb92411c66f1a39fe2c34b167a9926bc7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cb22348fb92411c66f1a39fe2c34b167a9926bc7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 13 06:06:01 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 13 May 2020 02:06:01 -0400 Subject: [Git][ghc/ghc][master] fix printf warning when using with ghc with clang on mingw Message-ID: <5ebb8e49bf527_61673f81a3bd711c1100788f@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 90e38b81 by Emeka Nkurumeh at 2020-05-13T02:05:51-04:00 fix printf warning when using with ghc with clang on mingw - - - - - 1 changed file: - includes/rts/Messages.h Changes: ===================================== includes/rts/Messages.h ===================================== @@ -18,7 +18,7 @@ #include -#if defined(mingw32_HOST_OS) +#if defined(mingw32_HOST_OS) && !defined(__clang__) /* On Win64, if we say "printf" then gcc thinks we are going to use MS format specifiers like %I64d rather than %llu */ #define PRINTF gnu_printf View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/90e38b8139c10854280da56664c040120256bacc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/90e38b8139c10854280da56664c040120256bacc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 13 06:06:42 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 13 May 2020 02:06:42 -0400 Subject: [Git][ghc/ghc][master] CprAnal: Don't attach CPR sigs to expandable bindings (#18154) Message-ID: <5ebb8e72d5062_6167119f856011012190@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 86d8ac22 by Sebastian Graf at 2020-05-13T02:06:29-04:00 CprAnal: Don't attach CPR sigs to expandable bindings (#18154) Instead, look through expandable unfoldings in `cprTransform`. See the new Note [CPR for expandable unfoldings]: ``` Long static data structures (whether top-level or not) like xs = x1 : xs1 xs1 = x2 : xs2 xs2 = x3 : xs3 should not get CPR signatures, because they * Never get WW'd, so their CPR signature should be irrelevant after analysis (in fact the signature might even be harmful for that reason) * Would need to be inlined/expanded to see their constructed product * Recording CPR on them blows up interface file sizes and is redundant with their unfolding. In case of Nested CPR, this blow-up can be quadratic! But we can't just stop giving DataCon application bindings the CPR property, for example fac 0 = 1 fac n = n * fac (n-1) fac certainly has the CPR property and should be WW'd! But FloatOut will transform the first clause to lvl = 1 fac 0 = lvl If lvl doesn't have the CPR property, fac won't either. But lvl doesn't have a CPR signature to extrapolate into a CPR transformer ('cprTransform'). So instead we keep on cprAnal'ing through *expandable* unfoldings for these arity 0 bindings via 'cprExpandUnfolding_maybe'. In practice, GHC generates a lot of (nested) TyCon and KindRep bindings, one for each data declaration. It's wasteful to attach CPR signatures to each of them (and intractable in case of Nested CPR). ``` Fixes #18154. - - - - - 29 changed files: - compiler/GHC/Core/Opt/CprAnal.hs - testsuite/tests/numeric/should_compile/T14170.stdout - testsuite/tests/numeric/should_compile/T14465.stdout - testsuite/tests/numeric/should_compile/T7116.stdout - testsuite/tests/simplCore/should_compile/T13143.stderr - testsuite/tests/simplCore/should_compile/T13543.stderr - testsuite/tests/simplCore/should_compile/T18013.stderr - testsuite/tests/simplCore/should_compile/T3717.stderr - testsuite/tests/simplCore/should_compile/T3772.stdout - testsuite/tests/simplCore/should_compile/T4908.stderr - testsuite/tests/simplCore/should_compile/T4930.stderr - testsuite/tests/simplCore/should_compile/T7360.stderr - testsuite/tests/simplCore/should_compile/noinline01.stderr - testsuite/tests/simplCore/should_compile/par01.stderr - testsuite/tests/simplCore/should_compile/spec-inline.stderr - testsuite/tests/stranal/should_compile/T10694.stderr - testsuite/tests/stranal/sigs/BottomFromInnerLambda.stderr - testsuite/tests/stranal/sigs/CaseBinderCPR.stderr - testsuite/tests/stranal/sigs/DmdAnalGADTs.hs - testsuite/tests/stranal/sigs/DmdAnalGADTs.stderr - testsuite/tests/stranal/sigs/HyperStrUse.stderr - testsuite/tests/stranal/sigs/NewtypeArity.stderr - testsuite/tests/stranal/sigs/StrAnalExample.stderr - testsuite/tests/stranal/sigs/T12370.stderr - testsuite/tests/stranal/sigs/T17932.stderr - testsuite/tests/stranal/sigs/T5075.stderr - testsuite/tests/stranal/sigs/T8569.stderr - testsuite/tests/stranal/sigs/T8598.stderr - testsuite/tests/stranal/sigs/UnsatFun.stderr Changes: ===================================== compiler/GHC/Core/Opt/CprAnal.hs ===================================== @@ -21,7 +21,6 @@ import GHC.Core.Seq import GHC.Utils.Outputable import GHC.Types.Var.Env import GHC.Types.Basic -import Data.List import GHC.Core.DataCon import GHC.Types.Id import GHC.Types.Id.Info @@ -34,6 +33,9 @@ import GHC.Utils.Misc import GHC.Utils.Error ( dumpIfSet_dyn, DumpFormat (..) ) import GHC.Data.Maybe ( isJust, isNothing ) +import Control.Monad ( guard ) +import Data.List + {- Note [Constructed Product Result] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The goal of Constructed Product Result analysis is to identify functions that @@ -231,9 +233,14 @@ cprTransform env id sig where sig - | isGlobalId id -- imported function or data con worker + -- See Note [CPR for expandable unfoldings] + | Just rhs <- cprExpandUnfolding_maybe id + = fst $ cprAnal env rhs + -- Imported function or data con worker + | isGlobalId id = getCprSig (idCprInfo id) - | Just sig <- lookupSigEnv env id -- local let-bound + -- Local let-bound + | Just sig <- lookupSigEnv env id = getCprSig sig | otherwise = topCprType @@ -303,6 +310,8 @@ cprAnalBind top_lvl env id rhs | stays_thunk = trimCprTy rhs_ty -- See Note [CPR for sum types] | returns_sum = trimCprTy rhs_ty + -- See Note [CPR for expandable unfoldings] + | will_expand = topCprType | otherwise = rhs_ty -- See Note [Arity trimming for CPR signatures] sig = mkCprSigForArity (idArity id) rhs_ty' @@ -316,6 +325,15 @@ cprAnalBind top_lvl env id rhs (_, ret_ty) = splitPiTys (idType id) not_a_prod = isNothing (deepSplitProductType_maybe (ae_fam_envs env) ret_ty) returns_sum = not (isTopLevel top_lvl) && not_a_prod + -- See Note [CPR for expandable unfoldings] + will_expand = isJust (cprExpandUnfolding_maybe id) + +cprExpandUnfolding_maybe :: Id -> Maybe CoreExpr +cprExpandUnfolding_maybe id = do + guard (idArity id == 0) + -- There are only phase 0 Simplifier runs after CPR analysis + guard (isActiveIn 0 (idInlineActivation id)) + expandUnfolding_maybe (idUnfolding id) {- Note [Arity trimming for CPR signatures] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -626,6 +644,48 @@ fac won't have the CPR property here when we trim every thunk! But the assumption is that error cases are rarely entered and we are diverging anyway, so WW doesn't hurt. +Should we also trim CPR on DataCon application bindings? +See Note [CPR for expandable unfoldings]! + +Note [CPR for expandable unfoldings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Long static data structures (whether top-level or not) like + + xs = x1 : xs1 + xs1 = x2 : xs2 + xs2 = x3 : xs3 + +should not get CPR signatures, because they + + * Never get WW'd, so their CPR signature should be irrelevant after analysis + (in fact the signature might even be harmful for that reason) + * Would need to be inlined/expanded to see their constructed product + * Recording CPR on them blows up interface file sizes and is redundant with + their unfolding. In case of Nested CPR, this blow-up can be quadratic! + +But we can't just stop giving DataCon application bindings the CPR property, +for example + + fac 0 = 1 + fac n = n * fac (n-1) + +fac certainly has the CPR property and should be WW'd! But FloatOut will +transform the first clause to + + lvl = 1 + fac 0 = lvl + +If lvl doesn't have the CPR property, fac won't either. But lvl doesn't have a +CPR signature to extrapolate into a CPR transformer ('cprTransform'). So +instead we keep on cprAnal'ing through *expandable* unfoldings for these arity +0 bindings via 'cprExpandUnfolding_maybe'. + +In practice, GHC generates a lot of (nested) TyCon and KindRep bindings, one +for each data declaration. It's wasteful to attach CPR signatures to each of +them (and intractable in case of Nested CPR). + +Tracked by #18154. + Note [CPR examples] ~~~~~~~~~~~~~~~~~~~~ Here are some examples (stranal/should_compile/T10482a) of the ===================================== testsuite/tests/numeric/should_compile/T14170.stdout ===================================== @@ -13,7 +13,6 @@ NatVal.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} NatVal.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] NatVal.$trModule3 = GHC.Types.TrNameS NatVal.$trModule4 @@ -28,7 +27,6 @@ NatVal.$trModule2 = "NatVal"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} NatVal.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] NatVal.$trModule1 = GHC.Types.TrNameS NatVal.$trModule2 @@ -36,7 +34,6 @@ NatVal.$trModule1 = GHC.Types.TrNameS NatVal.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} NatVal.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] NatVal.$trModule ===================================== testsuite/tests/numeric/should_compile/T14465.stdout ===================================== @@ -20,7 +20,6 @@ M.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} M.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] M.$trModule3 = GHC.Types.TrNameS M.$trModule4 @@ -35,7 +34,6 @@ M.$trModule2 = "M"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} M.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] M.$trModule1 = GHC.Types.TrNameS M.$trModule2 @@ -43,7 +41,6 @@ M.$trModule1 = GHC.Types.TrNameS M.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} M.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] M.$trModule = GHC.Types.Module M.$trModule3 M.$trModule1 ===================================== testsuite/tests/numeric/should_compile/T7116.stdout ===================================== @@ -13,7 +13,6 @@ T7116.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7116.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7116.$trModule3 = GHC.Types.TrNameS T7116.$trModule4 @@ -28,7 +27,6 @@ T7116.$trModule2 = "T7116"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7116.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7116.$trModule1 = GHC.Types.TrNameS T7116.$trModule2 @@ -36,7 +34,6 @@ T7116.$trModule1 = GHC.Types.TrNameS T7116.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T7116.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T7116.$trModule ===================================== testsuite/tests/simplCore/should_compile/T13143.stderr ===================================== @@ -33,7 +33,6 @@ T13143.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T13143.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T13143.$trModule3 = GHC.Types.TrNameS T13143.$trModule4 @@ -48,7 +47,6 @@ T13143.$trModule2 = "T13143"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T13143.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T13143.$trModule1 = GHC.Types.TrNameS T13143.$trModule2 @@ -56,7 +54,6 @@ T13143.$trModule1 = GHC.Types.TrNameS T13143.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T13143.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T13143.$trModule ===================================== testsuite/tests/simplCore/should_compile/T13543.stderr ===================================== @@ -7,7 +7,7 @@ Foo.g: ==================== Cpr signatures ==================== -Foo.$trModule: m1 +Foo.$trModule: Foo.f: m1 Foo.g: m1 ===================================== testsuite/tests/simplCore/should_compile/T18013.stderr ===================================== @@ -177,7 +177,6 @@ T18013.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T18013.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T18013.$trModule3 = GHC.Types.TrNameS T18013.$trModule4 @@ -192,7 +191,6 @@ T18013.$trModule2 = "T18013"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T18013.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T18013.$trModule1 = GHC.Types.TrNameS T18013.$trModule2 @@ -200,7 +198,6 @@ T18013.$trModule1 = GHC.Types.TrNameS T18013.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T18013.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T18013.$trModule ===================================== testsuite/tests/simplCore/should_compile/T3717.stderr ===================================== @@ -13,7 +13,6 @@ T3717.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T3717.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T3717.$trModule3 = GHC.Types.TrNameS T3717.$trModule4 @@ -28,7 +27,6 @@ T3717.$trModule2 = "T3717"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T3717.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T3717.$trModule1 = GHC.Types.TrNameS T3717.$trModule2 @@ -36,7 +34,6 @@ T3717.$trModule1 = GHC.Types.TrNameS T3717.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T3717.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T3717.$trModule ===================================== testsuite/tests/simplCore/should_compile/T3772.stdout ===================================== @@ -13,7 +13,6 @@ T3772.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T3772.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T3772.$trModule3 = GHC.Types.TrNameS T3772.$trModule4 @@ -28,7 +27,6 @@ T3772.$trModule2 = "T3772"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T3772.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T3772.$trModule1 = GHC.Types.TrNameS T3772.$trModule2 @@ -36,7 +34,6 @@ T3772.$trModule1 = GHC.Types.TrNameS T3772.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T3772.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T3772.$trModule ===================================== testsuite/tests/simplCore/should_compile/T4908.stderr ===================================== @@ -13,7 +13,6 @@ T4908.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T4908.$trModule3 :: TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T4908.$trModule3 = GHC.Types.TrNameS T4908.$trModule4 @@ -28,7 +27,6 @@ T4908.$trModule2 = "T4908"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T4908.$trModule1 :: TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T4908.$trModule1 = GHC.Types.TrNameS T4908.$trModule2 @@ -36,7 +34,6 @@ T4908.$trModule1 = GHC.Types.TrNameS T4908.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T4908.$trModule :: Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T4908.$trModule ===================================== testsuite/tests/simplCore/should_compile/T4930.stderr ===================================== @@ -13,7 +13,6 @@ T4930.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T4930.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T4930.$trModule3 = GHC.Types.TrNameS T4930.$trModule4 @@ -28,7 +27,6 @@ T4930.$trModule2 = "T4930"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T4930.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T4930.$trModule1 = GHC.Types.TrNameS T4930.$trModule2 @@ -36,7 +34,6 @@ T4930.$trModule1 = GHC.Types.TrNameS T4930.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T4930.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T4930.$trModule ===================================== testsuite/tests/simplCore/should_compile/T7360.stderr ===================================== @@ -64,7 +64,6 @@ T7360.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$trModule3 = GHC.Types.TrNameS T7360.$trModule4 @@ -79,7 +78,6 @@ T7360.$trModule2 = "T7360"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$trModule1 = GHC.Types.TrNameS T7360.$trModule2 @@ -87,7 +85,6 @@ T7360.$trModule1 = GHC.Types.TrNameS T7360.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} T7360.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] T7360.$trModule @@ -110,7 +107,6 @@ T7360.$tcFoo2 = "Foo"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$tcFoo1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$tcFoo1 = GHC.Types.TrNameS T7360.$tcFoo2 @@ -118,7 +114,6 @@ T7360.$tcFoo1 = GHC.Types.TrNameS T7360.$tcFoo2 -- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} T7360.$tcFoo :: GHC.Types.TyCon [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 70}] T7360.$tcFoo @@ -147,7 +142,6 @@ T7360.$tc'Foo6 = "'Foo1"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo5 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$tc'Foo5 = GHC.Types.TrNameS T7360.$tc'Foo6 @@ -155,7 +149,6 @@ T7360.$tc'Foo5 = GHC.Types.TrNameS T7360.$tc'Foo6 -- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo1 :: GHC.Types.TyCon [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 70}] T7360.$tc'Foo1 @@ -177,7 +170,6 @@ T7360.$tc'Foo8 = "'Foo2"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo7 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$tc'Foo7 = GHC.Types.TrNameS T7360.$tc'Foo8 @@ -185,7 +177,6 @@ T7360.$tc'Foo7 = GHC.Types.TrNameS T7360.$tc'Foo8 -- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo2 :: GHC.Types.TyCon [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 70}] T7360.$tc'Foo2 @@ -212,7 +203,6 @@ T7360.$tc'Foo11 = "'Foo3"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo10 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T7360.$tc'Foo10 = GHC.Types.TrNameS T7360.$tc'Foo11 @@ -220,7 +210,6 @@ T7360.$tc'Foo10 = GHC.Types.TrNameS T7360.$tc'Foo11 -- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} T7360.$tc'Foo3 :: GHC.Types.TyCon [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 70}] T7360.$tc'Foo3 ===================================== testsuite/tests/simplCore/should_compile/noinline01.stderr ===================================== @@ -14,7 +14,7 @@ Noinline01.$trModule4 :: GHC.Prim.Addr# "main"#; Noinline01.$trModule3 :: GHC.Types.TrName -[GblId, Cpr=m1, Unf=OtherCon []] = +[GblId, Unf=OtherCon []] = CCS_DONT_CARE GHC.Types.TrNameS! [Noinline01.$trModule4]; Noinline01.$trModule2 :: GHC.Prim.Addr# @@ -22,11 +22,11 @@ Noinline01.$trModule2 :: GHC.Prim.Addr# "Noinline01"#; Noinline01.$trModule1 :: GHC.Types.TrName -[GblId, Cpr=m1, Unf=OtherCon []] = +[GblId, Unf=OtherCon []] = CCS_DONT_CARE GHC.Types.TrNameS! [Noinline01.$trModule2]; Noinline01.$trModule :: GHC.Types.Module -[GblId, Cpr=m1, Unf=OtherCon []] = +[GblId, Unf=OtherCon []] = CCS_DONT_CARE GHC.Types.Module! [Noinline01.$trModule3 Noinline01.$trModule1]; ===================================== testsuite/tests/simplCore/should_compile/par01.stderr ===================================== @@ -21,7 +21,7 @@ Par01.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Par01.$trModule3 :: GHC.Types.TrName -[GblId, Cpr=m1, Unf=OtherCon []] +[GblId, Unf=OtherCon []] Par01.$trModule3 = GHC.Types.TrNameS Par01.$trModule4 -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} @@ -31,12 +31,12 @@ Par01.$trModule2 = "Par01"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Par01.$trModule1 :: GHC.Types.TrName -[GblId, Cpr=m1, Unf=OtherCon []] +[GblId, Unf=OtherCon []] Par01.$trModule1 = GHC.Types.TrNameS Par01.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} Par01.$trModule :: GHC.Types.Module -[GblId, Cpr=m1, Unf=OtherCon []] +[GblId, Unf=OtherCon []] Par01.$trModule = GHC.Types.Module Par01.$trModule3 Par01.$trModule1 ===================================== testsuite/tests/simplCore/should_compile/spec-inline.stderr ===================================== @@ -13,7 +13,6 @@ Roman.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Roman.$trModule3 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] Roman.$trModule3 = GHC.Types.TrNameS Roman.$trModule4 @@ -28,7 +27,6 @@ Roman.$trModule2 = "Roman"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Roman.$trModule1 :: GHC.Types.TrName [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] Roman.$trModule1 = GHC.Types.TrNameS Roman.$trModule2 @@ -36,7 +34,6 @@ Roman.$trModule1 = GHC.Types.TrNameS Roman.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} Roman.$trModule :: GHC.Types.Module [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] Roman.$trModule @@ -132,7 +129,6 @@ Roman.foo_go -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} Roman.foo2 :: Int [GblId, - Cpr=m1, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] Roman.foo2 = GHC.Types.I# 6# @@ -140,7 +136,6 @@ Roman.foo2 = GHC.Types.I# 6# -- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0} Roman.foo1 :: Maybe Int [GblId, - Cpr=m2, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] Roman.foo1 = GHC.Maybe.Just @Int Roman.foo2 ===================================== testsuite/tests/stranal/should_compile/T10694.stderr ===================================== @@ -6,26 +6,26 @@ Result size of Tidy Core = {terms: 74, types: 65, coercions: 0, joins: 0/4} T10694.$wpm [InlPrag=NOINLINE] :: Int -> Int -> (# Int, Int #) [GblId, Arity=2, Str=, Unf=OtherCon []] T10694.$wpm - = \ (w_s1vj :: Int) (w1_s1vk :: Int) -> + = \ (w_s1v1 :: Int) (w1_s1v2 :: Int) -> let { - l_s1uR :: Int + l_s1uz :: Int [LclId] - l_s1uR - = case w_s1vj of { GHC.Types.I# x_aJ9 -> case w1_s1vk of { GHC.Types.I# y_aJc -> GHC.Types.I# (GHC.Prim.+# x_aJ9 y_aJc) } } } in + l_s1uz + = case w_s1v1 of { GHC.Types.I# x_aJ0 -> case w1_s1v2 of { GHC.Types.I# y_aJ3 -> GHC.Types.I# (GHC.Prim.+# x_aJ0 y_aJ3) } } } in let { - l1_s1uS :: Int + l1_s1uA :: Int [LclId] - l1_s1uS - = case w_s1vj of { GHC.Types.I# x_aJh -> case w1_s1vk of { GHC.Types.I# y_aJk -> GHC.Types.I# (GHC.Prim.-# x_aJh y_aJk) } } } in + l1_s1uA + = case w_s1v1 of { GHC.Types.I# x_aJ8 -> case w1_s1v2 of { GHC.Types.I# y_aJb -> GHC.Types.I# (GHC.Prim.-# x_aJ8 y_aJb) } } } in let { - l2_s1uT :: [Int] + l2_s1uB :: [Int] [LclId, Unf=OtherCon []] - l2_s1uT = GHC.Types.: @Int l1_s1uS (GHC.Types.[] @Int) } in + l2_s1uB = GHC.Types.: @Int l1_s1uA (GHC.Types.[] @Int) } in let { - l3_sJv :: [Int] + l3_sJm :: [Int] [LclId, Unf=OtherCon []] - l3_sJv = GHC.Types.: @Int l_s1uR l2_s1uT } in - (# GHC.List.$w!! @Int l3_sJv 0#, GHC.List.$w!! @Int l3_sJv 1# #) + l3_sJm = GHC.Types.: @Int l_s1uz l2_s1uB } in + (# GHC.List.$w!! @Int l3_sJm 0#, GHC.List.$w!! @Int l3_sJm 1# #) -- RHS size: {terms: 10, types: 11, coercions: 0, joins: 0/0} pm [InlPrag=NOUSERINLINE[0]] :: Int -> Int -> (Int, Int) @@ -35,9 +35,9 @@ pm [InlPrag=NOUSERINLINE[0]] :: Int -> Int -> (Int, Int) Cpr=m1, Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=2,unsat_ok=True,boring_ok=False) - Tmpl= \ (w_s1vj [Occ=Once] :: Int) (w1_s1vk [Occ=Once] :: Int) -> - case T10694.$wpm w_s1vj w1_s1vk of { (# ww1_s1vp [Occ=Once], ww2_s1vq [Occ=Once] #) -> (ww1_s1vp, ww2_s1vq) }}] -pm = \ (w_s1vj :: Int) (w1_s1vk :: Int) -> case T10694.$wpm w_s1vj w1_s1vk of { (# ww1_s1vp, ww2_s1vq #) -> (ww1_s1vp, ww2_s1vq) } + Tmpl= \ (w_s1v1 [Occ=Once] :: Int) (w1_s1v2 [Occ=Once] :: Int) -> + case T10694.$wpm w_s1v1 w1_s1v2 of { (# ww1_s1v7 [Occ=Once], ww2_s1v8 [Occ=Once] #) -> (ww1_s1v7, ww2_s1v8) }}] +pm = \ (w_s1v1 :: Int) (w1_s1v2 :: Int) -> case T10694.$wpm w_s1v1 w1_s1v2 of { (# ww1_s1v7, ww2_s1v8 #) -> (ww1_s1v7, ww2_s1v8) } -- RHS size: {terms: 8, types: 9, coercions: 0, joins: 0/0} m :: Int -> Int -> Int @@ -46,9 +46,9 @@ m :: Int -> Int -> Int Str=, Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=2,unsat_ok=True,boring_ok=False) - Tmpl= \ (x_awt [Occ=Once] :: Int) (y_awu [Occ=Once] :: Int) -> - case pm x_awt y_awu of { (_ [Occ=Dead], mr_aww [Occ=Once]) -> mr_aww }}] -m = \ (x_awt :: Int) (y_awu :: Int) -> case T10694.$wpm x_awt y_awu of { (# ww1_s1vp, ww2_s1vq #) -> ww2_s1vq } + Tmpl= \ (x_awo [Occ=Once] :: Int) (y_awp [Occ=Once] :: Int) -> + case pm x_awo y_awp of { (_ [Occ=Dead], mr_awr [Occ=Once]) -> mr_awr }}] +m = \ (x_awo :: Int) (y_awp :: Int) -> case T10694.$wpm x_awo y_awp of { (# ww1_s1v7, ww2_s1v8 #) -> ww2_s1v8 } -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T10694.$trModule4 :: GHC.Prim.Addr# @@ -57,9 +57,7 @@ T10694.$trModule4 = "main"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T10694.$trModule3 :: GHC.Types.TrName -[GblId, - Cpr=m1, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T10694.$trModule3 = GHC.Types.TrNameS T10694.$trModule4 -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} @@ -69,17 +67,13 @@ T10694.$trModule2 = "T10694"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} T10694.$trModule1 :: GHC.Types.TrName -[GblId, - Cpr=m1, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] T10694.$trModule1 = GHC.Types.TrNameS T10694.$trModule2 -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} -T10694.$trModule :: GHC.Unit.Module -[GblId, - Cpr=m1, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] -T10694.$trModule = GHC.Unit.Module T10694.$trModule3 T10694.$trModule1 +T10694.$trModule :: GHC.Types.Module +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] +T10694.$trModule = GHC.Types.Module T10694.$trModule3 T10694.$trModule1 ===================================== testsuite/tests/stranal/sigs/BottomFromInnerLambda.stderr ===================================== @@ -7,7 +7,7 @@ BottomFromInnerLambda.f: ==================== Cpr signatures ==================== -BottomFromInnerLambda.$trModule: m1 +BottomFromInnerLambda.$trModule: BottomFromInnerLambda.expensive: m1 BottomFromInnerLambda.f: ===================================== testsuite/tests/stranal/sigs/CaseBinderCPR.stderr ===================================== @@ -6,7 +6,7 @@ CaseBinderCPR.f_list_cmp: ==================== Cpr signatures ==================== -CaseBinderCPR.$trModule: m1 +CaseBinderCPR.$trModule: CaseBinderCPR.f_list_cmp: m1 ===================================== testsuite/tests/stranal/sigs/DmdAnalGADTs.hs ===================================== @@ -7,11 +7,13 @@ data D a where A :: D Int B :: D (Int -> Int) +-- Doesn't have the CPR property anymore (#18154), but an expandable unfolding. +-- The point of this test is that f' has the CPR property. hasCPR :: Int hasCPR = 1 hasStrSig :: Int -> Int -hasStrSig x = x +hasStrSig x = x + 1 diverges :: Int diverges = diverges ===================================== testsuite/tests/stranal/sigs/DmdAnalGADTs.stderr ===================================== @@ -9,21 +9,21 @@ DmdAnalGADTs.f: DmdAnalGADTs.f': DmdAnalGADTs.g: DmdAnalGADTs.hasCPR: -DmdAnalGADTs.hasStrSig: +DmdAnalGADTs.hasStrSig: ==================== Cpr signatures ==================== -DmdAnalGADTs.$tc'A: m1 -DmdAnalGADTs.$tc'B: m1 -DmdAnalGADTs.$tcD: m1 -DmdAnalGADTs.$trModule: m1 +DmdAnalGADTs.$tc'A: +DmdAnalGADTs.$tc'B: +DmdAnalGADTs.$tcD: +DmdAnalGADTs.$trModule: DmdAnalGADTs.diverges: b DmdAnalGADTs.f: DmdAnalGADTs.f': m1 DmdAnalGADTs.g: -DmdAnalGADTs.hasCPR: m1 -DmdAnalGADTs.hasStrSig: +DmdAnalGADTs.hasCPR: +DmdAnalGADTs.hasStrSig: m1 @@ -37,6 +37,6 @@ DmdAnalGADTs.f: DmdAnalGADTs.f': DmdAnalGADTs.g: DmdAnalGADTs.hasCPR: -DmdAnalGADTs.hasStrSig: +DmdAnalGADTs.hasStrSig: ===================================== testsuite/tests/stranal/sigs/HyperStrUse.stderr ===================================== @@ -6,7 +6,7 @@ HyperStrUse.f: ==================== Cpr signatures ==================== -HyperStrUse.$trModule: m1 +HyperStrUse.$trModule: HyperStrUse.f: m1 ===================================== testsuite/tests/stranal/sigs/NewtypeArity.stderr ===================================== @@ -9,9 +9,9 @@ Test.t2: ==================== Cpr signatures ==================== -Test.$tc'MkT: m1 -Test.$tcT: m1 -Test.$trModule: m1 +Test.$tc'MkT: +Test.$tcT: +Test.$trModule: Test.t: m1 Test.t2: m1 ===================================== testsuite/tests/stranal/sigs/StrAnalExample.stderr ===================================== @@ -6,7 +6,7 @@ StrAnalExample.foo: ==================== Cpr signatures ==================== -StrAnalExample.$trModule: m1 +StrAnalExample.$trModule: StrAnalExample.foo: ===================================== testsuite/tests/stranal/sigs/T12370.stderr ===================================== @@ -7,7 +7,7 @@ T12370.foo: ==================== Cpr signatures ==================== -T12370.$trModule: m1 +T12370.$trModule: T12370.bar: m1 T12370.foo: m1 ===================================== testsuite/tests/stranal/sigs/T17932.stderr ===================================== @@ -10,11 +10,11 @@ T17932.flags: ==================== Cpr signatures ==================== -T17932.$tc'Options: m1 -T17932.$tc'X: m1 -T17932.$tcOptions: m1 -T17932.$tcX: m1 -T17932.$trModule: m1 +T17932.$tc'Options: +T17932.$tc'X: +T17932.$tcOptions: +T17932.$tcX: +T17932.$trModule: T17932.flags: ===================================== testsuite/tests/stranal/sigs/T5075.stderr ===================================== @@ -6,7 +6,7 @@ T5075.loop: ==================== Cpr signatures ==================== -T8569.$tc'Rdata: m1 -T8569.$tc'Rint: m1 -T8569.$tcRep: m1 -T8569.$trModule: m1 +T8569.$tc'Rdata: +T8569.$tc'Rint: +T8569.$tcRep: +T8569.$trModule: T8569.addUp: ===================================== testsuite/tests/stranal/sigs/T8598.stderr ===================================== @@ -6,7 +6,7 @@ T8598.fun: ==================== Cpr signatures ==================== -T8598.$trModule: m1 +T8598.$trModule: T8598.fun: m1 ===================================== testsuite/tests/stranal/sigs/UnsatFun.stderr ===================================== @@ -12,7 +12,7 @@ UnsatFun.h3: ==================== Cpr signatures ==================== -UnsatFun.$trModule: m1 +UnsatFun.$trModule: UnsatFun.f: b UnsatFun.g: UnsatFun.g': View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/86d8ac22608eb8f04ceaff65e76dbeec23b76753 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/86d8ac22608eb8f04ceaff65e76dbeec23b76753 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 13 06:07:19 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 13 May 2020 02:07:19 -0400 Subject: [Git][ghc/ghc][master] users-guide: Add discussion of shared object naming Message-ID: <5ebb8e97a2399_61673f819aad978c110164d2@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: e34bf656 by Ben Gamari at 2020-05-13T02:07:08-04:00 users-guide: Add discussion of shared object naming Fixes #18074. - - - - - 2 changed files: - docs/users_guide/packages.rst - docs/users_guide/phases.rst Changes: ===================================== docs/users_guide/packages.rst ===================================== @@ -1061,6 +1061,14 @@ extra indirection). its output in place of ⟨GHCVersion⟩. See also :ref:`options-codegen` on how object files must be prepared for shared object linking. +- When building a shared library, care must be taken to ensure that the + resulting object is named appropriately. In particular, GHC expects the + name of a shared object to have the form ``libHS-ghc.`` where *unit id* is the unit ID given during compilation via + the :ghc-flag:`-this-unit-id ⟨unit-id⟩` flag, *ghc version* is the version of + GHC that produced/consumes the object and *ext* is the host system's usual + file extension for shared objects. + To compile a module which is to be part of a new package, use the ``-package-name`` (to identify the name of the package) and ``-library-name`` (to identify the version and the version hashes of its ===================================== docs/users_guide/phases.rst ===================================== @@ -807,7 +807,8 @@ for example). When creating shared objects for Haskell packages, the shared object must be named properly, so that GHC recognizes the shared object - when linked against this package. See shared object name mangling. + when linking against this package. + See :ref:`shared object name mangling ` for details. .. ghc-flag:: -dynload :shortdesc: Selects one of a number of modes for finding shared libraries at runtime. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e34bf65613f0062ea902fb3d59623701b7cd01d5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e34bf65613f0062ea902fb3d59623701b7cd01d5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 13 06:07:57 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 13 May 2020 02:07:57 -0400 Subject: [Git][ghc/ghc][master] testsuite: Print sign of performance changes Message-ID: <5ebb8ebd66a5e_61671288ff4c1101934f@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 5d0f2445 by Ben Gamari at 2020-05-13T02:07:47-04:00 testsuite: Print sign of performance changes Executes the minor formatting change in the tabulated performance changes suggested in #18135. - - - - - 1 changed file: - testsuite/driver/runtests.py Changes: ===================================== testsuite/driver/runtests.py ===================================== @@ -349,13 +349,13 @@ def tabulate_metrics(metrics: List[PerfMetric]) -> None: val0 = metric.baseline.perfStat.value val1 = metric.stat.value rel = 100 * (val1 - val0) / val0 - print("{space:24} {herald:40} {value:15.3f} [{direction} {rel:2.1f}%]".format( + print("{space:24} {herald:40} {value:15.3f} [{direction}, {rel:2.1f}%]".format( space = "", herald = "(baseline @ HEAD~{depth})".format( depth = metric.baseline.commitDepth), value = val0, direction = metric.change, - rel = abs(rel) + rel = rel )) # First collect all the tests to be run View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5d0f244528f8f7ba3058a4cf7b075a474c63fa1b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5d0f244528f8f7ba3058a4cf7b075a474c63fa1b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 13 06:08:35 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 13 May 2020 02:08:35 -0400 Subject: [Git][ghc/ghc][master] testsuite: Add testcase for #18129 Message-ID: <5ebb8ee3a73fb_616711a31edc11022059@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 9e4b981f by Ben Gamari at 2020-05-13T02:08:24-04:00 testsuite: Add testcase for #18129 - - - - - 2 changed files: - + testsuite/tests/typecheck/should_compile/T18129.hs - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== testsuite/tests/typecheck/should_compile/T18129.hs ===================================== @@ -0,0 +1,52 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE ConstraintKinds #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE TypeOperators #-} +{-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE UndecidableSuperClasses #-} + +module T18129 where + +import Data.Kind (Constraint) +import Data.Proxy (Proxy) +import Data.Typeable (Typeable) + +-- First, `generics-sop` code, intact. +-- +type family + AllF (c :: k -> Constraint) (xs :: [k]) :: Constraint where + AllF _c '[] = () + AllF c (x ': xs) = (c x, All c xs) + +class (AllF c xs, SListI xs) => All (c :: k -> Constraint) (xs :: [k]) +instance All c '[] +instance (c x, All c xs) => All c (x ': xs) where + +class Top x +instance Top x + +type SListI = All Top + +-- Next, user code, minimised. +-- +data GADT + = forall (xs :: [*]) (a :: *) + . (Top a, All Typeable xs) + => GADT + +withSomePipe' + :: GADT + -> (forall (xs :: [*]) + . (Proxy xs -> GADT) + -> GADT) + -> GADT +withSomePipe' GADT f = f (const GADT) + ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -706,3 +706,4 @@ test('T18023', normal, compile, ['']) test('T18036', normal, compile, ['']) test('T18036a', normal, compile, ['']) test('T17873', normal, compile, ['']) +test('T18129', expect_broken(18129), compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9e4b981ff7a0852c7bdc93039eed13582d923241 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9e4b981ff7a0852c7bdc93039eed13582d923241 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 13 06:09:13 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 13 May 2020 02:09:13 -0400 Subject: [Git][ghc/ghc][master] doc: Reformulate the opening paragraph of Ch. 4 in User's guide Message-ID: <5ebb8f09e7bee_616712a9b7f01102638a@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 266310c3 by Ivan-Yudin at 2020-05-13T02:09:03-04:00 doc: Reformulate the opening paragraph of Ch. 4 in User's guide Removes mentioning of Hugs (it is not helpful for new users anymore). Changes the wording for the rest of the paragraph. Fixes #18132. - - - - - 1 changed file: - docs/users_guide/ghci.rst Changes: ===================================== docs/users_guide/ghci.rst ===================================== @@ -7,23 +7,25 @@ Using GHCi single: GHCi single: interpreter single: interactive - single: Hugs single: Foreign Function Interface; GHCi support single: FFI; GHCi support -GHCi [1]_ is GHC's interactive environment, in which Haskell expressions -can be interactively evaluated and programs can be interpreted. If -you're familiar with `Hugs `__, then -you'll be right at home with GHCi. However, GHCi also has support for -interactively loading compiled code, as well as supporting all [2]_ the -language extensions that GHC provides. GHCi also includes an interactive +GHCi [1]_ is GHC's interactive environment that includes an interactive debugger (see :ref:`ghci-debugger`). +GHCi can + +- interactively evaluate Haskell expressions +- interpret Haskell programs +- load GHC-compiled modules. + +At the moment GHCi supports most of GHC's language extensions. + + .. [1] The "i" stands for “Interactive” -.. [2] - except ``foreign export``, at the moment + .. _ghci-introduction: View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/266310c300f2254dfdeb5eb2123737f765ed18f8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/266310c300f2254dfdeb5eb2123737f765ed18f8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 13 10:32:23 2020 From: gitlab at gitlab.haskell.org (Vilem-Benjamin Liepelt) Date: Wed, 13 May 2020 06:32:23 -0400 Subject: [Git][ghc/ghc][wip/buggymcbugfix/15185-enum-int] Add inline pragmas to Enum methods Message-ID: <5ebbccb710182_61671288ff4c110542cc@gitlab.haskell.org.mail> Vilem-Benjamin Liepelt pushed to branch wip/buggymcbugfix/15185-enum-int at Glasgow Haskell Compiler / GHC Commits: fc47ad26 by buggymcbugfix at 2020-05-13T13:31:17+03:00 Add inline pragmas to Enum methods Fixes t15185 - - - - - 1 changed file: - libraries/base/GHC/Enum.hs Changes: ===================================== libraries/base/GHC/Enum.hs ===================================== @@ -139,13 +139,36 @@ class Enum a where -- * @enumFromThenTo 6 8 2 :: [Int] = []@ enumFromThenTo :: a -> a -> a -> [a] - succ = toEnum . (+ 1) . fromEnum - pred = toEnum . (subtract 1) . fromEnum - enumFrom x = map toEnum [fromEnum x ..] - enumFromThen x y = map toEnum [fromEnum x, fromEnum y ..] - enumFromTo x y = map toEnum [fromEnum x .. fromEnum y] + succ = toEnum . (+ 1) . fromEnum + + pred = toEnum . (subtract 1) . fromEnum + + -- See Note [Stable Unfolding for Enum methods] + {-# INLINABLE enumFrom #-} + enumFrom x = map toEnum [fromEnum x ..] + + -- See Note [Stable Unfolding for Enum methods] + {-# INLINABLE enumFromThen #-} + enumFromThen x y = map toEnum [fromEnum x, fromEnum y ..] + + -- See Note [Stable Unfolding for Enum methods] + {-# INLINABLE enumFromTo #-} + enumFromTo x y = map toEnum [fromEnum x .. fromEnum y] + + -- See Note [Stable Unfolding for Enum methods] + {-# INLINABLE enumFromThenTo #-} enumFromThenTo x1 x2 y = map toEnum [fromEnum x1, fromEnum x2 .. fromEnum y] +{- +Note [Stable Unfolding for Enum methods] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The INLINABLE pragmas ensure that we export stable (unoptimised) unfoldings in +the interface file so we can do list fusion at usage sites outside this module. + +Fixes https://gitlab.haskell.org/ghc/ghc/issues/15185 +-} + -- Default methods for bounded enumerations boundedEnumFrom :: (Enum a, Bounded a) => a -> [a] boundedEnumFrom n = map toEnum [fromEnum n .. fromEnum (maxBound `asTypeOf` n)] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fc47ad267b81673626e07731530a6cb90734d725 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fc47ad267b81673626e07731530a6cb90734d725 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 13 15:04:25 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 13 May 2020 11:04:25 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn-simpl] 42 commits: Refactor hole constraints. Message-ID: <5ebc0c79c00a3_61673f81cd539dbc110698f0@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn-simpl at Glasgow Haskell Compiler / GHC Commits: 7ab6ab09 by Richard Eisenberg at 2020-05-06T04:39:32-04:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG ------------------------- - - - - - 420b957d by Ben Gamari at 2020-05-06T04:40:08-04:00 rts: Zero block flags with -DZ Block flags are very useful for determining the state of a block. However, some block allocator users don't touch them, leading to misleading values. Ensure that we zero then when zero-on-gc is set. This is safe and makes the flags more useful during debugging. - - - - - 740b3b8d by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix incorrect failed_to_evac value during deadlock gc Previously we would incorrectly set the failed_to_evac flag if we evacuated a value due to a deadlock GC. This would cause us to mark more things as dirty than strictly necessary. It also turned up a nasty but which I will fix next. - - - - - b2d72c75 by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - 9f3e6884 by Zubin Duggal at 2020-05-06T04:41:08-04:00 Allow atomic update of NameCache in readHieFile The situation arises in ghcide where multiple different threads may need to update the name cache, therefore with the older interface it could happen that you start reading a hie file with name cache A and produce name cache A + B, but another thread in the meantime updated the namecache to A + C. Therefore if you write the new namecache you will lose the A' updates from the second thread. Updates haddock submodule - - - - - edec6a6c by Ryan Scott at 2020-05-06T04:41:57-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _)`. Fixes #18127. - - - - - a95e7fe0 by Ömer Sinan Ağacan at 2020-05-06T04:42:39-04:00 ELF linker: increment curSymbol after filling in fields of current entry The bug was introduced in a8b7cef4d45 which added a field to the `symbols` array elements and then updated this code incorrectly: - oc->symbols[curSymbol++] = nm; + oc->symbols[curSymbol++].name = nm; + oc->symbols[curSymbol].addr = symbol->addr; - - - - - cab1871a by Sylvain Henry at 2020-05-06T04:43:21-04:00 Move LeadingUnderscore into Platform (#17957) Avoid direct use of DynFlags to know if symbols must be prefixed by an underscore. - - - - - 94e7c563 by Sylvain Henry at 2020-05-06T04:43:21-04:00 Don't use DynFlags in showLinkerState (#17957) - - - - - 9afd9251 by Ryan Scott at 2020-05-06T04:43:58-04:00 Refactoring: Use bindSigTyVarsFV in rnMethodBinds `rnMethodBinds` was explicitly using `xoptM` to determine if `ScopedTypeVariables` is enabled before bringing type variables bound by the class/instance header into scope. However, this `xoptM` logic is already performed by the `bindSigTyVarsFV` function. This patch uses `bindSigTyVarsFV` in `rnMethodBinds` to reduce the number of places where we need to consult if `ScopedTypeVariables` is on. This is purely refactoring, and there should be no user-visible change in behavior. - - - - - 6f6d72b2 by Brian Foley at 2020-05-08T15:29:25-04:00 Remove further dead code found by a simple Python script. Avoid removing some functions that are part of an API even though they're not used in-tree at the moment. - - - - - 78bf8bf9 by Julien Debon at 2020-05-08T15:29:28-04:00 Add doc examples for Bifoldable See #17929 - - - - - 66f0a847 by Julien Debon at 2020-05-08T15:29:29-04:00 doc (Bitraversable): Add examples to Bitraversable * Add examples to Data.Bitraversable * Fix formatting for (,) in Bitraversable and Bifoldable * Fix mistake on bimapAccumR documentation See #17929 - - - - - 9749fe12 by Baldur Blöndal at 2020-05-08T15:29:32-04:00 Specify kind variables for inferred kinds in base. - - - - - 4e9aef9e by John Ericson at 2020-05-08T15:29:36-04:00 HsSigWcTypeScoping: Pull in documentation from stray location - - - - - f4d5c6df by John Ericson at 2020-05-08T15:29:36-04:00 Rename local `real_fvs` to `implicit_vs` It doesn't make sense to call the "free" variables we are about to implicitly bind the real ones. - - - - - 20570b4b by John Ericson at 2020-05-08T15:29:36-04:00 A few tiny style nits with renaming - Use case rather than guards that repeatedly scrutenize same thing. - No need for view pattern when `L` is fine. - Use type synnonym to convey the intent like elsewhere. - - - - - 09ac8de5 by John Ericson at 2020-05-08T15:29:36-04:00 Add `forAllOrNothing` function with note - - - - - bb35c0e5 by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Document lawlessness of Ap's Num instance - - - - - cdd229ff by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply suggestion to libraries/base/Data/Monoid.hs - - - - - 926d2aab by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply more suggestions from Simon Jakobi - - - - - 7a763cff by Adam Gundry at 2020-05-08T15:29:41-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. - - - - - 88e3c815 by Simon Peyton Jones at 2020-05-08T15:29:41-04:00 Fix specialisation for DFuns When specialising a DFun we must take care to saturate the unfolding. See Note [Specialising DFuns] in Specialise. Fixes #18120 - - - - - 86c77b36 by Greg Steuck at 2020-05-08T15:29:45-04:00 Remove unused SEGMENT_PROT_RWX It's been unused for a year and is problematic on any OS which requires W^X for security. - - - - - 9d97f4b5 by nineonine at 2020-05-08T15:30:03-04:00 Add test for #16167 - - - - - aa318338 by Ryan Scott at 2020-05-08T15:30:04-04:00 Bump exceptions submodule so that dist-boot is .gitignore'd `exceptions` is a stage-0 boot library as of commit 30272412fa437ab8e7a8035db94a278e10513413, which means that building `exceptions` in a GHC tree will generate a `dist-boot` directory. However, this directory was not specified in `exceptions`' `.gitignore` file, which causes it to dirty up the current `git` working directory. Accordingly, this bumps the `exceptions` submodule to commit ghc/packages/exceptions at 23c0b8a50d7592af37ca09beeec16b93080df98f, which adds `dist-boot` to the `.gitignore` file. - - - - - ea86360f by Ömer Sinan Ağacan at 2020-05-08T15:30:30-04:00 Linker.c: initialize n_symbols of ObjectCode with other fields - - - - - 951c1fb0 by Sylvain Henry at 2020-05-09T21:46:38-04:00 Fix unboxed-sums GC ptr-slot rubbish value (#17791) This patch allows boot libraries to use unboxed sums without implicitly depending on `base` package because of `absentSumFieldError`. See updated Note [aBSENT_SUM_FIELD_ERROR_ID] in GHC.Core.Make - - - - - b352d63c by Ben Gamari at 2020-05-09T21:47:14-04:00 rts: Make non-existent linker search path merely a warning As noted in #18105, previously this resulted in a rather intrusive error message. This is in contrast to the general expectation that search paths are merely places to look, not places that must exist. Fixes #18105. - - - - - cf4f1e2f by Ben Gamari at 2020-05-13T02:02:33-04:00 rts/CNF: Fix fixup comparison function Previously we would implicitly convert the difference between two words to an int, resulting in an integer overflow on 64-bit machines. Fixes #16992 - - - - - a03da9bf by Ömer Sinan Ağacan at 2020-05-13T02:03:16-04:00 Pack some of IdInfo fields into a bit field This reduces residency of compiler quite a bit on some programs. Example stats when building T10370: Before: 2,871,242,832 bytes allocated in the heap 4,693,328,008 bytes copied during GC 33,941,448 bytes maximum residency (276 sample(s)) 375,976 bytes maximum slop 83 MiB total memory in use (0 MB lost due to fragmentation) After: 2,858,897,344 bytes allocated in the heap 4,629,255,440 bytes copied during GC 32,616,624 bytes maximum residency (278 sample(s)) 314,400 bytes maximum slop 80 MiB total memory in use (0 MB lost due to fragmentation) So -3.9% residency, -1.3% bytes copied and -0.4% allocations. Fixes #17497 Metric Decrease: T9233 T9675 - - - - - 670c3e5c by Ben Gamari at 2020-05-13T02:03:54-04:00 get-win32-tarballs: Fix base URL Revert a change previously made for testing purposes. - - - - - 8ad8dc41 by Ben Gamari at 2020-05-13T02:03:54-04:00 get-win32-tarballs: Improve diagnostics output - - - - - 8c0740b7 by Simon Jakobi at 2020-05-13T02:04:33-04:00 docs: Add examples for Data.Semigroup.Arg{Min,Max} Context: #17153 - - - - - cb22348f by Ben Gamari at 2020-05-13T02:05:11-04:00 Add few cleanups of the CAF logic Give the NameSet of non-CAFfy names a proper newtype to distinguish it from all of the other NameSets floating about. - - - - - 90e38b81 by Emeka Nkurumeh at 2020-05-13T02:05:51-04:00 fix printf warning when using with ghc with clang on mingw - - - - - 86d8ac22 by Sebastian Graf at 2020-05-13T02:06:29-04:00 CprAnal: Don't attach CPR sigs to expandable bindings (#18154) Instead, look through expandable unfoldings in `cprTransform`. See the new Note [CPR for expandable unfoldings]: ``` Long static data structures (whether top-level or not) like xs = x1 : xs1 xs1 = x2 : xs2 xs2 = x3 : xs3 should not get CPR signatures, because they * Never get WW'd, so their CPR signature should be irrelevant after analysis (in fact the signature might even be harmful for that reason) * Would need to be inlined/expanded to see their constructed product * Recording CPR on them blows up interface file sizes and is redundant with their unfolding. In case of Nested CPR, this blow-up can be quadratic! But we can't just stop giving DataCon application bindings the CPR property, for example fac 0 = 1 fac n = n * fac (n-1) fac certainly has the CPR property and should be WW'd! But FloatOut will transform the first clause to lvl = 1 fac 0 = lvl If lvl doesn't have the CPR property, fac won't either. But lvl doesn't have a CPR signature to extrapolate into a CPR transformer ('cprTransform'). So instead we keep on cprAnal'ing through *expandable* unfoldings for these arity 0 bindings via 'cprExpandUnfolding_maybe'. In practice, GHC generates a lot of (nested) TyCon and KindRep bindings, one for each data declaration. It's wasteful to attach CPR signatures to each of them (and intractable in case of Nested CPR). ``` Fixes #18154. - - - - - e34bf656 by Ben Gamari at 2020-05-13T02:07:08-04:00 users-guide: Add discussion of shared object naming Fixes #18074. - - - - - 5d0f2445 by Ben Gamari at 2020-05-13T02:07:47-04:00 testsuite: Print sign of performance changes Executes the minor formatting change in the tabulated performance changes suggested in #18135. - - - - - 9e4b981f by Ben Gamari at 2020-05-13T02:08:24-04:00 testsuite: Add testcase for #18129 - - - - - 266310c3 by Ivan-Yudin at 2020-05-13T02:09:03-04:00 doc: Reformulate the opening paragraph of Ch. 4 in User's guide Removes mentioning of Hugs (it is not helpful for new users anymore). Changes the wording for the rest of the paragraph. Fixes #18132. - - - - - 4e1fb536 by Sebastian Graf at 2020-05-13T17:04:14+02:00 DmdAnal: Improve handling of precise exceptions This patch does two things: Fix possible unsoundness in what was called the "IO hack" and implement part 2.1 of the "fixing precise exceptions" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions, which, in combination with !2956, supersedes !3014 and !2525. **IO hack** The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is called `exprMayThrowPreciseException` now. I came up with two testcases exemplifying possible unsoundness (if twisted enough) in the old approach: - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. - `T13380e`: Demonstrating unsoundness of the "IO hack" when we have Nested CPR. Not currently relevant, as we don't have Nested CPR yet. - `T13380f`: Demonstrating unsoundness of the "IO hack" for safe FFI calls. Basically, the IO hack assumed that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future, see `T13380e`. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380{d,e}` (and will hopefully be robust to Nested CPR). **Precise exceptions** In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that was terribly unprincipled. That unprincipledness resulted in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception (and the existing IO hack doesn't detect that) Fixing both issues in !3014 turned out to be too complicated and had the potential to regress in the future. Hence we decided to only fix `T13380b` and augment the `Divergence` lattice with a new middle-layer element, `ExnOrDiv`, which means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. See the wiki page on Step 2.1 for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#dead-code-elimination-for-raiseio-with-isdeadenddiv-introducing-exnordiv-step-21 - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/PPC/Cond.hs - compiler/GHC/CmmToAsm/SPARC/Cond.hs - compiler/GHC/CmmToAsm/X86/Cond.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/LiberateCase.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Driver/Main.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1d5265f9e8c3074c2129054880ae8dc9ed7ac4e8...4e1fb5362886e37d24d2a68881e674fbdca2bb41 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1d5265f9e8c3074c2129054880ae8dc9ed7ac4e8...4e1fb5362886e37d24d2a68881e674fbdca2bb41 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 13 16:42:43 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 13 May 2020 12:42:43 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 23 commits: rts/CNF: Fix fixup comparison function Message-ID: <5ebc238380a44_616711922e9c1109031e@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: cf4f1e2f by Ben Gamari at 2020-05-13T02:02:33-04:00 rts/CNF: Fix fixup comparison function Previously we would implicitly convert the difference between two words to an int, resulting in an integer overflow on 64-bit machines. Fixes #16992 - - - - - a03da9bf by Ömer Sinan Ağacan at 2020-05-13T02:03:16-04:00 Pack some of IdInfo fields into a bit field This reduces residency of compiler quite a bit on some programs. Example stats when building T10370: Before: 2,871,242,832 bytes allocated in the heap 4,693,328,008 bytes copied during GC 33,941,448 bytes maximum residency (276 sample(s)) 375,976 bytes maximum slop 83 MiB total memory in use (0 MB lost due to fragmentation) After: 2,858,897,344 bytes allocated in the heap 4,629,255,440 bytes copied during GC 32,616,624 bytes maximum residency (278 sample(s)) 314,400 bytes maximum slop 80 MiB total memory in use (0 MB lost due to fragmentation) So -3.9% residency, -1.3% bytes copied and -0.4% allocations. Fixes #17497 Metric Decrease: T9233 T9675 - - - - - 670c3e5c by Ben Gamari at 2020-05-13T02:03:54-04:00 get-win32-tarballs: Fix base URL Revert a change previously made for testing purposes. - - - - - 8ad8dc41 by Ben Gamari at 2020-05-13T02:03:54-04:00 get-win32-tarballs: Improve diagnostics output - - - - - 8c0740b7 by Simon Jakobi at 2020-05-13T02:04:33-04:00 docs: Add examples for Data.Semigroup.Arg{Min,Max} Context: #17153 - - - - - cb22348f by Ben Gamari at 2020-05-13T02:05:11-04:00 Add few cleanups of the CAF logic Give the NameSet of non-CAFfy names a proper newtype to distinguish it from all of the other NameSets floating about. - - - - - 90e38b81 by Emeka Nkurumeh at 2020-05-13T02:05:51-04:00 fix printf warning when using with ghc with clang on mingw - - - - - 86d8ac22 by Sebastian Graf at 2020-05-13T02:06:29-04:00 CprAnal: Don't attach CPR sigs to expandable bindings (#18154) Instead, look through expandable unfoldings in `cprTransform`. See the new Note [CPR for expandable unfoldings]: ``` Long static data structures (whether top-level or not) like xs = x1 : xs1 xs1 = x2 : xs2 xs2 = x3 : xs3 should not get CPR signatures, because they * Never get WW'd, so their CPR signature should be irrelevant after analysis (in fact the signature might even be harmful for that reason) * Would need to be inlined/expanded to see their constructed product * Recording CPR on them blows up interface file sizes and is redundant with their unfolding. In case of Nested CPR, this blow-up can be quadratic! But we can't just stop giving DataCon application bindings the CPR property, for example fac 0 = 1 fac n = n * fac (n-1) fac certainly has the CPR property and should be WW'd! But FloatOut will transform the first clause to lvl = 1 fac 0 = lvl If lvl doesn't have the CPR property, fac won't either. But lvl doesn't have a CPR signature to extrapolate into a CPR transformer ('cprTransform'). So instead we keep on cprAnal'ing through *expandable* unfoldings for these arity 0 bindings via 'cprExpandUnfolding_maybe'. In practice, GHC generates a lot of (nested) TyCon and KindRep bindings, one for each data declaration. It's wasteful to attach CPR signatures to each of them (and intractable in case of Nested CPR). ``` Fixes #18154. - - - - - e34bf656 by Ben Gamari at 2020-05-13T02:07:08-04:00 users-guide: Add discussion of shared object naming Fixes #18074. - - - - - 5d0f2445 by Ben Gamari at 2020-05-13T02:07:47-04:00 testsuite: Print sign of performance changes Executes the minor formatting change in the tabulated performance changes suggested in #18135. - - - - - 9e4b981f by Ben Gamari at 2020-05-13T02:08:24-04:00 testsuite: Add testcase for #18129 - - - - - 266310c3 by Ivan-Yudin at 2020-05-13T02:09:03-04:00 doc: Reformulate the opening paragraph of Ch. 4 in User's guide Removes mentioning of Hugs (it is not helpful for new users anymore). Changes the wording for the rest of the paragraph. Fixes #18132. - - - - - 0fcebef2 by Baldur Blöndal at 2020-05-13T12:41:44-04:00 Predicate, Equivalence derive via `.. -> a -> All' - - - - - 094219f6 by Alp Mestanogullari at 2020-05-13T12:41:52-04:00 hadrian: add a --freeze2 option to freeze stage 1 and 2 - - - - - 927b3a5e by Artem Pelenitsyn at 2020-05-13T12:42:12-04:00 Don't reload environment files on every setSessionDynFlags Makes `interpretPackageEnv` (which loads envirinment files) a part of `parseDynamicFlags` (parsing command-line arguments, which is typically done once) instead of `setSessionDynFlags` (which is typically called several times). Making several (transitive) calls to `interpretPackageEnv`, as before, caused #18125 #16318, which should be fixed now. - - - - - 267ef0ea by Ryan Scott at 2020-05-13T12:42:12-04:00 Factor out HsPatSigType for pat sigs/RULE term sigs (#16762) This implements chunks (2) and (3) of https://gitlab.haskell.org/ghc/ghc/issues/16762#note_270170. Namely, it introduces a dedicated `HsPatSigType` AST type, which represents the types that can appear in pattern signatures and term-level `RULE` binders. Previously, these were represented with `LHsSigWcType`. Although `LHsSigWcType` is isomorphic to `HsPatSigType`, the intended semantics of the two types are slightly different, as evidenced by the fact that they have different code paths in the renamer and typechecker. See also the new `Note [Pattern signature binders and scoping]` in `GHC.Hs.Types`. - - - - - f0de7e63 by Hécate at 2020-05-13T12:42:16-04:00 fix(documentation): Fix the RST links to GHC.Prim - - - - - 9cef8408 by Baldur Blöndal at 2020-05-13T12:42:17-04:00 Document (->) using inferred quantification for its runtime representations. Fixes #18142. - - - - - b30f2d41 by Takenobu Tani at 2020-05-13T12:42:27-04:00 Tweak man page for ghc command This commit updates the ghc command's man page as followings: * Enable `man_show_urls` to show URL addresses in the `DESCRIPTION` section of ghc.rst, because sphinx currently removes hyperlinks for man pages. * Add a `SEE ALSO` section to point to the GHC homepage - - - - - a85ee5d1 by Takenobu Tani at 2020-05-13T12:42:29-04:00 GHCi: Add link to the user's guide in help message This commit adds a link to the user's guide in ghci's `:help` message. Newcomers could easily reach to details of ghci. - - - - - 36c5fa81 by Jeff Happily at 2020-05-13T12:42:32-04:00 Handle single unused import - - - - - 027e2c7d by Ben Gamari at 2020-05-13T12:42:33-04:00 Ensure that printMinimalImports closes handle Fixes #18166. - - - - - cf7a9ecc by Ben Gamari at 2020-05-13T12:42:33-04:00 hadrian: Tell testsuite driver about LLVM availability This reflects the logic present in the Make build system into Hadrian. Fixes #18167. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Extension.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Types.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/UpdateCafInfos.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/Gen/Rule.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Name/Set.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bef5dc3e525f80612206eb792833a54566f688ad...cf7a9ecc5265b1f654b68ca2806c5765c1a6162e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bef5dc3e525f80612206eb792833a54566f688ad...cf7a9ecc5265b1f654b68ca2806c5765c1a6162e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 13 17:05:08 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 13 May 2020 13:05:08 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn-simpl] DmdAnal: Improve handling of precise exceptions Message-ID: <5ebc28c48c402_616712a9b7f011108731@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn-simpl at Glasgow Haskell Compiler / GHC Commits: 030b0b36 by Sebastian Graf at 2020-05-13T19:05:02+02:00 DmdAnal: Improve handling of precise exceptions This patch does two things: Fix possible unsoundness in what was called the "IO hack" and implement part 2.1 of the "fixing precise exceptions" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions, which, in combination with !2956, supersedes !3014 and !2525. **IO hack** The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is called `exprMayThrowPreciseException` now. I came up with two testcases exemplifying possible unsoundness (if twisted enough) in the old approach: - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. - `T13380e`: Demonstrating unsoundness of the "IO hack" when we have Nested CPR. Not currently relevant, as we don't have Nested CPR yet. - `T13380f`: Demonstrating unsoundness of the "IO hack" for safe FFI calls. Basically, the IO hack assumed that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future, see `T13380e`. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380{d,e}` (and will hopefully be robust to Nested CPR). **Precise exceptions** In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that was terribly unprincipled. That unprincipledness resulted in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception (and the existing IO hack doesn't detect that) Fixing both issues in !3014 turned out to be too complicated and had the potential to regress in the future. Hence we decided to only fix `T13380b` and augment the `Divergence` lattice with a new middle-layer element, `ExnOrDiv`, which means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. See the wiki page on Step 2.1 for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#dead-code-elimination-for-raiseio-with-isdeadenddiv-introducing-exnordiv-step-21 - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/LiberateCase.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Make.hs - testsuite/tests/stranal/should_compile/T10482a.stderr - testsuite/tests/stranal/should_compile/T10694.stderr - + testsuite/tests/stranal/should_compile/T13380b.hs - testsuite/tests/stranal/should_compile/all.T - + testsuite/tests/stranal/should_run/T13380d.hs - + testsuite/tests/stranal/should_run/T13380d.stderr - + testsuite/tests/stranal/should_run/T13380e.hs - + testsuite/tests/stranal/should_run/T13380e.stderr - testsuite/tests/stranal/should_run/all.T The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/030b0b366ca4fa29c6acd363f347da1378120b20 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/030b0b366ca4fa29c6acd363f347da1378120b20 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 13 22:16:33 2020 From: gitlab at gitlab.haskell.org (Alan Zimmerman) Date: Wed, 13 May 2020 18:16:33 -0400 Subject: [Git][ghc/ghc][wip/az/exactprint] Adding test infrastructure for check-exact Message-ID: <5ebc71c1ce522_61673f8103f8794c11129368@gitlab.haskell.org.mail> Alan Zimmerman pushed to branch wip/az/exactprint at Glasgow Haskell Compiler / GHC Commits: 18f174bf by Alan Zimmerman at 2020-05-13T22:40:55+01:00 Adding test infrastructure for check-exact Like check-ppr, but checking for an exact reproduction of the parsed source file. - - - - - 8 changed files: - + compiler/GHC/Hs/Exact.hs - compiler/ghc.cabal.in - ghc.mk - hadrian/src/Packages.hs - hadrian/src/Rules/BinaryDist.hs - hadrian/src/Rules/Test.hs - hadrian/src/Settings/Builders/Make.hs - testsuite/mk/boilerplate.mk Changes: ===================================== compiler/GHC/Hs/Exact.hs ===================================== @@ -0,0 +1,123 @@ +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE TypeSynonymInstances #-} +module GHC.Hs.Exact + ( + ExactPrint(..) + ) where + +-- Module to provide "exact" printing of a GhcPs syntax fragment. +-- This will be the the home of the functionality currently in ghc-exactprint. + +import GHC.Hs.Extension +import GHC.Types.Name.Reader +import GHC.Types.SrcLoc +import GHC.Utils.Outputable + +-- --------------------------------------------------------------------- + +-- | Modeled on Outputable +class ExactPrint a where + exact :: a -> SDoc + +-- --------------------------------------------------------------------- + +instance ExactPrint (LocatedA RdrName) where + exact (L l n) = ppr n + +{- +Code in ghc-exactprint + +isSymRdr :: GHC.RdrName -> Bool +isSymRdr n = GHC.isSymOcc (GHC.rdrNameOcc n) || rdrName2String n == "." + +instance Annotate GHC.RdrName where + markAST l n = do + let + str = rdrName2String n + isSym = isSymRdr n + doNormalRdrName = do + let str' = case str of + -- TODO: unicode support? + "forall" -> if spanLength l == 1 then "∀" else str + _ -> str + + let + markParen :: GHC.AnnKeywordId -> Annotated () + markParen pa = do + if isSym + then ifInContext (Set.fromList [PrefixOp,PrefixOpDollar]) + (mark pa) -- '(' + (markOptional pa) + else markOptional pa + + markOptional GHC.AnnSimpleQuote + markParen GHC.AnnOpenP + unless isSym $ inContext (Set.fromList [InfixOp]) $ markOffset GHC.AnnBackquote 0 + cnt <- countAnns GHC.AnnVal + case cnt of + 0 -> markExternal l GHC.AnnVal str' + 1 -> markWithString GHC.AnnVal str' + _ -> traceM $ "Printing RdrName, more than 1 AnnVal:" ++ showGhc (l,n) + unless isSym $ inContext (Set.fromList [InfixOp]) $ markOffset GHC.AnnBackquote 1 + markParen GHC.AnnCloseP + + case n of + GHC.Unqual _ -> doNormalRdrName + GHC.Qual _ _ -> doNormalRdrName + GHC.Orig _ _ -> if str == "~" + then doNormalRdrName + -- then error $ "GHC.orig:(isSym,canParen)=" ++ show (isSym,canParen) + else markExternal l GHC.AnnVal str + -- GHC.Orig _ _ -> markExternal l GHC.AnnVal str + -- GHC.Orig _ _ -> error $ "GHC.orig:str=[" ++ str ++ "]" + GHC.Exact n' -> do + case str of + -- Special handling for Exact RdrNames, which are built-in Names + "[]" -> do + mark GHC.AnnOpenS -- '[' + mark GHC.AnnCloseS -- ']' + "()" -> do + mark GHC.AnnOpenP -- '(' + mark GHC.AnnCloseP -- ')' + ('(':'#':_) -> do + markWithString GHC.AnnOpen "(#" -- '(#' + let cnt = length $ filter (==',') str + replicateM_ cnt (mark GHC.AnnCommaTuple) + markWithString GHC.AnnClose "#)"-- '#)' + "[::]" -> do + markWithString GHC.AnnOpen "[:" -- '[:' + markWithString GHC.AnnClose ":]" -- ':]' + "->" -> do + mark GHC.AnnOpenP -- '(' + mark GHC.AnnRarrow + mark GHC.AnnCloseP -- ')' + -- "~#" -> do + -- mark GHC.AnnOpenP -- '(' + -- mark GHC.AnnTildehsh + -- mark GHC.AnnCloseP + "~" -> do + doNormalRdrName + "*" -> do + markExternal l GHC.AnnVal str + "★" -> do -- Note: unicode star + markExternal l GHC.AnnVal str + ":" -> do + -- Note: The OccName for ":" has the following attributes (via occAttributes) + -- (d, Data DataSym Sym Val ) + -- consDataConName = mkWiredInDataConName BuiltInSyntax gHC_TYPES (fsLit ":") consDataConKey consDataCon + doNormalRdrName + -- trace ("RdrName.checking :" ++ (occAttributes $ GHC.occName n)) doNormalRdrName + ('(':',':_) -> do + mark GHC.AnnOpenP + let cnt = length $ filter (==',') str + replicateM_ cnt (mark GHC.AnnCommaTuple) + mark GHC.AnnCloseP -- ')' + _ -> do + let isSym' = isSymRdr (GHC.nameRdrName n') + when isSym' $ mark GHC.AnnOpenP -- '(' + markWithString GHC.AnnVal str + when isSym $ mark GHC.AnnCloseP -- ')' + inContext (Set.fromList [Intercalate]) $ mark GHC.AnnComma `debug` ("AnnComma in RdrName") + + +-} ===================================== compiler/ghc.cabal.in ===================================== @@ -335,6 +335,7 @@ Library GHC.Hs.Binds GHC.Hs.Decls GHC.Hs.Doc + GHC.Hs.Exact GHC.Hs.Expr GHC.Hs.ImpExp GHC.Hs.Lit ===================================== ghc.mk ===================================== @@ -554,6 +554,7 @@ ghc/stage2/package-data.mk: compiler/stage2/package-data.mk utils/haddock/dist/package-data.mk: compiler/stage2/package-data.mk utils/check-api-annotations/dist-install/package-data.mk: compiler/stage2/package-data.mk utils/check-ppr/dist-install/package-data.mk: compiler/stage2/package-data.mk +utils/check-exact/dist-install/package-data.mk: compiler/stage2/package-data.mk # add the final package.conf dependency: ghc-prim depends on RTS libraries/ghc-prim/dist-install/package-data.mk : rts/dist/package.conf.inplace @@ -665,6 +666,7 @@ BUILD_DIRS += utils/ghc-pkg BUILD_DIRS += utils/testremove BUILD_DIRS += utils/check-api-annotations BUILD_DIRS += utils/check-ppr +BUILD_DIRS += utils/check-exact BUILD_DIRS += utils/ghc-cabal BUILD_DIRS += utils/hpc BUILD_DIRS += utils/runghc @@ -710,6 +712,7 @@ ifneq "$(CrossCompiling) $(Stage1Only)" "NO NO" # See Note [Stage1Only vs stage=1] in mk/config.mk.in. BUILD_DIRS := $(filter-out utils/check-api-annotations,$(BUILD_DIRS)) BUILD_DIRS := $(filter-out utils/check-ppr,$(BUILD_DIRS)) +BUILD_DIRS := $(filter-out utils/check-exact,$(BUILD_DIRS)) endif endif # CLEANING ===================================== hadrian/src/Packages.hs ===================================== @@ -2,6 +2,7 @@ module Packages ( -- * GHC packages array, base, binary, bytestring, cabal, checkApiAnnotations, checkPpr, + checkExact, compareSizes, compiler, containers, deepseq, deriveConstants, directory, exceptions, filepath, genapply, genprimopcode, ghc, ghcBoot, ghcBootTh, ghcCompact, ghcHeap, ghci, ghcPkg, ghcPrim, haddock, haskeline, @@ -52,6 +53,7 @@ bytestring = lib "bytestring" cabal = lib "Cabal" `setPath` "libraries/Cabal/Cabal" checkApiAnnotations = util "check-api-annotations" checkPpr = util "check-ppr" +checkExact = util "check-exact" compareSizes = util "compareSizes" `setPath` "utils/compare_sizes" compiler = top "ghc" `setPath` "compiler" containers = lib "containers" `setPath` "libraries/containers/containers" ===================================== hadrian/src/Rules/BinaryDist.hs ===================================== @@ -148,7 +148,7 @@ bindistRules = do need $ map (bindistFilesDir -/-) (["configure", "Makefile"] ++ bindistInstallFiles) need $ map ((bindistFilesDir -/- "wrappers") -/-) ["check-api-annotations" - , "check-ppr", "ghc", "ghc-iserv", "ghc-pkg" + , "check-ppr", "check-exact", "ghc", "ghc-iserv", "ghc-pkg" , "ghci-script", "haddock", "hpc", "hp2ps", "hsc2hs" , "runghc"] ===================================== hadrian/src/Rules/Test.hs ===================================== @@ -28,6 +28,10 @@ checkPprProgPath, checkPprSourcePath :: FilePath checkPprProgPath = "test/bin/check-ppr" <.> exe checkPprSourcePath = "utils/check-ppr/Main.hs" +checkExactProgPath, checkExactSourcePath :: FilePath +checkExactProgPath = "test/bin/check-exact" <.> exe +checkExactSourcePath = "utils/check-exact/Main.hs" + checkApiAnnotationsProgPath, checkApiAnnotationsSourcePath :: FilePath checkApiAnnotationsProgPath = "test/bin/check-api-annotations" <.> exe checkApiAnnotationsSourcePath = "utils/check-api-annotations/Main.hs" @@ -35,6 +39,7 @@ checkApiAnnotationsSourcePath = "utils/check-api-annotations/Main.hs" checkPrograms :: [(FilePath, FilePath, Package)] checkPrograms = [ (checkPprProgPath, checkPprSourcePath, checkPpr) + , (checkExactProgPath, checkExactSourcePath, checkExact) , (checkApiAnnotationsProgPath, checkApiAnnotationsSourcePath, checkApiAnnotations) ] @@ -53,8 +58,9 @@ testRules = do -- Reasons why this is required are not entirely clear. cmd ["bash"] ["-c", ghc0Path ++ " " ++ ghcConfigHsPath ++ " -o " ++ (root -/- ghcConfigProgPath)] - -- Rules for building check-ppr and check-ppr-annotations with the compiler - -- we are going to test (in-tree or out-of-tree). + -- Rules for building check-ppr, check-exact and + -- check-ppr-annotations with the compiler we are going to test + -- (in-tree or out-of-tree). forM_ checkPrograms $ \(progPath, sourcePath, progPkg) -> root -/- progPath %> \path -> do need [ sourcePath ] @@ -117,7 +123,9 @@ testRules = do ] pythonPath <- builderPath Python - need [ root -/- checkPprProgPath, root -/- checkApiAnnotationsProgPath ] + need [ root -/- checkPprProgPath + , root -/- checkExactProgPath + , root -/- checkApiAnnotationsProgPath ] -- Set environment variables for test's Makefile. -- TODO: Ideally we would define all those env vars in 'env', so that @@ -133,6 +141,7 @@ testRules = do setEnv "TEST_HC_OPTS" ghcFlags setEnv "TEST_HC_OPTS_INTERACTIVE" ghciFlags setEnv "CHECK_PPR" (top -/- root -/- checkPprProgPath) + setEnv "CHECK_EXACT" (top -/- root -/- checkExactProgPath) setEnv "CHECK_API_ANNOTATIONS" (top -/- root -/- checkApiAnnotationsProgPath) ===================================== hadrian/src/Settings/Builders/Make.hs ===================================== @@ -25,12 +25,14 @@ validateBuilderArgs = builder (Make "testsuite/tests") ? do top <- expr topDirectory compiler <- expr $ fullpath ghc checkPpr <- expr $ fullpath checkPpr + checkExact <- expr $ fullpath checkExact checkApiAnnotations <- expr $ fullpath checkApiAnnotations args <- expr $ userSetting defaultTestArgs return [ setTestSpeed $ testSpeed args , "THREADS=" ++ show threads , "TEST_HC=" ++ (top -/- compiler) , "CHECK_PPR=" ++ (top -/- checkPpr) + , "CHECK_EXACT=" ++ (top -/- checkExact) , "CHECK_API_ANNOTATIONS=" ++ (top -/- checkApiAnnotations) ] where ===================================== testsuite/mk/boilerplate.mk ===================================== @@ -227,6 +227,9 @@ ifeq "$(CHECK_PPR)" "" CHECK_PPR := $(abspath $(TOP)/../inplace/bin/check-ppr) endif +ifeq "$(CHECK_EXACT)" "" +CHECK_EXACT := $(abspath $(TOP)/../inplace/bin/check-exact) +endif # ----------------------------------------------------------------------------- # configuration of TEST_HC View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/18f174bf73f046df5201f389c273fc4e0e5a7ec8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/18f174bf73f046df5201f389c273fc4e0e5a7ec8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 00:03:02 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 13 May 2020 20:03:02 -0400 Subject: [Git][ghc/ghc][master] Predicate, Equivalence derive via `.. -> a -> All' Message-ID: <5ebc8ab638907_616712a9b7f011132843@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 55e35c0b by Baldur Blöndal at 2020-05-13T20:02:48-04:00 Predicate, Equivalence derive via `.. -> a -> All' - - - - - 1 changed file: - libraries/base/Data/Functor/Contravariant.hs Changes: ===================================== libraries/base/Data/Functor/Contravariant.hs ===================================== @@ -1,5 +1,8 @@ +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE DerivingVia #-} {-# LANGUAGE EmptyCase #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} +{-# LANGUAGE InstanceSigs #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE Trustworthy #-} {-# LANGUAGE TypeOperators #-} @@ -53,11 +56,11 @@ import Data.Functor.Product import Data.Functor.Sum import Data.Functor.Compose -import Data.Monoid (Alt(..)) +import Data.Monoid (Alt(..), All(..)) import Data.Proxy import GHC.Generics -import Prelude hiding ((.),id) +import Prelude hiding ((.), id) -- | The class of contravariant functors. -- @@ -76,6 +79,7 @@ import Prelude hiding ((.),id) -- newtype Predicate a = Predicate { getPredicate :: a -> Bool } -- -- instance Contravariant Predicate where +-- contramap :: (a' -> a) -> (Predicate a -> Predicate a') -- contramap f (Predicate p) = Predicate (p . f) -- | `- First, map the input... -- `----- then apply the predicate. @@ -86,7 +90,7 @@ import Prelude hiding ((.),id) -- -- Any instance should be subject to the following laws: -- --- [Identity] @'contramap' 'id' = 'id'@ +-- [Identity] @'contramap' 'id' = 'id'@ -- [Composition] @'contramap' (g . f) = 'contramap' f . 'contramap' g@ -- -- Note, that the second law follows from the free theorem of the type of @@ -94,7 +98,7 @@ import Prelude hiding ((.),id) -- condition holds. class Contravariant f where - contramap :: (a -> b) -> f b -> f a + contramap :: (a' -> a) -> (f a -> f a') -- | Replace all locations in the output with the same value. -- The default definition is @'contramap' . 'const'@, but this may be @@ -110,7 +114,7 @@ class Contravariant f where -- lawful we have the following laws: -- -- @ --- 'fmap' f ≡ 'phantom' +-- 'fmap' f ≡ 'phantom' -- 'contramap' f ≡ 'phantom' -- @ phantom :: (Functor f, Contravariant f) => f a -> f b @@ -123,79 +127,134 @@ infixl 4 >$, $<, >$<, >$$< ($<) = flip (>$) -- | This is an infix alias for 'contramap'. -(>$<) :: Contravariant f => (a -> b) -> f b -> f a +(>$<) :: Contravariant f => (a -> b) -> (f b -> f a) (>$<) = contramap -- | This is an infix version of 'contramap' with the arguments flipped. (>$$<) :: Contravariant f => f b -> (a -> b) -> f a (>$$<) = flip contramap -deriving instance Contravariant f => Contravariant (Alt f) -deriving instance Contravariant f => Contravariant (Rec1 f) -deriving instance Contravariant f => Contravariant (M1 i c f) +deriving newtype instance Contravariant f => Contravariant (Alt f) +deriving newtype instance Contravariant f => Contravariant (Rec1 f) +deriving newtype instance Contravariant f => Contravariant (M1 i c f) instance Contravariant V1 where + contramap :: (a' -> a) -> (V1 a -> V1 a') contramap _ x = case x of instance Contravariant U1 where + contramap :: (a' -> a) -> (U1 a -> U1 a') contramap _ _ = U1 instance Contravariant (K1 i c) where + contramap :: (a' -> a) -> (K1 i c a -> K1 i c a') contramap _ (K1 c) = K1 c instance (Contravariant f, Contravariant g) => Contravariant (f :*: g) where + contramap :: (a' -> a) -> ((f :*: g) a -> (f :*: g) a') contramap f (xs :*: ys) = contramap f xs :*: contramap f ys instance (Functor f, Contravariant g) => Contravariant (f :.: g) where + contramap :: (a' -> a) -> ((f :.: g) a -> (f :.: g) a') contramap f (Comp1 fg) = Comp1 (fmap (contramap f) fg) instance (Contravariant f, Contravariant g) => Contravariant (f :+: g) where + contramap :: (a' -> a) -> ((f :+: g) a -> (f :+: g) a') contramap f (L1 xs) = L1 (contramap f xs) contramap f (R1 ys) = R1 (contramap f ys) instance (Contravariant f, Contravariant g) => Contravariant (Sum f g) where + contramap :: (a' -> a) -> (Sum f g a -> Sum f g a') contramap f (InL xs) = InL (contramap f xs) contramap f (InR ys) = InR (contramap f ys) instance (Contravariant f, Contravariant g) - => Contravariant (Product f g) where - contramap f (Pair a b) = Pair (contramap f a) (contramap f b) + => Contravariant (Product f g) where + contramap :: (a' -> a) -> (Product f g a -> Product f g a') + contramap f (Pair a b) = Pair (contramap f a) (contramap f b) instance Contravariant (Const a) where + contramap :: (b' -> b) -> (Const a b -> Const a b') contramap _ (Const a) = Const a instance (Functor f, Contravariant g) => Contravariant (Compose f g) where + contramap :: (a' -> a) -> (Compose f g a -> Compose f g a') contramap f (Compose fga) = Compose (fmap (contramap f) fga) instance Contravariant Proxy where + contramap :: (a' -> a) -> (Proxy a -> Proxy a') contramap _ _ = Proxy newtype Predicate a = Predicate { getPredicate :: a -> Bool } - --- | A 'Predicate' is a 'Contravariant' 'Functor', because 'contramap' can --- apply its function argument to the input of the predicate. -instance Contravariant Predicate where - contramap f g = Predicate $ getPredicate g . f - -instance Semigroup (Predicate a) where - Predicate p <> Predicate q = Predicate $ \a -> p a && q a - -instance Monoid (Predicate a) where - mempty = Predicate $ const True + deriving + ( -- | @('<>')@ on predicates uses logical conjunction @('&&')@ on + -- the results. Without newtypes this equals @'liftA2' (&&)@. + -- + -- @ + -- (<>) :: Predicate a -> Predicate a -> Predicate a + -- Predicate pred <> Predicate pred' = Predicate \a -> + -- pred a && pred' a + -- @ + Semigroup + , -- | @'mempty'@ on predicates always returns @True at . Without + -- newtypes this equals @'pure' True at . + -- + -- @ + -- mempty :: Predicate a + -- mempty = \_ -> True + -- @ + Monoid + ) + via a -> All + + deriving + ( -- | A 'Predicate' is a 'Contravariant' 'Functor', because + -- 'contramap' can apply its function argument to the input of + -- the predicate. + -- + -- Without newtypes @'contramap' f@ equals precomposing with @f@ + -- (= @(. f)@). + -- + -- @ + -- contramap :: (a' -> a) -> (Predicate a -> Predicate a') + -- contramap f (Predicate g) = Predicate (g . f) + -- @ + Contravariant + ) + via Op Bool -- | Defines a total ordering on a type as per 'compare'. -- -- This condition is not checked by the types. You must ensure that the -- supplied values are valid total orderings yourself. newtype Comparison a = Comparison { getComparison :: a -> a -> Ordering } - -deriving instance Semigroup (Comparison a) -deriving instance Monoid (Comparison a) + deriving + newtype + ( -- | @('<>')@ on comparisons combines results with @('<>') + -- \@Ordering at . Without newtypes this equals @'liftA2' ('liftA2' + -- ('<>'))@. + -- + -- @ + -- (<>) :: Comparison a -> Comparison a -> Comparison a + -- Comparison cmp <> Comparison cmp' = Comparison \a a' -> + -- cmp a a' <> cmp a a' + -- @ + Semigroup + , -- | @'mempty'@ on comparisons always returns @EQ at . Without + -- newtypes this equals @'pure' ('pure' EQ)@. + -- + -- @ + -- mempty :: Comparison a + -- mempty = Comparison \_ _ -> EQ + -- @ + Monoid + ) -- | A 'Comparison' is a 'Contravariant' 'Functor', because 'contramap' can -- apply its function argument to each input of the comparison function. instance Contravariant Comparison where - contramap f g = Comparison $ on (getComparison g) f + contramap :: (a' -> a) -> (Comparison a -> Comparison a') + contramap f (Comparison g) = Comparison (on g f) -- | Compare using 'compare'. defaultComparison :: Ord a => Comparison a @@ -214,18 +273,34 @@ defaultComparison = Comparison compare -- The types alone do not enforce these laws, so you'll have to check them -- yourself. newtype Equivalence a = Equivalence { getEquivalence :: a -> a -> Bool } + deriving + ( -- | @('<>')@ on equivalences uses logical conjunction @('&&')@ + -- on the results. Without newtypes this equals @'liftA2' + -- ('liftA2' (&&))@. + -- + -- @ + -- (<>) :: Equivalence a -> Equivalence a -> Equivalence a + -- Equivalence equiv <> Equivalence equiv' = Equivalence \a b -> + -- equiv a b && equiv a b + -- @ + Semigroup + , -- | @'mempty'@ on equivalences always returns @True at . Without + -- newtypes this equals @'pure' ('pure' True)@. + -- + -- @ + -- mempty :: Equivalence a + -- mempty = Equivalence \_ _ -> True + -- @ + Monoid + ) + via a -> a -> All -- | Equivalence relations are 'Contravariant', because you can -- apply the contramapped function to each input to the equivalence -- relation. instance Contravariant Equivalence where - contramap f g = Equivalence $ on (getEquivalence g) f - -instance Semigroup (Equivalence a) where - Equivalence p <> Equivalence q = Equivalence $ \a b -> p a b && q a b - -instance Monoid (Equivalence a) where - mempty = Equivalence (\_ _ -> True) + contramap :: (a' -> a) -> (Equivalence a -> Equivalence a') + contramap f (Equivalence g) = Equivalence (on g f) -- | Check for equivalence with '=='. -- @@ -238,15 +313,36 @@ comparisonEquivalence (Comparison p) = Equivalence $ \a b -> p a b == EQ -- | Dual function arrows. newtype Op a b = Op { getOp :: b -> a } - -deriving instance Semigroup a => Semigroup (Op a b) -deriving instance Monoid a => Monoid (Op a b) + deriving + newtype + ( -- | @('<>') \@(Op a b)@ without newtypes is @('<>') \@(b->a)@ = + -- @liftA2 ('<>')@. This lifts the 'Semigroup' operation + -- @('<>')@ over the output of @a at . + -- + -- @ + -- (<>) :: Op a b -> Op a b -> Op a b + -- Op f <> Op g = Op \a -> f a <> g a + -- @ + Semigroup + , -- | @'mempty' \@(Op a b)@ without newtypes is @mempty \@(b->a)@ + -- = @\_ -> mempty at . + -- + -- @ + -- mempty :: Op a b + -- mempty = Op \_ -> mempty + -- @ + Monoid + ) instance Category Op where + id :: Op a a id = Op id + + (.) :: Op b c -> Op a b -> Op a c Op f . Op g = Op (g . f) instance Contravariant (Op a) where + contramap :: (b' -> b) -> (Op a b -> Op a b') contramap f g = Op (getOp g . f) instance Num a => Num (Op a b) where View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/55e35c0b7e0f4b907dc21d42827b1cea4317226e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/55e35c0b7e0f4b907dc21d42827b1cea4317226e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 00:03:47 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 13 May 2020 20:03:47 -0400 Subject: [Git][ghc/ghc][master] hadrian: add a --freeze2 option to freeze stage 1 and 2 Message-ID: <5ebc8ae33163a_61671288ff4c11137681@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: d7e0b57f by Alp Mestanogullari at 2020-05-13T20:03:30-04:00 hadrian: add a --freeze2 option to freeze stage 1 and 2 - - - - - 3 changed files: - hadrian/README.md - hadrian/src/CommandLine.hs - hadrian/src/Main.hs Changes: ===================================== hadrian/README.md ===================================== @@ -101,6 +101,9 @@ time when you are working on a feature that affects both Stage1 and Stage2 compilers, but may lead to incorrect build results. To unfreeze Stage1 GHC simply drop the `--freeze1` flag and Hadrian will rebuild all out-of-date files. +* `--freeze2`: just like `--freeze1` but tell Hadrian to additionally freeze +Stage2 GHC. + * `--integer-simple`: build GHC using the `integer-simple` integer library (instead of `integer-gmp`). ===================================== hadrian/src/CommandLine.hs ===================================== @@ -1,6 +1,6 @@ module CommandLine ( - optDescrs, cmdLineArgsMap, cmdFlavour, lookupFreeze1, cmdIntegerSimple, - cmdProgressInfo, cmdConfigure, cmdCompleteSetting, + optDescrs, cmdLineArgsMap, cmdFlavour, lookupFreeze1, lookupFreeze2, + cmdIntegerSimple, cmdProgressInfo, cmdConfigure, cmdCompleteSetting, cmdDocsArgs, lookupBuildRoot, TestArgs(..), TestSpeed(..), defaultTestArgs ) where @@ -24,6 +24,7 @@ data CommandLineArgs = CommandLineArgs { configure :: Bool , flavour :: Maybe String , freeze1 :: Bool + , freeze2 :: Bool , integerSimple :: Bool , progressInfo :: ProgressInfo , buildRoot :: BuildRoot @@ -38,6 +39,7 @@ defaultCommandLineArgs = CommandLineArgs { configure = False , flavour = Nothing , freeze1 = False + , freeze2 = False , integerSimple = False , progressInfo = Brief , buildRoot = BuildRoot "_build" @@ -100,8 +102,9 @@ readBuildRoot ms = set :: BuildRoot -> CommandLineArgs -> CommandLineArgs set flag flags = flags { buildRoot = flag } -readFreeze1 :: Either String (CommandLineArgs -> CommandLineArgs) +readFreeze1, readFreeze2 :: Either String (CommandLineArgs -> CommandLineArgs) readFreeze1 = Right $ \flags -> flags { freeze1 = True } +readFreeze2 = Right $ \flags -> flags { freeze1 = True, freeze2 = True } readIntegerSimple :: Either String (CommandLineArgs -> CommandLineArgs) readIntegerSimple = Right $ \flags -> flags { integerSimple = True } @@ -239,6 +242,8 @@ optDescrs = "Build flavour (Default, Devel1, Devel2, Perf, Prof, Quick or Quickest)." , Option [] ["freeze1"] (NoArg readFreeze1) "Freeze Stage1 GHC." + , Option [] ["freeze2"] (NoArg readFreeze2) + "Freeze Stage2 GHC." , Option [] ["integer-simple"] (NoArg readIntegerSimple) "Build GHC with integer-simple library." , Option [] ["progress-info"] (OptArg readProgressInfo "STYLE") @@ -336,6 +341,9 @@ lookupBuildRoot = buildRoot . lookupExtra defaultCommandLineArgs lookupFreeze1 :: Map.HashMap TypeRep Dynamic -> Bool lookupFreeze1 = freeze1 . lookupExtra defaultCommandLineArgs +lookupFreeze2 :: Map.HashMap TypeRep Dynamic -> Bool +lookupFreeze2 = freeze2 . lookupExtra defaultCommandLineArgs + cmdIntegerSimple :: Action Bool cmdIntegerSimple = integerSimple <$> cmdLineArgs ===================================== hadrian/src/Main.hs ===================================== @@ -30,7 +30,12 @@ main = do BuildRoot buildRoot = CommandLine.lookupBuildRoot argsMap rebuild = [ (RebuildLater, buildRoot -/- "stage0/**") - | CommandLine.lookupFreeze1 argsMap ] + | CommandLine.lookupFreeze1 argsMap || + CommandLine.lookupFreeze2 argsMap + ] ++ + [ (RebuildLater, buildRoot -/- "stage1/**") + | CommandLine.lookupFreeze2 argsMap + ] cwd <- getCurrentDirectory shakeColor <- shouldUseColor View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d7e0b57fda289e2715e7be86d4871503e3c09ee8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d7e0b57fda289e2715e7be86d4871503e3c09ee8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 00:04:22 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 13 May 2020 20:04:22 -0400 Subject: [Git][ghc/ghc][master] Don't reload environment files on every setSessionDynFlags Message-ID: <5ebc8b069981e_616711a31edc1114097b@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: d880d6b2 by Artem Pelenitsyn at 2020-05-13T20:04:11-04:00 Don't reload environment files on every setSessionDynFlags Makes `interpretPackageEnv` (which loads envirinment files) a part of `parseDynamicFlags` (parsing command-line arguments, which is typically done once) instead of `setSessionDynFlags` (which is typically called several times). Making several (transitive) calls to `interpretPackageEnv`, as before, caused #18125 #16318, which should be fixed now. - - - - - 6 changed files: - compiler/GHC.hs - + testsuite/tests/driver/T16318/Makefile - + testsuite/tests/driver/T16318/all.T - + testsuite/tests/driver/T18125/Makefile - + testsuite/tests/driver/T18125/T18125.hs - + testsuite/tests/driver/T18125/all.T Changes: ===================================== compiler/GHC.hs ===================================== @@ -597,8 +597,7 @@ checkBrokenTablesNextToCode' dflags setSessionDynFlags :: GhcMonad m => DynFlags -> m [UnitId] setSessionDynFlags dflags = do dflags' <- checkNewDynFlags dflags - dflags'' <- liftIO $ interpretPackageEnv dflags' - (dflags''', preload) <- liftIO $ initPackages dflags'' + (dflags''', preload) <- liftIO $ initPackages dflags' -- Interpreter interp <- if gopt Opt_ExternalInterpreter dflags @@ -715,7 +714,11 @@ getInteractiveDynFlags = withSession $ \h -> return (ic_dflags (hsc_IC h)) parseDynamicFlags :: MonadIO m => DynFlags -> [Located String] -> m (DynFlags, [Located String], [Warn]) -parseDynamicFlags = parseDynamicFlagsCmdLine +parseDynamicFlags dflags cmdline = do + (dflags1, leftovers, warns) <- parseDynamicFlagsCmdLine dflags cmdline + dflags2 <- liftIO $ interpretPackageEnv dflags1 + return (dflags2, leftovers, warns) + -- | Checks the set of new DynFlags for possibly erroneous option -- combinations when invoking 'setSessionDynFlags' and friends, and if ===================================== testsuite/tests/driver/T16318/Makefile ===================================== @@ -0,0 +1,11 @@ +TOP=../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +test_pe = test-package-environment + +T16318: + $(GHC_PKG) latest base > $(test_pe) + "$(TEST_HC)" $(TEST_HC_OPTS) -v1 -package-env $(test_pe) -e "putStrLn \"Hello\"" > out 2>&1 + C=`cat out | grep "Loaded package environment" -c` ; \ + if [ $$C != "1" ]; then false; fi ===================================== testsuite/tests/driver/T16318/all.T ===================================== @@ -0,0 +1 @@ +test('T16318', normal, makefile_test, []) ===================================== testsuite/tests/driver/T18125/Makefile ===================================== @@ -0,0 +1,13 @@ +TOP=../../.. +include $(TOP)/mk/boilerplate.mk +include $(TOP)/mk/test.mk + +test_pe = test-package-environment +test_lib = containers + +T18125: + $(GHC_PKG) latest base > $(test_pe) + $(GHC_PKG) latest $(test_lib) >> $(test_pe) + "$(TEST_HC)" $(TEST_HC_OPTS) -Wunused-packages -package-env $(test_pe) T18125.hs > out 2>&1 + C=`cat out | grep "$(test_lib)" -c` ; \ + if [ $$C != "1" ]; then false; fi ===================================== testsuite/tests/driver/T18125/T18125.hs ===================================== @@ -0,0 +1,2 @@ +module Main where +main = putStrLn "hello world" ===================================== testsuite/tests/driver/T18125/all.T ===================================== @@ -0,0 +1 @@ +test('T18125', normal, makefile_test, []) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d880d6b2e48268f5ed4d3eb751fe24cc833e9221 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d880d6b2e48268f5ed4d3eb751fe24cc833e9221 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 00:05:06 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 13 May 2020 20:05:06 -0400 Subject: [Git][ghc/ghc][master] Factor out HsPatSigType for pat sigs/RULE term sigs (#16762) Message-ID: <5ebc8b32d62ac_6167119ebbd011144132@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 102cfd67 by Ryan Scott at 2020-05-13T20:04:46-04:00 Factor out HsPatSigType for pat sigs/RULE term sigs (#16762) This implements chunks (2) and (3) of https://gitlab.haskell.org/ghc/ghc/issues/16762#note_270170. Namely, it introduces a dedicated `HsPatSigType` AST type, which represents the types that can appear in pattern signatures and term-level `RULE` binders. Previously, these were represented with `LHsSigWcType`. Although `LHsSigWcType` is isomorphic to `HsPatSigType`, the intended semantics of the two types are slightly different, as evidenced by the fact that they have different code paths in the renamer and typechecker. See also the new `Note [Pattern signature binders and scoping]` in `GHC.Hs.Types`. - - - - - 18 changed files: - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Extension.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Types.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Pat.hs - compiler/GHC/Tc/Gen/Rule.hs - compiler/GHC/ThToHs.hs - testsuite/tests/hiefile/should_compile/hie007.hs Changes: ===================================== compiler/GHC/Hs/Decls.hs ===================================== @@ -2244,7 +2244,7 @@ type LRuleBndr pass = Located (RuleBndr pass) -- | Rule Binder data RuleBndr pass = RuleBndr (XCRuleBndr pass) (Located (IdP pass)) - | RuleBndrSig (XRuleBndrSig pass) (Located (IdP pass)) (LHsSigWcType pass) + | RuleBndrSig (XRuleBndrSig pass) (Located (IdP pass)) (HsPatSigType pass) | XRuleBndr !(XXRuleBndr pass) -- ^ -- - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnOpen', @@ -2256,7 +2256,7 @@ type instance XCRuleBndr (GhcPass _) = NoExtField type instance XRuleBndrSig (GhcPass _) = NoExtField type instance XXRuleBndr (GhcPass _) = NoExtCon -collectRuleBndrSigTys :: [RuleBndr pass] -> [LHsSigWcType pass] +collectRuleBndrSigTys :: [RuleBndr pass] -> [HsPatSigType pass] collectRuleBndrSigTys bndrs = [ty | RuleBndrSig _ _ ty <- bndrs] pprFullRuleName :: Located (SourceText, RuleName) -> SDoc ===================================== compiler/GHC/Hs/Extension.hs ===================================== @@ -685,6 +685,11 @@ type family XXHsWildCardBndrs x b -- ------------------------------------- +type family XHsPS x +type family XXHsPatSigType x + +-- ------------------------------------- + type family XForAllTy x type family XQualTy x type family XTyVar x ===================================== compiler/GHC/Hs/Instances.hs ===================================== @@ -386,6 +386,11 @@ deriving instance (Data thing) => Data (HsWildCardBndrs GhcPs thing) deriving instance (Data thing) => Data (HsWildCardBndrs GhcRn thing) deriving instance (Data thing) => Data (HsWildCardBndrs GhcTc thing) +-- deriving instance (DataIdLR p p) => Data (HsPatSigType p) +deriving instance Data (HsPatSigType GhcPs) +deriving instance Data (HsPatSigType GhcRn) +deriving instance Data (HsPatSigType GhcTc) + -- deriving instance (DataIdLR p p) => Data (HsTyVarBndr p) deriving instance Data (HsTyVarBndr GhcPs) deriving instance Data (HsTyVarBndr GhcRn) ===================================== compiler/GHC/Hs/Pat.hs ===================================== @@ -240,7 +240,7 @@ data Pat p -- For details on above see note [Api annotations] in GHC.Parser.Annotation | SigPat (XSigPat p) -- After typechecker: Type (LPat p) -- Pattern with a type signature - (LHsSigWcType (NoGhcTc p)) -- Signature can bind both + (HsPatSigType (NoGhcTc p)) -- Signature can bind both -- kind and type vars -- ^ Pattern with a type signature ===================================== compiler/GHC/Hs/Types.hs ===================================== @@ -23,6 +23,7 @@ module GHC.Hs.Types ( LHsQTyVars(..), HsImplicitBndrs(..), HsWildCardBndrs(..), + HsPatSigType(..), HsPSRn(..), LHsSigType, LHsSigWcType, LHsWcType, HsTupleSort(..), HsContext, LHsContext, noLHsContext, @@ -47,7 +48,7 @@ module GHC.Hs.Types ( mkAnonWildCardTy, pprAnonWildCard, - mkHsImplicitBndrs, mkHsWildCardBndrs, hsImplicitBody, + mkHsImplicitBndrs, mkHsWildCardBndrs, mkHsPatSigType, hsImplicitBody, mkEmptyImplicitBndrs, mkEmptyWildCardBndrs, mkHsQTvs, hsQTvExplicit, emptyLHsQTvs, isEmptyLHsQTvs, isHsKindedTyVar, hsTvbAllKinded, isLHsForAllTy, @@ -59,7 +60,7 @@ module GHC.Hs.Types ( splitLHsForAllTyInvis, splitLHsQualTy, splitLHsSigmaTyInvis, splitHsFunType, hsTyGetAppHead_maybe, mkHsOpTy, mkHsAppTy, mkHsAppTys, mkHsAppKindTy, - ignoreParens, hsSigType, hsSigWcType, + ignoreParens, hsSigType, hsSigWcType, hsPatSigType, hsLTyVarBndrToType, hsLTyVarBndrsToTypes, hsTyKindSig, hsConDetailsArgs, @@ -184,6 +185,13 @@ is a bit complicated. Here's how it works. f :: _a -> _ The enclosing HsWildCardBndrs binds the wildcards _a and _. +* HsSigPatType describes types that appear in pattern signatures and + the signatures of term-level binders in RULES. Like + HsWildCardBndrs/HsImplicitBndrs, they track the names of wildcard + variables and implicitly bound type variables. Unlike + HsImplicitBndrs, however, HsSigPatTypes do not obey the + forall-or-nothing rule. See Note [Pattern signature binders and scoping]. + * The explicit presence of these wrappers specifies, in the HsSyn, exactly where implicit quantification is allowed, and where wildcards are allowed. @@ -225,13 +233,15 @@ Note carefully: Here _a is an ordinary forall'd binder, but (With NamedWildCards) _b is a named wildcard. (See the comments in #10982) -* Named wildcards are bound by the HsWildCardBndrs construct, which wraps - types that are allowed to have wildcards. Unnamed wildcards however are left - unchanged until typechecking, where we give them fresh wild tyavrs and - determine whether or not to emit hole constraints on each wildcard - (we don't if it's a visible type/kind argument or a type family pattern). - See related notes Note [Wildcards in visible kind application] - and Note [Wildcards in visible type application] in GHC.Tc.Gen.HsType +* Named wildcards are bound by the HsWildCardBndrs (for types that obey the + forall-or-nothing rule) and HsPatSigType (for type signatures in patterns + and term-level binders in RULES), which wrap types that are allowed to have + wildcards. Unnamed wildcards, however are left unchanged until typechecking, + where we give them fresh wild tyvars and determine whether or not to emit + hole constraints on each wildcard (we don't if it's a visible type/kind + argument or a type family pattern). See related notes + Note [Wildcards in visible kind application] and + Note [Wildcards in visible type application] in GHC.Tc.Gen.HsType. * After type checking is done, we report what types the wildcards got unified with. @@ -399,6 +409,33 @@ type instance XHsWC GhcTc b = [Name] type instance XXHsWildCardBndrs (GhcPass _) b = NoExtCon +-- | Types that can appear in pattern signatures, as well as the signatures for +-- term-level binders in RULES. +-- See @Note [Pattern signature binders and scoping]@. +-- +-- This is very similar to 'HsSigWcType', but with +-- slightly different semantics: see @Note [HsType binders]@. +-- See also @Note [The wildcard story for types]@. +data HsPatSigType pass + = HsPS { hsps_ext :: XHsPS pass -- ^ After renamer: 'HsPSRn' + , hsps_body :: LHsType pass -- ^ Main payload (the type itself) + } + | XHsPatSigType !(XXHsPatSigType pass) + +-- | The extension field for 'HsPatSigType', which is only used in the +-- renamer onwards. See @Note [Pattern signature binders and scoping]@. +data HsPSRn = HsPSRn + { hsps_nwcs :: [Name] -- ^ Wildcard names + , hsps_imp_tvs :: [Name] -- ^ Implicitly bound variable names + } + deriving Data + +type instance XHsPS GhcPs = NoExtField +type instance XHsPS GhcRn = HsPSRn +type instance XHsPS GhcTc = HsPSRn + +type instance XXHsPatSigType (GhcPass _) = NoExtCon + -- | Located Haskell Signature Type type LHsSigType pass = HsImplicitBndrs pass (LHsType pass) -- Implicit only @@ -419,6 +456,9 @@ hsSigType = hsImplicitBody hsSigWcType :: LHsSigWcType pass -> LHsType pass hsSigWcType sig_ty = hsib_body (hswc_body sig_ty) +hsPatSigType :: HsPatSigType pass -> LHsType pass +hsPatSigType = hsps_body + dropWildCards :: LHsSigWcType pass -> LHsSigType pass -- Drop the wildcard part of a LHsSigWcType dropWildCards sig_ty = hswc_body sig_ty @@ -441,6 +481,71 @@ we get , hst_body = blah } The implicit kind variable 'k' is bound by the HsIB; the explicitly forall'd tyvar 'a' is bound by the HsForAllTy + +Note [Pattern signature binders and scoping] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider the pattern signatures like those on `t` and `g` in: + + f = let h = \(t :: (b, b) -> + \(g :: forall a. a -> b) -> + ...(t :: (Int,Int))... + in woggle + +* The `b` in t's pattern signature is implicitly bound and scopes over + the signature and the body of the lambda. It stands for a type (any type); + indeed we subsequently discover that b=Int. + (See Note [TyVarTv] in GHC.Tc.Utils.TcMType for more on this point.) +* The `b` in g's pattern signature is an /occurrence/ of the `b` bound by + t's pattern signature. +* The `a` in `forall a` scopes only over the type `a -> b`, not over the body + of the lambda. +* There is no forall-or-nothing rule for pattern signatures, which is why the + type `forall a. a -> b` is permitted in `g`'s pattern signature, even though + `b` is not explicitly bound. + See Note [forall-or-nothing rule] in GHC.Rename.HsType. + +Similar scoping rules apply to term variable binders in RULES, like in the +following example: + + {-# RULES "h" forall (t :: (b, b)) (g :: forall a. a -> b). h t g = ... #-} + +Just like in pattern signatures, the `b` in t's signature is implicitly bound +and scopes over the remainder of the RULE. As a result, the `b` in g's +signature is an occurrence. Moreover, the `a` in `forall a` scopes only over +the type `a -> b`, and the forall-or-nothing rule does not apply. + +While quite similar, RULE term binder signatures behave slightly differently +from pattern signatures in two ways: + +1. Unlike in pattern signatures, where type variables can stand for any type, + type variables in RULE term binder signatures are skolems. + See Note [Typechecking pattern signature binders] in GHC.Tc.Gen.HsType for + more on this point. + + In this sense, type variables in pattern signatures are quite similar to + named wildcards, as both can refer to arbitrary types. The main difference + lies in error reporting: if a named wildcard `_a` in a pattern signature + stands for Int, then by default GHC will emit a warning stating as much. + Changing `_a` to `a`, on the other hand, will cause it not to be reported. +2. In the `h` RULE above, only term variables are explicitly bound, so any free + type variables in the term variables' signatures are implicitly bound. + This is just like how the free type variables in pattern signatures are + implicitly bound. If a RULE explicitly binds both term and type variables, + however, then free type variables in term signatures are /not/ implicitly + bound. For example, this RULE would be ill scoped: + + {-# RULES "h2" forall b. forall (t :: (b, c)) (g :: forall a. a -> b). + h2 t g = ... #-} + + This is because `b` and `c` occur free in the signature for `t`, but only + `b` was explicitly bound, leaving `c` out of scope. If the RULE had started + with `forall b c.`, then it would have been accepted. + +The types in pattern signatures and RULE term binder signatures are represented +in the AST by HsSigPatType. From the renamer onward, the hsps_ext field (of +type HsPSRn) tracks the names of named wildcards and implicitly bound type +variables so that they can be brought into scope during renaming and +typechecking. -} mkHsImplicitBndrs :: thing -> HsImplicitBndrs GhcPs thing @@ -451,6 +556,10 @@ mkHsWildCardBndrs :: thing -> HsWildCardBndrs GhcPs thing mkHsWildCardBndrs x = HsWC { hswc_body = x , hswc_ext = noExtField } +mkHsPatSigType :: LHsType GhcPs -> HsPatSigType GhcPs +mkHsPatSigType x = HsPS { hsps_ext = noExtField + , hsps_body = x } + -- Add empty binders. This is a bit suspicious; what if -- the wrapped thing had free type variables? mkEmptyImplicitBndrs :: thing -> HsImplicitBndrs GhcRn thing @@ -1408,6 +1517,10 @@ instance Outputable thing => Outputable (HsWildCardBndrs (GhcPass p) thing) where ppr (HsWC { hswc_body = ty }) = ppr ty +instance OutputableBndrId p + => Outputable (HsPatSigType (GhcPass p)) where + ppr (HsPS { hsps_body = ty }) = ppr ty + pprAnonWildCard :: SDoc pprAnonWildCard = char '_' ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -821,7 +821,7 @@ repRuleD (L loc (HsRule { rd_name = n ruleBndrNames :: LRuleBndr GhcRn -> [Name] ruleBndrNames (L _ (RuleBndr _ n)) = [unLoc n] ruleBndrNames (L _ (RuleBndrSig _ n sig)) - | HsWC { hswc_body = HsIB { hsib_ext = vars }} <- sig + | HsPS { hsps_ext = HsPSRn { hsps_imp_tvs = vars }} <- sig = unLoc n : vars repRuleBndr :: LRuleBndr GhcRn -> MetaM (Core (M TH.RuleBndr)) @@ -830,7 +830,7 @@ repRuleBndr (L _ (RuleBndr _ n)) ; rep2 ruleVarName [n'] } repRuleBndr (L _ (RuleBndrSig _ n sig)) = do { MkC n' <- lookupLBinder n - ; MkC ty' <- repLTy (hsSigWcType sig) + ; MkC ty' <- repLTy (hsPatSigType sig) ; rep2 typedRuleVarName [n', ty'] } repAnnD :: LAnnDecl GhcRn -> MetaM (SrcSpan, Core (M TH.Dec)) @@ -1935,7 +1935,7 @@ repP (NPat _ (L _ l) Nothing _) = do { a <- repOverloadedLiteral l repP (ViewPat _ e p) = do { e' <- repLE e; p' <- repLP p; repPview e' p' } repP p@(NPat _ _ (Just _) _) = notHandled "Negative overloaded patterns" (ppr p) repP (SigPat _ p t) = do { p' <- repLP p - ; t' <- repLTy (hsSigWcType t) + ; t' <- repLTy (hsPatSigType t) ; repPsig p' t' } repP (SplicePat _ splice) = repSplice splice repP other = notHandled "Exotic pattern" (ppr other) ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -413,35 +413,9 @@ bar (x :: forall a. a -> a) = ... -- a is not in scope here -- ^ a is in scope here (pattern body) bax (x :: a) = ... -- a is in scope here -Because of HsWC and HsIB pass on their scope to their children -we must wrap the LHsType in pattern signatures in a -Shielded explicitly, so that the HsWC/HsIB scope is not passed -on the the LHsType --} - -data Shielded a = SH Scope a -- Ignores its TScope, uses its own scope instead - -type family ProtectedSig a where - ProtectedSig GhcRn = HsWildCardBndrs GhcRn (HsImplicitBndrs - GhcRn - (Shielded (LHsType GhcRn))) - ProtectedSig GhcTc = NoExtField - -class ProtectSig a where - protectSig :: Scope -> LHsSigWcType (NoGhcTc a) -> ProtectedSig a - -instance (HasLoc a) => HasLoc (Shielded a) where - loc (SH _ a) = loc a - -instance (ToHie (TScoped a)) => ToHie (TScoped (Shielded a)) where - toHie (TS _ (SH sc a)) = toHie (TS (ResolvedScopes [sc]) a) -instance ProtectSig GhcTc where - protectSig _ _ = noExtField - -instance ProtectSig GhcRn where - protectSig sc (HsWC a (HsIB b sig)) = - HsWC a (HsIB b (SH sc sig)) +This case in handled in the instance for HsPatSigType +-} class HasLoc a where -- ^ defined so that HsImplicitBndrs and HsWildCardBndrs can @@ -770,8 +744,6 @@ instance ( a ~ GhcPass p , ToHie (RContext (HsRecFields a (PScoped (LPat a)))) , ToHie (LHsExpr a) , ToHie (TScoped (LHsSigWcType a)) - , ProtectSig a - , ToHie (TScoped (ProtectedSig a)) , HasType (LPat a) , Data (HsSplice a) , IsPass p @@ -832,9 +804,12 @@ instance ( a ~ GhcPass p SigPat _ pat sig -> [ toHie $ PS rsp scope pscope pat , let cscope = mkLScope pat in - toHie $ TS (ResolvedScopes [cscope, scope, pscope]) - (protectSig @a cscope sig) - -- See Note [Scoping Rules for SigPat] + case ghcPass @p of + GhcPs -> pure [] + GhcTc -> pure [] + GhcRn -> + toHie $ TS (ResolvedScopes [cscope, scope, pscope]) + sig ] XPat e -> case ghcPass @p of #if __GLASGOW_HASKELL__ < 811 @@ -856,6 +831,13 @@ instance ( a ~ GhcPass p L spn $ HsRecField lbl (PS rsp scope fscope pat) pun scoped_fds = listScopes pscope fds +instance ToHie (TScoped (HsPatSigType GhcRn)) where + toHie (TS sc (HsPS (HsPSRn wcs tvs) body@(L span _))) = concatM $ + [ pure $ bindingsOnly $ map (C $ TyVarBind (mkScope span) sc) (wcs++tvs) + , toHie body + ] + -- See Note [Scoping Rules for SigPat] + instance ( ToHie body , ToHie (LGRHS a body) , ToHie (RScoped (LHsLocalBinds a)) ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -874,7 +874,7 @@ mkRuleBndrs :: [LRuleTyTmVar] -> [LRuleBndr GhcPs] mkRuleBndrs = fmap (fmap cvt_one) where cvt_one (RuleTyTmVar v Nothing) = RuleBndr noExtField v cvt_one (RuleTyTmVar v (Just sig)) = - RuleBndrSig noExtField v (mkLHsSigWcType sig) + RuleBndrSig noExtField v (mkHsPatSigType sig) -- turns RuleTyTmVars into HsTyVarBndrs - this is more interesting mkRuleTyVarBndrs :: [LRuleTyTmVar] -> [LHsTyVarBndr GhcPs] @@ -2033,7 +2033,7 @@ instance DisambECP (PatBuilder GhcPs) where mkHsWildCardPV l = return $ L l (PatBuilderPat (WildPat noExtField)) mkHsTySigPV l b sig = do p <- checkLPat b - return $ L l (PatBuilderPat (SigPat noExtField p (mkLHsSigWcType sig))) + return $ L l (PatBuilderPat (SigPat noExtField p (mkHsPatSigType sig))) mkHsExplicitListPV l xs = do ps <- traverse checkLPat xs return (L l (PatBuilderPat (ListPat noExtField ps))) ===================================== compiler/GHC/Rename/Bind.hs ===================================== @@ -955,7 +955,7 @@ renameSig _ (IdSig _ x) renameSig ctxt sig@(TypeSig _ vs ty) = do { new_vs <- mapM (lookupSigOccRn ctxt sig) vs ; let doc = TypeSigCtx (ppr_sig_bndrs vs) - ; (new_ty, fvs) <- rnHsSigWcType BindUnlessForall doc ty + ; (new_ty, fvs) <- rnHsSigWcType doc ty ; return (TypeSig noExtField new_vs new_ty, fvs) } renameSig ctxt sig@(ClassOpSig _ is_deflt vs ty) ===================================== compiler/GHC/Rename/Expr.hs ===================================== @@ -316,7 +316,7 @@ rnExpr (RecordUpd { rupd_expr = expr, rupd_flds = rbinds }) , fvExpr `plusFV` fvRbinds) } rnExpr (ExprWithTySig _ expr pty) - = do { (pty', fvTy) <- rnHsSigWcType BindUnlessForall ExprWithTySigCtx pty + = do { (pty', fvTy) <- rnHsSigWcType ExprWithTySigCtx pty ; (expr', fvExpr) <- bindSigTyVarsFV (hsWcScopedTvs pty') $ rnLExpr expr ; return (ExprWithTySig noExtField expr' pty', fvExpr `plusFV` fvTy) } ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -13,7 +13,7 @@ module GHC.Rename.HsType ( rnHsType, rnLHsType, rnLHsTypes, rnContext, rnHsKind, rnLHsKind, rnLHsTypeArgs, rnHsSigType, rnHsWcType, - HsSigWcTypeScoping(..), rnHsSigWcType, rnHsSigWcTypeScoped, + HsSigWcTypeScoping(..), rnHsSigWcType, rnHsPatSigType, newTyVarNameRn, rnConDeclFields, rnLTyVar, @@ -71,11 +71,11 @@ import Control.Monad ( unless, when ) {- These type renamers are in a separate module, rather than in (say) GHC.Rename.Module, -to break several loop. +to break several loops. ********************************************************* * * - HsSigWcType (i.e with wildcards) + HsSigWcType and HsPatSigType (i.e with wildcards) * * ********************************************************* -} @@ -85,46 +85,77 @@ data HsSigWcTypeScoping -- ^ Always bind any free tyvars of the given type, regardless of whether we -- have a forall at the top. -- - -- For pattern type sigs and rules we /do/ want to bring those type + -- For pattern type sigs, we /do/ want to bring those type -- variables into scope, even if there's a forall at the top which usually -- stops that happening, e.g: -- - -- > \ (x :: forall a. a-> b) -> e + -- > \ (x :: forall a. a -> b) -> e -- -- Here we do bring 'b' into scope. + -- + -- RULES can also use 'AlwaysBind', such as in the following example: + -- + -- > {-# RULES \"f\" forall (x :: forall a. a -> b). f x = ... b ... #-} + -- + -- This only applies to RULES that do not explicitly bind their type + -- variables. If a RULE explicitly quantifies its type variables, then + -- 'NeverBind' is used instead. See also + -- @Note [Pattern signature binders and scoping]@ in "GHC.Hs.Types". | BindUnlessForall - -- ^ Unless there's forall at the top, do the same thing as 'AlwaysBind' + -- ^ Unless there's forall at the top, do the same thing as 'AlwaysBind'. + -- This is only ever used in places where the \"@forall at -or-nothing\" rule + -- is in effect. See @Note [forall-or-nothing rule]@. | NeverBind - -- ^ Never bind any free tyvars - -rnHsSigWcType :: HsSigWcTypeScoping -> HsDocContext -> LHsSigWcType GhcPs + -- ^ Never bind any free tyvars. This is used for RULES that have both + -- explicit type and term variable binders, e.g.: + -- + -- > {-# RULES \"const\" forall a. forall (x :: a) y. const x y = x #-} + -- + -- The presence of the type variable binder @forall a.@ implies that the + -- free variables in the types of the term variable binders @x@ and @y@ + -- are /not/ bound. In the example above, there are no such free variables, + -- but if the user had written @(y :: b)@ instead of @y@ in the term + -- variable binders, then @b@ would be rejected for being out of scope. + -- See also @Note [Pattern signature binders and scoping]@ in + -- "GHC.Hs.Types". + +rnHsSigWcType :: HsDocContext -> LHsSigWcType GhcPs -> RnM (LHsSigWcType GhcRn, FreeVars) -rnHsSigWcType scoping doc sig_ty - = rn_hs_sig_wc_type scoping doc sig_ty $ \sig_ty' -> - return (sig_ty', emptyFVs) - -rnHsSigWcTypeScoped :: HsSigWcTypeScoping - -> HsDocContext -> LHsSigWcType GhcPs - -> (LHsSigWcType GhcRn -> RnM (a, FreeVars)) - -> RnM (a, FreeVars) +rnHsSigWcType doc (HsWC { hswc_body = HsIB { hsib_body = hs_ty }}) + = rn_hs_sig_wc_type BindUnlessForall doc hs_ty $ \nwcs imp_tvs body -> + let ib_ty = HsIB { hsib_ext = imp_tvs, hsib_body = body } + wc_ty = HsWC { hswc_ext = nwcs, hswc_body = ib_ty } in + pure (wc_ty, emptyFVs) + +rnHsPatSigType :: HsSigWcTypeScoping + -> HsDocContext -> HsPatSigType GhcPs + -> (HsPatSigType GhcRn -> RnM (a, FreeVars)) + -> RnM (a, FreeVars) -- Used for --- - Signatures on binders in a RULE --- - Pattern type signatures +-- - Pattern type signatures, which are only allowed with ScopedTypeVariables +-- - Signatures on binders in a RULE, which are allowed even if +-- ScopedTypeVariables isn't enabled -- Wildcards are allowed --- type signatures on binders only allowed with ScopedTypeVariables -rnHsSigWcTypeScoped scoping ctx sig_ty thing_inside +-- +-- See Note [Pattern signature binders and scoping] in GHC.Hs.Types +rnHsPatSigType scoping ctx sig_ty thing_inside = do { ty_sig_okay <- xoptM LangExt.ScopedTypeVariables - ; checkErr ty_sig_okay (unexpectedTypeSigErr sig_ty) - ; rn_hs_sig_wc_type scoping ctx sig_ty thing_inside - } - -rn_hs_sig_wc_type :: HsSigWcTypeScoping -> HsDocContext -> LHsSigWcType GhcPs - -> (LHsSigWcType GhcRn -> RnM (a, FreeVars)) + ; checkErr ty_sig_okay (unexpectedPatSigTypeErr sig_ty) + ; rn_hs_sig_wc_type scoping ctx (hsPatSigType sig_ty) $ + \nwcs imp_tvs body -> + do { let sig_names = HsPSRn { hsps_nwcs = nwcs, hsps_imp_tvs = imp_tvs } + sig_ty' = HsPS { hsps_ext = sig_names, hsps_body = body } + ; thing_inside sig_ty' + } } + +-- The workhorse for rnHsSigWcType and rnHsPatSigType. +rn_hs_sig_wc_type :: HsSigWcTypeScoping -> HsDocContext -> LHsType GhcPs + -> ([Name] -- Wildcard names + -> [Name] -- Implicitly bound type variable names + -> LHsType GhcRn + -> RnM (a, FreeVars)) -> RnM (a, FreeVars) --- rn_hs_sig_wc_type is used for source-language type signatures -rn_hs_sig_wc_type scoping ctxt - (HsWC { hswc_body = HsIB { hsib_body = hs_ty }}) - thing_inside +rn_hs_sig_wc_type scoping ctxt hs_ty thing_inside = do { free_vars <- extractFilteredRdrTyVarsDups hs_ty ; (nwc_rdrs', tv_rdrs) <- partition_nwcs free_vars ; let nwc_rdrs = nubL nwc_rdrs' @@ -134,10 +165,7 @@ rn_hs_sig_wc_type scoping ctxt NeverBind -> [] ; rnImplicitBndrs implicit_bndrs $ \ vars -> do { (wcs, hs_ty', fvs1) <- rnWcBody ctxt nwc_rdrs hs_ty - ; let sig_ty' = HsWC { hswc_ext = wcs, hswc_body = ib_ty' } - ib_ty' = HsIB { hsib_ext = vars - , hsib_body = hs_ty' } - ; (res, fvs2) <- thing_inside sig_ty' + ; (res, fvs2) <- thing_inside wcs vars hs_ty' ; return (res, fvs1 `plusFV` fvs2) } } rnHsWcType :: HsDocContext -> LHsWcType GhcPs -> RnM (LHsWcType GhcRn, FreeVars) @@ -321,8 +349,9 @@ rnHsSigType ctx level (HsIB { hsib_body = hs_ty }) -- therefore an indication that the user is trying to be fastidious, so -- we don't implicitly bind any variables. --- | See note Note [forall-or-nothing rule]. This tiny little function is used --- (rather than its small body inlined) to indicate we implementing that rule. +-- | See Note [forall-or-nothing rule]. This tiny little function is used +-- (rather than its small body inlined) to indicate that we are implementing +-- that rule. forAllOrNothing :: Bool -- ^ True <=> explicit forall -- E.g. f :: forall a. a->b @@ -1396,8 +1425,8 @@ ppr_opfix (op, fixity) = pp_op <+> brackets (ppr fixity) * * ***************************************************** -} -unexpectedTypeSigErr :: LHsSigWcType GhcPs -> SDoc -unexpectedTypeSigErr ty +unexpectedPatSigTypeErr :: HsPatSigType GhcPs -> SDoc +unexpectedPatSigTypeErr ty = hang (text "Illegal type signature:" <+> quotes (ppr ty)) 2 (text "Type signatures are only allowed in patterns with ScopedTypeVariables") ===================================== compiler/GHC/Rename/Module.hs ===================================== @@ -957,7 +957,7 @@ rnSrcDerivDecl (DerivDecl _ ty mds overlap) ; unless standalone_deriv_ok (addErr standaloneDerivErr) ; (mds', ty', fvs) <- rnLDerivStrategy DerivDeclCtx mds $ - rnHsSigWcType BindUnlessForall DerivDeclCtx ty + rnHsSigWcType DerivDeclCtx ty ; warnNoDerivStrat mds' loc ; return (DerivDecl noExtField ty' mds' overlap, fvs) } where @@ -1028,7 +1028,7 @@ bindRuleTmVars doc tyvs vars names thing_inside go ((L l (RuleBndrSig _ (L loc _) bsig)) : vars) (n : ns) thing_inside - = rnHsSigWcTypeScoped bind_free_tvs doc bsig $ \ bsig' -> + = rnHsPatSigType bind_free_tvs doc bsig $ \ bsig' -> go vars ns $ \ vars' -> thing_inside (L l (RuleBndrSig noExtField (L loc n) bsig') : vars') ===================================== compiler/GHC/Rename/Pat.hs ===================================== @@ -218,9 +218,6 @@ matchNameMaker ctxt = LamMk report_unused ThPatQuote -> False _ -> True -rnHsSigCps :: LHsSigWcType GhcPs -> CpsRn (LHsSigWcType GhcRn) -rnHsSigCps sig = CpsRn (rnHsSigWcTypeScoped AlwaysBind PatCtx sig) - newPatLName :: NameMaker -> Located RdrName -> CpsRn (Located Name) newPatLName name_maker rdr_name@(L loc _) = do { name <- newPatName name_maker rdr_name @@ -410,9 +407,12 @@ rnPatAndThen mk (SigPat x pat sig) -- f ((Just (x :: a) :: Maybe a) -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~^ `a' is first bound here -- ~~~~~~~~~~~~~~~^ the same `a' then used here - = do { sig' <- rnHsSigCps sig + = do { sig' <- rnHsPatSigTypeAndThen sig ; pat' <- rnLPatAndThen mk pat ; return (SigPat x pat' sig' ) } + where + rnHsPatSigTypeAndThen :: HsPatSigType GhcPs -> CpsRn (HsPatSigType GhcRn) + rnHsPatSigTypeAndThen sig = CpsRn (rnHsPatSigType AlwaysBind PatCtx sig) rnPatAndThen mk (LitPat x lit) | HsString src s <- lit ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -3338,7 +3338,7 @@ Result works fine, but it may eventually bite us. ********************************************************************* -} tcHsPatSigType :: UserTypeCtxt - -> LHsSigWcType GhcRn -- The type signature + -> HsPatSigType GhcRn -- The type signature -> TcM ( [(Name, TcTyVar)] -- Wildcards , [(Name, TcTyVar)] -- The new bit of type environment, binding -- the scoped type variables @@ -3346,13 +3346,13 @@ tcHsPatSigType :: UserTypeCtxt -- Used for type-checking type signatures in -- (a) patterns e.g f (x::Int) = e -- (b) RULE forall bndrs e.g. forall (x::Int). f x = x +-- See Note [Pattern signature binders and scoping] in GHC.Hs.Types -- -- This may emit constraints -- See Note [Recipe for checking a signature] -tcHsPatSigType ctxt sig_ty - | HsWC { hswc_ext = sig_wcs, hswc_body = ib_ty } <- sig_ty - , HsIB { hsib_ext = sig_ns - , hsib_body = hs_ty } <- ib_ty +tcHsPatSigType ctxt + (HsPS { hsps_ext = HsPSRn { hsps_nwcs = sig_wcs, hsps_imp_tvs = sig_ns } + , hsps_body = hs_ty }) = addSigCtxt ctxt hs_ty $ do { sig_tkv_prs <- mapM new_implicit_tv sig_ns ; (wcs, sig_ty) @@ -3385,12 +3385,12 @@ tcHsPatSigType ctxt sig_ty ; tv <- case ctxt of RuleSigCtxt {} -> newSkolemTyVar name kind _ -> newPatSigTyVar name kind - -- See Note [Pattern signature binders] + -- See Note [Typechecking pattern signature binders] -- NB: tv's Name may be fresh (in the case of newPatSigTyVar) ; return (name, tv) } -{- Note [Pattern signature binders] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [Typechecking pattern signature binders] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ See also Note [Type variables in the type environment] in GHC.Tc.Utils. Consider ===================================== compiler/GHC/Tc/Gen/Pat.hs ===================================== @@ -690,7 +690,7 @@ because they won't be in scope when we do the desugaring -} tcPatSig :: Bool -- True <=> pattern binding - -> LHsSigWcType GhcRn + -> HsPatSigType GhcRn -> ExpSigmaType -> TcM (TcType, -- The type to use for "inside" the signature [(Name,TcTyVar)], -- The new bit of type environment, binding ===================================== compiler/GHC/Tc/Gen/Rule.hs ===================================== @@ -230,7 +230,7 @@ tcRuleTmBndrs (L _ (RuleBndrSig _ (L _ name) rn_ty) : rule_bndrs) = do { let ctxt = RuleSigCtxt name ; (_ , tvs, id_ty) <- tcHsPatSigType ctxt rn_ty ; let id = mkLocalId name id_ty - -- See Note [Pattern signature binders] in GHC.Tc.Gen.HsType + -- See Note [Typechecking pattern signature binders] in GHC.Tc.Gen.HsType -- The type variables scope over subsequent bindings; yuk ; (tyvars, tmvars) <- tcExtendNameTyVarEnv tvs $ ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -830,7 +830,7 @@ cvtRuleBndr (RuleVar n) cvtRuleBndr (TypedRuleVar n ty) = do { n' <- vNameL n ; ty' <- cvtType ty - ; return $ noLoc $ Hs.RuleBndrSig noExtField n' $ mkLHsSigWcType ty' } + ; return $ noLoc $ Hs.RuleBndrSig noExtField n' $ mkHsPatSigType ty' } --------------------------------------------------- -- Declarations @@ -1307,7 +1307,7 @@ cvtp (ListP ps) = do { ps' <- cvtPats ps ; return $ ListPat noExtField ps'} cvtp (SigP p t) = do { p' <- cvtPat p; t' <- cvtType t - ; return $ SigPat noExtField p' (mkLHsSigWcType t') } + ; return $ SigPat noExtField p' (mkHsPatSigType t') } cvtp (ViewP e p) = do { e' <- cvtl e; p' <- cvtPat p ; return $ ViewPat noExtField e' p'} ===================================== testsuite/tests/hiefile/should_compile/hie007.hs ===================================== @@ -64,3 +64,6 @@ thud f x = (x :: a, y) :: (a, b) where y = (f :: a -> b) x :: b + +rankn :: (forall a1. a1 -> b) -> a2 -> b +rankn (g :: forall a1. a1 -> b) x = g x :: b View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/102cfd6784d16a0d0cc8bdf42d4de4c7b8dd0190 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/102cfd6784d16a0d0cc8bdf42d4de4c7b8dd0190 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 00:05:40 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 13 May 2020 20:05:40 -0400 Subject: [Git][ghc/ghc][master] fix(documentation): Fix the RST links to GHC.Prim Message-ID: <5ebc8b54b8577_61671288ff4c1114922e@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: b17574f7 by Hécate at 2020-05-13T20:05:28-04:00 fix(documentation): Fix the RST links to GHC.Prim - - - - - 3 changed files: - docs/users_guide/editing-guide.rst - docs/users_guide/exts/ffi.rst - docs/users_guide/exts/primitives.rst Changes: ===================================== docs/users_guide/editing-guide.rst ===================================== @@ -228,7 +228,7 @@ For instance, .. code-block:: rest - See the documentation for :base-ref:`Control.Applicative ` + See the documentation for :base-ref:`Control.Applicative.` for details. Math ===================================== docs/users_guide/exts/ffi.rst ===================================== @@ -1027,7 +1027,7 @@ Pinned Byte Arrays A pinned byte array is one that the garbage collector is not allowed to move. Consequently, it has a stable address that can be safely requested with ``byteArrayContents#``. There are a handful of -primitive functions in :ghc-prim-ref:`GHC.Prim ` +primitive functions in :ghc-prim-ref:`GHC.Prim.` used to enforce or check for pinnedness: ``isByteArrayPinned#``, ``isMutableByteArrayPinned#``, and ``newPinnedByteArray#``. A byte array can be pinned as a result of three possible causes: ===================================== docs/users_guide/exts/primitives.rst ===================================== @@ -12,9 +12,8 @@ you write will be optimised to the efficient unboxed version in any case. And if it isn't, we'd like to know about it. All these primitive data types and operations are exported by the -library ``GHC.Prim``, for which there is -:ghc-prim-ref:`detailed online documentation `. (This -documentation is generated from the file ``compiler/GHC/Builtin/primops.txt.pp``.) +library :ghc-prim-ref:`GHC.Prim.`. (This documentation is generated from +the file ``compiler/GHC/Builtin/primops.txt.pp``.) If you want to mention any of the primitive data types or operations in your program, you must first import ``GHC.Prim`` to bring them into View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b17574f74173d0fa83b0def070dcba51b710be2e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b17574f74173d0fa83b0def070dcba51b710be2e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 00:06:17 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 13 May 2020 20:06:17 -0400 Subject: [Git][ghc/ghc][master] Document (->) using inferred quantification for its runtime representations. Message-ID: <5ebc8b791ff57_61673f81cd539dbc11153482@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: df021fb1 by Baldur Blöndal at 2020-05-13T20:06:06-04:00 Document (->) using inferred quantification for its runtime representations. Fixes #18142. - - - - - 4 changed files: - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/Type.hs Changes: ===================================== compiler/GHC/Builtin/Types/Prim.hs ===================================== @@ -399,9 +399,23 @@ funTyConName = mkPrimTyConName (fsLit "->") funTyConKey funTyCon -- | The @(->)@ type constructor. -- -- @ --- (->) :: forall (rep1 :: RuntimeRep) (rep2 :: RuntimeRep). --- TYPE rep1 -> TYPE rep2 -> * +-- (->) :: forall {rep1 :: RuntimeRep} {rep2 :: RuntimeRep}. +-- TYPE rep1 -> TYPE rep2 -> Type -- @ +-- +-- The runtime representations quantification is left inferred. This +-- means they cannot be specified with @-XTypeApplications at . +-- +-- This is a deliberate choice to allow future extensions to the +-- function arrow. To allow visible application a type synonym can be +-- defined: +-- +-- @ +-- type Arr :: forall (rep1 :: RuntimeRep) (rep2 :: RuntimeRep). +-- TYPE rep1 -> TYPE rep2 -> Type +-- type Arr = (->) +-- @ +-- funTyCon :: TyCon funTyCon = mkFunTyCon funTyConName tc_bndrs tc_rep_nm where ===================================== compiler/GHC/Core/Coercion.hs ===================================== @@ -292,7 +292,9 @@ tidyCoAxBndrsForUser init_env tcvs Note [Function coercions] ~~~~~~~~~~~~~~~~~~~~~~~~~ Remember that - (->) :: forall r1 r2. TYPE r1 -> TYPE r2 -> TYPE LiftedRep + (->) :: forall {r1} {r2}. TYPE r1 -> TYPE r2 -> TYPE LiftedRep +whose `RuntimeRep' arguments are intentionally marked inferred to +avoid type application. Hence FunCo r co1 co2 :: (s1->t1) ~r (s2->t2) ===================================== compiler/GHC/Core/TyCo/Rep.hs ===================================== @@ -255,12 +255,15 @@ about it! * FFunTy is the data constructor, meaning "full function type". * The function type constructor (->) has kind - (->) :: forall r1 r2. TYPE r1 -> TYPE r2 -> Type LiftedRep + (->) :: forall {r1} {r2}. TYPE r1 -> TYPE r2 -> Type LiftedRep mkTyConApp ensure that we convert a saturated application TyConApp (->) [r1,r2,t1,t2] into FunTy t1 t2 dropping the 'r1' and 'r2' arguments; they are easily recovered from 't1' and 't2'. +* For the time being its RuntimeRep quantifiers are left + inferred. This is to allow for it to evolve. + * The ft_af field says whether or not this is an invisible argument VisArg: t1 -> t2 Ordinary function type InvisArg: t1 => t2 t1 is guaranteed to be a predicate type, ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -1012,9 +1012,10 @@ Note [Representation of function types] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Functions (e.g. Int -> Char) can be thought of as being applications -of funTyCon (known in Haskell surface syntax as (->)), +of funTyCon (known in Haskell surface syntax as (->)), (note that +`RuntimeRep' quantifiers are left inferred) - (->) :: forall (r1 :: RuntimeRep) (r2 :: RuntimeRep) + (->) :: forall {r1 :: RuntimeRep} {r2 :: RuntimeRep} (a :: TYPE r1) (b :: TYPE r2). a -> b -> Type View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/df021fb15bcef313f30e772997bcb263c8f34078 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/df021fb15bcef313f30e772997bcb263c8f34078 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 00:07:07 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 13 May 2020 20:07:07 -0400 Subject: [Git][ghc/ghc][master] Tweak man page for ghc command Message-ID: <5ebc8bab8a018_61673f8103f8794c11157782@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 1a93ea57 by Takenobu Tani at 2020-05-13T20:06:54-04:00 Tweak man page for ghc command This commit updates the ghc command's man page as followings: * Enable `man_show_urls` to show URL addresses in the `DESCRIPTION` section of ghc.rst, because sphinx currently removes hyperlinks for man pages. * Add a `SEE ALSO` section to point to the GHC homepage - - - - - 2 changed files: - docs/users_guide/conf.py - docs/users_guide/ghc.rst Changes: ===================================== docs/users_guide/conf.py ===================================== @@ -135,7 +135,7 @@ man_pages = [ ] # If true, show URL addresses after external links. -#man_show_urls = False +man_show_urls = True # -- Options for Texinfo output ------------------------------------------- ===================================== docs/users_guide/ghc.rst ===================================== @@ -379,3 +379,8 @@ Copyright Copyright 2015. The University Court of the University of Glasgow. All rights reserved. + +See also +-------- + +https://www.haskell.org/ghc the GHC homepage View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1a93ea57355d521b92daf4e3120de88a1f94deee -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1a93ea57355d521b92daf4e3120de88a1f94deee You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 00:07:47 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 13 May 2020 20:07:47 -0400 Subject: [Git][ghc/ghc][master] GHCi: Add link to the user's guide in help message Message-ID: <5ebc8bd356091_616712a9b7f01116199a@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: a951e1ba by Takenobu Tani at 2020-05-13T20:07:37-04:00 GHCi: Add link to the user's guide in help message This commit adds a link to the user's guide in ghci's `:help` message. Newcomers could easily reach to details of ghci. - - - - - 1 changed file: - ghc/GHCi/UI.hs Changes: ===================================== ghc/GHCi/UI.hs ===================================== @@ -403,6 +403,10 @@ defFullHelpText = " :show show value of , which is one of\n" ++ " [args, prog, editor, stop]\n" ++ " :showi language show language flags for interactive evaluation\n" ++ + "\n" ++ + " The User's Guide has more information. An online copy can be found here:\n" ++ + "\n" ++ + " https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ghci.html\n" ++ "\n" findEditor :: IO String View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a951e1bab3dfd3e9de31b0d8bf5699a9216b181d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a951e1bab3dfd3e9de31b0d8bf5699a9216b181d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 00:08:24 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 13 May 2020 20:08:24 -0400 Subject: [Git][ghc/ghc][master] Handle single unused import Message-ID: <5ebc8bf8397e9_6167119ebbd011165028@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 404581ea by Jeff Happily at 2020-05-13T20:08:15-04:00 Handle single unused import - - - - - 5 changed files: - compiler/GHC/Rename/Names.hs - testsuite/tests/rename/should_compile/T13064.stderr - testsuite/tests/rename/should_compile/rn046.stderr - testsuite/tests/rename/should_fail/T7454.stderr - testsuite/tests/rename/should_fail/T8149.stderr Changes: ===================================== compiler/GHC/Rename/Names.hs ===================================== @@ -1498,9 +1498,16 @@ warnUnusedImport flag fld_env (L loc decl, used, unused) | null unused = return () + -- Only one import is unused, with `SrcSpan` covering only the unused item instead of + -- the whole import statement + | Just (_, L _ imports) <- ideclHiding decl + , length unused == 1 + , Just (L loc _) <- find (\(L _ ie) -> ((ieName ie) :: Name) `elem` unused) imports + = addWarnAt (Reason flag) loc msg2 + -- Some imports are unused | otherwise - = addWarnAt (Reason flag) loc msg2 + = addWarnAt (Reason flag) loc msg2 where msg1 = vcat [ pp_herald <+> quotes pp_mod <+> is_redundant ===================================== testsuite/tests/rename/should_compile/T13064.stderr ===================================== @@ -1,3 +1,3 @@ -T13064.hs:5:1: warning: [-Wunused-imports (in -Wextra)] +T13064.hs:5:21: warning: [-Wunused-imports (in -Wextra)] The import of ‘pure’ from module ‘Prelude’ is redundant ===================================== testsuite/tests/rename/should_compile/rn046.stderr ===================================== @@ -4,5 +4,5 @@ rn046.hs:2:1: warning: [-Wunused-imports (in -Wextra)] except perhaps to import instances from ‘Data.List’ To import instances alone, use: import Data.List() -rn046.hs:3:1: warning: [-Wunused-imports (in -Wextra)] +rn046.hs:3:19: warning: [-Wunused-imports (in -Wextra)] The import of ‘ord’ from module ‘Data.Char’ is redundant ===================================== testsuite/tests/rename/should_fail/T7454.stderr ===================================== @@ -1,3 +1,3 @@ -T7454.hs:5:1: warning: [-Wunused-imports (in -Wextra)] +T7454.hs:5:23: warning: [-Wunused-imports (in -Wextra)] The import of ‘Arrow’ from module ‘Control.Arrow’ is redundant ===================================== testsuite/tests/rename/should_fail/T8149.stderr ===================================== @@ -1,4 +1,4 @@ -T8149.hs:5:1: warning: [-Wunused-imports (in -Wextra)] +T8149.hs:5:36: warning: [-Wunused-imports (in -Wextra)] The import of ‘WriterT’ from module ‘Control.Monad.Trans.Writer’ is redundant View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/404581eaa3bf8d3f100da7610a6a38158bea17c4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/404581eaa3bf8d3f100da7610a6a38158bea17c4 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 00:09:25 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 13 May 2020 20:09:25 -0400 Subject: [Git][ghc/ghc][master] Ensure that printMinimalImports closes handle Message-ID: <5ebc8c35984e8_61673f8103f8794c111691de@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 1c999e5d by Ben Gamari at 2020-05-13T20:09:07-04:00 Ensure that printMinimalImports closes handle Fixes #18166. - - - - - 1 changed file: - compiler/GHC/Rename/Names.hs Changes: ===================================== compiler/GHC/Rename/Names.hs ===================================== @@ -1619,9 +1619,8 @@ printMinimalImports imports_w_usage = do { imports' <- getMinimalImports imports_w_usage ; this_mod <- getModule ; dflags <- getDynFlags - ; liftIO $ - do { h <- openFile (mkFilename dflags this_mod) WriteMode - ; printForUser dflags h neverQualify (vcat (map ppr imports')) } + ; liftIO $ withFile (mkFilename dflags this_mod) WriteMode $ \h -> + printForUser dflags h neverQualify (vcat (map ppr imports')) -- The neverQualify is important. We are printing Names -- but they are in the context of an 'import' decl, and -- we never qualify things inside there View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1c999e5d4e63e7b407b174f51913cfa38e2dec46 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1c999e5d4e63e7b407b174f51913cfa38e2dec46 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 00:10:01 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 13 May 2020 20:10:01 -0400 Subject: [Git][ghc/ghc][master] hadrian: Tell testsuite driver about LLVM availability Message-ID: <5ebc8c59b8ca8_616711a31edc1117313@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: c9f5a8f4 by Ben Gamari at 2020-05-13T20:09:51-04:00 hadrian: Tell testsuite driver about LLVM availability This reflects the logic present in the Make build system into Hadrian. Fixes #18167. - - - - - 1 changed file: - hadrian/src/Settings/Builders/RunTest.hs Changes: ===================================== hadrian/src/Settings/Builders/RunTest.hs ===================================== @@ -70,6 +70,7 @@ runTestBuilderArgs = builder RunTest ? do withSMP <- getBooleanSetting TestGhcWithSMP debugged <- getBooleanSetting TestGhcDebugged keepFiles <- expr (testKeepFiles <$> userSetting defaultTestArgs) + withLlvm <- expr (not . null <$> settingsFileSetting SettingsFileSetting_LlcCommand) accept <- expr (testAccept <$> userSetting defaultTestArgs) (acceptPlatform, acceptOS) <- expr . liftIO $ @@ -121,7 +122,7 @@ runTestBuilderArgs = builder RunTest ? do , arg "-e", arg $ asBool "config.have_dynamic=" (hasLibWay dynamic) , arg "-e", arg $ asBool "config.have_profiling=" (hasLibWay profiling) , arg "-e", arg $ asBool "ghc_with_smp=" withSMP - , arg "-e", arg $ "ghc_with_llvm=0" -- TODO: support LLVM + , arg "-e", arg $ asBool "ghc_with_llvm=" withLlvm , arg "-e", arg $ "config.ghc_dynamic_by_default=" ++ show hasDynamicByDefault , arg "-e", arg $ "config.ghc_dynamic=" ++ show hasDynamic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c9f5a8f4653c4696a1fbb768bd0d8f672d4c7d5f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c9f5a8f4653c4696a1fbb768bd0d8f672d4c7d5f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 00:41:19 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 13 May 2020 20:41:19 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 13 commits: Predicate, Equivalence derive via `.. -> a -> All' Message-ID: <5ebc93af7068_61671288ff4c11175524@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 55e35c0b by Baldur Blöndal at 2020-05-13T20:02:48-04:00 Predicate, Equivalence derive via `.. -> a -> All' - - - - - d7e0b57f by Alp Mestanogullari at 2020-05-13T20:03:30-04:00 hadrian: add a --freeze2 option to freeze stage 1 and 2 - - - - - d880d6b2 by Artem Pelenitsyn at 2020-05-13T20:04:11-04:00 Don't reload environment files on every setSessionDynFlags Makes `interpretPackageEnv` (which loads envirinment files) a part of `parseDynamicFlags` (parsing command-line arguments, which is typically done once) instead of `setSessionDynFlags` (which is typically called several times). Making several (transitive) calls to `interpretPackageEnv`, as before, caused #18125 #16318, which should be fixed now. - - - - - 102cfd67 by Ryan Scott at 2020-05-13T20:04:46-04:00 Factor out HsPatSigType for pat sigs/RULE term sigs (#16762) This implements chunks (2) and (3) of https://gitlab.haskell.org/ghc/ghc/issues/16762#note_270170. Namely, it introduces a dedicated `HsPatSigType` AST type, which represents the types that can appear in pattern signatures and term-level `RULE` binders. Previously, these were represented with `LHsSigWcType`. Although `LHsSigWcType` is isomorphic to `HsPatSigType`, the intended semantics of the two types are slightly different, as evidenced by the fact that they have different code paths in the renamer and typechecker. See also the new `Note [Pattern signature binders and scoping]` in `GHC.Hs.Types`. - - - - - b17574f7 by Hécate at 2020-05-13T20:05:28-04:00 fix(documentation): Fix the RST links to GHC.Prim - - - - - df021fb1 by Baldur Blöndal at 2020-05-13T20:06:06-04:00 Document (->) using inferred quantification for its runtime representations. Fixes #18142. - - - - - 1a93ea57 by Takenobu Tani at 2020-05-13T20:06:54-04:00 Tweak man page for ghc command This commit updates the ghc command's man page as followings: * Enable `man_show_urls` to show URL addresses in the `DESCRIPTION` section of ghc.rst, because sphinx currently removes hyperlinks for man pages. * Add a `SEE ALSO` section to point to the GHC homepage - - - - - a951e1ba by Takenobu Tani at 2020-05-13T20:07:37-04:00 GHCi: Add link to the user's guide in help message This commit adds a link to the user's guide in ghci's `:help` message. Newcomers could easily reach to details of ghci. - - - - - 404581ea by Jeff Happily at 2020-05-13T20:08:15-04:00 Handle single unused import - - - - - 1c999e5d by Ben Gamari at 2020-05-13T20:09:07-04:00 Ensure that printMinimalImports closes handle Fixes #18166. - - - - - c9f5a8f4 by Ben Gamari at 2020-05-13T20:09:51-04:00 hadrian: Tell testsuite driver about LLVM availability This reflects the logic present in the Make build system into Hadrian. Fixes #18167. - - - - - 2714aec1 by Simon Jakobi at 2020-05-13T20:41:09-04:00 Improve some folds over Uniq[D]FM * Replace some non-deterministic lazy folds with strict folds. * Replace some O(n log n) folds in deterministic order with O(n) non-deterministic folds. * Replace some folds with set-operations on the underlying IntMaps. This reduces max residency when compiling `nofib/spectral/simple/Main.hs` with -O0 by about 1%. Maximum residency when compiling Cabal also seems reduced on the order of 3-9%. - - - - - 48eeb279 by Simon Jakobi at 2020-05-13T20:41:10-04:00 Use Data.IntMap.disjoint Data.IntMap gained a dedicated `disjoint` function in containers-0.6.2.1. This patch applies this function where appropriate in hopes of modest compiler performance improvements. Closes #16806. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/Data/Graph/Ops.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Extension.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Types.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Names.hs - compiler/GHC/Rename/Pat.hs - compiler/GHC/Stg/Lift/Analysis.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cf7a9ecc5265b1f654b68ca2806c5765c1a6162e...48eeb2795215044136ec8c71493bb142312ddcf7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cf7a9ecc5265b1f654b68ca2806c5765c1a6162e...48eeb2795215044136ec8c71493bb142312ddcf7 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 07:31:34 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 14 May 2020 03:31:34 -0400 Subject: [Git][ghc/ghc][master] Improve some folds over Uniq[D]FM Message-ID: <5ebcf3d6a682_6167addfa40111972d@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: c05c0659 by Simon Jakobi at 2020-05-14T03:31:21-04:00 Improve some folds over Uniq[D]FM * Replace some non-deterministic lazy folds with strict folds. * Replace some O(n log n) folds in deterministic order with O(n) non-deterministic folds. * Replace some folds with set-operations on the underlying IntMaps. This reduces max residency when compiling `nofib/spectral/simple/Main.hs` with -O0 by about 1%. Maximum residency when compiling Cabal also seems reduced on the order of 3-9%. - - - - - 21 changed files: - compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/Data/Graph/Ops.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Stg/Lift/Analysis.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/Types/Evidence.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Unique/DFM.hs - compiler/GHC/Types/Unique/DSet.hs - compiler/GHC/Types/Unique/FM.hs - compiler/GHC/Types/Unique/Set.hs - compiler/GHC/Types/Var/Env.hs - compiler/GHC/Types/Var/Set.hs Changes: ===================================== compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.hs ===================================== @@ -554,8 +554,9 @@ delAssoc :: (Uniquable a) delAssoc a m | Just aSet <- lookupUFM m a , m1 <- delFromUFM m a - = nonDetFoldUniqSet (\x m -> delAssoc1 x a m) m1 aSet - -- It's OK to use nonDetFoldUFM here because deletion is commutative + = nonDetStrictFoldUniqSet (\x m -> delAssoc1 x a m) m1 aSet + -- It's OK to use a non-deterministic fold here because deletion is + -- commutative | otherwise = m ===================================== compiler/GHC/Core/FamInstEnv.hs ===================================== @@ -380,8 +380,8 @@ famInstEnvElts fi = [elt | FamIE elts <- eltsUDFM fi, elt <- elts] -- See Note [FamInstEnv determinism] famInstEnvSize :: FamInstEnv -> Int -famInstEnvSize = nonDetFoldUDFM (\(FamIE elt) sum -> sum + length elt) 0 - -- It's OK to use nonDetFoldUDFM here since we're just computing the +famInstEnvSize = nonDetStrictFoldUDFM (\(FamIE elt) sum -> sum + length elt) 0 + -- It's OK to use nonDetStrictFoldUDFM here since we're just computing the -- size. familyInstances :: (FamInstEnv, FamInstEnv) -> TyCon -> [FamInst] ===================================== compiler/GHC/Core/Opt/OccurAnal.hs ===================================== @@ -2245,8 +2245,8 @@ extendFvs env s = (s `unionVarSet` extras, extras `subVarSet` s) where extras :: VarSet -- env(s) - extras = nonDetFoldUFM unionVarSet emptyVarSet $ - -- It's OK to use nonDetFoldUFM here because unionVarSet commutes + extras = nonDetStrictFoldUFM unionVarSet emptyVarSet $ + -- It's OK to use nonDetStrictFoldUFM here because unionVarSet commutes intersectUFM_C (\x _ -> x) env (getUniqSet s) {- @@ -2567,8 +2567,8 @@ addManyOcc v u | isId v = addManyOccId u v -- (Same goes for INLINE.) addManyOccs :: UsageDetails -> VarSet -> UsageDetails -addManyOccs usage id_set = nonDetFoldUniqSet addManyOcc usage id_set - -- It's OK to use nonDetFoldUFM here because addManyOcc commutes +addManyOccs usage id_set = nonDetStrictFoldUniqSet addManyOcc usage id_set + -- It's OK to use nonDetStrictFoldUniqSet here because addManyOcc commutes delDetails :: UsageDetails -> Id -> UsageDetails delDetails ud bndr ===================================== compiler/GHC/Core/Opt/SetLevels.hs ===================================== @@ -83,7 +83,7 @@ import GHC.Types.Id import GHC.Types.Id.Info import GHC.Types.Var import GHC.Types.Var.Set -import GHC.Types.Unique.Set ( nonDetFoldUniqSet ) +import GHC.Types.Unique.Set ( nonDetStrictFoldUniqSet ) import GHC.Types.Unique.DSet ( getUniqDSet ) import GHC.Types.Var.Env import GHC.Types.Literal ( litIsTrivial ) @@ -1469,8 +1469,8 @@ isFunction (_, AnnLam b e) | isId b = True isFunction _ = False countFreeIds :: DVarSet -> Int -countFreeIds = nonDetFoldUDFM add 0 . getUniqDSet - -- It's OK to use nonDetFoldUDFM here because we're just counting things. +countFreeIds = nonDetStrictFoldUDFM add 0 . getUniqDSet + -- It's OK to use nonDetStrictFoldUDFM here because we're just counting things. where add :: Var -> Int -> Int add v n | isId v = n+1 @@ -1581,12 +1581,14 @@ placeJoinCeiling le@(LE { le_ctxt_lvl = lvl }) maxFvLevel :: (Var -> Bool) -> LevelEnv -> DVarSet -> Level maxFvLevel max_me env var_set - = foldDVarSet (maxIn max_me env) tOP_LEVEL var_set + = nonDetStrictFoldDVarSet (maxIn max_me env) tOP_LEVEL var_set + -- It's OK to use a non-deterministic fold here because maxIn commutes. maxFvLevel' :: (Var -> Bool) -> LevelEnv -> TyCoVarSet -> Level -- Same but for TyCoVarSet maxFvLevel' max_me env var_set - = nonDetFoldUniqSet (maxIn max_me env) tOP_LEVEL var_set + = nonDetStrictFoldUniqSet (maxIn max_me env) tOP_LEVEL var_set + -- It's OK to use a non-deterministic fold here because maxIn commutes. maxIn :: (Var -> Bool) -> LevelEnv -> InVar -> Level -> Level maxIn max_me (LE { le_lvl_env = lvl_env, le_env = id_env }) in_var lvl ===================================== compiler/GHC/Core/Opt/Specialise.hs ===================================== @@ -2431,8 +2431,8 @@ unionCallInfoSet (CIS f calls1) (CIS _ calls2) = callDetailsFVs :: CallDetails -> VarSet callDetailsFVs calls = - nonDetFoldUDFM (unionVarSet . callInfoFVs) emptyVarSet calls - -- It's OK to use nonDetFoldUDFM here because we forget the ordering + nonDetStrictFoldUDFM (unionVarSet . callInfoFVs) emptyVarSet calls + -- It's OK to use nonDetStrictFoldUDFM here because we forget the ordering -- immediately by converting to a nondeterministic set. callInfoFVs :: CallInfoSet -> VarSet ===================================== compiler/GHC/Core/TyCo/FVs.hs ===================================== @@ -441,7 +441,7 @@ deepCoVarFolder = TyCoFolder { tcf_view = noView closeOverKinds :: TyCoVarSet -> TyCoVarSet -- For each element of the input set, -- add the deep free variables of its kind -closeOverKinds vs = nonDetFoldVarSet do_one vs vs +closeOverKinds vs = nonDetStrictFoldVarSet do_one vs vs where do_one v acc = appEndo (deep_ty (varType v)) acc ===================================== compiler/GHC/Core/Unify.hs ===================================== @@ -658,9 +658,9 @@ niSubstTvSet :: TvSubstEnv -> TyCoVarSet -> TyCoVarSet -- remembering that the substitution isn't necessarily idempotent -- This is used in the occurs check, before extending the substitution niSubstTvSet tsubst tvs - = nonDetFoldUniqSet (unionVarSet . get) emptyVarSet tvs - -- It's OK to nonDetFoldUFM here because we immediately forget the - -- ordering by creating a set. + = nonDetStrictFoldUniqSet (unionVarSet . get) emptyVarSet tvs + -- It's OK to use a non-deterministic fold here because we immediately forget + -- the ordering by creating a set. where get tv | Just ty <- lookupVarEnv tsubst tv ===================================== compiler/GHC/Data/Graph/Ops.hs ===================================== @@ -79,8 +79,8 @@ addNode k node graph = let -- add back conflict edges from other nodes to this one map_conflict = - nonDetFoldUniqSet - -- It's OK to use nonDetFoldUFM here because the + nonDetStrictFoldUniqSet + -- It's OK to use a non-deterministic fold here because the -- operation is commutative (adjustUFM_C (\n -> n { nodeConflicts = addOneToUniqSet (nodeConflicts n) k})) @@ -89,8 +89,8 @@ addNode k node graph -- add back coalesce edges from other nodes to this one map_coalesce = - nonDetFoldUniqSet - -- It's OK to use nonDetFoldUFM here because the + nonDetStrictFoldUniqSet + -- It's OK to use a non-deterministic fold here because the -- operation is commutative (adjustUFM_C (\n -> n { nodeCoalesce = addOneToUniqSet (nodeCoalesce n) k})) @@ -492,9 +492,9 @@ freezeNode k else node -- panic "GHC.Data.Graph.Ops.freezeNode: edge to freeze wasn't in the coalesce set" -- If the edge isn't actually in the coelesce set then just ignore it. - fm2 = nonDetFoldUniqSet (adjustUFM_C (freezeEdge k)) fm1 - -- It's OK to use nonDetFoldUFM here because the operation - -- is commutative + fm2 = nonDetStrictFoldUniqSet (adjustUFM_C (freezeEdge k)) fm1 + -- It's OK to use a non-deterministic fold here because the + -- operation is commutative $ nodeCoalesce node in fm2 ===================================== compiler/GHC/HsToCore/Usage.hs ===================================== @@ -261,9 +261,9 @@ mk_mod_usage_info pit hsc_env this_mod direct_imports used_names -- ent_map groups together all the things imported and used -- from a particular module ent_map :: ModuleEnv [OccName] - ent_map = nonDetFoldUniqSet add_mv emptyModuleEnv used_names - -- nonDetFoldUFM is OK here. If you follow the logic, we sort by OccName - -- in ent_hashs + ent_map = nonDetStrictFoldUniqSet add_mv emptyModuleEnv used_names + -- nonDetStrictFoldUniqSet is OK here. If you follow the logic, we sort by + -- OccName in ent_hashs where add_mv name mv_map | isWiredInName name = mv_map -- ignore wired-in names ===================================== compiler/GHC/Rename/Module.hs ===================================== @@ -1400,8 +1400,8 @@ depAnalTyClDecls rdr_env kisig_fv_env ds_w_fvs toParents :: GlobalRdrEnv -> NameSet -> NameSet toParents rdr_env ns - = nonDetFoldUniqSet add emptyNameSet ns - -- It's OK to use nonDetFoldUFM because we immediately forget the + = nonDetStrictFoldUniqSet add emptyNameSet ns + -- It's OK to use a non-deterministic fold because we immediately forget the -- ordering by creating a set where add n s = extendNameSet s (getParent rdr_env n) ===================================== compiler/GHC/Stg/Lift/Analysis.hs ===================================== @@ -545,7 +545,8 @@ closureGrowth expander sizer group abs_ids = go -- we lift @f@ newbies = abs_ids `minusDVarSet` clo_fvs' -- Lifting @f@ removes @f@ from the closure but adds all @newbies@ - cost = foldDVarSet (\id size -> sizer id + size) 0 newbies - n_occs + cost = nonDetStrictFoldDVarSet (\id size -> sizer id + size) 0 newbies - n_occs + -- Using a non-deterministic fold is OK here because addition is commutative. go (RhsSk body_dmd body) -- The conservative assumption would be that -- 1. Every RHS with positive growth would be called multiple times, ===================================== compiler/GHC/Tc/Solver.hs ===================================== @@ -1851,11 +1851,13 @@ neededEvVars implic@(Implic { ic_given = givens ; tcvs <- TcS.getTcEvTyCoVars ev_binds_var ; let seeds1 = foldr add_implic_seeds old_needs implics - seeds2 = foldEvBindMap add_wanted seeds1 ev_binds + seeds2 = nonDetStrictFoldEvBindMap add_wanted seeds1 ev_binds + -- It's OK to use a non-deterministic fold here + -- because add_wanted is commutative seeds3 = seeds2 `unionVarSet` tcvs need_inner = findNeededEvVars ev_binds seeds3 live_ev_binds = filterEvBindMap (needed_ev_bind need_inner) ev_binds - need_outer = foldEvBindMap del_ev_bndr need_inner live_ev_binds + need_outer = varSetMinusEvBindMap need_inner live_ev_binds `delVarSetList` givens ; TcS.setTcEvBindsMap ev_binds_var live_ev_binds @@ -1879,9 +1881,6 @@ neededEvVars implic@(Implic { ic_given = givens | is_given = ev_var `elemVarSet` needed | otherwise = True -- Keep all wanted bindings - del_ev_bndr :: EvBind -> VarSet -> VarSet - del_ev_bndr (EvBind { eb_lhs = v }) needs = delVarSet needs v - add_wanted :: EvBind -> VarSet -> VarSet add_wanted (EvBind { eb_is_given = is_given, eb_rhs = rhs }) needs | is_given = needs -- Add the rhs vars of the Wanted bindings only @@ -2377,7 +2376,7 @@ floatEqualities skols given_ids ev_binds_var no_given_eqs seed_skols = mkVarSet skols `unionVarSet` mkVarSet given_ids `unionVarSet` foldr add_non_flt_ct emptyVarSet no_float_cts `unionVarSet` - foldEvBindMap add_one_bind emptyVarSet binds + evBindMapToVarSet binds -- seed_skols: See Note [What prevents a constraint from floating] (1,2,3) -- Include the EvIds of any non-floating constraints @@ -2402,9 +2401,6 @@ floatEqualities skols given_ids ev_binds_var no_given_eqs ; return ( flt_eqs, wanteds { wc_simple = remaining_simples } ) } where - add_one_bind :: EvBind -> VarSet -> VarSet - add_one_bind bind acc = extendVarSet acc (evBindVar bind) - add_non_flt_ct :: Ct -> VarSet -> VarSet add_non_flt_ct ct acc | isDerivedCt ct = acc | otherwise = extendVarSet acc (ctEvId ct) ===================================== compiler/GHC/Tc/Types/Evidence.hs ===================================== @@ -15,8 +15,12 @@ module GHC.Tc.Types.Evidence ( -- * Evidence bindings TcEvBinds(..), EvBindsVar(..), EvBindMap(..), emptyEvBindMap, extendEvBinds, - lookupEvBind, evBindMapBinds, foldEvBindMap, filterEvBindMap, + lookupEvBind, evBindMapBinds, + foldEvBindMap, nonDetStrictFoldEvBindMap, + filterEvBindMap, isEmptyEvBindMap, + evBindMapToVarSet, + varSetMinusEvBindMap, EvBind(..), emptyTcEvBinds, isEmptyTcEvBinds, mkGivenEvBind, mkWantedEvBind, evBindVar, isCoEvBindsVar, @@ -55,6 +59,8 @@ module GHC.Tc.Types.Evidence ( import GHC.Prelude +import GHC.Types.Unique.DFM +import GHC.Types.Unique.FM import GHC.Types.Var import GHC.Core.Coercion.Axiom import GHC.Core.Coercion @@ -496,10 +502,22 @@ evBindMapBinds = foldEvBindMap consBag emptyBag foldEvBindMap :: (EvBind -> a -> a) -> a -> EvBindMap -> a foldEvBindMap k z bs = foldDVarEnv k z (ev_bind_varenv bs) +-- See Note [Deterministic UniqFM] to learn about nondeterminism. +-- If you use this please provide a justification why it doesn't introduce +-- nondeterminism. +nonDetStrictFoldEvBindMap :: (EvBind -> a -> a) -> a -> EvBindMap -> a +nonDetStrictFoldEvBindMap k z bs = nonDetStrictFoldDVarEnv k z (ev_bind_varenv bs) + filterEvBindMap :: (EvBind -> Bool) -> EvBindMap -> EvBindMap filterEvBindMap k (EvBindMap { ev_bind_varenv = env }) = EvBindMap { ev_bind_varenv = filterDVarEnv k env } +evBindMapToVarSet :: EvBindMap -> VarSet +evBindMapToVarSet (EvBindMap dve) = unsafeUFMToUniqSet (mapUFM evBindVar (udfmToUfm dve)) + +varSetMinusEvBindMap :: VarSet -> EvBindMap -> VarSet +varSetMinusEvBindMap vs (EvBindMap dve) = vs `uniqSetMinusUDFM` dve + instance Outputable EvBindMap where ppr (EvBindMap m) = ppr m @@ -851,8 +869,8 @@ findNeededEvVars ev_binds seeds = transCloVarSet also_needs seeds where also_needs :: VarSet -> VarSet - also_needs needs = nonDetFoldUniqSet add emptyVarSet needs - -- It's OK to use nonDetFoldUFM here because we immediately + also_needs needs = nonDetStrictFoldUniqSet add emptyVarSet needs + -- It's OK to use a non-deterministic fold here because we immediately -- forget about the ordering by creating a set add :: Var -> VarSet -> VarSet ===================================== compiler/GHC/Tc/Utils/TcType.hs ===================================== @@ -693,7 +693,9 @@ tcTyVarLevel tv tcTypeLevel :: TcType -> TcLevel -- Max level of any free var of the type tcTypeLevel ty - = foldDVarSet add topTcLevel (tyCoVarsOfTypeDSet ty) + = nonDetStrictFoldDVarSet add topTcLevel (tyCoVarsOfTypeDSet ty) + -- It's safe to use a non-deterministic fold because `maxTcLevel` is + -- commutative. where add v lvl | isTcTyVar v = lvl `maxTcLevel` tcTyVarLevel v ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -785,16 +785,23 @@ cleanUseDmd_maybe _ = Nothing splitFVs :: Bool -- Thunk -> DmdEnv -> (DmdEnv, DmdEnv) splitFVs is_thunk rhs_fvs - | is_thunk = nonDetFoldUFM_Directly add (emptyVarEnv, emptyVarEnv) rhs_fvs - -- It's OK to use nonDetFoldUFM_Directly because we + | is_thunk = strictPairToTuple $ + nonDetStrictFoldUFM_Directly add (emptyVarEnv :*: emptyVarEnv) rhs_fvs + -- It's OK to use a non-deterministic fold because we -- immediately forget the ordering by putting the elements -- in the envs again | otherwise = partitionVarEnv isWeakDmd rhs_fvs where - add uniq dmd@(JD { sd = s, ud = u }) (lazy_fv, sig_fv) - | Lazy <- s = (addToUFM_Directly lazy_fv uniq dmd, sig_fv) - | otherwise = ( addToUFM_Directly lazy_fv uniq (JD { sd = Lazy, ud = u }) - , addToUFM_Directly sig_fv uniq (JD { sd = s, ud = Abs }) ) + add uniq dmd@(JD { sd = s, ud = u }) (lazy_fv :*: sig_fv) + | Lazy <- s = addToUFM_Directly lazy_fv uniq dmd :*: sig_fv + | otherwise = addToUFM_Directly lazy_fv uniq (JD { sd = Lazy, ud = u }) + :*: + addToUFM_Directly sig_fv uniq (JD { sd = s, ud = Abs }) + +data StrictPair a b = !a :*: !b + +strictPairToTuple :: StrictPair a b -> (a, b) +strictPairToTuple (x :*: y) = (x, y) data TypeShape = TsFun TypeShape | TsProd [TypeShape] ===================================== compiler/GHC/Types/Unique/DFM.hs ===================================== @@ -50,14 +50,14 @@ module GHC.Types.Unique.DFM ( equalKeysUDFM, minusUDFM, listToUDFM, - udfmMinusUFM, + udfmMinusUFM, ufmMinusUDFM, partitionUDFM, anyUDFM, allUDFM, pprUniqDFM, pprUDFM, udfmToList, udfmToUfm, - nonDetFoldUDFM, + nonDetStrictFoldUDFM, alwaysUnsafeUfmToUdfm, ) where @@ -72,7 +72,7 @@ import Data.Functor.Classes (Eq1 (..)) import Data.List (sortBy) import Data.Function (on) import qualified Data.Semigroup as Semi -import GHC.Types.Unique.FM (UniqFM, listToUFM_Directly, nonDetUFMToList, ufmToIntMap) +import GHC.Types.Unique.FM (UniqFM, nonDetUFMToList, ufmToIntMap, unsafeIntMapToUFM) -- Note [Deterministic UniqFM] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -272,12 +272,14 @@ elemUDFM k (UDFM m _i) = M.member (getKey $ getUnique k) m foldUDFM :: (elt -> a -> a) -> a -> UniqDFM elt -> a foldUDFM k z m = foldr k z (eltsUDFM m) --- | Performs a nondeterministic fold over the UniqDFM. +-- | Performs a nondeterministic strict fold over the UniqDFM. -- It's O(n), same as the corresponding function on `UniqFM`. -- If you use this please provide a justification why it doesn't introduce -- nondeterminism. -nonDetFoldUDFM :: (elt -> a -> a) -> a -> UniqDFM elt -> a -nonDetFoldUDFM k z (UDFM m _i) = foldr k z $ map taggedFst $ M.elems m +nonDetStrictFoldUDFM :: (elt -> a -> a) -> a -> UniqDFM elt -> a +nonDetStrictFoldUDFM k z (UDFM m _i) = foldl' k' z m + where + k' acc (TaggedVal v _) = k v acc eltsUDFM :: UniqDFM elt -> [elt] eltsUDFM (UDFM m _i) = @@ -337,6 +339,9 @@ udfmMinusUFM (UDFM x i) y = UDFM (M.difference x (ufmToIntMap y)) i -- M.difference returns a subset of a left set, so `i` is a good upper -- bound. +ufmMinusUDFM :: UniqFM elt1 -> UniqDFM elt2 -> UniqFM elt1 +ufmMinusUDFM x (UDFM y _i) = unsafeIntMapToUFM (M.difference (ufmToIntMap x) y) + -- | Partition UniqDFM into two UniqDFMs according to the predicate partitionUDFM :: (elt -> Bool) -> UniqDFM elt -> (UniqDFM elt, UniqDFM elt) partitionUDFM p (UDFM m i) = @@ -349,8 +354,7 @@ delListFromUDFM = foldl' delFromUDFM -- | This allows for lossy conversion from UniqDFM to UniqFM udfmToUfm :: UniqDFM elt -> UniqFM elt -udfmToUfm (UDFM m _i) = - listToUFM_Directly [(getUnique k, taggedFst tv) | (k, tv) <- M.toList m] +udfmToUfm (UDFM m _i) = unsafeIntMapToUFM (M.map taggedFst m) listToUDFM :: Uniquable key => [(key,elt)] -> UniqDFM elt listToUDFM = foldl' (\m (k, v) -> addToUDFM m k v) emptyUDFM ===================================== compiler/GHC/Types/Unique/DSet.hs ===================================== @@ -26,7 +26,7 @@ module GHC.Types.Unique.DSet ( unionUniqDSets, unionManyUniqDSets, minusUniqDSet, uniqDSetMinusUniqSet, intersectUniqDSets, uniqDSetIntersectUniqSet, - foldUniqDSet, + nonDetStrictFoldUniqDSet, elementOfUniqDSet, filterUniqDSet, sizeUniqDSet, @@ -98,8 +98,11 @@ uniqDSetIntersectUniqSet :: UniqDSet a -> UniqSet b -> UniqDSet a uniqDSetIntersectUniqSet xs ys = UniqDSet (udfmIntersectUFM (getUniqDSet xs) (getUniqSet ys)) -foldUniqDSet :: (a -> b -> b) -> b -> UniqDSet a -> b -foldUniqDSet c n (UniqDSet s) = foldUDFM c n s +-- See Note [Deterministic UniqFM] to learn about nondeterminism. +-- If you use this please provide a justification why it doesn't introduce +-- nondeterminism. +nonDetStrictFoldUniqDSet :: (a -> b -> b) -> b -> UniqDSet a -> b +nonDetStrictFoldUniqDSet f acc (UniqDSet s) = nonDetStrictFoldUDFM f acc s elementOfUniqDSet :: Uniquable a => a -> UniqDSet a -> Bool elementOfUniqDSet k = elemUDFM k . getUniqDSet ===================================== compiler/GHC/Types/Unique/FM.hs ===================================== @@ -56,7 +56,7 @@ module GHC.Types.Unique.FM ( intersectUFM_C, disjointUFM, equalKeysUFM, - nonDetFoldUFM, foldUFM, nonDetFoldUFM_Directly, + nonDetStrictFoldUFM, foldUFM, nonDetStrictFoldUFM_Directly, anyUFM, allUFM, seqEltsUFM, mapUFM, mapUFM_Directly, elemUFM, elemUFM_Directly, @@ -67,7 +67,7 @@ module GHC.Types.Unique.FM ( lookupWithDefaultUFM, lookupWithDefaultUFM_Directly, nonDetEltsUFM, eltsUFM, nonDetKeysUFM, ufmToSet_Directly, - nonDetUFMToList, ufmToIntMap, + nonDetUFMToList, ufmToIntMap, unsafeIntMapToUFM, pprUniqFM, pprUFM, pprUFMWithKeys, pluralUFM ) where @@ -318,14 +318,14 @@ nonDetKeysUFM (UFM m) = map getUnique $ M.keys m -- See Note [Deterministic UniqFM] to learn about nondeterminism. -- If you use this please provide a justification why it doesn't introduce -- nondeterminism. -nonDetFoldUFM :: (elt -> a -> a) -> a -> UniqFM elt -> a -nonDetFoldUFM k z (UFM m) = M.foldr k z m +nonDetStrictFoldUFM :: (elt -> a -> a) -> a -> UniqFM elt -> a +nonDetStrictFoldUFM k z (UFM m) = M.foldl' (flip k) z m -- See Note [Deterministic UniqFM] to learn about nondeterminism. -- If you use this please provide a justification why it doesn't introduce -- nondeterminism. -nonDetFoldUFM_Directly:: (Unique -> elt -> a -> a) -> a -> UniqFM elt -> a -nonDetFoldUFM_Directly k z (UFM m) = M.foldrWithKey (k . getUnique) z m +nonDetStrictFoldUFM_Directly:: (Unique -> elt -> a -> a) -> a -> UniqFM elt -> a +nonDetStrictFoldUFM_Directly k z (UFM m) = M.foldlWithKey' (\z' i x -> k (getUnique i) x z') z m -- See Note [Deterministic UniqFM] to learn about nondeterminism. -- If you use this please provide a justification why it doesn't introduce @@ -359,6 +359,9 @@ instance Traversable NonDetUniqFM where ufmToIntMap :: UniqFM elt -> M.IntMap elt ufmToIntMap (UFM m) = m +unsafeIntMapToUFM :: M.IntMap elt -> UniqFM elt +unsafeIntMapToUFM = UFM + -- Determines whether two 'UniqFM's contain the same keys. equalKeysUFM :: UniqFM a -> UniqFM b -> Bool equalKeysUFM (UFM m1) (UFM m2) = liftEq (\_ _ -> True) m1 m2 ===================================== compiler/GHC/Types/Unique/Set.hs ===================================== @@ -25,7 +25,7 @@ module GHC.Types.Unique.Set ( delOneFromUniqSet, delOneFromUniqSet_Directly, delListFromUniqSet, delListFromUniqSet_Directly, unionUniqSets, unionManyUniqSets, - minusUniqSet, uniqSetMinusUFM, + minusUniqSet, uniqSetMinusUFM, uniqSetMinusUDFM, intersectUniqSets, restrictUniqSetToUFM, uniqSetAny, uniqSetAll, @@ -42,12 +42,12 @@ module GHC.Types.Unique.Set ( unsafeUFMToUniqSet, nonDetEltsUniqSet, nonDetKeysUniqSet, - nonDetFoldUniqSet, - nonDetFoldUniqSet_Directly + nonDetStrictFoldUniqSet, ) where import GHC.Prelude +import GHC.Types.Unique.DFM import GHC.Types.Unique.FM import GHC.Types.Unique import Data.Coerce @@ -111,6 +111,9 @@ restrictUniqSetToUFM (UniqSet s) m = UniqSet (intersectUFM s m) uniqSetMinusUFM :: UniqSet a -> UniqFM b -> UniqSet a uniqSetMinusUFM (UniqSet s) t = UniqSet (minusUFM s t) +uniqSetMinusUDFM :: UniqSet a -> UniqDFM b -> UniqSet a +uniqSetMinusUDFM (UniqSet s) t = UniqSet (ufmMinusUDFM s t) + elementOfUniqSet :: Uniquable a => a -> UniqSet a -> Bool elementOfUniqSet a (UniqSet s) = elemUFM a s @@ -159,14 +162,8 @@ nonDetKeysUniqSet = nonDetKeysUFM . getUniqSet' -- See Note [Deterministic UniqFM] to learn about nondeterminism. -- If you use this please provide a justification why it doesn't introduce -- nondeterminism. -nonDetFoldUniqSet :: (elt -> a -> a) -> a -> UniqSet elt -> a -nonDetFoldUniqSet c n (UniqSet s) = nonDetFoldUFM c n s - --- See Note [Deterministic UniqFM] to learn about nondeterminism. --- If you use this please provide a justification why it doesn't introduce --- nondeterminism. -nonDetFoldUniqSet_Directly:: (Unique -> elt -> a -> a) -> a -> UniqSet elt -> a -nonDetFoldUniqSet_Directly f n (UniqSet s) = nonDetFoldUFM_Directly f n s +nonDetStrictFoldUniqSet :: (elt -> a -> a) -> a -> UniqSet elt -> a +nonDetStrictFoldUniqSet c n (UniqSet s) = nonDetStrictFoldUFM c n s -- See Note [UniqSet invariant] mapUniqSet :: Uniquable b => (a -> b) -> UniqSet a -> UniqSet b ===================================== compiler/GHC/Types/Var/Env.hs ===================================== @@ -33,7 +33,7 @@ module GHC.Types.Var.Env ( extendDVarEnv, extendDVarEnv_C, extendDVarEnvList, lookupDVarEnv, elemDVarEnv, - isEmptyDVarEnv, foldDVarEnv, + isEmptyDVarEnv, foldDVarEnv, nonDetStrictFoldDVarEnv, mapDVarEnv, filterDVarEnv, modifyDVarEnv, alterDVarEnv, @@ -575,6 +575,12 @@ lookupDVarEnv = lookupUDFM foldDVarEnv :: (a -> b -> b) -> b -> DVarEnv a -> b foldDVarEnv = foldUDFM +-- See Note [Deterministic UniqFM] to learn about nondeterminism. +-- If you use this please provide a justification why it doesn't introduce +-- nondeterminism. +nonDetStrictFoldDVarEnv :: (a -> b -> b) -> b -> DVarEnv a -> b +nonDetStrictFoldDVarEnv = nonDetStrictFoldUDFM + mapDVarEnv :: (a -> b) -> DVarEnv a -> DVarEnv b mapDVarEnv = mapUDFM ===================================== compiler/GHC/Types/Var/Set.hs ===================================== @@ -23,7 +23,7 @@ module GHC.Types.Var.Set ( sizeVarSet, seqVarSet, elemVarSetByKey, partitionVarSet, pluralVarSet, pprVarSet, - nonDetFoldVarSet, + nonDetStrictFoldVarSet, -- * Deterministic Var set types DVarSet, DIdSet, DTyVarSet, DTyCoVarSet, @@ -36,7 +36,9 @@ module GHC.Types.Var.Set ( intersectDVarSet, dVarSetIntersectVarSet, intersectsDVarSet, disjointDVarSet, isEmptyDVarSet, delDVarSet, delDVarSetList, - minusDVarSet, foldDVarSet, filterDVarSet, mapDVarSet, + minusDVarSet, + nonDetStrictFoldDVarSet, + filterDVarSet, mapDVarSet, dVarSetMinusVarSet, anyDVarSet, allDVarSet, transCloDVarSet, sizeDVarSet, seqDVarSet, @@ -152,8 +154,11 @@ allVarSet = uniqSetAll mapVarSet :: Uniquable b => (a -> b) -> UniqSet a -> UniqSet b mapVarSet = mapUniqSet -nonDetFoldVarSet :: (Var -> a -> a) -> a -> VarSet -> a -nonDetFoldVarSet = nonDetFoldUniqSet +-- See Note [Deterministic UniqFM] to learn about nondeterminism. +-- If you use this please provide a justification why it doesn't introduce +-- nondeterminism. +nonDetStrictFoldVarSet :: (Var -> a -> a) -> a -> VarSet -> a +nonDetStrictFoldVarSet = nonDetStrictFoldUniqSet fixVarSet :: (VarSet -> VarSet) -- Map the current set to a new set -> VarSet -> VarSet @@ -290,8 +295,11 @@ minusDVarSet = minusUniqDSet dVarSetMinusVarSet :: DVarSet -> VarSet -> DVarSet dVarSetMinusVarSet = uniqDSetMinusUniqSet -foldDVarSet :: (Var -> a -> a) -> a -> DVarSet -> a -foldDVarSet = foldUniqDSet +-- See Note [Deterministic UniqFM] to learn about nondeterminism. +-- If you use this please provide a justification why it doesn't introduce +-- nondeterminism. +nonDetStrictFoldDVarSet :: (Var -> a -> a) -> a -> DVarSet -> a +nonDetStrictFoldDVarSet = nonDetStrictFoldUniqDSet anyDVarSet :: (Var -> Bool) -> DVarSet -> Bool anyDVarSet p = anyUDFM p . getUniqDSet View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c05c06596bd1b2852454af6243fc15ee852d2f45 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c05c06596bd1b2852454af6243fc15ee852d2f45 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 07:32:11 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 14 May 2020 03:32:11 -0400 Subject: [Git][ghc/ghc][master] Use Data.IntMap.disjoint Message-ID: <5ebcf3fbd1f69_61673f81afdc5030112018f7@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 477f13bb by Simon Jakobi at 2020-05-14T03:31:58-04:00 Use Data.IntMap.disjoint Data.IntMap gained a dedicated `disjoint` function in containers-0.6.2.1. This patch applies this function where appropriate in hopes of modest compiler performance improvements. Closes #16806. - - - - - 16 changed files: - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Rename/Expr.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Solver.hs - compiler/GHC/Tc/TyCl/Build.hs - compiler/GHC/Types/Name/Env.hs - compiler/GHC/Types/Name/Occurrence.hs - compiler/GHC/Types/Name/Set.hs - compiler/GHC/Types/Unique/DFM.hs - compiler/GHC/Types/Unique/FM.hs - compiler/GHC/Types/Unique/Set.hs - compiler/GHC/Types/Var/Env.hs - compiler/ghc.cabal.in - hadrian/src/Rules/Documentation.hs Changes: ===================================== compiler/GHC/Core/Opt/Specialise.hs ===================================== @@ -1141,7 +1141,7 @@ specCase env scrut' case_bndr [(con, args, rhs)] is_flt_sc_arg var = isId var && not (isDeadBinder var) && isDictTy var_ty - && not (tyCoVarsOfType var_ty `intersectsVarSet` arg_set) + && tyCoVarsOfType var_ty `disjointVarSet` arg_set where var_ty = idType var @@ -2745,7 +2745,7 @@ filterCalls (CIS fn call_bag) dbs = extendVarSetList so_far (bindersOf bind) | otherwise = so_far - ok_call (CI { ci_fvs = fvs }) = not (fvs `intersectsVarSet` dump_set) + ok_call (CI { ci_fvs = fvs }) = fvs `disjointVarSet` dump_set ---------------------- splitDictBinds :: Bag DictBind -> IdSet -> (Bag DictBind, Bag DictBind, IdSet) @@ -2776,7 +2776,7 @@ deleteCallsMentioning :: VarSet -> CallDetails -> CallDetails deleteCallsMentioning bs calls = mapDVarEnv (ciSetFilter keep_call) calls where - keep_call (CI { ci_fvs = fvs }) = not (fvs `intersectsVarSet` bs) + keep_call (CI { ci_fvs = fvs }) = fvs `disjointVarSet` bs deleteCallsFor :: [Id] -> CallDetails -> CallDetails -- Remove calls *for* bs ===================================== compiler/GHC/Core/TyCo/Subst.hs ===================================== @@ -383,8 +383,8 @@ extendTCvSubstList subst tvs tys unionTCvSubst :: TCvSubst -> TCvSubst -> TCvSubst -- Works when the ranges are disjoint unionTCvSubst (TCvSubst in_scope1 tenv1 cenv1) (TCvSubst in_scope2 tenv2 cenv2) - = ASSERT( not (tenv1 `intersectsVarEnv` tenv2) - && not (cenv1 `intersectsVarEnv` cenv2) ) + = ASSERT( tenv1 `disjointVarEnv` tenv2 + && cenv1 `disjointVarEnv` cenv2 ) TCvSubst (in_scope1 `unionInScope` in_scope2) (tenv1 `plusVarEnv` tenv2) (cenv1 `plusVarEnv` cenv2) ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -2116,7 +2116,7 @@ isValidJoinPointType arity ty where valid_under tvs arity ty | arity == 0 - = isEmptyVarSet (tvs `intersectVarSet` tyCoVarsOfType ty) + = tvs `disjointVarSet` tyCoVarsOfType ty | Just (t, ty') <- splitForAllTy_maybe ty = valid_under (tvs `extendVarSet` t) (arity-1) ty' | Just (_, res_ty) <- splitFunTy_maybe ty ===================================== compiler/GHC/Rename/Expr.hs ===================================== @@ -1335,7 +1335,7 @@ glomSegments ctxt ((defs,uses,fwds,stmt) : segs) = (reverse yeses, reverse noes) where (noes, yeses) = span not_needed (reverse dus) - not_needed (defs,_,_,_) = not (intersectsNameSet defs uses) + not_needed (defs,_,_,_) = disjointNameSet defs uses ---------------------------------------------------- segsToStmts :: Stmt GhcRn body @@ -1889,7 +1889,7 @@ slurpIndependentStmts stmts = go [] [] emptyNameSet stmts -- then we have actually done some splitting. Otherwise it will go into -- an infinite loop (#14163). go lets indep bndrs ((L loc (BindStmt xbs pat body), fvs): rest) - | isEmptyNameSet (bndrs `intersectNameSet` fvs) && not (isStrictPattern pat) + | disjointNameSet bndrs fvs && not (isStrictPattern pat) = go lets ((L loc (BindStmt xbs pat body), fvs) : indep) bndrs' rest where bndrs' = bndrs `unionNameSet` mkNameSet (collectPatBinders pat) @@ -1899,7 +1899,7 @@ slurpIndependentStmts stmts = go [] [] emptyNameSet stmts -- TODO: perhaps we shouldn't do this if there are any strict bindings, -- because we might be moving evaluation earlier. go lets indep bndrs ((L loc (LetStmt noExtField binds), fvs) : rest) - | isEmptyNameSet (bndrs `intersectNameSet` fvs) + | disjointNameSet bndrs fvs = go ((L loc (LetStmt noExtField binds), fvs) : lets) indep bndrs rest go _ [] _ _ = Nothing go _ [_] _ _ = Nothing ===================================== compiler/GHC/Tc/Errors/Hole.hs ===================================== @@ -648,8 +648,7 @@ findValidHoleFits tidy_env implics simples h@(Hole { hole_sort = ExprHole _ ctFreeVarSet = fvVarSet . tyCoFVsOfType . ctPred hole_fv_set = fvVarSet hole_fvs anyFVMentioned :: Ct -> Bool - anyFVMentioned ct = not $ isEmptyVarSet $ - ctFreeVarSet ct `intersectVarSet` hole_fv_set + anyFVMentioned ct = ctFreeVarSet ct `intersectsVarSet` hole_fv_set -- We filter out those constraints that have no variables (since -- they won't be solved by finding a type for the type variable -- representing the hole) and also other holes, since we're not ===================================== compiler/GHC/Tc/Solver.hs ===================================== @@ -2407,7 +2407,7 @@ floatEqualities skols given_ids ev_binds_var no_given_eqs is_floatable :: VarSet -> Ct -> Bool is_floatable skols ct - | isDerivedCt ct = not (tyCoVarsOfCt ct `intersectsVarSet` skols) + | isDerivedCt ct = tyCoVarsOfCt ct `disjointVarSet` skols | otherwise = not (ctEvId ct `elemVarSet` skols) add_captured_ev_ids :: Cts -> VarSet -> VarSet ===================================== compiler/GHC/Tc/TyCl/Build.hs ===================================== @@ -164,8 +164,7 @@ mkDataConStupidTheta tycon arg_tys univ_tvs -- stupid theta, taken from the TyCon arg_tyvars = tyCoVarsOfTypes arg_tys - in_arg_tys pred = not $ isEmptyVarSet $ - tyCoVarsOfType pred `intersectVarSet` arg_tyvars + in_arg_tys pred = tyCoVarsOfType pred `intersectsVarSet` arg_tyvars ------------------------------------------------------ ===================================== compiler/GHC/Types/Name/Env.hs ===================================== @@ -140,7 +140,7 @@ delFromNameEnv x y = delFromUFM x y delListFromNameEnv x y = delListFromUFM x y filterNameEnv x y = filterUFM x y anyNameEnv f x = foldUFM ((||) . f) False x -disjointNameEnv x y = isNullUFM (intersectUFM x y) +disjointNameEnv x y = disjointUFM x y lookupNameEnv_NF env n = expectJust "lookupNameEnv_NF" (lookupNameEnv env n) ===================================== compiler/GHC/Types/Name/Occurrence.hs ===================================== @@ -90,7 +90,7 @@ module GHC.Types.Name.Occurrence ( OccSet, emptyOccSet, unitOccSet, mkOccSet, extendOccSet, extendOccSetList, unionOccSets, unionManyOccSets, minusOccSet, elemOccSet, - isEmptyOccSet, intersectOccSet, intersectsOccSet, + isEmptyOccSet, intersectOccSet, filterOccSet, -- * Tidying up @@ -449,7 +449,6 @@ minusOccSet :: OccSet -> OccSet -> OccSet elemOccSet :: OccName -> OccSet -> Bool isEmptyOccSet :: OccSet -> Bool intersectOccSet :: OccSet -> OccSet -> OccSet -intersectsOccSet :: OccSet -> OccSet -> Bool filterOccSet :: (OccName -> Bool) -> OccSet -> OccSet emptyOccSet = emptyUniqSet @@ -463,7 +462,6 @@ minusOccSet = minusUniqSet elemOccSet = elementOfUniqSet isEmptyOccSet = isEmptyUniqSet intersectOccSet = intersectUniqSets -intersectsOccSet s1 s2 = not (isEmptyOccSet (s1 `intersectOccSet` s2)) filterOccSet = filterUniqSet {- ===================================== compiler/GHC/Types/Name/Set.hs ===================================== @@ -13,7 +13,7 @@ module GHC.Types.Name.Set ( emptyNameSet, unitNameSet, mkNameSet, unionNameSet, unionNameSets, minusNameSet, elemNameSet, extendNameSet, extendNameSetList, delFromNameSet, delListFromNameSet, isEmptyNameSet, filterNameSet, - intersectsNameSet, intersectNameSet, + intersectsNameSet, disjointNameSet, intersectNameSet, nameSetAny, nameSetAll, nameSetElemsStable, -- * Free variables @@ -69,6 +69,7 @@ delListFromNameSet :: NameSet -> [Name] -> NameSet filterNameSet :: (Name -> Bool) -> NameSet -> NameSet intersectNameSet :: NameSet -> NameSet -> NameSet intersectsNameSet :: NameSet -> NameSet -> Bool +disjointNameSet :: NameSet -> NameSet -> Bool -- ^ True if there is a non-empty intersection. -- @s1 `intersectsNameSet` s2@ doesn't compute @s2@ if @s1@ is empty @@ -85,10 +86,11 @@ elemNameSet = elementOfUniqSet delFromNameSet = delOneFromUniqSet filterNameSet = filterUniqSet intersectNameSet = intersectUniqSets +disjointNameSet = disjointUniqSets delListFromNameSet set ns = foldl' delFromNameSet set ns -intersectsNameSet s1 s2 = not (isEmptyNameSet (s1 `intersectNameSet` s2)) +intersectsNameSet s1 s2 = not (s1 `disjointNameSet` s2) nameSetAny :: (Name -> Bool) -> NameSet -> Bool nameSetAny = uniqSetAny ===================================== compiler/GHC/Types/Unique/DFM.hs ===================================== @@ -45,7 +45,6 @@ module GHC.Types.Unique.DFM ( isNullUDFM, sizeUDFM, intersectUDFM, udfmIntersectUFM, - intersectsUDFM, disjointUDFM, disjointUdfmUfm, equalKeysUDFM, minusUDFM, @@ -320,14 +319,11 @@ udfmIntersectUFM (UDFM x i) y = UDFM (M.intersection x (ufmToIntMap y)) i -- M.intersection is left biased, that means the result will only have -- a subset of elements from the left set, so `i` is a good upper bound. -intersectsUDFM :: UniqDFM elt -> UniqDFM elt -> Bool -intersectsUDFM x y = isNullUDFM (x `intersectUDFM` y) - disjointUDFM :: UniqDFM elt -> UniqDFM elt -> Bool -disjointUDFM (UDFM x _i) (UDFM y _j) = M.null (M.intersection x y) +disjointUDFM (UDFM x _i) (UDFM y _j) = M.disjoint x y disjointUdfmUfm :: UniqDFM elt -> UniqFM elt2 -> Bool -disjointUdfmUfm (UDFM x _i) y = M.null (M.intersection x (ufmToIntMap y)) +disjointUdfmUfm (UDFM x _i) y = M.disjoint x (ufmToIntMap y) minusUDFM :: UniqDFM elt1 -> UniqDFM elt2 -> UniqDFM elt1 minusUDFM (UDFM x i) (UDFM y _j) = UDFM (M.difference x y) i ===================================== compiler/GHC/Types/Unique/FM.hs ===================================== @@ -241,7 +241,7 @@ intersectUFM_C intersectUFM_C f (UFM x) (UFM y) = UFM (M.intersectionWith f x y) disjointUFM :: UniqFM elt1 -> UniqFM elt2 -> Bool -disjointUFM (UFM x) (UFM y) = M.null (M.intersection x y) +disjointUFM (UFM x) (UFM y) = M.disjoint x y foldUFM :: (elt -> a -> a) -> a -> UniqFM elt -> a foldUFM k z (UFM m) = M.foldr k z m ===================================== compiler/GHC/Types/Unique/Set.hs ===================================== @@ -27,6 +27,7 @@ module GHC.Types.Unique.Set ( unionUniqSets, unionManyUniqSets, minusUniqSet, uniqSetMinusUFM, uniqSetMinusUDFM, intersectUniqSets, + disjointUniqSets, restrictUniqSetToUFM, uniqSetAny, uniqSetAll, elementOfUniqSet, @@ -105,6 +106,9 @@ minusUniqSet (UniqSet s) (UniqSet t) = UniqSet (minusUFM s t) intersectUniqSets :: UniqSet a -> UniqSet a -> UniqSet a intersectUniqSets (UniqSet s) (UniqSet t) = UniqSet (intersectUFM s t) +disjointUniqSets :: UniqSet a -> UniqSet a -> Bool +disjointUniqSets (UniqSet s) (UniqSet t) = disjointUFM s t + restrictUniqSetToUFM :: UniqSet a -> UniqFM b -> UniqSet a restrictUniqSetToUFM (UniqSet s) m = UniqSet (intersectUFM s m) ===================================== compiler/GHC/Types/Var/Env.hs ===================================== @@ -15,7 +15,7 @@ module GHC.Types.Var.Env ( plusVarEnv, plusVarEnv_C, plusVarEnv_CD, plusMaybeVarEnv_C, plusVarEnvList, alterVarEnv, delVarEnvList, delVarEnv, - minusVarEnv, intersectsVarEnv, + minusVarEnv, lookupVarEnv, lookupVarEnv_NF, lookupWithDefaultVarEnv, mapVarEnv, zipVarEnv, modifyVarEnv, modifyVarEnv_Directly, @@ -472,7 +472,6 @@ restrictVarEnv :: VarEnv a -> VarSet -> VarEnv a delVarEnvList :: VarEnv a -> [Var] -> VarEnv a delVarEnv :: VarEnv a -> Var -> VarEnv a minusVarEnv :: VarEnv a -> VarEnv b -> VarEnv a -intersectsVarEnv :: VarEnv a -> VarEnv a -> Bool plusVarEnv_C :: (a -> a -> a) -> VarEnv a -> VarEnv a -> VarEnv a plusVarEnv_CD :: (a -> a -> a) -> VarEnv a -> a -> VarEnv a -> a -> VarEnv a plusMaybeVarEnv_C :: (a -> a -> Maybe a) -> VarEnv a -> VarEnv a -> VarEnv a @@ -502,7 +501,6 @@ plusMaybeVarEnv_C = plusMaybeUFM_C delVarEnvList = delListFromUFM delVarEnv = delFromUFM minusVarEnv = minusUFM -intersectsVarEnv e1 e2 = not (isEmptyVarEnv (e1 `intersectUFM` e2)) plusVarEnv = plusUFM plusVarEnvList = plusUFMList lookupVarEnv = lookupUFM ===================================== compiler/ghc.cabal.in ===================================== @@ -66,7 +66,7 @@ Library bytestring >= 0.9 && < 0.11, binary == 0.8.*, time >= 1.4 && < 1.10, - containers >= 0.5 && < 0.7, + containers >= 0.6.2.1 && < 0.7, array >= 0.1 && < 0.6, filepath >= 1 && < 1.5, template-haskell == 2.17.*, ===================================== hadrian/src/Rules/Documentation.hs ===================================== @@ -103,9 +103,8 @@ documentationRules = do -- include toplevel html target unless we neither want -- haddocks nor html pages produced by sphinx. - ++ [ html | Set.size (doctargets `Set.intersection` - Set.fromList [Haddocks, SphinxHTML] - ) > 0 ] + ++ [ html | Haddocks `Set.member` doctargets + || SphinxHTML `Set.member` doctargets ] -- include archives for whatever targets remain from -- the --docs arguments we got. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/477f13bb4c5c2ba969d2c90890c51d7de01c5312 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/477f13bb4c5c2ba969d2c90890c51d7de01c5312 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 10:38:43 2020 From: gitlab at gitlab.haskell.org (Richard Eisenberg) Date: Thu, 14 May 2020 06:38:43 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/mr-template-key-part Message-ID: <5ebd1fb378886_6167122db45c1121365e@gitlab.haskell.org.mail> Richard Eisenberg pushed new branch wip/mr-template-key-part at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/mr-template-key-part You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 12:53:47 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Thu, 14 May 2020 08:53:47 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/mod-rem-strict Message-ID: <5ebd3f5b85882_61678d4bb581123162d@gitlab.haskell.org.mail> Sebastian Graf pushed new branch wip/mod-rem-strict at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/mod-rem-strict You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 14:39:42 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Thu, 14 May 2020 10:39:42 -0400 Subject: [Git][ghc/ghc][wip/nested-cpr-2019] 2 commits: Fix T9291 Message-ID: <5ebd582e2cc63_61671265a3301125848b@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/nested-cpr-2019 at Glasgow Haskell Compiler / GHC Commits: d0b49961 by Sebastian Graf at 2020-05-11T21:51:42+02:00 Fix T9291 - - - - - 5397fe39 by Sebastian Graf at 2020-05-14T16:39:22+02:00 Document -fcase-binder-cpr-depth in the user's guide - - - - - 3 changed files: - compiler/GHC/Driver/Session.hs - docs/users_guide/using-optimisation.rst - testsuite/tests/simplStg/should_run/T9291.hs Changes: ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -3523,7 +3523,6 @@ fFlagsDeps = [ flagSpec "stg-cse" Opt_StgCSE, flagSpec "stg-lift-lams" Opt_StgLiftLams, flagSpec "cpr-anal" Opt_CprAnal, - flagSpec "case-binder-cpr" Opt_CaseBinderCpr, flagSpec "defer-diagnostics" Opt_DeferDiagnostics, flagSpec "defer-type-errors" Opt_DeferTypeErrors, flagSpec "defer-typed-holes" Opt_DeferTypedHoles, ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -293,6 +293,41 @@ by saying ``-fno-wombat``. Turn on CPR analysis in the demand analyser. +.. ghc-flag:: -fcase-binder-cpr-depth + :shortdesc: Maximum depth at which case binders have the CPR property. + :type: dynamic + :category: + + :default: 1 + + Normally, case binders get the CPR property if their scrutinee had it. + But depending on whether the case binder occurs on a cold path, it may make sense + to give it the CPR property unconditionally. + + This flag controls how deep inside a constructor application we still + consider CPR binders to have th CPR property. The default is 1, so the + following function will have the CPR property: :: + + f :: Bool -> Int -> Int + f False _ = 1 + f _ x at 2 = x + f _ _ = 3 + + Note that ``x`` did not occur nested inside a constructor, so depth 1. + + On the other hand, the following function will *not* have the Nested CPR + property: :: + + g :: Bool -> Int -> (Int, Int) + g False _ = (1, 1) + g _ x at 2 = (x, x) + g _ _ = (3, 3) + + Because ``x`` occurs nested inside a pair, so at depth 2. + + Depth 0 will never give any CPR binder the CPR property, unless the + scrutinee had it to begin with. + .. ghc-flag:: -fcse :shortdesc: Enable common sub-expression elimination. Implied by :ghc-flag:`-O`. :type: dynamic ===================================== testsuite/tests/simplStg/should_run/T9291.hs ===================================== @@ -2,17 +2,19 @@ import GHC.Exts import Unsafe.Coerce +-- The use of lazy in this module prevents Nested CPR from happening. +-- Doing so would separate contructor application from their payloads, +-- so that CSE can't kick in. +-- This is unfortunate, but this testcase is about demonstrating +-- effectiveness of STG CSE. + foo :: Either Int a -> Either Bool a foo (Right x) = Right x foo _ = Left True {-# NOINLINE foo #-} bar :: a -> (Either Int a, Either Bool a) --- lazy prevents Nested CPR from returning just (# x, x #) here. --- Doing so would lead to reboxing at the call site, where CSE --- isn't able to see that both tuple components are equivalent. --- This is unfortunate, but this testcase is about demonstrating --- effectiveness of STG CSE. +-- Why lazy? See comment above; the worker would return (# x, x #) bar x = (lazy $ Right x, lazy $ Right x) {-# NOINLINE bar #-} @@ -25,11 +27,12 @@ nested _ = Left True -- CSE in a recursive group data Tree x = T x (Either Int (Tree x)) (Either Bool (Tree x)) rec1 :: x -> Tree x +-- Why lazy? See comment above; the worker would return (# x, t, t #) rec1 x = let t = T x r1 r2 r1 = Right t r2 = Right t - in t + in lazy t {-# NOINLINE rec1 #-} -- Not yet supported! (and tricky) @@ -42,17 +45,8 @@ rec2 x = {-# NOINLINE rec2 #-} test x = do - let (r1,r2) = bar x - (same $! r1) $! r2 - let r3 = foo r1 - (same $! r1) $! r3 - let (r4,_) = bar r1 - let r5 = nested r4 - (same $! r4) $! r5 let (T _ r6 r7) = rec1 x (same $! r6) $! r7 - let s1@(S _ s2) = rec2 x - (same $! s1) $! s2 {-# NOINLINE test #-} main = test "foo" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f0d83bab1f471fb9f0b8ff8cd1aa75ec6c6a4a20...5397fe394009f07b0c42977af1bc1030c2592b8a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f0d83bab1f471fb9f0b8ff8cd1aa75ec6c6a4a20...5397fe394009f07b0c42977af1bc1030c2592b8a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 15:22:45 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Thu, 14 May 2020 11:22:45 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn-simpl] DmdAnal: Improve handling of precise exceptions Message-ID: <5ebd6245d1982_61673f81cc06592c1126834c@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn-simpl at Glasgow Haskell Compiler / GHC Commits: f7a6fd26 by Sebastian Graf at 2020-05-14T17:21:59+02:00 DmdAnal: Improve handling of precise exceptions This patch does two things: Fix possible unsoundness in what was called the "IO hack" and implement part 2.1 of the "fixing precise exceptions" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions, which, in combination with !2956, supersedes !3014 and !2525. **IO hack** The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is called `exprMayThrowPreciseException` now. I came up with two testcases exemplifying possible unsoundness (if twisted enough) in the old approach: - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. - `T13380e`: Demonstrating unsoundness of the "IO hack" when we have Nested CPR. Not currently relevant, as we don't have Nested CPR yet. - `T13380f`: Demonstrating unsoundness of the "IO hack" for safe FFI calls. Basically, the IO hack assumed that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future, see `T13380e`. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380{d,e}` (and will hopefully be robust to Nested CPR). **Precise exceptions** In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that was terribly unprincipled. That unprincipledness resulted in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception (and the existing IO hack doesn't detect that) Fixing both issues in !3014 turned out to be too complicated and had the potential to regress in the future. Hence we decided to only fix `T13380b` and augment the `Divergence` lattice with a new middle-layer element, `ExnOrDiv`, which means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. See the wiki page on Step 2.1 for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#dead-code-elimination-for-raiseio-with-isdeadenddiv-introducing-exnordiv-step-21 - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/LiberateCase.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/ForeignCall.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Make.hs - testsuite/tests/stranal/should_compile/T10482a.stderr - testsuite/tests/stranal/should_compile/T10694.stderr - + testsuite/tests/stranal/should_compile/T13380b.hs - testsuite/tests/stranal/should_compile/all.T - + testsuite/tests/stranal/should_run/T13380d.hs - + testsuite/tests/stranal/should_run/T13380d.stderr - + testsuite/tests/stranal/should_run/T13380e.hs - + testsuite/tests/stranal/should_run/T13380e.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f7a6fd26bd0d1e936e854672f29578ea6c7ebcca -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f7a6fd26bd0d1e936e854672f29578ea6c7ebcca You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 16:11:26 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 14 May 2020 12:11:26 -0400 Subject: [Git][ghc/ghc][wip/backports] 14 commits: configure.ac: Reset RELEASE to NO Message-ID: <5ebd6dae250b3_61673f81afdc503011284517@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/backports at Glasgow Haskell Compiler / GHC Commits: 584c3b05 by Ben Gamari at 2020-05-12T12:42:34-04:00 configure.ac: Reset RELEASE to NO - - - - - 40cb7155 by Ben Gamari at 2020-05-14T12:10:51-04:00 rts: Add getCurrentThreadCPUTime helper (cherry picked from commit cedd6f3041de6abe64dfa3257bec7730a9dced9f) - - - - - 66be810f by Ben Gamari at 2020-05-14T12:10:51-04:00 rts: Prefer darwin-specific getCurrentThreadCPUTime macOS Catalina now supports a non-POSIX-compliant version of clock_gettime which cannot use the clock_gettime codepath. Fixes #17906. (cherry picked from commit bb586f894532baf1bcb822afd0df7f9fea198671) - - - - - 76f679ea by Ben Gamari at 2020-05-14T12:10:51-04:00 nonmoving-gc: Track time usage of nonmoving marking (cherry picked from commit ace618cd2294989e783bd453cee88e0e1c0dad77) - - - - - c8e88946 by Ben Gamari at 2020-05-14T12:10:51-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 3837ad4c by Ben Gamari at 2020-05-14T12:10:51-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - d9127b8f by Ben Gamari at 2020-05-14T12:10:51-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - a70192c8 by Ben Gamari at 2020-05-14T12:10:51-04:00 hadrian: Allow libnuma library path to be specified - - - - - ea602081 by Ben Gamari at 2020-05-14T12:10:51-04:00 hadrian: Refactor gmp arguments Move the gmp configuration to its own binding. - - - - - b74dc41d by Ben Gamari at 2020-05-14T12:10:52-04:00 hadrian: Tell Cabal about integer-gmp library location - - - - - e8db3006 by Ben Gamari at 2020-05-14T12:10:52-04:00 rts: Zero block flags with -DZ Block flags are very useful for determining the state of a block. However, some block allocator users don't touch them, leading to misleading values. Ensure that we zero then when zero-on-gc is set. This is safe and makes the flags more useful during debugging. - - - - - e7524deb by Ben Gamari at 2020-05-14T12:10:52-04:00 nonmoving: Fix incorrect failed_to_evac value during deadlock gc Previously we would incorrectly set the failed_to_evac flag if we evacuated a value due to a deadlock GC. This would cause us to mark more things as dirty than strictly necessary. It also turned up a nasty but which I will fix next. - - - - - 4c31e510 by Ben Gamari at 2020-05-14T12:10:52-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - b9df14c4 by Ben Gamari at 2020-05-14T12:10:52-04:00 nonmoving: Optimise the write barrier (cherry picked from commit a636eadac1f30bae37aeb6526f94893293f098b8) - - - - - 25 changed files: - configure.ac - hadrian/cfg/system.config.in - hadrian/src/Oracles/Flag.hs - hadrian/src/Oracles/Setting.hs - hadrian/src/Settings/Packages.hs - includes/RtsAPI.h - includes/rts/Time.h - libraries/base/GHC/Stats.hsc - libraries/text - rts/GetTime.h - rts/ProfHeap.c - rts/Stats.c - rts/Stats.h - rts/Updates.h - rts/posix/GetTime.c - rts/sm/BlockAlloc.c - rts/sm/Evac.c - rts/sm/GC.c - rts/sm/GCThread.h - rts/sm/NonMoving.c - rts/sm/NonMovingMark.c - rts/sm/NonMovingScav.c - rts/sm/NonMovingSweep.c - rts/sm/Storage.c - rts/win32/GetTime.c Changes: ===================================== configure.ac ===================================== @@ -16,7 +16,7 @@ dnl AC_INIT([The Glorious Glasgow Haskell Compilation System], [8.10.1], [glasgow-haskell-bugs at haskell.org], [ghc-AC_PACKAGE_VERSION]) # Set this to YES for a released version, otherwise NO -: ${RELEASE=YES} +: ${RELEASE=NO} # The primary version (e.g. 7.5, 7.4.1) is set in the AC_INIT line # above. If this is not a released version, then we will append the @@ -1285,6 +1285,28 @@ AC_DEFINE_UNQUOTED([USE_LIBDW], [$USE_LIBDW], [Set to 1 to use libdw]) dnl ** Have libnuma? dnl -------------------------------------------------------------- +AC_ARG_WITH([libnuma-libraries], + [AC_HELP_STRING([--with-libnuma-libraries=ARG], + [Find libraries for libnuma in ARG [default=system default]]) + ], + [ + LibNumaLibDir="$withval" + LIBNUMA_LDFLAGS="-L$withval" + ]) + +AC_SUBST(LibNumaLibDir) + +AC_ARG_WITH([libnuma-includes], + [AC_HELP_STRING([--with-libnuma-includes=ARG], + [Find includes for libnuma in ARG [default=system default]]) + ], + [ + LibNumaIncludeDir="$withval" + LIBNUMA_CFLAGS="-I$withval" + ]) + +AC_SUBST(LibNumaIncludeDir) + HaveLibNuma=0 AC_ARG_ENABLE(numa, [AC_HELP_STRING([--enable-numa], @@ -1292,6 +1314,11 @@ AC_ARG_ENABLE(numa, runtime system via numactl's libnuma [default=auto]])]) if test "$enable_numa" != "no" ; then + CFLAGS2="$CFLAGS" + CFLAGS="$LIBNUMA_CFLAGS $CFLAGS" + LDFLAGS2="$LDFLAGS" + LDFLAGS="$LIBNUMA_LDFLAGS $LDFLAGS" + AC_CHECK_HEADERS([numa.h numaif.h]) if test "$ac_cv_header_numa_h$ac_cv_header_numaif_h" = "yesyes" ; then @@ -1300,16 +1327,20 @@ if test "$enable_numa" != "no" ; then if test "$enable_numa:$HaveLibNuma" = "yes:0" ; then AC_MSG_ERROR([Cannot find system libnuma (required by --enable-numa)])] fi + + CFLAGS="$CFLAGS2" + LDFLAGS="$LDFLAGS2" fi AC_DEFINE_UNQUOTED([HAVE_LIBNUMA], [$HaveLibNuma], [Define to 1 if you have libnuma]) if test $HaveLibNuma = "1" ; then + AC_SUBST([UseLibNuma],[YES]) AC_SUBST([CabalHaveLibNuma],[True]) else + AC_SUBST([UseLibNuma],[NO]) AC_SUBST([CabalHaveLibNuma],[False]) fi - dnl ** Documentation dnl -------------------------------------------------------------- if test -n "$SPHINXBUILD"; then ===================================== hadrian/cfg/system.config.in ===================================== @@ -172,8 +172,12 @@ ffi-lib-dir = @FFILibDir@ libdw-include-dir = @LibdwIncludeDir@ libdw-lib-dir = @LibdwLibDir@ +libnuma-include-dir = @LibNumaIncludeDir@ +libnuma-lib-dir = @LibNumaLibDir@ + # Optional Dependencies: #======================= with-libdw = @UseLibdw@ +with-libnuma = @UseLibNuma@ have-lib-mingw-ex = @HaveLibMingwEx@ ===================================== hadrian/src/Oracles/Flag.hs ===================================== @@ -21,6 +21,7 @@ data Flag = ArSupportsAtFile | LeadingUnderscore | SolarisBrokenShld | WithLibdw + | WithLibnuma | HaveLibMingwEx | UseSystemFfi @@ -39,6 +40,7 @@ flag f = do LeadingUnderscore -> "leading-underscore" SolarisBrokenShld -> "solaris-broken-shld" WithLibdw -> "with-libdw" + WithLibnuma -> "with-libnuma" HaveLibMingwEx -> "have-lib-mingw-ex" UseSystemFfi -> "use-system-ffi" value <- lookupValueOrError configFile key ===================================== hadrian/src/Oracles/Setting.hs ===================================== @@ -56,6 +56,8 @@ data Setting = BuildArch | IconvLibDir | LibdwIncludeDir | LibdwLibDir + | LibnumaIncludeDir + | LibnumaLibDir | LlvmTarget | ProjectGitCommitId | ProjectName @@ -145,6 +147,8 @@ setting key = lookupValueOrError configFile $ case key of IconvLibDir -> "iconv-lib-dir" LibdwIncludeDir -> "libdw-include-dir" LibdwLibDir -> "libdw-lib-dir" + LibnumaIncludeDir -> "libnuma-include-dir" + LibnumaLibDir -> "libnuma-lib-dir" LlvmTarget -> "llvm-target" ProjectGitCommitId -> "project-git-commit-id" ProjectName -> "project-name" ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -147,18 +147,7 @@ packageArgs = do builder (Cabal Flags) ? arg "in-ghc-tree" ------------------------------ integerGmp ------------------------------ - , package integerGmp ? mconcat - [ builder Cc ? arg includeGmp - - , builder (Cabal Setup) ? mconcat - [ flag GmpInTree ? arg "--configure-option=--with-intree-gmp" - -- Windows is always built with inplace GMP until we have dynamic - -- linking working. - , windowsHost ? arg "--configure-option=--with-intree-gmp" - , flag GmpFrameworkPref ? - arg "--configure-option=--with-gmp-framework-preferred" - , arg ("--configure-option=CFLAGS=" ++ includeGmp) - , arg ("--gcc-options=" ++ includeGmp) ] ] + , gmpPackageArgs ---------------------------------- rts --------------------------------- , package rts ? rtsPackageArgs -- RTS deserves a separate function @@ -181,6 +170,32 @@ packageArgs = do builder (Cabal Flags) ? notStage0 ? intLib == integerSimple ? pure ["+integer-simple", "-bytestring-builder"] ] +gmpPackageArgs :: Args +gmpPackageArgs = do + -- These are only used for non-in-tree builds. + librariesGmp <- getSetting GmpLibDir + includesGmp <- getSetting GmpIncludeDir + + -- Windows is always built with inplace GMP until we have dynamic + -- linking working. + inTreeFlag <- getFlag GmpInTree + let inTree = inTreeFlag || windowsHost + + package integerGmp ? mconcat + [ builder (Cabal Setup) ? mconcat + [ inTree ? arg "--configure-option=--with-intree-gmp" + , flag GmpFrameworkPref ? + arg "--configure-option=--with-gmp-framework-preferred" + + -- Ensure that the integer-gmp package registration includes + -- knowledge of the system gmp's library and include directories. + , notM (flag GmpInTree) ? mconcat + [ if not (null librariesGmp) then arg ("--extra-lib-dirs=" ++ librariesGmp) else mempty + , if not (null includesGmp) then arg ("--extra-include-dirs=" ++ includesGmp) else mempty + ] + ] + ] + -- | RTS-specific command line arguments. rtsPackageArgs :: Args rtsPackageArgs = package rts ? do @@ -208,6 +223,8 @@ rtsPackageArgs = package rts ? do ffiLibraryDir <- getSetting FfiLibDir libdwIncludeDir <- getSetting LibdwIncludeDir libdwLibraryDir <- getSetting LibdwLibDir + libnumaIncludeDir <- getSetting LibnumaIncludeDir + libnumaLibraryDir <- getSetting LibnumaLibDir -- Arguments passed to GHC when compiling C and .cmm sources. let ghcArgs = mconcat @@ -215,6 +232,8 @@ rtsPackageArgs = package rts ? do , arg $ "-I" ++ path , flag WithLibdw ? if not (null libdwIncludeDir) then arg ("-I" ++ libdwIncludeDir) else mempty , flag WithLibdw ? if not (null libdwLibraryDir) then arg ("-L" ++ libdwLibraryDir) else mempty + , flag WithLibnuma ? if not (null libnumaIncludeDir) then arg ("-I" ++ libnumaIncludeDir) else mempty + , flag WithLibnuma ? if not (null libnumaLibraryDir) then arg ("-L" ++ libnumaLibraryDir) else mempty , arg $ "-DRtsWay=\"rts_" ++ show way ++ "\"" -- Set the namespace for the rts fs functions , arg $ "-DFS_NAMESPACE=rts" @@ -324,6 +343,9 @@ rtsPackageArgs = package rts ? do , any (wayUnit Dynamic) rtsWays ? arg "dynamic" , Debug `wayUnit` way ? arg "find-ptr" ] + , builder (Cabal Setup) ? + if not (null libnumaLibraryDir) then arg ("--extra-lib-dirs="++libnumaLibraryDir) else mempty + <> if not (null libnumaIncludeDir) then arg ("--extra-include-dirs="++libnumaIncludeDir) else mempty , builder (Cc FindCDependencies) ? cArgs , builder (Ghc CompileCWithGhc) ? map ("-optc" ++) <$> cArgs , builder Ghc ? ghcArgs ===================================== includes/RtsAPI.h ===================================== @@ -151,6 +151,23 @@ typedef struct GCDetails_ { Time cpu_ns; // The time elapsed during GC itself Time elapsed_ns; + + // + // Concurrent garbage collector + // + + // The CPU time used during the post-mark pause phase of the concurrent + // nonmoving GC. + Time nonmoving_gc_sync_cpu_ns; + // The time elapsed during the post-mark pause phase of the concurrent + // nonmoving GC. + Time nonmoving_gc_sync_elapsed_ns; + // The CPU time used during the post-mark pause phase of the concurrent + // nonmoving GC. + Time nonmoving_gc_cpu_ns; + // The time elapsed during the post-mark pause phase of the concurrent + // nonmoving GC. + Time nonmoving_gc_elapsed_ns; } GCDetails; // @@ -241,6 +258,28 @@ typedef struct _RTSStats { // The number of times a GC thread has iterated it's outer loop across all // parallel GCs uint64_t scav_find_work; + + // ---------------------------------- + // Concurrent garbage collector + + // The CPU time used during the post-mark pause phase of the concurrent + // nonmoving GC. + Time nonmoving_gc_sync_cpu_ns; + // The time elapsed during the post-mark pause phase of the concurrent + // nonmoving GC. + Time nonmoving_gc_sync_elapsed_ns; + // The maximum time elapsed during the post-mark pause phase of the + // concurrent nonmoving GC. + Time nonmoving_gc_sync_max_elapsed_ns; + // The CPU time used during the post-mark pause phase of the concurrent + // nonmoving GC. + Time nonmoving_gc_cpu_ns; + // The time elapsed during the post-mark pause phase of the concurrent + // nonmoving GC. + Time nonmoving_gc_elapsed_ns; + // The maximum time elapsed during the post-mark pause phase of the + // concurrent nonmoving GC. + Time nonmoving_gc_max_elapsed_ns; } RTSStats; void getRTSStats (RTSStats *s); ===================================== includes/rts/Time.h ===================================== @@ -33,6 +33,7 @@ typedef int64_t Time; #define SecondsToTime(t) ((Time)(t) * TIME_RESOLUTION) #define TimeToSeconds(t) ((t) / TIME_RESOLUTION) +#define TimeToSecondsDbl(t) ((double)(t) / TIME_RESOLUTION) // Use instead of SecondsToTime() when we have a floating-point // seconds value, to avoid truncating it. ===================================== libraries/base/GHC/Stats.hsc ===================================== @@ -103,6 +103,25 @@ data RTSStats = RTSStats { -- | Total elapsed time (at the previous GC) , elapsed_ns :: RtsTime + -- | The CPU time used during the post-mark pause phase of the concurrent + -- nonmoving GC. + , nonmoving_gc_sync_cpu_ns :: RtsTime + -- | The time elapsed during the post-mark pause phase of the concurrent + -- nonmoving GC. + , nonmoving_gc_sync_elapsed_ns :: RtsTime + -- | The maximum time elapsed during the post-mark pause phase of the + -- concurrent nonmoving GC. + , nonmoving_gc_sync_max_elapsed_ns :: RtsTime + -- | The CPU time used during the post-mark pause phase of the concurrent + -- nonmoving GC. + , nonmoving_gc_cpu_ns :: RtsTime + -- | The time elapsed during the post-mark pause phase of the concurrent + -- nonmoving GC. + , nonmoving_gc_elapsed_ns :: RtsTime + -- | The maximum time elapsed during the post-mark pause phase of the + -- concurrent nonmoving GC. + , nonmoving_gc_max_elapsed_ns :: RtsTime + -- | Details about the most recent GC , gc :: GCDetails } deriving ( Read -- ^ @since 4.10.0.0 @@ -146,6 +165,13 @@ data GCDetails = GCDetails { , gcdetails_cpu_ns :: RtsTime -- | The time elapsed during GC itself , gcdetails_elapsed_ns :: RtsTime + + -- | The CPU time used during the post-mark pause phase of the concurrent + -- nonmoving GC. + , gcdetails_nonmoving_gc_sync_cpu_ns :: RtsTime + -- | The time elapsed during the post-mark pause phase of the concurrent + -- nonmoving GC. + , gcdetails_nonmoving_gc_sync_elapsed_ns :: RtsTime } deriving ( Read -- ^ @since 4.10.0.0 , Show -- ^ @since 4.10.0.0 ) @@ -192,6 +218,12 @@ getRTSStats = do gc_elapsed_ns <- (# peek RTSStats, gc_elapsed_ns) p cpu_ns <- (# peek RTSStats, cpu_ns) p elapsed_ns <- (# peek RTSStats, elapsed_ns) p + nonmoving_gc_sync_cpu_ns <- (# peek RTSStats, nonmoving_gc_sync_cpu_ns) p + nonmoving_gc_sync_elapsed_ns <- (# peek RTSStats, nonmoving_gc_sync_elapsed_ns) p + nonmoving_gc_sync_max_elapsed_ns <- (# peek RTSStats, nonmoving_gc_sync_max_elapsed_ns) p + nonmoving_gc_cpu_ns <- (# peek RTSStats, nonmoving_gc_cpu_ns) p + nonmoving_gc_elapsed_ns <- (# peek RTSStats, nonmoving_gc_elapsed_ns) p + nonmoving_gc_max_elapsed_ns <- (# peek RTSStats, nonmoving_gc_max_elapsed_ns) p let pgc = (# ptr RTSStats, gc) p gc <- do gcdetails_gen <- (# peek GCDetails, gen) pgc @@ -211,5 +243,7 @@ getRTSStats = do gcdetails_sync_elapsed_ns <- (# peek GCDetails, sync_elapsed_ns) pgc gcdetails_cpu_ns <- (# peek GCDetails, cpu_ns) pgc gcdetails_elapsed_ns <- (# peek GCDetails, elapsed_ns) pgc + gcdetails_nonmoving_gc_sync_cpu_ns <- (# peek GCDetails, nonmoving_gc_sync_cpu_ns) pgc + gcdetails_nonmoving_gc_sync_elapsed_ns <- (# peek GCDetails, nonmoving_gc_sync_elapsed_ns) pgc return GCDetails{..} return RTSStats{..} ===================================== libraries/text ===================================== @@ -1 +1 @@ -Subproject commit c6768a2a07e94b8b26d0f0e53517773de1110ce2 +Subproject commit ebb98f3929360f3abb681dfca4caa8a190f9c5a8 ===================================== rts/GetTime.h ===================================== @@ -13,6 +13,7 @@ void initializeTimer (void); Time getProcessCPUTime (void); +Time getCurrentThreadCPUTime (void); void getProcessTimes (Time *user, Time *elapsed); /* Get the current date and time. ===================================== rts/ProfHeap.c ===================================== @@ -1166,6 +1166,8 @@ heapCensusChain( Census *census, bdescr *bd ) } } +// Time is process CPU time of beginning of current GC and is used as +// the mutator CPU time reported as the census timestamp. void heapCensus (Time t) { uint32_t g, n; @@ -1173,7 +1175,7 @@ void heapCensus (Time t) gen_workspace *ws; census = &censuses[era]; - census->time = mut_user_time_until(t); + census->time = TimeToSecondsDbl(t); census->rtime = TimeToNS(stat_getElapsedTime()); ===================================== rts/Stats.c ===================================== @@ -26,14 +26,14 @@ #include // for memset -#define TimeToSecondsDbl(t) ((double)(t) / TIME_RESOLUTION) - static Time start_init_cpu, start_init_elapsed, end_init_cpu, end_init_elapsed, start_exit_cpu, start_exit_elapsed, start_exit_gc_elapsed, start_exit_gc_cpu, - end_exit_cpu, end_exit_elapsed; + end_exit_cpu, end_exit_elapsed, + start_nonmoving_gc_cpu, start_nonmoving_gc_elapsed, + start_nonmoving_gc_sync_elapsed; #if defined(PROFILING) static Time RP_start_time = 0, RP_tot_time = 0; // retainer prof user time @@ -84,7 +84,7 @@ Time stat_getElapsedTime(void) double mut_user_time_until( Time t ) { - return TimeToSecondsDbl(t - stats.gc_cpu_ns); + return TimeToSecondsDbl(t - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns); // heapCensus() time is included in GC_tot_cpu, so we don't need // to subtract it here. @@ -125,6 +125,10 @@ initStats0(void) end_init_cpu = 0; end_init_elapsed = 0; + start_nonmoving_gc_cpu = 0; + start_nonmoving_gc_elapsed = 0; + start_nonmoving_gc_sync_elapsed = 0; + start_exit_cpu = 0; start_exit_elapsed = 0; start_exit_gc_cpu = 0; @@ -175,6 +179,11 @@ initStats0(void) .gc_elapsed_ns = 0, .cpu_ns = 0, .elapsed_ns = 0, + .nonmoving_gc_cpu_ns = 0, + .nonmoving_gc_elapsed_ns = 0, + .nonmoving_gc_max_elapsed_ns = 0, + .nonmoving_gc_sync_elapsed_ns = 0, + .nonmoving_gc_sync_max_elapsed_ns = 0, .gc = { .gen = 0, .threads = 0, @@ -189,7 +198,10 @@ initStats0(void) .par_balanced_copied_bytes = 0, .sync_elapsed_ns = 0, .cpu_ns = 0, - .elapsed_ns = 0 + .elapsed_ns = 0, + .nonmoving_gc_cpu_ns = 0, + .nonmoving_gc_elapsed_ns = 0, + .nonmoving_gc_sync_elapsed_ns = 0, } }; } @@ -274,6 +286,11 @@ stat_startExit(void) start_exit_gc_cpu = stats.gc_cpu_ns; } +/* ----------------------------------------------------------------------------- + Nonmoving (concurrent) collector statistics + + These two measure the time taken in the concurrent mark & sweep collector. + -------------------------------------------------------------------------- */ void stat_endExit(void) { @@ -286,10 +303,115 @@ stat_startGCSync (gc_thread *gct) gct->gc_sync_start_elapsed = getProcessElapsedTime(); } +void +stat_startNonmovingGc () +{ + start_nonmoving_gc_cpu = getCurrentThreadCPUTime(); + start_nonmoving_gc_elapsed = getProcessCPUTime(); +} + +void +stat_endNonmovingGc () +{ + Time cpu = getCurrentThreadCPUTime(); + Time elapsed = getProcessCPUTime(); + stats.gc.nonmoving_gc_elapsed_ns = elapsed - start_nonmoving_gc_elapsed; + stats.nonmoving_gc_elapsed_ns += stats.gc.nonmoving_gc_elapsed_ns; + + stats.gc.nonmoving_gc_cpu_ns = cpu - start_nonmoving_gc_cpu; + stats.nonmoving_gc_cpu_ns += stats.gc.nonmoving_gc_cpu_ns; + + stats.nonmoving_gc_max_elapsed_ns = + stg_max(stats.gc.nonmoving_gc_elapsed_ns, + stats.nonmoving_gc_max_elapsed_ns); +} + +void +stat_startNonmovingGcSync () +{ + start_nonmoving_gc_sync_elapsed = getProcessElapsedTime(); + traceConcSyncBegin(); +} + +void +stat_endNonmovingGcSync () +{ + Time end_elapsed = getProcessElapsedTime(); + stats.gc.nonmoving_gc_sync_elapsed_ns = end_elapsed - start_nonmoving_gc_sync_elapsed; + stats.nonmoving_gc_sync_elapsed_ns += stats.gc.nonmoving_gc_sync_elapsed_ns; + stats.nonmoving_gc_sync_max_elapsed_ns = + stg_max(stats.gc.nonmoving_gc_sync_elapsed_ns, + stats.nonmoving_gc_sync_max_elapsed_ns); + traceConcSyncEnd(); +} + /* ----------------------------------------------------------------------------- Called at the beginning of each GC -------------------------------------------------------------------------- */ +/* + * Note [Time accounting] + * ~~~~~~~~~~~~~~~~~~~~~~ + * In the "vanilla" configuration (using the standard copying GC) GHC keeps + * track of a two different sinks of elapsed and CPU time: + * + * - time spent synchronising to initiate garbage collection + * - garbage collection (per generation) + * - mutation + * + * When using the (concurrent) non-moving garbage collector (see Note + * [Non-moving garbage collector]) we also track a few more sinks: + * + * - minor GC + * - major GC (namly time spent in the preparatory phase) + * - concurrent mark + * - final synchronization (elapsed only) + * - mutation + * + * To keep track of these CPU times we rely on the system's per-thread CPU time + * clock (exposed via the runtime's getCurrentThreadCPUTime utility). + * + * CPU time spent in the copying garbage collector is tracked in each GC + * worker's gc_thread struct. At the beginning of scavenging each worker + * records its OS thread's CPU time its gc_thread (by stat_startGCWorker). At + * the end of scavenging we again record the CPU time (in stat_endGCworker). + * The differences of these are then summed over by the thread leading the GC + * at the end of collection in stat_endGC. By contrast, the elapsed time is + * recorded only by the leader. + * + * Mutator time is derived from the process's CPU time, subtracting out + * contributions from stop-the-world and concurrent GCs. + * + * Time spent in concurrent marking is recorded by stat_{start,end}NonmovingGc. + * Likewise, elapsed time spent in the final synchronization is recorded by + * stat_{start,end}NonmovingGcSync. + */ + +void +stat_startGCWorker (Capability *cap STG_UNUSED, gc_thread *gct) +{ + bool stats_enabled = + RtsFlags.GcFlags.giveStats != NO_GC_STATS || + rtsConfig.gcDoneHook != NULL; + + if (stats_enabled || RtsFlags.ProfFlags.doHeapProfile) { + gct->gc_start_cpu = getCurrentThreadCPUTime(); + } +} + +void +stat_endGCWorker (Capability *cap STG_UNUSED, gc_thread *gct) +{ + bool stats_enabled = + RtsFlags.GcFlags.giveStats != NO_GC_STATS || + rtsConfig.gcDoneHook != NULL; + + if (stats_enabled || RtsFlags.ProfFlags.doHeapProfile) { + gct->gc_end_cpu = getCurrentThreadCPUTime(); + ASSERT(gct->gc_end_cpu >= gct->gc_start_cpu); + } +} + void stat_startGC (Capability *cap, gc_thread *gct) { @@ -297,7 +419,15 @@ stat_startGC (Capability *cap, gc_thread *gct) debugBelch("\007"); } - getProcessTimes(&gct->gc_start_cpu, &gct->gc_start_elapsed); + bool stats_enabled = + RtsFlags.GcFlags.giveStats != NO_GC_STATS || + rtsConfig.gcDoneHook != NULL; + + if (stats_enabled || RtsFlags.ProfFlags.doHeapProfile) { + gct->gc_start_cpu = getCurrentThreadCPUTime(); + } + + gct->gc_start_elapsed = getProcessElapsedTime(); // Post EVENT_GC_START with the same timestamp as used for stats // (though converted from Time=StgInt64 to EventTimestamp=StgWord64). @@ -320,9 +450,9 @@ stat_startGC (Capability *cap, gc_thread *gct) -------------------------------------------------------------------------- */ void -stat_endGC (Capability *cap, gc_thread *gct, W_ live, W_ copied, W_ slop, - uint32_t gen, uint32_t par_n_threads, W_ par_max_copied, - W_ par_balanced_copied, W_ gc_spin_spin, W_ gc_spin_yield, +stat_endGC (Capability *cap, gc_thread *initiating_gct, W_ live, W_ copied, W_ slop, + uint32_t gen, uint32_t par_n_threads, gc_thread **gc_threads, + W_ par_max_copied, W_ par_balanced_copied, W_ gc_spin_spin, W_ gc_spin_yield, W_ mut_spin_spin, W_ mut_spin_yield, W_ any_work, W_ no_work, W_ scav_find_work) { @@ -364,9 +494,14 @@ stat_endGC (Capability *cap, gc_thread *gct, W_ live, W_ copied, W_ slop, stats.elapsed_ns = current_elapsed - start_init_elapsed; stats.gc.sync_elapsed_ns = - gct->gc_start_elapsed - gct->gc_sync_start_elapsed; - stats.gc.elapsed_ns = current_elapsed - gct->gc_start_elapsed; - stats.gc.cpu_ns = current_cpu - gct->gc_start_cpu; + initiating_gct->gc_start_elapsed - initiating_gct->gc_sync_start_elapsed; + stats.gc.elapsed_ns = current_elapsed - initiating_gct->gc_start_elapsed; + stats.gc.cpu_ns = 0; + for (unsigned int i=0; i < par_n_threads; i++) { + gc_thread *gct = gc_threads[i]; + ASSERT(gct->gc_end_cpu >= gct->gc_start_cpu); + stats.gc.cpu_ns += gct->gc_end_cpu - gct->gc_start_cpu; + } } // ------------------------------------------------- // Update the cumulative stats @@ -473,8 +608,8 @@ stat_endGC (Capability *cap, gc_thread *gct, W_ live, W_ copied, W_ slop, TimeToSecondsDbl(stats.gc.elapsed_ns), TimeToSecondsDbl(stats.cpu_ns), TimeToSecondsDbl(stats.elapsed_ns), - faults - gct->gc_start_faults, - gct->gc_start_faults - GC_end_faults, + faults - initiating_gct->gc_start_faults, + initiating_gct->gc_start_faults - GC_end_faults, gen); GC_end_faults = faults; @@ -700,6 +835,21 @@ static void report_summary(const RTSSummaryStats* sum) TimeToSecondsDbl(gen_stats->avg_pause_ns), TimeToSecondsDbl(gen_stats->max_pause_ns)); } + if (RtsFlags.GcFlags.useNonmoving) { + const int n_major_colls = sum->gc_summary_stats[RtsFlags.GcFlags.generations-1].collections; + statsPrintf(" Gen 1 %5d syncs" + ", %6.3fs %3.4fs %3.4fs\n", + n_major_colls, + TimeToSecondsDbl(stats.nonmoving_gc_sync_elapsed_ns), + TimeToSecondsDbl(stats.nonmoving_gc_sync_elapsed_ns) / n_major_colls, + TimeToSecondsDbl(stats.nonmoving_gc_sync_max_elapsed_ns)); + statsPrintf(" Gen 1 concurrent" + ", %6.3fs %6.3fs %3.4fs %3.4fs\n", + TimeToSecondsDbl(stats.nonmoving_gc_cpu_ns), + TimeToSecondsDbl(stats.nonmoving_gc_elapsed_ns), + TimeToSecondsDbl(stats.nonmoving_gc_elapsed_ns) / n_major_colls, + TimeToSecondsDbl(stats.nonmoving_gc_max_elapsed_ns)); + } statsPrintf("\n"); @@ -736,6 +886,12 @@ static void report_summary(const RTSSummaryStats* sum) statsPrintf(" GC time %7.3fs (%7.3fs elapsed)\n", TimeToSecondsDbl(stats.gc_cpu_ns), TimeToSecondsDbl(stats.gc_elapsed_ns)); + if (RtsFlags.GcFlags.useNonmoving) { + statsPrintf( + " CONC GC time %7.3fs (%7.3fs elapsed)\n", + TimeToSecondsDbl(stats.nonmoving_gc_cpu_ns), + TimeToSecondsDbl(stats.nonmoving_gc_elapsed_ns)); + } #if defined(PROFILING) statsPrintf(" RP time %7.3fs (%7.3fs elapsed)\n", @@ -1094,7 +1250,8 @@ stat_exit (void) stats.mutator_cpu_ns = start_exit_cpu - end_init_cpu - - (stats.gc_cpu_ns - exit_gc_cpu); + - (stats.gc_cpu_ns - exit_gc_cpu) + - stats.nonmoving_gc_cpu_ns; stats.mutator_elapsed_ns = start_exit_elapsed - end_init_elapsed - (stats.gc_elapsed_ns - exit_gc_elapsed); @@ -1504,7 +1661,8 @@ void getRTSStats( RTSStats *s ) s->cpu_ns = current_cpu - end_init_cpu; s->elapsed_ns = current_elapsed - end_init_elapsed; - s->mutator_cpu_ns = current_cpu - end_init_cpu - stats.gc_cpu_ns; + s->mutator_cpu_ns = current_cpu - end_init_cpu - stats.gc_cpu_ns - + stats.nonmoving_gc_cpu_ns; s->mutator_elapsed_ns = current_elapsed - end_init_elapsed - stats.gc_elapsed_ns; } ===================================== rts/Stats.h ===================================== @@ -30,13 +30,21 @@ void stat_endInit(void); void stat_startGCSync(struct gc_thread_ *_gct); void stat_startGC(Capability *cap, struct gc_thread_ *_gct); -void stat_endGC (Capability *cap, struct gc_thread_ *_gct, W_ live, - W_ copied, W_ slop, uint32_t gen, uint32_t n_gc_threads, +void stat_startGCWorker (Capability *cap, struct gc_thread_ *_gct); +void stat_endGCWorker (Capability *cap, struct gc_thread_ *_gct); +void stat_endGC (Capability *cap, struct gc_thread_ *initiating_gct, W_ live, + W_ copied, W_ slop, uint32_t gen, + uint32_t n_gc_threads, struct gc_thread_ **gc_threads, W_ par_max_copied, W_ par_balanced_copied, W_ gc_spin_spin, W_ gc_spin_yield, W_ mut_spin_spin, W_ mut_spin_yield, W_ any_work, W_ no_work, W_ scav_find_work); +void stat_startNonmovingGcSync(void); +void stat_endNonmovingGcSync(void); +void stat_startNonmovingGc (void); +void stat_endNonmovingGc (void); + #if defined(PROFILING) void stat_startRP(void); void stat_endRP(uint32_t, int, double); ===================================== rts/Updates.h ===================================== @@ -50,22 +50,21 @@ \ prim_write_barrier; \ OVERWRITING_CLOSURE(p1); \ - IF_NONMOVING_WRITE_BARRIER_ENABLED { \ - ccall updateRemembSetPushThunk_(BaseReg, p1 "ptr"); \ - } \ - StgInd_indirectee(p1) = p2; \ - prim_write_barrier; \ - SET_INFO(p1, stg_BLACKHOLE_info); \ - LDV_RECORD_CREATE(p1); \ bd = Bdescr(p1); \ if (bdescr_gen_no(bd) != 0 :: bits16) { \ + IF_NONMOVING_WRITE_BARRIER_ENABLED { \ + ccall updateRemembSetPushThunk_(BaseReg, p1 "ptr"); \ + } \ recordMutableCap(p1, TO_W_(bdescr_gen_no(bd))); \ TICK_UPD_OLD_IND(); \ - and_then; \ } else { \ TICK_UPD_NEW_IND(); \ - and_then; \ - } + } \ + StgInd_indirectee(p1) = p2; \ + prim_write_barrier; \ + SET_INFO(p1, stg_BLACKHOLE_info); \ + LDV_RECORD_CREATE(p1); \ + and_then; #else /* !CMINUSMINUS */ @@ -73,28 +72,26 @@ INLINE_HEADER void updateWithIndirection (Capability *cap, StgClosure *p1, StgClosure *p2) { - bdescr *bd; - ASSERT( (P_)p1 != (P_)p2 ); /* not necessarily true: ASSERT( !closure_IND(p1) ); */ /* occurs in RaiseAsync.c:raiseAsync() */ /* See Note [Heap memory barriers] in SMP.h */ write_barrier(); - OVERWRITING_CLOSURE(p1); - IF_NONMOVING_WRITE_BARRIER_ENABLED { - updateRemembSetPushThunk(cap, (StgThunk*)p1); - } - ((StgInd *)p1)->indirectee = p2; - write_barrier(); - SET_INFO(p1, &stg_BLACKHOLE_info); - LDV_RECORD_CREATE(p1); - bd = Bdescr((StgPtr)p1); + bdescr *bd = Bdescr((StgPtr)p1); if (bd->gen_no != 0) { + IF_NONMOVING_WRITE_BARRIER_ENABLED { + updateRemembSetPushThunk(cap, (StgThunk*)p1); + } recordMutableCap(p1, cap, bd->gen_no); TICK_UPD_OLD_IND(); } else { TICK_UPD_NEW_IND(); } + OVERWRITING_CLOSURE(p1); + ((StgInd *)p1)->indirectee = p2; + write_barrier(); + SET_INFO(p1, &stg_BLACKHOLE_info); + LDV_RECORD_CREATE(p1); } #endif /* CMINUSMINUS */ ===================================== rts/posix/GetTime.c ===================================== @@ -25,18 +25,25 @@ #error No implementation for getProcessCPUTime() available. #endif +#if defined(darwin_HOST_OS) +#include +#include +#include +#include +#endif + #if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_GETRUSAGE) // we'll implement getProcessCPUTime() and getProcessElapsedTime() // separately, using getrusage() and gettimeofday() respectively -#if !defined(HAVE_CLOCK_GETTIME) && defined(darwin_HOST_OS) +#if defined(darwin_HOST_OS) static uint64_t timer_scaling_factor_numer = 0; static uint64_t timer_scaling_factor_denom = 0; #endif void initializeTimer() { -#if !defined(HAVE_CLOCK_GETTIME) && defined(darwin_HOST_OS) +#if defined(darwin_HOST_OS) mach_timebase_info_data_t info; (void) mach_timebase_info(&info); timer_scaling_factor_numer = (uint64_t)info.numer; @@ -44,11 +51,64 @@ void initializeTimer() #endif } +#if defined(HAVE_CLOCK_GETTIME) +static Time getClockTime(clockid_t clock) +{ + struct timespec ts; + int res = clock_gettime(clock, &ts); + if (res == 0) { + return SecondsToTime(ts.tv_sec) + NSToTime(ts.tv_nsec); + } else { + sysErrorBelch("clock_gettime"); + stg_exit(EXIT_FAILURE); + } +} +#endif + +Time getCurrentThreadCPUTime(void) +{ + // N.B. Since macOS Catalina, Darwin supports clock_gettime but does not + // support clock_getcpuclockid. Hence we prefer to use the Darwin-specific + // path on Darwin, even if clock_gettime is available. +#if defined(darwin_HOST_OS) + mach_port_t port = pthread_mach_thread_np(osThreadId()); + thread_basic_info_data_t info = { 0 }; + mach_msg_type_number_t info_count = THREAD_BASIC_INFO_COUNT; + kern_return_t kern_err = thread_info(mach_thread_self(), THREAD_BASIC_INFO, + (thread_info_t) &info, &info_count); + if (kern_err == KERN_SUCCESS) { + return SecondsToTime(info.user_time.seconds) + USToTime(info.user_time.microseconds); + } else { + sysErrorBelch("getThreadCPUTime"); + stg_exit(EXIT_FAILURE); + } +#elif defined(HAVE_CLOCK_GETTIME) && \ + defined(CLOCK_PROCESS_CPUTIME_ID) && \ + defined(HAVE_SYSCONF) + static bool have_checked_usability = false; + if (!have_checked_usability) { + // The Linux clock_getres(2) manpage claims that some early versions of + // Linux will return values which are uninterpretable in the presence + // of migration across CPUs. They claim that clock_getcpuclockid(0) + // will return ENOENT in this case. Check this. + clockid_t clkid; + if (clock_getcpuclockid(0, &clkid)) { + sysErrorBelch("getCurrentThreadCPUTime: no supported"); + stg_exit(EXIT_FAILURE); + } + have_checked_usability = true; + } + return getClockTime(CLOCK_THREAD_CPUTIME_ID); +#else +#error I know of no means to find the CPU time of current thread on this platform. +#endif +} + Time getProcessCPUTime(void) { #if !defined(BE_CONSERVATIVE) && \ defined(HAVE_CLOCK_GETTIME) && \ - defined(_SC_CPUTIME) && \ + defined(_SC_CPUTIME) && \ defined(CLOCK_PROCESS_CPUTIME_ID) && \ defined(HAVE_SYSCONF) static int checked_sysconf = 0; @@ -59,15 +119,7 @@ Time getProcessCPUTime(void) checked_sysconf = 1; } if (sysconf_result != -1) { - struct timespec ts; - int res; - res = clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts); - if (res == 0) { - return SecondsToTime(ts.tv_sec) + NSToTime(ts.tv_nsec); - } else { - sysErrorBelch("clock_gettime"); - stg_exit(EXIT_FAILURE); - } + return getClockTime(CLOCK_PROCESS_CPUTIME_ID); } #endif @@ -82,16 +134,7 @@ Time getProcessCPUTime(void) StgWord64 getMonotonicNSec(void) { #if defined(HAVE_CLOCK_GETTIME) - struct timespec ts; - int res; - - res = clock_gettime(CLOCK_ID, &ts); - if (res != 0) { - sysErrorBelch("clock_gettime"); - stg_exit(EXIT_FAILURE); - } - return (StgWord64)ts.tv_sec * 1000000000 + - (StgWord64)ts.tv_nsec; + return getClockTime(CLOCK_ID); #elif defined(darwin_HOST_OS) @@ -102,7 +145,9 @@ StgWord64 getMonotonicNSec(void) struct timeval tv; - gettimeofday(&tv, (struct timezone *) NULL); + if (gettimeofday(&tv, (struct timezone *) NULL) != 0) { + debugBlech("getMonotonicNSec: gettimeofday failed: %s", strerror(errno)); + }; return (StgWord64)tv.tv_sec * 1000000000 + (StgWord64)tv.tv_usec * 1000; ===================================== rts/sm/BlockAlloc.c ===================================== @@ -233,6 +233,12 @@ initGroup(bdescr *head) last->blocks = 0; last->link = head; } + +#if defined(DEBUG) + for (uint32_t i=0; i < head->blocks; i++) { + head[i].flags = 0; + } +#endif } #if SIZEOF_VOID_P == SIZEOF_LONG @@ -792,6 +798,12 @@ freeGroup(bdescr *p) ASSERT(p->free != (P_)-1); +#if defined(DEBUG) + for (uint32_t i=0; i < p->blocks; i++) { + p[i].flags = 0; + } +#endif + node = p->node; p->free = (void *)-1; /* indicates that this block is free */ ===================================== rts/sm/Evac.c ===================================== @@ -80,16 +80,15 @@ alloc_for_copy (uint32_t size, uint32_t gen_no) if (gen_no < gct->evac_gen_no) { if (gct->eager_promotion) { gen_no = gct->evac_gen_no; + } else if (RTS_UNLIKELY(RtsFlags.GcFlags.useNonmoving) && deadlock_detect_gc) { + /* See Note [Deadlock detection under nonmoving collector]. */ + gen_no = oldest_gen->no; } else { gct->failed_to_evac = true; } } if (RTS_UNLIKELY(RtsFlags.GcFlags.useNonmoving)) { - /* See Note [Deadlock detection under nonmoving collector]. */ - if (deadlock_detect_gc) - gen_no = oldest_gen->no; - if (gen_no == oldest_gen->no) { gct->copied += size; to = nonmovingAllocate(gct->cap, size); ===================================== rts/sm/GC.c ===================================== @@ -209,6 +209,14 @@ GarbageCollect (uint32_t collect_gen, gc_thread *saved_gct; #endif uint32_t g, n; + // The time we should report our heap census as occurring at, if necessary. + Time mut_time = 0; + + if (do_heap_census) { + RTSStats stats; + getRTSStats(&stats); + mut_time = stats.mutator_cpu_ns; + } // necessary if we stole a callee-saves register for gct: #if defined(THREADED_RTS) @@ -730,11 +738,13 @@ GarbageCollect (uint32_t collect_gen, } } // for all generations - // Flush the update remembered set. See Note [Eager update remembered set + // Flush the update remembered sets. See Note [Eager update remembered set // flushing] in NonMovingMark.c if (RtsFlags.GcFlags.useNonmoving) { RELEASE_SM_LOCK; - nonmovingAddUpdRemSetBlocks(&gct->cap->upd_rem_set.queue); + for (n = 0; n < n_capabilities; n++) { + nonmovingAddUpdRemSetBlocks(&capabilities[n]->upd_rem_set.queue); + } ACQUIRE_SM_LOCK; } @@ -846,7 +856,7 @@ GarbageCollect (uint32_t collect_gen, if (do_heap_census) { debugTrace(DEBUG_sched, "performing heap census"); RELEASE_SM_LOCK; - heapCensus(gct->gc_start_cpu); + heapCensus(mut_time); ACQUIRE_SM_LOCK; } @@ -927,9 +937,11 @@ GarbageCollect (uint32_t collect_gen, #endif // ok, GC over: tell the stats department what happened. + stat_endGCWorker(cap, gct); stat_endGC(cap, gct, live_words, copied, live_blocks * BLOCK_SIZE_W - live_words /* slop */, - N, n_gc_threads, par_max_copied, par_balanced_copied, + N, n_gc_threads, gc_threads, + par_max_copied, par_balanced_copied, gc_spin_spin, gc_spin_yield, mut_spin_spin, mut_spin_yield, any_work, no_work, scav_find_work); @@ -1209,6 +1221,7 @@ gcWorkerThread (Capability *cap) SET_GCT(gc_threads[cap->no]); gct->id = osThreadId(); + stat_startGCWorker (cap, gct); // Wait until we're told to wake up RELEASE_SPIN_LOCK(&gct->mut_spin); @@ -1247,6 +1260,7 @@ gcWorkerThread (Capability *cap) gct->wakeup = GC_THREAD_WAITING_TO_CONTINUE; debugTrace(DEBUG_gc, "GC thread %d waiting to continue...", gct->thread_index); + stat_endGCWorker (cap, gct); ACQUIRE_SPIN_LOCK(&gct->mut_spin); debugTrace(DEBUG_gc, "GC thread %d on my way...", gct->thread_index); ===================================== rts/sm/GCThread.h ===================================== @@ -185,9 +185,11 @@ typedef struct gc_thread_ { W_ no_work; W_ scav_find_work; - Time gc_start_cpu; // process CPU time - Time gc_sync_start_elapsed; // start of GC sync - Time gc_start_elapsed; // process elapsed time + Time gc_start_cpu; // thread CPU time + Time gc_end_cpu; // thread CPU time + Time gc_sync_start_elapsed; // start of GC sync + Time gc_start_elapsed; // process elapsed time + Time gc_end_elapsed; // process elapsed time W_ gc_start_faults; // ------------------- ===================================== rts/sm/NonMoving.c ===================================== @@ -18,6 +18,7 @@ #include "GCThread.h" #include "GCTDecl.h" #include "Schedule.h" +#include "Stats.h" #include "NonMoving.h" #include "NonMovingMark.h" @@ -227,6 +228,10 @@ Mutex concurrent_coll_finished_lock; * - Note [Static objects under the nonmoving collector] (Storage.c) describes * treatment of static objects. * + * - Note [Dirty flags in the non-moving collector] (NonMoving.c) describes + * how we use the DIRTY flags associated with MUT_VARs and TVARs to improve + * barrier efficiency. + * * * Note [Concurrent non-moving collection] * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -368,6 +373,7 @@ Mutex concurrent_coll_finished_lock; * approximate due to concurrent collection and ultimately seems more costly * than the problem demands. * + * * Note [Spark management under the nonmoving collector] * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Every GC, both minor and major, prunes the spark queue (using @@ -386,6 +392,88 @@ Mutex concurrent_coll_finished_lock; * BF_EVACUATED flag won't be set on the nursery blocks) and will consequently * only prune dead sparks living in the non-moving heap. * + * + * Note [Dirty flags in the non-moving collector] + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Some mutable object types (e.g. MUT_VARs, TVARs) have a one-bit dirty flag + * encoded in their info table pointer. The moving collector's uses this flag + * to minimize redundant mut_list entries. The flag is preserves the following + * simple invariant: + * + * An object being marked as dirty implies that the object is on mut_list. + * + * This allows a nice optimisation in the write barrier (e.g. dirty_MUT_VAR): + * if we write to an already-dirty object there is no need to + * push it to the mut_list as we know it's already there. + * + * During GC (scavenging) we will then keep track of whether all of the + * object's reference have been promoted. If so we can mark the object as clean. + * If not then we re-add it to mut_list and mark it as dirty. + * + * In the non-moving collector we use the same dirty flag to implement a + * related optimisation on the non-moving write barrier: Specifically, the + * snapshot invariant only requires that the non-moving write barrier applies + * to the *first* mutation to an object after collection begins. To achieve this, + * we impose the following invariant: + * + * An object being marked as dirty implies that all of its fields are on + * the mark queue (or, equivalently, update remembered set). + * + * With this guarantee we can safely make the the write barriers dirty objects + * no-ops. We perform this optimisation for the following object types: + * + * - MVAR + * - TVAR + * - MUT_VAR + * + * However, maintaining this invariant requires great care. For instance, + * consider the case of an MVar (which has two pointer fields) before + * preparatory collection: + * + * Non-moving heap ┊ Moving heap + * gen 1 ┊ gen 0 + * ──────────────────────┼──────────────────────────────── + * ┊ + * MVAR A ────────────────→ X + * (dirty) ───────────╮ + * ┊ ╰────→ Y + * ┊ │ + * ┊ │ + * ╭───────────────────────╯ + * │ ┊ + * ↓ ┊ + * Z ┊ + * ┊ + * + * During the preparatory collection we promote Y to the nonmoving heap but + * fail to promote X. Since the failed_to_evac field is conservative (being set + * if *any* of the fields are not promoted), this gives us: + * + * Non-moving heap ┊ Moving heap + * gen 1 ┊ gen 0 + * ──────────────────────┼──────────────────────────────── + * ┊ + * MVAR A ────────────────→ X + * (dirty) ┊ + * │ ┊ + * │ ┊ + * ↓ ┊ + * Y ┊ + * │ ┊ + * │ ┊ + * ↓ ┊ + * Z ┊ + * ┊ + * + * This is bad. When we resume mutation a mutator may mutate MVAR A; since it's + * already dirty we would fail to add Y to the update remembered set, breaking the + * snapshot invariant and potentially losing track of the liveness of Z. + * + * To avoid this nonmovingScavengeOne we eagerly pushes the values of the + * fields of all objects which it fails to evacuate (e.g. MVAR A) to the update + * remembered set during the preparatory GC. This allows us to safely skip the + * non-moving write barrier without jeopardizing the snapshot invariant. + * */ memcount nonmoving_live_words = 0; @@ -401,10 +489,10 @@ static void nonmovingInitSegment(struct NonmovingSegment *seg, uint8_t log_block seg->link = NULL; seg->todo_link = NULL; seg->next_free = 0; - nonmovingClearBitmap(seg); bd->nonmoving_segment.log_block_size = log_block_size; bd->nonmoving_segment.next_free_snap = 0; bd->u.scan = nonmovingSegmentGetBlock(seg, 0); + nonmovingClearBitmap(seg); } // Add a segment to the free list. @@ -951,6 +1039,7 @@ static void nonmovingMark_(MarkQueue *mark_queue, StgWeak **dead_weaks, StgTSO * { ACQUIRE_LOCK(&nonmoving_collection_mutex); debugTrace(DEBUG_nonmoving_gc, "Starting mark..."); + stat_startNonmovingGc(); // Walk the list of filled segments that we collected during preparation, // updated their snapshot pointers and move them to the sweep list. @@ -1132,6 +1221,7 @@ finish: // We are done... mark_thread = 0; + stat_endNonmovingGc(); // Signal that the concurrent collection is finished, allowing the next // non-moving collection to proceed ===================================== rts/sm/NonMovingMark.c ===================================== @@ -21,11 +21,13 @@ #include "Printer.h" #include "Schedule.h" #include "Weak.h" +#include "Stats.h" #include "STM.h" #include "MarkWeak.h" #include "sm/Storage.h" #include "CNF.h" +static bool check_in_nonmoving_heap(StgClosure *p); static void mark_closure (MarkQueue *queue, const StgClosure *p, StgClosure **origin); static void mark_tso (MarkQueue *queue, StgTSO *tso); static void mark_stack (MarkQueue *queue, StgStack *stack); @@ -316,6 +318,7 @@ void nonmovingBeginFlush(Task *task) debugTrace(DEBUG_nonmoving_gc, "Starting update remembered set flush..."); traceConcSyncBegin(); upd_rem_set_flush_count = 0; + stat_startNonmovingGcSync(); stopAllCapabilitiesWith(NULL, task, SYNC_FLUSH_UPD_REM_SET); // XXX: We may have been given a capability via releaseCapability (i.e. a @@ -407,6 +410,7 @@ void nonmovingFinishFlush(Task *task) debugTrace(DEBUG_nonmoving_gc, "Finished update remembered set flush..."); traceConcSyncEnd(); + stat_endNonmovingGcSync(); releaseAllCapabilities(n_capabilities, NULL, task); } #endif @@ -447,10 +451,17 @@ push (MarkQueue *q, const MarkQueueEnt *ent) void markQueuePushClosureGC (MarkQueue *q, StgClosure *p) { + if (!check_in_nonmoving_heap(p)) { + return; + } + /* We should not make it here if we are doing a deadlock detect GC. * See Note [Deadlock detection under nonmoving collector]. + * This is actually no longer true due to call in nonmovingScavengeOne + * introduced due to Note [Dirty flags in the non-moving collector] + * (see NonMoving.c). */ - ASSERT(!deadlock_detect_gc); + //ASSERT(!deadlock_detect_gc); // Are we at the end of the block? if (q->top->head == MARK_QUEUE_BLOCK_ENTRIES) { ===================================== rts/sm/NonMovingScav.c ===================================== @@ -31,6 +31,11 @@ nonmovingScavengeOne (StgClosure *q) gct->eager_promotion = saved_eager_promotion; if (gct->failed_to_evac) { mvar->header.info = &stg_MVAR_DIRTY_info; + + // Note [Dirty flags in the non-moving collector] in NonMoving.c + markQueuePushClosureGC(&gct->cap->upd_rem_set.queue, (StgClosure *) mvar->head); + markQueuePushClosureGC(&gct->cap->upd_rem_set.queue, (StgClosure *) mvar->tail); + markQueuePushClosureGC(&gct->cap->upd_rem_set.queue, (StgClosure *) mvar->value); } else { mvar->header.info = &stg_MVAR_CLEAN_info; } @@ -46,6 +51,10 @@ nonmovingScavengeOne (StgClosure *q) gct->eager_promotion = saved_eager_promotion; if (gct->failed_to_evac) { tvar->header.info = &stg_TVAR_DIRTY_info; + + // Note [Dirty flags in the non-moving collector] in NonMoving.c + markQueuePushClosureGC(&gct->cap->upd_rem_set.queue, (StgClosure *) tvar->current_value); + markQueuePushClosureGC(&gct->cap->upd_rem_set.queue, (StgClosure *) tvar->first_watch_queue_entry); } else { tvar->header.info = &stg_TVAR_CLEAN_info; } @@ -160,16 +169,21 @@ nonmovingScavengeOne (StgClosure *q) } case MUT_VAR_CLEAN: - case MUT_VAR_DIRTY: + case MUT_VAR_DIRTY: { + StgMutVar *mv = (StgMutVar *) p; gct->eager_promotion = false; - evacuate(&((StgMutVar *)p)->var); + evacuate(&mv->var); gct->eager_promotion = saved_eager_promotion; if (gct->failed_to_evac) { ((StgClosure *)q)->header.info = &stg_MUT_VAR_DIRTY_info; + + // Note [Dirty flags in the non-moving collector] in NonMoving.c + markQueuePushClosureGC(&gct->cap->upd_rem_set.queue, (StgClosure *) mv->var); } else { ((StgClosure *)q)->header.info = &stg_MUT_VAR_CLEAN_info; } break; + } case BLOCKING_QUEUE: { ===================================== rts/sm/NonMovingSweep.c ===================================== @@ -30,12 +30,11 @@ enum SweepResult { GNUC_ATTR_HOT static enum SweepResult nonmovingSweepSegment(struct NonmovingSegment *seg) { + const nonmoving_block_idx blk_cnt = nonmovingSegmentBlockCount(seg); bool found_free = false; bool found_live = false; - for (nonmoving_block_idx i = 0; - i < nonmovingSegmentBlockCount(seg); - ++i) + for (nonmoving_block_idx i = 0; i < blk_cnt; ++i) { if (seg->bitmap[i] == nonmovingMarkEpoch) { found_live = true; ===================================== rts/sm/Storage.c ===================================== @@ -1206,6 +1206,7 @@ dirty_MUT_VAR(StgRegTable *reg, StgMutVar *mvar, StgClosure *old) mvar->header.info = &stg_MUT_VAR_DIRTY_info; recordClosureMutated(cap, (StgClosure *) mvar); IF_NONMOVING_WRITE_BARRIER_ENABLED { + // See Note [Dirty flags in the non-moving collector] in NonMoving.c updateRemembSetPushClosure_(reg, old); } } @@ -1228,6 +1229,7 @@ dirty_TVAR(Capability *cap, StgTVar *p, p->header.info = &stg_TVAR_DIRTY_info; recordClosureMutated(cap,(StgClosure*)p); IF_NONMOVING_WRITE_BARRIER_ENABLED { + // See Note [Dirty flags in the non-moving collector] in NonMoving.c updateRemembSetPushClosure(cap, old); } } @@ -1309,6 +1311,7 @@ update_MVAR(StgRegTable *reg, StgClosure *p, StgClosure *old_val) { Capability *cap = regTableToCapability(reg); IF_NONMOVING_WRITE_BARRIER_ENABLED { + // See Note [Dirty flags in the non-moving collector] in NonMoving.c StgMVar *mvar = (StgMVar *) p; updateRemembSetPushClosure(cap, old_val); updateRemembSetPushClosure(cap, (StgClosure *) mvar->head); ===================================== rts/win32/GetTime.c ===================================== @@ -34,6 +34,20 @@ getProcessTimes(Time *user, Time *elapsed) *elapsed = getProcessElapsedTime(); } +Time +getCurrentThreadCPUTime(void) +{ + FILETIME creationTime, exitTime, userTime, kernelTime = {0,0}; + + if (!GetThreadTimes(GetCurrentThread(), &creationTime, + &exitTime, &kernelTime, &userTime)) { + sysErrorBelch("getCurrentThreadCPUTime: Win32 error %lu", GetLastError()); + return 0; + } + + return fileTimeToRtsTime(userTime); +} + Time getProcessCPUTime(void) { View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8ba7aacd3fc882715100788a8ac8f06b6cf914dd...b9df14c49bd6b70e403559e9a70669cc50d7e2f8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8ba7aacd3fc882715100788a8ac8f06b6cf914dd...b9df14c49bd6b70e403559e9a70669cc50d7e2f8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 16:18:39 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Thu, 14 May 2020 12:18:39 -0400 Subject: [Git][ghc/ghc][wip/dmdanal-precise-exn-simpl] DmdAnal: Improve handling of precise exceptions Message-ID: <5ebd6f5fde5cc_61679b2e0f4112890be@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/dmdanal-precise-exn-simpl at Glasgow Haskell Compiler / GHC Commits: 9df74a90 by Sebastian Graf at 2020-05-14T18:18:33+02:00 DmdAnal: Improve handling of precise exceptions This patch does two things: Fix possible unsoundness in what was called the "IO hack" and implement part 2.1 of the "fixing precise exceptions" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions, which, in combination with !2956, supersedes !3014 and !2525. **IO hack** The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is called `exprMayThrowPreciseException` now. I came up with two testcases exemplifying possible unsoundness (if twisted enough) in the old approach: - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. - `T13380e`: Demonstrating unsoundness of the "IO hack" when we have Nested CPR. Not currently relevant, as we don't have Nested CPR yet. - `T13380f`: Demonstrating unsoundness of the "IO hack" for safe FFI calls. Basically, the IO hack assumed that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future, see `T13380e`. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380{d,e}` (and will hopefully be robust to Nested CPR). **Precise exceptions** In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that was terribly unprincipled. That unprincipledness resulted in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception (and the existing IO hack doesn't detect that) Fixing both issues in !3014 turned out to be too complicated and had the potential to regress in the future. Hence we decided to only fix `T13380b` and augment the `Divergence` lattice with a new middle-layer element, `ExnOrDiv`, which means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. See the wiki page on Step 2.1 for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#dead-code-elimination-for-raiseio-with-isdeadenddiv-introducing-exnordiv-step-21 - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/LiberateCase.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/ForeignCall.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Make.hs - testsuite/tests/stranal/should_compile/T10482a.stderr - testsuite/tests/stranal/should_compile/T10694.stderr - + testsuite/tests/stranal/should_compile/T13380b.hs - testsuite/tests/stranal/should_compile/all.T - + testsuite/tests/stranal/should_run/T13380d.hs - + testsuite/tests/stranal/should_run/T13380d.stderr - + testsuite/tests/stranal/should_run/T13380e.hs - + testsuite/tests/stranal/should_run/T13380e.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9df74a90157fcb30cc83f70426fa5f22e434e4d1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9df74a90157fcb30cc83f70426fa5f22e434e4d1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 16:26:00 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 14 May 2020 12:26:00 -0400 Subject: [Git][ghc/ghc][master] IdInfo: Add reference to bitfield-packing ticket Message-ID: <5ebd7118b0528_6167c96b4bc11294542@gitlab.haskell.org.mail> Ben Gamari pushed to branch master at Glasgow Haskell Compiler / GHC Commits: e9c0110c by Ben Gamari at 2020-05-14T12:25:53-04:00 IdInfo: Add reference to bitfield-packing ticket - - - - - 1 changed file: - compiler/GHC/Types/Id/Info.hs Changes: ===================================== compiler/GHC/Types/Id/Info.hs ===================================== @@ -267,7 +267,7 @@ data IdInfo -- ^ Bitfield packs CafInfo, OneShotInfo, arity info, LevityInfo, and -- call arity info in one 64-bit word. Packing these fields reduces size -- of `IdInfo` from 12 words to 7 words and reduces residency by almost - -- 4% in some programs. + -- 4% in some programs. See #17497 and associated MR. -- -- See documentation of the getters for what these packed fields mean. } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e9c0110ce9e753360d7e6523114109b7616f2f08 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e9c0110ce9e753360d7e6523114109b7616f2f08 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 16:30:13 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 14 May 2020 12:30:13 -0400 Subject: [Git][ghc/ghc][wip/dwarf-bindists] 203 commits: Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie Message-ID: <5ebd721557ec9_6167122db45c112947bf@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/dwarf-bindists at Glasgow Haskell Compiler / GHC Commits: ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.0.0 This requires bumping the `exceptions` and `text` submodules to bring in commits that bump their respective upper version bounds on `template-haskell`. Fixes #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - ffd7eef2 by Takenobu Tani at 2020-04-22T23:09:50-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - e8a5d81b by Jonathan DK Gibbons at 2020-04-22T23:10:28-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - dcb7fe5a by John Ericson at 2020-04-22T23:10:28-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - cde23cd4 by John Ericson at 2020-04-22T23:10:28-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - 72cb6bcc by John Ericson at 2020-04-22T23:10:28-04:00 Generalize type of `matchCanFail` - - - - - 401f7bb3 by John Ericson at 2020-04-22T23:10:28-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 6c9fae23 by Alexis King at 2020-04-22T23:11:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 48b8951e by Roland Senn at 2020-04-22T23:11:51-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 34a45ee6 by Peter Trommler at 2020-04-22T23:12:27-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - ffde2348 by Simon Peyton Jones at 2020-04-22T23:13:06-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 6f84aca3 by Ben Gamari at 2020-04-22T23:13:43-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - c29f0fa6 by Andreas Klebinger at 2020-04-22T23:14:21-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 4b4a8b60 by Ben Gamari at 2020-04-22T23:14:57-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 831b6642 by Moritz Angermann at 2020-04-22T23:15:33-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - c409961a by Ryan Scott at 2020-04-22T23:16:12-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 125aa2b8 by Ömer Sinan Ağacan at 2020-04-22T23:16:51-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - 8ea37b01 by Sylvain Henry at 2020-04-22T23:17:34-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - cd8409c2 by Ryan Scott at 2020-04-23T11:39:24-04:00 Create di_scoped_tvs for associated data family instances properly See `Note [Associated data family instances and di_scoped_tvs]` in `GHC.Tc.TyCl.Instance`, which explains all of the moving parts. Fixes #18055. - - - - - 339e8ece by Ben Gamari at 2020-04-23T11:40:02-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 5946c85a by Ben Gamari at 2020-04-23T11:40:38-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - c42754d5 by John Ericson at 2020-04-23T18:32:43-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 72da0c29 by mniip at 2020-04-23T18:33:21-04:00 Add :doc to GHC.Prim - - - - - 2c23e2e3 by mniip at 2020-04-23T18:33:21-04:00 Include docs for non-primop entries in primops.txt as well - - - - - 0ac29c88 by mniip at 2020-04-23T18:33:21-04:00 GHC.Prim docs: note and test - - - - - b0fbfc75 by John Ericson at 2020-04-24T12:07:14-04:00 Switch order on `GhcMake.IsBoot` In !1798 we were requested to replace many `Bool`s with this data type. But those bools had `False` meaning `NotBoot`, so the `Ord` instance would be flipped if we use this data-type as-is. Since the planned formally-`Bool` occurrences vastly outnumber the current occurrences, we figured it would be better to conform the `Ord` instance to how the `Bool` is used now, fixing any issues, rather than fix them currently with the bigger refactor later in !1798. That way, !1798 can be a "pure" refactor with no behavioral changes. - - - - - af332442 by Sylvain Henry at 2020-04-26T13:55:14-04:00 Modules: Utils and Data (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - cd4434c8 by Sylvain Henry at 2020-04-26T13:55:16-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 22bf5c73 by Ömer Sinan Ağacan at 2020-04-26T13:55:22-04:00 Tweak includes in non-moving GC headers We don't use hash tables in non-moving GC so remove the includes. This breaks Compact.c as existing includes no longer include Hash.h, so include Hash.h explicitly in Compact.c. - - - - - 99823ed2 by Sylvain Henry at 2020-04-27T20:24:46-04:00 TH: fix Show/Eq/Ord instances for Bytes (#16457) We shouldn't compare pointer values but the actual bytes. - - - - - c62271a2 by Alp Mestanogullari at 2020-04-27T20:25:33-04:00 hadrian: always capture both stdout and stderr when running a builder fails The idea being that when a builder('s command) fails, we quite likely want to have all the information available to figure out why. Depending on the builder _and_ the particular problem, the useful bits of information can be printed on stdout or stderr. We accomplish this by defining a simple wrapper for Shake's `cmd` function, that just _always_ captures both streams in case the command returns a non-zero exit code, and by using this wrapper everywhere in `hadrian/src/Builder.hs`. Fixes #18089. - - - - - 4b9764db by Ryan Scott at 2020-04-28T15:40:04-04:00 Define a Quote IO instance Fixes #18103. - - - - - 518a63d4 by Ryan Scott at 2020-04-28T15:40:42-04:00 Make boxed 1-tuples have known keys Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. - - - - - 2cfc4ab9 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Document backpack fields in DynFlags - - - - - 10a2ba90 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 69562e34 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 9e2c8e0e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - ea717aa4 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 10d15f1e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 8bfb0219 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - 71484b09 by Alexis King at 2020-04-30T01:57:35-04:00 Allow block arguments in arrow control operators Arrow control operators have their own entries in the grammar, so they did not cooperate with BlockArguments. This was just a minor oversight, so this patch adjusts the grammar to add the desired behavior. fixes #18050 - - - - - a48cd2a0 by Alexis King at 2020-04-30T01:57:35-04:00 Allow LambdaCase to be used as a command in proc notation - - - - - f4d3773c by Alexis King at 2020-04-30T01:57:35-04:00 Document BlockArguments/LambdaCase support in arrow notation - - - - - 5bdfdd13 by Simon Peyton Jones at 2020-04-30T01:58:15-04:00 Add tests for #17873 - - - - - 19b701c2 by Simon Peyton Jones at 2020-04-30T07:30:13-04:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - 014ef4a3 by Matthew Pickering at 2020-04-30T07:30:50-04:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 2aa67611 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - 54dad3cf by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - 99ff8145 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 05b0a9fd by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 Remove OneShotInfo field of LFReEntrant, document OneShotInfo The field is only used in withNewTickyCounterFun and it's easier to directly pass a parameter for one-shot info to withNewTickyCounterFun instead of passing it via LFReEntrant. This also makes !2842 simpler. Other changes: - New Note (by SPJ) [OneShotInfo overview] added. - Arity argument of thunkCode removed as it's always 0. - - - - - a43620c6 by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 GHC.StgToCmm.Ticky: remove a few unused stuff - - - - - 780de9e1 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Use platform in Iface Binary - - - - - f8386c7b by Sylvain Henry at 2020-05-01T10:37:39-04:00 Refactor PprDebug handling If `-dppr-debug` is set, then PprUser and PprDump styles are silently replaced with PprDebug style. This was done in `mkUserStyle` and `mkDumpStyle` smart constructors. As a consequence they needed a DynFlags parameter. Now we keep the original PprUser and PprDump styles until they are used to create an `SDocContext`. I.e. the substitution is only performed in `initSDocContext`. - - - - - b3df9e78 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Remove PprStyle param of logging actions Use `withPprStyle` instead to apply a specific style to a SDoc. - - - - - de9fc995 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Fully remove PprDebug PprDebug was a pain to deal with consistently as it is implied by `-dppr-debug` but it isn't really a PprStyle. We remove it completely and query the appropriate SDoc flag instead (`sdocPprDebug`) via helpers (`getPprDebug` and its friends). - - - - - 8b51fcbd by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Only call checkSingle if we would report warnings - - - - - fd7ea0fe by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 7bfe9ac5 by Ben Gamari at 2020-05-03T04:41:33-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. - - - - - c560dd07 by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Move eventlog documentation users guide - - - - - 02543d5e by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Add documentation for non-moving GC events - - - - - b465dd45 by Alexis King at 2020-05-03T04:42:12-04:00 Flatten nested casts in the simple optimizer Normally, we aren’t supposed to generated any nested casts, since mkCast takes care to flatten them, but the simple optimizer didn’t use mkCast, so they could show up after inlining. This isn’t really a problem, since the simplifier will clean them up immediately anyway, but it can clutter the -ddump-ds output, and it’s an extremely easy fix. closes #18112 - - - - - 8bdc03d6 by Simon Peyton Jones at 2020-05-04T01:56:59-04:00 Don't return a panic in tcNestedSplice In GHC.Tc.Gen.Splice.tcNestedSplice we were returning a typechecked expression of "panic". That is usually OK, because the result is discarded. But it happens that tcApp now looks at the typechecked expression, trivially, to ask if it is tagToEnum. So being bottom is bad. Moreover a debug-trace might print it out. So better to return a civilised expression, even though it is usually discarded. - - - - - 0bf640b1 by Baldur Blöndal at 2020-05-04T01:57:36-04:00 Don't require parentheses around via type (`-XDerivingVia'). Fixes #18130". - - - - - 30272412 by Artem Pelenitsyn at 2020-05-04T13:19:59-04:00 Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) - - - - - b9f7c08f by jneira at 2020-05-04T13:20:37-04:00 Remove unused hs-boot file - - - - - 1d8f80cd by Sylvain Henry at 2020-05-05T03:22:46-04:00 Remove references to -package-key * remove references to `-package-key` which has been removed in 2016 (240ddd7c39536776e955e881d709bbb039b48513) * remove support for `-this-package-key` which has been deprecated at the same time - - - - - 7bc3a65b by Sylvain Henry at 2020-05-05T03:23:31-04:00 Remove SpecConstrAnnotation (#13681) This has been deprecated since 2013. Use GHC.Types.SPEC instead. Make GHC.Exts "not-home" for haddock Metric Decrease: haddock.base - - - - - 3c862f63 by DenisFrezzato at 2020-05-05T03:24:15-04:00 Fix Haskell98 short description in documentation - - - - - 2420c555 by Ryan Scott at 2020-05-05T03:24:53-04:00 Add regression tests for #16244, #16245, #16758 Commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70 ended up fixing quite a few bugs: * This commit fixes #16244 completely. A regression test has been added. * This commit fixes one program from #16245. (The program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211369 still panics, and the program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211400 still loops infinitely.) A regression test has been added for this program. * This commit fixes #16758. Accordingly, this patch removes the `expect_broken` label from the `T16758` test case, moves it from `should_compile` to `should_fail` (as it should produce an error message), and checks in the expected stderr. - - - - - 40c71c2c by Sylvain Henry at 2020-05-05T03:25:31-04:00 Fix colorized error messages (#18128) In b3df9e780fb2f5658412c644849cd0f1e6f50331 I broke colorized messages by using "dump" style instead of "user" style. This commits fixes it. - - - - - 7ab6ab09 by Richard Eisenberg at 2020-05-06T04:39:32-04:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG ------------------------- - - - - - 420b957d by Ben Gamari at 2020-05-06T04:40:08-04:00 rts: Zero block flags with -DZ Block flags are very useful for determining the state of a block. However, some block allocator users don't touch them, leading to misleading values. Ensure that we zero then when zero-on-gc is set. This is safe and makes the flags more useful during debugging. - - - - - 740b3b8d by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix incorrect failed_to_evac value during deadlock gc Previously we would incorrectly set the failed_to_evac flag if we evacuated a value due to a deadlock GC. This would cause us to mark more things as dirty than strictly necessary. It also turned up a nasty but which I will fix next. - - - - - b2d72c75 by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - 9f3e6884 by Zubin Duggal at 2020-05-06T04:41:08-04:00 Allow atomic update of NameCache in readHieFile The situation arises in ghcide where multiple different threads may need to update the name cache, therefore with the older interface it could happen that you start reading a hie file with name cache A and produce name cache A + B, but another thread in the meantime updated the namecache to A + C. Therefore if you write the new namecache you will lose the A' updates from the second thread. Updates haddock submodule - - - - - edec6a6c by Ryan Scott at 2020-05-06T04:41:57-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _)`. Fixes #18127. - - - - - a95e7fe0 by Ömer Sinan Ağacan at 2020-05-06T04:42:39-04:00 ELF linker: increment curSymbol after filling in fields of current entry The bug was introduced in a8b7cef4d45 which added a field to the `symbols` array elements and then updated this code incorrectly: - oc->symbols[curSymbol++] = nm; + oc->symbols[curSymbol++].name = nm; + oc->symbols[curSymbol].addr = symbol->addr; - - - - - cab1871a by Sylvain Henry at 2020-05-06T04:43:21-04:00 Move LeadingUnderscore into Platform (#17957) Avoid direct use of DynFlags to know if symbols must be prefixed by an underscore. - - - - - 94e7c563 by Sylvain Henry at 2020-05-06T04:43:21-04:00 Don't use DynFlags in showLinkerState (#17957) - - - - - 9afd9251 by Ryan Scott at 2020-05-06T04:43:58-04:00 Refactoring: Use bindSigTyVarsFV in rnMethodBinds `rnMethodBinds` was explicitly using `xoptM` to determine if `ScopedTypeVariables` is enabled before bringing type variables bound by the class/instance header into scope. However, this `xoptM` logic is already performed by the `bindSigTyVarsFV` function. This patch uses `bindSigTyVarsFV` in `rnMethodBinds` to reduce the number of places where we need to consult if `ScopedTypeVariables` is on. This is purely refactoring, and there should be no user-visible change in behavior. - - - - - 6f6d72b2 by Brian Foley at 2020-05-08T15:29:25-04:00 Remove further dead code found by a simple Python script. Avoid removing some functions that are part of an API even though they're not used in-tree at the moment. - - - - - 78bf8bf9 by Julien Debon at 2020-05-08T15:29:28-04:00 Add doc examples for Bifoldable See #17929 - - - - - 66f0a847 by Julien Debon at 2020-05-08T15:29:29-04:00 doc (Bitraversable): Add examples to Bitraversable * Add examples to Data.Bitraversable * Fix formatting for (,) in Bitraversable and Bifoldable * Fix mistake on bimapAccumR documentation See #17929 - - - - - 9749fe12 by Baldur Blöndal at 2020-05-08T15:29:32-04:00 Specify kind variables for inferred kinds in base. - - - - - 4e9aef9e by John Ericson at 2020-05-08T15:29:36-04:00 HsSigWcTypeScoping: Pull in documentation from stray location - - - - - f4d5c6df by John Ericson at 2020-05-08T15:29:36-04:00 Rename local `real_fvs` to `implicit_vs` It doesn't make sense to call the "free" variables we are about to implicitly bind the real ones. - - - - - 20570b4b by John Ericson at 2020-05-08T15:29:36-04:00 A few tiny style nits with renaming - Use case rather than guards that repeatedly scrutenize same thing. - No need for view pattern when `L` is fine. - Use type synnonym to convey the intent like elsewhere. - - - - - 09ac8de5 by John Ericson at 2020-05-08T15:29:36-04:00 Add `forAllOrNothing` function with note - - - - - bb35c0e5 by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Document lawlessness of Ap's Num instance - - - - - cdd229ff by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply suggestion to libraries/base/Data/Monoid.hs - - - - - 926d2aab by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply more suggestions from Simon Jakobi - - - - - 7a763cff by Adam Gundry at 2020-05-08T15:29:41-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. - - - - - 88e3c815 by Simon Peyton Jones at 2020-05-08T15:29:41-04:00 Fix specialisation for DFuns When specialising a DFun we must take care to saturate the unfolding. See Note [Specialising DFuns] in Specialise. Fixes #18120 - - - - - 86c77b36 by Greg Steuck at 2020-05-08T15:29:45-04:00 Remove unused SEGMENT_PROT_RWX It's been unused for a year and is problematic on any OS which requires W^X for security. - - - - - 9d97f4b5 by nineonine at 2020-05-08T15:30:03-04:00 Add test for #16167 - - - - - aa318338 by Ryan Scott at 2020-05-08T15:30:04-04:00 Bump exceptions submodule so that dist-boot is .gitignore'd `exceptions` is a stage-0 boot library as of commit 30272412fa437ab8e7a8035db94a278e10513413, which means that building `exceptions` in a GHC tree will generate a `dist-boot` directory. However, this directory was not specified in `exceptions`' `.gitignore` file, which causes it to dirty up the current `git` working directory. Accordingly, this bumps the `exceptions` submodule to commit ghc/packages/exceptions at 23c0b8a50d7592af37ca09beeec16b93080df98f, which adds `dist-boot` to the `.gitignore` file. - - - - - ea86360f by Ömer Sinan Ağacan at 2020-05-08T15:30:30-04:00 Linker.c: initialize n_symbols of ObjectCode with other fields - - - - - 951c1fb0 by Sylvain Henry at 2020-05-09T21:46:38-04:00 Fix unboxed-sums GC ptr-slot rubbish value (#17791) This patch allows boot libraries to use unboxed sums without implicitly depending on `base` package because of `absentSumFieldError`. See updated Note [aBSENT_SUM_FIELD_ERROR_ID] in GHC.Core.Make - - - - - b352d63c by Ben Gamari at 2020-05-09T21:47:14-04:00 rts: Make non-existent linker search path merely a warning As noted in #18105, previously this resulted in a rather intrusive error message. This is in contrast to the general expectation that search paths are merely places to look, not places that must exist. Fixes #18105. - - - - - cf4f1e2f by Ben Gamari at 2020-05-13T02:02:33-04:00 rts/CNF: Fix fixup comparison function Previously we would implicitly convert the difference between two words to an int, resulting in an integer overflow on 64-bit machines. Fixes #16992 - - - - - a03da9bf by Ömer Sinan Ağacan at 2020-05-13T02:03:16-04:00 Pack some of IdInfo fields into a bit field This reduces residency of compiler quite a bit on some programs. Example stats when building T10370: Before: 2,871,242,832 bytes allocated in the heap 4,693,328,008 bytes copied during GC 33,941,448 bytes maximum residency (276 sample(s)) 375,976 bytes maximum slop 83 MiB total memory in use (0 MB lost due to fragmentation) After: 2,858,897,344 bytes allocated in the heap 4,629,255,440 bytes copied during GC 32,616,624 bytes maximum residency (278 sample(s)) 314,400 bytes maximum slop 80 MiB total memory in use (0 MB lost due to fragmentation) So -3.9% residency, -1.3% bytes copied and -0.4% allocations. Fixes #17497 Metric Decrease: T9233 T9675 - - - - - 670c3e5c by Ben Gamari at 2020-05-13T02:03:54-04:00 get-win32-tarballs: Fix base URL Revert a change previously made for testing purposes. - - - - - 8ad8dc41 by Ben Gamari at 2020-05-13T02:03:54-04:00 get-win32-tarballs: Improve diagnostics output - - - - - 8c0740b7 by Simon Jakobi at 2020-05-13T02:04:33-04:00 docs: Add examples for Data.Semigroup.Arg{Min,Max} Context: #17153 - - - - - cb22348f by Ben Gamari at 2020-05-13T02:05:11-04:00 Add few cleanups of the CAF logic Give the NameSet of non-CAFfy names a proper newtype to distinguish it from all of the other NameSets floating about. - - - - - 90e38b81 by Emeka Nkurumeh at 2020-05-13T02:05:51-04:00 fix printf warning when using with ghc with clang on mingw - - - - - 86d8ac22 by Sebastian Graf at 2020-05-13T02:06:29-04:00 CprAnal: Don't attach CPR sigs to expandable bindings (#18154) Instead, look through expandable unfoldings in `cprTransform`. See the new Note [CPR for expandable unfoldings]: ``` Long static data structures (whether top-level or not) like xs = x1 : xs1 xs1 = x2 : xs2 xs2 = x3 : xs3 should not get CPR signatures, because they * Never get WW'd, so their CPR signature should be irrelevant after analysis (in fact the signature might even be harmful for that reason) * Would need to be inlined/expanded to see their constructed product * Recording CPR on them blows up interface file sizes and is redundant with their unfolding. In case of Nested CPR, this blow-up can be quadratic! But we can't just stop giving DataCon application bindings the CPR property, for example fac 0 = 1 fac n = n * fac (n-1) fac certainly has the CPR property and should be WW'd! But FloatOut will transform the first clause to lvl = 1 fac 0 = lvl If lvl doesn't have the CPR property, fac won't either. But lvl doesn't have a CPR signature to extrapolate into a CPR transformer ('cprTransform'). So instead we keep on cprAnal'ing through *expandable* unfoldings for these arity 0 bindings via 'cprExpandUnfolding_maybe'. In practice, GHC generates a lot of (nested) TyCon and KindRep bindings, one for each data declaration. It's wasteful to attach CPR signatures to each of them (and intractable in case of Nested CPR). ``` Fixes #18154. - - - - - e34bf656 by Ben Gamari at 2020-05-13T02:07:08-04:00 users-guide: Add discussion of shared object naming Fixes #18074. - - - - - 5d0f2445 by Ben Gamari at 2020-05-13T02:07:47-04:00 testsuite: Print sign of performance changes Executes the minor formatting change in the tabulated performance changes suggested in #18135. - - - - - 9e4b981f by Ben Gamari at 2020-05-13T02:08:24-04:00 testsuite: Add testcase for #18129 - - - - - 266310c3 by Ivan-Yudin at 2020-05-13T02:09:03-04:00 doc: Reformulate the opening paragraph of Ch. 4 in User's guide Removes mentioning of Hugs (it is not helpful for new users anymore). Changes the wording for the rest of the paragraph. Fixes #18132. - - - - - 55e35c0b by Baldur Blöndal at 2020-05-13T20:02:48-04:00 Predicate, Equivalence derive via `.. -> a -> All' - - - - - d7e0b57f by Alp Mestanogullari at 2020-05-13T20:03:30-04:00 hadrian: add a --freeze2 option to freeze stage 1 and 2 - - - - - d880d6b2 by Artem Pelenitsyn at 2020-05-13T20:04:11-04:00 Don't reload environment files on every setSessionDynFlags Makes `interpretPackageEnv` (which loads envirinment files) a part of `parseDynamicFlags` (parsing command-line arguments, which is typically done once) instead of `setSessionDynFlags` (which is typically called several times). Making several (transitive) calls to `interpretPackageEnv`, as before, caused #18125 #16318, which should be fixed now. - - - - - 102cfd67 by Ryan Scott at 2020-05-13T20:04:46-04:00 Factor out HsPatSigType for pat sigs/RULE term sigs (#16762) This implements chunks (2) and (3) of https://gitlab.haskell.org/ghc/ghc/issues/16762#note_270170. Namely, it introduces a dedicated `HsPatSigType` AST type, which represents the types that can appear in pattern signatures and term-level `RULE` binders. Previously, these were represented with `LHsSigWcType`. Although `LHsSigWcType` is isomorphic to `HsPatSigType`, the intended semantics of the two types are slightly different, as evidenced by the fact that they have different code paths in the renamer and typechecker. See also the new `Note [Pattern signature binders and scoping]` in `GHC.Hs.Types`. - - - - - b17574f7 by Hécate at 2020-05-13T20:05:28-04:00 fix(documentation): Fix the RST links to GHC.Prim - - - - - df021fb1 by Baldur Blöndal at 2020-05-13T20:06:06-04:00 Document (->) using inferred quantification for its runtime representations. Fixes #18142. - - - - - 1a93ea57 by Takenobu Tani at 2020-05-13T20:06:54-04:00 Tweak man page for ghc command This commit updates the ghc command's man page as followings: * Enable `man_show_urls` to show URL addresses in the `DESCRIPTION` section of ghc.rst, because sphinx currently removes hyperlinks for man pages. * Add a `SEE ALSO` section to point to the GHC homepage - - - - - a951e1ba by Takenobu Tani at 2020-05-13T20:07:37-04:00 GHCi: Add link to the user's guide in help message This commit adds a link to the user's guide in ghci's `:help` message. Newcomers could easily reach to details of ghci. - - - - - 404581ea by Jeff Happily at 2020-05-13T20:08:15-04:00 Handle single unused import - - - - - 1c999e5d by Ben Gamari at 2020-05-13T20:09:07-04:00 Ensure that printMinimalImports closes handle Fixes #18166. - - - - - c9f5a8f4 by Ben Gamari at 2020-05-13T20:09:51-04:00 hadrian: Tell testsuite driver about LLVM availability This reflects the logic present in the Make build system into Hadrian. Fixes #18167. - - - - - c05c0659 by Simon Jakobi at 2020-05-14T03:31:21-04:00 Improve some folds over Uniq[D]FM * Replace some non-deterministic lazy folds with strict folds. * Replace some O(n log n) folds in deterministic order with O(n) non-deterministic folds. * Replace some folds with set-operations on the underlying IntMaps. This reduces max residency when compiling `nofib/spectral/simple/Main.hs` with -O0 by about 1%. Maximum residency when compiling Cabal also seems reduced on the order of 3-9%. - - - - - 477f13bb by Simon Jakobi at 2020-05-14T03:31:58-04:00 Use Data.IntMap.disjoint Data.IntMap gained a dedicated `disjoint` function in containers-0.6.2.1. This patch applies this function where appropriate in hopes of modest compiler performance improvements. Closes #16806. - - - - - e9c0110c by Ben Gamari at 2020-05-14T12:25:53-04:00 IdInfo: Add reference to bitfield-packing ticket - - - - - 481e3174 by Ben Gamari at 2020-05-14T12:30:08-04:00 gitlab-ci: Introduce DWARF release jobs for Deb10 and Fedora 27 - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - CODEOWNERS - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - compiler/prelude/PrelNames.hs-boot → compiler/GHC/Builtin/Names.hs-boot - compiler/prelude/THNames.hs → compiler/GHC/Builtin/Names/TH.hs - compiler/prelude/PrimOp.hs → compiler/GHC/Builtin/PrimOps.hs - + compiler/GHC/Builtin/PrimOps.hs-boot - compiler/prelude/TysWiredIn.hs → compiler/GHC/Builtin/Types.hs - compiler/prelude/TysWiredIn.hs-boot → compiler/GHC/Builtin/Types.hs-boot - compiler/typecheck/TcTypeNats.hs → compiler/GHC/Builtin/Types/Literals.hs - compiler/prelude/TysPrim.hs → compiler/GHC/Builtin/Types/Prim.hs - compiler/prelude/KnownUniques.hs → compiler/GHC/Builtin/Uniques.hs - compiler/prelude/KnownUniques.hs-boot → compiler/GHC/Builtin/Uniques.hs-boot - compiler/prelude/PrelInfo.hs → compiler/GHC/Builtin/Utils.hs - compiler/prelude/primops.txt.pp → compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.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/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Block.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f337a64537fe453aaabaf121f7d9aa8a821a8c06...481e31740672a37c5b3a8924bba7e15c4080bc2e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f337a64537fe453aaabaf121f7d9aa8a821a8c06...481e31740672a37c5b3a8924bba7e15c4080bc2e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 16:39:06 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Thu, 14 May 2020 12:39:06 -0400 Subject: [Git][ghc/ghc][wip/mod-rem-strict] Make `Int`'s `mod` and `rem` strict in their first arguments Message-ID: <5ebd742aa88bb_61679b2e0f4113020e8@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/mod-rem-strict at Glasgow Haskell Compiler / GHC Commits: 748cf6be by Sebastian Graf at 2020-05-14T18:37:21+02:00 Make `Int`'s `mod` and `rem` strict in their first arguments They used to be strict until 4d2ac2d (9 years ago). It's obviously better to be strict for performance reasons. It also blocks #18067. NoFib results: ``` -------------------------------------------------------------------------------- Program Allocs Instrs -------------------------------------------------------------------------------- integer -1.1% +0.4% wheel-sieve2 +21.2% +20.7% -------------------------------------------------------------------------------- Min -1.1% -0.0% Max +21.2% +20.7% Geometric Mean +0.2% +0.2% ``` The regression in `wheel-sieve2` is due to reboxing that likely will go away with the resolution of #18067. See !3282 for details. Fixes #18187. - - - - - 1 changed file: - libraries/base/GHC/Real.hs Changes: ===================================== libraries/base/GHC/Real.hs ===================================== @@ -334,7 +334,7 @@ instance Integral Int where -- in GHC.Int | otherwise = a `quotInt` b - a `rem` b + !a `rem` b | b == 0 = divZeroError -- The quotRem CPU instruction fails for minBound `quotRem` -1, -- but minBound `rem` -1 is well-defined (0). We therefore @@ -348,7 +348,7 @@ instance Integral Int where -- in GHC.Int | otherwise = a `divInt` b - a `mod` b + !a `mod` b | b == 0 = divZeroError -- The divMod CPU instruction fails for minBound `divMod` -1, -- but minBound `mod` -1 is well-defined (0). We therefore View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/748cf6be65805844ce0c5a978b457feefd6d06bd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/748cf6be65805844ce0c5a978b457feefd6d06bd You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 16:51:05 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 14 May 2020 12:51:05 -0400 Subject: [Git][ghc/ghc][wip/backports] 9 commits: FastString: fix eager reading of string ptr in hashStr Message-ID: <5ebd76f93f873_6167c96b4bc113025de@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/backports at Glasgow Haskell Compiler / GHC Commits: 8b2e2c5d by Ömer Sinan Ağacan at 2020-05-14T12:31:10-04:00 FastString: fix eager reading of string ptr in hashStr This read causes NULL dereferencing when len is 0. Fixes #17909 In the reproducer in #17909 this bug is triggered as follows: - SimplOpt.dealWithStringLiteral is called with a single-char string ("=" in #17909) - tailFS gets called on the FastString of the single-char string. - tailFS checks the length of the string, which is 1, and calls mkFastStringByteString on the tail of the ByteString, which is an empty ByteString as the original ByteString has only one char. - ByteString's unsafeUseAsCStringLen returns (NULL, 0) for the empty ByteString, which is passed to mkFastStringWith. - mkFastStringWith gets hash of the NULL pointer via hashStr, which fails on empty strings because of this bug. (cherry picked from commit d15b61608a542f6349b42224140b7d227b88ef4e) - - - - - feabe4bd by Simon Peyton Jones at 2020-05-14T12:34:39-04:00 Improve error handling for VTA + deferred type errors This fixes #17792 See Note [VTA for out-of-scope functions] in TcExpr (cherry picked from commit 335b18bac3c361d243f427b66e67c2c94f5c6494) - - - - - fbf280c2 by Simon Peyton Jones at 2020-05-14T12:38:20-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 (cherry picked from commit 658bda511237593bb80389280d0364180648058d) - - - - - 3d9267f2 by Sylvain Henry at 2020-05-14T12:39:04-04:00 Rts: show errno on failure (#18033) (cherry picked from commit 4875d419ba066e479f7ac07f8b39ebe10c855859) - - - - - 1ad5f9d3 by Simon Peyton Jones at 2020-05-14T12:48:31-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! (cherry picked from commit 7052d7c7ce3418db9e66ad6ff31e80b2a2c724bb) - - - - - 0e15cd02 by Ryan Scott at 2020-05-14T12:48:43-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). (cherry picked from commit cfb66d181ac45ce3d934bda3521b94277e6eb683) - - - - - 522fb66e by Adam Gundry at 2020-05-14T12:50:21-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. (cherry picked from commit 0d8c7a6c7c3513089668f49efb0a2dd8b4bbe74a) - - - - - 9e50a165 by Ben Gamari at 2020-05-14T12:50:34-04:00 Ensure that printMinimalImports closes handle Fixes #18166. (cherry picked from commit 5afc160dee7142c96a842037fb64bee1429ad9ec) - - - - - c54556ec by Ben Gamari at 2020-05-14T12:50:48-04:00 rts: Make non-existent linker search path merely a warning As noted in #18105, previously this resulted in a rather intrusive error message. This is in contrast to the general expectation that search paths are merely places to look, not places that must exist. Fixes #18105. (cherry picked from commit 24af9f30681444380c25465f555599da563713cb) - - - - - 30 changed files: - compiler/basicTypes/RdrName.hs - compiler/coreSyn/CoreSubst.hs - compiler/coreSyn/CoreUnfold.hs - compiler/deSugar/DsBinds.hs - compiler/rename/RnNames.hs - compiler/specialise/Specialise.hs - compiler/typecheck/TcExpr.hs - compiler/typecheck/TcHsType.hs - compiler/typecheck/TcSplice.hs - compiler/utils/FastString.hs - rts/linker/PEi386.c - rts/posix/itimer/Pthread.c - + testsuite/tests/overloadedrecflds/should_fail/T17965.hs - + testsuite/tests/overloadedrecflds/should_fail/T17965.stderr - testsuite/tests/overloadedrecflds/should_fail/all.T - + testsuite/tests/partial-sigs/should_compile/T18008.hs - + testsuite/tests/partial-sigs/should_compile/T18008.stderr - testsuite/tests/partial-sigs/should_compile/all.T - testsuite/tests/perf/compiler/T16473.stdout - testsuite/tests/simplCore/should_compile/Makefile - + testsuite/tests/simplCore/should_compile/T17810.hs - + testsuite/tests/simplCore/should_compile/T17810a.hs - + testsuite/tests/simplCore/should_compile/T17930.hs - + testsuite/tests/simplCore/should_compile/T17930.stderr - + testsuite/tests/simplCore/should_compile/T17966.hs - + testsuite/tests/simplCore/should_compile/T17966.stdout - testsuite/tests/simplCore/should_compile/all.T - + testsuite/tests/simplCore/should_compile/spec004.hs - + testsuite/tests/simplCore/should_compile/spec004.stderr - + testsuite/tests/th/T17305.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b9df14c49bd6b70e403559e9a70669cc50d7e2f8...c54556ec1a6864b620d7eafcc10a7f55ac0c69b1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b9df14c49bd6b70e403559e9a70669cc50d7e2f8...c54556ec1a6864b620d7eafcc10a7f55ac0c69b1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 16:53:02 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 14 May 2020 12:53:02 -0400 Subject: [Git][ghc/ghc][wip/gc/opt-barrier] 344 commits: Be explicit about how stack usage of mvar primops are covered. Message-ID: <5ebd776ea3f44_61673f81cc06592c1130529c@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/gc/opt-barrier at Glasgow Haskell Compiler / GHC Commits: 8c663c2c by Andreas Klebinger at 2020-03-04T16:12:14+01:00 Be explicit about how stack usage of mvar primops are covered. This fixes #17893 [skip-ci] - - - - - cedd6f30 by Ben Gamari at 2020-03-05T14:53:12-05:00 rts: Add getCurrentThreadCPUTime helper - - - - - ace618cd by Ben Gamari at 2020-03-05T14:53:12-05:00 nonmoving-gc: Track time usage of nonmoving marking - - - - - 022b5ad5 by Ben Gamari at 2020-03-05T14:53:12-05:00 Stats: Add sync pauses to +RTS -S output - - - - - 06763234 by Ben Gamari at 2020-03-05T14:53:12-05:00 rts: Report nonmoving collector statistics in machine-readable output - - - - - 70d2b995 by Ben Gamari at 2020-03-09T06:10:52-04:00 nonmoving: Fix collection of sparks Previously sparks living in the non-moving heap would be promptly GC'd by the minor collector since pruneSparkQueue uses the BF_EVACUATED flag, which non-moving heap blocks do not have set. Fix this by implementing proper support in pruneSparkQueue for determining reachability in the non-moving heap. The story is told in Note [Spark management in the nonmoving heap]. - - - - - 9668781a by Ben Gamari at 2020-03-09T06:11:30-04:00 gitlab-ci: Disable Sphinx documentation in Alpine build - - - - - 8eb2c263 by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 Fix Windows breakage by not touching locales on Windows - - - - - b8dab057 by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 rts: ensure C numerics in heap profiles using Windows locales if needed - - - - - 7d95260f by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 rts: refactor and comment profile locales - - - - - 5b627813 by Ryan Scott at 2020-03-09T16:34:14-04:00 Use InstanceSigs in GND/DerivingVia-generated code (#17899) Aside from making the generated code easier to read when `-ddump-deriv` is enabled, this makes the error message in `T15073` substantially simpler (see the updated `T15073` expected stderr). Fixes #17899. - - - - - 70b50778 by Ben Gamari at 2020-03-10T02:05:42-04:00 SysTools: Ensure that error parser can handle absolute paths on Windows This fixes #17786, where the error parser fails to correctly handle the drive name in absolute Windows paths. Unfortunately I couldn't find a satisfactory way to test this. - - - - - 85b861d8 by Ben Gamari at 2020-03-10T02:05:42-04:00 testsuite: Add test for #17786 This isn't pretty but it's perhaps better than nothing. - - - - - ee2c50cb by Sylvain Henry at 2020-03-10T02:06:33-04:00 Hadrian: track missing configure results - - - - - ca8f51d4 by Ömer Sinan Ağacan at 2020-03-10T02:07:22-04:00 Add regression test for T17904 Closes #17904 - - - - - 5fa9cb82 by Richard Eisenberg at 2020-03-10T12:29:46-04:00 anyRewritableTyVar now looks in RuntimeReps Previously, anyRewritableTyVar looked only at the arg and res of `arg -> res`, but their RuntimeReps are also subject to rewriting. Easy to fix. Test case: typecheck/should_compile/T17024 Fixes #17024. - - - - - 5ba01d83 by Ben Price at 2020-03-10T12:30:27-04:00 Clarify a Lint message When developing a plugin I had a shadowing problem, where I generated code app = \f{v r7B} x{v r7B} -> f{v r7B} x{v r7B} This is obviously wrong, since the occurrence of `f` to the right of the arrow refers to the `x` binder (they share a Unique). However, it is rather confusing when Lint reports Mismatch in type between binder and occurrence Var: x{v rB7} since it is printing the binder, rather than the occurrence. It is rather easy to read this as claiming there is something wrong with the `x` occurrence! We change the report to explicitly print both the binder and the occurrence variables. - - - - - 7b2c827b by Simon Peyton Jones at 2020-03-10T12:31:15-04:00 Comments only Clarify code added in #17852 and MR !2724 - - - - - 3300eeac by Krzysztof Gogolewski at 2020-03-10T12:31:54-04:00 Misc cleanup - Remove Note [Existentials in shift_con_pat]. The function shift_con_pat has been removed 15 years ago in 23f40f0e9be6d4. - Remove kcLookupTcTyCon - it's the same as tcLookupTcTyCon - Remove ASSERT in tyConAppArgN. It's already done by getNth, and it's the only reason getNth exists. - Remove unused function nextRole - - - - - abf5736b by Krzysztof Gogolewski at 2020-03-10T18:05:01+01:00 Typos in comments [skip ci] - - - - - bb586f89 by Ben Gamari at 2020-03-11T00:14:59-04:00 rts: Prefer darwin-specific getCurrentThreadCPUTime macOS Catalina now supports a non-POSIX-compliant version of clock_gettime which cannot use the clock_gettime codepath. Fixes #17906. - - - - - 20800b9a by Sylvain Henry at 2020-03-11T08:17:19-04:00 Split GHC.Iface.Utils module * GHC.Iface.Recomp: recompilation avoidance stuff * GHC.Iface.Make: mkIface* Moved `writeIfaceFile` into GHC.Iface.Load alongside `readIface` and renamed it `writeIface` for consistency. - - - - - 1daa2029 by Greg Steuck at 2020-03-11T08:17:56-04:00 Fixed a minor typo in codegen.rst - - - - - 0bc23338 by Ryan Scott at 2020-03-11T08:18:32-04:00 Re-quantify when generalising over rewrite rule types Previously, `tcRules` would check for naughty quantification candidates (see `Note [Naughty quantification candidates]` in `TcMType`) when generalising over the type of a rewrite rule. This caused sensible-looking rewrite rules (like those in #17710) to be rejected. A more permissing (and easier-to-implement) approach is to do what is described in `Note [Generalising in tcTyFamInstEqnGuts]` in `TcTyClsDecls`: just re-quantify all the type variable binders, regardless of the order in which the user specified them. After all, the notion of type variable specificity has no real meaning in rewrite rules, since one cannot "visibly apply" a rewrite rule. I have written up this wisdom in `Note [Re-quantify type variables in rules]` in `TcRules`. As a result of this patch, compiling the `ExplicitForAllRules1` test case now generates one fewer warning than it used to. As far as I can tell, this is benign, since the thing that the disappearing warning talked about was also mentioned in an entirely separate warning. Fixes #17710. - - - - - 336eac7e by Ben Gamari at 2020-03-11T08:19:08-04:00 testsuite: Mark ghci056 and ghcilink004 as fragile in unreg As noted in #17018. Also fix fragile declaration of T13786, which only runs in the normal way. - - - - - c61b9b02 by Simon Peyton Jones at 2020-03-11T08:19:44-04:00 Deepen call stack for isIn I see quite a few warnings like: WARNING: file compiler/utils/Util.hs, line 593 Over-long elem in unionLists But the call stack is uninformative. Better to add HasDebugCallStack to isIn. Ditto isn'tIn. - - - - - 3aa9b35f by Ömer Sinan Ağacan at 2020-03-11T08:20:27-04:00 Zero any slop after compaction in compacting GC In copying GC, with the relevant debug flags enabled, we release the old blocks after a GC, and the block allocator zeroes the space before releasing a block. This effectively zeros the old heap. In compacting GC we reuse the blocks and previously we didn't zero the unused space in a compacting generation after compaction. With this patch we zero the slop between the free pointer and the end of the block when we're done with compaction and when switching to a new block (because the current block doesn't have enough space for the next object we're shifting). - - - - - 8e6febce by Sylvain Henry at 2020-03-11T20:33:37-04:00 Refactor GHC.Driver.Session (Ways and Flags) * extract flags and ways into their own modules (with some renaming) * remove one SOURCE import of GHC.Driver.Session from GHC.Driver.Phases * when GHC uses dynamic linking (WayDyn), `interpWays` was only reporting WayDyn even if the host was profiled (WayProf). Now it returns both as expected (might fix #16803). * `mkBuildTag :: [Way] -> String` wasn't reporting a canonical tag for differently ordered lists. Now we sort and nub the list to fix this. - - - - - bc41e471 by Sylvain Henry at 2020-03-11T20:33:37-04:00 Refactor interpreterDynamic and interpreterProfiled * `interpreterDynamic` and `interpreterProfiled` now take `Interp` parameters instead of DynFlags * slight refactoring of `ExternalInterp` so that we can read the iserv configuration (which is pure) without reading an MVar. - - - - - a6989971 by Sylvain Henry at 2020-03-11T20:33:37-04:00 Use a Set to represent Ways Should make `member` queries faster and avoid messing up with missing `nubSort`. Metric Increase: hie002 - - - - - cb93a1a4 by Ryan Scott at 2020-03-11T20:34:14-04:00 Make DeriveFunctor-generated code require fewer beta reductions Issue #17880 demonstrates that `DeriveFunctor`-generated code is surprisingly fragile when rank-_n_ types are involved. The culprit is that `$fmap` (the algorithm used to generate `fmap` implementations) was too keen on applying arguments with rank-_n_ types to lambdas, which fail to typecheck more often than not. In this patch, I change `$fmap` (both the specification and the implementation) to produce code that avoids creating as many lambdas, avoiding problems when rank-_n_ field types arise. See the comments titled "Functor instances" in `TcGenFunctor` for a more detailed description. Not only does this fix #17880, but it also ensures that the code that `DeriveFunctor` generates will continue to work after simplified subsumption is implemented (see #17775). What is truly amazing is that #17880 is actually a regression (introduced in GHC 7.6.3) caused by commit 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e, the fix #7436. Prior to that commit, the version of `$fmap` that was used was almost identical to the one used in this patch! Why did that commit change `$fmap` then? It was to avoid severe performance issues that would arise for recursive `fmap` implementations, such as in the example below: ```hs data List a = Nil | Cons a (List a) deriving Functor -- ===> instance Functor List where fmap f Nil = Nil fmap f (Cons x xs) = Cons (f x) (fmap (\y -> f y) xs) ``` The fact that `\y -> f y` was eta expanded caused significant performance overheads. Commit 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e fixed this performance issue, but it went too far. As a result, this patch partially reverts 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e. To ensure that the performance issues pre-#7436 do not resurface, I have taken some precautionary measures: * I have added a special case to `$fmap` for situations where the last type variable in an application of some type occurs directly. If this special case fires, we avoid creating a lambda expression. This ensures that we generate `fmap f (Cons x xs) = Cons (f x) (fmap f xs)` in the derived `Functor List` instance above. For more details, see `Note [Avoid unnecessary eta expansion in derived fmap implementations]` in `TcGenFunctor`. * I have added a `T7436b` test case to ensure that the performance of this derived `Functor List`-style code does not regress. When implementing this, I discovered that `$replace`, the algorithm which generates implementations of `(<$)`, has a special case that is very similar to the `$fmap` special case described above. `$replace` marked this special case with a custom `Replacer` data type, which was a bit overkill. In order to use the same machinery for both `Functor` methods, I ripped out `Replacer` and instead implemented a simple way to detect the special case. See the updated commentary in `Note [Deriving <$]` for more details. - - - - - 1f9db3e7 by Kirill Elagin at 2020-03-12T09:45:51-04:00 pretty-printer: Properly parenthesise LastStmt After ApplicatveDo strips the last `return` during renaming, the pretty printer has to restore it. However, if the return was followed by `$`, the dollar was stripped too and not restored. For example, the last stamement in: ``` foo = do x <- ... ... return $ f x ``` would be printed as: ``` return f x ``` This commit preserved the dolar, so it becomes: ``` return $ f x ``` - - - - - 5cb93af7 by Kirill Elagin at 2020-03-12T09:45:51-04:00 pretty-printer: Do not print ApplicativeDo join * Do not print `join` in ApplictiveStmt, unless ppr-debug * Print parens around multiple parallel binds When ApplicativeDo is enabled, the renamer analyses the statements of a `do` block and in certain cases marks them as needing to be rewritten using `join`. For example, if you have: ``` foo = do a <- e1 b <- e2 doSomething a b ``` it will be desugared into: ``` foo = join (doSomething <$> e1 <*> e2) ``` After renaming but before desugaring the expression is stored essentially as: ``` foo = do [will need join] (a <- e1 | b <- e2) [no return] doSomething a b ``` Before this change, the pretty printer would print a call to `join`, even though it is not needed at this stage at all. The expression will be actually rewritten into one using join only at desugaring, at which point a literal call to join will be inserted. - - - - - 3a259092 by Simon Peyton Jones at 2020-03-12T09:46:29-04:00 Expose compulsory unfoldings always The unsafeCoerce# patch requires that unsafeCoerce# has a compulsory unfolding that is always available. So we have to be careful to expose compulsory unfoldings unconditionally and consistently. We didn't get this quite right: #17871. This patch fixes it. No real surprises here. See Note [Always expose compulsory unfoldings] in GHC.Iface.Tidy - - - - - 6a65b8c2 by Alp Mestanogullari at 2020-03-13T02:29:20-04:00 hadrian: improve dependency tracking for the check-* programs The code in Rules.Register responsible for finding all the build artifacts that Cabal installs when registering a library (static/shared libs, .hi files, ...) was looking in the wrong place. This patch fixes that logic and makes sure we gather all those artifacts in a list to declare that the rule for a given `.conf` file, our proxy for "Hadrian, please install this package in the package db for this stage", also produces those artifacts under the said package database. We also were completely missing some logic to declare that the check-* programs have dependencies besides their source code, at least when testing an in-tree compiler. Finally, this patch also removes redundant packages from 'testsuitePackages', since they should already be covered by the stage<N>Packages lists from Settings.Default. With this patch, after a complete build and freezing stage 1, a change to `compiler/parser/Parser.y` results in rebuilding the ghc lib, reinstalling it, and rebuilding the few programs that depend on it, _including_ `check-ppr` and `check-api-annotations` (therefore fixing #17273). - - - - - 44fad4a9 by Sylvain Henry at 2020-03-13T02:30:22-04:00 Rename isDllName I wanted to fix the dangling comment in `isDllName` ("This is the cause of #", #8696 is already mentioned earlier). I took the opportunity to change the function name to better reflect what it does. - - - - - 2f292db8 by Paavo at 2020-03-13T02:31:03-04:00 Update documentation for closureSize - - - - - f124ff0d by Ben Gamari at 2020-03-13T02:31:40-04:00 gitlab-ci: Rework triggering of release builds Use a push option instead of tagging. - - - - - 7f25557a by Ben Gamari at 2020-03-13T10:38:09-04:00 gitlab-ci: Distinguish integer-simple test envs Previously two integer-simple jobs declared the same test environment. One (the nightly job) was built in the perf way, the other in the validate way. Consequently they had appreciably different performance characteristics, causing in the nightly job to spuriously fail with performance changes. - - - - - c12a2ec5 by Simon Peyton Jones at 2020-03-14T05:25:30-04:00 Fix Lint Ticket #17590 pointed out a bug in the way the linter dealt with type lets, exposed by the new uniqAway story. The fix is described in Note [Linting type lets]. I ended up putting the in-scope Ids in a different env field, le_ids, rather than (as before) sneaking them into the TCvSubst. Surprisingly tiresome, but done. Metric Decrease: hie002 - - - - - b989845e by Sylvain Henry at 2020-03-14T05:26:11-04:00 Hadrian: fix absolute buildroot support (#17822) Shake's "**" wildcard doesn't match absolute root. We must use "//" instead. - - - - - 4f117135 by Sylvain Henry at 2020-03-14T05:26:49-04:00 Make: refactor GMP rules Document and use simpler rules for the ghc-gmp.h header. - - - - - 7432b327 by Sylvain Henry at 2020-03-14T05:27:28-04:00 Use correct option name (-opti) (fix #17314) s/pgmo/opti - - - - - 8f7dd571 by Judah Jacobson at 2020-03-14T05:28:07-04:00 Allow overriding LD_STAGE0 and AR_STAGE0 in the configure script. Previously it was possible to override the stage0 C compiler via `CC_STAGE0`, but you couldn't override `ld` or `ar` in stage0. This change allows overriding them by setting `LD_STAGE0` or `AR_STAGE0`, respectively. Our team uses this feature internally to take more control of our GHC build and make it run more hermetically. - - - - - 7c3e39a9 by Judah Jacobson at 2020-03-14T05:28:07-04:00 Use AC_ARG_VAR for LD_STAGE0 and AR_STAGE0. - - - - - 20d4d676 by Ben Gamari at 2020-03-14T05:28:43-04:00 nonmoving: Don't traverse filled segment list in pause The non-moving collector would previously walk the entire filled segment list during the preparatory pause. However, this is far more work than is strictly necessary. We can rather get away with merely collecting the allocators' filled segment list heads and process the lists themselves during the concurrent phase. This can significantly reduce the maximum gen1 GC pause time in programs with high rates of long-lived allocations. - - - - - fdfa2d01 by Ben Gamari at 2020-03-14T05:29:18-04:00 nonmoving: Remove redundant bitmap clearing nonmovingSweep already clears the bitmap in the sweep loop. There is no reason to do so a second time. - - - - - 2f8c7767 by Simon Peyton Jones at 2020-03-14T05:29:55-04:00 Simple refactor of cheapEqExpr No change in functionality. Just seems tidier (and signficantly more efficient) to deal with ticks directly than to call stripTicksTopE. - - - - - 88f7a762 by Simon Peyton Jones at 2020-03-14T05:29:55-04:00 Improve CSE.combineAlts This patch improves the way that CSE combines identical alternatives. See #17901. I'm still not happy about the duplication between CSE.combineAlts and GHC.Core.Utils.combineIdenticalAlts; see the Notes with those functions. But this patch is a step forward. Metric Decrease: T12425 T5642 - - - - - 8b95ddd3 by Ben Gamari at 2020-03-14T05:30:31-04:00 gitlab-ci: Add integer-simple release build for Windows Closes #16144. - - - - - e3c374cc by Simon Peyton Jones at 2020-03-14T05:31:07-04:00 Wrap an implication around class-sig kind errors Ticket #17841 showed that we can get a kind error in a class signature, but lack an enclosing implication that binds its skolems. This patch * Adds the wrapping implication: the new call to checkTvConstraints in tcClassDecl1 * Simplifies the API to checkTvConstraints, which was not otherwise called at all. * Simplifies TcErrors.report_unsolved by *not* initialising the TidyEnv from the typechecker lexical envt. It's enough to do so from the free vars of the unsolved constraints; and we get silly renamings if we add variables twice: once from the lexical scope and once from the implication constraint. - - - - - 73133a3b by Simon Peyton Jones at 2020-03-14T05:31:07-04:00 Refactoring in TcSMonad This patch is just refactoring: no change in behaviour. I removed the rather complicated checkConstraintsTcS checkTvConstraintsTcS in favour of simpler functions emitImplicationTcS emitTvImplicationTcS pushLevelNoWorkList The last of these is a little strange, but overall it's much better I think. - - - - - 93c88c26 by Ben Gamari at 2020-03-14T05:31:42-04:00 base: Make `open` calls interruptible As noted in #17912, `open` system calls were `safe` rather than `interruptible`. Consequently, the program could not be interrupted with SIGINT if stuck in a slow open operation. Fix this by marking `c_safe_open` as interruptible. - - - - - bee4cdad by Vladislav Zavialov at 2020-03-14T05:32:18-04:00 Remove second tcLookupTcTyCon in tcDataDefn Before this patch, tcDataDefn used to call tcLookupTcTyCon twice in a row: 1. in bindTyClTyVars itself 2. in the continuation passed to it Now bindTyClTyVars passes the TcTyCon to the continuation, making the second lookup unnecessary. - - - - - 3f116d35 by Cale Gibbard at 2020-03-14T19:34:42-04:00 Enable stage1 build of haddock The submodule has already been bumped to contain the fix. - - - - - 49e9d739 by Ömer Sinan Ağacan at 2020-03-14T19:35:24-04:00 rts: Fix printClosure when printing fwd ptrs - - - - - 1de3ab4a by Krzysztof Gogolewski at 2020-03-14T19:36:04-04:00 Remove unused field var_inline (#17915) - - - - - d30aeb4b by Krzysztof Gogolewski at 2020-03-15T03:57:41-04:00 Document restriction on SCC pragma syntax Currently, the names of cost centres must be quoted or be lowercase identifiers. Fixes #17916. - - - - - b4774598 by Brian Foley at 2020-03-15T03:58:18-04:00 Remove some dead code >From the notes.ghc.drop list found using weeder in #17713 - - - - - dd6ffe6b by Viktor Dukhovni at 2020-03-15T03:58:55-04:00 Note platform-specific Foreign.C.Types in context Also fix the markup in the general note at the top of the module. Haddock (usability trade-off), does not support multi-line emphasised text. - - - - - 2e82465f by Sylvain Henry at 2020-03-15T10:57:10-04:00 Refactor CmmToAsm (disentangle DynFlags) This patch disentangles a bit more DynFlags from the native code generator (CmmToAsm). In more details: - add a new NCGConfig datatype in GHC.CmmToAsm.Config which contains the configuration of a native code generation session - explicitly pass NCGConfig/Platform arguments when necessary - as a consequence `sdocWithPlatform` is gone and there are only a few `sdocWithDynFlags` left - remove the use of `unsafeGlobalDynFlags` from GHC.CmmToAsm.CFG - remove `sdocDebugLevel` (now we pass the debug level via NCGConfig) There are still some places where DynFlags is used, especially because of pretty-printing (CLabel), because of Cmm helpers (such as `cmmExprType`) and because of `Outputable` instance for the instructions. These are left for future refactoring as this patch is already big. - - - - - c35c545d by Judah Jacobson at 2020-03-15T10:57:48-04:00 Add a -no-haddock flag. This flag undoes the effect of a previous "-haddock" flag. Having both flags makes it easier for build systems to enable Haddock parsing in a set of global flags, but then disable it locally for specific targets (e.g., third-party packages whose comments don't pass the validation in the latest GHC). I added the flag to expected-undocumented-flags.txt since `-haddock` was alreadyin that list. - - - - - cfcc3c9a by Ömer Sinan Ağacan at 2020-03-15T10:58:27-04:00 Fix global_link of TSOs for threads reachable via dead weaks Fixes #17785 Here's how the problem occurs: - In generation 0 we have a TSO that is finished (i.e. it has no more work to do or it is killed). - The TSO only becomes reachable after collectDeadWeakPtrs(). - After collectDeadWeakPtrs() we switch to WeakDone phase where we don't move TSOs to different lists anymore (like the next gen's thread list or the resurrected_threads list). - So the TSO will never be moved to a generation's thread list, but it will be promoted to generation 1. - Generation 1 collected via mark-compact, and because the TSO is reachable it is marked, and its `global_link` field, which is bogus at this point (because the TSO is not in a list), will be threaded. - Chaos ensues. In other words, when these conditions hold: - A TSO is reachable only after collectDeadWeakPtrs() - It's finished (what_next is ThreadComplete or ThreadKilled) - It's retained by mark-compact collector (moving collector doesn't evacuate the global_list field) We end up doing random mutations on the heap because the TSO's global_list field is not valid, but it still looks like a heap pointer so we thread it during compacting GC. The fix is simple: when we traverse old_threads lists to resurrect unreachable threads the threads that won't be resurrected currently stays on the old_threads lists. Those threads will never be visited again by MarkWeak so we now reset the global_list fields. This way compacting GC does not thread pointers to nowhere. Testing ------- The reproducer in #17785 is quite large and hard to build, because of the dependencies, so I'm not adding a regression test. In my testing the reproducer would take a less than 5 seconds to run, and once in every ~5 runs would fail with a segfault or an assertion error. In other cases it also fails with a test failure. Because the tests never fail with the bug fix, assuming the code is correct, this also means that this bug can sometimes lead to incorrect runtime results. After the fix I was able to run the reproducer repeatedly for about an hour, with no runtime crashes or test failures. To run the reproducer clone the git repo: $ git clone https://github.com/osa1/streamly --branch ghc-segfault Then clone primitive and atomic-primops from their git repos and point to the clones in cabal.project.local. The project should then be buildable using GHC HEAD. Run the executable `properties` with `+RTS -c -DZ`. In addition to the reproducer above I run the test suite using: $ make slowtest EXTRA_HC_OPTS="-debug -with-rtsopts=-DS \ -with-rtsopts=-c +RTS -c -RTS" SKIPWAY='nonmoving nonmoving_thr' This enables compacting GC always in both GHC when building the test programs and when running the test programs, and also enables sanity checking when running the test programs. These set of flags are not compatible for all tests so there are some failures, but I got the same set of failures with this patch compared to GHC HEAD. - - - - - 818b3c38 by Lysxia at 2020-03-16T23:52:42-04:00 base: add strict IO functions: readFile', getContents', hGetContents' - - - - - 18a346a4 by Sylvain Henry at 2020-03-16T23:53:24-04:00 Modules: Core (#13009) Update submodule: haddock - - - - - 92327e3a by Ömer Sinan Ağacan at 2020-03-16T23:54:04-04:00 Update sanity checking for TSOs: - Remove an invalid assumption about GC checking what_next field. The GC doesn't care about what_next at all, if a TSO is reachable then all its pointers are followed (other than global_tso, which is only followed by compacting GC). - Remove checkSTACK in checkTSO: TSO stacks will be visited in checkHeapChain, or checkLargeObjects etc. - Add an assertion in checkTSO to check that the global_link field is sane. - Did some refactor to remove forward decls in checkGlobalTSOList and added braces around single-statement if statements. - - - - - e1aa4052 by PHO at 2020-03-17T07:36:09-04:00 Don't use non-portable operator "==" in configure.ac The test operator "==" is a Bash extension and produces a wrong result if /bin/sh is not Bash. - - - - - 89f034dd by Maximilian Tagher at 2020-03-17T07:36:48-04:00 Document the units of -ddump-timings Right now, in the output of -ddump-timings to a file, you can't tell what the units are: ``` CodeGen [TemplateTestImports]: alloc=22454880 time=14.597 ``` I believe bytes/milliseconds are the correct units, but confirmation would be appreciated. I'm basing it off of this snippet from `withTiming'`: ``` when (verbosity dflags >= 2 && prtimings == PrintTimings) $ liftIO $ logInfo dflags (defaultUserStyle dflags) (text "!!!" <+> what <> colon <+> text "finished in" <+> doublePrec 2 time <+> text "milliseconds" <> comma <+> text "allocated" <+> doublePrec 3 (realToFrac alloc / 1024 / 1024) <+> text "megabytes") ``` which implies time is in milliseconds, and allocations in bytes (which divided by 1024 would be KB, and again would be MB) - - - - - beffa147 by Simon Peyton Jones at 2020-03-17T07:37:25-04:00 Implement mapTyCo like foldTyCo This patch makes mapType use the successful idiom described in TyCoRep Note [Specialising foldType] I have not yet changed any functions to use mapType, though there may be some suitable candidates. This patch should be a no-op in terms of functionality but, because it inlines the mapper itself, I'm hoping that there may be some modest perf improvements. Metric Decrease: T5631 T5642 T3064 T9020 T14683 hie002 haddock.Cabal haddock.base haddock.compiler - - - - - 5800ebfe by Ömer Sinan Ağacan at 2020-03-17T07:38:08-04:00 Don't update ModDetails with CafInfos when opts are disabled This is consistent with the interface file behavior where we omit HsNoCafRefs annotations with -fomit-interface-pragmas (implied by -O0). ModDetails and ModIface are just different representations of the same thing, so they really need to be in sync. This patch does the right thing and does not need too much explanation, but here's an example of a problem not doing this causes in !2842: -- MyInteger.hs module MyInteger ( MyInteger (MyInteger) , ToMyInteger (toMyInteger) ) where newtype MyInteger = MyInteger Integer class ToMyInteger a where toMyInteger :: a -> MyInteger instance ToMyInteger Integer where toMyInteger = MyInteger {- . succ -} -- Main.hs module Main ( main ) where import MyInteger (MyInteger (MyInteger), toMyInteger) main :: IO () main = do let (MyInteger i) = (id . toMyInteger) (41 :: Integer) print i If I build this with -O0, without this fix, we generate a ModDetails with accurate LFInfo for toMyInteger (MyInteger.$fToMyIntegerInteger) which says that it's a LFReEntrant with arity 1. This means in the use site (Main) we tag the value: R3 = MyInteger.$fToMyIntegerInteger_closure + 1; R2 = GHC.Base.id_closure; R1 = GHC.Base.._closure; Sp = Sp - 16; call stg_ap_ppp_fast(R4, R3, R2, R1) args: 24, res: 0, upd: 24; Now we change the definition by uncommenting the `succ` part and it becomes a thunk: MyInteger.$fToMyIntegerInteger [InlPrag=INLINE (sat-args=0)] :: MyInteger.ToMyInteger GHC.Integer.Type.Integer [GblId[DFunId(nt)]] = {} \u [] $ctoMyInteger_rEA; and its LFInfo is now LFThunk. This change in LFInfo makes a difference in the use site: we can no longer tag it. But becuase the interface fingerprint does not change (because ModIface does not change) we don't rebuild Main and tag the thunk. (1.2% increase in allocations when building T12545 on armv7 because we generate more code without CafInfos) Metric Increase: T12545 - - - - - 5b632dad by Paavo at 2020-03-17T07:38:48-04:00 Add example for Data.Semigroup.diff - - - - - 4d85d68b by Paavo at 2020-03-17T07:38:48-04:00 Clean up - - - - - 75168d07 by Paavo at 2020-03-17T07:38:48-04:00 Make example collapsible - - - - - 53ff2cd0 by Richard Eisenberg at 2020-03-17T13:46:57+00:00 Fix #17021 by checking more return kinds All the details are in new Note [Datatype return kinds] in TcTyClsDecls. Test case: typecheck/should_fail/T17021{,b} typecheck/should_compile/T17021a Updates haddock submodule - - - - - 528df8ec by Sylvain Henry at 2020-03-18T10:06:43-04:00 Modules: Core operations (#13009) - - - - - 4e8a71c1 by Richard Eisenberg at 2020-03-18T10:07:19-04:00 Add release note about fix to #16502. We thought we needed to update the manual, but the fix for #16502 actually brings the implementation in line with the manual. So we just alert users of how to update their code. - - - - - 5cbf9934 by Andreas Klebinger at 2020-03-19T00:39:27-04:00 Update "GHC differences to the FFI Chapter" in user guide. The old entry had a heavy focus on how things had been. Which is not what I generally look for in a user guide. I also added a small section on behaviour of nested safe ffi calls. [skip-ci] - - - - - b03fd3bc by Sebastian Graf at 2020-03-19T00:40:06-04:00 PmCheck: Use ConLikeSet to model negative info In #17911, Simon recognised many warnings stemming from over-long list unions while coverage checking Cabal's `LicenseId` module. This patch introduces a new `PmAltConSet` type which uses a `UniqDSet` instead of an association list for `ConLike`s. For `PmLit`s, it will still use an assocation list, though, because a similar map data structure would entail a lot of busy work. Fixes #17911. - - - - - 64f20756 by Sylvain Henry at 2020-03-19T12:16:49-04:00 Refactoring: use Platform instead of DynFlags when possible Metric Decrease: ManyConstructors T12707 T13035 T1969 - - - - - cb1785d9 by Ömer Sinan Ağacan at 2020-03-19T12:16:54-04:00 FastString: fix eager reading of string ptr in hashStr This read causes NULL dereferencing when len is 0. Fixes #17909 In the reproducer in #17909 this bug is triggered as follows: - SimplOpt.dealWithStringLiteral is called with a single-char string ("=" in #17909) - tailFS gets called on the FastString of the single-char string. - tailFS checks the length of the string, which is 1, and calls mkFastStringByteString on the tail of the ByteString, which is an empty ByteString as the original ByteString has only one char. - ByteString's unsafeUseAsCStringLen returns (NULL, 0) for the empty ByteString, which is passed to mkFastStringWith. - mkFastStringWith gets hash of the NULL pointer via hashStr, which fails on empty strings because of this bug. - - - - - 73a7383e by Richard Eisenberg at 2020-03-20T20:42:56-04:00 Simplify treatment of heterogeneous equality Previously, if we had a [W] (a :: k1) ~ (rhs :: k2), we would spit out a [D] k1 ~ k2 and part the W as irreducible, hoping for a unification. But we needn't do this. Instead, we now spit out a [W] co :: k2 ~ k1 and then use co to cast the rhs of the original Wanted. This means that we retain the connection between the spat-out constraint and the original. The problem with this new approach is that we cannot use the casted equality for substitution; it's too like wanteds-rewriting- wanteds. So, we forbid CTyEqCans that mention coercion holes. All the details are in Note [Equalities with incompatible kinds] in TcCanonical. There are a few knock-on effects, documented where they occur. While debugging an error in this patch, Simon and I ran into infelicities in how patterns and matches are printed; we made small improvements. This patch includes mitigations for #17828, which causes spurious pattern-match warnings. When #17828 is fixed, these lines should be removed. - - - - - faa36e5b by Sylvain Henry at 2020-03-20T20:43:41-04:00 Hadrian: ignore in-tree GMP objects with ``--lint`` - - - - - 9a96ff6b by Richard Eisenberg at 2020-03-20T20:44:17-04:00 Update core spec to reflect changes to Core. Key changes: * Adds a new rule for forall-coercions over coercion variables, which was implemented but conspicuously missing from the spec. * Adds treatment for FunCo. * Adds treatment for ForAllTy over coercion variables. * Improves commentary (including restoring a Note lost in 03d4852658e1b7407abb4da84b1b03bfa6f6db3b) in the source. No changes to running code. - - - - - 7e0451c6 by Sergej Jaskiewicz at 2020-03-20T20:44:55-04:00 Fix event message in withTiming' This typo caused generating 'end' events without the corresponding 'begin' events. - - - - - 1542a626 by Ben Gamari at 2020-03-22T22:37:47-04:00 fs.h: Add missing declarations on Windows - - - - - 3bcf2ccd by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump process submodule Avoids redundant case alternative warning. - - - - - 3b363ef9 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Normalize slashes in ghc-api annotations output Enable `normalise_slashes` on `annotations`, `listcomps`, and `parseTree` to fix Windows failures. - - - - - 25fc9429 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - 7f58ec6d by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Fix TOP of T17786 - - - - - aadcd909 by GHC GitLab CI at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - dc1eb10d by GHC GitLab CI at 2020-03-22T22:37:47-04:00 hadrian: Fix executable extension passed to testsuite driver - - - - - 58f62e2c by GHC GitLab CI at 2020-03-22T22:37:47-04:00 gitlab-ci: Require that Windows-hadrian job passes - - - - - 8dd2415d by Ben Gamari at 2020-03-22T22:37:47-04:00 hadrian: Eliminate redundant .exe from GHC path Previously we were invoking: bash -c "c:/GitLabRunner/builds/eEQrxK4p/0/ghc/ghc/toolchain/bin/ghc.exe.exe testsuite/mk/ghc-config.hs -o _build/test/bin/ghc-config.exe" - - - - - 373621f6 by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump hsc2hs submodule - - - - - abc02b40 by Hécate at 2020-03-22T22:38:33-04:00 Annotate the non-total function in Data.Foldable as such - - - - - 19f12557 by Josef Svenningsson at 2020-03-23T14:05:33-04:00 Fix ApplicativeDo regression #17835 A previous fix for #15344 made sure that monadic 'fail' is used properly when translating ApplicativeDo. However, it didn't properly account for when a 'fail' will be inserted which resulted in some programs failing with a type error. - - - - - 2643ba46 by Paavo at 2020-03-24T08:31:32-04:00 Add example and doc for Arg (Fixes #17153) - - - - - 703221f4 by Roland Senn at 2020-03-25T14:45:04-04:00 Use export list of Main module in function TcRnDriver.hs:check_main (Fix #16453) - Provide the export list of the `Main` module as parameter to the `compiler/typecheck/TcRnDriver.hs:check_main` function. - Instead of `lookupOccRn_maybe` call the function `lookupInfoOccRn`. It returns the list `mains_all` of all the main functions in scope. - Select from this list `mains_all` all `main` functions that are in the export list of the `Main` module. - If this new list contains exactly one single `main` function, then typechecking continues. - Otherwise issue an appropriate error message. - - - - - 3e27205a by Sebastian Graf at 2020-03-25T14:45:40-04:00 Remove -fkill-absence and -fkill-one-shot flags They seem to be a benchmarking vestige of the Cardinality paper and probably shouldn't have been merged to HEAD in the first place. - - - - - 262e42aa by Peter Trommler at 2020-03-25T22:41:39-04:00 Do not panic on linker errors - - - - - 0de03cd7 by Sylvain Henry at 2020-03-25T22:42:02-04:00 DynFlags refactoring III Use Platform instead of DynFlags when possible: * `tARGET_MIN_INT` et al. replaced with `platformMinInt` et al. * no more DynFlags in PreRules: added a new `RuleOpts` datatype * don't use `wORD_SIZE` in the compiler * make `wordAlignment` use `Platform` * make `dOUBLE_SIZE` a constant Metric Decrease: T13035 T1969 - - - - - 7a04920b by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: fix a typo in liftA doc This change removes an extra '|' that should not be rendered in the liftA documentation. Tracking: #17929 - - - - - 1c5a15f7 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add Control.Applicative optional example This change adds an optional example. Tracking: #17929 - - - - - 6d172e63 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add markup around Except - - - - - eb2162c8 by John Ericson at 2020-03-26T12:37:08-04:00 Remove unused `ghciTablesNextToCode` from compiler proper - - - - - f51efc4b by Joachim Breitner at 2020-03-26T12:37:09-04:00 Prepare to use run-time tablesNextToCode in compiler exclusively Factor out CPP as much as possible to prepare for runtime determinattion. Progress towards #15548 - - - - - 1c446220 by Joachim Breitner at 2020-03-26T12:37:09-04:00 Use run-time tablesNextToCode in compiler exclusively (#15548) Summary: - There is no more use of the TABLES_NEXT_TO_CODE CPP macro in `compiler/`. GHCI_TABLES_NEXT_TO_CODE is also removed entirely. The field within `PlatformMisc` within `DynFlags` is used instead. - The field is still not exposed as a CLI flag. We might consider some way to ensure the right RTS / libraries are used before doing that. Original reviewers: Original subscribers: TerrorJack, rwbarton, carter Original Differential Revision: https://phabricator.haskell.org/D5082 - - - - - 1941ef4f by Sylvain Henry at 2020-03-29T17:28:51-04:00 Modules: Types (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - 1c7c6f1a by Sylvain Henry at 2020-03-29T17:28:51-04:00 Remove GHC.Types.Unique.Map module This module isn't used anywhere in GHC. - - - - - f1a6c73d by Sylvain Henry at 2020-03-29T17:28:51-04:00 Merge GHC.Types.CostCentre.Init into GHC.Driver.CodeOutput - - - - - 54250f2d by Simon Peyton Jones at 2020-03-29T17:29:30-04:00 Demand analysis: simplify the demand for a RHS Ticket #17932 showed that we were using a stupid demand for the RHS of a let-binding, when the result is a product. This was the result of a "fix" in 2013, which (happily) turns out to no longer be necessary. So I just deleted the code, which simplifies the demand analyser, and fixes #17932. That in turn uncovered that the anticipation of worker/wrapper in CPR analysis was inaccurate, hence the logic that decides whether to unbox an argument in WW was extracted into a function `wantToUnbox`, now consulted by CPR analysis. I tried nofib, and got 0.0% perf changes. All this came up when messing about with !2873 (ticket #17917), but is idependent of it. Unfortunately, this patch regresses #4267 and realised that it is now blocked on #16335. - - - - - 03060b2f by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 on Windows Fixes line ending normalization issue. - - - - - 1f7995ba by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 Fix missing quoting and expected exit code. - - - - - ef9c608e by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Mark T12971 as broken on Windows Due to #17945. - - - - - e54500c1 by Sylvain Henry at 2020-03-29T17:30:47-04:00 Store ComponentId details As far as GHC is concerned, installed package components ("units") are identified by an opaque ComponentId string provided by Cabal. But we don't want to display it to users (as it contains a hash) so GHC queries the database to retrieve some infos about the original source package (name, version, component name). This patch caches these infos in the ComponentId itself so that we don't need to provide DynFlags (which contains installed package informations) to print a ComponentId. In the future we want GHC to support several independent package states (e.g. for plugins and for target code), hence we need to avoid implicitly querying a single global package state. - - - - - 7e7cb714 by Marius Bakke at 2020-03-29T17:31:27-04:00 testsuite: Remove test that dlopens a PIE object. glibc 2.30 disallowed dlopening PIE objects, so just remove the test. Fixes #17952. - - - - - 6c8f80d8 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Correct haddocks for testBit in Data.Bits It conflated the nth bit with the bit at offset n. Now we instead give the definition in terms of `bit and `.&.` on top of clearer phrasing. - - - - - c916f190 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Apply suggestion to libraries/base/Data/Bits.hs - - - - - 64bf7f51 by Ben Gamari at 2020-03-29T17:32:41-04:00 gitlab-ci: Add FreeBSD release job - - - - - a0d8e92e by Ryan Scott at 2020-03-29T17:33:20-04:00 Run checkNewDataCon before constraint-solving newtype constructors Within `checkValidDataCon`, we used to run `checkValidType` on the argument types of a newtype constructor before running `checkNewDataCon`, which ensures that the user does not attempt non-sensical things such as newtypes with multiple arguments or constraints. This works out in most situations, but this falls over on a corner case revealed in #17955: ```hs newtype T = Coercible () T => T () ``` `checkValidType`, among other things, peforms an ambiguity check on the context of a data constructor, and that it turn invokes the constraint solver. It turns out that there is a special case in the constraint solver for representational equalities (read: `Coercible` constraints) that causes newtypes to be unwrapped (see `Note [Unwrap newtypes first]` in `TcCanonical`). This special case does not know how to cope with an ill formed newtype like `T`, so it ends up panicking. The solution is surprisingly simple: just invoke `checkNewDataCon` before `checkValidType` to ensure that the illicit newtype constructor context is detected before the constraint solver can run amok with it. Fixes #17955. - - - - - 45eb9d8c by Krzysztof Gogolewski at 2020-03-29T17:33:59-04:00 Minor cleanup - Simplify mkBuildExpr, the function newTyVars was called only on a one-element list. - TTG: use noExtCon in more places. This is more future-proof. - In zonkExpr, panic instead of printing a warning. - - - - - f024b6e3 by Sylvain Henry at 2020-03-30T12:48:39+02:00 Expect T4267 to pass Since 54250f2d8de910b094070c1b48f086030df634b1 we expected T4267 to fail, but it passes on CI. - - - - - 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.0.0 This requires bumping the `exceptions` and `text` submodules to bring in commits that bump their respective upper version bounds on `template-haskell`. Fixes #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - ffd7eef2 by Takenobu Tani at 2020-04-22T23:09:50-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - e8a5d81b by Jonathan DK Gibbons at 2020-04-22T23:10:28-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - dcb7fe5a by John Ericson at 2020-04-22T23:10:28-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - cde23cd4 by John Ericson at 2020-04-22T23:10:28-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - 72cb6bcc by John Ericson at 2020-04-22T23:10:28-04:00 Generalize type of `matchCanFail` - - - - - 401f7bb3 by John Ericson at 2020-04-22T23:10:28-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 6c9fae23 by Alexis King at 2020-04-22T23:11:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 48b8951e by Roland Senn at 2020-04-22T23:11:51-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 34a45ee6 by Peter Trommler at 2020-04-22T23:12:27-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - ffde2348 by Simon Peyton Jones at 2020-04-22T23:13:06-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 6f84aca3 by Ben Gamari at 2020-04-22T23:13:43-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - c29f0fa6 by Andreas Klebinger at 2020-04-22T23:14:21-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 4b4a8b60 by Ben Gamari at 2020-04-22T23:14:57-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 831b6642 by Moritz Angermann at 2020-04-22T23:15:33-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - c409961a by Ryan Scott at 2020-04-22T23:16:12-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 125aa2b8 by Ömer Sinan Ağacan at 2020-04-22T23:16:51-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - 8ea37b01 by Sylvain Henry at 2020-04-22T23:17:34-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - cd8409c2 by Ryan Scott at 2020-04-23T11:39:24-04:00 Create di_scoped_tvs for associated data family instances properly See `Note [Associated data family instances and di_scoped_tvs]` in `GHC.Tc.TyCl.Instance`, which explains all of the moving parts. Fixes #18055. - - - - - 339e8ece by Ben Gamari at 2020-04-23T11:40:02-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 5946c85a by Ben Gamari at 2020-04-23T11:40:38-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - c42754d5 by John Ericson at 2020-04-23T18:32:43-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 72da0c29 by mniip at 2020-04-23T18:33:21-04:00 Add :doc to GHC.Prim - - - - - 2c23e2e3 by mniip at 2020-04-23T18:33:21-04:00 Include docs for non-primop entries in primops.txt as well - - - - - 0ac29c88 by mniip at 2020-04-23T18:33:21-04:00 GHC.Prim docs: note and test - - - - - b0fbfc75 by John Ericson at 2020-04-24T12:07:14-04:00 Switch order on `GhcMake.IsBoot` In !1798 we were requested to replace many `Bool`s with this data type. But those bools had `False` meaning `NotBoot`, so the `Ord` instance would be flipped if we use this data-type as-is. Since the planned formally-`Bool` occurrences vastly outnumber the current occurrences, we figured it would be better to conform the `Ord` instance to how the `Bool` is used now, fixing any issues, rather than fix them currently with the bigger refactor later in !1798. That way, !1798 can be a "pure" refactor with no behavioral changes. - - - - - af332442 by Sylvain Henry at 2020-04-26T13:55:14-04:00 Modules: Utils and Data (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - cd4434c8 by Sylvain Henry at 2020-04-26T13:55:16-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 22bf5c73 by Ömer Sinan Ağacan at 2020-04-26T13:55:22-04:00 Tweak includes in non-moving GC headers We don't use hash tables in non-moving GC so remove the includes. This breaks Compact.c as existing includes no longer include Hash.h, so include Hash.h explicitly in Compact.c. - - - - - 99823ed2 by Sylvain Henry at 2020-04-27T20:24:46-04:00 TH: fix Show/Eq/Ord instances for Bytes (#16457) We shouldn't compare pointer values but the actual bytes. - - - - - c62271a2 by Alp Mestanogullari at 2020-04-27T20:25:33-04:00 hadrian: always capture both stdout and stderr when running a builder fails The idea being that when a builder('s command) fails, we quite likely want to have all the information available to figure out why. Depending on the builder _and_ the particular problem, the useful bits of information can be printed on stdout or stderr. We accomplish this by defining a simple wrapper for Shake's `cmd` function, that just _always_ captures both streams in case the command returns a non-zero exit code, and by using this wrapper everywhere in `hadrian/src/Builder.hs`. Fixes #18089. - - - - - 4b9764db by Ryan Scott at 2020-04-28T15:40:04-04:00 Define a Quote IO instance Fixes #18103. - - - - - 518a63d4 by Ryan Scott at 2020-04-28T15:40:42-04:00 Make boxed 1-tuples have known keys Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. - - - - - 2cfc4ab9 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Document backpack fields in DynFlags - - - - - 10a2ba90 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 69562e34 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 9e2c8e0e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - ea717aa4 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 10d15f1e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 8bfb0219 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - 71484b09 by Alexis King at 2020-04-30T01:57:35-04:00 Allow block arguments in arrow control operators Arrow control operators have their own entries in the grammar, so they did not cooperate with BlockArguments. This was just a minor oversight, so this patch adjusts the grammar to add the desired behavior. fixes #18050 - - - - - a48cd2a0 by Alexis King at 2020-04-30T01:57:35-04:00 Allow LambdaCase to be used as a command in proc notation - - - - - f4d3773c by Alexis King at 2020-04-30T01:57:35-04:00 Document BlockArguments/LambdaCase support in arrow notation - - - - - 5bdfdd13 by Simon Peyton Jones at 2020-04-30T01:58:15-04:00 Add tests for #17873 - - - - - 19b701c2 by Simon Peyton Jones at 2020-04-30T07:30:13-04:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - 014ef4a3 by Matthew Pickering at 2020-04-30T07:30:50-04:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 2aa67611 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - 54dad3cf by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - 99ff8145 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 05b0a9fd by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 Remove OneShotInfo field of LFReEntrant, document OneShotInfo The field is only used in withNewTickyCounterFun and it's easier to directly pass a parameter for one-shot info to withNewTickyCounterFun instead of passing it via LFReEntrant. This also makes !2842 simpler. Other changes: - New Note (by SPJ) [OneShotInfo overview] added. - Arity argument of thunkCode removed as it's always 0. - - - - - a43620c6 by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 GHC.StgToCmm.Ticky: remove a few unused stuff - - - - - 780de9e1 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Use platform in Iface Binary - - - - - f8386c7b by Sylvain Henry at 2020-05-01T10:37:39-04:00 Refactor PprDebug handling If `-dppr-debug` is set, then PprUser and PprDump styles are silently replaced with PprDebug style. This was done in `mkUserStyle` and `mkDumpStyle` smart constructors. As a consequence they needed a DynFlags parameter. Now we keep the original PprUser and PprDump styles until they are used to create an `SDocContext`. I.e. the substitution is only performed in `initSDocContext`. - - - - - b3df9e78 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Remove PprStyle param of logging actions Use `withPprStyle` instead to apply a specific style to a SDoc. - - - - - de9fc995 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Fully remove PprDebug PprDebug was a pain to deal with consistently as it is implied by `-dppr-debug` but it isn't really a PprStyle. We remove it completely and query the appropriate SDoc flag instead (`sdocPprDebug`) via helpers (`getPprDebug` and its friends). - - - - - 8b51fcbd by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Only call checkSingle if we would report warnings - - - - - fd7ea0fe by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 7bfe9ac5 by Ben Gamari at 2020-05-03T04:41:33-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. - - - - - c560dd07 by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Move eventlog documentation users guide - - - - - 02543d5e by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Add documentation for non-moving GC events - - - - - b465dd45 by Alexis King at 2020-05-03T04:42:12-04:00 Flatten nested casts in the simple optimizer Normally, we aren’t supposed to generated any nested casts, since mkCast takes care to flatten them, but the simple optimizer didn’t use mkCast, so they could show up after inlining. This isn’t really a problem, since the simplifier will clean them up immediately anyway, but it can clutter the -ddump-ds output, and it’s an extremely easy fix. closes #18112 - - - - - 8bdc03d6 by Simon Peyton Jones at 2020-05-04T01:56:59-04:00 Don't return a panic in tcNestedSplice In GHC.Tc.Gen.Splice.tcNestedSplice we were returning a typechecked expression of "panic". That is usually OK, because the result is discarded. But it happens that tcApp now looks at the typechecked expression, trivially, to ask if it is tagToEnum. So being bottom is bad. Moreover a debug-trace might print it out. So better to return a civilised expression, even though it is usually discarded. - - - - - 0bf640b1 by Baldur Blöndal at 2020-05-04T01:57:36-04:00 Don't require parentheses around via type (`-XDerivingVia'). Fixes #18130". - - - - - 30272412 by Artem Pelenitsyn at 2020-05-04T13:19:59-04:00 Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) - - - - - b9f7c08f by jneira at 2020-05-04T13:20:37-04:00 Remove unused hs-boot file - - - - - 1d8f80cd by Sylvain Henry at 2020-05-05T03:22:46-04:00 Remove references to -package-key * remove references to `-package-key` which has been removed in 2016 (240ddd7c39536776e955e881d709bbb039b48513) * remove support for `-this-package-key` which has been deprecated at the same time - - - - - 7bc3a65b by Sylvain Henry at 2020-05-05T03:23:31-04:00 Remove SpecConstrAnnotation (#13681) This has been deprecated since 2013. Use GHC.Types.SPEC instead. Make GHC.Exts "not-home" for haddock Metric Decrease: haddock.base - - - - - 3c862f63 by DenisFrezzato at 2020-05-05T03:24:15-04:00 Fix Haskell98 short description in documentation - - - - - 2420c555 by Ryan Scott at 2020-05-05T03:24:53-04:00 Add regression tests for #16244, #16245, #16758 Commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70 ended up fixing quite a few bugs: * This commit fixes #16244 completely. A regression test has been added. * This commit fixes one program from #16245. (The program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211369 still panics, and the program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211400 still loops infinitely.) A regression test has been added for this program. * This commit fixes #16758. Accordingly, this patch removes the `expect_broken` label from the `T16758` test case, moves it from `should_compile` to `should_fail` (as it should produce an error message), and checks in the expected stderr. - - - - - 40c71c2c by Sylvain Henry at 2020-05-05T03:25:31-04:00 Fix colorized error messages (#18128) In b3df9e780fb2f5658412c644849cd0f1e6f50331 I broke colorized messages by using "dump" style instead of "user" style. This commits fixes it. - - - - - 7ab6ab09 by Richard Eisenberg at 2020-05-06T04:39:32-04:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG ------------------------- - - - - - 420b957d by Ben Gamari at 2020-05-06T04:40:08-04:00 rts: Zero block flags with -DZ Block flags are very useful for determining the state of a block. However, some block allocator users don't touch them, leading to misleading values. Ensure that we zero then when zero-on-gc is set. This is safe and makes the flags more useful during debugging. - - - - - 740b3b8d by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix incorrect failed_to_evac value during deadlock gc Previously we would incorrectly set the failed_to_evac flag if we evacuated a value due to a deadlock GC. This would cause us to mark more things as dirty than strictly necessary. It also turned up a nasty but which I will fix next. - - - - - b2d72c75 by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - 9f3e6884 by Zubin Duggal at 2020-05-06T04:41:08-04:00 Allow atomic update of NameCache in readHieFile The situation arises in ghcide where multiple different threads may need to update the name cache, therefore with the older interface it could happen that you start reading a hie file with name cache A and produce name cache A + B, but another thread in the meantime updated the namecache to A + C. Therefore if you write the new namecache you will lose the A' updates from the second thread. Updates haddock submodule - - - - - edec6a6c by Ryan Scott at 2020-05-06T04:41:57-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _)`. Fixes #18127. - - - - - a95e7fe0 by Ömer Sinan Ağacan at 2020-05-06T04:42:39-04:00 ELF linker: increment curSymbol after filling in fields of current entry The bug was introduced in a8b7cef4d45 which added a field to the `symbols` array elements and then updated this code incorrectly: - oc->symbols[curSymbol++] = nm; + oc->symbols[curSymbol++].name = nm; + oc->symbols[curSymbol].addr = symbol->addr; - - - - - cab1871a by Sylvain Henry at 2020-05-06T04:43:21-04:00 Move LeadingUnderscore into Platform (#17957) Avoid direct use of DynFlags to know if symbols must be prefixed by an underscore. - - - - - 94e7c563 by Sylvain Henry at 2020-05-06T04:43:21-04:00 Don't use DynFlags in showLinkerState (#17957) - - - - - 9afd9251 by Ryan Scott at 2020-05-06T04:43:58-04:00 Refactoring: Use bindSigTyVarsFV in rnMethodBinds `rnMethodBinds` was explicitly using `xoptM` to determine if `ScopedTypeVariables` is enabled before bringing type variables bound by the class/instance header into scope. However, this `xoptM` logic is already performed by the `bindSigTyVarsFV` function. This patch uses `bindSigTyVarsFV` in `rnMethodBinds` to reduce the number of places where we need to consult if `ScopedTypeVariables` is on. This is purely refactoring, and there should be no user-visible change in behavior. - - - - - 6f6d72b2 by Brian Foley at 2020-05-08T15:29:25-04:00 Remove further dead code found by a simple Python script. Avoid removing some functions that are part of an API even though they're not used in-tree at the moment. - - - - - 78bf8bf9 by Julien Debon at 2020-05-08T15:29:28-04:00 Add doc examples for Bifoldable See #17929 - - - - - 66f0a847 by Julien Debon at 2020-05-08T15:29:29-04:00 doc (Bitraversable): Add examples to Bitraversable * Add examples to Data.Bitraversable * Fix formatting for (,) in Bitraversable and Bifoldable * Fix mistake on bimapAccumR documentation See #17929 - - - - - 9749fe12 by Baldur Blöndal at 2020-05-08T15:29:32-04:00 Specify kind variables for inferred kinds in base. - - - - - 4e9aef9e by John Ericson at 2020-05-08T15:29:36-04:00 HsSigWcTypeScoping: Pull in documentation from stray location - - - - - f4d5c6df by John Ericson at 2020-05-08T15:29:36-04:00 Rename local `real_fvs` to `implicit_vs` It doesn't make sense to call the "free" variables we are about to implicitly bind the real ones. - - - - - 20570b4b by John Ericson at 2020-05-08T15:29:36-04:00 A few tiny style nits with renaming - Use case rather than guards that repeatedly scrutenize same thing. - No need for view pattern when `L` is fine. - Use type synnonym to convey the intent like elsewhere. - - - - - 09ac8de5 by John Ericson at 2020-05-08T15:29:36-04:00 Add `forAllOrNothing` function with note - - - - - bb35c0e5 by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Document lawlessness of Ap's Num instance - - - - - cdd229ff by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply suggestion to libraries/base/Data/Monoid.hs - - - - - 926d2aab by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply more suggestions from Simon Jakobi - - - - - 7a763cff by Adam Gundry at 2020-05-08T15:29:41-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. - - - - - 88e3c815 by Simon Peyton Jones at 2020-05-08T15:29:41-04:00 Fix specialisation for DFuns When specialising a DFun we must take care to saturate the unfolding. See Note [Specialising DFuns] in Specialise. Fixes #18120 - - - - - 86c77b36 by Greg Steuck at 2020-05-08T15:29:45-04:00 Remove unused SEGMENT_PROT_RWX It's been unused for a year and is problematic on any OS which requires W^X for security. - - - - - 9d97f4b5 by nineonine at 2020-05-08T15:30:03-04:00 Add test for #16167 - - - - - aa318338 by Ryan Scott at 2020-05-08T15:30:04-04:00 Bump exceptions submodule so that dist-boot is .gitignore'd `exceptions` is a stage-0 boot library as of commit 30272412fa437ab8e7a8035db94a278e10513413, which means that building `exceptions` in a GHC tree will generate a `dist-boot` directory. However, this directory was not specified in `exceptions`' `.gitignore` file, which causes it to dirty up the current `git` working directory. Accordingly, this bumps the `exceptions` submodule to commit ghc/packages/exceptions at 23c0b8a50d7592af37ca09beeec16b93080df98f, which adds `dist-boot` to the `.gitignore` file. - - - - - ea86360f by Ömer Sinan Ağacan at 2020-05-08T15:30:30-04:00 Linker.c: initialize n_symbols of ObjectCode with other fields - - - - - 951c1fb0 by Sylvain Henry at 2020-05-09T21:46:38-04:00 Fix unboxed-sums GC ptr-slot rubbish value (#17791) This patch allows boot libraries to use unboxed sums without implicitly depending on `base` package because of `absentSumFieldError`. See updated Note [aBSENT_SUM_FIELD_ERROR_ID] in GHC.Core.Make - - - - - b352d63c by Ben Gamari at 2020-05-09T21:47:14-04:00 rts: Make non-existent linker search path merely a warning As noted in #18105, previously this resulted in a rather intrusive error message. This is in contrast to the general expectation that search paths are merely places to look, not places that must exist. Fixes #18105. - - - - - cf4f1e2f by Ben Gamari at 2020-05-13T02:02:33-04:00 rts/CNF: Fix fixup comparison function Previously we would implicitly convert the difference between two words to an int, resulting in an integer overflow on 64-bit machines. Fixes #16992 - - - - - a03da9bf by Ömer Sinan Ağacan at 2020-05-13T02:03:16-04:00 Pack some of IdInfo fields into a bit field This reduces residency of compiler quite a bit on some programs. Example stats when building T10370: Before: 2,871,242,832 bytes allocated in the heap 4,693,328,008 bytes copied during GC 33,941,448 bytes maximum residency (276 sample(s)) 375,976 bytes maximum slop 83 MiB total memory in use (0 MB lost due to fragmentation) After: 2,858,897,344 bytes allocated in the heap 4,629,255,440 bytes copied during GC 32,616,624 bytes maximum residency (278 sample(s)) 314,400 bytes maximum slop 80 MiB total memory in use (0 MB lost due to fragmentation) So -3.9% residency, -1.3% bytes copied and -0.4% allocations. Fixes #17497 Metric Decrease: T9233 T9675 - - - - - 670c3e5c by Ben Gamari at 2020-05-13T02:03:54-04:00 get-win32-tarballs: Fix base URL Revert a change previously made for testing purposes. - - - - - 8ad8dc41 by Ben Gamari at 2020-05-13T02:03:54-04:00 get-win32-tarballs: Improve diagnostics output - - - - - 8c0740b7 by Simon Jakobi at 2020-05-13T02:04:33-04:00 docs: Add examples for Data.Semigroup.Arg{Min,Max} Context: #17153 - - - - - cb22348f by Ben Gamari at 2020-05-13T02:05:11-04:00 Add few cleanups of the CAF logic Give the NameSet of non-CAFfy names a proper newtype to distinguish it from all of the other NameSets floating about. - - - - - 90e38b81 by Emeka Nkurumeh at 2020-05-13T02:05:51-04:00 fix printf warning when using with ghc with clang on mingw - - - - - 86d8ac22 by Sebastian Graf at 2020-05-13T02:06:29-04:00 CprAnal: Don't attach CPR sigs to expandable bindings (#18154) Instead, look through expandable unfoldings in `cprTransform`. See the new Note [CPR for expandable unfoldings]: ``` Long static data structures (whether top-level or not) like xs = x1 : xs1 xs1 = x2 : xs2 xs2 = x3 : xs3 should not get CPR signatures, because they * Never get WW'd, so their CPR signature should be irrelevant after analysis (in fact the signature might even be harmful for that reason) * Would need to be inlined/expanded to see their constructed product * Recording CPR on them blows up interface file sizes and is redundant with their unfolding. In case of Nested CPR, this blow-up can be quadratic! But we can't just stop giving DataCon application bindings the CPR property, for example fac 0 = 1 fac n = n * fac (n-1) fac certainly has the CPR property and should be WW'd! But FloatOut will transform the first clause to lvl = 1 fac 0 = lvl If lvl doesn't have the CPR property, fac won't either. But lvl doesn't have a CPR signature to extrapolate into a CPR transformer ('cprTransform'). So instead we keep on cprAnal'ing through *expandable* unfoldings for these arity 0 bindings via 'cprExpandUnfolding_maybe'. In practice, GHC generates a lot of (nested) TyCon and KindRep bindings, one for each data declaration. It's wasteful to attach CPR signatures to each of them (and intractable in case of Nested CPR). ``` Fixes #18154. - - - - - e34bf656 by Ben Gamari at 2020-05-13T02:07:08-04:00 users-guide: Add discussion of shared object naming Fixes #18074. - - - - - 5d0f2445 by Ben Gamari at 2020-05-13T02:07:47-04:00 testsuite: Print sign of performance changes Executes the minor formatting change in the tabulated performance changes suggested in #18135. - - - - - 9e4b981f by Ben Gamari at 2020-05-13T02:08:24-04:00 testsuite: Add testcase for #18129 - - - - - 266310c3 by Ivan-Yudin at 2020-05-13T02:09:03-04:00 doc: Reformulate the opening paragraph of Ch. 4 in User's guide Removes mentioning of Hugs (it is not helpful for new users anymore). Changes the wording for the rest of the paragraph. Fixes #18132. - - - - - 55e35c0b by Baldur Blöndal at 2020-05-13T20:02:48-04:00 Predicate, Equivalence derive via `.. -> a -> All' - - - - - d7e0b57f by Alp Mestanogullari at 2020-05-13T20:03:30-04:00 hadrian: add a --freeze2 option to freeze stage 1 and 2 - - - - - d880d6b2 by Artem Pelenitsyn at 2020-05-13T20:04:11-04:00 Don't reload environment files on every setSessionDynFlags Makes `interpretPackageEnv` (which loads envirinment files) a part of `parseDynamicFlags` (parsing command-line arguments, which is typically done once) instead of `setSessionDynFlags` (which is typically called several times). Making several (transitive) calls to `interpretPackageEnv`, as before, caused #18125 #16318, which should be fixed now. - - - - - 102cfd67 by Ryan Scott at 2020-05-13T20:04:46-04:00 Factor out HsPatSigType for pat sigs/RULE term sigs (#16762) This implements chunks (2) and (3) of https://gitlab.haskell.org/ghc/ghc/issues/16762#note_270170. Namely, it introduces a dedicated `HsPatSigType` AST type, which represents the types that can appear in pattern signatures and term-level `RULE` binders. Previously, these were represented with `LHsSigWcType`. Although `LHsSigWcType` is isomorphic to `HsPatSigType`, the intended semantics of the two types are slightly different, as evidenced by the fact that they have different code paths in the renamer and typechecker. See also the new `Note [Pattern signature binders and scoping]` in `GHC.Hs.Types`. - - - - - b17574f7 by Hécate at 2020-05-13T20:05:28-04:00 fix(documentation): Fix the RST links to GHC.Prim - - - - - df021fb1 by Baldur Blöndal at 2020-05-13T20:06:06-04:00 Document (->) using inferred quantification for its runtime representations. Fixes #18142. - - - - - 1a93ea57 by Takenobu Tani at 2020-05-13T20:06:54-04:00 Tweak man page for ghc command This commit updates the ghc command's man page as followings: * Enable `man_show_urls` to show URL addresses in the `DESCRIPTION` section of ghc.rst, because sphinx currently removes hyperlinks for man pages. * Add a `SEE ALSO` section to point to the GHC homepage - - - - - a951e1ba by Takenobu Tani at 2020-05-13T20:07:37-04:00 GHCi: Add link to the user's guide in help message This commit adds a link to the user's guide in ghci's `:help` message. Newcomers could easily reach to details of ghci. - - - - - 404581ea by Jeff Happily at 2020-05-13T20:08:15-04:00 Handle single unused import - - - - - 1c999e5d by Ben Gamari at 2020-05-13T20:09:07-04:00 Ensure that printMinimalImports closes handle Fixes #18166. - - - - - c9f5a8f4 by Ben Gamari at 2020-05-13T20:09:51-04:00 hadrian: Tell testsuite driver about LLVM availability This reflects the logic present in the Make build system into Hadrian. Fixes #18167. - - - - - c05c0659 by Simon Jakobi at 2020-05-14T03:31:21-04:00 Improve some folds over Uniq[D]FM * Replace some non-deterministic lazy folds with strict folds. * Replace some O(n log n) folds in deterministic order with O(n) non-deterministic folds. * Replace some folds with set-operations on the underlying IntMaps. This reduces max residency when compiling `nofib/spectral/simple/Main.hs` with -O0 by about 1%. Maximum residency when compiling Cabal also seems reduced on the order of 3-9%. - - - - - 477f13bb by Simon Jakobi at 2020-05-14T03:31:58-04:00 Use Data.IntMap.disjoint Data.IntMap gained a dedicated `disjoint` function in containers-0.6.2.1. This patch applies this function where appropriate in hopes of modest compiler performance improvements. Closes #16806. - - - - - e9c0110c by Ben Gamari at 2020-05-14T12:25:53-04:00 IdInfo: Add reference to bitfield-packing ticket - - - - - aab6735e by Ben Gamari at 2020-05-14T12:52:57-04:00 nonmoving: Optimise the write barrier - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/linters/check-cpp.py - CODEOWNERS - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - compiler/prelude/PrelNames.hs-boot → compiler/GHC/Builtin/Names.hs-boot - compiler/prelude/THNames.hs → compiler/GHC/Builtin/Names/TH.hs - compiler/prelude/PrimOp.hs → compiler/GHC/Builtin/PrimOps.hs - + compiler/GHC/Builtin/PrimOps.hs-boot - compiler/prelude/TysWiredIn.hs → compiler/GHC/Builtin/Types.hs - compiler/prelude/TysWiredIn.hs-boot → compiler/GHC/Builtin/Types.hs-boot - compiler/typecheck/TcTypeNats.hs → compiler/GHC/Builtin/Types/Literals.hs - compiler/prelude/TysPrim.hs → compiler/GHC/Builtin/Types/Prim.hs - compiler/prelude/KnownUniques.hs → compiler/GHC/Builtin/Uniques.hs - compiler/prelude/KnownUniques.hs-boot → compiler/GHC/Builtin/Uniques.hs-boot - compiler/prelude/PrelInfo.hs → compiler/GHC/Builtin/Utils.hs - compiler/prelude/primops.txt.pp → compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.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/BlockId.hs-boot - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2fa79119570b358a4db61446396889b8260d7957...aab6735ed2840b96e284e75234bf65a34d7c1288 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2fa79119570b358a4db61446396889b8260d7957...aab6735ed2840b96e284e75234bf65a34d7c1288 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 16:59:08 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 14 May 2020 12:59:08 -0400 Subject: [Git][ghc/ghc][wip/backports] 15 commits: hadrian: Refactor gmp arguments Message-ID: <5ebd78dc2919e_6167122db45c11305715@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/backports at Glasgow Haskell Compiler / GHC Commits: a077ea75 by Ben Gamari at 2020-05-14T12:58:58-04:00 hadrian: Refactor gmp arguments Move the gmp configuration to its own binding. - - - - - 6e1bfe5e by Ben Gamari at 2020-05-14T12:59:01-04:00 hadrian: Tell Cabal about integer-gmp library location - - - - - ff430471 by Ben Gamari at 2020-05-14T12:59:01-04:00 rts: Zero block flags with -DZ Block flags are very useful for determining the state of a block. However, some block allocator users don't touch them, leading to misleading values. Ensure that we zero then when zero-on-gc is set. This is safe and makes the flags more useful during debugging. - - - - - cca97fa0 by Ben Gamari at 2020-05-14T12:59:01-04:00 nonmoving: Fix incorrect failed_to_evac value during deadlock gc Previously we would incorrectly set the failed_to_evac flag if we evacuated a value due to a deadlock GC. This would cause us to mark more things as dirty than strictly necessary. It also turned up a nasty but which I will fix next. - - - - - f5d32432 by Ben Gamari at 2020-05-14T12:59:01-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - 9e57f3ef by Ben Gamari at 2020-05-14T12:59:01-04:00 nonmoving: Optimise the write barrier (cherry picked from commit a636eadac1f30bae37aeb6526f94893293f098b8) - - - - - f8776330 by Ömer Sinan Ağacan at 2020-05-14T12:59:01-04:00 FastString: fix eager reading of string ptr in hashStr This read causes NULL dereferencing when len is 0. Fixes #17909 In the reproducer in #17909 this bug is triggered as follows: - SimplOpt.dealWithStringLiteral is called with a single-char string ("=" in #17909) - tailFS gets called on the FastString of the single-char string. - tailFS checks the length of the string, which is 1, and calls mkFastStringByteString on the tail of the ByteString, which is an empty ByteString as the original ByteString has only one char. - ByteString's unsafeUseAsCStringLen returns (NULL, 0) for the empty ByteString, which is passed to mkFastStringWith. - mkFastStringWith gets hash of the NULL pointer via hashStr, which fails on empty strings because of this bug. (cherry picked from commit d15b61608a542f6349b42224140b7d227b88ef4e) - - - - - ee13fe28 by Simon Peyton Jones at 2020-05-14T12:59:01-04:00 Improve error handling for VTA + deferred type errors This fixes #17792 See Note [VTA for out-of-scope functions] in TcExpr (cherry picked from commit 335b18bac3c361d243f427b66e67c2c94f5c6494) - - - - - b0fd1e2b by Simon Peyton Jones at 2020-05-14T12:59:01-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 (cherry picked from commit 658bda511237593bb80389280d0364180648058d) - - - - - f3f98a26 by Sylvain Henry at 2020-05-14T12:59:01-04:00 Rts: show errno on failure (#18033) (cherry picked from commit 4875d419ba066e479f7ac07f8b39ebe10c855859) - - - - - 249683ab by Simon Peyton Jones at 2020-05-14T12:59:01-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! (cherry picked from commit 7052d7c7ce3418db9e66ad6ff31e80b2a2c724bb) - - - - - 2cfa4cba by Ryan Scott at 2020-05-14T12:59:01-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). (cherry picked from commit cfb66d181ac45ce3d934bda3521b94277e6eb683) - - - - - 99e2054b by Adam Gundry at 2020-05-14T12:59:01-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. (cherry picked from commit 0d8c7a6c7c3513089668f49efb0a2dd8b4bbe74a) - - - - - bd3b58b2 by Ben Gamari at 2020-05-14T12:59:01-04:00 Ensure that printMinimalImports closes handle Fixes #18166. (cherry picked from commit 5afc160dee7142c96a842037fb64bee1429ad9ec) - - - - - 98ea4b70 by Ben Gamari at 2020-05-14T12:59:01-04:00 rts: Make non-existent linker search path merely a warning As noted in #18105, previously this resulted in a rather intrusive error message. This is in contrast to the general expectation that search paths are merely places to look, not places that must exist. Fixes #18105. (cherry picked from commit 24af9f30681444380c25465f555599da563713cb) - - - - - 30 changed files: - compiler/basicTypes/RdrName.hs - compiler/coreSyn/CoreSubst.hs - compiler/coreSyn/CoreUnfold.hs - compiler/deSugar/DsBinds.hs - compiler/rename/RnNames.hs - compiler/specialise/Specialise.hs - compiler/typecheck/TcExpr.hs - compiler/typecheck/TcHsType.hs - compiler/typecheck/TcSplice.hs - compiler/utils/FastString.hs - hadrian/src/Settings/Packages.hs - rts/Updates.h - rts/linker/PEi386.c - rts/posix/itimer/Pthread.c - rts/sm/BlockAlloc.c - rts/sm/Evac.c - rts/sm/NonMoving.c - rts/sm/NonMovingMark.c - rts/sm/NonMovingScav.c - rts/sm/Storage.c - + testsuite/tests/overloadedrecflds/should_fail/T17965.hs - + testsuite/tests/overloadedrecflds/should_fail/T17965.stderr - testsuite/tests/overloadedrecflds/should_fail/all.T - + testsuite/tests/partial-sigs/should_compile/T18008.hs - + testsuite/tests/partial-sigs/should_compile/T18008.stderr - testsuite/tests/partial-sigs/should_compile/all.T - testsuite/tests/perf/compiler/T16473.stdout - testsuite/tests/simplCore/should_compile/Makefile - + testsuite/tests/simplCore/should_compile/T17810.hs - + testsuite/tests/simplCore/should_compile/T17810a.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c54556ec1a6864b620d7eafcc10a7f55ac0c69b1...98ea4b70f1122b264399e004cfab00904cb7720c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c54556ec1a6864b620d7eafcc10a7f55ac0c69b1...98ea4b70f1122b264399e004cfab00904cb7720c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 17:22:20 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 14 May 2020 13:22:20 -0400 Subject: [Git][ghc/ghc][wip/backports] 5 commits: Major improvements to the specialiser Message-ID: <5ebd7e4ca096a_61679b2e0f4113076c4@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/backports at Glasgow Haskell Compiler / GHC Commits: fc520fca by Simon Peyton Jones at 2020-05-14T13:22:08-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! (cherry picked from commit 7052d7c7ce3418db9e66ad6ff31e80b2a2c724bb) - - - - - 81a6aac6 by Ryan Scott at 2020-05-14T13:22:08-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). (cherry picked from commit cfb66d181ac45ce3d934bda3521b94277e6eb683) - - - - - 2f9f4aec by Adam Gundry at 2020-05-14T13:22:08-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. (cherry picked from commit 0d8c7a6c7c3513089668f49efb0a2dd8b4bbe74a) - - - - - 0a034244 by Ben Gamari at 2020-05-14T13:22:08-04:00 Ensure that printMinimalImports closes handle Fixes #18166. (cherry picked from commit 5afc160dee7142c96a842037fb64bee1429ad9ec) - - - - - 3697a048 by Ben Gamari at 2020-05-14T13:22:08-04:00 rts: Make non-existent linker search path merely a warning As noted in #18105, previously this resulted in a rather intrusive error message. This is in contrast to the general expectation that search paths are merely places to look, not places that must exist. Fixes #18105. (cherry picked from commit 24af9f30681444380c25465f555599da563713cb) - - - - - 25 changed files: - compiler/basicTypes/RdrName.hs - compiler/coreSyn/CoreSubst.hs - compiler/coreSyn/CoreUnfold.hs - compiler/deSugar/DsBinds.hs - compiler/rename/RnNames.hs - compiler/specialise/Specialise.hs - compiler/typecheck/TcSplice.hs - rts/linker/PEi386.c - + testsuite/tests/overloadedrecflds/should_fail/T17965.hs - + testsuite/tests/overloadedrecflds/should_fail/T17965.stderr - testsuite/tests/overloadedrecflds/should_fail/all.T - testsuite/tests/perf/compiler/T16473.stdout - testsuite/tests/simplCore/should_compile/Makefile - + testsuite/tests/simplCore/should_compile/T17810.hs - + testsuite/tests/simplCore/should_compile/T17810a.hs - + testsuite/tests/simplCore/should_compile/T17930.hs - + testsuite/tests/simplCore/should_compile/T17930.stderr - + testsuite/tests/simplCore/should_compile/T17966.hs - + testsuite/tests/simplCore/should_compile/T17966.stdout - testsuite/tests/simplCore/should_compile/all.T - + testsuite/tests/simplCore/should_compile/spec004.hs - + testsuite/tests/simplCore/should_compile/spec004.stderr - + testsuite/tests/th/T17305.hs - + testsuite/tests/th/T17305.stderr - testsuite/tests/th/all.T Changes: ===================================== compiler/basicTypes/RdrName.hs ===================================== @@ -57,7 +57,7 @@ module RdrName ( gresToAvailInfo, -- ** Global 'RdrName' mapping elements: 'GlobalRdrElt', 'Provenance', 'ImportSpec' - GlobalRdrElt(..), isLocalGRE, isRecFldGRE, greLabel, + GlobalRdrElt(..), isLocalGRE, isRecFldGRE, isOverloadedRecFldGRE, greLabel, unQualOK, qualSpecOK, unQualSpecOK, pprNameProvenance, Parent(..), greParent_maybe, @@ -842,6 +842,12 @@ isRecFldGRE :: GlobalRdrElt -> Bool isRecFldGRE (GRE {gre_par = FldParent{}}) = True isRecFldGRE _ = False +isOverloadedRecFldGRE :: GlobalRdrElt -> Bool +-- ^ Is this a record field defined with DuplicateRecordFields? +-- (See Note [Parents for record fields]) +isOverloadedRecFldGRE (GRE {gre_par = FldParent{par_lbl = Just _}}) = True +isOverloadedRecFldGRE _ = False + -- Returns the field label of this GRE, if it has one greLabel :: GlobalRdrElt -> Maybe FieldLabelString greLabel (GRE{gre_par = FldParent{par_lbl = Just lbl}}) = Just lbl ===================================== compiler/coreSyn/CoreSubst.hs ===================================== @@ -16,7 +16,7 @@ module CoreSubst ( deShadowBinds, substSpec, substRulesForImportedIds, substTy, substCo, substExpr, substExprSC, substBind, substBindSC, substUnfolding, substUnfoldingSC, - lookupIdSubst, lookupTCvSubst, substIdOcc, + lookupIdSubst, lookupTCvSubst, substIdType, substIdOcc, substTickish, substDVarSet, substIdInfo, -- ** Operations on substitutions @@ -754,4 +754,3 @@ analyser, so it's possible that the worker is not even in scope any more. In all all these cases we simply drop the special case, returning to InlVanilla. The WARN is just so I can see if it happens a lot. -} - ===================================== compiler/coreSyn/CoreUnfold.hs ===================================== @@ -169,15 +169,16 @@ mkInlinableUnfolding dflags expr where expr' = simpleOptExpr dflags expr -specUnfolding :: DynFlags -> [Var] -> (CoreExpr -> CoreExpr) -> Arity +specUnfolding :: DynFlags -> Id -> [Var] -> (CoreExpr -> CoreExpr) -> Arity -> Unfolding -> Unfolding -- See Note [Specialising unfoldings] -- specUnfolding spec_bndrs spec_app arity_decrease unf -- = \spec_bndrs. spec_app( unf ) -- -specUnfolding dflags spec_bndrs spec_app arity_decrease +specUnfolding dflags fn spec_bndrs spec_app arity_decrease df@(DFunUnfolding { df_bndrs = old_bndrs, df_con = con, df_args = args }) - = ASSERT2( arity_decrease == count isId old_bndrs - count isId spec_bndrs, ppr df ) + = ASSERT2( arity_decrease == count isId old_bndrs - count isId spec_bndrs + , ppr df $$ ppr spec_bndrs $$ ppr (spec_app (Var fn)) $$ ppr arity_decrease ) mkDFunUnfolding spec_bndrs con (map spec_arg args) -- There is a hard-to-check assumption here that the spec_app has -- enough applications to exactly saturate the old_bndrs @@ -191,7 +192,7 @@ specUnfolding dflags spec_bndrs spec_app arity_decrease -- The beta-redexes created by spec_app will be -- simplified away by simplOptExpr -specUnfolding dflags spec_bndrs spec_app arity_decrease +specUnfolding dflags _ spec_bndrs spec_app arity_decrease (CoreUnfolding { uf_src = src, uf_tmpl = tmpl , uf_is_top = top_lvl , uf_guidance = old_guidance }) @@ -208,7 +209,7 @@ specUnfolding dflags spec_bndrs spec_app arity_decrease in mkCoreUnfolding src top_lvl new_tmpl guidance -specUnfolding _ _ _ _ _ = noUnfolding +specUnfolding _ _ _ _ _ _ = noUnfolding {- Note [Specialising unfoldings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/deSugar/DsBinds.hs ===================================== @@ -699,7 +699,7 @@ dsSpec mb_poly_rhs (dL->L loc (SpecPrag poly_id spec_co spec_inl)) { this_mod <- getModule ; let fn_unf = realIdUnfolding poly_id - spec_unf = specUnfolding dflags spec_bndrs core_app arity_decrease fn_unf + spec_unf = specUnfolding dflags poly_id spec_bndrs core_app arity_decrease fn_unf spec_id = mkLocalId spec_name spec_ty `setInlinePragma` inl_prag `setIdUnfolding` spec_unf ===================================== compiler/rename/RnNames.hs ===================================== @@ -635,9 +635,12 @@ extendGlobalRdrEnvRn avails new_fixities | otherwise = return (extendGlobalRdrEnv env gre) where - name = gre_name gre - occ = nameOccName name - dups = filter isLocalGRE (lookupGlobalRdrEnv env occ) + occ = greOccName gre + dups = filter isDupGRE (lookupGlobalRdrEnv env occ) + -- Duplicate GREs are those defined locally with the same OccName, + -- except cases where *both* GREs are DuplicateRecordFields (#17965). + isDupGRE gre' = isLocalGRE gre' + && not (isOverloadedRecFldGRE gre && isOverloadedRecFldGRE gre') {- ********************************************************************* @@ -1611,9 +1614,8 @@ printMinimalImports imports_w_usage = do { imports' <- getMinimalImports imports_w_usage ; this_mod <- getModule ; dflags <- getDynFlags - ; liftIO $ - do { h <- openFile (mkFilename dflags this_mod) WriteMode - ; printForUser dflags h neverQualify (vcat (map ppr imports')) } + ; liftIO $ withFile (mkFilename dflags this_mod) WriteMode $ \h -> + printForUser dflags h neverQualify (vcat (map ppr imports')) -- The neverQualify is important. We are printing Names -- but they are in the context of an 'import' decl, and -- we never qualify things inside there @@ -1769,14 +1771,13 @@ addDupDeclErr gres@(gre : _) = addErrAt (getSrcSpan (last sorted_names)) $ -- Report the error at the later location vcat [text "Multiple declarations of" <+> - quotes (ppr (nameOccName name)), + quotes (ppr (greOccName gre)), -- NB. print the OccName, not the Name, because the -- latter might not be in scope in the RdrEnv and so will -- be printed qualified. text "Declared at:" <+> vcat (map (ppr . nameSrcLoc) sorted_names)] where - name = gre_name gre sorted_names = sortWith nameSrcLoc (map gre_name gres) ===================================== compiler/specialise/Specialise.hs ===================================== @@ -20,7 +20,7 @@ import Predicate import Module( Module, HasModule(..) ) import Coercion( Coercion ) import CoreMonad -import qualified CoreSubst +import qualified CoreSubst as Core import CoreUnfold import Var ( isLocalVar ) import VarSet @@ -28,13 +28,14 @@ import VarEnv import CoreSyn import Rules import CoreOpt ( collectBindersPushingCo ) -import CoreUtils ( exprIsTrivial, mkCast, exprType ) +import CoreUtils ( exprIsTrivial, mkCast, exprType, getIdFromTrivialExpr_maybe ) import CoreFVs import CoreArity ( etaExpandToJoinPointRule ) import UniqSupply import Name import MkId ( voidArgId, voidPrimId ) -import Maybes ( mapMaybe, isJust ) +import TysPrim ( voidPrimTy ) +import Maybes ( mapMaybe, maybeToList, isJust ) import MonadUtils ( foldlM ) import BasicTypes import HscTypes @@ -605,7 +606,7 @@ specProgram guts@(ModGuts { mg_module = this_mod -- accidentally re-use a unique that's already in use -- Easiest thing is to do it all at once, as if all the top-level -- decls were mutually recursive - top_env = SE { se_subst = CoreSubst.mkEmptySubst $ mkInScopeSet $ mkVarSet $ + top_env = SE { se_subst = Core.mkEmptySubst $ mkInScopeSet $ mkVarSet $ bindersOfBinds binds , se_interesting = emptyVarSet } @@ -635,189 +636,12 @@ bitten by such instances to revert to the pre-7.10 behavior. See #10491 -} --- | An argument that we might want to specialise. --- See Note [Specialising Calls] for the nitty gritty details. -data SpecArg - = - -- | Type arguments that should be specialised, due to appearing - -- free in the type of a 'SpecDict'. - SpecType Type - -- | Type arguments that should remain polymorphic. - | UnspecType - -- | Dictionaries that should be specialised. - | SpecDict DictExpr - -- | Value arguments that should not be specialised. - | UnspecArg - -instance Outputable SpecArg where - ppr (SpecType t) = text "SpecType" <+> ppr t - ppr UnspecType = text "UnspecType" - ppr (SpecDict d) = text "SpecDict" <+> ppr d - ppr UnspecArg = text "UnspecArg" - -getSpecDicts :: [SpecArg] -> [DictExpr] -getSpecDicts = mapMaybe go - where - go (SpecDict d) = Just d - go _ = Nothing - -getSpecTypes :: [SpecArg] -> [Type] -getSpecTypes = mapMaybe go - where - go (SpecType t) = Just t - go _ = Nothing - -isUnspecArg :: SpecArg -> Bool -isUnspecArg UnspecArg = True -isUnspecArg UnspecType = True -isUnspecArg _ = False - -isValueArg :: SpecArg -> Bool -isValueArg UnspecArg = True -isValueArg (SpecDict _) = True -isValueArg _ = False - --- | Given binders from an original function 'f', and the 'SpecArg's --- corresponding to its usage, compute everything necessary to build --- a specialisation. --- --- We will use a running example. Consider the function --- --- foo :: forall a b. Eq a => Int -> blah --- foo @a @b dEqA i = blah --- --- which is called with the 'CallInfo' --- --- [SpecType T1, UnspecType, SpecDict dEqT1, UnspecArg] --- --- We'd eventually like to build the RULE --- --- RULE "SPEC foo @T1 _" --- forall @a @b (dEqA' :: Eq a). --- foo @T1 @b dEqA' = $sfoo @b --- --- and the specialisation '$sfoo' --- --- $sfoo :: forall b. Int -> blah --- $sfoo @b = \i -> SUBST[a->T1, dEqA->dEqA'] blah --- --- The cases for 'specHeader' below are presented in the same order as this --- running example. The result of 'specHeader' for this example is as follows: --- --- ( -- Returned arguments --- env + [a -> T1, deqA -> dEqA'] --- , [] --- --- -- RULE helpers --- , [b, dx', i] --- , [T1, b, dx', i] --- --- -- Specialised function helpers --- , [b, i] --- , [dx] --- , [T1, b, dx_spec, i] --- ) -specHeader - :: SpecEnv - -> [CoreBndr] -- The binders from the original function 'f' - -> [SpecArg] -- From the CallInfo - -> SpecM ( -- Returned arguments - SpecEnv -- Substitution to apply to the body of 'f' - , [CoreBndr] -- All the remaining unspecialised args from the original function 'f' - - -- RULE helpers - , [CoreBndr] -- Binders for the RULE - , [CoreArg] -- Args for the LHS of the rule - - -- Specialised function helpers - , [CoreBndr] -- Binders for $sf - , [DictBind] -- Auxiliary dictionary bindings - , [CoreExpr] -- Specialised arguments for unfolding - ) - --- We want to specialise on type 'T1', and so we must construct a substitution --- 'a->T1', as well as a LHS argument for the resulting RULE and unfolding --- details. -specHeader env (bndr : bndrs) (SpecType t : args) - = do { let env' = extendTvSubstList env [(bndr, t)] - ; (env'', unused_bndrs, rule_bs, rule_es, bs', dx, spec_args) - <- specHeader env' bndrs args - ; pure ( env'' - , unused_bndrs - , rule_bs - , Type t : rule_es - , bs' - , dx - , Type t : spec_args - ) - } - --- Next we have a type that we don't want to specialise. We need to perform --- a substitution on it (in case the type refers to 'a'). Additionally, we need --- to produce a binder, LHS argument and RHS argument for the resulting rule, --- /and/ a binder for the specialised body. -specHeader env (bndr : bndrs) (UnspecType : args) - = do { let (env', bndr') = substBndr env bndr - ; (env'', unused_bndrs, rule_bs, rule_es, bs', dx, spec_args) - <- specHeader env' bndrs args - ; pure ( env'' - , unused_bndrs - , bndr' : rule_bs - , varToCoreExpr bndr' : rule_es - , bndr' : bs' - , dx - , varToCoreExpr bndr' : spec_args - ) - } - --- Next we want to specialise the 'Eq a' dict away. We need to construct --- a wildcard binder to match the dictionary (See Note [Specialising Calls] for --- the nitty-gritty), as a LHS rule and unfolding details. -specHeader env (bndr : bndrs) (SpecDict d : args) - = do { inst_dict_id <- newDictBndr env bndr - ; let (rhs_env2, dx_binds, spec_dict_args') - = bindAuxiliaryDicts env [bndr] [d] [inst_dict_id] - ; (env', unused_bndrs, rule_bs, rule_es, bs', dx, spec_args) - <- specHeader rhs_env2 bndrs args - ; pure ( env' - , unused_bndrs - -- See Note [Evidence foralls] - , exprFreeIdsList (varToCoreExpr inst_dict_id) ++ rule_bs - , varToCoreExpr inst_dict_id : rule_es - , bs' - , dx_binds ++ dx - , spec_dict_args' ++ spec_args - ) - } - --- Finally, we have the unspecialised argument 'i'. We need to produce --- a binder, LHS and RHS argument for the RULE, and a binder for the --- specialised body. --- --- NB: Calls to 'specHeader' will trim off any trailing 'UnspecArg's, which is --- why 'i' doesn't appear in our RULE above. But we have no guarantee that --- there aren't 'UnspecArg's which come /before/ all of the dictionaries, so --- this case must be here. -specHeader env (bndr : bndrs) (UnspecArg : args) - = do { let (env', bndr') = substBndr env bndr - ; (env'', unused_bndrs, rule_bs, rule_es, bs', dx, spec_args) - <- specHeader env' bndrs args - ; pure ( env'' - , unused_bndrs - , bndr' : rule_bs - , varToCoreExpr bndr' : rule_es - , bndr' : bs' - , dx - , varToCoreExpr bndr' : spec_args - ) - } - --- Return all remaining binders from the original function. These have the --- invariant that they should all correspond to unspecialised arguments, so --- it's safe to stop processing at this point. -specHeader env bndrs [] = pure (env, bndrs, [], [], [], [], []) -specHeader env [] _ = pure (env, [], [], [], [], [], []) +{- ********************************************************************* +* * + Specialising imported functions +* * +********************************************************************* -} -- | Specialise a set of calls to imported bindings specImports :: DynFlags @@ -1034,7 +858,7 @@ Avoiding this recursive specialisation loop is the reason for the -} data SpecEnv - = SE { se_subst :: CoreSubst.Subst + = SE { se_subst :: Core.Subst -- We carry a substitution down: -- a) we must clone any binding that might float outwards, -- to avoid name clashes @@ -1048,8 +872,14 @@ data SpecEnv -- See Note [Interesting dictionary arguments] } +instance Outputable SpecEnv where + ppr (SE { se_subst = subst, se_interesting = interesting }) + = text "SE" <+> braces (sep $ punctuate comma + [ text "subst =" <+> ppr subst + , text "interesting =" <+> ppr interesting ]) + specVar :: SpecEnv -> Id -> CoreExpr -specVar env v = CoreSubst.lookupIdSubst (text "specVar") (se_subst env) v +specVar env v = Core.lookupIdSubst (text "specVar") (se_subst env) v specExpr :: SpecEnv -> CoreExpr -> SpecM (CoreExpr, UsageDetails) @@ -1110,6 +940,18 @@ specExpr env (Let bind body) -- All done ; return (foldr Let body' binds', uds) } +-------------- +specLam :: SpecEnv -> [OutBndr] -> InExpr -> SpecM (OutExpr, UsageDetails) +-- The binders have been substituted, but the body has not +specLam env bndrs body + | null bndrs + = specExpr env body + | otherwise + = do { (body', uds) <- specExpr env body + ; let (free_uds, dumped_dbs) = dumpUDs bndrs uds + ; return (mkLams bndrs (wrapDictBindsE dumped_dbs body'), free_uds) } + +-------------- specTickish :: SpecEnv -> Tickish Id -> Tickish Id specTickish env (Breakpoint ix ids) = Breakpoint ix [ id' | id <- ids, Var id' <- [specVar env id]] @@ -1117,6 +959,7 @@ specTickish env (Breakpoint ix ids) -- should never happen, but it's harmless to drop them anyway. specTickish _ other_tickish = other_tickish +-------------- specCase :: SpecEnv -> CoreExpr -- Scrutinee, already done -> Id -> [CoreAlt] @@ -1142,7 +985,7 @@ specCase env scrut' case_bndr [(con, args, rhs)] subst_prs = (case_bndr, Var case_bndr_flt) : [ (arg, Var sc_flt) | (arg, Just sc_flt) <- args `zip` mb_sc_flts ] - env_rhs' = env_rhs { se_subst = CoreSubst.extendIdSubstList (se_subst env_rhs) subst_prs + env_rhs' = env_rhs { se_subst = Core.extendIdSubstList (se_subst env_rhs) subst_prs , se_interesting = se_interesting env_rhs `extendVarSetList` (case_bndr_flt : sc_args_flt) } @@ -1239,7 +1082,13 @@ specBind :: SpecEnv -- Use this for RHSs -- No calls for binders of this bind specBind rhs_env (NonRec fn rhs) body_uds = do { (rhs', rhs_uds) <- specExpr rhs_env rhs - ; (fn', spec_defns, body_uds1) <- specDefn rhs_env body_uds fn rhs + + ; let zapped_fn = zapIdDemandInfo fn + -- We zap the demand info because the binding may float, + -- which would invaidate the demand info (see #17810 for example). + -- Destroying demand info is not terrible; specialisation is + -- always followed soon by demand analysis. + ; (fn', spec_defns, body_uds1) <- specDefn rhs_env body_uds zapped_fn rhs ; let pairs = spec_defns ++ [(fn', rhs')] -- fn' mentions the spec_defns in its rules, @@ -1359,8 +1208,7 @@ type SpecInfo = ( [CoreRule] -- Specialisation rules specCalls mb_mod env existing_rules calls_for_me fn rhs -- The first case is the interesting one - | callSpecArity pis <= fn_arity -- See Note [Specialisation Must Preserve Sharing] - && notNull calls_for_me -- And there are some calls to specialise + | notNull calls_for_me -- And there are some calls to specialise && not (isNeverActive (idInlineActivation fn)) -- Don't specialise NOINLINE things -- See Note [Auto-specialisation and RULES] @@ -1380,27 +1228,22 @@ specCalls mb_mod env existing_rules calls_for_me fn rhs -- pprTrace "specDefn: none" (ppr fn <+> ppr calls_for_me) $ return ([], [], emptyUDs) where - _trace_doc = sep [ ppr rhs_tyvars, ppr rhs_bndrs - , ppr (idInlineActivation fn) ] - - fn_type = idType fn - fn_arity = idArity fn - fn_unf = realIdUnfolding fn -- Ignore loop-breaker-ness here - pis = fst $ splitPiTys fn_type - theta = getTheta pis - n_dicts = length theta - inl_prag = idInlinePragma fn - inl_act = inlinePragmaActivation inl_prag - is_local = isLocalId fn + _trace_doc = sep [ ppr rhs_bndrs, ppr (idInlineActivation fn) ] + + fn_type = idType fn + fn_arity = idArity fn + fn_unf = realIdUnfolding fn -- Ignore loop-breaker-ness here + inl_prag = idInlinePragma fn + inl_act = inlinePragmaActivation inl_prag + is_local = isLocalId fn -- Figure out whether the function has an INLINE pragma -- See Note [Inline specialisations] - (rhs_bndrs, rhs_body) = collectBindersPushingCo rhs - -- See Note [Account for casts in binding] - rhs_tyvars = filter isTyVar rhs_bndrs + (rhs_bndrs, rhs_body) = collectBindersPushingCo rhs + -- See Note [Account for casts in binding] - in_scope = CoreSubst.substInScope (se_subst env) + in_scope = Core.substInScope (se_subst env) already_covered :: DynFlags -> [CoreRule] -> [CoreExpr] -> Bool already_covered dflags new_rules args -- Note [Specialisations already covered] @@ -1415,38 +1258,43 @@ specCalls mb_mod env existing_rules calls_for_me fn rhs spec_call :: SpecInfo -- Accumulating parameter -> CallInfo -- Call instance -> SpecM SpecInfo - spec_call spec_acc@(rules_acc, pairs_acc, uds_acc) - (CI { ci_key = call_args, ci_arity = call_arity }) - = ASSERT(call_arity <= fn_arity) - - -- See Note [Specialising Calls] - do { (rhs_env2, unused_bndrs, rule_bndrs, rule_args, unspec_bndrs, dx_binds, spec_args) - <- specHeader env rhs_bndrs $ dropWhileEndLE isUnspecArg call_args - ; let rhs_body' = mkLams unused_bndrs rhs_body + spec_call spec_acc@(rules_acc, pairs_acc, uds_acc) (CI { ci_key = call_args }) + = -- See Note [Specialising Calls] + do { ( useful, rhs_env2, leftover_bndrs + , rule_bndrs, rule_lhs_args + , spec_bndrs, dx_binds, spec_args) <- specHeader env rhs_bndrs call_args + ; dflags <- getDynFlags - ; if already_covered dflags rules_acc rule_args + ; if not useful -- No useful specialisation + || already_covered dflags rules_acc rule_lhs_args then return spec_acc else -- pprTrace "spec_call" (vcat [ ppr _call_info, ppr fn, ppr rhs_dict_ids -- , text "rhs_env2" <+> ppr (se_subst rhs_env2) -- , ppr dx_binds ]) $ - do - { -- Figure out the type of the specialised function - let body = mkLams unspec_bndrs rhs_body' - body_ty = substTy rhs_env2 $ exprType body - (lam_extra_args, app_args) -- See Note [Specialisations Must Be Lifted] - | isUnliftedType body_ty -- C.f. WwLib.mkWorkerArgs - , not (isJoinId fn) - = ([voidArgId], voidPrimId : unspec_bndrs) - | otherwise = ([], unspec_bndrs) - join_arity_change = length app_args - length rule_args + do { -- Run the specialiser on the specialised RHS + -- The "1" suffix is before we maybe add the void arg + ; (spec_rhs1, rhs_uds) <- specLam rhs_env2 (spec_bndrs ++ leftover_bndrs) rhs_body + ; let spec_fn_ty1 = exprType spec_rhs1 + + -- Maybe add a void arg to the specialised function, + -- to avoid unlifted bindings + -- See Note [Specialisations Must Be Lifted] + -- C.f. GHC.Core.Op.WorkWrap.Lib.mkWorkerArgs + add_void_arg = isUnliftedType spec_fn_ty1 && not (isJoinId fn) + (spec_rhs, spec_fn_ty, rule_rhs_args) + | add_void_arg = ( Lam voidArgId spec_rhs1 + , mkVisFunTy voidPrimTy spec_fn_ty1 + , voidPrimId : spec_bndrs) + | otherwise = (spec_rhs1, spec_fn_ty1, spec_bndrs) + + arity_decr = count isValArg rule_lhs_args - count isId rule_rhs_args + join_arity_decr = length rule_lhs_args - length rule_rhs_args spec_join_arity | Just orig_join_arity <- isJoinId_maybe fn - = Just (orig_join_arity + join_arity_change) + = Just (orig_join_arity - join_arity_decr) | otherwise = Nothing - ; (spec_rhs, rhs_uds) <- specExpr rhs_env2 (mkLams lam_extra_args body) - ; let spec_id_ty = exprType spec_rhs - ; spec_f <- newSpecIdSM fn spec_id_ty spec_join_arity + ; spec_fn <- newSpecIdSM fn spec_fn_ty spec_join_arity ; this_mod <- getModule ; let -- The rule to put in the function's specialisation is: @@ -1474,13 +1322,12 @@ specCalls mb_mod env existing_rules calls_for_me fn rhs inl_act -- Note [Auto-specialisation and RULES] (idName fn) rule_bndrs - rule_args - (mkVarApps (Var spec_f) app_args) + rule_lhs_args + (mkVarApps (Var spec_fn) rule_rhs_args) spec_rule = case isJoinId_maybe fn of - Just join_arity -> etaExpandToJoinPointRule join_arity - rule_wout_eta + Just join_arity -> etaExpandToJoinPointRule join_arity rule_wout_eta Nothing -> rule_wout_eta -- Add the { d1' = dx1; d2' = dx2 } usage stuff @@ -1499,7 +1346,7 @@ specCalls mb_mod env existing_rules calls_for_me fn rhs = (inl_prag { inl_inline = NoUserInline }, noUnfolding) | otherwise - = (inl_prag, specUnfolding dflags unspec_bndrs spec_app n_dicts fn_unf) + = (inl_prag, specUnfolding dflags fn spec_bndrs spec_app arity_decr fn_unf) spec_app e = e `mkApps` spec_args @@ -1507,13 +1354,14 @@ specCalls mb_mod env existing_rules calls_for_me fn rhs -- Adding arity information just propagates it a bit faster -- See Note [Arity decrease] in Simplify -- Copy InlinePragma information from the parent Id. - -- So if f has INLINE[1] so does spec_f - spec_f_w_arity = spec_f `setIdArity` max 0 (fn_arity - n_dicts) - `setInlinePragma` spec_inl_prag - `setIdUnfolding` spec_unf - `asJoinId_maybe` spec_join_arity - - _rule_trace_doc = vcat [ ppr spec_f, ppr fn_type, ppr spec_id_ty + -- So if f has INLINE[1] so does spec_fn + spec_f_w_arity = spec_fn `setIdArity` max 0 (fn_arity - arity_decr) + `setInlinePragma` spec_inl_prag + `setIdUnfolding` spec_unf + `asJoinId_maybe` spec_join_arity + + _rule_trace_doc = vcat [ ppr fn <+> dcolon <+> ppr fn_type + , ppr spec_fn <+> dcolon <+> ppr spec_fn_ty , ppr rhs_bndrs, ppr call_args , ppr spec_rule ] @@ -1572,33 +1420,44 @@ preserve laziness. Note [Specialising Calls] ~~~~~~~~~~~~~~~~~~~~~~~~~ -Suppose we have a function: +Suppose we have a function with a complicated type: - f :: Int -> forall a b c. (Foo a, Foo c) => Bar -> Qux - f = \x -> /\ a b c -> \d1 d2 bar -> rhs + f :: forall a b c. Int -> Eq a => Show b => c -> Blah + f @a @b @c i dEqA dShowA x = blah and suppose it is called at: - f 7 @T1 @T2 @T3 dFooT1 dFooT3 bar + f 7 @T1 @T2 @T3 dEqT1 ($dfShow dShowT2) t3 -This call is described as a 'CallInfo' whose 'ci_key' is +This call is described as a 'CallInfo' whose 'ci_key' is: - [ UnspecArg, SpecType T1, UnspecType, SpecType T3, SpecDict dFooT1 - , SpecDict dFooT3, UnspecArg ] + [ SpecType T1, SpecType T2, UnspecType, UnspecArg, SpecDict dEqT1 + , SpecDict ($dfShow dShowT2), UnspecArg ] -Why are 'a' and 'c' identified as 'SpecType', while 'b' is 'UnspecType'? +Why are 'a' and 'b' identified as 'SpecType', while 'c' is 'UnspecType'? Because we must specialise the function on type variables that appear free in its *dictionary* arguments; but not on type variables that do not appear in any dictionaries, i.e. are fully polymorphic. Because this call has dictionaries applied, we'd like to specialise the call on any type argument that appears free in those dictionaries. -In this case, those are (a ~ T1, c ~ T3). +In this case, those are [a :-> T1, b :-> T2]. + +We also need to substitute the dictionary binders with their +specialised dictionaries. The simplest substitution would be +[dEqA :-> dEqT1, dShowA :-> $dfShow dShowT2], but this duplicates +work, since `$dfShow dShowT2` is a function application. Therefore, we +also want to *float the dictionary out* (via bindAuxiliaryDict), +creating a new dict binding + + dShow1 = $dfShow dShowT2 -As a result, we'd like to generate a function: +and the substitution [dEqA :-> dEqT1, dShowA :-> dShow1]. - $sf :: Int -> forall b. Bar -> Qux - $sf = SUBST[a->T1, c->T3, d1->d1', d2->d2'] (\x -> /\ b -> \bar -> rhs) +With the substitutions in hand, we can generate a specialised function: + + $sf :: forall c. Int -> c -> Blah + $sf = SUBST[a :-> T1, b :-> T2, dEqA :-> dEqT1, dShowA :-> dShow1] (\@c i x -> blah) Note that the substitution is applied to the whole thing. This is convenient, but just slightly fragile. Notably: @@ -1606,20 +1465,71 @@ convenient, but just slightly fragile. Notably: We must construct a rewrite rule: - RULE "SPEC f @T1 _ @T3" - forall (x :: Int) (@b :: Type) (d1' :: Foo T1) (d2' :: Foo T3). - f x @T1 @b @T3 d1' d2' = $sf x @b + RULE "SPEC f @T1 @T2 _" + forall (@c :: Type) (i :: Int) (d1 :: Eq T1) (d2 :: Show T2). + f @T1 @T2 @c i d1 d2 = $sf @c i -In the rule, d1' and d2' are just wildcards, not used in the RHS. Note -additionally that 'bar' isn't captured by this rule --- we bind only +In the rule, d1 and d2 are just wildcards, not used in the RHS. Note +additionally that 'x' isn't captured by this rule --- we bind only enough etas in order to capture all of the *specialised* arguments. -Finally, we must also construct the usage-details +Note [Drop dead args from specialisations] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When specialising a function, it’s possible some of the arguments may +actually be dead. For example, consider: + + f :: forall a. () -> Show a => a -> String + f x y = show y ++ "!" + +We might generate the following CallInfo for `f @Int`: + + [SpecType Int, UnspecArg, SpecDict $dShowInt, UnspecArg] + +Normally we’d include both the x and y arguments in the +specialisation, since we’re not specialising on either of them. But +that’s silly, since x is actually unused! So we might as well drop it +in the specialisation: + + $sf :: Int -> String + $sf y = show y ++ "!" + + {-# RULE "SPEC f @Int" forall x. f @Int x $dShow = $sf #-} + +This doesn’t save us much, since the arg would be removed later by +worker/wrapper, anyway, but it’s easy to do. Note, however, that we +only drop dead arguments if: + + 1. We don’t specialise on them. + 2. They come before an argument we do specialise on. + +Doing the latter would require eta-expanding the RULE, which could +make it match less often, so it’s not worth it. Doing the former could +be more useful --- it would stop us from generating pointless +specialisations --- but it’s more involved to implement and unclear if +it actually provides much benefit in practice. - { d1' = dx1; d2' = dx2 } +Note [Zap occ info in rule binders] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When we generate a specialisation RULE, we need to drop occurrence +info on the binders. If we don’t, things go wrong when we specialise a +function like + + f :: forall a. () -> Show a => a -> String + f x y = show y ++ "!" + +since we’ll generate a RULE like + + RULE "SPEC f @Int" forall x [Occ=Dead]. + f @Int x $dShow = $sf + +and Core Lint complains, even though x only appears on the LHS (due to +Note [Drop dead args from specialisations]). -where d1', d2' are cloned versions of d1,d2, with the type substitution -applied. These auxiliary bindings just avoid duplication of dx1, dx2. +Why is that a Lint error? Because the arguments on the LHS of a rule +are syntactically expressions, not patterns, so Lint treats the +appearance of x as a use rather than a binding. Fortunately, the +solution is simple: we just make sure to zap the occ info before +using ids as wildcard binders in a rule. Note [Account for casts in binding] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1674,56 +1584,6 @@ type correctness issue.) But specialisation rules are strictly for What this means is that a SPEC rules from auto-specialisation in module M will be used in other modules only if M.hi has been read for some other reason, which is actually pretty likely. --} - -bindAuxiliaryDicts - :: SpecEnv - -> [DictId] -> [CoreExpr] -- Original dict bndrs, and the witnessing expressions - -> [DictId] -- A cloned dict-id for each dict arg - -> (SpecEnv, -- Substitute for all orig_dicts - [DictBind], -- Auxiliary dict bindings - [CoreExpr]) -- Witnessing expressions (all trivial) --- Bind any dictionary arguments to fresh names, to preserve sharing -bindAuxiliaryDicts env@(SE { se_subst = subst, se_interesting = interesting }) - orig_dict_ids call_ds inst_dict_ids - = (env', dx_binds, spec_dict_args) - where - (dx_binds, spec_dict_args) = go call_ds inst_dict_ids - env' = env { se_subst = subst `CoreSubst.extendSubstList` - (orig_dict_ids `zip` spec_dict_args) - `CoreSubst.extendInScopeList` dx_ids - , se_interesting = interesting `unionVarSet` interesting_dicts } - - dx_ids = [dx_id | (NonRec dx_id _, _) <- dx_binds] - interesting_dicts = mkVarSet [ dx_id | (NonRec dx_id dx, _) <- dx_binds - , interestingDict env dx ] - -- See Note [Make the new dictionaries interesting] - - go :: [CoreExpr] -> [CoreBndr] -> ([DictBind], [CoreExpr]) - go [] _ = ([], []) - go (dx:dxs) (dx_id:dx_ids) - | exprIsTrivial dx = (dx_binds, dx : args) - | otherwise = (mkDB (NonRec dx_id dx) : dx_binds, Var dx_id : args) - where - (dx_binds, args) = go dxs dx_ids - -- In the first case extend the substitution but not bindings; - -- in the latter extend the bindings but not the substitution. - -- For the former, note that we bind the *original* dict in the substitution, - -- overriding any d->dx_id binding put there by substBndrs - go _ _ = pprPanic "bindAuxiliaryDicts" (ppr orig_dict_ids $$ ppr call_ds $$ ppr inst_dict_ids) - -{- -Note [Make the new dictionaries interesting] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Important! We're going to substitute dx_id1 for d -and we want it to look "interesting", else we won't gather *any* -consequential calls. E.g. - f d = ...g d.... -If we specialise f for a call (f (dfun dNumInt)), we'll get -a consequent call (g d') with an auxiliary definition - d' = df dNumInt -We want that consequent call to look interesting - Note [From non-recursive to recursive] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2059,15 +1919,297 @@ a complete solution; ignoring specialisation for now, INLINABLE functions don't get properly strictness analysed, for example. But it works well for examples involving specialisation, which is the dominant use of INLINABLE. See #4874. +-} - -************************************************************************ +{- ********************************************************************* * * -\subsubsection{UsageDetails and suchlike} + SpecArg, and specHeader * * -************************************************************************ +********************************************************************* -} + +-- | An argument that we might want to specialise. +-- See Note [Specialising Calls] for the nitty gritty details. +data SpecArg + = + -- | Type arguments that should be specialised, due to appearing + -- free in the type of a 'SpecDict'. + SpecType Type + + -- | Type arguments that should remain polymorphic. + | UnspecType + + -- | Dictionaries that should be specialised. mkCallUDs ensures + -- that only "interesting" dictionary arguments get a SpecDict; + -- see Note [Interesting dictionary arguments] + | SpecDict DictExpr + + -- | Value arguments that should not be specialised. + | UnspecArg + +instance Outputable SpecArg where + ppr (SpecType t) = text "SpecType" <+> ppr t + ppr UnspecType = text "UnspecType" + ppr (SpecDict d) = text "SpecDict" <+> ppr d + ppr UnspecArg = text "UnspecArg" + +specArgFreeVars :: SpecArg -> VarSet +specArgFreeVars (SpecType ty) = tyCoVarsOfType ty +specArgFreeVars (SpecDict dx) = exprFreeVars dx +specArgFreeVars UnspecType = emptyVarSet +specArgFreeVars UnspecArg = emptyVarSet + +isSpecDict :: SpecArg -> Bool +isSpecDict (SpecDict {}) = True +isSpecDict _ = False + +-- | Given binders from an original function 'f', and the 'SpecArg's +-- corresponding to its usage, compute everything necessary to build +-- a specialisation. +-- +-- We will use the running example from Note [Specialising Calls]: +-- +-- f :: forall a b c. Int -> Eq a => Show b => c -> Blah +-- f @a @b @c i dEqA dShowA x = blah +-- +-- Suppose we decide to specialise it at the following pattern: +-- +-- [ SpecType T1, SpecType T2, UnspecType, UnspecArg +-- , SpecDict dEqT1, SpecDict ($dfShow dShowT2), UnspecArg ] +-- +-- We'd eventually like to build the RULE +-- +-- RULE "SPEC f @T1 @T2 _" +-- forall (@c :: Type) (i :: Int) (d1 :: Eq T1) (d2 :: Show T2). +-- f @T1 @T2 @c i d1 d2 = $sf @c i +-- +-- and the specialisation '$sf' +-- +-- $sf :: forall c. Int -> c -> Blah +-- $sf = SUBST[a :-> T1, b :-> T2, dEqA :-> dEqT1, dShowA :-> dShow1] (\@c i x -> blah) +-- +-- where dShow1 is a floated binding created by bindAuxiliaryDict. +-- +-- The cases for 'specHeader' below are presented in the same order as this +-- running example. The result of 'specHeader' for this example is as follows: +-- +-- ( -- Returned arguments +-- env + [a :-> T1, b :-> T2, dEqA :-> dEqT1, dShowA :-> dShow1] +-- , [x] +-- +-- -- RULE helpers +-- , [c, i, d1, d2] +-- , [T1, T2, c, i, d1, d2] +-- +-- -- Specialised function helpers +-- , [c, i, x] +-- , [dShow1 = $dfShow dShowT2] +-- , [T1, T2, dEqT1, dShow1] +-- ) +specHeader + :: SpecEnv + -> [InBndr] -- The binders from the original function 'f' + -> [SpecArg] -- From the CallInfo + -> SpecM ( Bool -- True <=> some useful specialisation happened + -- Not the same as any (isSpecDict args) because + -- the args might be longer than bndrs + + -- Returned arguments + , SpecEnv -- Substitution to apply to the body of 'f' + , [OutBndr] -- Leftover binders from the original function 'f' + -- that don’t have a corresponding SpecArg + + -- RULE helpers + , [OutBndr] -- Binders for the RULE + , [CoreArg] -- Args for the LHS of the rule + + -- Specialised function helpers + , [OutBndr] -- Binders for $sf + , [DictBind] -- Auxiliary dictionary bindings + , [OutExpr] -- Specialised arguments for unfolding + ) + +-- We want to specialise on type 'T1', and so we must construct a substitution +-- 'a->T1', as well as a LHS argument for the resulting RULE and unfolding +-- details. +specHeader env (bndr : bndrs) (SpecType t : args) + = do { let env' = extendTvSubstList env [(bndr, t)] + ; (useful, env'', leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args) + <- specHeader env' bndrs args + ; pure ( useful + , env'' + , leftover_bndrs + , rule_bs + , Type t : rule_es + , bs' + , dx + , Type t : spec_args + ) + } + +-- Next we have a type that we don't want to specialise. We need to perform +-- a substitution on it (in case the type refers to 'a'). Additionally, we need +-- to produce a binder, LHS argument and RHS argument for the resulting rule, +-- /and/ a binder for the specialised body. +specHeader env (bndr : bndrs) (UnspecType : args) + = do { let (env', bndr') = substBndr env bndr + ; (useful, env'', leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args) + <- specHeader env' bndrs args + ; pure ( useful + , env'' + , leftover_bndrs + , bndr' : rule_bs + , varToCoreExpr bndr' : rule_es + , bndr' : bs' + , dx + , varToCoreExpr bndr' : spec_args + ) + } + +-- Next we want to specialise the 'Eq a' dict away. We need to construct +-- a wildcard binder to match the dictionary (See Note [Specialising Calls] for +-- the nitty-gritty), as a LHS rule and unfolding details. +specHeader env (bndr : bndrs) (SpecDict d : args) + = do { bndr' <- newDictBndr env bndr -- See Note [Zap occ info in rule binders] + ; let (env', dx_bind, spec_dict) = bindAuxiliaryDict env bndr bndr' d + ; (_, env'', leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args) + <- specHeader env' bndrs args + ; pure ( True -- Ha! A useful specialisation! + , env'' + , leftover_bndrs + -- See Note [Evidence foralls] + , exprFreeIdsList (varToCoreExpr bndr') ++ rule_bs + , varToCoreExpr bndr' : rule_es + , bs' + , maybeToList dx_bind ++ dx + , spec_dict : spec_args + ) + } + +-- Finally, we have the unspecialised argument 'i'. We need to produce +-- a binder, LHS and RHS argument for the RULE, and a binder for the +-- specialised body. +-- +-- NB: Calls to 'specHeader' will trim off any trailing 'UnspecArg's, which is +-- why 'i' doesn't appear in our RULE above. But we have no guarantee that +-- there aren't 'UnspecArg's which come /before/ all of the dictionaries, so +-- this case must be here. +specHeader env (bndr : bndrs) (UnspecArg : args) + = do { -- see Note [Zap occ info in rule binders] + let (env', bndr') = substBndr env (zapIdOccInfo bndr) + ; (useful, env'', leftover_bndrs, rule_bs, rule_es, bs', dx, spec_args) + <- specHeader env' bndrs args + ; pure ( useful + , env'' + , leftover_bndrs + , bndr' : rule_bs + , varToCoreExpr bndr' : rule_es + , if isDeadBinder bndr + then bs' -- see Note [Drop dead args from specialisations] + else bndr' : bs' + , dx + , varToCoreExpr bndr' : spec_args + ) + } + +-- If we run out of binders, stop immediately +-- See Note [Specialisation Must Preserve Sharing] +specHeader env [] _ = pure (False, env, [], [], [], [], [], []) + +-- Return all remaining binders from the original function. These have the +-- invariant that they should all correspond to unspecialised arguments, so +-- it's safe to stop processing at this point. +specHeader env bndrs [] + = pure (False, env', bndrs', [], [], [], [], []) + where + (env', bndrs') = substBndrs env bndrs + + +-- | Binds a dictionary argument to a fresh name, to preserve sharing +bindAuxiliaryDict + :: SpecEnv + -> InId -> OutId -> OutExpr -- Original dict binder, and the witnessing expression + -> ( SpecEnv -- Substitute for orig_dict_id + , Maybe DictBind -- Auxiliary dict binding, if any + , OutExpr) -- Witnessing expression (always trivial) +bindAuxiliaryDict env@(SE { se_subst = subst, se_interesting = interesting }) + orig_dict_id fresh_dict_id dict_expr + + -- If the dictionary argument is trivial, + -- don’t bother creating a new dict binding; just substitute + | Just dict_id <- getIdFromTrivialExpr_maybe dict_expr + = let env' = env { se_subst = Core.extendSubst subst orig_dict_id dict_expr + `Core.extendInScope` dict_id + -- See Note [Keep the old dictionaries interesting] + , se_interesting = interesting `extendVarSet` dict_id } + in (env', Nothing, dict_expr) + + | otherwise -- Non-trivial dictionary arg; make an auxiliary binding + = let dict_bind = mkDB (NonRec fresh_dict_id dict_expr) + env' = env { se_subst = Core.extendSubst subst orig_dict_id (Var fresh_dict_id) + `Core.extendInScope` fresh_dict_id + -- See Note [Make the new dictionaries interesting] + , se_interesting = interesting `extendVarSet` fresh_dict_id } + in (env', Just dict_bind, Var fresh_dict_id) + +{- +Note [Make the new dictionaries interesting] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Important! We're going to substitute dx_id1 for d +and we want it to look "interesting", else we won't gather *any* +consequential calls. E.g. + f d = ...g d.... +If we specialise f for a call (f (dfun dNumInt)), we'll get +a consequent call (g d') with an auxiliary definition + d' = df dNumInt +We want that consequent call to look interesting + +Note [Keep the old dictionaries interesting] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In bindAuxiliaryDict, we don’t bother creating a new dict binding if +the dict expression is trivial. For example, if we have + + f = \ @m1 (d1 :: Monad m1) -> ... + +and we specialize it at the pattern + + [SpecType IO, SpecArg $dMonadIO] + +it would be silly to create a new binding for $dMonadIO; it’s already +a binding! So we just extend the substitution directly: + + m1 :-> IO + d1 :-> $dMonadIO + +But this creates a new subtlety: the dict expression might be a dict +binding we floated out while specializing another function. For +example, we might have + + d2 = $p1Monad $dMonadIO -- floated out by bindAuxiliaryDict + $sg = h @IO d2 + h = \ @m2 (d2 :: Applicative m2) -> ... + +and end up specializing h at the following pattern: + + [SpecType IO, SpecArg d2] + +When we created the d2 binding in the first place, we locally marked +it as interesting while specializing g as described above by +Note [Make the new dictionaries interesting]. But when we go to +specialize h, it isn’t in the SpecEnv anymore, so we’ve lost the +knowledge that we should specialize on it. + +To fix this, we have to explicitly add d2 *back* to the interesting +set. That way, it will still be considered interesting while +specializing the body of h. See !2913. -} + +{- ********************************************************************* +* * + UsageDetails and suchlike +* * +********************************************************************* -} + data UsageDetails = MkUD { ud_binds :: !(Bag DictBind), @@ -2137,8 +2279,6 @@ data CallInfoSet = CIS Id (Bag CallInfo) data CallInfo = CI { ci_key :: [SpecArg] -- All arguments - , ci_arity :: Int -- The number of variables necessary to bind - -- all of the specialised arguments , ci_fvs :: VarSet -- Free vars of the ci_key -- call (including tyvars) -- [*not* include the main id itself, of course] @@ -2184,12 +2324,6 @@ callInfoFVs :: CallInfoSet -> VarSet callInfoFVs (CIS _ call_info) = foldr (\(CI { ci_fvs = fv }) vs -> unionVarSet fv vs) emptyVarSet call_info -computeArity :: [SpecArg] -> Int -computeArity = length . filter isValueArg . dropWhileEndLE isUnspecArg - -callSpecArity :: [TyCoBinder] -> Int -callSpecArity = length . filter (not . isNamedBinder) . dropWhileEndLE isVisibleBinder - getTheta :: [TyCoBinder] -> [PredType] getTheta = fmap tyBinderType . filter isInvisibleBinder . filter (not . isNamedBinder) @@ -2200,13 +2334,9 @@ singleCall id args = MkUD {ud_binds = emptyBag, ud_calls = unitDVarEnv id $ CIS id $ unitBag (CI { ci_key = args -- used to be tys - , ci_arity = computeArity args , ci_fvs = call_fvs }) } where - tys = getSpecTypes args - dicts = getSpecDicts args - call_fvs = exprsFreeVars dicts `unionVarSet` tys_fvs - tys_fvs = tyCoVarsOfTypes tys + call_fvs = foldr (unionVarSet . specArgFreeVars) emptyVarSet args -- The type args (tys) are guaranteed to be part of the dictionary -- types, because they are just the constrained types, -- and the dictionary is therefore sure to be bound @@ -2225,42 +2355,47 @@ mkCallUDs env f args res = mkCallUDs' env f args mkCallUDs' env f args - | not (want_calls_for f) -- Imported from elsewhere - || null theta -- Not overloaded - = emptyUDs - - | not (all type_determines_value theta) - || not (computeArity ci_key <= idArity f) - || not (length dicts == length theta) - || not (any (interestingDict env) dicts) -- Note [Interesting dictionary arguments] - -- See also Note [Specialisations already covered] + | not (want_calls_for f) -- Imported from elsewhere + || null ci_key -- No useful specialisation + -- See also Note [Specialisations already covered] = -- pprTrace "mkCallUDs: discarding" _trace_doc - emptyUDs -- Not overloaded, or no specialisation wanted + emptyUDs | otherwise = -- pprTrace "mkCallUDs: keeping" _trace_doc singleCall f ci_key where - _trace_doc = vcat [ppr f, ppr args, ppr (map (interestingDict env) dicts)] + _trace_doc = vcat [ppr f, ppr args, ppr ci_key] pis = fst $ splitPiTys $ idType f - theta = getTheta pis - constrained_tyvars = tyCoVarsOfTypes theta + constrained_tyvars = tyCoVarsOfTypes $ getTheta pis ci_key :: [SpecArg] - ci_key = fmap (\(t, a) -> - case t of - Named (binderVar -> tyVar) - | tyVar `elemVarSet` constrained_tyvars - -> case a of - Type ty -> SpecType ty - _ -> pprPanic "ci_key" $ ppr a - | otherwise - -> UnspecType - Anon InvisArg _ -> SpecDict a - Anon VisArg _ -> UnspecArg - ) $ zip pis args - - dicts = getSpecDicts ci_key + ci_key = dropWhileEndLE (not . isSpecDict) $ + zipWith mk_spec_arg args pis + -- Drop trailing args until we get to a SpecDict + -- In this way the RULE has as few args as possible, + -- which broadens its applicability, since rules only + -- fire when saturated + + mk_spec_arg :: CoreExpr -> TyCoBinder -> SpecArg + mk_spec_arg arg (Named bndr) + | binderVar bndr `elemVarSet` constrained_tyvars + = case arg of + Type ty -> SpecType ty + _ -> pprPanic "ci_key" $ ppr arg + | otherwise = UnspecType + + -- For "InvisArg", which are the type-class dictionaries, + -- we decide on a case by case basis if we want to specialise + -- on this argument; if so, SpecDict, if not UnspecArg + mk_spec_arg arg (Anon InvisArg pred) + | type_determines_value pred + , interestingDict env arg -- Note [Interesting dictionary arguments] + = SpecDict arg + | otherwise = UnspecArg + + mk_spec_arg _ (Anon VisArg _) + = UnspecArg want_calls_for f = isLocalId f || isJust (maybeUnfoldingTemplate (realIdUnfolding f)) -- For imported things, we gather call instances if @@ -2280,12 +2415,18 @@ mkCallUDs' env f args {- Note [Type determines value] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Only specialise if all overloading is on non-IP *class* params, -because these are the ones whose *type* determines their *value*. In -parrticular, with implicit params, the type args *don't* say what the -value of the implicit param is! See #7101 - -However, consider +Only specialise on non-IP *class* params, because these are the ones +whose *type* determines their *value*. In particular, with implicit +params, the type args *don't* say what the value of the implicit param +is! See #7101. + +So we treat implicit params just like ordinary arguments for the +purposes of specialisation. Note that we still want to specialise +functions with implicit params if they have *other* dicts which are +class params; see #17930. + +One apparent additional complexity involves type families. For +example, consider type family D (v::*->*) :: Constraint type instance D [] = () f :: D v => v Char -> Int @@ -2296,8 +2437,7 @@ and it's good to specialise f at this dictionary. So the question is: can an implicit parameter "hide inside" a type-family constraint like (D a). Well, no. We don't allow type instance D Maybe = ?x:Int -Hence the IrredPred case in type_determines_value. -See #7785. +Hence the IrredPred case in type_determines_value. See #7785. Note [Interesting dictionary arguments] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2593,20 +2733,20 @@ mapAndCombineSM f (x:xs) = do (y, uds1) <- f x extendTvSubstList :: SpecEnv -> [(TyVar,Type)] -> SpecEnv extendTvSubstList env tv_binds - = env { se_subst = CoreSubst.extendTvSubstList (se_subst env) tv_binds } + = env { se_subst = Core.extendTvSubstList (se_subst env) tv_binds } substTy :: SpecEnv -> Type -> Type -substTy env ty = CoreSubst.substTy (se_subst env) ty +substTy env ty = Core.substTy (se_subst env) ty substCo :: SpecEnv -> Coercion -> Coercion -substCo env co = CoreSubst.substCo (se_subst env) co +substCo env co = Core.substCo (se_subst env) co substBndr :: SpecEnv -> CoreBndr -> (SpecEnv, CoreBndr) -substBndr env bs = case CoreSubst.substBndr (se_subst env) bs of +substBndr env bs = case Core.substBndr (se_subst env) bs of (subst', bs') -> (env { se_subst = subst' }, bs') substBndrs :: SpecEnv -> [CoreBndr] -> (SpecEnv, [CoreBndr]) -substBndrs env bs = case CoreSubst.substBndrs (se_subst env) bs of +substBndrs env bs = case Core.substBndrs (se_subst env) bs of (subst', bs') -> (env { se_subst = subst' }, bs') cloneBindSM :: SpecEnv -> CoreBind -> SpecM (SpecEnv, SpecEnv, CoreBind) @@ -2614,7 +2754,7 @@ cloneBindSM :: SpecEnv -> CoreBind -> SpecM (SpecEnv, SpecEnv, CoreBind) -- Return the substitution to use for RHSs, and the one to use for the body cloneBindSM env@(SE { se_subst = subst, se_interesting = interesting }) (NonRec bndr rhs) = do { us <- getUniqueSupplyM - ; let (subst', bndr') = CoreSubst.cloneIdBndr subst us bndr + ; let (subst', bndr') = Core.cloneIdBndr subst us bndr interesting' | interestingDict env rhs = interesting `extendVarSet` bndr' | otherwise = interesting @@ -2623,7 +2763,7 @@ cloneBindSM env@(SE { se_subst = subst, se_interesting = interesting }) (NonRec cloneBindSM env@(SE { se_subst = subst, se_interesting = interesting }) (Rec pairs) = do { us <- getUniqueSupplyM - ; let (subst', bndrs') = CoreSubst.cloneRecIdBndrs subst us (map fst pairs) + ; let (subst', bndrs') = Core.cloneRecIdBndrs subst us (map fst pairs) env' = env { se_subst = subst' , se_interesting = interesting `extendVarSetList` [ v | (v,r) <- pairs, interestingDict env r ] } @@ -2633,9 +2773,9 @@ newDictBndr :: SpecEnv -> CoreBndr -> SpecM CoreBndr -- Make up completely fresh binders for the dictionaries -- Their bindings are going to float outwards newDictBndr env b = do { uniq <- getUniqueM - ; let n = idName b - ty' = substTy env (idType b) - ; return (mkUserLocalOrCoVar (nameOccName n) uniq ty' (getSrcSpan n)) } + ; let n = idName b + ty' = substTy env (idType b) + ; return (mkUserLocalOrCoVar (nameOccName n) uniq ty' (getSrcSpan n)) } newSpecIdSM :: Id -> Type -> Maybe JoinArity -> SpecM Id -- Give the new Id a similar occurrence name to the old one ===================================== compiler/typecheck/TcSplice.hs ===================================== @@ -1645,7 +1645,7 @@ reifyDataCon isGadtDataCon tys dc -- constructors can be declared infix. -- See Note [Infix GADT constructors] in TcTyClsDecls. | dataConIsInfix dc && not isGadtDataCon -> - ASSERT( arg_tys `lengthIs` 2 ) do + ASSERT( r_arg_tys `lengthIs` 2 ) do { let [r_a1, r_a2] = r_arg_tys [s1, s2] = dcdBangs ; return $ TH.InfixC (s1,r_a1) name (s2,r_a2) } @@ -1664,7 +1664,7 @@ reifyDataCon isGadtDataCon tys dc { cxt <- reifyCxt theta' ; ex_tvs'' <- reifyTyVars ex_tvs' ; return (TH.ForallC ex_tvs'' cxt main_con) } - ; ASSERT( arg_tys `equalLength` dcdBangs ) + ; ASSERT( r_arg_tys `equalLength` dcdBangs ) ret_con } {- ===================================== rts/linker/PEi386.c ===================================== @@ -776,12 +776,12 @@ HsPtr addLibrarySearchPath_PEi386(pathchar* dll_path) WCHAR* abs_path = malloc(sizeof(WCHAR) * init_buf_size); DWORD wResult = GetFullPathNameW(dll_path, bufsize, abs_path, NULL); if (!wResult){ - sysErrorBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError()); + IF_DEBUG(linker, debugBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError())); } else if (wResult > init_buf_size) { abs_path = realloc(abs_path, sizeof(WCHAR) * wResult); if (!GetFullPathNameW(dll_path, bufsize, abs_path, NULL)) { - sysErrorBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError()); + IF_DEBUG(linker, debugBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError())); } } ===================================== testsuite/tests/overloadedrecflds/should_fail/T17965.hs ===================================== @@ -0,0 +1,4 @@ +{-# LANGUAGE DuplicateRecordFields #-} +main = return () +newtype Record a = Record { f :: a -> a } +class C a where f :: a -> a ===================================== testsuite/tests/overloadedrecflds/should_fail/T17965.stderr ===================================== @@ -0,0 +1,5 @@ + +T17965.hs:4:17: error: + Multiple declarations of ‘f’ + Declared at: T17965.hs:3:29 + T17965.hs:4:17 ===================================== testsuite/tests/overloadedrecflds/should_fail/all.T ===================================== @@ -32,3 +32,4 @@ test('hasfieldfail03', normal, compile_fail, ['']) test('T14953', [extra_files(['T14953_A.hs', 'T14953_B.hs'])], multimod_compile_fail, ['T14953', '']) test('DuplicateExports', normal, compile_fail, ['']) +test('T17965', normal, compile_fail, ['']) ===================================== testsuite/tests/perf/compiler/T16473.stdout ===================================== @@ -68,15 +68,15 @@ Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @ Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>>= @ Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>> @ Identity _ (Main) +Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) +Rule fired: SPEC/Main $fMonadStateT_$c>>= @Identity _ (Main) +Rule fired: SPEC/Main $fMonadStateT_$c>> @Identity _ (Main) Rule fired: Class op return (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @ Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>>= @ Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT_$c>> @ Identity _ (Main) +Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) +Rule fired: SPEC/Main $fMonadStateT_$c>>= @Identity _ (Main) +Rule fired: SPEC/Main $fMonadStateT_$c>> @Identity _ (Main) Rule fired: Class op return (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) @@ -84,14 +84,20 @@ Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @ Identity _ (Main) +Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT @ Identity _ (Main) +Rule fired: SPEC/Main $fApplicativeStateT @Identity _ (Main) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) Rule fired: Class op fmap (BUILTIN) Rule fired: Class op fmap (BUILTIN) +Rule fired: Class op fmap (BUILTIN) +Rule fired: Class op fmap (BUILTIN) +Rule fired: SPEC/Main $fFunctorStateT_$cfmap @Identity _ (Main) +Rule fired: Class op fmap (BUILTIN) +Rule fired: SPEC/Main $fFunctorStateT_$cfmap @Identity _ (Main) +Rule fired: Class op fmap (BUILTIN) Rule fired: Class op return (BUILTIN) Rule fired: Class op return (BUILTIN) Rule fired: Class op >>= (BUILTIN) @@ -105,34 +111,33 @@ Rule fired: Class op fmap (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op >>= (BUILTIN) Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fFunctorStateT @ Identity _ (Main) -Rule fired: - SPEC/Main $fApplicativeStateT_$cpure @ Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @ Identity _ (Main) +Rule fired: SPEC/Main $fFunctorStateT @Identity _ (Main) +Rule fired: SPEC/Main $fApplicativeStateT_$cpure @Identity _ (Main) +Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @Identity _ (Main) Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fApplicativeStateT_$c*> @ Identity _ (Main) +Rule fired: SPEC/Main $fApplicativeStateT_$c*> @Identity _ (Main) +Rule fired: Class op fmap (BUILTIN) +Rule fired: SPEC/Main $fFunctorStateT @Identity _ (Main) +Rule fired: SPEC/Main $fApplicativeStateT_$cpure @Identity _ (Main) +Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @Identity _ (Main) +Rule fired: SPEC/Main $fApplicativeStateT_$c*> @Identity _ (Main) +Rule fired: SPEC/Main $fMonadStateT @Identity _ (Main) +Rule fired: Class op $p1Monad (BUILTIN) +Rule fired: Class op $p1Applicative (BUILTIN) Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC/Main $fFunctorStateT @ Identity _ (Main) -Rule fired: - SPEC/Main $fApplicativeStateT_$cpure @ Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$c<*> @ Identity _ (Main) -Rule fired: SPEC/Main $fApplicativeStateT_$c*> @ Identity _ (Main) -Rule fired: SPEC/Main $fMonadStateT @ Identity _ (Main) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op <*> (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) Rule fired: Class op fmap (BUILTIN) -Rule fired: Class op fmap (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op <*> (BUILTIN) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op $p1Applicative (BUILTIN) Rule fired: Class op fmap (BUILTIN) Rule fired: Class op >>= (BUILTIN) -Rule fired: Class op fmap (BUILTIN) -Rule fired: SPEC go @ (StateT (Sum Int) Identity) (Main) +Rule fired: SPEC go @(StateT (Sum Int) Identity) (Main) Rule fired: Class op $p1Monad (BUILTIN) Rule fired: Class op pure (BUILTIN) -Rule fired: SPEC/Main $fMonadStateT @ Identity _ (Main) -Rule fired: SPEC go @ (StateT (Sum Int) Identity) (Main) +Rule fired: SPEC/Main $fMonadStateT @Identity _ (Main) +Rule fired: SPEC go @(StateT (Sum Int) Identity) (Main) ===================================== testsuite/tests/simplCore/should_compile/Makefile ===================================== @@ -2,6 +2,11 @@ TOP=../../.. include $(TOP)/mk/boilerplate.mk include $(TOP)/mk/test.mk +T17966: + $(RM) -f T17966.o T17966.hi + - '$(TEST_HC)' $(TEST_HC_OPTS) -O -c -ddump-spec T17966.hs 2> /dev/null | grep 'SPEC' + # Expecting a SPEC rule for $cm + T17409: $(RM) -f T17409.o T17409.hi - '$(TEST_HC)' $(TEST_HC_OPTS) -O -c -dverbose-core2core -dsuppress-uniques T17409.hs 2> /dev/null | grep '\' ===================================== testsuite/tests/simplCore/should_compile/T17810.hs ===================================== @@ -0,0 +1,7 @@ +module T17801 where + +import Control.Monad.Except +import T17810a + +f :: ExceptT e (TCMT IO) () +f = liftReduce ===================================== testsuite/tests/simplCore/should_compile/T17810a.hs ===================================== @@ -0,0 +1,27 @@ +module T17810a where + +import Control.Monad.Except + +class Monad m => ReadTCState m where + locallyTCState :: m () + liftReduce :: m () + +instance ReadTCState m => ReadTCState (ExceptT err m) where + locallyTCState = undefined + liftReduce = lift liftReduce + +instance MonadIO m => ReadTCState (TCMT m) where + locallyTCState = (undefined <$> liftReduce) <* TCM (\_ -> return ()) + liftReduce = undefined + +newtype TCMT m a = TCM { unTCM :: () -> m a } + +instance MonadIO m => Functor (TCMT m) where + fmap f (TCM m) = TCM $ \r -> liftM f (m r ) + +instance MonadIO m => Applicative (TCMT m) where + pure x = TCM (\_ -> return x) + (<*>) (TCM mf) (TCM m) = TCM $ \r -> ap (mf r) (m r) + +instance MonadIO m => Monad (TCMT m) where + (>>=) (TCM m) k = TCM $ \r -> m r >>= \x -> unTCM (k x) r ===================================== testsuite/tests/simplCore/should_compile/T17930.hs ===================================== @@ -0,0 +1,10 @@ +{-# LANGUAGE ImplicitParams #-} +module T17930 where + +foo :: (?b :: Bool, Show a) => a -> String +foo x | ?b = show x ++ "!" + | otherwise = show x ++ "." +{-# INLINABLE[0] foo #-} + +str :: String +str = let ?b = True in foo "Hello" ===================================== testsuite/tests/simplCore/should_compile/T17930.stderr ===================================== @@ -0,0 +1,2 @@ +$sfoo :: (?b::Bool) => [Char] -> [Char] +$sfoo ===================================== testsuite/tests/simplCore/should_compile/T17966.hs ===================================== @@ -0,0 +1,20 @@ +{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-} + +-- The issue here is whether $cm gets a specialiation +-- See #17966 + +module T17966 where + +class C a b where + m :: Show c => a -> b -> c -> String + +instance Show b => C Bool b where + m a b c = show a ++ show b ++ show c + {-# INLINABLE [0] m #-} + +f :: (C a b, Show c) => a -> b -> c -> String +f a b c = m a b c ++ "!" +{-# INLINABLE [0] f #-} + +x :: String +x = f True () (Just 42) ===================================== testsuite/tests/simplCore/should_compile/T17966.stdout ===================================== @@ -0,0 +1,4 @@ + RULES: "SPEC $cm @()" [0] + RULES: "SPEC f @Bool @() @(Maybe Integer)" [0] +"SPEC/T17966 $fShowMaybe_$cshowList @Integer" +"SPEC/T17966 $fShowMaybe @Integer" ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -316,3 +316,10 @@ test('T17722', normal, multimod_compile, ['T17722B', '-dcore-lint -O2 -v0']) test('T17724', normal, compile, ['-dcore-lint -O2']) # N.B. output spuriously different in profiled and hpc ways. test('T17787', [ only_ways(['optasm', 'normal']), grep_errmsg(r'foo') ], compile, ['-ddump-simpl -dsuppress-uniques']) +test('T17930', [ grep_errmsg(r'^\$sfoo') ], compile, ['-O -ddump-spec -dsuppress-uniques -dsuppress-idinfo']) +test('spec004', [ grep_errmsg(r'\$sfoo') ], compile, ['-O -ddump-spec -dsuppress-uniques']) +test('T17966', + normal, + makefile_test, ['T17966']) +# NB: T17810: -fspecialise-aggressively +test('T17810', normal, multimod_compile, ['T17810', '-fspecialise-aggressively -dcore-lint -O -v0']) ===================================== testsuite/tests/simplCore/should_compile/spec004.hs ===================================== @@ -0,0 +1,12 @@ +{-# LANGUAGE RankNTypes #-} + +-- Dead arguments should be dropped in specialisations. See !2913. + +module ShouldCompile where + +foo :: () -> Show a => a -> String +foo _x y = show y ++ "!" +{-# NOINLINE[0] foo #-} + +bar :: String +bar = foo () (42 :: Int) ===================================== testsuite/tests/simplCore/should_compile/spec004.stderr ===================================== @@ -0,0 +1,84 @@ + +==================== Specialise ==================== +Result size of Specialise + = {terms: 53, types: 46, coercions: 0, joins: 0/0} + +-- RHS size: {terms: 14, types: 12, coercions: 0, joins: 0/0} +$sfoo [InlPrag=NOINLINE[0]] :: Int -> [Char] +[LclId] +$sfoo + = \ (y :: Int) -> + GHC.Base.build + @Char + (\ (@b) (c [OS=OneShot] :: Char -> b -> b) (n [OS=OneShot] :: b) -> + GHC.Base.foldr + @Char + @b + c + (GHC.CString.unpackFoldrCString# @b "!"# c n) + (show @Int GHC.Show.$fShowInt y)) + +-- RHS size: {terms: 17, types: 17, coercions: 0, joins: 0/0} +foo [InlPrag=NOINLINE[0]] :: forall a. () -> Show a => a -> String +[LclIdX, + Arity=3, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [0 30 0] 150 40}, + RULES: "SPEC foo @Int" [0] + forall (dk :: ()) ($dShow :: Show Int). foo @Int dk $dShow = $sfoo] +foo + = \ (@a) _ [Occ=Dead] ($dShow :: Show a) (y :: a) -> + GHC.Base.build + @Char + (\ (@b) (c [OS=OneShot] :: Char -> b -> b) (n [OS=OneShot] :: b) -> + GHC.Base.foldr + @Char + @b + c + (GHC.CString.unpackFoldrCString# @b "!"# c n) + (show @a $dShow y)) + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +$trModule :: GHC.Prim.Addr# +[LclId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +$trModule = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +$trModule :: GHC.Types.TrName +[LclId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +$trModule = GHC.Types.TrNameS $trModule + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +$trModule :: GHC.Prim.Addr# +[LclId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 50 0}] +$trModule = "ShouldCompile"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +$trModule :: GHC.Types.TrName +[LclId, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +$trModule = GHC.Types.TrNameS $trModule + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +ShouldCompile.$trModule :: GHC.Types.Module +[LclIdX, + Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, + WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] +ShouldCompile.$trModule = GHC.Types.Module $trModule $trModule + +-- RHS size: {terms: 5, types: 1, coercions: 0, joins: 0/0} +bar :: String +[LclIdX, + Unf=Unf{Src=, TopLvl=True, Value=False, ConLike=False, + WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 50 0}] +bar = foo @Int GHC.Tuple.() GHC.Show.$fShowInt (GHC.Types.I# 42#) + + + ===================================== testsuite/tests/th/T17305.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE GADTs #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE TypeFamilies #-} +module T17305 where + +import Data.Kind +import Language.Haskell.TH hiding (Type) +import System.IO + +data family Foo a +data instance Foo :: Type -> Type where + MkFoo :: Foo a + +$(do i <- reify ''Foo + runIO $ hPutStrLn stderr $ pprint i + pure []) ===================================== testsuite/tests/th/T17305.stderr ===================================== @@ -0,0 +1,3 @@ +data family T17305.Foo (a_0 :: *) :: * +data instance T17305.Foo where + T17305.MkFoo :: forall (a_1 :: *) . T17305.Foo a_1 ===================================== testsuite/tests/th/all.T ===================================== @@ -489,6 +489,7 @@ test('T16980a', expect_broken(16980), compile_fail, ['']) test('T17270a', extra_files(['T17270.hs']), multimod_compile, ['T17270', '-v0']) test('T17270b', extra_files(['T17270.hs']), multimod_compile, ['T17270', '-fenable-th-splice-warnings -v0']) test('T17296', normal, compile, ['-v0']) +test('T17305', normal, compile, ['-v0']) test('T17380', normal, compile_fail, ['']) test('T17394', normal, compile, ['-v0 -ddump-splices -dsuppress-uniques']) test('T17379a', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/98ea4b70f1122b264399e004cfab00904cb7720c...3697a0480bf86f06dcbb0021ef65963de7e2278b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/98ea4b70f1122b264399e004cfab00904cb7720c...3697a0480bf86f06dcbb0021ef65963de7e2278b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 18:14:06 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Thu, 14 May 2020 14:14:06 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18185 Message-ID: <5ebd8a6e1de8d_61673f81cc06592c11311040@gitlab.haskell.org.mail> Ryan Scott pushed new branch wip/T18185 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18185 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 19:05:54 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 14 May 2020 15:05:54 -0400 Subject: [Git][ghc/ghc][wip/backports] 4 commits: Fix two ASSERT buglets in reifyDataCon Message-ID: <5ebd9692cc7da_6167122db45c113160fb@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/backports at Glasgow Haskell Compiler / GHC Commits: 9eb3f663 by Ryan Scott at 2020-05-14T15:05:48-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). (cherry picked from commit cfb66d181ac45ce3d934bda3521b94277e6eb683) - - - - - f30e8941 by Adam Gundry at 2020-05-14T15:05:48-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. (cherry picked from commit 0d8c7a6c7c3513089668f49efb0a2dd8b4bbe74a) - - - - - 4061ff3c by Ben Gamari at 2020-05-14T15:05:48-04:00 Ensure that printMinimalImports closes handle Fixes #18166. (cherry picked from commit 5afc160dee7142c96a842037fb64bee1429ad9ec) - - - - - 29ca4c51 by Ben Gamari at 2020-05-14T15:05:48-04:00 rts: Make non-existent linker search path merely a warning As noted in #18105, previously this resulted in a rather intrusive error message. This is in contrast to the general expectation that search paths are merely places to look, not places that must exist. Fixes #18105. (cherry picked from commit 24af9f30681444380c25465f555599da563713cb) - - - - - 10 changed files: - compiler/basicTypes/RdrName.hs - compiler/rename/RnNames.hs - compiler/typecheck/TcSplice.hs - rts/linker/PEi386.c - + testsuite/tests/overloadedrecflds/should_fail/T17965.hs - + testsuite/tests/overloadedrecflds/should_fail/T17965.stderr - testsuite/tests/overloadedrecflds/should_fail/all.T - + testsuite/tests/th/T17305.hs - + testsuite/tests/th/T17305.stderr - testsuite/tests/th/all.T Changes: ===================================== compiler/basicTypes/RdrName.hs ===================================== @@ -57,7 +57,7 @@ module RdrName ( gresToAvailInfo, -- ** Global 'RdrName' mapping elements: 'GlobalRdrElt', 'Provenance', 'ImportSpec' - GlobalRdrElt(..), isLocalGRE, isRecFldGRE, greLabel, + GlobalRdrElt(..), isLocalGRE, isRecFldGRE, isOverloadedRecFldGRE, greLabel, unQualOK, qualSpecOK, unQualSpecOK, pprNameProvenance, Parent(..), greParent_maybe, @@ -842,6 +842,12 @@ isRecFldGRE :: GlobalRdrElt -> Bool isRecFldGRE (GRE {gre_par = FldParent{}}) = True isRecFldGRE _ = False +isOverloadedRecFldGRE :: GlobalRdrElt -> Bool +-- ^ Is this a record field defined with DuplicateRecordFields? +-- (See Note [Parents for record fields]) +isOverloadedRecFldGRE (GRE {gre_par = FldParent{par_lbl = Just _}}) = True +isOverloadedRecFldGRE _ = False + -- Returns the field label of this GRE, if it has one greLabel :: GlobalRdrElt -> Maybe FieldLabelString greLabel (GRE{gre_par = FldParent{par_lbl = Just lbl}}) = Just lbl ===================================== compiler/rename/RnNames.hs ===================================== @@ -635,9 +635,12 @@ extendGlobalRdrEnvRn avails new_fixities | otherwise = return (extendGlobalRdrEnv env gre) where - name = gre_name gre - occ = nameOccName name - dups = filter isLocalGRE (lookupGlobalRdrEnv env occ) + occ = greOccName gre + dups = filter isDupGRE (lookupGlobalRdrEnv env occ) + -- Duplicate GREs are those defined locally with the same OccName, + -- except cases where *both* GREs are DuplicateRecordFields (#17965). + isDupGRE gre' = isLocalGRE gre' + && not (isOverloadedRecFldGRE gre && isOverloadedRecFldGRE gre') {- ********************************************************************* @@ -1611,9 +1614,8 @@ printMinimalImports imports_w_usage = do { imports' <- getMinimalImports imports_w_usage ; this_mod <- getModule ; dflags <- getDynFlags - ; liftIO $ - do { h <- openFile (mkFilename dflags this_mod) WriteMode - ; printForUser dflags h neverQualify (vcat (map ppr imports')) } + ; liftIO $ withFile (mkFilename dflags this_mod) WriteMode $ \h -> + printForUser dflags h neverQualify (vcat (map ppr imports')) -- The neverQualify is important. We are printing Names -- but they are in the context of an 'import' decl, and -- we never qualify things inside there @@ -1769,14 +1771,13 @@ addDupDeclErr gres@(gre : _) = addErrAt (getSrcSpan (last sorted_names)) $ -- Report the error at the later location vcat [text "Multiple declarations of" <+> - quotes (ppr (nameOccName name)), + quotes (ppr (greOccName gre)), -- NB. print the OccName, not the Name, because the -- latter might not be in scope in the RdrEnv and so will -- be printed qualified. text "Declared at:" <+> vcat (map (ppr . nameSrcLoc) sorted_names)] where - name = gre_name gre sorted_names = sortWith nameSrcLoc (map gre_name gres) ===================================== compiler/typecheck/TcSplice.hs ===================================== @@ -1645,7 +1645,7 @@ reifyDataCon isGadtDataCon tys dc -- constructors can be declared infix. -- See Note [Infix GADT constructors] in TcTyClsDecls. | dataConIsInfix dc && not isGadtDataCon -> - ASSERT( arg_tys `lengthIs` 2 ) do + ASSERT( r_arg_tys `lengthIs` 2 ) do { let [r_a1, r_a2] = r_arg_tys [s1, s2] = dcdBangs ; return $ TH.InfixC (s1,r_a1) name (s2,r_a2) } @@ -1664,7 +1664,7 @@ reifyDataCon isGadtDataCon tys dc { cxt <- reifyCxt theta' ; ex_tvs'' <- reifyTyVars ex_tvs' ; return (TH.ForallC ex_tvs'' cxt main_con) } - ; ASSERT( arg_tys `equalLength` dcdBangs ) + ; ASSERT( r_arg_tys `equalLength` dcdBangs ) ret_con } {- ===================================== rts/linker/PEi386.c ===================================== @@ -776,12 +776,12 @@ HsPtr addLibrarySearchPath_PEi386(pathchar* dll_path) WCHAR* abs_path = malloc(sizeof(WCHAR) * init_buf_size); DWORD wResult = GetFullPathNameW(dll_path, bufsize, abs_path, NULL); if (!wResult){ - sysErrorBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError()); + IF_DEBUG(linker, debugBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError())); } else if (wResult > init_buf_size) { abs_path = realloc(abs_path, sizeof(WCHAR) * wResult); if (!GetFullPathNameW(dll_path, bufsize, abs_path, NULL)) { - sysErrorBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError()); + IF_DEBUG(linker, debugBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError())); } } ===================================== testsuite/tests/overloadedrecflds/should_fail/T17965.hs ===================================== @@ -0,0 +1,4 @@ +{-# LANGUAGE DuplicateRecordFields #-} +main = return () +newtype Record a = Record { f :: a -> a } +class C a where f :: a -> a ===================================== testsuite/tests/overloadedrecflds/should_fail/T17965.stderr ===================================== @@ -0,0 +1,5 @@ + +T17965.hs:4:17: error: + Multiple declarations of ‘f’ + Declared at: T17965.hs:3:29 + T17965.hs:4:17 ===================================== testsuite/tests/overloadedrecflds/should_fail/all.T ===================================== @@ -32,3 +32,4 @@ test('hasfieldfail03', normal, compile_fail, ['']) test('T14953', [extra_files(['T14953_A.hs', 'T14953_B.hs'])], multimod_compile_fail, ['T14953', '']) test('DuplicateExports', normal, compile_fail, ['']) +test('T17965', normal, compile_fail, ['']) ===================================== testsuite/tests/th/T17305.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE GADTs #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE TypeFamilies #-} +module T17305 where + +import Data.Kind +import Language.Haskell.TH hiding (Type) +import System.IO + +data family Foo a +data instance Foo :: Type -> Type where + MkFoo :: Foo a + +$(do i <- reify ''Foo + runIO $ hPutStrLn stderr $ pprint i + pure []) ===================================== testsuite/tests/th/T17305.stderr ===================================== @@ -0,0 +1,3 @@ +data family T17305.Foo (a_0 :: *) :: * +data instance T17305.Foo where + T17305.MkFoo :: forall (a_1 :: *) . T17305.Foo a_1 ===================================== testsuite/tests/th/all.T ===================================== @@ -489,6 +489,7 @@ test('T16980a', expect_broken(16980), compile_fail, ['']) test('T17270a', extra_files(['T17270.hs']), multimod_compile, ['T17270', '-v0']) test('T17270b', extra_files(['T17270.hs']), multimod_compile, ['T17270', '-fenable-th-splice-warnings -v0']) test('T17296', normal, compile, ['-v0']) +test('T17305', normal, compile, ['-v0']) test('T17380', normal, compile_fail, ['']) test('T17394', normal, compile, ['-v0 -ddump-splices -dsuppress-uniques']) test('T17379a', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3697a0480bf86f06dcbb0021ef65963de7e2278b...29ca4c5121f1b1b08417bc6b87bc7915a20fdd42 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3697a0480bf86f06dcbb0021ef65963de7e2278b...29ca4c5121f1b1b08417bc6b87bc7915a20fdd42 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 21:27:34 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 14 May 2020 17:27:34 -0400 Subject: [Git][ghc/ghc][wip/backports] 12 commits: rts: Zero block flags with -DZ Message-ID: <5ebdb7c6d87c5_61673f81afe3293c113271b6@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/backports at Glasgow Haskell Compiler / GHC Commits: 22fe8c6c by Ben Gamari at 2020-05-14T17:27:22-04:00 rts: Zero block flags with -DZ Block flags are very useful for determining the state of a block. However, some block allocator users don't touch them, leading to misleading values. Ensure that we zero then when zero-on-gc is set. This is safe and makes the flags more useful during debugging. - - - - - 3e605c37 by Ben Gamari at 2020-05-14T17:27:22-04:00 nonmoving: Fix incorrect failed_to_evac value during deadlock gc Previously we would incorrectly set the failed_to_evac flag if we evacuated a value due to a deadlock GC. This would cause us to mark more things as dirty than strictly necessary. It also turned up a nasty but which I will fix next. - - - - - 5d3ef6bc by Ben Gamari at 2020-05-14T17:27:22-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - a2275146 by Ben Gamari at 2020-05-14T17:27:22-04:00 nonmoving: Optimise the write barrier (cherry picked from commit a636eadac1f30bae37aeb6526f94893293f098b8) - - - - - 76278971 by Ömer Sinan Ağacan at 2020-05-14T17:27:22-04:00 FastString: fix eager reading of string ptr in hashStr This read causes NULL dereferencing when len is 0. Fixes #17909 In the reproducer in #17909 this bug is triggered as follows: - SimplOpt.dealWithStringLiteral is called with a single-char string ("=" in #17909) - tailFS gets called on the FastString of the single-char string. - tailFS checks the length of the string, which is 1, and calls mkFastStringByteString on the tail of the ByteString, which is an empty ByteString as the original ByteString has only one char. - ByteString's unsafeUseAsCStringLen returns (NULL, 0) for the empty ByteString, which is passed to mkFastStringWith. - mkFastStringWith gets hash of the NULL pointer via hashStr, which fails on empty strings because of this bug. (cherry picked from commit d15b61608a542f6349b42224140b7d227b88ef4e) - - - - - f1fcaec7 by Simon Peyton Jones at 2020-05-14T17:27:22-04:00 Improve error handling for VTA + deferred type errors This fixes #17792 See Note [VTA for out-of-scope functions] in TcExpr (cherry picked from commit 335b18bac3c361d243f427b66e67c2c94f5c6494) - - - - - 951a7783 by Simon Peyton Jones at 2020-05-14T17:27:22-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 (cherry picked from commit 658bda511237593bb80389280d0364180648058d) - - - - - 6bc44deb by Sylvain Henry at 2020-05-14T17:27:22-04:00 Rts: show errno on failure (#18033) (cherry picked from commit 4875d419ba066e479f7ac07f8b39ebe10c855859) - - - - - e5f5e5ab by Ryan Scott at 2020-05-14T17:27:22-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). (cherry picked from commit cfb66d181ac45ce3d934bda3521b94277e6eb683) - - - - - 880a6591 by Adam Gundry at 2020-05-14T17:27:22-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. (cherry picked from commit 0d8c7a6c7c3513089668f49efb0a2dd8b4bbe74a) - - - - - 73263d82 by Ben Gamari at 2020-05-14T17:27:22-04:00 Ensure that printMinimalImports closes handle Fixes #18166. (cherry picked from commit 5afc160dee7142c96a842037fb64bee1429ad9ec) - - - - - 2b7c1326 by Ben Gamari at 2020-05-14T17:27:22-04:00 rts: Make non-existent linker search path merely a warning As noted in #18105, previously this resulted in a rather intrusive error message. This is in contrast to the general expectation that search paths are merely places to look, not places that must exist. Fixes #18105. (cherry picked from commit 24af9f30681444380c25465f555599da563713cb) - - - - - 28 changed files: - compiler/basicTypes/RdrName.hs - compiler/rename/RnNames.hs - compiler/typecheck/TcExpr.hs - compiler/typecheck/TcHsType.hs - compiler/typecheck/TcSplice.hs - compiler/utils/FastString.hs - rts/Updates.h - rts/linker/PEi386.c - rts/posix/itimer/Pthread.c - rts/sm/BlockAlloc.c - rts/sm/Evac.c - rts/sm/NonMoving.c - rts/sm/NonMovingMark.c - rts/sm/NonMovingScav.c - rts/sm/Storage.c - + testsuite/tests/overloadedrecflds/should_fail/T17965.hs - + testsuite/tests/overloadedrecflds/should_fail/T17965.stderr - testsuite/tests/overloadedrecflds/should_fail/all.T - + testsuite/tests/partial-sigs/should_compile/T18008.hs - + testsuite/tests/partial-sigs/should_compile/T18008.stderr - testsuite/tests/partial-sigs/should_compile/all.T - + testsuite/tests/th/T17305.hs - + testsuite/tests/th/T17305.stderr - testsuite/tests/th/all.T - + testsuite/tests/typecheck/should_compile/T17792.hs - + testsuite/tests/typecheck/should_compile/T17792.stderr - testsuite/tests/typecheck/should_compile/all.T - testsuite/tests/typecheck/should_fail/T13834.stderr Changes: ===================================== compiler/basicTypes/RdrName.hs ===================================== @@ -57,7 +57,7 @@ module RdrName ( gresToAvailInfo, -- ** Global 'RdrName' mapping elements: 'GlobalRdrElt', 'Provenance', 'ImportSpec' - GlobalRdrElt(..), isLocalGRE, isRecFldGRE, greLabel, + GlobalRdrElt(..), isLocalGRE, isRecFldGRE, isOverloadedRecFldGRE, greLabel, unQualOK, qualSpecOK, unQualSpecOK, pprNameProvenance, Parent(..), greParent_maybe, @@ -842,6 +842,12 @@ isRecFldGRE :: GlobalRdrElt -> Bool isRecFldGRE (GRE {gre_par = FldParent{}}) = True isRecFldGRE _ = False +isOverloadedRecFldGRE :: GlobalRdrElt -> Bool +-- ^ Is this a record field defined with DuplicateRecordFields? +-- (See Note [Parents for record fields]) +isOverloadedRecFldGRE (GRE {gre_par = FldParent{par_lbl = Just _}}) = True +isOverloadedRecFldGRE _ = False + -- Returns the field label of this GRE, if it has one greLabel :: GlobalRdrElt -> Maybe FieldLabelString greLabel (GRE{gre_par = FldParent{par_lbl = Just lbl}}) = Just lbl ===================================== compiler/rename/RnNames.hs ===================================== @@ -635,9 +635,12 @@ extendGlobalRdrEnvRn avails new_fixities | otherwise = return (extendGlobalRdrEnv env gre) where - name = gre_name gre - occ = nameOccName name - dups = filter isLocalGRE (lookupGlobalRdrEnv env occ) + occ = greOccName gre + dups = filter isDupGRE (lookupGlobalRdrEnv env occ) + -- Duplicate GREs are those defined locally with the same OccName, + -- except cases where *both* GREs are DuplicateRecordFields (#17965). + isDupGRE gre' = isLocalGRE gre' + && not (isOverloadedRecFldGRE gre && isOverloadedRecFldGRE gre') {- ********************************************************************* @@ -1611,9 +1614,8 @@ printMinimalImports imports_w_usage = do { imports' <- getMinimalImports imports_w_usage ; this_mod <- getModule ; dflags <- getDynFlags - ; liftIO $ - do { h <- openFile (mkFilename dflags this_mod) WriteMode - ; printForUser dflags h neverQualify (vcat (map ppr imports')) } + ; liftIO $ withFile (mkFilename dflags this_mod) WriteMode $ \h -> + printForUser dflags h neverQualify (vcat (map ppr imports')) -- The neverQualify is important. We are printing Names -- but they are in the context of an 'import' decl, and -- we never qualify things inside there @@ -1769,14 +1771,13 @@ addDupDeclErr gres@(gre : _) = addErrAt (getSrcSpan (last sorted_names)) $ -- Report the error at the later location vcat [text "Multiple declarations of" <+> - quotes (ppr (nameOccName name)), + quotes (ppr (greOccName gre)), -- NB. print the OccName, not the Name, because the -- latter might not be in scope in the RdrEnv and so will -- be printed qualified. text "Declared at:" <+> vcat (map (ppr . nameSrcLoc) sorted_names)] where - name = gre_name gre sorted_names = sortWith nameSrcLoc (map gre_name gres) ===================================== compiler/typecheck/TcExpr.hs ===================================== @@ -1080,10 +1080,6 @@ isHsValArg (HsValArg {}) = True isHsValArg (HsTypeArg {}) = False isHsValArg (HsArgPar {}) = False -isHsTypeArg :: HsArg tm ty -> Bool -isHsTypeArg (HsTypeArg {}) = True -isHsTypeArg _ = False - isArgPar :: HsArg tm ty -> Bool isArgPar (HsArgPar {}) = True isArgPar (HsValArg {}) = False @@ -1218,14 +1214,6 @@ tcArgs :: LHsExpr GhcRn -- ^ The function itself (for err msgs only) -> TcM (HsWrapper, [LHsExprArgOut], TcSigmaType) -- ^ (a wrapper for the function, the tc'd args, result type) tcArgs fun orig_fun_ty fun_orig orig_args herald - | fun_is_out_of_scope - , any isHsTypeArg orig_args - = failM -- See Note [VTA for out-of-scope functions] - -- We have /already/ emitted a CHoleCan constraint (in tcInferFun), - -- which will later cough up a "Variable not in scope error", so - -- we can simply fail now, avoiding a confusing error cascade - - | otherwise = go [] 1 orig_fun_ty orig_args where -- Don't count visible type arguments when determining how many arguments @@ -1247,6 +1235,10 @@ tcArgs fun orig_fun_ty fun_orig orig_args herald } go acc_args n fun_ty (HsTypeArg l hs_ty_arg : args) + | fun_is_out_of_scope -- See Note [VTA for out-of-scope functions] + = go acc_args (n+1) fun_ty args + + | otherwise = do { (wrap1, upsilon_ty) <- topInstantiateInferred fun_orig fun_ty -- wrap1 :: fun_ty "->" upsilon_ty ; case tcSplitForAllTy_maybe upsilon_ty of @@ -1337,17 +1329,23 @@ generate an immediate failure (in tc_app_err), saying that a function of type 'alpha' can't be applied to Bool. That's insane! And indeed users complain bitterly (#13834, #17150.) -The right error is the CHoleCan, which reports 'wurble' as out of -scope, and tries to give its type. +The right error is the CHoleCan, which has /already/ been emitted by +tcUnboundId. It later reports 'wurble' as out of scope, and tries to +give its type. + +Fortunately in tcArgs we still have access to the function, so we can +check if it is a HsUnboundVar. We use this info to simply skip over +any visible type arguments. We've already inferred the type of the +function, so we'll /already/ have emitted a CHoleCan constraint; +failing preserves that constraint. -Fortunately in tcArgs we still have acces to the function, so -we can check if it is a HsUnboundVar. If so, we simply fail -immediately. We've already inferred the type of the function, -so we'll /already/ have emitted a CHoleCan constraint; failing -preserves that constraint. +We do /not/ want to fail altogether in this case (via failM) becuase +that may abandon an entire instance decl, which (in the presence of +-fdefer-type-errors) leads to leading to #17792. -A mild shortcoming of this approach is that we thereby -don't typecheck any of the arguments, but so be it. +Downside; the typechecked term has lost its visible type arguments; we +don't even kind-check them. But let's jump that bridge if we come to +it. Meanwhile, let's not crash! Note [Visible type application zonk] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/typecheck/TcHsType.hs ===================================== @@ -725,6 +725,7 @@ tc_hs_type mode forall@(HsForAllTy { hst_fvf = fvf, hst_bndrs = hs_tvs m_telescope = Just (sep (map ppr hs_tvs)) ; emitResidualTvConstraint skol_info m_telescope tvs' tclvl wanted + -- See Note [Skolem escape and forall-types] ; return (mkForAllTys bndrs ty') } @@ -913,6 +914,26 @@ under these conditions. See related Note [Wildcards in visible type application] here and Note [The wildcard story for types] in GHC.Hs.Types +Note [Skolem escape and forall-types] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider + f :: forall a. (forall kb (b :: kb). Proxy '[a, b]) -> () + +The Proxy '[a,b] forces a and b to have the same kind. But a's +kind must be bound outside the 'forall a', and hence escapes. +We discover this by building an implication constraint for +each forall. So the inner implication constraint will look like + forall kb (b::kb). kb ~ ka +where ka is a's kind. We can't unify these two, /even/ if ka is +unification variable, because it would be untouchable inside +this inner implication. + +That's what the pushLevelAndCaptureConstraints, plus subsequent +emitResidualTvConstraint is all about, when kind-checking +HsForAllTy. + +Note that we don't need to /simplify/ the constraints here +because we aren't generalising. We just capture them. -} {- ********************************************************************* @@ -2810,10 +2831,13 @@ kindGeneralizeAll ty = do { traceTc "kindGeneralizeAll" empty ; kindGeneralizeSome (const True) ty } -- | Specialized version of 'kindGeneralizeSome', but where no variables --- can be generalized. Use this variant when it is unknowable whether metavariables --- might later be constrained. --- See Note [Recipe for checking a signature] for why and where this --- function is needed. +-- can be generalized, but perhaps some may neeed to be promoted. +-- Use this variant when it is unknowable whether metavariables might +-- later be constrained. +-- +-- To see why this promotion is needed, see +-- Note [Recipe for checking a signature], and especially +-- Note [Promotion in signatures]. kindGeneralizeNone :: TcType -- needn't be zonked -> TcM () kindGeneralizeNone ty @@ -3148,7 +3172,7 @@ tcHsPartialSigType ctxt sig_ty ; return (wcs, wcx, theta, tau) } - -- No kind-generalization here: + -- No kind-generalization here, but perhaps some promotion ; kindGeneralizeNone (mkSpecForAllTys implicit_tvs $ mkSpecForAllTys explicit_tvs $ mkPhiTy theta $ @@ -3159,6 +3183,14 @@ tcHsPartialSigType ctxt sig_ty -- See Note [Extra-constraint holes in partial type signatures] ; emitNamedWildCardHoleConstraints wcs + -- Zonk, so that any nested foralls can "see" their occurrences + -- See Note [Checking partial type signatures], in + -- the bullet on Nested foralls. + ; implicit_tvs <- mapM zonkTcTyVarToTyVar implicit_tvs + ; explicit_tvs <- mapM zonkTcTyVarToTyVar explicit_tvs + ; theta <- mapM zonkTcType theta + ; tau <- zonkTcType tau + -- We return a proper (Name,TyVar) environment, to be sure that -- we bring the right name into scope in the function body. -- Test case: partial-sigs/should_compile/LocalDefinitionBug @@ -3167,7 +3199,7 @@ tcHsPartialSigType ctxt sig_ty -- NB: checkValidType on the final inferred type will be -- done later by checkInferredPolyId. We can't do it - -- here because we don't have a complete tuype to check + -- here because we don't have a complete type to check ; traceTc "tcHsPartialSigType" (ppr tv_prs) ; return (wcs, wcx, tv_prs, theta, tau) } @@ -3189,13 +3221,32 @@ tcPartialContext hs_theta {- Note [Checking partial type signatures] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -See also Note [Recipe for checking a signature] +This Note is about tcHsPartialSigType. See also +Note [Recipe for checking a signature] -When we have a parital signature like - f,g :: forall a. a -> _ +When we have a partial signature like + f :: forall a. a -> _ we do the following -* In TcSigs.tcUserSigType we return a PartialSig, which (unlike +* tcHsPartialSigType does not make quantified type (forall a. blah) + and then instantiate it -- it makes no sense to instantiate a type + with wildcards in it. Rather, tcHsPartialSigType just returns the + 'a' and the 'blah' separately. + + Nor, for the same reason, do we push a level in tcHsPartialSigType. + +* We instantiate 'a' to a unification variable, a TyVarTv, and /not/ + a skolem; hence the "_Tv" in bindExplicitTKBndrs_Tv. Consider + f :: forall a. a -> _ + g :: forall b. _ -> b + f = g + g = f + They are typechecked as a recursive group, with monomorphic types, + so 'a' and 'b' will get unified together. Very like kind inference + for mutually recursive data types (sans CUSKs or SAKS); see + Note [Cloning for tyvar binders] in GHC.Tc.Gen.HsType + +* In GHC.Tc.Gen.Sig.tcUserSigType we return a PartialSig, which (unlike the companion CompleteSig) contains the original, as-yet-unchecked source-code LHsSigWcType @@ -3203,18 +3254,34 @@ we do the following call tchsPartialSig (defined near this Note). It kind-checks the LHsSigWcType, creating fresh unification variables for each "_" wildcard. It's important that the wildcards for f and g are distinct - becase they migh get instantiated completely differently. E.g. + because they might get instantiated completely differently. E.g. f,g :: forall a. a -> _ f x = a g x = True It's really as if we'd written two distinct signatures. -* Note that we don't make quantified type (forall a. blah) and then - instantiate it -- it makes no sense to instantiate a type with - wildcards in it. Rather, tcHsPartialSigType just returns the - 'a' and the 'blah' separately. - - Nor, for the same reason, do we push a level in tcHsPartialSigType. +* Nested foralls. Consider + f :: forall b. (forall a. a -> _) -> b + We do /not/ allow the "_" to be instantiated to 'a'; but we do + (as before) allow it to be instantiated to the (top level) 'b'. + Why not? Because suppose + f x = (x True, x 'c') + We must instantiate that (forall a. a -> _) when typechecking + f's body, so we must know precisely where all the a's are; they + must not be hidden under (filled-in) unification variables! + + We achieve this in the usual way: we push a level at a forall, + so now the unification variable for the "_" can't unify with + 'a'. + +* Just as for ordinary signatures, we must zonk the type after + kind-checking it, to ensure that all the nested forall binders can + see their occurrenceds + + Just as for ordinary signatures, this zonk also gets any Refl casts + out of the way of instantiation. Example: #18008 had + foo :: (forall a. (Show a => blah) |> Refl) -> _ + and that Refl cast messed things up. See #18062. Note [Extra-constraint holes in partial type signatures] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/typecheck/TcSplice.hs ===================================== @@ -1645,7 +1645,7 @@ reifyDataCon isGadtDataCon tys dc -- constructors can be declared infix. -- See Note [Infix GADT constructors] in TcTyClsDecls. | dataConIsInfix dc && not isGadtDataCon -> - ASSERT( arg_tys `lengthIs` 2 ) do + ASSERT( r_arg_tys `lengthIs` 2 ) do { let [r_a1, r_a2] = r_arg_tys [s1, s2] = dcdBangs ; return $ TH.InfixC (s1,r_a1) name (s2,r_a2) } @@ -1664,7 +1664,7 @@ reifyDataCon isGadtDataCon tys dc { cxt <- reifyCxt theta' ; ex_tvs'' <- reifyTyVars ex_tvs' ; return (TH.ForallC ex_tvs'' cxt main_con) } - ; ASSERT( arg_tys `equalLength` dcdBangs ) + ; ASSERT( r_arg_tys `equalLength` dcdBangs ) ret_con } {- ===================================== compiler/utils/FastString.hs ===================================== @@ -531,16 +531,22 @@ cmpStringPrefix ptr1 ptr2 len = do r <- memcmp ptr1 ptr2 len return (r == 0) - hashStr :: Ptr Word8 -> Int -> Int -- use the Addr to produce a hash value between 0 & m (inclusive) hashStr (Ptr a#) (I# len#) = loop 0# 0# - where - loop h n | isTrue# (n ==# len#) = I# h - | otherwise = loop h2 (n +# 1#) - where - !c = ord# (indexCharOffAddr# a# n) - !h2 = (h *# 16777619#) `xorI#` c + where + loop h n = + if isTrue# (n ==# len#) then + I# h + else + let + -- DO NOT move this let binding! indexCharOffAddr# reads from the + -- pointer so we need to evaluate this based on the length check + -- above. Not doing this right caused #17909. + !c = ord# (indexCharOffAddr# a# n) + !h2 = (h *# 16777619#) `xorI#` c + in + loop h2 (n +# 1#) -- ----------------------------------------------------------------------------- -- Operations ===================================== rts/Updates.h ===================================== @@ -50,22 +50,21 @@ \ prim_write_barrier; \ OVERWRITING_CLOSURE(p1); \ - IF_NONMOVING_WRITE_BARRIER_ENABLED { \ - ccall updateRemembSetPushThunk_(BaseReg, p1 "ptr"); \ - } \ - StgInd_indirectee(p1) = p2; \ - prim_write_barrier; \ - SET_INFO(p1, stg_BLACKHOLE_info); \ - LDV_RECORD_CREATE(p1); \ bd = Bdescr(p1); \ if (bdescr_gen_no(bd) != 0 :: bits16) { \ + IF_NONMOVING_WRITE_BARRIER_ENABLED { \ + ccall updateRemembSetPushThunk_(BaseReg, p1 "ptr"); \ + } \ recordMutableCap(p1, TO_W_(bdescr_gen_no(bd))); \ TICK_UPD_OLD_IND(); \ - and_then; \ } else { \ TICK_UPD_NEW_IND(); \ - and_then; \ - } + } \ + StgInd_indirectee(p1) = p2; \ + prim_write_barrier; \ + SET_INFO(p1, stg_BLACKHOLE_info); \ + LDV_RECORD_CREATE(p1); \ + and_then; #else /* !CMINUSMINUS */ @@ -73,28 +72,26 @@ INLINE_HEADER void updateWithIndirection (Capability *cap, StgClosure *p1, StgClosure *p2) { - bdescr *bd; - ASSERT( (P_)p1 != (P_)p2 ); /* not necessarily true: ASSERT( !closure_IND(p1) ); */ /* occurs in RaiseAsync.c:raiseAsync() */ /* See Note [Heap memory barriers] in SMP.h */ write_barrier(); - OVERWRITING_CLOSURE(p1); - IF_NONMOVING_WRITE_BARRIER_ENABLED { - updateRemembSetPushThunk(cap, (StgThunk*)p1); - } - ((StgInd *)p1)->indirectee = p2; - write_barrier(); - SET_INFO(p1, &stg_BLACKHOLE_info); - LDV_RECORD_CREATE(p1); - bd = Bdescr((StgPtr)p1); + bdescr *bd = Bdescr((StgPtr)p1); if (bd->gen_no != 0) { + IF_NONMOVING_WRITE_BARRIER_ENABLED { + updateRemembSetPushThunk(cap, (StgThunk*)p1); + } recordMutableCap(p1, cap, bd->gen_no); TICK_UPD_OLD_IND(); } else { TICK_UPD_NEW_IND(); } + OVERWRITING_CLOSURE(p1); + ((StgInd *)p1)->indirectee = p2; + write_barrier(); + SET_INFO(p1, &stg_BLACKHOLE_info); + LDV_RECORD_CREATE(p1); } #endif /* CMINUSMINUS */ ===================================== rts/linker/PEi386.c ===================================== @@ -776,12 +776,12 @@ HsPtr addLibrarySearchPath_PEi386(pathchar* dll_path) WCHAR* abs_path = malloc(sizeof(WCHAR) * init_buf_size); DWORD wResult = GetFullPathNameW(dll_path, bufsize, abs_path, NULL); if (!wResult){ - sysErrorBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError()); + IF_DEBUG(linker, debugBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError())); } else if (wResult > init_buf_size) { abs_path = realloc(abs_path, sizeof(WCHAR) * wResult); if (!GetFullPathNameW(dll_path, bufsize, abs_path, NULL)) { - sysErrorBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError()); + IF_DEBUG(linker, debugBelch("addLibrarySearchPath[GetFullPathNameW]: %" PATH_FMT " (Win32 error %lu)", dll_path, GetLastError())); } } ===================================== rts/posix/itimer/Pthread.c ===================================== @@ -109,13 +109,13 @@ static void *itimer_thread_func(void *_handle_tick) timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC); if (timerfd == -1) { - barf("timerfd_create"); + barf("timerfd_create: %s", strerror(errno)); } if (!TFD_CLOEXEC) { fcntl(timerfd, F_SETFD, FD_CLOEXEC); } if (timerfd_settime(timerfd, 0, &it, NULL)) { - barf("timerfd_settime"); + barf("timerfd_settime: %s", strerror(errno)); } #endif @@ -123,7 +123,7 @@ static void *itimer_thread_func(void *_handle_tick) if (USE_TIMERFD_FOR_ITIMER) { if (read(timerfd, &nticks, sizeof(nticks)) != sizeof(nticks)) { if (errno != EINTR) { - barf("Itimer: read(timerfd) failed"); + barf("Itimer: read(timerfd) failed: %s", strerror(errno)); } } } else { @@ -169,7 +169,7 @@ initTicker (Time interval, TickProc handle_tick) pthread_setname_np(thread, "ghc_ticker"); #endif } else { - barf("Itimer: Failed to spawn thread"); + barf("Itimer: Failed to spawn thread: %s", strerror(errno)); } } @@ -203,7 +203,7 @@ exitTicker (bool wait) // wait for ticker to terminate if necessary if (wait) { if (pthread_join(thread, NULL)) { - sysErrorBelch("Itimer: Failed to join"); + sysErrorBelch("Itimer: Failed to join: %s", strerror(errno)); } closeMutex(&mutex); closeCondition(&start_cond); ===================================== rts/sm/BlockAlloc.c ===================================== @@ -233,6 +233,12 @@ initGroup(bdescr *head) last->blocks = 0; last->link = head; } + +#if defined(DEBUG) + for (uint32_t i=0; i < head->blocks; i++) { + head[i].flags = 0; + } +#endif } #if SIZEOF_VOID_P == SIZEOF_LONG @@ -792,6 +798,12 @@ freeGroup(bdescr *p) ASSERT(p->free != (P_)-1); +#if defined(DEBUG) + for (uint32_t i=0; i < p->blocks; i++) { + p[i].flags = 0; + } +#endif + node = p->node; p->free = (void *)-1; /* indicates that this block is free */ ===================================== rts/sm/Evac.c ===================================== @@ -80,16 +80,15 @@ alloc_for_copy (uint32_t size, uint32_t gen_no) if (gen_no < gct->evac_gen_no) { if (gct->eager_promotion) { gen_no = gct->evac_gen_no; + } else if (RTS_UNLIKELY(RtsFlags.GcFlags.useNonmoving) && deadlock_detect_gc) { + /* See Note [Deadlock detection under nonmoving collector]. */ + gen_no = oldest_gen->no; } else { gct->failed_to_evac = true; } } if (RTS_UNLIKELY(RtsFlags.GcFlags.useNonmoving)) { - /* See Note [Deadlock detection under nonmoving collector]. */ - if (deadlock_detect_gc) - gen_no = oldest_gen->no; - if (gen_no == oldest_gen->no) { gct->copied += size; to = nonmovingAllocate(gct->cap, size); ===================================== rts/sm/NonMoving.c ===================================== @@ -228,6 +228,10 @@ Mutex concurrent_coll_finished_lock; * - Note [Static objects under the nonmoving collector] (Storage.c) describes * treatment of static objects. * + * - Note [Dirty flags in the non-moving collector] (NonMoving.c) describes + * how we use the DIRTY flags associated with MUT_VARs and TVARs to improve + * barrier efficiency. + * * * Note [Concurrent non-moving collection] * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -369,6 +373,7 @@ Mutex concurrent_coll_finished_lock; * approximate due to concurrent collection and ultimately seems more costly * than the problem demands. * + * * Note [Spark management under the nonmoving collector] * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Every GC, both minor and major, prunes the spark queue (using @@ -387,6 +392,88 @@ Mutex concurrent_coll_finished_lock; * BF_EVACUATED flag won't be set on the nursery blocks) and will consequently * only prune dead sparks living in the non-moving heap. * + * + * Note [Dirty flags in the non-moving collector] + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Some mutable object types (e.g. MUT_VARs, TVARs) have a one-bit dirty flag + * encoded in their info table pointer. The moving collector's uses this flag + * to minimize redundant mut_list entries. The flag is preserves the following + * simple invariant: + * + * An object being marked as dirty implies that the object is on mut_list. + * + * This allows a nice optimisation in the write barrier (e.g. dirty_MUT_VAR): + * if we write to an already-dirty object there is no need to + * push it to the mut_list as we know it's already there. + * + * During GC (scavenging) we will then keep track of whether all of the + * object's reference have been promoted. If so we can mark the object as clean. + * If not then we re-add it to mut_list and mark it as dirty. + * + * In the non-moving collector we use the same dirty flag to implement a + * related optimisation on the non-moving write barrier: Specifically, the + * snapshot invariant only requires that the non-moving write barrier applies + * to the *first* mutation to an object after collection begins. To achieve this, + * we impose the following invariant: + * + * An object being marked as dirty implies that all of its fields are on + * the mark queue (or, equivalently, update remembered set). + * + * With this guarantee we can safely make the the write barriers dirty objects + * no-ops. We perform this optimisation for the following object types: + * + * - MVAR + * - TVAR + * - MUT_VAR + * + * However, maintaining this invariant requires great care. For instance, + * consider the case of an MVar (which has two pointer fields) before + * preparatory collection: + * + * Non-moving heap ┊ Moving heap + * gen 1 ┊ gen 0 + * ──────────────────────┼──────────────────────────────── + * ┊ + * MVAR A ────────────────→ X + * (dirty) ───────────╮ + * ┊ ╰────→ Y + * ┊ │ + * ┊ │ + * ╭───────────────────────╯ + * │ ┊ + * ↓ ┊ + * Z ┊ + * ┊ + * + * During the preparatory collection we promote Y to the nonmoving heap but + * fail to promote X. Since the failed_to_evac field is conservative (being set + * if *any* of the fields are not promoted), this gives us: + * + * Non-moving heap ┊ Moving heap + * gen 1 ┊ gen 0 + * ──────────────────────┼──────────────────────────────── + * ┊ + * MVAR A ────────────────→ X + * (dirty) ┊ + * │ ┊ + * │ ┊ + * ↓ ┊ + * Y ┊ + * │ ┊ + * │ ┊ + * ↓ ┊ + * Z ┊ + * ┊ + * + * This is bad. When we resume mutation a mutator may mutate MVAR A; since it's + * already dirty we would fail to add Y to the update remembered set, breaking the + * snapshot invariant and potentially losing track of the liveness of Z. + * + * To avoid this nonmovingScavengeOne we eagerly pushes the values of the + * fields of all objects which it fails to evacuate (e.g. MVAR A) to the update + * remembered set during the preparatory GC. This allows us to safely skip the + * non-moving write barrier without jeopardizing the snapshot invariant. + * */ memcount nonmoving_live_words = 0; ===================================== rts/sm/NonMovingMark.c ===================================== @@ -27,6 +27,7 @@ #include "sm/Storage.h" #include "CNF.h" +static bool check_in_nonmoving_heap(StgClosure *p); static void mark_closure (MarkQueue *queue, const StgClosure *p, StgClosure **origin); static void mark_tso (MarkQueue *queue, StgTSO *tso); static void mark_stack (MarkQueue *queue, StgStack *stack); @@ -450,10 +451,17 @@ push (MarkQueue *q, const MarkQueueEnt *ent) void markQueuePushClosureGC (MarkQueue *q, StgClosure *p) { + if (!check_in_nonmoving_heap(p)) { + return; + } + /* We should not make it here if we are doing a deadlock detect GC. * See Note [Deadlock detection under nonmoving collector]. + * This is actually no longer true due to call in nonmovingScavengeOne + * introduced due to Note [Dirty flags in the non-moving collector] + * (see NonMoving.c). */ - ASSERT(!deadlock_detect_gc); + //ASSERT(!deadlock_detect_gc); // Are we at the end of the block? if (q->top->head == MARK_QUEUE_BLOCK_ENTRIES) { ===================================== rts/sm/NonMovingScav.c ===================================== @@ -31,6 +31,11 @@ nonmovingScavengeOne (StgClosure *q) gct->eager_promotion = saved_eager_promotion; if (gct->failed_to_evac) { mvar->header.info = &stg_MVAR_DIRTY_info; + + // Note [Dirty flags in the non-moving collector] in NonMoving.c + markQueuePushClosureGC(&gct->cap->upd_rem_set.queue, (StgClosure *) mvar->head); + markQueuePushClosureGC(&gct->cap->upd_rem_set.queue, (StgClosure *) mvar->tail); + markQueuePushClosureGC(&gct->cap->upd_rem_set.queue, (StgClosure *) mvar->value); } else { mvar->header.info = &stg_MVAR_CLEAN_info; } @@ -46,6 +51,10 @@ nonmovingScavengeOne (StgClosure *q) gct->eager_promotion = saved_eager_promotion; if (gct->failed_to_evac) { tvar->header.info = &stg_TVAR_DIRTY_info; + + // Note [Dirty flags in the non-moving collector] in NonMoving.c + markQueuePushClosureGC(&gct->cap->upd_rem_set.queue, (StgClosure *) tvar->current_value); + markQueuePushClosureGC(&gct->cap->upd_rem_set.queue, (StgClosure *) tvar->first_watch_queue_entry); } else { tvar->header.info = &stg_TVAR_CLEAN_info; } @@ -160,16 +169,21 @@ nonmovingScavengeOne (StgClosure *q) } case MUT_VAR_CLEAN: - case MUT_VAR_DIRTY: + case MUT_VAR_DIRTY: { + StgMutVar *mv = (StgMutVar *) p; gct->eager_promotion = false; - evacuate(&((StgMutVar *)p)->var); + evacuate(&mv->var); gct->eager_promotion = saved_eager_promotion; if (gct->failed_to_evac) { ((StgClosure *)q)->header.info = &stg_MUT_VAR_DIRTY_info; + + // Note [Dirty flags in the non-moving collector] in NonMoving.c + markQueuePushClosureGC(&gct->cap->upd_rem_set.queue, (StgClosure *) mv->var); } else { ((StgClosure *)q)->header.info = &stg_MUT_VAR_CLEAN_info; } break; + } case BLOCKING_QUEUE: { ===================================== rts/sm/Storage.c ===================================== @@ -1206,6 +1206,7 @@ dirty_MUT_VAR(StgRegTable *reg, StgMutVar *mvar, StgClosure *old) mvar->header.info = &stg_MUT_VAR_DIRTY_info; recordClosureMutated(cap, (StgClosure *) mvar); IF_NONMOVING_WRITE_BARRIER_ENABLED { + // See Note [Dirty flags in the non-moving collector] in NonMoving.c updateRemembSetPushClosure_(reg, old); } } @@ -1228,6 +1229,7 @@ dirty_TVAR(Capability *cap, StgTVar *p, p->header.info = &stg_TVAR_DIRTY_info; recordClosureMutated(cap,(StgClosure*)p); IF_NONMOVING_WRITE_BARRIER_ENABLED { + // See Note [Dirty flags in the non-moving collector] in NonMoving.c updateRemembSetPushClosure(cap, old); } } @@ -1309,6 +1311,7 @@ update_MVAR(StgRegTable *reg, StgClosure *p, StgClosure *old_val) { Capability *cap = regTableToCapability(reg); IF_NONMOVING_WRITE_BARRIER_ENABLED { + // See Note [Dirty flags in the non-moving collector] in NonMoving.c StgMVar *mvar = (StgMVar *) p; updateRemembSetPushClosure(cap, old_val); updateRemembSetPushClosure(cap, (StgClosure *) mvar->head); ===================================== testsuite/tests/overloadedrecflds/should_fail/T17965.hs ===================================== @@ -0,0 +1,4 @@ +{-# LANGUAGE DuplicateRecordFields #-} +main = return () +newtype Record a = Record { f :: a -> a } +class C a where f :: a -> a ===================================== testsuite/tests/overloadedrecflds/should_fail/T17965.stderr ===================================== @@ -0,0 +1,5 @@ + +T17965.hs:4:17: error: + Multiple declarations of ‘f’ + Declared at: T17965.hs:3:29 + T17965.hs:4:17 ===================================== testsuite/tests/overloadedrecflds/should_fail/all.T ===================================== @@ -32,3 +32,4 @@ test('hasfieldfail03', normal, compile_fail, ['']) test('T14953', [extra_files(['T14953_A.hs', 'T14953_B.hs'])], multimod_compile_fail, ['T14953', '']) test('DuplicateExports', normal, compile_fail, ['']) +test('T17965', normal, compile_fail, ['']) ===================================== testsuite/tests/partial-sigs/should_compile/T18008.hs ===================================== @@ -0,0 +1,7 @@ +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE PartialTypeSignatures #-} +module Bug where + +f :: (forall a. Show a => a -> String) -> _ +f s = s () + ===================================== testsuite/tests/partial-sigs/should_compile/T18008.stderr ===================================== @@ -0,0 +1,5 @@ + +T18008.hs:5:43: warning: [-Wpartial-type-signatures (in -Wdefault)] + • Found type wildcard ‘_’ standing for ‘String’ + • In the type ‘(forall a. Show a => a -> String) -> _’ + In the type signature: f :: (forall a. Show a => a -> String) -> _ ===================================== testsuite/tests/partial-sigs/should_compile/all.T ===================================== @@ -95,3 +95,4 @@ test('T16334', normal, compile, ['']) test('T16728', normal, compile, ['']) test('T16728a', normal, compile, ['']) test('T16728b', normal, compile, ['']) +test('T18008', normal, compile, ['']) ===================================== testsuite/tests/th/T17305.hs ===================================== @@ -0,0 +1,16 @@ +{-# LANGUAGE GADTs #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE TypeFamilies #-} +module T17305 where + +import Data.Kind +import Language.Haskell.TH hiding (Type) +import System.IO + +data family Foo a +data instance Foo :: Type -> Type where + MkFoo :: Foo a + +$(do i <- reify ''Foo + runIO $ hPutStrLn stderr $ pprint i + pure []) ===================================== testsuite/tests/th/T17305.stderr ===================================== @@ -0,0 +1,3 @@ +data family T17305.Foo (a_0 :: *) :: * +data instance T17305.Foo where + T17305.MkFoo :: forall (a_1 :: *) . T17305.Foo a_1 ===================================== testsuite/tests/th/all.T ===================================== @@ -489,6 +489,7 @@ test('T16980a', expect_broken(16980), compile_fail, ['']) test('T17270a', extra_files(['T17270.hs']), multimod_compile, ['T17270', '-v0']) test('T17270b', extra_files(['T17270.hs']), multimod_compile, ['T17270', '-fenable-th-splice-warnings -v0']) test('T17296', normal, compile, ['-v0']) +test('T17305', normal, compile, ['-v0']) test('T17380', normal, compile_fail, ['']) test('T17394', normal, compile, ['-v0 -ddump-splices -dsuppress-uniques']) test('T17379a', normal, compile_fail, ['']) ===================================== testsuite/tests/typecheck/should_compile/T17792.hs ===================================== @@ -0,0 +1,10 @@ +{-# LANGUAGE TypeApplications #-} +{-# OPTIONS_GHC -fdefer-type-errors #-} + +module T17792 where + +class C a where + m :: a + +instance C Bool where + m = notInScope @Word ===================================== testsuite/tests/typecheck/should_compile/T17792.stderr ===================================== @@ -0,0 +1,3 @@ + +T17792.hs:10:7: warning: [-Wdeferred-out-of-scope-variables (in -Wdefault)] + Variable not in scope: notInScope :: Bool ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -693,3 +693,4 @@ test('T17202', expect_broken(17202), compile, ['']) test('T15839a', normal, compile, ['']) test('T15839b', normal, compile, ['']) test('T17343', exit_code(1), compile_and_run, ['']) +test('T17792', normal, compile, ['']) ===================================== testsuite/tests/typecheck/should_fail/T13834.stderr ===================================== @@ -1,2 +1,3 @@ -T13834.hs:5:7: error: Variable not in scope: notInScope +T13834.hs:5:7: + Variable not in scope: notInScope :: Bool -> t View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/29ca4c5121f1b1b08417bc6b87bc7915a20fdd42...2b7c13267aaec9d2b3e2c0ad94ad343993e386d1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/29ca4c5121f1b1b08417bc6b87bc7915a20fdd42...2b7c13267aaec9d2b3e2c0ad94ad343993e386d1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 22:12:03 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Thu, 14 May 2020 18:12:03 -0400 Subject: [Git][ghc/ghc][wip/T18185] Add orderingTyCon to wiredInTyCons (#18185) Message-ID: <5ebdc23326472_61673f81cc06592c1134243c@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T18185 at Glasgow Haskell Compiler / GHC Commits: 1e823a34 by Ryan Scott at 2020-05-14T17:58:56-04:00 Add orderingTyCon to wiredInTyCons (#18185) `Ordering` needs to be wired in for use in the built-in `CmpNat` and `CmpSymbol` type families, but somehow it was never added to the list of `wiredInTyCons`, leading to the various oddities observed in #18185. Easily fixed. Fixes #18185. - - - - - 3 changed files: - compiler/GHC/Builtin/Types.hs - + testsuite/tests/typecheck/should_compile/T18185.hs - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== compiler/GHC/Builtin/Types.hs ===================================== @@ -202,8 +202,11 @@ names in GHC.Builtin.Names, so they use wTcQual, wDataQual, etc -- that occurs in this list that name will be assigned the wired-in key we -- define here. -- --- Because of their infinite nature, this list excludes tuples, Any and implicit --- parameter TyCons (see Note [Built-in syntax and the OrigNameCache]). +-- Because of their infinite nature, this list excludes +-- * tuples, including boxed, unboxed and constraint tuples +--- (mkTupleTyCon, unitTyCon, pairTyCon) +-- * unboxed sums (sumTyCon) +-- See Note [Infinite families of known-key names] in GHC.Builtin.Names -- -- See also Note [Known-key names] wiredInTyCons :: [TyCon] @@ -224,6 +227,7 @@ wiredInTyCons = [ -- Units are not treated like other tuples, because they , wordTyCon , word8TyCon , listTyCon + , orderingTyCon , maybeTyCon , heqTyCon , eqTyCon ===================================== testsuite/tests/typecheck/should_compile/T18185.hs ===================================== @@ -0,0 +1,31 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeOperators #-} +module T18185 where + +import GHC.TypeLits +import Type.Reflection + +class iss :|+ is ~ oss => AddT (iss :: [Symbol]) (is :: Symbol) (oss :: [Symbol]) where + type iss :|+ is :: [Symbol] + +class (CmpSymbol is ish ~ ord, AddT'I ord is ish ist ~ oss) => AddT' ord is ish ist oss where + type AddT'I ord is ish ist :: [Symbol] + +class (CmpSymbol "a" "a" ~ o) => C1 o +class (CmpNat 1 1 ~ o) => C2 o +class ((CmpSymbol "a" "a" :: Ordering) ~ o) => C3 o +class ((CmpNat 1 1 :: Ordering) ~ o) => C4 o + +f1 :: TypeRep (CmpSymbol "a" "a") +f1 = typeRep + +f2 :: TypeRep (CmpNat 1 1) +f2 = typeRep + +f3 :: TypeRep (CmpSymbol "a" "a" :: Ordering) +f3 = typeRep + +f4 :: TypeRep (CmpNat 1 1 :: Ordering) +f4 = typeRep ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -707,3 +707,4 @@ test('T18036', normal, compile, ['']) test('T18036a', normal, compile, ['']) test('T17873', normal, compile, ['']) test('T18129', expect_broken(18129), compile, ['']) +test('T18185', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1e823a34780eccce39bf3b2a68006311368df0f1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1e823a34780eccce39bf3b2a68006311368df0f1 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 22:26:13 2020 From: gitlab at gitlab.haskell.org (Vilem-Benjamin Liepelt) Date: Thu, 14 May 2020 18:26:13 -0400 Subject: [Git][ghc/ghc][wip/buggymcbugfix/15185-enum-int] Add inline pragmas to Enum methods Message-ID: <5ebdc585db705_61678d4bb5811350767@gitlab.haskell.org.mail> Vilem-Benjamin Liepelt pushed to branch wip/buggymcbugfix/15185-enum-int at Glasgow Haskell Compiler / GHC Commits: 745cdb42 by buggymcbugfix at 2020-05-15T01:10:10+03:00 Add inline pragmas to Enum methods The INLINABLE pragmas ensure that we export stable (unoptimised) unfoldings in the interface file so we can do list fusion at usage sites. Related tickets: #15185, #8763, #18178. - - - - - 4 changed files: - compiler/GHC/Tc/Deriv/Generate.hs - libraries/base/GHC/Enum.hs - libraries/base/GHC/Word.hs - + testsuite/tests/perf/should_run/T15185.hs Changes: ===================================== compiler/GHC/Tc/Deriv/Generate.hs ===================================== @@ -588,8 +588,8 @@ gen_Enum_binds loc tycon = do [ succ_enum dflags , pred_enum dflags , to_enum dflags - , enum_from dflags - , enum_from_then dflags + , enum_from dflags -- [0 ..] + , enum_from_then dflags -- [0, 1 ..] , from_enum dflags ] aux_binds = listToBag $ map DerivAuxBind ===================================== libraries/base/GHC/Enum.hs ===================================== @@ -139,17 +139,34 @@ class Enum a where -- * @enumFromThenTo 6 8 2 :: [Int] = []@ enumFromThenTo :: a -> a -> a -> [a] - succ = toEnum . (+ 1) . fromEnum - pred = toEnum . (subtract 1) . fromEnum - enumFrom x = map toEnum [fromEnum x ..] - enumFromThen x y = map toEnum [fromEnum x, fromEnum y ..] - enumFromTo x y = map toEnum [fromEnum x .. fromEnum y] + succ = toEnum . (+ 1) . fromEnum + + pred = toEnum . (subtract 1) . fromEnum + + -- See Note [Stable Unfolding for list producers] + {-# INLINABLE enumFrom #-} + enumFrom x = map toEnum [fromEnum x ..] + + -- See Note [Stable Unfolding for list producers] + {-# INLINABLE enumFromThen #-} + enumFromThen x y = map toEnum [fromEnum x, fromEnum y ..] + + -- See Note [Stable Unfolding for list producers] + {-# INLINABLE enumFromTo #-} + enumFromTo x y = map toEnum [fromEnum x .. fromEnum y] + + -- See Note [Stable Unfolding for list producers] + {-# INLINABLE enumFromThenTo #-} enumFromThenTo x1 x2 y = map toEnum [fromEnum x1, fromEnum x2 .. fromEnum y] +-- See Note [Stable Unfolding for list producers] +{-# INLINABLE boundedEnumFrom #-} -- Default methods for bounded enumerations boundedEnumFrom :: (Enum a, Bounded a) => a -> [a] boundedEnumFrom n = map toEnum [fromEnum n .. fromEnum (maxBound `asTypeOf` n)] +-- See Note [Stable Unfolding for list producers] +{-# INLINABLE boundedEnumFromThen #-} boundedEnumFromThen :: (Enum a, Bounded a) => a -> a -> [a] boundedEnumFromThen n1 n2 | i_n2 >= i_n1 = map toEnum [i_n1, i_n2 .. fromEnum (maxBound `asTypeOf` n1)] @@ -158,6 +175,16 @@ boundedEnumFromThen n1 n2 i_n1 = fromEnum n1 i_n2 = fromEnum n2 +{- +Note [Stable Unfolding for list producers] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The INLINABLE pragmas ensure that we export stable (unoptimised) unfoldings in +the interface file so we can do list fusion at usage sites. + +Related tickets: #15185, #8763, #18178. +-} + ------------------------------------------------------------------------ -- Helper functions ------------------------------------------------------------------------ ===================================== libraries/base/GHC/Word.hs ===================================== @@ -892,10 +892,8 @@ instance Enum Word64 where | x <= fromIntegral (maxBound::Int) = I# (word2Int# x#) | otherwise = fromEnumError "Word64" x - enumFrom = integralEnumFrom - enumFromThen = integralEnumFromThen - enumFromTo = integralEnumFromTo - enumFromThenTo = integralEnumFromThenTo + enumFrom = boundedEnumFrom + enumFromThen = boundedEnumFromThen -- | @since 2.01 instance Integral Word64 where ===================================== testsuite/tests/perf/should_run/T15185.hs ===================================== @@ -0,0 +1,20 @@ +-- Ensure that we do list fusion on `foldr f z [from..to]` for various Int` and +-- `Word` types. Related tickets: #15185, #8763. + +import Control.Exception (Evaluate) + +fact :: Integral t => t -> t +fact n = product [1..n] + +main :: IO () +main = do + _ <- evaluate (fact @Int 50) + _ <- evaluate (fact @Int64 50) + _ <- evaluate (fact @Int32 50) + _ <- evaluate (fact @Int16 50) + _ <- evaluate (fact @Int8 50) + _ <- evaluate (fact @Word 50) + _ <- evaluate (fact @Word64 50) + _ <- evaluate (fact @Word32 50) + _ <- evaluate (fact @Word16 50) + _ <- evaluate (fact @Word8 50) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/745cdb42b10e05c5731a99854047d1348bedb9e4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/745cdb42b10e05c5731a99854047d1348bedb9e4 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 22:58:00 2020 From: gitlab at gitlab.haskell.org (Vilem-Benjamin Liepelt) Date: Thu, 14 May 2020 18:58:00 -0400 Subject: [Git][ghc/ghc][wip/buggymcbugfix/15185-enum-int] Add INLINABLE pragmas to Enum list producers Message-ID: <5ebdccf873746_6167124c079011353322@gitlab.haskell.org.mail> Vilem-Benjamin Liepelt pushed to branch wip/buggymcbugfix/15185-enum-int at Glasgow Haskell Compiler / GHC Commits: 331970da by buggymcbugfix at 2020-05-15T01:57:45+03:00 Add INLINABLE pragmas to Enum list producers The INLINABLE pragmas ensure that we export stable (unoptimised) unfoldings in the interface file so we can do list fusion at usage sites. Related tickets: #15185, #8763, #18178. - - - - - 4 changed files: - compiler/GHC/Tc/Deriv/Generate.hs - libraries/base/GHC/Enum.hs - libraries/base/GHC/Word.hs - + testsuite/tests/perf/should_run/T15185.hs Changes: ===================================== compiler/GHC/Tc/Deriv/Generate.hs ===================================== @@ -588,8 +588,8 @@ gen_Enum_binds loc tycon = do [ succ_enum dflags , pred_enum dflags , to_enum dflags - , enum_from dflags - , enum_from_then dflags + , enum_from dflags -- [0 ..] + , enum_from_then dflags -- [0, 1 ..] , from_enum dflags ] aux_binds = listToBag $ map DerivAuxBind ===================================== libraries/base/GHC/Enum.hs ===================================== @@ -139,17 +139,34 @@ class Enum a where -- * @enumFromThenTo 6 8 2 :: [Int] = []@ enumFromThenTo :: a -> a -> a -> [a] - succ = toEnum . (+ 1) . fromEnum - pred = toEnum . (subtract 1) . fromEnum - enumFrom x = map toEnum [fromEnum x ..] - enumFromThen x y = map toEnum [fromEnum x, fromEnum y ..] - enumFromTo x y = map toEnum [fromEnum x .. fromEnum y] + succ = toEnum . (+ 1) . fromEnum + + pred = toEnum . (subtract 1) . fromEnum + + -- See Note [Stable Unfolding for list producers] + {-# INLINABLE enumFrom #-} + enumFrom x = map toEnum [fromEnum x ..] + + -- See Note [Stable Unfolding for list producers] + {-# INLINABLE enumFromThen #-} + enumFromThen x y = map toEnum [fromEnum x, fromEnum y ..] + + -- See Note [Stable Unfolding for list producers] + {-# INLINABLE enumFromTo #-} + enumFromTo x y = map toEnum [fromEnum x .. fromEnum y] + + -- See Note [Stable Unfolding for list producers] + {-# INLINABLE enumFromThenTo #-} enumFromThenTo x1 x2 y = map toEnum [fromEnum x1, fromEnum x2 .. fromEnum y] +-- See Note [Stable Unfolding for list producers] +{-# INLINABLE boundedEnumFrom #-} -- Default methods for bounded enumerations boundedEnumFrom :: (Enum a, Bounded a) => a -> [a] boundedEnumFrom n = map toEnum [fromEnum n .. fromEnum (maxBound `asTypeOf` n)] +-- See Note [Stable Unfolding for list producers] +{-# INLINABLE boundedEnumFromThen #-} boundedEnumFromThen :: (Enum a, Bounded a) => a -> a -> [a] boundedEnumFromThen n1 n2 | i_n2 >= i_n1 = map toEnum [i_n1, i_n2 .. fromEnum (maxBound `asTypeOf` n1)] @@ -158,6 +175,16 @@ boundedEnumFromThen n1 n2 i_n1 = fromEnum n1 i_n2 = fromEnum n2 +{- +Note [Stable Unfolding for list producers] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The INLINABLE pragmas ensure that we export stable (unoptimised) unfoldings in +the interface file so we can do list fusion at usage sites. + +Related tickets: #15185, #8763, #18178. +-} + ------------------------------------------------------------------------ -- Helper functions ------------------------------------------------------------------------ ===================================== libraries/base/GHC/Word.hs ===================================== @@ -892,10 +892,8 @@ instance Enum Word64 where | x <= fromIntegral (maxBound::Int) = I# (word2Int# x#) | otherwise = fromEnumError "Word64" x - enumFrom = integralEnumFrom - enumFromThen = integralEnumFromThen - enumFromTo = integralEnumFromTo - enumFromThenTo = integralEnumFromThenTo + enumFrom = boundedEnumFrom + enumFromThen = boundedEnumFromThen -- | @since 2.01 instance Integral Word64 where ===================================== testsuite/tests/perf/should_run/T15185.hs ===================================== @@ -0,0 +1,25 @@ +{-# LANGUAGE TypeApplications #-} + +-- Ensure that we do list fusion on `foldr f z [from..to]` for various Int` and +-- `Word` types. Related tickets: #15185, #8763. + +import Control.Exception (evaluate) +import Data.Int +import Data.Word + +fact :: Integral t => t -> t +fact n = product [1..n] + +main :: IO () +main = do + _ <- evaluate (fact @Int 50) + _ <- evaluate (fact @Int64 50) + _ <- evaluate (fact @Int32 50) + _ <- evaluate (fact @Int16 50) + _ <- evaluate (fact @Int8 50) + _ <- evaluate (fact @Word 50) + _ <- evaluate (fact @Word64 50) + _ <- evaluate (fact @Word32 50) + _ <- evaluate (fact @Word16 50) + _ <- evaluate (fact @Word8 50) + pure () View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/331970da5b13140892fc7e1b4f1c1fd1f94225ef -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/331970da5b13140892fc7e1b4f1c1fd1f94225ef You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 14 23:46:58 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Thu, 14 May 2020 19:46:58 -0400 Subject: [Git][ghc/ghc][wip/T18185] WIP: Add orderingTyCon to wiredInTyCons (#18185) Message-ID: <5ebdd872b4f7b_61673f81afe3293c113607cc@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T18185 at Glasgow Haskell Compiler / GHC Commits: 9894236e by Ryan Scott at 2020-05-14T19:42:58-04:00 WIP: Add orderingTyCon to wiredInTyCons (#18185) `Ordering` needs to be wired in for use in the built-in `CmpNat` and `CmpSymbol` type families, but somehow it was never added to the list of `wiredInTyCons`, leading to the various oddities observed in #18185. Easily fixed. Fixes #18185. - - - - - 4 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - + testsuite/tests/typecheck/should_compile/T18185.hs - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== compiler/GHC/Builtin/Names.hs ===================================== @@ -428,8 +428,7 @@ basicKnownKeyNames -- Annotation type checking toAnnotationWrapperName - -- The Ordering type - , orderingTyConName + -- Ordering data constructors , ordLTDataConName, ordEQDataConName, ordGTDataConName -- The SPEC type for SpecConstr ===================================== compiler/GHC/Builtin/Types.hs ===================================== @@ -202,8 +202,11 @@ names in GHC.Builtin.Names, so they use wTcQual, wDataQual, etc -- that occurs in this list that name will be assigned the wired-in key we -- define here. -- --- Because of their infinite nature, this list excludes tuples, Any and implicit --- parameter TyCons (see Note [Built-in syntax and the OrigNameCache]). +-- Because of their infinite nature, this list excludes +-- * tuples, including boxed, unboxed and constraint tuples +--- (mkTupleTyCon, unitTyCon, pairTyCon) +-- * unboxed sums (sumTyCon) +-- See Note [Infinite families of known-key names] in GHC.Builtin.Names -- -- See also Note [Known-key names] wiredInTyCons :: [TyCon] @@ -224,6 +227,7 @@ wiredInTyCons = [ -- Units are not treated like other tuples, because they , wordTyCon , word8TyCon , listTyCon + , orderingTyCon , maybeTyCon , heqTyCon , eqTyCon ===================================== testsuite/tests/typecheck/should_compile/T18185.hs ===================================== @@ -0,0 +1,31 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeOperators #-} +module T18185 where + +import GHC.TypeLits +import Type.Reflection + +class iss :|+ is ~ oss => AddT (iss :: [Symbol]) (is :: Symbol) (oss :: [Symbol]) where + type iss :|+ is :: [Symbol] + +class (CmpSymbol is ish ~ ord, AddT'I ord is ish ist ~ oss) => AddT' ord is ish ist oss where + type AddT'I ord is ish ist :: [Symbol] + +class (CmpSymbol "a" "a" ~ o) => C1 o +class (CmpNat 1 1 ~ o) => C2 o +class ((CmpSymbol "a" "a" :: Ordering) ~ o) => C3 o +class ((CmpNat 1 1 :: Ordering) ~ o) => C4 o + +f1 :: TypeRep (CmpSymbol "a" "a") +f1 = typeRep + +f2 :: TypeRep (CmpNat 1 1) +f2 = typeRep + +f3 :: TypeRep (CmpSymbol "a" "a" :: Ordering) +f3 = typeRep + +f4 :: TypeRep (CmpNat 1 1 :: Ordering) +f4 = typeRep ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -707,3 +707,4 @@ test('T18036', normal, compile, ['']) test('T18036a', normal, compile, ['']) test('T17873', normal, compile, ['']) test('T18129', expect_broken(18129), compile, ['']) +test('T18185', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9894236ee58dc1ba504bfe071a3e7a0412dbbf8a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9894236ee58dc1ba504bfe071a3e7a0412dbbf8a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 15 00:34:15 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Thu, 14 May 2020 20:34:15 -0400 Subject: [Git][ghc/ghc][wip/T18185] WIP: Add orderingTyCon to wiredInTyCons (#18185) Message-ID: <5ebde3876b745_61678d4bb5811365466@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T18185 at Glasgow Haskell Compiler / GHC Commits: 8d7fbf32 by Ryan Scott at 2020-05-14T20:33:55-04:00 WIP: Add orderingTyCon to wiredInTyCons (#18185) `Ordering` needs to be wired in for use in the built-in `CmpNat` and `CmpSymbol` type families, but somehow it was never added to the list of `wiredInTyCons`, leading to the various oddities observed in #18185. Easily fixed. Fixes #18185. - - - - - 4 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - + testsuite/tests/typecheck/should_compile/T18185.hs - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== compiler/GHC/Builtin/Names.hs ===================================== @@ -428,10 +428,6 @@ basicKnownKeyNames -- Annotation type checking toAnnotationWrapperName - -- The Ordering type - , orderingTyConName - , ordLTDataConName, ordEQDataConName, ordGTDataConName - -- The SPEC type for SpecConstr , specTyConName ===================================== compiler/GHC/Builtin/Types.hs ===================================== @@ -202,8 +202,11 @@ names in GHC.Builtin.Names, so they use wTcQual, wDataQual, etc -- that occurs in this list that name will be assigned the wired-in key we -- define here. -- --- Because of their infinite nature, this list excludes tuples, Any and implicit --- parameter TyCons (see Note [Built-in syntax and the OrigNameCache]). +-- Because of their infinite nature, this list excludes +-- * tuples, including boxed, unboxed and constraint tuples +--- (mkTupleTyCon, unitTyCon, pairTyCon) +-- * unboxed sums (sumTyCon) +-- See Note [Infinite families of known-key names] in GHC.Builtin.Names -- -- See also Note [Known-key names] wiredInTyCons :: [TyCon] @@ -224,6 +227,7 @@ wiredInTyCons = [ -- Units are not treated like other tuples, because they , wordTyCon , word8TyCon , listTyCon + , orderingTyCon , maybeTyCon , heqTyCon , eqTyCon ===================================== testsuite/tests/typecheck/should_compile/T18185.hs ===================================== @@ -0,0 +1,31 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeOperators #-} +module T18185 where + +import GHC.TypeLits +import Type.Reflection + +class iss :|+ is ~ oss => AddT (iss :: [Symbol]) (is :: Symbol) (oss :: [Symbol]) where + type iss :|+ is :: [Symbol] + +class (CmpSymbol is ish ~ ord, AddT'I ord is ish ist ~ oss) => AddT' ord is ish ist oss where + type AddT'I ord is ish ist :: [Symbol] + +class (CmpSymbol "a" "a" ~ o) => C1 o +class (CmpNat 1 1 ~ o) => C2 o +class ((CmpSymbol "a" "a" :: Ordering) ~ o) => C3 o +class ((CmpNat 1 1 :: Ordering) ~ o) => C4 o + +f1 :: TypeRep (CmpSymbol "a" "a") +f1 = typeRep + +f2 :: TypeRep (CmpNat 1 1) +f2 = typeRep + +f3 :: TypeRep (CmpSymbol "a" "a" :: Ordering) +f3 = typeRep + +f4 :: TypeRep (CmpNat 1 1 :: Ordering) +f4 = typeRep ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -707,3 +707,4 @@ test('T18036', normal, compile, ['']) test('T18036a', normal, compile, ['']) test('T17873', normal, compile, ['']) test('T18129', expect_broken(18129), compile, ['']) +test('T18185', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8d7fbf32958107ae811b40541b856898579584a2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8d7fbf32958107ae811b40541b856898579584a2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 15 01:41:50 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 14 May 2020 21:41:50 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: Improve some folds over Uniq[D]FM Message-ID: <5ebdf35e553f_61679b2e0f4113678bc@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: c05c0659 by Simon Jakobi at 2020-05-14T03:31:21-04:00 Improve some folds over Uniq[D]FM * Replace some non-deterministic lazy folds with strict folds. * Replace some O(n log n) folds in deterministic order with O(n) non-deterministic folds. * Replace some folds with set-operations on the underlying IntMaps. This reduces max residency when compiling `nofib/spectral/simple/Main.hs` with -O0 by about 1%. Maximum residency when compiling Cabal also seems reduced on the order of 3-9%. - - - - - 477f13bb by Simon Jakobi at 2020-05-14T03:31:58-04:00 Use Data.IntMap.disjoint Data.IntMap gained a dedicated `disjoint` function in containers-0.6.2.1. This patch applies this function where appropriate in hopes of modest compiler performance improvements. Closes #16806. - - - - - e9c0110c by Ben Gamari at 2020-05-14T12:25:53-04:00 IdInfo: Add reference to bitfield-packing ticket - - - - - ce715cab by Sebastian Graf at 2020-05-14T21:41:41-04:00 DmdAnal: Improve handling of precise exceptions This patch does two things: Fix possible unsoundness in what was called the "IO hack" and implement part 2.1 of the "fixing precise exceptions" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions, which, in combination with !2956, supersedes !3014 and !2525. **IO hack** The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is called `exprMayThrowPreciseException` now. I came up with two testcases exemplifying possible unsoundness (if twisted enough) in the old approach: - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. - `T13380e`: Demonstrating unsoundness of the "IO hack" when we have Nested CPR. Not currently relevant, as we don't have Nested CPR yet. - `T13380f`: Demonstrating unsoundness of the "IO hack" for safe FFI calls. Basically, the IO hack assumed that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future, see `T13380e`. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380{d,e}` (and will hopefully be robust to Nested CPR). **Precise exceptions** In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that was terribly unprincipled. That unprincipledness resulted in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception (and the existing IO hack doesn't detect that) Fixing both issues in !3014 turned out to be too complicated and had the potential to regress in the future. Hence we decided to only fix `T13380b` and augment the `Divergence` lattice with a new middle-layer element, `ExnOrDiv`, which means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. See the wiki page on Step 2.1 for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#dead-code-elimination-for-raiseio-with-isdeadenddiv-introducing-exnordiv-step-21 - - - - - 4787cf00 by Ben Gamari at 2020-05-14T21:41:41-04:00 GHC.Cmm.Opt: Handle MO_XX_Conv This MachOp was introduced by 2c959a1894311e59cd2fd469c1967491c1e488f3 but a wildcard match in cmmMachOpFoldM hid the fact that it wasn't handled. Ideally we would eliminate the match but this appears to be a larger task. Fixes #18141. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/Opt.hs - compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/LiberateCase.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Data/Graph/Ops.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Rename/Expr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/48eeb2795215044136ec8c71493bb142312ddcf7...4787cf001d7fa6acd734f64ce8627d0fe704e2a0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/48eeb2795215044136ec8c71493bb142312ddcf7...4787cf001d7fa6acd734f64ce8627d0fe704e2a0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 15 08:02:05 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 15 May 2020 04:02:05 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 2 commits: DmdAnal: Improve handling of precise exceptions Message-ID: <5ebe4c7dab6c1_6167c96b4bc113994a5@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 60dfea91 by Sebastian Graf at 2020-05-15T04:02:00-04:00 DmdAnal: Improve handling of precise exceptions This patch does two things: Fix possible unsoundness in what was called the "IO hack" and implement part 2.1 of the "fixing precise exceptions" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions, which, in combination with !2956, supersedes !3014 and !2525. **IO hack** The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is called `exprMayThrowPreciseException` now. I came up with two testcases exemplifying possible unsoundness (if twisted enough) in the old approach: - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. - `T13380e`: Demonstrating unsoundness of the "IO hack" when we have Nested CPR. Not currently relevant, as we don't have Nested CPR yet. - `T13380f`: Demonstrating unsoundness of the "IO hack" for safe FFI calls. Basically, the IO hack assumed that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future, see `T13380e`. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380{d,e}` (and will hopefully be robust to Nested CPR). **Precise exceptions** In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that was terribly unprincipled. That unprincipledness resulted in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception (and the existing IO hack doesn't detect that) Fixing both issues in !3014 turned out to be too complicated and had the potential to regress in the future. Hence we decided to only fix `T13380b` and augment the `Divergence` lattice with a new middle-layer element, `ExnOrDiv`, which means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. See the wiki page on Step 2.1 for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#dead-code-elimination-for-raiseio-with-isdeadenddiv-introducing-exnordiv-step-21 - - - - - ecc2e67a by Ben Gamari at 2020-05-15T04:02:00-04:00 GHC.Cmm.Opt: Handle MO_XX_Conv This MachOp was introduced by 2c959a1894311e59cd2fd469c1967491c1e488f3 but a wildcard match in cmmMachOpFoldM hid the fact that it wasn't handled. Ideally we would eliminate the match but this appears to be a larger task. Fixes #18141. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/LiberateCase.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/ForeignCall.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Make.hs - + testsuite/tests/cmm/opt/T18141.hs - testsuite/tests/cmm/opt/all.T - testsuite/tests/stranal/should_compile/T10482a.stderr - testsuite/tests/stranal/should_compile/T10694.stderr - + testsuite/tests/stranal/should_compile/T13380b.hs - testsuite/tests/stranal/should_compile/all.T - + testsuite/tests/stranal/should_run/T13380d.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4787cf001d7fa6acd734f64ce8627d0fe704e2a0...ecc2e67a2296986049580d785f5f78d450a83901 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4787cf001d7fa6acd734f64ce8627d0fe704e2a0...ecc2e67a2296986049580d785f5f78d450a83901 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 15 10:26:06 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Fri, 15 May 2020 06:26:06 -0400 Subject: [Git][ghc/ghc][wip/T18185] Add orderingTyCon to wiredInTyCons (#18185) Message-ID: <5ebe6e3e2f899_61673f81afdc503011417675@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T18185 at Glasgow Haskell Compiler / GHC Commits: 28ee5a1f by Ryan Scott at 2020-05-15T06:23:45-04:00 Add orderingTyCon to wiredInTyCons (#18185) `Ordering` needs to be wired in for use in the built-in `CmpNat` and `CmpSymbol` type families, but somehow it was never added to the list of `wiredInTyCons`, leading to the various oddities observed in #18185. Easily fixed by moving `orderingTyCon` from `basicKnownKeyNames` to `wiredInTyCons`. Fixes #18185. - - - - - 4 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - + testsuite/tests/typecheck/should_compile/T18185.hs - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== compiler/GHC/Builtin/Names.hs ===================================== @@ -428,10 +428,6 @@ basicKnownKeyNames -- Annotation type checking toAnnotationWrapperName - -- The Ordering type - , orderingTyConName - , ordLTDataConName, ordEQDataConName, ordGTDataConName - -- The SPEC type for SpecConstr , specTyConName ===================================== compiler/GHC/Builtin/Types.hs ===================================== @@ -202,8 +202,11 @@ names in GHC.Builtin.Names, so they use wTcQual, wDataQual, etc -- that occurs in this list that name will be assigned the wired-in key we -- define here. -- --- Because of their infinite nature, this list excludes tuples, Any and implicit --- parameter TyCons (see Note [Built-in syntax and the OrigNameCache]). +-- Because of their infinite nature, this list excludes +-- * tuples, including boxed, unboxed and constraint tuples +--- (mkTupleTyCon, unitTyCon, pairTyCon) +-- * unboxed sums (sumTyCon) +-- See Note [Infinite families of known-key names] in GHC.Builtin.Names -- -- See also Note [Known-key names] wiredInTyCons :: [TyCon] @@ -224,6 +227,7 @@ wiredInTyCons = [ -- Units are not treated like other tuples, because they , wordTyCon , word8TyCon , listTyCon + , orderingTyCon , maybeTyCon , heqTyCon , eqTyCon ===================================== testsuite/tests/typecheck/should_compile/T18185.hs ===================================== @@ -0,0 +1,31 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeOperators #-} +module T18185 where + +import GHC.TypeLits +import Type.Reflection + +class iss :|+ is ~ oss => AddT (iss :: [Symbol]) (is :: Symbol) (oss :: [Symbol]) where + type iss :|+ is :: [Symbol] + +class (CmpSymbol is ish ~ ord, AddT'I ord is ish ist ~ oss) => AddT' ord is ish ist oss where + type AddT'I ord is ish ist :: [Symbol] + +class (CmpSymbol "a" "a" ~ o) => C1 o +class (CmpNat 1 1 ~ o) => C2 o +class ((CmpSymbol "a" "a" :: Ordering) ~ o) => C3 o +class ((CmpNat 1 1 :: Ordering) ~ o) => C4 o + +f1 :: TypeRep (CmpSymbol "a" "a") +f1 = typeRep + +f2 :: TypeRep (CmpNat 1 1) +f2 = typeRep + +f3 :: TypeRep (CmpSymbol "a" "a" :: Ordering) +f3 = typeRep + +f4 :: TypeRep (CmpNat 1 1 :: Ordering) +f4 = typeRep ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -707,3 +707,4 @@ test('T18036', normal, compile, ['']) test('T18036a', normal, compile, ['']) test('T17873', normal, compile, ['']) test('T18129', expect_broken(18129), compile, ['']) +test('T18185', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/28ee5a1f407257fdcd39ac0c9fec523488da4998 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/28ee5a1f407257fdcd39ac0c9fec523488da4998 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 15 10:26:45 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Fri, 15 May 2020 06:26:45 -0400 Subject: [Git][ghc/ghc][wip/mod-rem-strict] Make `Int`'s `mod` and `rem` strict in their first arguments Message-ID: <5ebe6e65e1885_61679b2e0f41141817d@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/mod-rem-strict at Glasgow Haskell Compiler / GHC Commits: dcef6615 by Sebastian Graf at 2020-05-15T12:26:29+02:00 Make `Int`'s `mod` and `rem` strict in their first arguments They used to be strict until 4d2ac2d (9 years ago). It's obviously better to be strict for performance reasons. It also blocks #18067. NoFib results: ``` -------------------------------------------------------------------------------- Program Allocs Instrs -------------------------------------------------------------------------------- integer -1.1% +0.4% wheel-sieve2 +21.2% +20.7% -------------------------------------------------------------------------------- Min -1.1% -0.0% Max +21.2% +20.7% Geometric Mean +0.2% +0.2% ``` The regression in `wheel-sieve2` is due to reboxing that likely will go away with the resolution of #18067. See !3282 for details. Fixes #18187. - - - - - 1 changed file: - libraries/base/GHC/Real.hs Changes: ===================================== libraries/base/GHC/Real.hs ===================================== @@ -334,11 +334,12 @@ instance Integral Int where -- in GHC.Int | otherwise = a `quotInt` b - a `rem` b + !a `rem` b -- banged a, because the second branch isn't strict in a | b == 0 = divZeroError -- The quotRem CPU instruction fails for minBound `quotRem` -1, -- but minBound `rem` -1 is well-defined (0). We therefore -- special-case it. + -- But this branch is lazy in a, hence the bang to guarantee unboxing. | b == (-1) = 0 | otherwise = a `remInt` b @@ -348,11 +349,12 @@ instance Integral Int where -- in GHC.Int | otherwise = a `divInt` b - a `mod` b + !a `mod` b -- banged a, because the second branch isn't strict in a | b == 0 = divZeroError -- The divMod CPU instruction fails for minBound `divMod` -1, -- but minBound `mod` -1 is well-defined (0). We therefore -- special-case it. + -- But this branch is lazy in a, hence the bang to guarantee unboxing. | b == (-1) = 0 | otherwise = a `modInt` b View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dcef6615d765d98a3614291e8ad3256a9ee8561c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dcef6615d765d98a3614291e8ad3256a9ee8561c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 15 10:58:27 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Fri, 15 May 2020 06:58:27 -0400 Subject: [Git][ghc/ghc][wip/mod-rem-strict] Make `Int`'s `mod` and `rem` strict in their first arguments Message-ID: <5ebe75d38a893_61678d4bb58114348d8@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/mod-rem-strict at Glasgow Haskell Compiler / GHC Commits: 8129df94 by Sebastian Graf at 2020-05-15T12:58:18+02:00 Make `Int`'s `mod` and `rem` strict in their first arguments They used to be strict until 4d2ac2d (9 years ago). It's obviously better to be strict for performance reasons. It also blocks #18067. NoFib results: ``` -------------------------------------------------------------------------------- Program Allocs Instrs -------------------------------------------------------------------------------- integer -1.1% +0.4% wheel-sieve2 +21.2% +20.7% -------------------------------------------------------------------------------- Min -1.1% -0.0% Max +21.2% +20.7% Geometric Mean +0.2% +0.2% ``` The regression in `wheel-sieve2` is due to reboxing that likely will go away with the resolution of #18067. See !3282 for details. Fixes #18187. - - - - - 1 changed file: - libraries/base/GHC/Real.hs Changes: ===================================== libraries/base/GHC/Real.hs ===================================== @@ -334,11 +334,8 @@ instance Integral Int where -- in GHC.Int | otherwise = a `quotInt` b - a `rem` b + !a `rem` b -- See Note [Special case of mod and rem is lazy] | b == 0 = divZeroError - -- The quotRem CPU instruction fails for minBound `quotRem` -1, - -- but minBound `rem` -1 is well-defined (0). We therefore - -- special-case it. | b == (-1) = 0 | otherwise = a `remInt` b @@ -348,11 +345,8 @@ instance Integral Int where -- in GHC.Int | otherwise = a `divInt` b - a `mod` b + !a `mod` b -- See Note [Special case of mod and rem is lazy] | b == 0 = divZeroError - -- The divMod CPU instruction fails for minBound `divMod` -1, - -- but minBound `mod` -1 is well-defined (0). We therefore - -- special-case it. | b == (-1) = 0 | otherwise = a `modInt` b @@ -368,6 +362,15 @@ instance Integral Int where | b == (-1) && a == minBound = (overflowError, 0) | otherwise = a `divModInt` b +{- Note [Special case of mod and rem is lazy] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The `quotRem`/`divMod` CPU instruction fails for minBound `quotRem` -1, but +minBound `rem` -1 is well-defined (0). We therefore special-case for `b == -1`, +but not for `a == minBound` because of Note [Order of tests] in GHC.Int. But +now we have to make sure the function stays strict in a, to guarantee unboxing. +Hence the bang on a, see #18187. +-} + -------------------------------------------------------------- -- Instances for @Word@ -------------------------------------------------------------- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8129df947eec0d4f803fb8bdb3cfc4a7088ba2fd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8129df947eec0d4f803fb8bdb3cfc4a7088ba2fd You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 15 12:24:21 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Fri, 15 May 2020 08:24:21 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/andreask/iface_magic_numbers Message-ID: <5ebe89f540cd_6167124c079011440678@gitlab.haskell.org.mail> Andreas Klebinger pushed new branch wip/andreask/iface_magic_numbers at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/andreask/iface_magic_numbers You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 15 12:25:10 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Fri, 15 May 2020 08:25:10 -0400 Subject: [Git][ghc/ghc][wip/andreask/iface_magic_numbers] Don't variable-length encode magic iface constant. Message-ID: <5ebe8a2622017_61679b2e0f411440862@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/iface_magic_numbers at Glasgow Haskell Compiler / GHC Commits: a146a18d by Andreas Klebinger at 2020-05-15T14:24:43+02:00 Don't variable-length encode magic iface constant. We changed to use variable length encodings for many types by default, including Word32. This makes sense for numbers but not when Word32 is meant to represent four bytes. I added a FixedLengthEncoding newtype to Binary who's instances interpret their argument as a collection of bytes instead of a number. We then use this when writing/reading magic numbers to the iface file. I also took the libery to remove the dummy iface field. This fixes #18180. - - - - - 2 changed files: - compiler/GHC/Iface/Binary.hs - compiler/GHC/Utils/Binary.hs Changes: ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -123,20 +123,9 @@ readBinIface_ dflags checkHiWay traceBinIFaceReading hi_path ncu = do -- (This magic number does not change when we change -- GHC interface file format) magic <- get bh - wantedGot "Magic" (binaryInterfaceMagic platform) magic ppr + wantedGot "Magic" (binaryInterfaceMagic platform) magic (ppr . unFixedLength) errorOnMismatch "magic number mismatch: old/corrupt interface file?" - (binaryInterfaceMagic platform) magic - - -- Note [dummy iface field] - -- read a dummy 32/64 bit value. This field used to hold the - -- dictionary pointer in old interface file formats, but now - -- the dictionary pointer is after the version (where it - -- should be). Also, the serialisation of value of type "Bin - -- a" used to depend on the word size of the machine, now they - -- are always 32 bits. - case platformWordSize platform of - PW4 -> do _ <- Binary.get bh :: IO Word32; return () - PW8 -> do _ <- Binary.get bh :: IO Word64; return () + (unFixedLength $ binaryInterfaceMagic platform) (unFixedLength magic) -- Check the interface file version and ways. check_ver <- get bh @@ -198,13 +187,6 @@ writeBinIface dflags hi_path mod_iface = do let platform = targetPlatform dflags put_ bh (binaryInterfaceMagic platform) - -- dummy 32/64-bit field before the version/way for - -- compatibility with older interface file formats. - -- See Note [dummy iface field] above. - case platformWordSize platform of - PW4 -> Binary.put_ bh (0 :: Word32) - PW8 -> Binary.put_ bh (0 :: Word64) - -- The version and way descriptor go next put_ bh (show hiVersion) let way_descr = getWayDescr dflags @@ -290,10 +272,10 @@ putWithUserData log_action bh payload = do initBinMemSize :: Int initBinMemSize = 1024 * 1024 -binaryInterfaceMagic :: Platform -> Word32 +binaryInterfaceMagic :: Platform -> FixedLengthEncoding Word32 binaryInterfaceMagic platform - | target32Bit platform = 0x1face - | otherwise = 0x1face64 + | target32Bit platform = FixedLengthEncoding 0x1face + | otherwise = FixedLengthEncoding 0x1face64 -- ----------------------------------------------------------------------------- ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -52,6 +52,9 @@ module GHC.Utils.Binary putSLEB128, getSLEB128, + -- * Fixed length encoding + FixedLengthEncoding(..), + -- * Lazy Binary I/O lazyGet, lazyPut, @@ -314,18 +317,18 @@ putWord8 h !w = putPrim h 1 (\op -> poke op w) getWord8 :: BinHandle -> IO Word8 getWord8 h = getPrim h 1 peek --- putWord16 :: BinHandle -> Word16 -> IO () --- putWord16 h w = putPrim h 2 (\op -> do --- pokeElemOff op 0 (fromIntegral (w `shiftR` 8)) --- pokeElemOff op 1 (fromIntegral (w .&. 0xFF)) --- ) +putWord16 :: BinHandle -> Word16 -> IO () +putWord16 h w = putPrim h 2 (\op -> do + pokeElemOff op 0 (fromIntegral (w `shiftR` 8)) + pokeElemOff op 1 (fromIntegral (w .&. 0xFF)) + ) --- getWord16 :: BinHandle -> IO Word16 --- getWord16 h = getPrim h 2 (\op -> do --- w0 <- fromIntegral <$> peekElemOff op 0 --- w1 <- fromIntegral <$> peekElemOff op 1 --- return $! w0 `shiftL` 8 .|. w1 --- ) +getWord16 :: BinHandle -> IO Word16 +getWord16 h = getPrim h 2 (\op -> do + w0 <- fromIntegral <$> peekElemOff op 0 + w1 <- fromIntegral <$> peekElemOff op 1 + return $! w0 `shiftL` 8 .|. w1 + ) putWord32 :: BinHandle -> Word32 -> IO () putWord32 h w = putPrim h 4 (\op -> do @@ -348,38 +351,38 @@ getWord32 h = getPrim h 4 (\op -> do w3 ) --- putWord64 :: BinHandle -> Word64 -> IO () --- putWord64 h w = putPrim h 8 (\op -> do --- pokeElemOff op 0 (fromIntegral (w `shiftR` 56)) --- pokeElemOff op 1 (fromIntegral ((w `shiftR` 48) .&. 0xFF)) --- pokeElemOff op 2 (fromIntegral ((w `shiftR` 40) .&. 0xFF)) --- pokeElemOff op 3 (fromIntegral ((w `shiftR` 32) .&. 0xFF)) --- pokeElemOff op 4 (fromIntegral ((w `shiftR` 24) .&. 0xFF)) --- pokeElemOff op 5 (fromIntegral ((w `shiftR` 16) .&. 0xFF)) --- pokeElemOff op 6 (fromIntegral ((w `shiftR` 8) .&. 0xFF)) --- pokeElemOff op 7 (fromIntegral (w .&. 0xFF)) --- ) - --- getWord64 :: BinHandle -> IO Word64 --- getWord64 h = getPrim h 8 (\op -> do --- w0 <- fromIntegral <$> peekElemOff op 0 --- w1 <- fromIntegral <$> peekElemOff op 1 --- w2 <- fromIntegral <$> peekElemOff op 2 --- w3 <- fromIntegral <$> peekElemOff op 3 --- w4 <- fromIntegral <$> peekElemOff op 4 --- w5 <- fromIntegral <$> peekElemOff op 5 --- w6 <- fromIntegral <$> peekElemOff op 6 --- w7 <- fromIntegral <$> peekElemOff op 7 - --- return $! (w0 `shiftL` 56) .|. --- (w1 `shiftL` 48) .|. --- (w2 `shiftL` 40) .|. --- (w3 `shiftL` 32) .|. --- (w4 `shiftL` 24) .|. --- (w5 `shiftL` 16) .|. --- (w6 `shiftL` 8) .|. --- w7 --- ) +putWord64 :: BinHandle -> Word64 -> IO () +putWord64 h w = putPrim h 8 (\op -> do + pokeElemOff op 0 (fromIntegral (w `shiftR` 56)) + pokeElemOff op 1 (fromIntegral ((w `shiftR` 48) .&. 0xFF)) + pokeElemOff op 2 (fromIntegral ((w `shiftR` 40) .&. 0xFF)) + pokeElemOff op 3 (fromIntegral ((w `shiftR` 32) .&. 0xFF)) + pokeElemOff op 4 (fromIntegral ((w `shiftR` 24) .&. 0xFF)) + pokeElemOff op 5 (fromIntegral ((w `shiftR` 16) .&. 0xFF)) + pokeElemOff op 6 (fromIntegral ((w `shiftR` 8) .&. 0xFF)) + pokeElemOff op 7 (fromIntegral (w .&. 0xFF)) + ) + +getWord64 :: BinHandle -> IO Word64 +getWord64 h = getPrim h 8 (\op -> do + w0 <- fromIntegral <$> peekElemOff op 0 + w1 <- fromIntegral <$> peekElemOff op 1 + w2 <- fromIntegral <$> peekElemOff op 2 + w3 <- fromIntegral <$> peekElemOff op 3 + w4 <- fromIntegral <$> peekElemOff op 4 + w5 <- fromIntegral <$> peekElemOff op 5 + w6 <- fromIntegral <$> peekElemOff op 6 + w7 <- fromIntegral <$> peekElemOff op 7 + + return $! (w0 `shiftL` 56) .|. + (w1 `shiftL` 48) .|. + (w2 `shiftL` 40) .|. + (w3 `shiftL` 32) .|. + (w4 `shiftL` 24) .|. + (w5 `shiftL` 16) .|. + (w6 `shiftL` 8) .|. + w7 + ) putByte :: BinHandle -> Word8 -> IO () putByte bh !w = putWord8 bh w @@ -512,6 +515,35 @@ getSLEB128 bh = do let !signed = testBit byte 6 return (val',shift',signed) +-- ----------------------------------------------------------------------------- +-- Fixed length encoding instances + +-- Sometimes words are used to represent a certain bit pattern instead +-- of a number. Using FixedLengthEncoding we will write the pattern as +-- is to the interface file without the variable length encoding we usually +-- apply. + +-- | Encode the argument in it's full length. This is different from many default +-- binary instances which make no guarantee about the actual encoding and +-- might do things use variable length encoding. +newtype FixedLengthEncoding a = FixedLengthEncoding { unFixedLength :: a } + +instance Binary (FixedLengthEncoding Word8) where + put_ h (FixedLengthEncoding x) = putByte h x + get h = FixedLengthEncoding <$> getByte h + +instance Binary (FixedLengthEncoding Word16) where + put_ h (FixedLengthEncoding x) = putWord16 h x + get h = FixedLengthEncoding <$> getWord16 h + +instance Binary (FixedLengthEncoding Word32) where + put_ h (FixedLengthEncoding x) = putWord32 h x + get h = FixedLengthEncoding <$> getWord32 h + +instance Binary (FixedLengthEncoding Word64) where + put_ h (FixedLengthEncoding x) = putWord64 h x + get h = FixedLengthEncoding <$> getWord64 h + -- ----------------------------------------------------------------------------- -- Primitive Word writes View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a146a18d9391236207a249b3e9ecb938781507bc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a146a18d9391236207a249b3e9ecb938781507bc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 15 13:01:30 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Fri, 15 May 2020 09:01:30 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/andreask/xchg_primop Message-ID: <5ebe92aa1652b_61673f81afe3293c1144818d@gitlab.haskell.org.mail> Andreas Klebinger pushed new branch wip/andreask/xchg_primop at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/andreask/xchg_primop You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 15 13:30:42 2020 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski) Date: Fri, 15 May 2020 09:30:42 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/test-11506 Message-ID: <5ebe99823f81b_6167127aeba0114560b9@gitlab.haskell.org.mail> Krzysztof Gogolewski pushed new branch wip/test-11506 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/test-11506 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 15 13:31:49 2020 From: gitlab at gitlab.haskell.org (Krzysztof Gogolewski) Date: Fri, 15 May 2020 09:31:49 -0400 Subject: [Git][ghc/ghc][wip/test-11506] Add a regression test for #11506 Message-ID: <5ebe99c54e47d_6167124c0790114562f2@gitlab.haskell.org.mail> Krzysztof Gogolewski pushed to branch wip/test-11506 at Glasgow Haskell Compiler / GHC Commits: 00132ba0 by Krzysztof Gogolewski at 2020-05-15T15:31:28+02:00 Add a regression test for #11506 The testcase works now. See explanation in https://gitlab.haskell.org/ghc/ghc/issues/11506#note_273202 - - - - - 2 changed files: - + testsuite/tests/typecheck/should_compile/T11506.hs - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== testsuite/tests/typecheck/should_compile/T11506.hs ===================================== @@ -0,0 +1,13 @@ +{-# LANGUAGE PolyKinds, ExistentialQuantification, ScopedTypeVariables, + TypeFamilies, TypeInType #-} + +module T11506 where + +import Data.Proxy +import Data.Kind + +type family ProxyType where ProxyType = (Proxy :: Type -> Type) + +data T = forall a. MkT (ProxyType a) + +foo (MkT (_ :: Proxy a)) = const True (undefined :: a) ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -497,6 +497,7 @@ test('RebindNegate', normal, compile, ['']) test('T11319', normal, compile, ['']) test('T11397', normal, compile, ['']) test('T11458', normal, compile, ['']) +test('T11506', normal, compile, ['']) test('T11524', normal, compile, ['']) test('T11552', normal, compile, ['']) test('T11246', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/00132ba08b2decf03273b389c4483cc44768cf76 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/00132ba08b2decf03273b389c4483cc44768cf76 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 15 13:40:42 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Fri, 15 May 2020 09:40:42 -0400 Subject: [Git][ghc/ghc][wip/andreask/xchg_primop] Make XCHG a Op, Reg instr as it should be Message-ID: <5ebe9bda1d667_61673f81afe3293c1145907@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/xchg_primop at Glasgow Haskell Compiler / GHC Commits: f2b661a6 by Andreas Klebinger at 2020-05-15T15:40:30+02:00 Make XCHG a Op,Reg instr as it should be - - - - - 3 changed files: - compiler/GHC/CmmToAsm/X86/CodeGen.hs - compiler/GHC/CmmToAsm/X86/Instr.hs - compiler/GHC/CmmToAsm/X86/Ppr.hs Changes: ===================================== compiler/GHC/CmmToAsm/X86/CodeGen.hs ===================================== @@ -2518,22 +2518,20 @@ genCCall' _ is32Bit (PrimTarget (MO_Cmpxchg width)) [dst] [addr, old, new] _ = d where format = intFormat width -genCCall' dflags is32Bit (PrimTarget MO_Xchg) [dst] [addr, value] _ = do - Amode amode addr_code <- getSimpleAmode dflags is32Bit addr - newval <- getNewRegNat format - newval_code <- getAnyReg value - let platform = targetPlatform dflags - dst_r = getRegisterReg platform (CmmLocal dst) - code = toOL - [ MOV format (OpReg newval) (OpReg eax) - , LOCK (XCHG format (OpReg eax) (OpAddr amode)) - , MOV format (OpReg eax) (OpReg dst_r) +genCCall' config is32Bit (PrimTarget MO_Xchg) [dst] [addr, value] _ = do + let dst_r = getRegisterReg platform (CmmLocal dst) + Amode amode addr_code <- getSimpleAmode is32Bit addr + (newval, newval_code) <- getSomeReg value + let code = toOL + [ MOV format (OpReg newval) (OpReg dst_r) + , XCHG format (OpAddr amode) dst_r ] - return $ addr_code `appOL` newval_code newval `appOL` code + return $ addr_code `appOL` newval_code `appOL` code where format = intFormat width width | is32Bit = W32 | otherwise = W64 + platform = ncgPlatform config genCCall' _ is32Bit target dest_regs args bid = do platform <- ncgPlatform <$> getConfig ===================================== compiler/GHC/CmmToAsm/X86/Instr.hs ===================================== @@ -329,7 +329,7 @@ data Instr | LOCK Instr -- lock prefix | XADD Format Operand Operand -- src (r), dst (r/m) | CMPXCHG Format Operand Operand -- src (r), dst (r/m), eax implicit - | XCHG Format Operand Operand -- src (r), dst (r/m) + | XCHG Format Operand Reg -- src (r/m), dst (r/m) | MFENCE data PrefetchVariant = NTA | Lvl0 | Lvl1 | Lvl2 @@ -432,7 +432,7 @@ x86_regUsageOfInstr platform instr LOCK i -> x86_regUsageOfInstr platform i XADD _ src dst -> usageMM src dst CMPXCHG _ src dst -> usageRMM src dst (OpReg eax) - XCHG _ src dst -> usageRMM src dst (OpReg eax) + XCHG _ src dst -> usageMM src (OpReg dst) MFENCE -> noUsage _other -> panic "regUsage: unrecognised instr" @@ -591,7 +591,7 @@ x86_patchRegsOfInstr instr env LOCK i -> LOCK (x86_patchRegsOfInstr i env) XADD fmt src dst -> patch2 (XADD fmt) src dst CMPXCHG fmt src dst -> patch2 (CMPXCHG fmt) src dst - XCHG fmt src dst -> patch2 (XCHG fmt) src dst + XCHG fmt src dst -> XCHG fmt (patchOp src) (env dst) MFENCE -> instr _other -> panic "patchRegs: unrecognised instr" ===================================== compiler/GHC/CmmToAsm/X86/Ppr.hs ===================================== @@ -825,7 +825,7 @@ pprInstr platform i = case i of -> pprCondInstr (sLit "set") cond (pprOperand platform II8 op) (XCHG format src val) - -> pprFormatOpOp (sLit "xchg") format src val + -> pprFormatOpReg (sLit "xchg") format src val JXX cond blockid -> pprCondInstr (sLit "j") cond (ppr lab) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f2b661a69f5fac51d7f7defc374d363006717362 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f2b661a69f5fac51d7f7defc374d363006717362 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 15 14:42:19 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 15 May 2020 10:42:19 -0400 Subject: [Git][ghc/ghc][master] DmdAnal: Improve handling of precise exceptions Message-ID: <5ebeaa4b999cd_61679b2e0f4114931c4@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 9bd20e83 by Sebastian Graf at 2020-05-15T10:42:09-04:00 DmdAnal: Improve handling of precise exceptions This patch does two things: Fix possible unsoundness in what was called the "IO hack" and implement part 2.1 of the "fixing precise exceptions" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions, which, in combination with !2956, supersedes !3014 and !2525. **IO hack** The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is called `exprMayThrowPreciseException` now. I came up with two testcases exemplifying possible unsoundness (if twisted enough) in the old approach: - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. - `T13380e`: Demonstrating unsoundness of the "IO hack" when we have Nested CPR. Not currently relevant, as we don't have Nested CPR yet. - `T13380f`: Demonstrating unsoundness of the "IO hack" for safe FFI calls. Basically, the IO hack assumed that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future, see `T13380e`. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380{d,e}` (and will hopefully be robust to Nested CPR). **Precise exceptions** In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that was terribly unprincipled. That unprincipledness resulted in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception (and the existing IO hack doesn't detect that) Fixing both issues in !3014 turned out to be too complicated and had the potential to regress in the future. Hence we decided to only fix `T13380b` and augment the `Divergence` lattice with a new middle-layer element, `ExnOrDiv`, which means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. See the wiki page on Step 2.1 for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#dead-code-elimination-for-raiseio-with-isdeadenddiv-introducing-exnordiv-step-21 - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/LiberateCase.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/ForeignCall.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Make.hs - testsuite/tests/stranal/should_compile/T10482a.stderr - testsuite/tests/stranal/should_compile/T10694.stderr - + testsuite/tests/stranal/should_compile/T13380b.hs - testsuite/tests/stranal/should_compile/all.T - + testsuite/tests/stranal/should_run/T13380d.hs - + testsuite/tests/stranal/should_run/T13380d.stderr - + testsuite/tests/stranal/should_run/T13380e.hs - + testsuite/tests/stranal/should_run/T13380e.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9bd20e83ff9b65bd5496fbb29d27072c9e4e84b9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9bd20e83ff9b65bd5496fbb29d27072c9e4e84b9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 15 14:43:06 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 15 May 2020 10:43:06 -0400 Subject: [Git][ghc/ghc][master] GHC.Cmm.Opt: Handle MO_XX_Conv Message-ID: <5ebeaa7a8215a_61679b2e0f411497069@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 568d7279 by Ben Gamari at 2020-05-15T10:42:46-04:00 GHC.Cmm.Opt: Handle MO_XX_Conv This MachOp was introduced by 2c959a1894311e59cd2fd469c1967491c1e488f3 but a wildcard match in cmmMachOpFoldM hid the fact that it wasn't handled. Ideally we would eliminate the match but this appears to be a larger task. Fixes #18141. - - - - - 3 changed files: - compiler/GHC/Cmm/Opt.hs - + testsuite/tests/cmm/opt/T18141.hs - testsuite/tests/cmm/opt/all.T Changes: ===================================== compiler/GHC/Cmm/Opt.hs ===================================== @@ -69,6 +69,7 @@ cmmMachOpFoldM _ op [CmmLit (CmmInt x rep)] MO_SF_Conv _from to -> CmmLit (CmmFloat (fromInteger x) to) MO_SS_Conv from to -> CmmLit (CmmInt (narrowS from x) to) MO_UU_Conv from to -> CmmLit (CmmInt (narrowU from x) to) + MO_XX_Conv from to -> CmmLit (CmmInt (narrowS from x) to) _ -> panic $ "cmmMachOpFoldM: unknown unary op: " ++ show op @@ -76,6 +77,7 @@ cmmMachOpFoldM _ op [CmmLit (CmmInt x rep)] -- Eliminate conversion NOPs cmmMachOpFoldM _ (MO_SS_Conv rep1 rep2) [x] | rep1 == rep2 = Just x cmmMachOpFoldM _ (MO_UU_Conv rep1 rep2) [x] | rep1 == rep2 = Just x +cmmMachOpFoldM _ (MO_XX_Conv rep1 rep2) [x] | rep1 == rep2 = Just x -- Eliminate nested conversions where possible cmmMachOpFoldM platform conv_outer [CmmMachOp conv_inner [x]] ===================================== testsuite/tests/cmm/opt/T18141.hs ===================================== @@ -0,0 +1,17 @@ +{-# LANGUAGE MagicHash #-} + +module T18141 where + +import GHC.Exts + +divInt8# :: Int8# -> Int8# -> Int8# +x# `divInt8#` y# + | isTrue# (x# `gtInt8#` zero#) && isTrue# (y# `ltInt8#` zero#) = + ((x# `subInt8#` one#) `quotInt8#` y#) `subInt8#` one# + | isTrue# (x# `ltInt8#` zero#) && isTrue# (y# `gtInt8#` zero#) = + ((x# `plusInt8#` one#) `quotInt8#` y#) `subInt8#` one# + | otherwise = x# `quotInt8#` y# + where + zero# = narrowInt8# 0# + one# = narrowInt8# 1# + ===================================== testsuite/tests/cmm/opt/all.T ===================================== @@ -1,3 +1,4 @@ # Verify that we optimize away conditional branches which always jump # to the same target. test('T15188', normal, makefile_test, []) +test('T18141', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/568d7279a80cf945271f0659f11a94eea3f1433d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/568d7279a80cf945271f0659f11a94eea3f1433d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 15 15:15:10 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 15 May 2020 11:15:10 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 6 commits: DmdAnal: Improve handling of precise exceptions Message-ID: <5ebeb1fec228e_61673f81afdc50301150939d@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 9bd20e83 by Sebastian Graf at 2020-05-15T10:42:09-04:00 DmdAnal: Improve handling of precise exceptions This patch does two things: Fix possible unsoundness in what was called the "IO hack" and implement part 2.1 of the "fixing precise exceptions" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions, which, in combination with !2956, supersedes !3014 and !2525. **IO hack** The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is called `exprMayThrowPreciseException` now. I came up with two testcases exemplifying possible unsoundness (if twisted enough) in the old approach: - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. - `T13380e`: Demonstrating unsoundness of the "IO hack" when we have Nested CPR. Not currently relevant, as we don't have Nested CPR yet. - `T13380f`: Demonstrating unsoundness of the "IO hack" for safe FFI calls. Basically, the IO hack assumed that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future, see `T13380e`. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380{d,e}` (and will hopefully be robust to Nested CPR). **Precise exceptions** In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that was terribly unprincipled. That unprincipledness resulted in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception (and the existing IO hack doesn't detect that) Fixing both issues in !3014 turned out to be too complicated and had the potential to regress in the future. Hence we decided to only fix `T13380b` and augment the `Divergence` lattice with a new middle-layer element, `ExnOrDiv`, which means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. See the wiki page on Step 2.1 for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#dead-code-elimination-for-raiseio-with-isdeadenddiv-introducing-exnordiv-step-21 - - - - - 568d7279 by Ben Gamari at 2020-05-15T10:42:46-04:00 GHC.Cmm.Opt: Handle MO_XX_Conv This MachOp was introduced by 2c959a1894311e59cd2fd469c1967491c1e488f3 but a wildcard match in cmmMachOpFoldM hid the fact that it wasn't handled. Ideally we would eliminate the match but this appears to be a larger task. Fixes #18141. - - - - - 0570ce99 by Ben Gamari at 2020-05-15T11:14:59-04:00 nonmoving: Optimise the write barrier - - - - - 65c81c36 by Richard Eisenberg at 2020-05-15T11:14:59-04:00 MR template should ask for key part - - - - - c36e4f15 by Galen Huntington at 2020-05-15T11:15:02-04:00 Clarify pitfalls of NegativeLiterals; see #18022. - - - - - 5dd21f0d by Alexey Kuleshevich at 2020-05-15T11:15:05-04:00 Fix wording in primops documentation to reflect the correct reasoning: * Besides resizing functions, shrinking ones also mutate the size of a mutable array and because of those two `sizeofMutabeByteArray` and `sizeofSmallMutableArray` are now deprecated * Change reference in documentation to the newer functions `getSizeof*` instead of `sizeof*` for shrinking functions * Fix incorrect mention of "byte" instead of "small" - - - - - 30 changed files: - .gitlab/merge_request_templates/merge-request.md - compiler/GHC.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/LiberateCase.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/ForeignCall.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Make.hs - docs/users_guide/exts/negative_literals.rst - rts/Updates.h - + testsuite/tests/cmm/opt/T18141.hs - testsuite/tests/cmm/opt/all.T - testsuite/tests/stranal/should_compile/T10482a.stderr - testsuite/tests/stranal/should_compile/T10694.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ecc2e67a2296986049580d785f5f78d450a83901...5dd21f0d87aa00f21dba0401ddb7989c8af486cd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ecc2e67a2296986049580d785f5f78d450a83901...5dd21f0d87aa00f21dba0401ddb7989c8af486cd You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 15 16:16:26 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 15 May 2020 12:16:26 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/gc/opt-log2-ceil Message-ID: <5ebec05addcac_61673f81afd7d1181152761e@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/gc/opt-log2-ceil at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/gc/opt-log2-ceil You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 15 16:24:53 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 15 May 2020 12:24:53 -0400 Subject: [Git][ghc/ghc][wip/backports] 4 commits: nonmoving: Optimise log2_ceil Message-ID: <5ebec25560ac_61677ddab24115294f5@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/backports at Glasgow Haskell Compiler / GHC Commits: c40a783b by Ben Gamari at 2020-05-15T12:17:22-04:00 nonmoving: Optimise log2_ceil (cherry picked from commit 5f69016115414d0dd921e72f3edcd0b365966141) - - - - - fb653554 by Ben Gamari at 2020-05-15T12:17:30-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. (cherry picked from commit 7bfe9ac514e18c0b0e24ff55230fe98ec9db894c) - - - - - ac832ad5 by Ben Gamari at 2020-05-15T12:17:37-04:00 users guide: Move eventlog documentation users guide (cherry picked from commit c560dd07f506810eaabae2f582491138aa224819) - - - - - 729922a5 by Ben Gamari at 2020-05-15T12:17:44-04:00 users guide: Add documentation for non-moving GC events (cherry picked from commit 02543d5ef9bd7a910fc9fece895780583ab9635a) - - - - - 6 changed files: - docs/users_guide/conf.py - docs/users_guide/eventlog-formats.rst - docs/users_guide/runtime_control.rst - includes/rts/EventLogFormat.h - rts/RtsFlags.c - rts/sm/NonMoving.c Changes: ===================================== docs/users_guide/conf.py ===================================== @@ -256,8 +256,18 @@ def setup(app): objname='runtime system command-line option', parse_node=parse_flag, indextemplate='pair: %s; RTS option', + doc_field_types=[ + Field('since', label='Introduced in GHC version', names=['since']) + ]) + + app.add_object_type('event-type', 'event-type', + objname='event log event type', + indextemplate='pair: %s; eventlog event type', doc_field_types=[ Field('since', label='Introduced in GHC version', names=['since']), + Field('tag', label='Event type ID', names=['tag']), + Field('length', label='Record length', names=['length']), + TypedField('fields', label='Fields', names='field', typenames=('fieldtype', 'type')) ]) app.add_object_type('pragma', 'pragma', ===================================== docs/users_guide/eventlog-formats.rst ===================================== @@ -1,3 +1,5 @@ +.. _eventlog-encodings: + Eventlog encodings ================== @@ -7,6 +9,481 @@ thread scheduling events, garbage collection statistics, profiling information, user-defined tracing events. This section is intended for implementors of tooling which consume these events. +GHC ships with a C header file (``EventlogFormat.h``) which provides symbolic +names for the event type IDs described in this file. + + +Event log format +---------------- + +The log format is designed to be extensible: old tools should be +able to parse (but not necessarily understand all of) new versions +of the format, and new tools will be able to understand old log +files. + +- The format is endian-independent: all values are represented in + big-endian order. + +- The format is extensible: + + - The header describes each event type and its length. Tools + that don't recognise a particular event type can skip those events. + + - There is room for extra information in the event type + specification, which can be ignored by older tools. + + - Events can have extra information added, but existing fields + cannot be changed. Tools should ignore extra fields at the + end of the event record. + +The event-log stream begins with a header describing the event types present in +the file. The header is followed by the event records themselves, each of which +consist of a 64-bit timestamp + +.. code-block:: none + + log : EVENT_HEADER_BEGIN + EventType* + EVENT_HEADER_END + EVENT_DATA_BEGIN + Event* + EVENT_DATA_END + + EventType : + EVENT_ET_BEGIN + Word16 -- unique identifier for this event + Int16 -- >=0 size of the event in bytes (minus the header) + -- -1 variable size + Word32 -- length of the next field in bytes + Word8* -- string describing the event + Word32 -- length of the next field in bytes + Word8* -- extra info (for future extensions) + EVENT_ET_END + + Event : + Word16 -- event_type + Word64 -- time (nanosecs) + [Word16] -- length of the rest (for variable-sized events only) + ... extra event-specific info ... + +There are two classes of event types: + + - *Fixed size*: All event records of a fixed-sized type are of the same + length, given in the header event-log header. + + - *Variable size*: Each event record includes a length field. + +Runtime system diagnostics +-------------------------- + + * ``ThreadId ~ Word32`` + * ``CapNo ~ Word16`` + * ``CapSetId ~ Word32`` + +Capability sets +~~~~~~~~~~~~~~~ + +TODO + +Environment information +~~~~~~~~~~~~~~~~~~~~~~~ + +These events are typically produced during program startup and describe the +environment which the program is being run in. + +.. event-type:: RTS_IDENTIFIER + + :tag: 29 + :length: variable + :field CapSetId: Capability set + :field String: Runtime system name and version. + + Describes the name and version of the runtime system responsible for the + indicated capability set. + +.. event-type:: PROGRAM_ARGS + + :tag: 30 + :length: variable + :field CapSetId: Capability set + :field [String]: The command-line arguments passed to the program + + Describes the command-line used to start the program. + +.. event-type:: PROGRAM_ENV + + :tag: 31 + :length: variable + :field CapSetId: Capability set + :field [String]: The environment variable name/value pairs. (TODO: encoding?) + + Describes the environment variables present in the program's environment. + +Thread and scheduling events +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. event-type:: CREATE_THREAD + + :tag: 0 + :length: fixed + :field ThreadId: thread id + + Marks the creation of a Haskell thread. + + +.. event-type:: RUN_THREAD + + :tag: 1 + :length: fixed + :field ThreadId: thread id + + The indicated thread has started running. + + +.. event-type:: STOP_THREAD + + :tag: 2 + :length: fixed + :field ThreadId: thread id + :field Word16: status + + * 1: HeapOverflow + * 2: StackOverflow + * 3: ThreadYielding + * 4: ThreadBlocked + * 5: ThreadFinished + * 6: ForeignCall + * 7: BlockedOnMVar + * 8: BlockedOnBlackHole + * 9: BlockedOnRead + * 10: BlockedOnWrite + * 11: BlockedOnDelay + * 12: BlockedOnSTM + * 13: BlockedOnDoProc + * 16: BlockedOnMsgThrowTo + + :field ThreadId: thread id of thread being blocked on (only for some status + values) + + The indicated thread has stopped running for the reason given by ``status``. + + +.. event-type:: THREAD_RUNNABLE + + :tag: 3 + :length: fixed + :field ThreadId: thread id + + The indicated thread is has been marked as ready to run. + + +.. event-type:: MIGRATE_THREAD + + :tag: 4 + :length: fixed + :field ThreadId: thread id + :field CapNo: capability + + The indicated thread has been migrated to a new capability. + + +.. event-type:: THREAD_WAKEUP + + :tag: 8 + :length: fixed + :field ThreadId: thread id + :field CapNo: other capability + + The indicated thread has been been woken up on another capability. + +.. event-type:: THREAD_LABEL + + :tag: 44 + :length: fixed + :field ThreadId: thread id + :field String: label + + The indicated thread has been given a label (e.g. with + :base-ref:`Control.Concurrent.setThreadLabel`). + + +Garbage collector events +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. event-type:: GC_START + + :tag: 9 + :length: fixed + + A garbage collection pass has been started. + +.. event-type:: GC_END + + :tag: 10 + :length: fixed + + A garbage collection pass has been finished. + +.. event-type:: REQUEST_SEQ_GC + + :tag: 11 + :length: fixed + + A sequential garbage collection has been requested by a capability. + +.. event-type:: REQUEST_PAR_GC + + :tag: 12 + :length: fixed + + A parallel garbage collection has been requested by a capability. + +.. event-type:: GC_IDLE + + :tag: 20 + :length: fixed + + An idle-time garbage collection has been started. + +.. event-type:: GC_WORK + + :tag: 21 + :length: fixed + + Marks the start of concurrent scavenging. + +.. event-type:: GC_DONE + + :tag: 22 + :length: fixed + + Marks the end of concurrent scavenging. + +.. event-type:: GC_STATS_GHC + + :tag: 53 + :length: fixed + :field CapSetId: heap capability set + :field Word16: generation of collection + :field Word64: bytes copied + :field Word64: bytes of slop found + :field Word64: TODO + :field Word64: number of parallel garbage collection threads + :field Word64: maximum number of bytes copied by any single collector thread + :field Word64: total bytes copied by all collector threads + + Report various information about the heap configuration. Typically produced + during RTS initialization.. + +.. event-type:: GC_GLOBAL_SYNC + + :tag: 54 + :length: fixed + + TODO + +Heap events and statistics +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. event-type:: HEAP_ALLOCATED + + :tag: 49 + :length: fixed + :field CapSetId: heap capability set + :field Word64: allocated bytes + + A new chunk of heap has been allocated by the indicated capability set. + +.. event-type:: HEAP_SIZE + + :tag: 50 + :length: fixed + :field CapSetId: heap capability set + :field Word64: heap size in bytes + + Report the heap size. + +.. event-type:: HEAP_LIVE + + :tag: 51 + :length: fixed + :field CapSetId: heap capability set + :field Word64: heap size in bytes + + Report the live heap size. + +.. event-type:: HEAP_INFO_GHC + + :tag: 52 + :length: fixed + :field CapSetId: heap capability set + :field Word16: number of garbage collection generations + :field Word64: maximum heap size + :field Word64: allocation area size + :field Word64: MBlock size + :field Word64: Block size + + Report various information about the heap configuration. Typically produced + during RTS initialization.. + +Spark events +~~~~~~~~~~~~ + +.. event-type:: CREATE_SPARK_THREAD + + :tag: 15 + :length: fixed + + A thread has been created to perform spark evaluation. + +.. event-type:: SPARK_COUNTERS + + :tag: 34 + :length: fixed + + A periodic reporting of various statistics of spark evaluation. + +.. event-type:: SPARK_CREATE + + :tag: 35 + :length: fixed + + A spark has been added to the spark pool. + +.. event-type:: SPARK_DUD + + :tag: 36 + :length: fixed + + TODO + +.. event-type:: SPARK_OVERFLOW + + :tag: 37 + :length: fixed + + TODO + +.. event-type:: SPARK_RUN + + :tag: 38 + :length: fixed + + Evaluation has started on a spark. + +.. event-type:: SPARK_STEAL + + :tag: 39 + :length: fixed + :field Word16: capability from which the spark was stolen + + A spark has been stolen from another capability for evaluation. + +.. event-type:: SPARK_FIZZLE + + :tag: 40 + :length: fixed + + A spark has been GC'd before being evaluated. + +.. event-type:: SPARK_GC + + :tag: 41 + :length: fixed + + An unevaluated spark has been garbage collected. + +Capability events +~~~~~~~~~~~~~~~~~ + +.. event-type:: CAP_CREATE + + :tag: 45 + :length: fixed + :field CapNo: the capability number + + A capability has been started. + +.. event-type:: CAP_DELETE + + :tag: 46 + :length: fixed + + A capability has been deleted. + +.. event-type:: CAP_DISABLE + + :tag: 47 + :length: fixed + + A capability has been disabled. + +.. event-type:: CAP_ENABLE + + :tag: 48 + :length: fixed + + A capability has been enabled. + +Task events +~~~~~~~~~~~ + +.. event-type:: TASK_CREATE + + :tag: 55 + :length: fixed + :field TaskId: task id + :field CapNo: capability number + :field ThreadId: TODO + + Marks the creation of a task. + +.. event-type:: TASK_MIGRATE + + :tag: 56 + :length: fixed + :field TaskId: task id + :field CapNo: old capability + :field CapNo: new capability + + Marks the migration of a task to a new capability. + +Tracing events +~~~~~~~~~~~~~~ + +.. event-type:: LOG_MSG + + :tag: 16 + :length: variable + :field String: The message + + A log message from the runtime system. + +.. event-type:: BLOCK_MARKER + + :tag: 18 + :length: variable + :field Word32: size + :field Word64: end time in nanoseconds + :field String: marker name + + TODO + +.. event-type:: USER_MSG + + :tag: 19 + :length: variable + :field String: message + + A user log message (from, e.g., :base-ref:`Control.Concurrent.traceEvent`). + +.. event-type:: USER_MARKER + + :tag: 58 + :length: variable + :field String: marker name + + A user marker (from :base-ref:`Debug.Trace.traceMarker`). .. _heap-profiler-events: @@ -28,11 +505,13 @@ Beginning of sample stream A single fixed-width event emitted during program start-up describing the samples that follow. - * ``EVENT_HEAP_PROF_BEGIN`` +.. event-type:: HEAP_PROF_BEGIN - * ``Word8``: Profile ID - * ``Word64``: Sampling period in nanoseconds - * ``Word32``: Sample break-down type. One of, + :tag: 160 + :length: variable + :field Word8: profile ID + :field Word64: sampling period in nanoseconds + :field Word32: sample breadown type. One of, * ``HEAP_PROF_BREAKDOWN_COST_CENTER`` (output from :rts-flag:`-hc`) * ``HEAP_PROF_BREAKDOWN_CLOSURE_DESCR`` (output from :rts-flag:`-hd`) @@ -42,32 +521,34 @@ A single fixed-width event emitted during program start-up describing the sample * ``HEAP_PROF_BREAKDOWN_BIOGRAPHY`` (output from :rts-flag:`-hb`) * ``HEAP_PROF_BREAKDOWN_CLOSURE_TYPE`` (output from :rts-flag:`-hT`) - * ``String``: Module filter - * ``String``: Closure description filter - * ``String``: Type description filter - * ``String``: Cost centre filter - * ``String``: Cost centre stack filter - * ``String``: Retainer filter - * ``String``: Biography filter + :field String: module filter + :field String: closure description filter + :field String: type description filter + :field String: cost centre filter + :field String: cost centre stack filter + :field String: retainer filter + :field String: biography filter Cost centre definitions ^^^^^^^^^^^^^^^^^^^^^^^ A variable-length packet produced once for each cost centre, - * ``EVENT_HEAP_PROF_COST_CENTRE`` +.. event-type:: HEAP_PROF_COST_CENTRE - * ``Word32``: cost centre number - * ``String``: label - * ``String``: module - * ``String``: source location - * ``Word8``: flags + :tag: 161 + :length: fixed + :field Word32: cost centre number + :field String: label + :field String: module + :field String: source location + :field Word8: flags: * bit 0: is the cost-centre a CAF? Sample event types -~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^ A sample (consisting of a list of break-down classes, e.g. cost centres, and heap residency sizes), is to be encoded in the body of one or more events. @@ -75,9 +556,12 @@ heap residency sizes), is to be encoded in the body of one or more events. We normally mark the beginning of a new sample with an ``EVENT_HEAP_PROF_SAMPLE_BEGIN`` event, - * ``EVENT_HEAP_PROF_SAMPLE_BEGIN`` +.. event-type:: HEAP_PROF_SAMPLE_BEGIN + + :length: fixed + :field Word64: sample number - * ``Word64``: sample number + Marks the beginning of a heap profile sample. Biographical profiling samples start with the ``EVENT_HEAP_BIO_PROF_SAMPLE_BEGIN`` event. These events also include a timestamp which indicates when the sample @@ -85,11 +569,12 @@ was taken. This is because all these samples will appear at the end of the eventlog due to how the biographical profiling mode works. You can use the timestamp to reorder the samples relative to the other events. - * ``EVENT_HEAP_BIO_PROF_SAMPLE_BEGIN`` - - * ``Word64``: sample number - * ``Word64``: eventlog timestamp in ns +.. event-type:: HEAP_BIO_PROF_SAMPLE_BEGIN + :tag: 166 + :length: fixed + :field Word64: sample number + :field Word64: eventlog timestamp in ns A heap residency census will follow. Since events may only be up to 2^16^ bytes in length a single sample may need to be split among multiple @@ -101,23 +586,29 @@ emitted. This is useful to properly delimit the sampling period and to record the total time spent profiling. - * ``EVENT_HEAP_PROF_SAMPLE_END`` - * ``Word64``: sample number +.. event-type:: HEAP_PROF_SAMPLE_END + :tag: 165 + :length: fixed + :field Word64: sample number + + Marks the end of a heap profile sample. Cost-centre break-down ^^^^^^^^^^^^^^^^^^^^^^ A variable-length packet encoding a heap profile sample broken down by, - * cost-centre (``-hc``) + * cost-centre (:rts-flag:`-hc`) - * ``EVENT_HEAP_PROF_SAMPLE_COST_CENTRE`` +.. event-type:: HEAP_PROF_SAMPLE_COST_CENTRE - * ``Word8``: Profile ID - * ``Word64``: heap residency in bytes - * ``Word8``: stack depth - * ``Word32[]``: cost centre stack starting with inner-most (cost centre numbers) + :tag: 163 + :length: variable + :field Word8: profile ID + :field Word64: heap residency in bytes + :field Word8: stack depth + :field Word32[]: cost centre stack starting with inner-most (cost centre numbers) String break-down @@ -125,42 +616,142 @@ String break-down A variable-length event encoding a heap sample broken down by, - * type description (``-hy``) - * closure description (``-hd``) - * module (``-hm``) + * type description (:rts-flag:`-hy`) + * closure description (:rts-flag:`-hd`) + * module (:rts-flag:`-hm`) - * ``EVENT_HEAP_PROF_SAMPLE_STRING`` +.. event-type:: HEAP_PROF_SAMPLE_STRING - * ``Word8``: Profile ID - * ``Word64``: heap residency in bytes - * ``String``: type or closure description, or module name + :tag: 164 + :length: variable + :field Word8: profile ID + :field Word64: heap residency in bytes + :field String: type or closure description, or module name .. _time-profiler-events: Time profiler event log output ------------------------------ -The time profiling mode enabled by ``-p`` also emits sample events to the eventlog. -At the start of profiling the tick interval is emitted to the eventlog and then -on each tick the current cost centre stack is emitted. Together these enable -a user to construct an approximate track of the executation of their program. +The time profiling mode enabled by :rts-flag:`-p` also emits +sample events to the eventlog. At the start of profiling the +tick interval is emitted to the eventlog and then on each tick +the current cost centre stack is emitted. Together these +enable a user to construct an approximate track of the +executation of their program. Profile begin event ~~~~~~~~~~~~~~~~~~~ - * ``EVENT_PROF_BEGIN`` +.. event-type:: PROF_BEGIN - * ``Word64``: Tick interval, in nanoseconds + :tag: 168 + :length: fixed + :field Word64: tick interval, in nanoseconds + Marks the beginning of a time profile. -Tick sample event -~~~~~~~~~~~~~~~~~ +Profile sample event +~~~~~~~~~~~~~~~~~~~~ A variable-length packet encoding a profile sample. - * ``EVENT_PROF_SAMPLE_COST_CENTRE`` +.. event-type:: PROF_SAMPLE_COST_CENTRE + + :tag: 167 + :length: variable + :field Word32: capability + :field Word64: current profiling tick + :field Word8: stack depth + :field Word32[]: cost centre stack starting with inner-most (cost centre numbers) + +Biographical profile sample event +--------------------------------- + +A variable-length packet encoding a profile sample. + +.. event-type:: BIO_PROF_SAMPLE_BEGIN + + :tag: 166 + + TODO + +.. _nonmoving-gc-events: + +Non-moving GC event output +-------------------------- + +These events mark various stages of the +:rts-flag:`non-moving collection <--nonmoving-gc>` lifecycle. These are enabled +with the ``+RTS -lg`` event-set. + +.. event-type:: CONC_MARK_BEGIN + + :tag: 200 + :length: fixed + + Marks the beginning of marking by the concurrent collector. + +.. event-type:: CONC_MARK_END + + :tag: 201 + :length: fixed + + Marks the end of marking by the concurrent collector. + +.. event-type:: CONC_SYNC_BEGIN + + :tag: 202 + :length: fixed + + Marks the beginning of the concurrent garbage collector's + post-mark synchronization phase. + +.. event-type:: CONC_SYNC_END + + :tag: 203 + :length: fixed + + Marks the end of the concurrent garbage collector's + post-mark synchronization phase. + +.. event-type:: CONC_SWEEP_BEGIN + + :tag: 204 + :length: fixed + + Marks the beginning of the concurrent garbage collector's + sweep phase. + +.. event-type:: CONC_SWEEP_END + + :tag: 205 + :length: fixed + + Marks the end of the concurrent garbage collector's + sweep phase. + +.. event-type:: CONC_UPD_REM_SET_FLUSH + + :tag: 206 + :length: fixed + + Marks a capability flushing its local update remembered set + accumulator. + +Non-moving heap census +~~~~~~~~~~~~~~~~~~~~~~ + +The non-moving heap census events (enabled with the ``+RTS -ln`` event-set) are +intended to provide insight into fragmentation of the non-moving heap. + +.. event-type:: NONMOVING_HEAP_CENSUS + + :tag: 207 + :length: fixed + :field Word8: base-2 logarithm of *blk_sz*. + :field Word32: number of active segments. + :field Word32: number of filled segments. + :field Word32: number of live blocks. - * ``Word32``: Capability - * ``Word64``: Current profiling tick - * ``Word8``: stack depth - * ``Word32[]``: cost centre stack starting with inner-most (cost centre numbers) + Describes the occupancy of the *blk_sz* sub-heap. ===================================== docs/users_guide/runtime_control.rst ===================================== @@ -1160,6 +1160,10 @@ When the program is linked with the :ghc-flag:`-eventlog` option - ``g`` — GC events, including GC start/stop. Enabled by default. + - ``n`` — non-moving garbage collector (see :rts-flag:`--nonmoving-gc`) + events including start and end of the concurrent mark and census + information to characterise heap fragmentation. Disabled by default. + - ``p`` — parallel sparks (sampled). Enabled by default. - ``f`` — parallel sparks (fully accurate). Disabled by default. @@ -1185,9 +1189,8 @@ When the program is linked with the :ghc-flag:`-eventlog` option accurate mode every spark event is logged individually. The latter has a higher runtime overhead and is not enabled by default. - The format of the log file is described by the header - ``EventLogFormat.h`` that comes with GHC, and it can be parsed in - Haskell using the + The format of the log file is described in this users guide in + :ref:`eventlog-encodings` It can be parsed in Haskell using the `ghc-events `__ library. To dump the contents of a ``.eventlog`` file as text, use the tool ``ghc-events show`` that comes with the ===================================== includes/rts/EventLogFormat.h ===================================== @@ -9,65 +9,25 @@ * of the format, and new tools will be able to understand old log * files. * - * Each event has a specific format. If you add new events, give them - * new numbers: we never re-use old event numbers. - * - * - The format is endian-independent: all values are represented in - * bigendian order. - * - * - The format is extensible: - * - * - The header describes each event type and its length. Tools - * that don't recognise a particular event type can skip those events. - * - * - There is room for extra information in the event type - * specification, which can be ignored by older tools. - * - * - Events can have extra information added, but existing fields - * cannot be changed. Tools should ignore extra fields at the - * end of the event record. - * - * - Old event type ids are never re-used; just take a new identifier. - * - * - * The format - * ---------- - * - * log : EVENT_HEADER_BEGIN - * EventType* - * EVENT_HEADER_END - * EVENT_DATA_BEGIN - * Event* - * EVENT_DATA_END - * - * EventType : - * EVENT_ET_BEGIN - * Word16 -- unique identifier for this event - * Int16 -- >=0 size of the event in bytes (minus the header) - * -- -1 variable size - * Word32 -- length of the next field in bytes - * Word8* -- string describing the event - * Word32 -- length of the next field in bytes - * Word8* -- extra info (for future extensions) - * EVENT_ET_END - * - * Event : - * Word16 -- event_type - * Word64 -- time (nanosecs) - * [Word16] -- length of the rest (for variable-sized events only) - * ... extra event-specific info ... - * + * The canonical documentation for the event log format and record layouts is + * the "Eventlog encodings" section of the GHC User's Guide. * * To add a new event * ------------------ * * - In this file: - * - give it a new number, add a new #define EVENT_XXX below + * - give it a new number, add a new #define EVENT_XXX + * below. Do not reuse event ids from deprecated event types. + * * - In EventLog.c * - add it to the EventDesc array * - emit the event type in initEventLogging() * - emit the new event in postEvent_() * - generate the event itself by calling postEvent() somewhere + * + * - Describe the meaning and encoding of the event in the users guide + * (docs/user_guide/eventlog-formats.rst) + * * - In the Haskell code to parse the event log file: * - add types and code to read the new event * ===================================== rts/RtsFlags.c ===================================== @@ -375,6 +375,7 @@ usage_text[] = { " where [flags] can contain:", " s scheduler events", " g GC and heap events", +" n non-moving GC heap census events", " p par spark events (sampled)", " f par spark events (full detail)", " u user events (emitted from Haskell code)", ===================================== rts/sm/NonMoving.c ===================================== @@ -586,15 +586,9 @@ static struct NonmovingSegment *nonmovingAllocSegment(uint32_t node) return ret; } -static inline unsigned long log2_floor(unsigned long x) -{ - return sizeof(unsigned long)*8 - 1 - __builtin_clzl(x); -} - static inline unsigned long log2_ceil(unsigned long x) { - unsigned long log = log2_floor(x); - return (x - (1 << log)) ? log + 1 : log; + return (sizeof(unsigned long)*8) - __builtin_clzl(x-1); } // Advance a segment's next_free pointer. Returns true if segment if full. @@ -1212,6 +1206,10 @@ static void nonmovingMark_(MarkQueue *mark_queue, StgWeak **dead_weaks, StgTSO * if (RtsFlags.DebugFlags.nonmoving_gc) nonmovingPrintAllocatorCensus(); #endif +#if defined(TRACING) + if (RtsFlags.TraceFlags.nonmoving_gc) + nonmovingTraceAllocatorCensus(); +#endif // TODO: Remainder of things done by GarbageCollect (update stats) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2b7c13267aaec9d2b3e2c0ad94ad343993e386d1...729922a5276f7a35b4090929acc1c9b07b618f75 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2b7c13267aaec9d2b3e2c0ad94ad343993e386d1...729922a5276f7a35b4090929acc1c9b07b618f75 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Fri May 15 21:08:25 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Fri, 15 May 2020 17:08:25 -0400 Subject: [Git][ghc/ghc][wip/ww-max-worker-args-old-arity] 48 commits: Remove further dead code found by a simple Python script. Message-ID: <5ebf04c99c23b_616711368c4011549338@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/ww-max-worker-args-old-arity at Glasgow Haskell Compiler / GHC Commits: 6f6d72b2 by Brian Foley at 2020-05-08T15:29:25-04:00 Remove further dead code found by a simple Python script. Avoid removing some functions that are part of an API even though they're not used in-tree at the moment. - - - - - 78bf8bf9 by Julien Debon at 2020-05-08T15:29:28-04:00 Add doc examples for Bifoldable See #17929 - - - - - 66f0a847 by Julien Debon at 2020-05-08T15:29:29-04:00 doc (Bitraversable): Add examples to Bitraversable * Add examples to Data.Bitraversable * Fix formatting for (,) in Bitraversable and Bifoldable * Fix mistake on bimapAccumR documentation See #17929 - - - - - 9749fe12 by Baldur Blöndal at 2020-05-08T15:29:32-04:00 Specify kind variables for inferred kinds in base. - - - - - 4e9aef9e by John Ericson at 2020-05-08T15:29:36-04:00 HsSigWcTypeScoping: Pull in documentation from stray location - - - - - f4d5c6df by John Ericson at 2020-05-08T15:29:36-04:00 Rename local `real_fvs` to `implicit_vs` It doesn't make sense to call the "free" variables we are about to implicitly bind the real ones. - - - - - 20570b4b by John Ericson at 2020-05-08T15:29:36-04:00 A few tiny style nits with renaming - Use case rather than guards that repeatedly scrutenize same thing. - No need for view pattern when `L` is fine. - Use type synnonym to convey the intent like elsewhere. - - - - - 09ac8de5 by John Ericson at 2020-05-08T15:29:36-04:00 Add `forAllOrNothing` function with note - - - - - bb35c0e5 by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Document lawlessness of Ap's Num instance - - - - - cdd229ff by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply suggestion to libraries/base/Data/Monoid.hs - - - - - 926d2aab by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply more suggestions from Simon Jakobi - - - - - 7a763cff by Adam Gundry at 2020-05-08T15:29:41-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. - - - - - 88e3c815 by Simon Peyton Jones at 2020-05-08T15:29:41-04:00 Fix specialisation for DFuns When specialising a DFun we must take care to saturate the unfolding. See Note [Specialising DFuns] in Specialise. Fixes #18120 - - - - - 86c77b36 by Greg Steuck at 2020-05-08T15:29:45-04:00 Remove unused SEGMENT_PROT_RWX It's been unused for a year and is problematic on any OS which requires W^X for security. - - - - - 9d97f4b5 by nineonine at 2020-05-08T15:30:03-04:00 Add test for #16167 - - - - - aa318338 by Ryan Scott at 2020-05-08T15:30:04-04:00 Bump exceptions submodule so that dist-boot is .gitignore'd `exceptions` is a stage-0 boot library as of commit 30272412fa437ab8e7a8035db94a278e10513413, which means that building `exceptions` in a GHC tree will generate a `dist-boot` directory. However, this directory was not specified in `exceptions`' `.gitignore` file, which causes it to dirty up the current `git` working directory. Accordingly, this bumps the `exceptions` submodule to commit ghc/packages/exceptions at 23c0b8a50d7592af37ca09beeec16b93080df98f, which adds `dist-boot` to the `.gitignore` file. - - - - - ea86360f by Ömer Sinan Ağacan at 2020-05-08T15:30:30-04:00 Linker.c: initialize n_symbols of ObjectCode with other fields - - - - - 951c1fb0 by Sylvain Henry at 2020-05-09T21:46:38-04:00 Fix unboxed-sums GC ptr-slot rubbish value (#17791) This patch allows boot libraries to use unboxed sums without implicitly depending on `base` package because of `absentSumFieldError`. See updated Note [aBSENT_SUM_FIELD_ERROR_ID] in GHC.Core.Make - - - - - b352d63c by Ben Gamari at 2020-05-09T21:47:14-04:00 rts: Make non-existent linker search path merely a warning As noted in #18105, previously this resulted in a rather intrusive error message. This is in contrast to the general expectation that search paths are merely places to look, not places that must exist. Fixes #18105. - - - - - cf4f1e2f by Ben Gamari at 2020-05-13T02:02:33-04:00 rts/CNF: Fix fixup comparison function Previously we would implicitly convert the difference between two words to an int, resulting in an integer overflow on 64-bit machines. Fixes #16992 - - - - - a03da9bf by Ömer Sinan Ağacan at 2020-05-13T02:03:16-04:00 Pack some of IdInfo fields into a bit field This reduces residency of compiler quite a bit on some programs. Example stats when building T10370: Before: 2,871,242,832 bytes allocated in the heap 4,693,328,008 bytes copied during GC 33,941,448 bytes maximum residency (276 sample(s)) 375,976 bytes maximum slop 83 MiB total memory in use (0 MB lost due to fragmentation) After: 2,858,897,344 bytes allocated in the heap 4,629,255,440 bytes copied during GC 32,616,624 bytes maximum residency (278 sample(s)) 314,400 bytes maximum slop 80 MiB total memory in use (0 MB lost due to fragmentation) So -3.9% residency, -1.3% bytes copied and -0.4% allocations. Fixes #17497 Metric Decrease: T9233 T9675 - - - - - 670c3e5c by Ben Gamari at 2020-05-13T02:03:54-04:00 get-win32-tarballs: Fix base URL Revert a change previously made for testing purposes. - - - - - 8ad8dc41 by Ben Gamari at 2020-05-13T02:03:54-04:00 get-win32-tarballs: Improve diagnostics output - - - - - 8c0740b7 by Simon Jakobi at 2020-05-13T02:04:33-04:00 docs: Add examples for Data.Semigroup.Arg{Min,Max} Context: #17153 - - - - - cb22348f by Ben Gamari at 2020-05-13T02:05:11-04:00 Add few cleanups of the CAF logic Give the NameSet of non-CAFfy names a proper newtype to distinguish it from all of the other NameSets floating about. - - - - - 90e38b81 by Emeka Nkurumeh at 2020-05-13T02:05:51-04:00 fix printf warning when using with ghc with clang on mingw - - - - - 86d8ac22 by Sebastian Graf at 2020-05-13T02:06:29-04:00 CprAnal: Don't attach CPR sigs to expandable bindings (#18154) Instead, look through expandable unfoldings in `cprTransform`. See the new Note [CPR for expandable unfoldings]: ``` Long static data structures (whether top-level or not) like xs = x1 : xs1 xs1 = x2 : xs2 xs2 = x3 : xs3 should not get CPR signatures, because they * Never get WW'd, so their CPR signature should be irrelevant after analysis (in fact the signature might even be harmful for that reason) * Would need to be inlined/expanded to see their constructed product * Recording CPR on them blows up interface file sizes and is redundant with their unfolding. In case of Nested CPR, this blow-up can be quadratic! But we can't just stop giving DataCon application bindings the CPR property, for example fac 0 = 1 fac n = n * fac (n-1) fac certainly has the CPR property and should be WW'd! But FloatOut will transform the first clause to lvl = 1 fac 0 = lvl If lvl doesn't have the CPR property, fac won't either. But lvl doesn't have a CPR signature to extrapolate into a CPR transformer ('cprTransform'). So instead we keep on cprAnal'ing through *expandable* unfoldings for these arity 0 bindings via 'cprExpandUnfolding_maybe'. In practice, GHC generates a lot of (nested) TyCon and KindRep bindings, one for each data declaration. It's wasteful to attach CPR signatures to each of them (and intractable in case of Nested CPR). ``` Fixes #18154. - - - - - e34bf656 by Ben Gamari at 2020-05-13T02:07:08-04:00 users-guide: Add discussion of shared object naming Fixes #18074. - - - - - 5d0f2445 by Ben Gamari at 2020-05-13T02:07:47-04:00 testsuite: Print sign of performance changes Executes the minor formatting change in the tabulated performance changes suggested in #18135. - - - - - 9e4b981f by Ben Gamari at 2020-05-13T02:08:24-04:00 testsuite: Add testcase for #18129 - - - - - 266310c3 by Ivan-Yudin at 2020-05-13T02:09:03-04:00 doc: Reformulate the opening paragraph of Ch. 4 in User's guide Removes mentioning of Hugs (it is not helpful for new users anymore). Changes the wording for the rest of the paragraph. Fixes #18132. - - - - - 55e35c0b by Baldur Blöndal at 2020-05-13T20:02:48-04:00 Predicate, Equivalence derive via `.. -> a -> All' - - - - - d7e0b57f by Alp Mestanogullari at 2020-05-13T20:03:30-04:00 hadrian: add a --freeze2 option to freeze stage 1 and 2 - - - - - d880d6b2 by Artem Pelenitsyn at 2020-05-13T20:04:11-04:00 Don't reload environment files on every setSessionDynFlags Makes `interpretPackageEnv` (which loads envirinment files) a part of `parseDynamicFlags` (parsing command-line arguments, which is typically done once) instead of `setSessionDynFlags` (which is typically called several times). Making several (transitive) calls to `interpretPackageEnv`, as before, caused #18125 #16318, which should be fixed now. - - - - - 102cfd67 by Ryan Scott at 2020-05-13T20:04:46-04:00 Factor out HsPatSigType for pat sigs/RULE term sigs (#16762) This implements chunks (2) and (3) of https://gitlab.haskell.org/ghc/ghc/issues/16762#note_270170. Namely, it introduces a dedicated `HsPatSigType` AST type, which represents the types that can appear in pattern signatures and term-level `RULE` binders. Previously, these were represented with `LHsSigWcType`. Although `LHsSigWcType` is isomorphic to `HsPatSigType`, the intended semantics of the two types are slightly different, as evidenced by the fact that they have different code paths in the renamer and typechecker. See also the new `Note [Pattern signature binders and scoping]` in `GHC.Hs.Types`. - - - - - b17574f7 by Hécate at 2020-05-13T20:05:28-04:00 fix(documentation): Fix the RST links to GHC.Prim - - - - - df021fb1 by Baldur Blöndal at 2020-05-13T20:06:06-04:00 Document (->) using inferred quantification for its runtime representations. Fixes #18142. - - - - - 1a93ea57 by Takenobu Tani at 2020-05-13T20:06:54-04:00 Tweak man page for ghc command This commit updates the ghc command's man page as followings: * Enable `man_show_urls` to show URL addresses in the `DESCRIPTION` section of ghc.rst, because sphinx currently removes hyperlinks for man pages. * Add a `SEE ALSO` section to point to the GHC homepage - - - - - a951e1ba by Takenobu Tani at 2020-05-13T20:07:37-04:00 GHCi: Add link to the user's guide in help message This commit adds a link to the user's guide in ghci's `:help` message. Newcomers could easily reach to details of ghci. - - - - - 404581ea by Jeff Happily at 2020-05-13T20:08:15-04:00 Handle single unused import - - - - - 1c999e5d by Ben Gamari at 2020-05-13T20:09:07-04:00 Ensure that printMinimalImports closes handle Fixes #18166. - - - - - c9f5a8f4 by Ben Gamari at 2020-05-13T20:09:51-04:00 hadrian: Tell testsuite driver about LLVM availability This reflects the logic present in the Make build system into Hadrian. Fixes #18167. - - - - - c05c0659 by Simon Jakobi at 2020-05-14T03:31:21-04:00 Improve some folds over Uniq[D]FM * Replace some non-deterministic lazy folds with strict folds. * Replace some O(n log n) folds in deterministic order with O(n) non-deterministic folds. * Replace some folds with set-operations on the underlying IntMaps. This reduces max residency when compiling `nofib/spectral/simple/Main.hs` with -O0 by about 1%. Maximum residency when compiling Cabal also seems reduced on the order of 3-9%. - - - - - 477f13bb by Simon Jakobi at 2020-05-14T03:31:58-04:00 Use Data.IntMap.disjoint Data.IntMap gained a dedicated `disjoint` function in containers-0.6.2.1. This patch applies this function where appropriate in hopes of modest compiler performance improvements. Closes #16806. - - - - - e9c0110c by Ben Gamari at 2020-05-14T12:25:53-04:00 IdInfo: Add reference to bitfield-packing ticket - - - - - 9bd20e83 by Sebastian Graf at 2020-05-15T10:42:09-04:00 DmdAnal: Improve handling of precise exceptions This patch does two things: Fix possible unsoundness in what was called the "IO hack" and implement part 2.1 of the "fixing precise exceptions" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions, which, in combination with !2956, supersedes !3014 and !2525. **IO hack** The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is called `exprMayThrowPreciseException` now. I came up with two testcases exemplifying possible unsoundness (if twisted enough) in the old approach: - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. - `T13380e`: Demonstrating unsoundness of the "IO hack" when we have Nested CPR. Not currently relevant, as we don't have Nested CPR yet. - `T13380f`: Demonstrating unsoundness of the "IO hack" for safe FFI calls. Basically, the IO hack assumed that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future, see `T13380e`. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380{d,e}` (and will hopefully be robust to Nested CPR). **Precise exceptions** In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that was terribly unprincipled. That unprincipledness resulted in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception (and the existing IO hack doesn't detect that) Fixing both issues in !3014 turned out to be too complicated and had the potential to regress in the future. Hence we decided to only fix `T13380b` and augment the `Divergence` lattice with a new middle-layer element, `ExnOrDiv`, which means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. See the wiki page on Step 2.1 for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#dead-code-elimination-for-raiseio-with-isdeadenddiv-introducing-exnordiv-step-21 - - - - - 568d7279 by Ben Gamari at 2020-05-15T10:42:46-04:00 GHC.Cmm.Opt: Handle MO_XX_Conv This MachOp was introduced by 2c959a1894311e59cd2fd469c1967491c1e488f3 but a wildcard match in cmmMachOpFoldM hid the fact that it wasn't handled. Ideally we would eliminate the match but this appears to be a larger task. Fixes #18141. - - - - - 563bc167 by Sebastian Graf at 2020-05-15T23:08:06+02:00 Make WorkWrap.Lib.isWorkerSmallEnough aware of the old arity We should allow a wrapper with up to 82 parameters when the original function had 82 parameters to begin with. I verified that this made no difference on NoFib, but then again it doesn't use huge records... Fixes #18122. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/PPC/Cond.hs - compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.hs - compiler/GHC/CmmToAsm/SPARC/Cond.hs - compiler/GHC/CmmToAsm/X86/Cond.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/LiberateCase.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/eb859b4e4c6da4f3ad524187181ecf5af2635806...563bc167dc89032f99cd78fb5d6167f51ddccb5b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/eb859b4e4c6da4f3ad524187181ecf5af2635806...563bc167dc89032f99cd78fb5d6167f51ddccb5b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 16 12:17:07 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Sat, 16 May 2020 08:17:07 -0400 Subject: [Git][ghc/ghc][wip/andreask/iface_magic_numbers] 29 commits: rts/CNF: Fix fixup comparison function Message-ID: <5ebfd9c3895ae_7647adfa9a8105462@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/iface_magic_numbers at Glasgow Haskell Compiler / GHC Commits: cf4f1e2f by Ben Gamari at 2020-05-13T02:02:33-04:00 rts/CNF: Fix fixup comparison function Previously we would implicitly convert the difference between two words to an int, resulting in an integer overflow on 64-bit machines. Fixes #16992 - - - - - a03da9bf by Ömer Sinan Ağacan at 2020-05-13T02:03:16-04:00 Pack some of IdInfo fields into a bit field This reduces residency of compiler quite a bit on some programs. Example stats when building T10370: Before: 2,871,242,832 bytes allocated in the heap 4,693,328,008 bytes copied during GC 33,941,448 bytes maximum residency (276 sample(s)) 375,976 bytes maximum slop 83 MiB total memory in use (0 MB lost due to fragmentation) After: 2,858,897,344 bytes allocated in the heap 4,629,255,440 bytes copied during GC 32,616,624 bytes maximum residency (278 sample(s)) 314,400 bytes maximum slop 80 MiB total memory in use (0 MB lost due to fragmentation) So -3.9% residency, -1.3% bytes copied and -0.4% allocations. Fixes #17497 Metric Decrease: T9233 T9675 - - - - - 670c3e5c by Ben Gamari at 2020-05-13T02:03:54-04:00 get-win32-tarballs: Fix base URL Revert a change previously made for testing purposes. - - - - - 8ad8dc41 by Ben Gamari at 2020-05-13T02:03:54-04:00 get-win32-tarballs: Improve diagnostics output - - - - - 8c0740b7 by Simon Jakobi at 2020-05-13T02:04:33-04:00 docs: Add examples for Data.Semigroup.Arg{Min,Max} Context: #17153 - - - - - cb22348f by Ben Gamari at 2020-05-13T02:05:11-04:00 Add few cleanups of the CAF logic Give the NameSet of non-CAFfy names a proper newtype to distinguish it from all of the other NameSets floating about. - - - - - 90e38b81 by Emeka Nkurumeh at 2020-05-13T02:05:51-04:00 fix printf warning when using with ghc with clang on mingw - - - - - 86d8ac22 by Sebastian Graf at 2020-05-13T02:06:29-04:00 CprAnal: Don't attach CPR sigs to expandable bindings (#18154) Instead, look through expandable unfoldings in `cprTransform`. See the new Note [CPR for expandable unfoldings]: ``` Long static data structures (whether top-level or not) like xs = x1 : xs1 xs1 = x2 : xs2 xs2 = x3 : xs3 should not get CPR signatures, because they * Never get WW'd, so their CPR signature should be irrelevant after analysis (in fact the signature might even be harmful for that reason) * Would need to be inlined/expanded to see their constructed product * Recording CPR on them blows up interface file sizes and is redundant with their unfolding. In case of Nested CPR, this blow-up can be quadratic! But we can't just stop giving DataCon application bindings the CPR property, for example fac 0 = 1 fac n = n * fac (n-1) fac certainly has the CPR property and should be WW'd! But FloatOut will transform the first clause to lvl = 1 fac 0 = lvl If lvl doesn't have the CPR property, fac won't either. But lvl doesn't have a CPR signature to extrapolate into a CPR transformer ('cprTransform'). So instead we keep on cprAnal'ing through *expandable* unfoldings for these arity 0 bindings via 'cprExpandUnfolding_maybe'. In practice, GHC generates a lot of (nested) TyCon and KindRep bindings, one for each data declaration. It's wasteful to attach CPR signatures to each of them (and intractable in case of Nested CPR). ``` Fixes #18154. - - - - - e34bf656 by Ben Gamari at 2020-05-13T02:07:08-04:00 users-guide: Add discussion of shared object naming Fixes #18074. - - - - - 5d0f2445 by Ben Gamari at 2020-05-13T02:07:47-04:00 testsuite: Print sign of performance changes Executes the minor formatting change in the tabulated performance changes suggested in #18135. - - - - - 9e4b981f by Ben Gamari at 2020-05-13T02:08:24-04:00 testsuite: Add testcase for #18129 - - - - - 266310c3 by Ivan-Yudin at 2020-05-13T02:09:03-04:00 doc: Reformulate the opening paragraph of Ch. 4 in User's guide Removes mentioning of Hugs (it is not helpful for new users anymore). Changes the wording for the rest of the paragraph. Fixes #18132. - - - - - 55e35c0b by Baldur Blöndal at 2020-05-13T20:02:48-04:00 Predicate, Equivalence derive via `.. -> a -> All' - - - - - d7e0b57f by Alp Mestanogullari at 2020-05-13T20:03:30-04:00 hadrian: add a --freeze2 option to freeze stage 1 and 2 - - - - - d880d6b2 by Artem Pelenitsyn at 2020-05-13T20:04:11-04:00 Don't reload environment files on every setSessionDynFlags Makes `interpretPackageEnv` (which loads envirinment files) a part of `parseDynamicFlags` (parsing command-line arguments, which is typically done once) instead of `setSessionDynFlags` (which is typically called several times). Making several (transitive) calls to `interpretPackageEnv`, as before, caused #18125 #16318, which should be fixed now. - - - - - 102cfd67 by Ryan Scott at 2020-05-13T20:04:46-04:00 Factor out HsPatSigType for pat sigs/RULE term sigs (#16762) This implements chunks (2) and (3) of https://gitlab.haskell.org/ghc/ghc/issues/16762#note_270170. Namely, it introduces a dedicated `HsPatSigType` AST type, which represents the types that can appear in pattern signatures and term-level `RULE` binders. Previously, these were represented with `LHsSigWcType`. Although `LHsSigWcType` is isomorphic to `HsPatSigType`, the intended semantics of the two types are slightly different, as evidenced by the fact that they have different code paths in the renamer and typechecker. See also the new `Note [Pattern signature binders and scoping]` in `GHC.Hs.Types`. - - - - - b17574f7 by Hécate at 2020-05-13T20:05:28-04:00 fix(documentation): Fix the RST links to GHC.Prim - - - - - df021fb1 by Baldur Blöndal at 2020-05-13T20:06:06-04:00 Document (->) using inferred quantification for its runtime representations. Fixes #18142. - - - - - 1a93ea57 by Takenobu Tani at 2020-05-13T20:06:54-04:00 Tweak man page for ghc command This commit updates the ghc command's man page as followings: * Enable `man_show_urls` to show URL addresses in the `DESCRIPTION` section of ghc.rst, because sphinx currently removes hyperlinks for man pages. * Add a `SEE ALSO` section to point to the GHC homepage - - - - - a951e1ba by Takenobu Tani at 2020-05-13T20:07:37-04:00 GHCi: Add link to the user's guide in help message This commit adds a link to the user's guide in ghci's `:help` message. Newcomers could easily reach to details of ghci. - - - - - 404581ea by Jeff Happily at 2020-05-13T20:08:15-04:00 Handle single unused import - - - - - 1c999e5d by Ben Gamari at 2020-05-13T20:09:07-04:00 Ensure that printMinimalImports closes handle Fixes #18166. - - - - - c9f5a8f4 by Ben Gamari at 2020-05-13T20:09:51-04:00 hadrian: Tell testsuite driver about LLVM availability This reflects the logic present in the Make build system into Hadrian. Fixes #18167. - - - - - c05c0659 by Simon Jakobi at 2020-05-14T03:31:21-04:00 Improve some folds over Uniq[D]FM * Replace some non-deterministic lazy folds with strict folds. * Replace some O(n log n) folds in deterministic order with O(n) non-deterministic folds. * Replace some folds with set-operations on the underlying IntMaps. This reduces max residency when compiling `nofib/spectral/simple/Main.hs` with -O0 by about 1%. Maximum residency when compiling Cabal also seems reduced on the order of 3-9%. - - - - - 477f13bb by Simon Jakobi at 2020-05-14T03:31:58-04:00 Use Data.IntMap.disjoint Data.IntMap gained a dedicated `disjoint` function in containers-0.6.2.1. This patch applies this function where appropriate in hopes of modest compiler performance improvements. Closes #16806. - - - - - e9c0110c by Ben Gamari at 2020-05-14T12:25:53-04:00 IdInfo: Add reference to bitfield-packing ticket - - - - - 9bd20e83 by Sebastian Graf at 2020-05-15T10:42:09-04:00 DmdAnal: Improve handling of precise exceptions This patch does two things: Fix possible unsoundness in what was called the "IO hack" and implement part 2.1 of the "fixing precise exceptions" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions, which, in combination with !2956, supersedes !3014 and !2525. **IO hack** The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is called `exprMayThrowPreciseException` now. I came up with two testcases exemplifying possible unsoundness (if twisted enough) in the old approach: - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. - `T13380e`: Demonstrating unsoundness of the "IO hack" when we have Nested CPR. Not currently relevant, as we don't have Nested CPR yet. - `T13380f`: Demonstrating unsoundness of the "IO hack" for safe FFI calls. Basically, the IO hack assumed that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future, see `T13380e`. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380{d,e}` (and will hopefully be robust to Nested CPR). **Precise exceptions** In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that was terribly unprincipled. That unprincipledness resulted in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception (and the existing IO hack doesn't detect that) Fixing both issues in !3014 turned out to be too complicated and had the potential to regress in the future. Hence we decided to only fix `T13380b` and augment the `Divergence` lattice with a new middle-layer element, `ExnOrDiv`, which means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. See the wiki page on Step 2.1 for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#dead-code-elimination-for-raiseio-with-isdeadenddiv-introducing-exnordiv-step-21 - - - - - 568d7279 by Ben Gamari at 2020-05-15T10:42:46-04:00 GHC.Cmm.Opt: Handle MO_XX_Conv This MachOp was introduced by 2c959a1894311e59cd2fd469c1967491c1e488f3 but a wildcard match in cmmMachOpFoldM hid the fact that it wasn't handled. Ideally we would eliminate the match but this appears to be a larger task. Fixes #18141. - - - - - 466a61c0 by Andreas Klebinger at 2020-05-16T08:16:53-04:00 Don't variable-length encode magic iface constant. We changed to use variable length encodings for many types by default, including Word32. This makes sense for numbers but not when Word32 is meant to represent four bytes. I added a FixedLengthEncoding newtype to Binary who's instances interpret their argument as a collection of bytes instead of a number. We then use this when writing/reading magic numbers to the iface file. I also took the libery to remove the dummy iface field. This fixes #18180. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/LiberateCase.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Unify.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a146a18d9391236207a249b3e9ecb938781507bc...466a61c0f42f1e8b340c05fb03abde289fbf942c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a146a18d9391236207a249b3e9ecb938781507bc...466a61c0f42f1e8b340c05fb03abde289fbf942c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 16 16:48:53 2020 From: gitlab at gitlab.haskell.org (Matthew Pickering) Date: Sat, 16 May 2020 12:48:53 -0400 Subject: [Git][ghc/ghc][wip/con-info] 2 commits: Checkpoint: SrcSpan information now correct for info tables Message-ID: <5ec0197564d0c_7647c31040011770@gitlab.haskell.org.mail> Matthew Pickering pushed to branch wip/con-info at Glasgow Haskell Compiler / GHC Commits: 4861f0f3 by Matthew Pickering at 2020-05-16T12:57:02+01:00 Checkpoint: SrcSpan information now correct for info tables - - - - - 5040ba85 by Matthew Pickering at 2020-05-16T17:44:03+01:00 WIP: Add InfoProvElt and dump source locations of info tables into eventlog - - - - - 24 changed files: - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/Driver/CodeOutput.hs - compiler/GHC/Driver/Hooks.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/StgToCmm.hs - compiler/GHC/StgToCmm/Closure.hs - compiler/GHC/StgToCmm/DataCon.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToCmm/Monad.hs - compiler/GHC/StgToCmm/Prof.hs - compiler/GHC/StgToCmm/Utils.hs - compiler/GHC/Types/CostCentre.hs - includes/rts/EventLogFormat.h - includes/rts/Profiling.h - includes/rts/prof/CCS.h - rts/Profiling.c - rts/RtsSymbols.c - rts/Trace.c - rts/Trace.h - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h Changes: ===================================== compiler/GHC/Cmm.hs ===================================== @@ -166,9 +166,10 @@ data CmmInfoTable -- GHC.Cmm.Info.Build.doSRTs. } + data ProfilingInfo = NoProfilingInfo - | ProfilingInfo ByteString ByteString -- closure_type, closure_desc + | ProfilingInfo ByteString ByteString -- closure_type, closure_desc ----------------------------------------------------------------------------- -- Static Data ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -13,6 +13,7 @@ module GHC.Cmm.CLabel ( CLabel, -- abstract type ForeignLabelSource(..), + InfoTableEnt(..), pprDebugCLabel, mkClosureLabel, @@ -87,6 +88,8 @@ module GHC.Cmm.CLabel ( isStaticClosureLabel, mkCCLabel, mkCCSLabel, + mkIPELabel, InfoTableEnt(..), + DynamicLinkerLabelInfo(..), mkDynamicLinkerLabel, dynamicLinkerLabelInfo, @@ -133,6 +136,7 @@ import GHC.Types.Unique.Set import GHC.Utils.Misc import GHC.Core.Ppr ( {- instances -} ) import GHC.CmmToAsm.Config +import GHC.Types.SrcLoc -- ----------------------------------------------------------------------------- -- The CLabel type @@ -235,6 +239,7 @@ data CLabel | CC_Label CostCentre | CCS_Label CostCentreStack + | IPE_Label InfoTableEnt -- | These labels are generated and used inside the NCG only. @@ -307,6 +312,8 @@ instance Ord CLabel where compare a1 a2 compare (CCS_Label a1) (CCS_Label a2) = compare a1 a2 + compare (IPE_Label a1) (IPE_Label a2) = + compare a1 a2 compare (DynamicLinkerLabel a1 b1) (DynamicLinkerLabel a2 b2) = compare a1 a2 `thenCmp` compare b1 b2 @@ -484,13 +491,13 @@ mkClosureLabel :: Name -> CafInfo -> CLabel mkInfoTableLabel :: Name -> CafInfo -> CLabel mkEntryLabel :: Name -> CafInfo -> CLabel mkClosureTableLabel :: Name -> CafInfo -> CLabel -mkConInfoTableLabel :: Name -> (Maybe (Module, Int)) -> CafInfo -> CLabel +mkConInfoTableLabel :: Name -> (Maybe (Module, Int)) -> CLabel mkBytesLabel :: Name -> CLabel mkClosureLabel name c = IdLabel name c Closure mkInfoTableLabel name c = IdLabel name c InfoTable mkEntryLabel name c = IdLabel name c Entry mkClosureTableLabel name c = IdLabel name c ClosureTable -mkConInfoTableLabel name k c = IdLabel name c (ConInfoTable k) +mkConInfoTableLabel name k = IdLabel name NoCafRefs (ConInfoTable k) mkBytesLabel name = IdLabel name NoCafRefs Bytes mkBlockInfoTableLabel :: Name -> CafInfo -> CLabel @@ -660,11 +667,18 @@ foreignLabelStdcallInfo _lbl = Nothing mkBitmapLabel :: Unique -> CLabel mkBitmapLabel uniq = LargeBitmapLabel uniq + +data InfoTableEnt = InfoTableEnt { infoTablePtr :: CLabel + , infoTableProv :: (Module, RealSrcSpan, String) } + deriving (Eq, Ord) + -- Constructing Cost Center Labels mkCCLabel :: CostCentre -> CLabel mkCCSLabel :: CostCentreStack -> CLabel +mkIPELabel :: InfoTableEnt -> CLabel mkCCLabel cc = CC_Label cc mkCCSLabel ccs = CCS_Label ccs +mkIPELabel ipe = IPE_Label ipe mkRtsApFastLabel :: FastString -> CLabel mkRtsApFastLabel str = RtsLabel (RtsApFast str) @@ -803,6 +817,7 @@ needsCDecl (CmmLabel pkgId _ _) needsCDecl l@(ForeignLabel{}) = not (isMathFun l) needsCDecl (CC_Label _) = True needsCDecl (CCS_Label _) = True +needsCDecl (IPE_Label {}) = True needsCDecl (HpcTicksLabel _) = True needsCDecl (DynamicLinkerLabel {}) = panic "needsCDecl DynamicLinkerLabel" needsCDecl PicBaseLabel = panic "needsCDecl PicBaseLabel" @@ -925,6 +940,7 @@ externallyVisibleCLabel (ForeignLabel{}) = True externallyVisibleCLabel (IdLabel name _ info) = isExternalName name && externallyVisibleIdLabel info externallyVisibleCLabel (CC_Label _) = True externallyVisibleCLabel (CCS_Label _) = True +externallyVisibleCLabel (IPE_Label {}) = True externallyVisibleCLabel (DynamicLinkerLabel _ _) = False externallyVisibleCLabel (HpcTicksLabel _) = True externallyVisibleCLabel (LargeBitmapLabel _) = False @@ -984,6 +1000,7 @@ labelType (AsmTempDerivedLabel _ _) = panic "labelType(AsmTempDerive labelType (StringLitLabel _) = DataLabel labelType (CC_Label _) = DataLabel labelType (CCS_Label _) = DataLabel +labelType (IPE_Label {}) = DataLabel labelType (DynamicLinkerLabel _ _) = DataLabel -- Is this right? labelType PicBaseLabel = DataLabel labelType (DeadStripPreventer _) = DataLabel @@ -1072,6 +1089,7 @@ labelDynamic config this_mod lbl = -- CCS_Label always contains a CostCentre defined in the current module CCS_Label _ -> False + IPE_Label {} -> False HpcTicksLabel m -> externalDynamicRefs && this_mod /= m @@ -1295,6 +1313,7 @@ pprCLbl dflags = \case (CC_Label cc) -> ppr cc (CCS_Label ccs) -> ppr ccs + (IPE_Label (InfoTableEnt l _)) -> ppr l <> text "_ipe" (HpcTicksLabel mod) -> text "_hpc_tickboxes_" <> ppr mod <> ptext (sLit "_hpc") (AsmTempLabel {}) -> panic "pprCLbl AsmTempLabel" ===================================== compiler/GHC/Cmm/DebugBlock.hs ===================================== @@ -189,7 +189,7 @@ cmmDebugGen modLoc decls = map (blocksForScope Nothing) topScopes ticks = nubBy (flip tickishContains) $ bCtxsTicks bctxs ++ ticksToCopy scope stick = case filter isSourceTick ticks of - [] -> cstick + [] -> pprTraceIt "DWARF-C" cstick sticks -> Just $! bestSrcTick (sticks ++ maybeToList cstick) -- | Build a map of blocks sorted by their tick scopes ===================================== compiler/GHC/CoreToStg.hs ===================================== @@ -11,7 +11,7 @@ -- And, as we have the info in hand, we may convert some lets to -- let-no-escapes. -module GHC.CoreToStg ( coreToStg ) where +module GHC.CoreToStg ( coreToStg ) where #include "HsVersions.h" @@ -53,8 +53,9 @@ import Data.List.NonEmpty (nonEmpty, toList) import Data.Maybe (fromMaybe) import Control.Monad (ap) import qualified Data.Set as Set -import Control.Monad.Trans.State +import Control.Monad.Trans.RWS import GHC.Types.Unique.Map +import GHC.Types.SrcLoc -- Note [Live vs free] -- ~~~~~~~~~~~~~~~~~~~ @@ -226,7 +227,6 @@ import GHC.Types.Unique.Map -- Setting variable info: top-level, binds, RHSs -- -------------------------------------------------------------- -type DCMap = UniqMap DataCon Int coreToStg :: DynFlags -> Module -> CoreProgram -> ([StgTopBinding], DCMap, CollectedCCs) @@ -410,12 +410,12 @@ coreToStgExpr expr@(Lam _ _) return result_expr coreToStgExpr (Tick tick expr) - = do case tick of - HpcTick{} -> return () - ProfNote{} -> return () - SourceNote{} -> return () - Breakpoint{} -> panic "coreToStgExpr: breakpoint should not happen" - expr2 <- coreToStgExpr expr + = do let k = case tick of + HpcTick{} -> id + ProfNote{} -> id + SourceNote ss fp -> withSpan (ss, fp) + Breakpoint{} -> panic "coreToStgExpr: breakpoint should not happen" + expr2 <- k (coreToStgExpr expr) return (StgTick tick expr2) coreToStgExpr (Cast expr _) @@ -833,7 +833,7 @@ isPAP env _ = False newtype CtsM a = CtsM { unCtsM :: DynFlags -- Needed for checking for bad coercions in coreToStgArgs -> IdEnv HowBound - -> State DCMap a + -> RWS (Maybe (RealSrcSpan, String)) () DCMap a } deriving (Functor) @@ -870,7 +870,9 @@ data LetInfo -- The std monad functions: initCts :: DynFlags -> IdEnv HowBound -> DCMap -> CtsM a -> (a, DCMap) -initCts dflags env u m = flip runState u (unCtsM m dflags env) +initCts dflags env u m = + let (a, d, ()) = runRWS (unCtsM m dflags env) Nothing u + in (a, d) @@ -915,11 +917,14 @@ lookupBinding env v = case lookupVarEnv env v of incDc :: DataCon -> CtsM Int incDc dc = CtsM $ \_ _ -> do env <- get - let env' = alterUniqMap (maybe (Just 0) (Just . (+1))) env dc + cc <- ask + let env' = alterUniqMap (maybe (Just [(0, cc)]) (\xs@((k, _):_) -> Just ((k + 1, cc) : xs))) env dc put env' let Just r = lookupUniqMap env' dc - return r + return (fst (head r)) +withSpan :: (RealSrcSpan, String) -> CtsM a -> CtsM a +withSpan s (CtsM act) = CtsM (\a b -> local (const $ Just s) (act a b)) getAllCAFsCC :: Module -> (CostCentre, CostCentreStack) getAllCAFsCC this_mod = ===================================== compiler/GHC/Driver/CodeOutput.hs ===================================== @@ -1,3 +1,4 @@ +{-# LANGUAGE TypeApplications #-} {- (c) The GRASP/AQUA Project, Glasgow University, 1993-1998 @@ -10,6 +11,7 @@ module GHC.Driver.CodeOutput ( codeOutput , outputForeignStubs , profilingInitCode + , ipInitCode ) where @@ -32,6 +34,8 @@ import GHC.Driver.Session import GHC.Data.Stream ( Stream ) import qualified GHC.Data.Stream as Stream import GHC.SysTools.FileCleanup +import GHC.StgToCmm.Utils + import GHC.Utils.Error import GHC.Utils.Outputable @@ -314,3 +318,35 @@ profilingInitCode dflags this_mod (local_CCs, singleton_CCSs) | cc <- ccs ] ++ [text "NULL"]) <> semi + + +-- | Generate code to initialise info pointer origin +ipInitCode :: DynFlags -> Module -> DCMap -> SDoc +ipInitCode dflags this_mod dcmap + = pprTraceIt "codeOutput" $ if not (gopt Opt_SccProfilingOn dflags) + then empty + else vcat + $ map emit_ipe_decl ents + ++ [emit_ipe_list ents] + ++ [ text "static void ip_init_" <> ppr this_mod + <> text "(void) __attribute__((constructor));" + , text "static void ip_init_" <> ppr this_mod <> text "(void)" + , braces (vcat + [ text "registerInfoProvList" <> parens local_ipe_list_label <> semi + ]) + ] + where + ents = convertDCMap this_mod dcmap + emit_ipe_decl ipe = + text "extern InfoProvEnt" <+> ipe_lbl <> text "[];" + where ipe_lbl = ppr (mkIPELabel ipe) + local_ipe_list_label = text "local_ipe_" <> ppr this_mod + emit_ipe_list ipes = + text "static InfoProvEnt *" <> local_ipe_list_label <> text "[] =" + <+> braces (vcat $ [ ppr (mkIPELabel ipe) <> comma + | ipe <- ipes + ] ++ [text "NULL"]) + <> semi + + + ===================================== compiler/GHC/Driver/Hooks.hs ===================================== @@ -110,7 +110,8 @@ data Hooks = Hooks , getValueSafelyHook :: Maybe (HscEnv -> Name -> Type -> IO (Maybe HValue)) , createIservProcessHook :: Maybe (CreateProcess -> IO ProcessHandle) - , stgToCmmHook :: Maybe (DynFlags -> Module -> UniqMap DataCon Int -> [TyCon] -> CollectedCCs + , stgToCmmHook :: Maybe (DynFlags -> Module -> DCMap -> [TyCon] -> CollectedCCs + -> [CgStgTopBinding] -> HpcInfo -> Stream IO CmmGroup ()) , cmmToRawCmmHook :: forall a . Maybe (DynFlags -> Maybe Module -> Stream IO CmmGroupSRTs a -> IO (Stream IO RawCmmGroup a)) ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -138,6 +138,7 @@ import GHC.Cmm.Parser ( parseCmmFile ) import GHC.Cmm.Info.Build import GHC.Cmm.Pipeline import GHC.Cmm.Info +import GHC.Cmm.CLabel import GHC.Driver.CodeOutput import GHC.Core.InstEnv import GHC.Core.FamInstEnv @@ -1418,7 +1419,8 @@ hscGenHardCode hsc_env cgguts location output_filename = do let cost_centre_info = (S.toList local_ccs ++ caf_ccs, caf_cc_stacks) prof_init = profilingInitCode dflags this_mod cost_centre_info - foreign_stubs = foreign_stubs0 `appendStubC` prof_init + ip_init = ipInitCode dflags this_mod denv + foreign_stubs = foreign_stubs0 `appendStubC` prof_init `appendStubC` ip_init ------------------ Code generation ------------------ @@ -1540,7 +1542,7 @@ This reduces residency towards the end of the CodeGen phase significantly (5-10%). -} -doCodeGen :: HscEnv -> Module -> UniqMap DataCon Int -> [TyCon] +doCodeGen :: HscEnv -> Module -> DCMap -> [TyCon] -> CollectedCCs -> [StgTopBinding] -> HpcInfo @@ -1589,7 +1591,7 @@ doCodeGen hsc_env this_mod denv data_tycons myCoreToStg :: DynFlags -> Module -> CoreProgram -> IO ( [StgTopBinding] -- output program - , UniqMap DataCon Int + , DCMap , CollectedCCs ) -- CAF cost centre info (declared and used) myCoreToStg dflags this_mod prepd_binds = do let (stg_binds, denv, cost_centre_info) ===================================== compiler/GHC/StgToCmm.hs ===================================== @@ -15,7 +15,7 @@ module GHC.StgToCmm ( codeGen ) where import GHC.Prelude as Prelude -import GHC.StgToCmm.Prof (initCostCentres, ldvEnter) +import GHC.StgToCmm.Prof (initInfoTableProv, initCostCentres, ldvEnter) import GHC.StgToCmm.Monad import GHC.StgToCmm.Env import GHC.StgToCmm.Bind @@ -58,10 +58,13 @@ import GHC.Utils.Misc import System.IO.Unsafe import qualified Data.ByteString as BS import GHC.Types.Unique.Map +import GHC.Types.SrcLoc +import Data.Maybe + codeGen :: DynFlags -> Module - -> UniqMap DataCon Int + -> DCMap -> [TyCon] -> CollectedCCs -- (Local/global) cost-centres needing declaring/registering. -> [CgStgTopBinding] -- Bindings to convert @@ -69,7 +72,7 @@ codeGen :: DynFlags -> Stream IO CmmGroup () -- Output as a stream, so codegen can -- be interleaved with output -codeGen dflags this_mod (UniqMap denv) data_tycons +codeGen dflags this_mod dcmap@(UniqMap denv) data_tycons cost_centre_info stg_binds hpc_info = do { -- cg: run the code generator, and yield the resulting CmmGroup -- Using an IORef to store the state is a bit crude, but otherwise @@ -92,7 +95,7 @@ codeGen dflags this_mod (UniqMap denv) data_tycons -- FIRST. This is because when -split-objs is on we need to -- combine this block with its initialisation routines; see -- Note [pipeline-split-init]. - ; cg (mkModuleInit cost_centre_info this_mod hpc_info) + ; cg (mkModuleInit cost_centre_info this_mod hpc_info (convertDCMap this_mod dcmap)) ; mapM_ (cg . cgTopBinding dflags) stg_binds @@ -106,11 +109,11 @@ codeGen dflags this_mod (UniqMap denv) data_tycons -- tagged. when (isEnumerationTyCon tycon) $ cg (cgEnumerationTyCon tycon) -- Emit normal info_tables, just in case - mapM_ (cg . cgDataCon Nothing) (tyConDataCons tycon) + mapM_ (cg . cgDataCon Nothing Nothing) (tyConDataCons tycon) -- Emit special info tables for everything used in this module ; mapM_ do_tycon data_tycons - ; mapM_ (\(dc, n) -> forM_ [0..n] $ \k -> cg (cgDataCon (Just (this_mod, k)) dc)) (nonDetEltsUFM denv) + ; mapM_ (\(dc, ns) -> forM_ ns $ \(k, ss) -> cg (cgDataCon (Just (this_mod, k)) ss dc)) (nonDetEltsUFM denv) } --------------------------------------------------------------- @@ -183,11 +186,13 @@ mkModuleInit :: CollectedCCs -- cost centre info -> Module -> HpcInfo + -> [InfoTableEnt] -> FCode () -mkModuleInit cost_centre_info this_mod hpc_info +mkModuleInit cost_centre_info this_mod hpc_info info_ents = do { initHpc this_mod hpc_info ; initCostCentres cost_centre_info + ; initInfoTableProv info_ents } @@ -205,12 +210,12 @@ cgEnumerationTyCon tycon | con <- tyConDataCons tycon] -cgDataCon :: Maybe (Module, Int) -> DataCon -> FCode () +cgDataCon :: Maybe (Module, Int) -> Maybe (RealSrcSpan, String) -> DataCon -> FCode () -- Generate the entry code, info tables, and (for niladic constructor) -- the static closure, for a constructor. -cgDataCon _ data_con | isUnboxedTupleCon data_con = return () -cgDataCon mn data_con - = do { pprTraceM "cgDataCon" (ppr mn <+> ppr data_con) +cgDataCon _ _ data_con | isUnboxedTupleCon data_con = return () +cgDataCon mn ms data_con + = do { pprTraceM "cgDataCon" (ppr mn <+> ppr ms <+> ppr data_con) ; dflags <- getDynFlags ; platform <- getPlatform ; let @@ -221,7 +226,7 @@ cgDataCon mn data_con nonptr_wds = tot_wds - ptr_wds dyn_info_tbl = - mkDataConInfoTable dflags data_con mn False ptr_wds nonptr_wds + mkDataConInfoTable dflags data_con mn ms False ptr_wds nonptr_wds -- We're generating info tables, so we don't know and care about -- what the actual arguments are. Using () here as the place holder. ===================================== compiler/GHC/StgToCmm/Closure.hs ===================================== @@ -71,6 +71,8 @@ import GHC.Runtime.Heap.Layout import GHC.Cmm import GHC.Cmm.Ppr.Expr() -- For Outputable instances +import GHC.Types.SrcLoc + import GHC.Types.CostCentre import GHC.Cmm.BlockId import GHC.Cmm.CLabel @@ -947,8 +949,8 @@ getTyLitDescription l = -- CmmInfoTable-related things -------------------------------------- -mkDataConInfoTable :: DynFlags -> DataCon -> Maybe (Module, Int) -> Bool -> Int -> Int -> CmmInfoTable -mkDataConInfoTable dflags data_con mn is_static ptr_wds nonptr_wds +mkDataConInfoTable :: DynFlags -> DataCon -> Maybe (Module, Int) -> Maybe (RealSrcSpan, String) -> Bool -> Int -> Int -> CmmInfoTable +mkDataConInfoTable dflags data_con mn mspn is_static ptr_wds nonptr_wds = CmmInfoTable { cit_lbl = info_lbl , cit_rep = sm_rep , cit_prof = prof @@ -956,7 +958,7 @@ mkDataConInfoTable dflags data_con mn is_static ptr_wds nonptr_wds , cit_clo = Nothing } where name = dataConName data_con - info_lbl = mkConInfoTableLabel name mn NoCafRefs + info_lbl = mkConInfoTableLabel name mn sm_rep = mkHeapRep dflags is_static ptr_wds nonptr_wds cl_type cl_type = Constr (dataConTagZ data_con) (dataConIdentity data_con) -- We keep the *zero-indexed* tag in the srt_len field @@ -966,7 +968,11 @@ mkDataConInfoTable dflags data_con mn is_static ptr_wds nonptr_wds | otherwise = ProfilingInfo ty_descr val_descr ty_descr = BS8.pack $ occNameString $ getOccName $ dataConTyCon data_con - val_descr = BS8.pack $ occNameString $ getOccName data_con + val_descr = BS8.pack $ (occNameString $ getOccName data_con) ++ span_string + + span_string = case mspn of + Nothing -> "" + Just (spn, f) -> f ++ ":" ++ show (srcSpanStartLine spn) ++ ":" ++ show (srcSpanStartCol spn) -- We need a black-hole closure info to pass to @allocDynClosure@ when we -- want to allocate the black hole on entry to a CAF. ===================================== compiler/GHC/StgToCmm/DataCon.hs ===================================== @@ -30,6 +30,7 @@ import GHC.StgToCmm.Layout import GHC.StgToCmm.Utils import GHC.StgToCmm.Closure +import GHC.Types.SrcLoc import GHC.Cmm.Expr import GHC.Cmm.Utils @@ -113,7 +114,7 @@ cgTopRhsCon dflags id con mn args -- we're not really going to emit an info table, so having -- to make a CmmInfoTable is a bit overkill, but mkStaticClosureFields -- needs to poke around inside it. - info_tbl = mkDataConInfoTable dflags con ((this_mod,) <$> mn) True ptr_wds nonptr_wds + info_tbl = mkDataConInfoTable dflags con ((this_mod,) <$> mn) Nothing True ptr_wds nonptr_wds ; payload <- mapM mk_payload nv_args_w_offsets @@ -146,11 +147,13 @@ buildDynCon :: Id -- Name of the thing to which this constr will -- Return details about how to find it and initialization code buildDynCon binder mn actually_bound cc con args = do dflags <- getDynFlags - buildDynCon' dflags binder mn actually_bound cc con args + spn <- getEnclosingSpan + buildDynCon' dflags binder mn spn actually_bound cc con args buildDynCon' :: DynFlags - -> Id -> Maybe Int -> Bool + -> Id -> Maybe Int -> Maybe (RealSrcSpan, String) + -> Bool -> CostCentreStack -> DataCon -> [NonVoid StgArg] @@ -167,13 +170,13 @@ the addr modes of the args is that we may be in a "knot", and premature looking at the args will cause the compiler to black-hole! -} -buildDynCon' dflags binder _ _ _cc con args +buildDynCon' dflags binder _ _ _ _cc con args | Just cgInfo <- precomputedStaticConInfo_maybe dflags binder con args -- , pprTrace "noCodeLocal:" (ppr (binder,con,args,cgInfo)) True = return (cgInfo, return mkNop) -------- buildDynCon': the general case ----------- -buildDynCon' dflags binder mn actually_bound ccs con args +buildDynCon' dflags binder mn spn actually_bound ccs con args = do { (id_info, reg) <- rhsIdInfo binder lf_info ; return (id_info, gen_code reg) } @@ -185,7 +188,7 @@ buildDynCon' dflags binder mn actually_bound ccs con args ; let (tot_wds, ptr_wds, args_w_offsets) = mkVirtConstrOffsets dflags (addArgReps args) nonptr_wds = tot_wds - ptr_wds - info_tbl = mkDataConInfoTable dflags con ((modu,) <$> mn) False + info_tbl = mkDataConInfoTable dflags con ((modu,) <$> mn) spn False ptr_wds nonptr_wds ; let ticky_name | actually_bound = Just binder | otherwise = Nothing ===================================== compiler/GHC/StgToCmm/Expr.hs ===================================== @@ -81,7 +81,7 @@ cgExpr (StgOpApp (StgPrimOp DataToTagOp) [StgVarArg a] _res_ty) = do cgExpr (StgOpApp op args ty) = cgOpApp op args ty cgExpr (StgConApp con mn args _)= cgConApp con mn args -cgExpr (StgTick t e) = cgTick t >> cgExpr e +cgExpr (StgTick t e) = cgTick t (cgExpr e) cgExpr (StgLit lit) = do cmm_lit <- cgLit lit emitReturn [CmmLit cmm_lit] @@ -1083,12 +1083,12 @@ emitEnter fun = do -- | Generate Cmm code for a tick. Depending on the type of Tickish, -- this will either generate actual Cmm instrumentation code, or -- simply pass on the annotation as a @CmmTickish at . -cgTick :: Tickish Id -> FCode () -cgTick tick +cgTick :: Tickish Id -> FCode a -> FCode a +cgTick tick k = do { platform <- getPlatform ; case tick of - ProfNote cc t p -> emitSetCCC cc t p - HpcTick m n -> emit (mkTickBox platform m n) - SourceNote s n -> emitTick $ SourceNote s n - _other -> return () -- ignore + ProfNote cc t p -> emitSetCCC cc t p >> k + HpcTick m n -> emit (mkTickBox platform m n) >> k + SourceNote s n -> emitTick (SourceNote s n) >> withEnclosingSpan s n k + _other -> k } ===================================== compiler/GHC/StgToCmm/Monad.hs ===================================== @@ -54,7 +54,7 @@ module GHC.StgToCmm.Monad ( -- more localised access to monad state CgIdInfo(..), getBinds, setBinds, - + withEnclosingSpan, getEnclosingSpan, -- out of general friendliness, we also export ... CgInfoDownwards(..), CgState(..) -- non-abstract ) where @@ -80,6 +80,7 @@ import GHC.Types.Unique.Supply import GHC.Data.FastString import GHC.Utils.Outputable import GHC.Utils.Misc +import GHC.Types.SrcLoc import Control.Monad import Data.List @@ -166,7 +167,8 @@ data CgInfoDownwards -- information only passed *downwards* by the monad -- as local jumps? See Note -- [Self-recursive tail calls] in -- GHC.StgToCmm.Expr - cgd_tick_scope:: CmmTickScope -- Tick scope for new blocks & ticks + cgd_tick_scope:: CmmTickScope, -- Tick scope for new blocks & ticks + cgd_enclosing_span :: Maybe (RealSrcSpan, String) -- } type CgBindings = IdEnv CgIdInfo @@ -281,7 +283,8 @@ initCgInfoDown dflags mod , cgd_ticky = mkTopTickyCtrLabel , cgd_sequel = initSequel , cgd_self_loop = Nothing - , cgd_tick_scope= GlobalScope } + , cgd_tick_scope= GlobalScope + , cgd_enclosing_span = Nothing } initSequel :: Sequel initSequel = Return @@ -455,6 +458,12 @@ newUnique = do return u ------------------ +withEnclosingSpan :: RealSrcSpan -> String -> FCode a -> FCode a +withEnclosingSpan ss s (FCode f)= FCode $ \info_down st -> f (info_down { cgd_enclosing_span = Just (ss, s) }) st + +getEnclosingSpan :: FCode (Maybe (RealSrcSpan, String)) +getEnclosingSpan = FCode $ \info_down st -> (cgd_enclosing_span info_down, st) + getInfoDown :: FCode CgInfoDownwards getInfoDown = FCode $ \info_down state -> (info_down,state) ===================================== compiler/GHC/StgToCmm/Prof.hs ===================================== @@ -10,6 +10,9 @@ module GHC.StgToCmm.Prof ( initCostCentres, ccType, ccsType, mkCCostCentre, mkCCostCentreStack, + -- infoTablePRov + initInfoTableProv, + -- Cost-centre Profiling dynProfHdr, profDynAlloc, profAlloc, staticProfHdr, initUpdFrameProf, enterCostCentreThunk, enterCostCentreFun, @@ -270,6 +273,37 @@ sizeof_ccs_words dflags platform = targetPlatform dflags (ws,ms) = sIZEOF_CostCentreStack dflags `divMod` platformWordSizeInBytes platform + +initInfoTableProv :: [InfoTableEnt] -> FCode () +-- Emit the declarations +initInfoTableProv ents + = do dflags <- getDynFlags + pprTraceM "initInfoTable" (ppr (length ents)) + mapM_ emitInfoTableProv ents + +--- Info Table Prov stuff +emitInfoTableProv :: InfoTableEnt -> FCode () +emitInfoTableProv ip = do + { dflags <- getDynFlags + ; let (mod, src, label) = infoTableProv ip + ; platform <- getPlatform + -- NB. bytesFS: we want the UTF-8 bytes here (#5559) + ; label <- newByteStringCLit (bytesFS $ mkFastString label) + ; modl <- newByteStringCLit (bytesFS $ moduleNameFS + $ moduleName + $ mod) + ; loc <- newByteStringCLit $ bytesFS $ mkFastString $ + showPpr dflags src + -- XXX going via FastString to get UTF-8 encoding is silly + ; let + lits = [ CmmLabel (infoTablePtr ip), -- Info table pointer + label, -- char *label, + modl, -- char *module, + loc, -- char *srcloc, + zero platform -- struct _InfoProvEnt *link + ] + ; emitDataLits (mkIPELabel ip) lits + } -- --------------------------------------------------------------------------- -- Set the current cost centre stack @@ -298,6 +332,7 @@ bumpSccCount dflags ccs (cmmOffsetB platform ccs (oFFSET_CostCentreStack_scc_count dflags)) 1 where platform = targetPlatform dflags + ----------------------------------------------------------------------------- -- -- Lag/drag/void stuff ===================================== compiler/GHC/StgToCmm/Utils.hs ===================================== @@ -44,6 +44,8 @@ module GHC.StgToCmm.Utils ( whenUpdRemSetEnabled, emitUpdRemSetPush, emitUpdRemSetPushThunk, + + convertDCMap ) where #include "HsVersions.h" @@ -85,6 +87,10 @@ import qualified Data.Map as M import Data.Char import Data.List import Data.Ord +import GHC.Types.Unique.Map +import GHC.Types.Unique.FM +import Data.Maybe +import GHC.Core.DataCon ------------------------------------------------------------------------- @@ -624,3 +630,13 @@ emitUpdRemSetPushThunk ptr = do [(CmmReg (CmmGlobal BaseReg), AddrHint), (ptr, AddrHint)] False + + +convertDCMap :: Module -> DCMap -> [InfoTableEnt] +convertDCMap this_mod (UniqMap denv) = + concatMap (\(dc, ns) -> mapMaybe (\(k, mss) -> + case mss of + Nothing -> Nothing + Just (ss, l) -> Just $ + InfoTableEnt (mkConInfoTableLabel (dataConName dc) (Just (this_mod, k))) + (this_mod, ss, l)) ns) (nonDetEltsUFM denv) \ No newline at end of file ===================================== compiler/GHC/Types/CostCentre.hs ===================================== @@ -2,7 +2,7 @@ module GHC.Types.CostCentre ( CostCentre(..), CcName, CCFlavour(..), -- All abstract except to friend: ParseIface.y - + DCMap, CostCentreStack, CollectedCCs, emptyCollectedCCs, collectCC, currentCCS, dontCareCCS, @@ -32,6 +32,8 @@ import GHC.Types.SrcLoc import GHC.Data.FastString import GHC.Utils.Misc import GHC.Types.CostCentre.State +import GHC.Core.DataCon +import GHC.Types.Unique.Map import Data.Data @@ -185,6 +187,8 @@ data CostCentreStack deriving (Eq, Ord) -- needed for Ord on CLabel +type DCMap = UniqMap DataCon [(Int, Maybe (RealSrcSpan, String))] + -- synonym for triple which describes the cost centre info in the generated -- code for a module. ===================================== includes/rts/EventLogFormat.h ===================================== @@ -142,6 +142,7 @@ #define EVENT_HEAP_BIO_PROF_SAMPLE_BEGIN 166 #define EVENT_PROF_SAMPLE_COST_CENTRE 167 #define EVENT_PROF_BEGIN 168 +#define EVENT_IPE 169 #define EVENT_USER_BINARY_MSG 181 ===================================== includes/rts/Profiling.h ===================================== @@ -14,4 +14,5 @@ #pragma once void registerCcList(CostCentre **cc_list); +void registerInfoProvList(InfoProvEnt **cc_list); void registerCcsList(CostCentreStack **cc_list); ===================================== includes/rts/prof/CCS.h ===================================== @@ -73,6 +73,19 @@ typedef struct CostCentreStack_ { } CostCentreStack; +typedef struct InfoProv_{ + char * label; + char * module; + char * srcloc; +} InfoProv; + +typedef struct InfoProvEnt_ { + StgInfoTable * info; + InfoProv prov; + struct InfoProvEnt_ *link; +} InfoProvEnt; + + /* ----------------------------------------------------------------------------- * Start and stop the profiling timer. These can be called from * Haskell to restrict the profile to portion(s) of the execution. @@ -177,6 +190,7 @@ void enterFunCCS (StgRegTable *reg, CostCentreStack *); CostCentre *mkCostCentre (char *label, char *module, char *srcloc); extern CostCentre * RTS_VAR(CC_LIST); // registered CC list +extern InfoProvEnt * RTS_VAR(IPE_LIST); // registered IP list /* ----------------------------------------------------------------------------- * Declaring Cost Centres & Cost Centre Stacks. ===================================== rts/Profiling.c ===================================== @@ -57,6 +57,8 @@ CostCentre *CC_LIST = NULL; // parent of all cost centres stacks (done in initProfiling2()). static CostCentreStack *CCS_LIST = NULL; +InfoProvEnt *IPE_LIST = NULL; + #if defined(THREADED_RTS) static Mutex ccs_mutex; #endif @@ -145,6 +147,19 @@ dumpCostCentresToEventLog(void) #endif } +static void +dumpIPEToEventLog(void) +{ +#if defined(PROFILING) + InfoProvEnt *ip, *next; + for (ip = IPE_LIST; ip != NULL; ip = next) { + next = ip->link; + traceIPE(ip->info, ip->prov.label, + ip->prov.module, ip->prov.srcloc); + } +#endif +} + void initProfiling (void) { // initialise our arena @@ -202,6 +217,7 @@ void initProfiling (void) } dumpCostCentresToEventLog(); + dumpIPEToEventLog(); } @@ -338,6 +354,15 @@ static void registerCCS(CostCentreStack *ccs) } } +static void +registerInfoProvEnt(InfoProvEnt *ipe) +{ + //if (ipe->link == NULL) { + ipe->link = IPE_LIST; + IPE_LIST = ipe; + //} +} + void registerCcList(CostCentre **cc_list) { for (CostCentre **i = cc_list; *i != NULL; i++) { @@ -352,6 +377,13 @@ void registerCcsList(CostCentreStack **cc_list) } } +void registerInfoProvList(InfoProvEnt **ent_list) +{ + for (InfoProvEnt **i = ent_list; *i != NULL; i++) { + registerInfoProvEnt(*i); + } +} + /* ----------------------------------------------------------------------------- Set CCCS when entering a function. ===================================== rts/RtsSymbols.c ===================================== @@ -527,11 +527,13 @@ #define RTS_PROF_SYMBOLS \ SymI_HasProto(CCS_DONT_CARE) \ SymI_HasProto(CC_LIST) \ + SymI_HasProto(IPE_LIST) \ SymI_HasProto(stg_restore_cccs_info) \ SymI_HasProto(enterFunCCS) \ SymI_HasProto(pushCostCentre) \ SymI_HasProto(mkCostCentre) \ SymI_HasProto(registerCcList) \ + SymI_HasProto(registerInfoProvList) \ SymI_HasProto(registerCcsList) \ SymI_HasProto(era) #else ===================================== rts/Trace.c ===================================== @@ -643,6 +643,16 @@ void traceHeapProfCostCentre(StgWord32 ccID, } } +void traceIPE(StgInfoTable * info, + const char *label, + const char *module, + const char *srcloc ) +{ + if (eventlog_enabled) { + postIPE(info, label, module, srcloc); + } +} + // This one is for .hp samples void traceHeapProfSampleCostCentre(StgWord8 profile_id, CostCentreStack *stack, StgWord residency) ===================================== rts/Trace.h ===================================== @@ -302,6 +302,10 @@ void traceHeapProfCostCentre(StgWord32 ccID, const char *module, const char *srcloc, StgBool is_caf); +void traceIPE(StgInfoTable *info, + const char *label, + const char *module, + const char *srcloc ); void traceHeapProfSampleCostCentre(StgWord8 profile_id, CostCentreStack *stack, StgWord residency); @@ -354,6 +358,7 @@ void flushTrace(void); #define traceTaskDelete_(taskID) /* nothing */ #define traceHeapProfBegin(profile_id) /* nothing */ #define traceHeapProfCostCentre(ccID, label, module, srcloc, is_caf) /* nothing */ +#define traceIPE(info, label, module, srcloc) /* nothing */ #define traceHeapProfSampleBegin(era) /* nothing */ #define traceHeapBioProfSampleBegin(era, time) /* nothing */ #define traceHeapProfSampleEnd(era) /* nothing */ ===================================== rts/eventlog/EventLog.c ===================================== @@ -104,6 +104,7 @@ char *EventDesc[] = { [EVENT_HACK_BUG_T9003] = "Empty event for bug #9003", [EVENT_HEAP_PROF_BEGIN] = "Start of heap profile", [EVENT_HEAP_PROF_COST_CENTRE] = "Cost center definition", + [EVENT_IPE] = "ITE", [EVENT_HEAP_PROF_SAMPLE_BEGIN] = "Start of heap profile sample", [EVENT_HEAP_BIO_PROF_SAMPLE_BEGIN] = "Start of heap profile (biographical) sample", [EVENT_HEAP_PROF_SAMPLE_END] = "End of heap profile sample", @@ -433,6 +434,9 @@ init_event_types(void) case EVENT_HEAP_PROF_COST_CENTRE: eventTypes[t].size = EVENT_SIZE_DYNAMIC; break; + case EVENT_IPE: + eventTypes[t].size = EVENT_SIZE_DYNAMIC; + break; case EVENT_HEAP_PROF_SAMPLE_BEGIN: eventTypes[t].size = 8; @@ -1407,6 +1411,25 @@ void postHeapProfCostCentre(StgWord32 ccID, postWord8(&eventBuf, is_caf); RELEASE_LOCK(&eventBufMutex); } +void postIPE(StgWord64 info, + const char *label, + const char *module, + const char *srcloc) +{ + ACQUIRE_LOCK(&eventBufMutex); + StgWord label_len = strlen(label); + StgWord module_len = strlen(module); + StgWord srcloc_len = strlen(srcloc); + StgWord len = 8+label_len+module_len+srcloc_len+3; + ensureRoomForVariableEvent(&eventBuf, len); + postEventHeader(&eventBuf, EVENT_IPE); + postPayloadSize(&eventBuf, len); + postWord64(&eventBuf, info); + postString(&eventBuf, label); + postString(&eventBuf, module); + postString(&eventBuf, srcloc); + RELEASE_LOCK(&eventBufMutex); +} void postHeapProfSampleCostCentre(StgWord8 profile_id, CostCentreStack *stack, ===================================== rts/eventlog/EventLog.h ===================================== @@ -157,6 +157,10 @@ void postHeapProfCostCentre(StgWord32 ccID, const char *module, const char *srcloc, StgBool is_caf); +void postIPE(StgWord64 info, + const char *label, + const char *module, + const char *srcloc); void postHeapProfSampleCostCentre(StgWord8 profile_id, CostCentreStack *stack, View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/65c5a4d7e40c2d357f34127d55d1cc0bbb535e8c...5040ba85bec702e45116e1e57f1150ca2b09bd89 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/65c5a4d7e40c2d357f34127d55d1cc0bbb535e8c...5040ba85bec702e45116e1e57f1150ca2b09bd89 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 16 18:59:01 2020 From: gitlab at gitlab.haskell.org (Vilem-Benjamin Liepelt) Date: Sat, 16 May 2020 14:59:01 -0400 Subject: [Git][ghc/ghc][wip/buggymcbugfix/15185-enum-int] 172 commits: Change zipWith to zipWithEqual in a few places Message-ID: <5ec037f56b133_7647114d489012091b@gitlab.haskell.org.mail> Vilem-Benjamin Liepelt pushed to branch wip/buggymcbugfix/15185-enum-int at Glasgow Haskell Compiler / GHC Commits: 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.0.0 This requires bumping the `exceptions` and `text` submodules to bring in commits that bump their respective upper version bounds on `template-haskell`. Fixes #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - ffd7eef2 by Takenobu Tani at 2020-04-22T23:09:50-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - e8a5d81b by Jonathan DK Gibbons at 2020-04-22T23:10:28-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - dcb7fe5a by John Ericson at 2020-04-22T23:10:28-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - cde23cd4 by John Ericson at 2020-04-22T23:10:28-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - 72cb6bcc by John Ericson at 2020-04-22T23:10:28-04:00 Generalize type of `matchCanFail` - - - - - 401f7bb3 by John Ericson at 2020-04-22T23:10:28-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 6c9fae23 by Alexis King at 2020-04-22T23:11:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 48b8951e by Roland Senn at 2020-04-22T23:11:51-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 34a45ee6 by Peter Trommler at 2020-04-22T23:12:27-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - ffde2348 by Simon Peyton Jones at 2020-04-22T23:13:06-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 6f84aca3 by Ben Gamari at 2020-04-22T23:13:43-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - c29f0fa6 by Andreas Klebinger at 2020-04-22T23:14:21-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 4b4a8b60 by Ben Gamari at 2020-04-22T23:14:57-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 831b6642 by Moritz Angermann at 2020-04-22T23:15:33-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - c409961a by Ryan Scott at 2020-04-22T23:16:12-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 125aa2b8 by Ömer Sinan Ağacan at 2020-04-22T23:16:51-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - 8ea37b01 by Sylvain Henry at 2020-04-22T23:17:34-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - cd8409c2 by Ryan Scott at 2020-04-23T11:39:24-04:00 Create di_scoped_tvs for associated data family instances properly See `Note [Associated data family instances and di_scoped_tvs]` in `GHC.Tc.TyCl.Instance`, which explains all of the moving parts. Fixes #18055. - - - - - 339e8ece by Ben Gamari at 2020-04-23T11:40:02-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 5946c85a by Ben Gamari at 2020-04-23T11:40:38-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - c42754d5 by John Ericson at 2020-04-23T18:32:43-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 72da0c29 by mniip at 2020-04-23T18:33:21-04:00 Add :doc to GHC.Prim - - - - - 2c23e2e3 by mniip at 2020-04-23T18:33:21-04:00 Include docs for non-primop entries in primops.txt as well - - - - - 0ac29c88 by mniip at 2020-04-23T18:33:21-04:00 GHC.Prim docs: note and test - - - - - b0fbfc75 by John Ericson at 2020-04-24T12:07:14-04:00 Switch order on `GhcMake.IsBoot` In !1798 we were requested to replace many `Bool`s with this data type. But those bools had `False` meaning `NotBoot`, so the `Ord` instance would be flipped if we use this data-type as-is. Since the planned formally-`Bool` occurrences vastly outnumber the current occurrences, we figured it would be better to conform the `Ord` instance to how the `Bool` is used now, fixing any issues, rather than fix them currently with the bigger refactor later in !1798. That way, !1798 can be a "pure" refactor with no behavioral changes. - - - - - af332442 by Sylvain Henry at 2020-04-26T13:55:14-04:00 Modules: Utils and Data (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - cd4434c8 by Sylvain Henry at 2020-04-26T13:55:16-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 22bf5c73 by Ömer Sinan Ağacan at 2020-04-26T13:55:22-04:00 Tweak includes in non-moving GC headers We don't use hash tables in non-moving GC so remove the includes. This breaks Compact.c as existing includes no longer include Hash.h, so include Hash.h explicitly in Compact.c. - - - - - 99823ed2 by Sylvain Henry at 2020-04-27T20:24:46-04:00 TH: fix Show/Eq/Ord instances for Bytes (#16457) We shouldn't compare pointer values but the actual bytes. - - - - - c62271a2 by Alp Mestanogullari at 2020-04-27T20:25:33-04:00 hadrian: always capture both stdout and stderr when running a builder fails The idea being that when a builder('s command) fails, we quite likely want to have all the information available to figure out why. Depending on the builder _and_ the particular problem, the useful bits of information can be printed on stdout or stderr. We accomplish this by defining a simple wrapper for Shake's `cmd` function, that just _always_ captures both streams in case the command returns a non-zero exit code, and by using this wrapper everywhere in `hadrian/src/Builder.hs`. Fixes #18089. - - - - - 4b9764db by Ryan Scott at 2020-04-28T15:40:04-04:00 Define a Quote IO instance Fixes #18103. - - - - - 518a63d4 by Ryan Scott at 2020-04-28T15:40:42-04:00 Make boxed 1-tuples have known keys Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. - - - - - 2cfc4ab9 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Document backpack fields in DynFlags - - - - - 10a2ba90 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 69562e34 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 9e2c8e0e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - ea717aa4 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 10d15f1e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 8bfb0219 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - 71484b09 by Alexis King at 2020-04-30T01:57:35-04:00 Allow block arguments in arrow control operators Arrow control operators have their own entries in the grammar, so they did not cooperate with BlockArguments. This was just a minor oversight, so this patch adjusts the grammar to add the desired behavior. fixes #18050 - - - - - a48cd2a0 by Alexis King at 2020-04-30T01:57:35-04:00 Allow LambdaCase to be used as a command in proc notation - - - - - f4d3773c by Alexis King at 2020-04-30T01:57:35-04:00 Document BlockArguments/LambdaCase support in arrow notation - - - - - 5bdfdd13 by Simon Peyton Jones at 2020-04-30T01:58:15-04:00 Add tests for #17873 - - - - - 19b701c2 by Simon Peyton Jones at 2020-04-30T07:30:13-04:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - 014ef4a3 by Matthew Pickering at 2020-04-30T07:30:50-04:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 2aa67611 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - 54dad3cf by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - 99ff8145 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 05b0a9fd by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 Remove OneShotInfo field of LFReEntrant, document OneShotInfo The field is only used in withNewTickyCounterFun and it's easier to directly pass a parameter for one-shot info to withNewTickyCounterFun instead of passing it via LFReEntrant. This also makes !2842 simpler. Other changes: - New Note (by SPJ) [OneShotInfo overview] added. - Arity argument of thunkCode removed as it's always 0. - - - - - a43620c6 by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 GHC.StgToCmm.Ticky: remove a few unused stuff - - - - - 780de9e1 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Use platform in Iface Binary - - - - - f8386c7b by Sylvain Henry at 2020-05-01T10:37:39-04:00 Refactor PprDebug handling If `-dppr-debug` is set, then PprUser and PprDump styles are silently replaced with PprDebug style. This was done in `mkUserStyle` and `mkDumpStyle` smart constructors. As a consequence they needed a DynFlags parameter. Now we keep the original PprUser and PprDump styles until they are used to create an `SDocContext`. I.e. the substitution is only performed in `initSDocContext`. - - - - - b3df9e78 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Remove PprStyle param of logging actions Use `withPprStyle` instead to apply a specific style to a SDoc. - - - - - de9fc995 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Fully remove PprDebug PprDebug was a pain to deal with consistently as it is implied by `-dppr-debug` but it isn't really a PprStyle. We remove it completely and query the appropriate SDoc flag instead (`sdocPprDebug`) via helpers (`getPprDebug` and its friends). - - - - - 8b51fcbd by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Only call checkSingle if we would report warnings - - - - - fd7ea0fe by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 7bfe9ac5 by Ben Gamari at 2020-05-03T04:41:33-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. - - - - - c560dd07 by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Move eventlog documentation users guide - - - - - 02543d5e by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Add documentation for non-moving GC events - - - - - b465dd45 by Alexis King at 2020-05-03T04:42:12-04:00 Flatten nested casts in the simple optimizer Normally, we aren’t supposed to generated any nested casts, since mkCast takes care to flatten them, but the simple optimizer didn’t use mkCast, so they could show up after inlining. This isn’t really a problem, since the simplifier will clean them up immediately anyway, but it can clutter the -ddump-ds output, and it’s an extremely easy fix. closes #18112 - - - - - 8bdc03d6 by Simon Peyton Jones at 2020-05-04T01:56:59-04:00 Don't return a panic in tcNestedSplice In GHC.Tc.Gen.Splice.tcNestedSplice we were returning a typechecked expression of "panic". That is usually OK, because the result is discarded. But it happens that tcApp now looks at the typechecked expression, trivially, to ask if it is tagToEnum. So being bottom is bad. Moreover a debug-trace might print it out. So better to return a civilised expression, even though it is usually discarded. - - - - - 0bf640b1 by Baldur Blöndal at 2020-05-04T01:57:36-04:00 Don't require parentheses around via type (`-XDerivingVia'). Fixes #18130". - - - - - 30272412 by Artem Pelenitsyn at 2020-05-04T13:19:59-04:00 Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) - - - - - b9f7c08f by jneira at 2020-05-04T13:20:37-04:00 Remove unused hs-boot file - - - - - 1d8f80cd by Sylvain Henry at 2020-05-05T03:22:46-04:00 Remove references to -package-key * remove references to `-package-key` which has been removed in 2016 (240ddd7c39536776e955e881d709bbb039b48513) * remove support for `-this-package-key` which has been deprecated at the same time - - - - - 7bc3a65b by Sylvain Henry at 2020-05-05T03:23:31-04:00 Remove SpecConstrAnnotation (#13681) This has been deprecated since 2013. Use GHC.Types.SPEC instead. Make GHC.Exts "not-home" for haddock Metric Decrease: haddock.base - - - - - 3c862f63 by DenisFrezzato at 2020-05-05T03:24:15-04:00 Fix Haskell98 short description in documentation - - - - - 2420c555 by Ryan Scott at 2020-05-05T03:24:53-04:00 Add regression tests for #16244, #16245, #16758 Commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70 ended up fixing quite a few bugs: * This commit fixes #16244 completely. A regression test has been added. * This commit fixes one program from #16245. (The program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211369 still panics, and the program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211400 still loops infinitely.) A regression test has been added for this program. * This commit fixes #16758. Accordingly, this patch removes the `expect_broken` label from the `T16758` test case, moves it from `should_compile` to `should_fail` (as it should produce an error message), and checks in the expected stderr. - - - - - 40c71c2c by Sylvain Henry at 2020-05-05T03:25:31-04:00 Fix colorized error messages (#18128) In b3df9e780fb2f5658412c644849cd0f1e6f50331 I broke colorized messages by using "dump" style instead of "user" style. This commits fixes it. - - - - - 7ab6ab09 by Richard Eisenberg at 2020-05-06T04:39:32-04:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG ------------------------- - - - - - 420b957d by Ben Gamari at 2020-05-06T04:40:08-04:00 rts: Zero block flags with -DZ Block flags are very useful for determining the state of a block. However, some block allocator users don't touch them, leading to misleading values. Ensure that we zero then when zero-on-gc is set. This is safe and makes the flags more useful during debugging. - - - - - 740b3b8d by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix incorrect failed_to_evac value during deadlock gc Previously we would incorrectly set the failed_to_evac flag if we evacuated a value due to a deadlock GC. This would cause us to mark more things as dirty than strictly necessary. It also turned up a nasty but which I will fix next. - - - - - b2d72c75 by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - 9f3e6884 by Zubin Duggal at 2020-05-06T04:41:08-04:00 Allow atomic update of NameCache in readHieFile The situation arises in ghcide where multiple different threads may need to update the name cache, therefore with the older interface it could happen that you start reading a hie file with name cache A and produce name cache A + B, but another thread in the meantime updated the namecache to A + C. Therefore if you write the new namecache you will lose the A' updates from the second thread. Updates haddock submodule - - - - - edec6a6c by Ryan Scott at 2020-05-06T04:41:57-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _)`. Fixes #18127. - - - - - a95e7fe0 by Ömer Sinan Ağacan at 2020-05-06T04:42:39-04:00 ELF linker: increment curSymbol after filling in fields of current entry The bug was introduced in a8b7cef4d45 which added a field to the `symbols` array elements and then updated this code incorrectly: - oc->symbols[curSymbol++] = nm; + oc->symbols[curSymbol++].name = nm; + oc->symbols[curSymbol].addr = symbol->addr; - - - - - cab1871a by Sylvain Henry at 2020-05-06T04:43:21-04:00 Move LeadingUnderscore into Platform (#17957) Avoid direct use of DynFlags to know if symbols must be prefixed by an underscore. - - - - - 94e7c563 by Sylvain Henry at 2020-05-06T04:43:21-04:00 Don't use DynFlags in showLinkerState (#17957) - - - - - 9afd9251 by Ryan Scott at 2020-05-06T04:43:58-04:00 Refactoring: Use bindSigTyVarsFV in rnMethodBinds `rnMethodBinds` was explicitly using `xoptM` to determine if `ScopedTypeVariables` is enabled before bringing type variables bound by the class/instance header into scope. However, this `xoptM` logic is already performed by the `bindSigTyVarsFV` function. This patch uses `bindSigTyVarsFV` in `rnMethodBinds` to reduce the number of places where we need to consult if `ScopedTypeVariables` is on. This is purely refactoring, and there should be no user-visible change in behavior. - - - - - 6f6d72b2 by Brian Foley at 2020-05-08T15:29:25-04:00 Remove further dead code found by a simple Python script. Avoid removing some functions that are part of an API even though they're not used in-tree at the moment. - - - - - 78bf8bf9 by Julien Debon at 2020-05-08T15:29:28-04:00 Add doc examples for Bifoldable See #17929 - - - - - 66f0a847 by Julien Debon at 2020-05-08T15:29:29-04:00 doc (Bitraversable): Add examples to Bitraversable * Add examples to Data.Bitraversable * Fix formatting for (,) in Bitraversable and Bifoldable * Fix mistake on bimapAccumR documentation See #17929 - - - - - 9749fe12 by Baldur Blöndal at 2020-05-08T15:29:32-04:00 Specify kind variables for inferred kinds in base. - - - - - 4e9aef9e by John Ericson at 2020-05-08T15:29:36-04:00 HsSigWcTypeScoping: Pull in documentation from stray location - - - - - f4d5c6df by John Ericson at 2020-05-08T15:29:36-04:00 Rename local `real_fvs` to `implicit_vs` It doesn't make sense to call the "free" variables we are about to implicitly bind the real ones. - - - - - 20570b4b by John Ericson at 2020-05-08T15:29:36-04:00 A few tiny style nits with renaming - Use case rather than guards that repeatedly scrutenize same thing. - No need for view pattern when `L` is fine. - Use type synnonym to convey the intent like elsewhere. - - - - - 09ac8de5 by John Ericson at 2020-05-08T15:29:36-04:00 Add `forAllOrNothing` function with note - - - - - bb35c0e5 by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Document lawlessness of Ap's Num instance - - - - - cdd229ff by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply suggestion to libraries/base/Data/Monoid.hs - - - - - 926d2aab by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply more suggestions from Simon Jakobi - - - - - 7a763cff by Adam Gundry at 2020-05-08T15:29:41-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. - - - - - 88e3c815 by Simon Peyton Jones at 2020-05-08T15:29:41-04:00 Fix specialisation for DFuns When specialising a DFun we must take care to saturate the unfolding. See Note [Specialising DFuns] in Specialise. Fixes #18120 - - - - - 86c77b36 by Greg Steuck at 2020-05-08T15:29:45-04:00 Remove unused SEGMENT_PROT_RWX It's been unused for a year and is problematic on any OS which requires W^X for security. - - - - - 9d97f4b5 by nineonine at 2020-05-08T15:30:03-04:00 Add test for #16167 - - - - - aa318338 by Ryan Scott at 2020-05-08T15:30:04-04:00 Bump exceptions submodule so that dist-boot is .gitignore'd `exceptions` is a stage-0 boot library as of commit 30272412fa437ab8e7a8035db94a278e10513413, which means that building `exceptions` in a GHC tree will generate a `dist-boot` directory. However, this directory was not specified in `exceptions`' `.gitignore` file, which causes it to dirty up the current `git` working directory. Accordingly, this bumps the `exceptions` submodule to commit ghc/packages/exceptions at 23c0b8a50d7592af37ca09beeec16b93080df98f, which adds `dist-boot` to the `.gitignore` file. - - - - - ea86360f by Ömer Sinan Ağacan at 2020-05-08T15:30:30-04:00 Linker.c: initialize n_symbols of ObjectCode with other fields - - - - - 951c1fb0 by Sylvain Henry at 2020-05-09T21:46:38-04:00 Fix unboxed-sums GC ptr-slot rubbish value (#17791) This patch allows boot libraries to use unboxed sums without implicitly depending on `base` package because of `absentSumFieldError`. See updated Note [aBSENT_SUM_FIELD_ERROR_ID] in GHC.Core.Make - - - - - b352d63c by Ben Gamari at 2020-05-09T21:47:14-04:00 rts: Make non-existent linker search path merely a warning As noted in #18105, previously this resulted in a rather intrusive error message. This is in contrast to the general expectation that search paths are merely places to look, not places that must exist. Fixes #18105. - - - - - cf4f1e2f by Ben Gamari at 2020-05-13T02:02:33-04:00 rts/CNF: Fix fixup comparison function Previously we would implicitly convert the difference between two words to an int, resulting in an integer overflow on 64-bit machines. Fixes #16992 - - - - - a03da9bf by Ömer Sinan Ağacan at 2020-05-13T02:03:16-04:00 Pack some of IdInfo fields into a bit field This reduces residency of compiler quite a bit on some programs. Example stats when building T10370: Before: 2,871,242,832 bytes allocated in the heap 4,693,328,008 bytes copied during GC 33,941,448 bytes maximum residency (276 sample(s)) 375,976 bytes maximum slop 83 MiB total memory in use (0 MB lost due to fragmentation) After: 2,858,897,344 bytes allocated in the heap 4,629,255,440 bytes copied during GC 32,616,624 bytes maximum residency (278 sample(s)) 314,400 bytes maximum slop 80 MiB total memory in use (0 MB lost due to fragmentation) So -3.9% residency, -1.3% bytes copied and -0.4% allocations. Fixes #17497 Metric Decrease: T9233 T9675 - - - - - 670c3e5c by Ben Gamari at 2020-05-13T02:03:54-04:00 get-win32-tarballs: Fix base URL Revert a change previously made for testing purposes. - - - - - 8ad8dc41 by Ben Gamari at 2020-05-13T02:03:54-04:00 get-win32-tarballs: Improve diagnostics output - - - - - 8c0740b7 by Simon Jakobi at 2020-05-13T02:04:33-04:00 docs: Add examples for Data.Semigroup.Arg{Min,Max} Context: #17153 - - - - - cb22348f by Ben Gamari at 2020-05-13T02:05:11-04:00 Add few cleanups of the CAF logic Give the NameSet of non-CAFfy names a proper newtype to distinguish it from all of the other NameSets floating about. - - - - - 90e38b81 by Emeka Nkurumeh at 2020-05-13T02:05:51-04:00 fix printf warning when using with ghc with clang on mingw - - - - - 86d8ac22 by Sebastian Graf at 2020-05-13T02:06:29-04:00 CprAnal: Don't attach CPR sigs to expandable bindings (#18154) Instead, look through expandable unfoldings in `cprTransform`. See the new Note [CPR for expandable unfoldings]: ``` Long static data structures (whether top-level or not) like xs = x1 : xs1 xs1 = x2 : xs2 xs2 = x3 : xs3 should not get CPR signatures, because they * Never get WW'd, so their CPR signature should be irrelevant after analysis (in fact the signature might even be harmful for that reason) * Would need to be inlined/expanded to see their constructed product * Recording CPR on them blows up interface file sizes and is redundant with their unfolding. In case of Nested CPR, this blow-up can be quadratic! But we can't just stop giving DataCon application bindings the CPR property, for example fac 0 = 1 fac n = n * fac (n-1) fac certainly has the CPR property and should be WW'd! But FloatOut will transform the first clause to lvl = 1 fac 0 = lvl If lvl doesn't have the CPR property, fac won't either. But lvl doesn't have a CPR signature to extrapolate into a CPR transformer ('cprTransform'). So instead we keep on cprAnal'ing through *expandable* unfoldings for these arity 0 bindings via 'cprExpandUnfolding_maybe'. In practice, GHC generates a lot of (nested) TyCon and KindRep bindings, one for each data declaration. It's wasteful to attach CPR signatures to each of them (and intractable in case of Nested CPR). ``` Fixes #18154. - - - - - e34bf656 by Ben Gamari at 2020-05-13T02:07:08-04:00 users-guide: Add discussion of shared object naming Fixes #18074. - - - - - 5d0f2445 by Ben Gamari at 2020-05-13T02:07:47-04:00 testsuite: Print sign of performance changes Executes the minor formatting change in the tabulated performance changes suggested in #18135. - - - - - 9e4b981f by Ben Gamari at 2020-05-13T02:08:24-04:00 testsuite: Add testcase for #18129 - - - - - 266310c3 by Ivan-Yudin at 2020-05-13T02:09:03-04:00 doc: Reformulate the opening paragraph of Ch. 4 in User's guide Removes mentioning of Hugs (it is not helpful for new users anymore). Changes the wording for the rest of the paragraph. Fixes #18132. - - - - - 55e35c0b by Baldur Blöndal at 2020-05-13T20:02:48-04:00 Predicate, Equivalence derive via `.. -> a -> All' - - - - - d7e0b57f by Alp Mestanogullari at 2020-05-13T20:03:30-04:00 hadrian: add a --freeze2 option to freeze stage 1 and 2 - - - - - d880d6b2 by Artem Pelenitsyn at 2020-05-13T20:04:11-04:00 Don't reload environment files on every setSessionDynFlags Makes `interpretPackageEnv` (which loads envirinment files) a part of `parseDynamicFlags` (parsing command-line arguments, which is typically done once) instead of `setSessionDynFlags` (which is typically called several times). Making several (transitive) calls to `interpretPackageEnv`, as before, caused #18125 #16318, which should be fixed now. - - - - - 102cfd67 by Ryan Scott at 2020-05-13T20:04:46-04:00 Factor out HsPatSigType for pat sigs/RULE term sigs (#16762) This implements chunks (2) and (3) of https://gitlab.haskell.org/ghc/ghc/issues/16762#note_270170. Namely, it introduces a dedicated `HsPatSigType` AST type, which represents the types that can appear in pattern signatures and term-level `RULE` binders. Previously, these were represented with `LHsSigWcType`. Although `LHsSigWcType` is isomorphic to `HsPatSigType`, the intended semantics of the two types are slightly different, as evidenced by the fact that they have different code paths in the renamer and typechecker. See also the new `Note [Pattern signature binders and scoping]` in `GHC.Hs.Types`. - - - - - b17574f7 by Hécate at 2020-05-13T20:05:28-04:00 fix(documentation): Fix the RST links to GHC.Prim - - - - - df021fb1 by Baldur Blöndal at 2020-05-13T20:06:06-04:00 Document (->) using inferred quantification for its runtime representations. Fixes #18142. - - - - - 1a93ea57 by Takenobu Tani at 2020-05-13T20:06:54-04:00 Tweak man page for ghc command This commit updates the ghc command's man page as followings: * Enable `man_show_urls` to show URL addresses in the `DESCRIPTION` section of ghc.rst, because sphinx currently removes hyperlinks for man pages. * Add a `SEE ALSO` section to point to the GHC homepage - - - - - a951e1ba by Takenobu Tani at 2020-05-13T20:07:37-04:00 GHCi: Add link to the user's guide in help message This commit adds a link to the user's guide in ghci's `:help` message. Newcomers could easily reach to details of ghci. - - - - - 404581ea by Jeff Happily at 2020-05-13T20:08:15-04:00 Handle single unused import - - - - - 1c999e5d by Ben Gamari at 2020-05-13T20:09:07-04:00 Ensure that printMinimalImports closes handle Fixes #18166. - - - - - c9f5a8f4 by Ben Gamari at 2020-05-13T20:09:51-04:00 hadrian: Tell testsuite driver about LLVM availability This reflects the logic present in the Make build system into Hadrian. Fixes #18167. - - - - - c05c0659 by Simon Jakobi at 2020-05-14T03:31:21-04:00 Improve some folds over Uniq[D]FM * Replace some non-deterministic lazy folds with strict folds. * Replace some O(n log n) folds in deterministic order with O(n) non-deterministic folds. * Replace some folds with set-operations on the underlying IntMaps. This reduces max residency when compiling `nofib/spectral/simple/Main.hs` with -O0 by about 1%. Maximum residency when compiling Cabal also seems reduced on the order of 3-9%. - - - - - 477f13bb by Simon Jakobi at 2020-05-14T03:31:58-04:00 Use Data.IntMap.disjoint Data.IntMap gained a dedicated `disjoint` function in containers-0.6.2.1. This patch applies this function where appropriate in hopes of modest compiler performance improvements. Closes #16806. - - - - - e9c0110c by Ben Gamari at 2020-05-14T12:25:53-04:00 IdInfo: Add reference to bitfield-packing ticket - - - - - 9bd20e83 by Sebastian Graf at 2020-05-15T10:42:09-04:00 DmdAnal: Improve handling of precise exceptions This patch does two things: Fix possible unsoundness in what was called the "IO hack" and implement part 2.1 of the "fixing precise exceptions" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions, which, in combination with !2956, supersedes !3014 and !2525. **IO hack** The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is called `exprMayThrowPreciseException` now. I came up with two testcases exemplifying possible unsoundness (if twisted enough) in the old approach: - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. - `T13380e`: Demonstrating unsoundness of the "IO hack" when we have Nested CPR. Not currently relevant, as we don't have Nested CPR yet. - `T13380f`: Demonstrating unsoundness of the "IO hack" for safe FFI calls. Basically, the IO hack assumed that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future, see `T13380e`. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380{d,e}` (and will hopefully be robust to Nested CPR). **Precise exceptions** In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that was terribly unprincipled. That unprincipledness resulted in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception (and the existing IO hack doesn't detect that) Fixing both issues in !3014 turned out to be too complicated and had the potential to regress in the future. Hence we decided to only fix `T13380b` and augment the `Divergence` lattice with a new middle-layer element, `ExnOrDiv`, which means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. See the wiki page on Step 2.1 for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#dead-code-elimination-for-raiseio-with-isdeadenddiv-introducing-exnordiv-step-21 - - - - - 568d7279 by Ben Gamari at 2020-05-15T10:42:46-04:00 GHC.Cmm.Opt: Handle MO_XX_Conv This MachOp was introduced by 2c959a1894311e59cd2fd469c1967491c1e488f3 but a wildcard match in cmmMachOpFoldM hid the fact that it wasn't handled. Ideally we would eliminate the match but this appears to be a larger task. Fixes #18141. - - - - - 5ce0f7ae by buggymcbugfix at 2020-05-16T21:57:44+03:00 Fix spelling mistakes and typos - - - - - 1096ff71 by buggymcbugfix at 2020-05-16T21:57:45+03:00 Add INLINABLE pragmas to Enum list producers The INLINABLE pragmas ensure that we export stable (unoptimised) unfoldings in the interface file so we can do list fusion at usage sites. Related tickets: #15185, #8763, #18178. - - - - - ad6d3995 by buggymcbugfix at 2020-05-16T21:57:45+03:00 Piggyback on Enum Word methods for Word64 If we are on a 64 bit platform, we can use the efficient Enum Word methods for the Enum Word64 instance. - - - - - ea3742d1 by buggymcbugfix at 2020-05-16T21:57:45+03:00 Document INLINE(ABLE) pragmas that enable fusion - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - compiler/prelude/PrelNames.hs-boot → compiler/GHC/Builtin/Names.hs-boot - compiler/prelude/THNames.hs → compiler/GHC/Builtin/Names/TH.hs - compiler/prelude/PrimOp.hs → compiler/GHC/Builtin/PrimOps.hs - + compiler/GHC/Builtin/PrimOps.hs-boot - compiler/prelude/TysWiredIn.hs → compiler/GHC/Builtin/Types.hs - compiler/prelude/TysWiredIn.hs-boot → compiler/GHC/Builtin/Types.hs-boot - compiler/typecheck/TcTypeNats.hs → compiler/GHC/Builtin/Types/Literals.hs - compiler/prelude/TysPrim.hs → compiler/GHC/Builtin/Types/Prim.hs - compiler/prelude/KnownUniques.hs → compiler/GHC/Builtin/Uniques.hs - compiler/prelude/KnownUniques.hs-boot → compiler/GHC/Builtin/Uniques.hs-boot - compiler/prelude/PrelInfo.hs → compiler/GHC/Builtin/Utils.hs - compiler/prelude/primops.txt.pp → compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.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/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Block.hs - compiler/GHC/Cmm/Dataflow/Collections.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/331970da5b13140892fc7e1b4f1c1fd1f94225ef...ea3742d16aaea4d080c6296fd29613c1fa3eba82 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/331970da5b13140892fc7e1b4f1c1fd1f94225ef...ea3742d16aaea4d080c6296fd29613c1fa3eba82 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 16 19:07:44 2020 From: gitlab at gitlab.haskell.org (Vilem-Benjamin Liepelt) Date: Sat, 16 May 2020 15:07:44 -0400 Subject: [Git][ghc/ghc][wip/buggymcbugfix/15185-enum-int] fixup! Add INLINABLE pragmas to Enum list producers Message-ID: <5ec03a00f363f_76473f9f6347004412377a@gitlab.haskell.org.mail> Vilem-Benjamin Liepelt pushed to branch wip/buggymcbugfix/15185-enum-int at Glasgow Haskell Compiler / GHC Commits: c37e4f47 by buggymcbugfix at 2020-05-16T22:05:56+03:00 fixup! Add INLINABLE pragmas to Enum list producers - - - - - 1 changed file: - testsuite/tests/perf/should_run/T15185.hs Changes: ===================================== testsuite/tests/perf/should_run/T15185.hs ===================================== @@ -18,7 +18,7 @@ main = do _ <- evaluate (fact @Int16 50) _ <- evaluate (fact @Int8 50) _ <- evaluate (fact @Word 50) - _ <- evaluate (fact @Word64 50) -- doesn't fuse yet + _ <- evaluate (fact @Word64 50) _ <- evaluate (fact @Word32 50) _ <- evaluate (fact @Word16 50) _ <- evaluate (fact @Word8 50) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c37e4f47fed84ae594e70e13ce4b8f37401c8937 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c37e4f47fed84ae594e70e13ce4b8f37401c8937 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 16 19:11:46 2020 From: gitlab at gitlab.haskell.org (Vilem-Benjamin Liepelt) Date: Sat, 16 May 2020 15:11:46 -0400 Subject: [Git][ghc/ghc][wip/buggymcbugfix/15185-enum-int] fixup! Piggyback on Enum Word methods for Word64 Message-ID: <5ec03af293c16_764760653141250c6@gitlab.haskell.org.mail> Vilem-Benjamin Liepelt pushed to branch wip/buggymcbugfix/15185-enum-int at Glasgow Haskell Compiler / GHC Commits: 055c2a92 by buggymcbugfix at 2020-05-16T22:09:58+03:00 fixup! Piggyback on Enum Word methods for Word64 - - - - - 1 changed file: - libraries/base/GHC/Word.hs Changes: ===================================== libraries/base/GHC/Word.hs ===================================== @@ -894,33 +894,30 @@ instance Enum Word64 where | otherwise = fromEnumError "Word64" x #if WORD_SIZE_IN_BITS < 64 - {-# INLINABLE enumFrom #-} - enumFrom = integralEnumFrom - - {-# INLINABLE enumFromThen #-} - enumFromThen = integralEnumFromThen - - {-# INLINABLE enumFromTo #-} - enumFromTo = integralEnumFromTo - - {-# INLINABLE enumFromThenTo #-} + enumFrom = integralEnumFrom + enumFromThen = integralEnumFromThen + enumFromTo = integralEnumFromTo enumFromThenTo = integralEnumFromThenTo #else + -- See Note [Stable Unfolding for list producers] in GHC.Enum {-# INLINABLE enumFrom #-} enumFrom w = map wordToWord64 $ enumFrom (word64ToWord w) + -- See Note [Stable Unfolding for list producers] in GHC.Enum {-# INLINABLE enumFromThen #-} enumFromThen w s = map wordToWord64 $ enumFromThen (word64ToWord w) (word64ToWord s) + -- See Note [Stable Unfolding for list producers] in GHC.Enum {-# INLINABLE enumFromTo #-} enumFromTo w1 w2 = map wordToWord64 $ enumFromTo (word64ToWord w1) (word64ToWord w2) + -- See Note [Stable Unfolding for list producers] in GHC.Enum {-# INLINABLE enumFromThenTo #-} enumFromThenTo w1 s w2 = map wordToWord64 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/055c2a92d1215f6b076818254c6834a84bb51d0c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/055c2a92d1215f6b076818254c6834a84bb51d0c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sat May 16 19:12:12 2020 From: gitlab at gitlab.haskell.org (Vilem-Benjamin Liepelt) Date: Sat, 16 May 2020 15:12:12 -0400 Subject: [Git][ghc/ghc][wip/buggymcbugfix/15185-enum-int] 3 commits: Add INLINABLE pragmas to Enum list producers Message-ID: <5ec03b0cd0629_764710f4b734125444@gitlab.haskell.org.mail> Vilem-Benjamin Liepelt pushed to branch wip/buggymcbugfix/15185-enum-int at Glasgow Haskell Compiler / GHC Commits: 5e49c27d by buggymcbugfix at 2020-05-16T22:10:54+03:00 Add INLINABLE pragmas to Enum list producers The INLINABLE pragmas ensure that we export stable (unoptimised) unfoldings in the interface file so we can do list fusion at usage sites. Related tickets: #15185, #8763, #18178. - - - - - accf2ca0 by buggymcbugfix at 2020-05-16T22:10:54+03:00 Piggyback on Enum Word methods for Word64 If we are on a 64 bit platform, we can use the efficient Enum Word methods for the Enum Word64 instance. - - - - - 7dc55606 by buggymcbugfix at 2020-05-16T22:10:54+03:00 Document INLINE(ABLE) pragmas that enable fusion - - - - - 3 changed files: - libraries/base/GHC/Enum.hs - libraries/base/GHC/Word.hs - + testsuite/tests/perf/should_run/T15185.hs Changes: ===================================== libraries/base/GHC/Enum.hs ===================================== @@ -139,17 +139,34 @@ class Enum a where -- * @enumFromThenTo 6 8 2 :: [Int] = []@ enumFromThenTo :: a -> a -> a -> [a] - succ = toEnum . (+ 1) . fromEnum - pred = toEnum . (subtract 1) . fromEnum - enumFrom x = map toEnum [fromEnum x ..] - enumFromThen x y = map toEnum [fromEnum x, fromEnum y ..] - enumFromTo x y = map toEnum [fromEnum x .. fromEnum y] + succ = toEnum . (+ 1) . fromEnum + + pred = toEnum . (subtract 1) . fromEnum + + -- See Note [Stable Unfolding for list producers] + {-# INLINABLE enumFrom #-} + enumFrom x = map toEnum [fromEnum x ..] + + -- See Note [Stable Unfolding for list producers] + {-# INLINABLE enumFromThen #-} + enumFromThen x y = map toEnum [fromEnum x, fromEnum y ..] + + -- See Note [Stable Unfolding for list producers] + {-# INLINABLE enumFromTo #-} + enumFromTo x y = map toEnum [fromEnum x .. fromEnum y] + + -- See Note [Stable Unfolding for list producers] + {-# INLINABLE enumFromThenTo #-} enumFromThenTo x1 x2 y = map toEnum [fromEnum x1, fromEnum x2 .. fromEnum y] +-- See Note [Stable Unfolding for list producers] +{-# INLINABLE boundedEnumFrom #-} -- Default methods for bounded enumerations boundedEnumFrom :: (Enum a, Bounded a) => a -> [a] boundedEnumFrom n = map toEnum [fromEnum n .. fromEnum (maxBound `asTypeOf` n)] +-- See Note [Stable Unfolding for list producers] +{-# INLINABLE boundedEnumFromThen #-} boundedEnumFromThen :: (Enum a, Bounded a) => a -> a -> [a] boundedEnumFromThen n1 n2 | i_n2 >= i_n1 = map toEnum [i_n1, i_n2 .. fromEnum (maxBound `asTypeOf` n1)] @@ -158,6 +175,14 @@ boundedEnumFromThen n1 n2 i_n1 = fromEnum n1 i_n2 = fromEnum n2 +{- +Note [Stable Unfolding for list producers] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The INLINABLE/INLINE pragmas ensure that we export stable (unoptimised) +unfoldings in the interface file so we can do list fusion at usage sites. +-} + ------------------------------------------------------------------------ -- Helper functions ------------------------------------------------------------------------ @@ -343,16 +368,20 @@ instance Enum Char where toEnum = chr fromEnum = ord + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFrom #-} enumFrom (C# x) = eftChar (ord# x) 0x10FFFF# -- Blarg: technically I guess enumFrom isn't strict! + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromTo #-} enumFromTo (C# x) (C# y) = eftChar (ord# x) (ord# y) + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromThen #-} enumFromThen (C# x1) (C# x2) = efdChar (ord# x1) (ord# x2) + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromThenTo #-} enumFromThenTo (C# x1) (C# x2) (C# y) = efdtChar (ord# x1) (ord# x2) (ord# y) @@ -472,17 +501,21 @@ instance Enum Int where toEnum x = x fromEnum x = x + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFrom #-} enumFrom (I# x) = eftInt x maxInt# where !(I# maxInt#) = maxInt -- Blarg: technically I guess enumFrom isn't strict! + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromTo #-} enumFromTo (I# x) (I# y) = eftInt x y + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromThen #-} enumFromThen (I# x1) (I# x2) = efdInt x1 x2 + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromThenTo #-} enumFromThenTo (I# x1) (I# x2) (I# y) = efdtInt x1 x2 y @@ -812,13 +845,20 @@ instance Enum Integer where toEnum (I# n) = smallInteger n fromEnum n = I# (integerToInt n) + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFrom #-} + enumFrom x = enumDeltaInteger x 1 + + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromThen #-} + enumFromThen x y = enumDeltaInteger x (y-x) + + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromTo #-} + enumFromTo x lim = enumDeltaToInteger x 1 lim + + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromThenTo #-} - enumFrom x = enumDeltaInteger x 1 - enumFromThen x y = enumDeltaInteger x (y-x) - enumFromTo x lim = enumDeltaToInteger x 1 lim enumFromThenTo x y lim = enumDeltaToInteger x (y-x) lim -- See Note [How the Enum rules work] @@ -927,6 +967,7 @@ instance Enum Natural where toEnum = intToNatural #if defined(MIN_VERSION_integer_gmp) + -- special case here, catch all is after endif fromEnum (NatS# w) | i >= 0 = i | otherwise = errorWithoutStackTrace "fromEnum: out of Int range" @@ -935,12 +976,22 @@ instance Enum Natural where #endif fromEnum n = fromEnum (naturalToInteger n) + -- See Note [Stable Unfolding for list producers] + {-# INLINABLE enumFrom #-} enumFrom x = enumDeltaNatural x (wordToNaturalBase 1##) + + -- See Note [Stable Unfolding for list producers] + {-# INLINABLE enumFromThen #-} enumFromThen x y | x <= y = enumDeltaNatural x (y-x) | otherwise = enumNegDeltaToNatural x (x-y) (wordToNaturalBase 0##) + -- See Note [Stable Unfolding for list producers] + {-# INLINABLE enumFromTo #-} enumFromTo x lim = enumDeltaToNatural x (wordToNaturalBase 1##) lim + + -- See Note [Stable Unfolding for list producers] + {-# INLINABLE enumFromThenTo #-} enumFromThenTo x y lim | x <= y = enumDeltaToNatural x (y-x) lim | otherwise = enumNegDeltaToNatural x (x-y) lim ===================================== libraries/base/GHC/Word.hs ===================================== @@ -892,10 +892,44 @@ instance Enum Word64 where | x <= fromIntegral (maxBound::Int) = I# (word2Int# x#) | otherwise = fromEnumError "Word64" x - enumFrom = integralEnumFrom - enumFromThen = integralEnumFromThen - enumFromTo = integralEnumFromTo - enumFromThenTo = integralEnumFromThenTo + +#if WORD_SIZE_IN_BITS < 64 + enumFrom = integralEnumFrom + enumFromThen = integralEnumFromThen + enumFromTo = integralEnumFromTo + enumFromThenTo = integralEnumFromThenTo +#else + -- See Note [Stable Unfolding for list producers] in GHC.Enum + {-# INLINABLE enumFrom #-} + enumFrom w + = map wordToWord64 + $ enumFrom (word64ToWord w) + + -- See Note [Stable Unfolding for list producers] in GHC.Enum + {-# INLINABLE enumFromThen #-} + enumFromThen w s + = map wordToWord64 + $ enumFromThen (word64ToWord w) (word64ToWord s) + + -- See Note [Stable Unfolding for list producers] in GHC.Enum + {-# INLINABLE enumFromTo #-} + enumFromTo w1 w2 + = map wordToWord64 + $ enumFromTo (word64ToWord w1) (word64ToWord w2) + + -- See Note [Stable Unfolding for list producers] in GHC.Enum + {-# INLINABLE enumFromThenTo #-} + enumFromThenTo w1 s w2 + = map wordToWord64 + $ enumFromThenTo (word64ToWord w1) (word64ToWord s) (word64ToWord w2) + +word64ToWord :: Word64 -> Word +word64ToWord (W64# w#) = (W# w#) + +wordToWord64 :: Word -> Word64 +wordToWord64 (W# w#) = (W64# w#) +#endif + -- | @since 2.01 instance Integral Word64 where ===================================== testsuite/tests/perf/should_run/T15185.hs ===================================== @@ -0,0 +1,25 @@ +{-# LANGUAGE TypeApplications #-} + +-- Ensure that we do list fusion on `foldr f z [from..to]` for sized `Int` and +-- `Word` types. Related tickets: #15185, #8763. + +import Control.Exception (evaluate) +import Data.Int +import Data.Word + +fact :: Integral t => t -> t +fact n = product [1..n] + +main :: IO () +main = do + _ <- evaluate (fact @Int 50) + _ <- evaluate (fact @Int64 50) + _ <- evaluate (fact @Int32 50) + _ <- evaluate (fact @Int16 50) + _ <- evaluate (fact @Int8 50) + _ <- evaluate (fact @Word 50) + _ <- evaluate (fact @Word64 50) + _ <- evaluate (fact @Word32 50) + _ <- evaluate (fact @Word16 50) + _ <- evaluate (fact @Word8 50) + pure () View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/055c2a92d1215f6b076818254c6834a84bb51d0c...7dc556068289dac776d1497dcb32b2d76d5e7373 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/055c2a92d1215f6b076818254c6834a84bb51d0c...7dc556068289dac776d1497dcb32b2d76d5e7373 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 17 12:49:16 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Sun, 17 May 2020 08:49:16 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/duplicate-forall-printing-notes Message-ID: <5ec132cc88619_76473f9f4a6d03e81624f4@gitlab.haskell.org.mail> Ryan Scott pushed new branch wip/duplicate-forall-printing-notes at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/duplicate-forall-printing-notes You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Sun May 17 14:59:58 2020 From: gitlab at gitlab.haskell.org (Sven Tennie) Date: Sun, 17 May 2020 10:59:58 -0400 Subject: [Git][ghc/ghc][wip/ghc-debug] Encode TSO fields for ghc-heap Message-ID: <5ec1516ee1958_76473f9f4a1694401676a1@gitlab.haskell.org.mail> Sven Tennie pushed to branch wip/ghc-debug at Glasgow Haskell Compiler / GHC Commits: 4e78046b by Sven Tennie at 2020-05-17T16:57:36+02:00 Encode TSO fields for ghc-heap - - - - - 4 changed files: - libraries/ghc-heap/GHC/Exts/Heap.hs - libraries/ghc-heap/GHC/Exts/Heap/Closures.hs - libraries/ghc-heap/GHC/Exts/Heap/FFIClosures.hsc - rts/Heap.c Changes: ===================================== libraries/ghc-heap/GHC/Exts/Heap.hs ===================================== @@ -58,7 +58,7 @@ import GHC.Exts.Heap.InfoTableProf import GHC.Exts.Heap.InfoTable #endif import GHC.Exts.Heap.Utils -import GHC.Exts.Heap.FFIClosures +import qualified GHC.Exts.Heap.FFIClosures as FFIClosures import Control.Monad import Data.Bits @@ -297,8 +297,7 @@ getClosureX get_closure_raw x = do allocaArray (length wds) (\ptr -> do pokeArray ptr wds - threadId' <- peekStgThreadID ptr - alloc_limit' <- peekAllocLimit ptr + fields <- FFIClosures.peekTSOFields ptr pure $ TSOClosure { info = itbl @@ -308,8 +307,14 @@ getClosureX get_closure_raw x = do , trec = (pts !! 3) , blocked_exceptions = (pts !! 4) , bq = (pts !! 5) - , threadId = threadId' - , alloc_limit = alloc_limit' + , what_next = FFIClosures.what_next fields + , why_blocked = FFIClosures.why_blocked fields + , flags = FFIClosures.flags fields + , threadId = FFIClosures.threadId fields + , saved_errno = FFIClosures.saved_errno fields + , dirty = FFIClosures.dirty fields + , alloc_limit = FFIClosures.alloc_limit fields + , tot_stack_size = FFIClosures.tot_stack_size fields } ) STACK -> do ===================================== libraries/ghc-heap/GHC/Exts/Heap/Closures.hs ===================================== @@ -260,9 +260,6 @@ data GenClosure b , link :: !b -- ^ next weak pointer for the capability, can be NULL. } - -- TODO: There are many more fields in a TSO closure which - -- are not yet implemented - -- | StgTSO | TSOClosure { info :: !StgInfoTable @@ -274,8 +271,14 @@ data GenClosure b , blocked_exceptions :: !b , bq :: !b -- values + , what_next :: Word16 + , why_blocked :: Word16 + , flags :: Word32 , threadId :: Word64 + , saved_errno :: Word32 + , dirty:: Word32 , alloc_limit :: Int64 + , tot_stack_size :: Word32 } | StackClosure ===================================== libraries/ghc-heap/GHC/Exts/Heap/FFIClosures.hsc ===================================== @@ -5,9 +5,41 @@ module GHC.Exts.Heap.FFIClosures where import Prelude import Foreign -peekStgThreadID :: Ptr a -> IO Word64 -peekStgThreadID ptr = (#peek struct StgTSO_, id) ptr +-- TODO use sum type for what_next, why_blocked, flags? +data TSOFields = TSOFields { + what_next :: Word16, + why_blocked :: Word16, + flags :: Word32, +-- Unfortunately block_info is a union without clear discriminator. +-- block_info :: TDB, + threadId :: Word64, + saved_errno :: Word32, + dirty:: Word32, + alloc_limit :: Int64, + tot_stack_size :: Word32 +-- TODO StgTSOProfInfo prof is optionally included, but looks very interesting. +} -peekAllocLimit :: Ptr a -> IO Int64 -peekAllocLimit ptr = (#peek struct StgTSO_, alloc_limit) ptr +-- | Get non-pointer fields from @StgTSO_@ (@TSO.h@) +peekTSOFields :: Ptr a -> IO TSOFields +peekTSOFields ptr = do + what_next' <- (#peek struct StgTSO_, what_next) ptr + why_blocked' <- (#peek struct StgTSO_, why_blocked) ptr + flags' <- (#peek struct StgTSO_, flags) ptr + threadId' <- (#peek struct StgTSO_, id) ptr + saved_errno' <- (#peek struct StgTSO_, saved_errno) ptr + dirty' <- (#peek struct StgTSO_, dirty) ptr + alloc_limit' <- (#peek struct StgTSO_, alloc_limit) ptr + tot_stack_size' <- (#peek struct StgTSO_, tot_stack_size) ptr + + return TSOFields { + what_next = what_next', + why_blocked = why_blocked', + flags = flags', + threadId = threadId', + saved_errno = saved_errno', + dirty= dirty', + alloc_limit = alloc_limit', + tot_stack_size = tot_stack_size' + } ===================================== rts/Heap.c ===================================== @@ -224,12 +224,6 @@ static StgWord collect_pointers(StgClosure *closure, StgWord size, StgClosure *p ASSERT((StgClosure *)((StgTSO *)closure)->bq != NULL); ptrs[nptrs++] = (StgClosure *)((StgTSO *)closure)->bq; - int threadId = ((StgTSO *)closure)->id; - debugBelch("threadId : %u", threadId); - - int alloc_limit = ((StgTSO *)closure)->alloc_limit; - debugBelch("alloc_limit : %d", alloc_limit); - break; case STACK: ptrs[nptrs++] = (StgClosure *)((StgStack *)closure)->sp; View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4e78046b7c166ee69e0200dbb8d4c1f3f3f13930 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4e78046b7c166ee69e0200dbb8d4c1f3f3f13930 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 18 11:54:19 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Mon, 18 May 2020 07:54:19 -0400 Subject: [Git][ghc/ghc][wip/nested-cpr-2019] 55 commits: rts/CNF: Fix fixup comparison function Message-ID: <5ec2776b4b42d_764712abe6d82232cd@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/nested-cpr-2019 at Glasgow Haskell Compiler / GHC Commits: cf4f1e2f by Ben Gamari at 2020-05-13T02:02:33-04:00 rts/CNF: Fix fixup comparison function Previously we would implicitly convert the difference between two words to an int, resulting in an integer overflow on 64-bit machines. Fixes #16992 - - - - - a03da9bf by Ömer Sinan Ağacan at 2020-05-13T02:03:16-04:00 Pack some of IdInfo fields into a bit field This reduces residency of compiler quite a bit on some programs. Example stats when building T10370: Before: 2,871,242,832 bytes allocated in the heap 4,693,328,008 bytes copied during GC 33,941,448 bytes maximum residency (276 sample(s)) 375,976 bytes maximum slop 83 MiB total memory in use (0 MB lost due to fragmentation) After: 2,858,897,344 bytes allocated in the heap 4,629,255,440 bytes copied during GC 32,616,624 bytes maximum residency (278 sample(s)) 314,400 bytes maximum slop 80 MiB total memory in use (0 MB lost due to fragmentation) So -3.9% residency, -1.3% bytes copied and -0.4% allocations. Fixes #17497 Metric Decrease: T9233 T9675 - - - - - 670c3e5c by Ben Gamari at 2020-05-13T02:03:54-04:00 get-win32-tarballs: Fix base URL Revert a change previously made for testing purposes. - - - - - 8ad8dc41 by Ben Gamari at 2020-05-13T02:03:54-04:00 get-win32-tarballs: Improve diagnostics output - - - - - 8c0740b7 by Simon Jakobi at 2020-05-13T02:04:33-04:00 docs: Add examples for Data.Semigroup.Arg{Min,Max} Context: #17153 - - - - - cb22348f by Ben Gamari at 2020-05-13T02:05:11-04:00 Add few cleanups of the CAF logic Give the NameSet of non-CAFfy names a proper newtype to distinguish it from all of the other NameSets floating about. - - - - - 90e38b81 by Emeka Nkurumeh at 2020-05-13T02:05:51-04:00 fix printf warning when using with ghc with clang on mingw - - - - - 86d8ac22 by Sebastian Graf at 2020-05-13T02:06:29-04:00 CprAnal: Don't attach CPR sigs to expandable bindings (#18154) Instead, look through expandable unfoldings in `cprTransform`. See the new Note [CPR for expandable unfoldings]: ``` Long static data structures (whether top-level or not) like xs = x1 : xs1 xs1 = x2 : xs2 xs2 = x3 : xs3 should not get CPR signatures, because they * Never get WW'd, so their CPR signature should be irrelevant after analysis (in fact the signature might even be harmful for that reason) * Would need to be inlined/expanded to see their constructed product * Recording CPR on them blows up interface file sizes and is redundant with their unfolding. In case of Nested CPR, this blow-up can be quadratic! But we can't just stop giving DataCon application bindings the CPR property, for example fac 0 = 1 fac n = n * fac (n-1) fac certainly has the CPR property and should be WW'd! But FloatOut will transform the first clause to lvl = 1 fac 0 = lvl If lvl doesn't have the CPR property, fac won't either. But lvl doesn't have a CPR signature to extrapolate into a CPR transformer ('cprTransform'). So instead we keep on cprAnal'ing through *expandable* unfoldings for these arity 0 bindings via 'cprExpandUnfolding_maybe'. In practice, GHC generates a lot of (nested) TyCon and KindRep bindings, one for each data declaration. It's wasteful to attach CPR signatures to each of them (and intractable in case of Nested CPR). ``` Fixes #18154. - - - - - e34bf656 by Ben Gamari at 2020-05-13T02:07:08-04:00 users-guide: Add discussion of shared object naming Fixes #18074. - - - - - 5d0f2445 by Ben Gamari at 2020-05-13T02:07:47-04:00 testsuite: Print sign of performance changes Executes the minor formatting change in the tabulated performance changes suggested in #18135. - - - - - 9e4b981f by Ben Gamari at 2020-05-13T02:08:24-04:00 testsuite: Add testcase for #18129 - - - - - 266310c3 by Ivan-Yudin at 2020-05-13T02:09:03-04:00 doc: Reformulate the opening paragraph of Ch. 4 in User's guide Removes mentioning of Hugs (it is not helpful for new users anymore). Changes the wording for the rest of the paragraph. Fixes #18132. - - - - - 55e35c0b by Baldur Blöndal at 2020-05-13T20:02:48-04:00 Predicate, Equivalence derive via `.. -> a -> All' - - - - - d7e0b57f by Alp Mestanogullari at 2020-05-13T20:03:30-04:00 hadrian: add a --freeze2 option to freeze stage 1 and 2 - - - - - d880d6b2 by Artem Pelenitsyn at 2020-05-13T20:04:11-04:00 Don't reload environment files on every setSessionDynFlags Makes `interpretPackageEnv` (which loads envirinment files) a part of `parseDynamicFlags` (parsing command-line arguments, which is typically done once) instead of `setSessionDynFlags` (which is typically called several times). Making several (transitive) calls to `interpretPackageEnv`, as before, caused #18125 #16318, which should be fixed now. - - - - - 102cfd67 by Ryan Scott at 2020-05-13T20:04:46-04:00 Factor out HsPatSigType for pat sigs/RULE term sigs (#16762) This implements chunks (2) and (3) of https://gitlab.haskell.org/ghc/ghc/issues/16762#note_270170. Namely, it introduces a dedicated `HsPatSigType` AST type, which represents the types that can appear in pattern signatures and term-level `RULE` binders. Previously, these were represented with `LHsSigWcType`. Although `LHsSigWcType` is isomorphic to `HsPatSigType`, the intended semantics of the two types are slightly different, as evidenced by the fact that they have different code paths in the renamer and typechecker. See also the new `Note [Pattern signature binders and scoping]` in `GHC.Hs.Types`. - - - - - b17574f7 by Hécate at 2020-05-13T20:05:28-04:00 fix(documentation): Fix the RST links to GHC.Prim - - - - - df021fb1 by Baldur Blöndal at 2020-05-13T20:06:06-04:00 Document (->) using inferred quantification for its runtime representations. Fixes #18142. - - - - - 1a93ea57 by Takenobu Tani at 2020-05-13T20:06:54-04:00 Tweak man page for ghc command This commit updates the ghc command's man page as followings: * Enable `man_show_urls` to show URL addresses in the `DESCRIPTION` section of ghc.rst, because sphinx currently removes hyperlinks for man pages. * Add a `SEE ALSO` section to point to the GHC homepage - - - - - a951e1ba by Takenobu Tani at 2020-05-13T20:07:37-04:00 GHCi: Add link to the user's guide in help message This commit adds a link to the user's guide in ghci's `:help` message. Newcomers could easily reach to details of ghci. - - - - - 404581ea by Jeff Happily at 2020-05-13T20:08:15-04:00 Handle single unused import - - - - - 1c999e5d by Ben Gamari at 2020-05-13T20:09:07-04:00 Ensure that printMinimalImports closes handle Fixes #18166. - - - - - c9f5a8f4 by Ben Gamari at 2020-05-13T20:09:51-04:00 hadrian: Tell testsuite driver about LLVM availability This reflects the logic present in the Make build system into Hadrian. Fixes #18167. - - - - - c05c0659 by Simon Jakobi at 2020-05-14T03:31:21-04:00 Improve some folds over Uniq[D]FM * Replace some non-deterministic lazy folds with strict folds. * Replace some O(n log n) folds in deterministic order with O(n) non-deterministic folds. * Replace some folds with set-operations on the underlying IntMaps. This reduces max residency when compiling `nofib/spectral/simple/Main.hs` with -O0 by about 1%. Maximum residency when compiling Cabal also seems reduced on the order of 3-9%. - - - - - 477f13bb by Simon Jakobi at 2020-05-14T03:31:58-04:00 Use Data.IntMap.disjoint Data.IntMap gained a dedicated `disjoint` function in containers-0.6.2.1. This patch applies this function where appropriate in hopes of modest compiler performance improvements. Closes #16806. - - - - - e9c0110c by Ben Gamari at 2020-05-14T12:25:53-04:00 IdInfo: Add reference to bitfield-packing ticket - - - - - 9bd20e83 by Sebastian Graf at 2020-05-15T10:42:09-04:00 DmdAnal: Improve handling of precise exceptions This patch does two things: Fix possible unsoundness in what was called the "IO hack" and implement part 2.1 of the "fixing precise exceptions" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions, which, in combination with !2956, supersedes !3014 and !2525. **IO hack** The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is called `exprMayThrowPreciseException` now. I came up with two testcases exemplifying possible unsoundness (if twisted enough) in the old approach: - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. - `T13380e`: Demonstrating unsoundness of the "IO hack" when we have Nested CPR. Not currently relevant, as we don't have Nested CPR yet. - `T13380f`: Demonstrating unsoundness of the "IO hack" for safe FFI calls. Basically, the IO hack assumed that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future, see `T13380e`. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380{d,e}` (and will hopefully be robust to Nested CPR). **Precise exceptions** In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that was terribly unprincipled. That unprincipledness resulted in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception (and the existing IO hack doesn't detect that) Fixing both issues in !3014 turned out to be too complicated and had the potential to regress in the future. Hence we decided to only fix `T13380b` and augment the `Divergence` lattice with a new middle-layer element, `ExnOrDiv`, which means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. See the wiki page on Step 2.1 for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#dead-code-elimination-for-raiseio-with-isdeadenddiv-introducing-exnordiv-step-21 - - - - - 568d7279 by Ben Gamari at 2020-05-15T10:42:46-04:00 GHC.Cmm.Opt: Handle MO_XX_Conv This MachOp was introduced by 2c959a1894311e59cd2fd469c1967491c1e488f3 but a wildcard match in cmmMachOpFoldM hid the fact that it wasn't handled. Ideally we would eliminate the match but this appears to be a larger task. Fixes #18141. - - - - - 6f2dd7d1 by Sebastian Graf at 2020-05-17T18:05:28+02:00 Nested CPR - - - - - d8ef66c6 by Sebastian Graf at 2020-05-17T18:05:30+02:00 Move tests from stranal to cpranal - - - - - 5f4a67bc by Sebastian Graf at 2020-05-17T18:05:30+02:00 Accept FacState - - - - - 84aaab65 by Sebastian Graf at 2020-05-17T18:09:20+02:00 Factor Cpr and Termination into a joint lattice As a result, we don't even have to export Termination from Cpr. Neat! Also I realised there is a simpler and more sound way to generate and unleash CPR signatures. - - - - - c2168883 by Sebastian Graf at 2020-05-17T18:09:21+02:00 Consider unboxing effects of WW better and get rid of hack - - - - - 64e8973c by Sebastian Graf at 2020-05-17T18:09:21+02:00 stuff - - - - - 58c5e7a2 by Sebastian Graf at 2020-05-17T18:09:21+02:00 Debug output - - - - - 28fd1541 by Sebastian Graf at 2020-05-17T18:10:15+02:00 A slew of testsuite changes - - - - - 8db32a83 by Sebastian Graf at 2020-05-17T18:10:17+02:00 Fix T1600 - - - - - 0122dab8 by Sebastian Graf at 2020-05-17T18:10:17+02:00 Inline `decodeDoubleInteger` and constant-fold `decodeDouble_Int64#` instead Currently, `decodeDoubleInteger` is known-key so that it can be recognised in constant folding. But that is very brittle and doesn't survive worker/wrapper, which we even do for `NOINLINE`/`CONSTANT_FOLDED` things since #13143. Also it is a trade-off: The implementation of `decodeDoubleInteger` allocates an `Integer` box that never cancels aways if we don't inline it. Hence we recognise the `decodeDouble_Int64#` primop instead in constant folding, so that we can inline `decodeDoubleInteger`. You may wonder how this affects performance of code using `integer-simple`; Apparently, according to @hsyl20 this is not a concern since we will hopefully land !2231 soon. Fixes #18092. - - - - - a68c809a by Sebastian Graf at 2020-05-17T18:10:17+02:00 Fix primop termination - - - - - 0df4b24f by Sebastian Graf at 2020-05-17T18:10:17+02:00 Test for DataCon wrapper CPR - - - - - d671da8a by Sebastian Graf at 2020-05-17T18:11:16+02:00 Fix CPR of bottoming functions/primops - - - - - d6c0898e by Sebastian Graf at 2020-05-17T18:11:18+02:00 Fix DataConWrapperCpr and accept other test outputs - - - - - a9a6d4df by Sebastian Graf at 2020-05-17T18:11:18+02:00 Accept two more changed test outputs - - - - - e445765f by Sebastian Graf at 2020-05-17T18:11:23+02:00 Update CaseBinderCPR with a new function - - - - - 20fab53c by Sebastian Graf at 2020-05-17T18:11:25+02:00 Don't give the case binder the CPR property - - - - - a1c73a85 by Sebastian Graf at 2020-05-17T18:11:25+02:00 Prune CPR sigs to constant depth on all bindings - - - - - ea1c7ed1 by Sebastian Graf at 2020-05-17T18:11:25+02:00 Use variable length coding for ConTags - - - - - 37796cdb by Sebastian Graf at 2020-05-17T18:11:28+02:00 Accept testuite output - - - - - edd8801e by Sebastian Graf at 2020-05-17T18:13:00+02:00 Don't attach CPR sigs to expandable bindings; transform their unfoldings instead - - - - - 88f8e954 by Sebastian Graf at 2020-05-17T18:13:02+02:00 Revert "Don't give the case binder the CPR property" This reverts commit 910edd76d5fe68b58c74f3805112f9faef4f2788. It seems we broke too much with this change. We lost our big win in `fish`. - - - - - 654f6727 by Sebastian Graf at 2020-05-17T18:13:02+02:00 A more modular and configurable approach to optimistic case binder CPR - - - - - b017a272 by Sebastian Graf at 2020-05-17T18:13:02+02:00 Fix T9291 - - - - - 5324d98d by Sebastian Graf at 2020-05-17T18:13:02+02:00 Document -fcase-binder-cpr-depth in the user's guide - - - - - a572aee9 by Sebastian Graf at 2020-05-18T13:14:25+02:00 Rebase woes - - - - - 0c2eedad by Sebastian Graf at 2020-05-18T13:36:40+02:00 Testsuite changes - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/LiberateCase.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/TyCo/FVs.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCo/Subst.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5397fe394009f07b0c42977af1bc1030c2592b8a...0c2eedad466fabeb8367a3d7617f13e87df9778f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5397fe394009f07b0c42977af1bc1030c2592b8a...0c2eedad466fabeb8367a3d7617f13e87df9778f You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 18 15:26:37 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Mon, 18 May 2020 11:26:37 -0400 Subject: [Git][ghc/ghc][wip/nested-cpr-2019] 2 commits: Refactoring around cprAnalBind Message-ID: <5ec2a92d8ff17_76473f9f630e107c24448a@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/nested-cpr-2019 at Glasgow Haskell Compiler / GHC Commits: 3dde931c by Sebastian Graf at 2020-05-18T16:36:42+02:00 Refactoring around cprAnalBind - - - - - 3ae7eb1f by Sebastian Graf at 2020-05-18T17:08:43+02:00 Fix case binder CPR by not looking into unfoldings of case binders - - - - - 2 changed files: - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Types/Cpr.hs Changes: ===================================== compiler/GHC/Core/Opt/CprAnal.hs ===================================== @@ -119,9 +119,9 @@ cprAnalTopBind :: AnalEnv -> CoreBind -> (AnalEnv, CoreBind) cprAnalTopBind env (NonRec id rhs) - = (extendAnalEnv env id' (idCprInfo id'), NonRec id' rhs') + = (env', NonRec id' rhs') where - (id', rhs') = cprAnalBind TopLevel env [] id rhs + (id', rhs', env') = cprAnalBind TopLevel env noWidening [] id rhs cprAnalTopBind env (Rec pairs) = (env', Rec pairs') @@ -196,7 +196,7 @@ cprAnal' env args (Lam var body) (arg_ty, body_args) | ty:args' <- args = (ty, args') -- We know things about the argument, for example from a StrictSig or an incoming argument. NB: This can never be an anonymous (non-let-bound) lambda! The simplifier would have eliminated the necessary (App (Lam{} |> co) _) construct. | otherwise = (topCprType, []) -- An anonymous lambda or no info on its argument - env' = extendAnalEnv env var (CprSig arg_ty) -- TODO: I think we also need to store assumed argument strictness (which would be all lazy here) in the env + env' = extendSigEnv env var (CprSig arg_ty) -- TODO: I think we also need to store assumed argument strictness (which would be all lazy here) in the env (body_ty, body') = cprAnal env' body_args body lam_ty = abstractCprTy body_ty @@ -213,9 +213,8 @@ cprAnal' env args (Case scrut case_bndr ty alts) cprAnal' env args (Let (NonRec id rhs) body) = (body_ty, Let (NonRec id' rhs') body') where - (id', rhs') = cprAnalBind NotTopLevel env args id rhs - env' = extendAnalEnv env id' (idCprInfo id') - (body_ty, body') = cprAnal env' args body + (id', rhs', env') = cprAnalBind NotTopLevel env noWidening args id rhs + (body_ty, body') = cprAnal env' args body cprAnal' env args (Let (Rec pairs) body) = body_ty `seq` (body_ty, Let (Rec pairs') body') @@ -239,7 +238,7 @@ cprAnalAlt env args case_bndr case_bndr_ty (con@(DataAlt dc),bndrs,rhs) cprAnalAlt env args case_bndr case_bndr_ty (con,bndrs,rhs) = (rhs_ty, (con, bndrs, rhs')) where - env' = extendAnalEnv env case_bndr (CprSig case_bndr_ty) + env' = extendSigEnv env case_bndr (CprSig case_bndr_ty) (rhs_ty, rhs') = cprAnal env' args rhs -- @@ -256,6 +255,9 @@ cprTransform env args id sig where sig + -- Local let-bound + | Just sig <- lookupSigEnv env id + = cprTransformSig (idStrictness id) sig args -- See Note [CPR for expandable unfoldings] | Just rhs <- cprExpandUnfolding_maybe id = fst $ cprAnal env args rhs @@ -265,9 +267,6 @@ cprTransform env args id -- Imported function or data con worker | isGlobalId id = cprTransformSig (idStrictness id) (idCprInfo id) args - -- Local let-bound - | Just sig <- lookupSigEnv env id - = cprTransformSig (idStrictness id) sig args | otherwise = topCprType @@ -275,57 +274,27 @@ cprTransform env args id -- * Bindings -- --- Recursive bindings -cprFix - :: TopLevelFlag - -> AnalEnv -- Does not include bindings for this binding - -> [CprType] - -> [(Id,CoreExpr)] - -> (AnalEnv, [(Id,CoreExpr)]) -- Binders annotated with stricness info -cprFix top_lvl env str orig_pairs - = loop 1 initial_pairs - where - init_sig id = mkCprSig (idArity id) divergeCpr - -- See Note [Initialising strictness] in GHC.Core.Opt.DmdAnal - initial_pairs | ae_virgin env = [(setIdCprInfo id (init_sig id), rhs) | (id, rhs) <- orig_pairs ] - | otherwise = orig_pairs - - -- The fixed-point varies the idCprInfo field of the binders, and terminates if that - -- annotation does not change any more. - loop :: Int -> [(Id,CoreExpr)] -> (AnalEnv, [(Id,CoreExpr)]) - loop n pairs - | found_fixpoint = (final_anal_env, pairs') - | otherwise = -- pprTrace "cprFix:loop" (ppr n <+> ppr (map fst pairs)) $ - loop (n+1) pairs' - where - found_fixpoint = selector pairs' == selector pairs - selector = map (idCprInfo . fst) - first_round = n == 1 - pairs' = step first_round pairs - final_anal_env = extendAnalEnvs env (map fst pairs') - - step :: Bool -> [(Id, CoreExpr)] -> [(Id, CoreExpr)] - step first_round pairs = pairs' - where - -- In all but the first iteration, delete the virgin flag - start_env | first_round = env - | otherwise = nonVirgin env +-- +-- ** Widening +-- - start = extendAnalEnvs start_env (map fst pairs) +type Widening = CprSig -> CprSig - (_, pairs') = mapAccumL my_downRhs start pairs +noWidening :: Widening +noWidening = id - my_downRhs env (id,rhs) - = (env', (id2, rhs')) - where - (id1, rhs') = cprAnalBind top_lvl env str id rhs - -- See Note [Ensuring termination of fixed-point iteration] - id2 = setIdCprInfo id1 $ pruneSig mAX_DEPTH $ markDiverging $ idCprInfo id1 - env' = extendAnalEnv env id2 (idCprInfo id2) +-- | A widening operator on 'CprSig' to ensure termination of fixed-point +-- iteration. See Note [Ensuring termination of fixed-point iteration] +depthWidening :: Widening +depthWidening = pruneSig mAX_DEPTH . markDiverging mAX_DEPTH :: Int mAX_DEPTH = 4 +pruneSig :: Int -> CprSig -> CprSig +pruneSig d (CprSig cpr_ty) + = CprSig $ cpr_ty { ct_cpr = pruneDeepCpr d (ct_cpr cpr_ty) } + -- TODO: We need the lubCpr with the initial CPR because -- of functions like iterate, which we would CPR -- multiple levels deep, thereby changing termination @@ -333,35 +302,26 @@ mAX_DEPTH = 4 markDiverging :: CprSig -> CprSig markDiverging (CprSig cpr_ty) = CprSig $ cpr_ty { ct_cpr = ct_cpr cpr_ty `lubCpr` divergeCpr } --- | A widening operator on 'CprSig' to ensure termination of fixed-point --- iteration. See Note [Ensuring termination of fixed-point iteration] -pruneSig :: Int -> CprSig -> CprSig -pruneSig d (CprSig cpr_ty) - = CprSig $ cpr_ty { ct_cpr = pruneDeepCpr d (ct_cpr cpr_ty) } - -unboxingStrategy :: AnalEnv -> UnboxingStrategy -unboxingStrategy env ty dmd - = prj <$> wantToUnbox (ae_fam_envs env) has_inlineable_prag ty dmd - where - prj (dmds, DataConAppContext { dcac_dc = dc, dcac_arg_tys = tys_w_str }) - = (dc, map fst tys_w_str, dmds) - -- Rather than maintaining in AnalEnv whether we are in an INLINEABLE - -- function, we just assume that we aren't. That flag is only relevant - -- to Note [Do not unpack class dictionaries], the few unboxing - -- opportunities on dicts it prohibits are probably irrelevant to CPR. - has_inlineable_prag = False +-- +-- ** Analysing a binding (one-round, the non-recursive case) +-- -- | Process the RHS of the binding for a sensible arity, add the CPR signature -- to the Id, and augment the environment with the signature as well. cprAnalBind :: TopLevelFlag -> AnalEnv + -> Widening -- ^ We want to specify 'depthWidening' in fixed-point iteration -> [CprType] -> Id -> CoreExpr - -> (Id, CoreExpr) -cprAnalBind top_lvl env args id rhs - = (id', rhs') + -> (Id, CoreExpr, AnalEnv) +cprAnalBind top_lvl env widening args id rhs + -- See Note [CPR for expandable unfoldings] + | isJust (cprExpandUnfolding_maybe id) + = (id, rhs, env) + | otherwise + = (id', rhs', env') where arg_tys = fst (splitFunNewTys (idType id)) -- We compute the Termination and CPR transformer based on the strictness @@ -387,16 +347,13 @@ cprAnalBind top_lvl env args id rhs | stays_thunk = trimCprTy rhs_ty -- See Note [CPR for sum types] | returns_sum = trimCprTy rhs_ty - -- See Note [CPR for expandable unfoldings] - | will_expand = topCprType | otherwise = rhs_ty -- See Note [Arity trimming for CPR signatures] - -- We prune so that we discard too deep info on e.g. TyCon bindings dflags = ae_dflags env - sig = pruneSig mAX_DEPTH $ mkCprSigForArity dflags (idArity id) rhs_ty' - id' = -- pprTrace "cprAnalBind" (ppr id $$ ppr sig) $ - setIdCprInfo id sig + sig = widening $ mkCprSigForArity dflags (idArity id) rhs_ty' + (id', env') = -- pprTrace "cprAnalBind" (ppr id $$ ppr sig) $ + (setIdCprInfo id sig, extendSigEnv env id sig) -- See Note [CPR for thunks] stays_thunk = is_thunk && not_strict @@ -406,8 +363,18 @@ cprAnalBind top_lvl env args id rhs (_, ret_ty) = splitPiTys (idType id) not_a_prod = isNothing (deepSplitProductType_maybe (ae_fam_envs env) ret_ty) returns_sum = not (isTopLevel top_lvl) && not_a_prod - -- See Note [CPR for expandable unfoldings] - will_expand = isJust (cprExpandUnfolding_maybe id) + +unboxingStrategy :: AnalEnv -> UnboxingStrategy +unboxingStrategy env ty dmd + = prj <$> wantToUnbox (ae_fam_envs env) has_inlineable_prag ty dmd + where + prj (dmds, DataConAppContext { dcac_dc = dc, dcac_arg_tys = tys_w_str }) + = (dc, map fst tys_w_str, dmds) + -- Rather than maintaining in AnalEnv whether we are in an INLINEABLE + -- function, we just assume that we aren't. That flag is only relevant + -- to Note [Do not unpack class dictionaries], the few unboxing + -- opportunities on dicts it prohibits are probably irrelevant to CPR. + has_inlineable_prag = False cprExpandUnfolding_maybe :: Id -> Maybe CoreExpr cprExpandUnfolding_maybe id = do @@ -416,6 +383,58 @@ cprExpandUnfolding_maybe id = do guard (isActiveIn 0 (idInlineActivation id)) expandUnfolding_maybe (idUnfolding id) +-- +-- ** Analysing recursive bindings +-- + +-- | Fixed-point iteration +cprFix + :: TopLevelFlag + -> AnalEnv -- Does not include bindings for this binding + -> [CprType] + -> [(Id,CoreExpr)] + -> (AnalEnv, [(Id,CoreExpr)]) -- Binders annotated with stricness info +cprFix top_lvl env args orig_pairs + = loop 1 initial_pairs + where + init_sig id + | isJust (cprExpandUnfolding_maybe id) = topCprSig + | otherwise = mkCprSig (idArity id) divergeCpr + -- See Note [Initialising strictness] in GHC.Core.Opt.DmdAnal + initial_pairs | ae_virgin env = [(setIdCprInfo id (init_sig id), rhs) | (id, rhs) <- orig_pairs ] + | otherwise = orig_pairs + + -- The fixed-point varies the idCprInfo field of the binders, and terminates if that + -- annotation does not change any more. + loop :: Int -> [(Id,CoreExpr)] -> (AnalEnv, [(Id,CoreExpr)]) + loop n pairs + | found_fixpoint = (final_anal_env, pairs') + | otherwise = -- pprTrace "cprFix:loop" (ppr n <+> ppr (map fst pairs)) $ + loop (n+1) pairs' + where + found_fixpoint = selector pairs' == selector pairs + selector = map (idCprInfo . fst) + first_round = n == 1 + pairs' = step first_round pairs + final_anal_env = extendSigEnvs env (map fst pairs') + + step :: Bool -> [(Id, CoreExpr)] -> [(Id, CoreExpr)] + step first_round pairs = pairs' + where + -- In all but the first iteration, delete the virgin flag + start_env | first_round = env + | otherwise = nonVirgin env + + start = extendSigEnvs start_env (map fst pairs) + + (_, pairs') = mapAccumL anal_bind start pairs + + anal_bind env (id,rhs) + = (env', (id', rhs')) + where + -- See Note [Ensuring termination of fixed-point iteration] + (id', rhs', env') = cprAnalBind top_lvl env depthWidening args id rhs + {- Note [Arity trimming for CPR signatures] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Although it doesn't affect correctness of the analysis per se, we have to trim @@ -478,17 +497,17 @@ emptyAnalEnv dflags fam_envs , ae_fam_envs = fam_envs } -extendAnalEnv :: AnalEnv -> Id -> CprSig -> AnalEnv -extendAnalEnv env id sig +extendSigEnv :: AnalEnv -> Id -> CprSig -> AnalEnv +extendSigEnv env id sig = env { ae_sigs = extendVarEnv (ae_sigs env) id sig } -extendAnalEnvList :: AnalEnv -> [(Id, CprSig)] -> AnalEnv -extendAnalEnvList env ids_cprs +extendSigEnvList :: AnalEnv -> [(Id, CprSig)] -> AnalEnv +extendSigEnvList env ids_cprs = env { ae_sigs = extendVarEnvList (ae_sigs env) ids_cprs } -- | Extend an environment with the CPR signatures attached to the id -extendAnalEnvs :: AnalEnv -> [Id] -> AnalEnv -extendAnalEnvs env ids +extendSigEnvs :: AnalEnv -> [Id] -> AnalEnv +extendSigEnvs env ids = env { ae_sigs = sigs' } where sigs' = extendVarEnvList (ae_sigs env) [ (id, idCprInfo id) | id <- ids ] @@ -502,7 +521,7 @@ nonVirgin env = env { ae_virgin = False } extendEnvForDataAlt :: AnalEnv -> Id -> CprType -> DataCon -> [Var] -> AnalEnv -- See Note [CPR in a DataAlt case alternative] extendEnvForDataAlt env case_bndr case_bndr_ty dc bndrs - = extendAnalEnv env' case_bndr (CprSig case_bndr_ty') + = extendSigEnv env' case_bndr (CprSig case_bndr_ty') where tycon = dataConTyCon dc is_product = isJust (isDataProductTyCon_maybe tycon) @@ -517,7 +536,7 @@ extendEnvForDataAlt env case_bndr case_bndr_ty dc bndrs | Just fields <- splitConCprTy dc case_bndr_ty' , let ids = filter isId bndrs , let cpr_tys = map (CprSig . CprType 0) fields - = extendAnalEnvList env (zipEqual "extendEnvForDataAlt" ids cpr_tys) + = extendSigEnvList env (zipEqual "extendEnvForDataAlt" ids cpr_tys) | otherwise = env @@ -746,6 +765,14 @@ In practice, GHC generates a lot of (nested) TyCon and KindRep bindings, one for each data declaration. It's wasteful to attach CPR signatures to each of them (and intractable in case of Nested CPR). +Also we don't need to analyse RHSs of expandable bindings: The CPR signature of +the binding is never consulted and there may not be let or case expressions +nested inside its RHS. In which case we also don't record a signature in the +local AnalEnv. Doing so would override looking into the unfolding. Why not give +the expandable case in cprTransform a higher priority then? Because then *all* +case binders would get the CPR property, regardless of -fcase-binder-cpr-depth, +because case binders have expandable unfoldings. + Tracked by #18154. Note [CPR examples] ===================================== compiler/GHC/Types/Cpr.hs ===================================== @@ -318,7 +318,8 @@ conCprType con_tag args = CprType 0 (conCpr con_tag cprs) markOptimisticConCprType :: DataCon -> CprType -> CprType markOptimisticConCprType dc _ty@(CprType n cpr) - = ASSERT2( n == 0, ppr _ty ) CprType 0 (optimisticConCpr con_tag fields) + = -- pprTraceWith "markOptimisticConCpr" (\ty' -> ppr _ty $$ ppr ty') $ + ASSERT2( n == 0, ppr _ty ) CprType 0 (optimisticConCpr con_tag fields) where con_tag = dataConTag dc wkr_arity = dataConRepArity dc @@ -364,8 +365,9 @@ trimCprTy :: CprType -> CprType trimCprTy (CprType arty cpr) = CprType arty (trimCpr cpr) zonkOptimisticCprTy :: Int -> CprType -> CprType -zonkOptimisticCprTy max_depth (CprType arty cpr) - = CprType arty (zonk max_depth cpr) +zonkOptimisticCprTy max_depth _ty@(CprType arty cpr) + = -- pprTraceWith "zonkOptimisticCprTy" (\ty' -> ppr max_depth <+> ppr _ty <+> ppr ty') $ + CprType arty (zonk max_depth cpr) where -- | The Int is the amount of "fuel" left; when it reaches 0, we no longer -- turn OptimisticCpr into Cpr, but into NoMoreCpr. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0c2eedad466fabeb8367a3d7617f13e87df9778f...3ae7eb1f530eba8e30fb85a0f5d018e15666b882 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0c2eedad466fabeb8367a3d7617f13e87df9778f...3ae7eb1f530eba8e30fb85a0f5d018e15666b882 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 18 19:48:11 2020 From: gitlab at gitlab.haskell.org (Bodigrim) Date: Mon, 18 May 2020 15:48:11 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/fromListN Message-ID: <5ec2e67ba4efd_764711e48da430842d@gitlab.haskell.org.mail> Bodigrim pushed new branch wip/fromListN at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/fromListN You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 18 20:08:13 2020 From: gitlab at gitlab.haskell.org (Vilem-Benjamin Liepelt) Date: Mon, 18 May 2020 16:08:13 -0400 Subject: [Git][ghc/ghc][wip/buggymcbugfix/15185-enum-int] 3 commits: Add INLINABLE pragmas to Enum list producers Message-ID: <5ec2eb2dc264d_76476f92788315643@gitlab.haskell.org.mail> Vilem-Benjamin Liepelt pushed to branch wip/buggymcbugfix/15185-enum-int at Glasgow Haskell Compiler / GHC Commits: d828a009 by buggymcbugfix at 2020-05-18T23:05:59+03:00 Add INLINABLE pragmas to Enum list producers The INLINABLE pragmas ensure that we export stable (unoptimised) unfoldings in the interface file so we can do list fusion at usage sites. Related tickets: #15185, #8763, #18178. - - - - - 2ae5e28c by buggymcbugfix at 2020-05-18T23:05:59+03:00 Piggyback on Enum Word methods for Word64 If we are on a 64 bit platform, we can use the efficient Enum Word methods for the Enum Word64 instance. - - - - - 8f9092da by buggymcbugfix at 2020-05-18T23:05:59+03:00 Document INLINE(ABLE) pragmas that enable fusion - - - - - 4 changed files: - libraries/base/GHC/Enum.hs - libraries/base/GHC/Word.hs - + testsuite/tests/perf/should_run/T15185.hs - testsuite/tests/perf/should_run/all.T Changes: ===================================== libraries/base/GHC/Enum.hs ===================================== @@ -139,17 +139,34 @@ class Enum a where -- * @enumFromThenTo 6 8 2 :: [Int] = []@ enumFromThenTo :: a -> a -> a -> [a] - succ = toEnum . (+ 1) . fromEnum - pred = toEnum . (subtract 1) . fromEnum - enumFrom x = map toEnum [fromEnum x ..] - enumFromThen x y = map toEnum [fromEnum x, fromEnum y ..] - enumFromTo x y = map toEnum [fromEnum x .. fromEnum y] + succ = toEnum . (+ 1) . fromEnum + + pred = toEnum . (subtract 1) . fromEnum + + -- See Note [Stable Unfolding for list producers] + {-# INLINABLE enumFrom #-} + enumFrom x = map toEnum [fromEnum x ..] + + -- See Note [Stable Unfolding for list producers] + {-# INLINABLE enumFromThen #-} + enumFromThen x y = map toEnum [fromEnum x, fromEnum y ..] + + -- See Note [Stable Unfolding for list producers] + {-# INLINABLE enumFromTo #-} + enumFromTo x y = map toEnum [fromEnum x .. fromEnum y] + + -- See Note [Stable Unfolding for list producers] + {-# INLINABLE enumFromThenTo #-} enumFromThenTo x1 x2 y = map toEnum [fromEnum x1, fromEnum x2 .. fromEnum y] +-- See Note [Stable Unfolding for list producers] +{-# INLINABLE boundedEnumFrom #-} -- Default methods for bounded enumerations boundedEnumFrom :: (Enum a, Bounded a) => a -> [a] boundedEnumFrom n = map toEnum [fromEnum n .. fromEnum (maxBound `asTypeOf` n)] +-- See Note [Stable Unfolding for list producers] +{-# INLINABLE boundedEnumFromThen #-} boundedEnumFromThen :: (Enum a, Bounded a) => a -> a -> [a] boundedEnumFromThen n1 n2 | i_n2 >= i_n1 = map toEnum [i_n1, i_n2 .. fromEnum (maxBound `asTypeOf` n1)] @@ -158,6 +175,14 @@ boundedEnumFromThen n1 n2 i_n1 = fromEnum n1 i_n2 = fromEnum n2 +{- +Note [Stable Unfolding for list producers] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The INLINABLE/INLINE pragmas ensure that we export stable (unoptimised) +unfoldings in the interface file so we can do list fusion at usage sites. +-} + ------------------------------------------------------------------------ -- Helper functions ------------------------------------------------------------------------ @@ -343,16 +368,20 @@ instance Enum Char where toEnum = chr fromEnum = ord + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFrom #-} enumFrom (C# x) = eftChar (ord# x) 0x10FFFF# -- Blarg: technically I guess enumFrom isn't strict! + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromTo #-} enumFromTo (C# x) (C# y) = eftChar (ord# x) (ord# y) + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromThen #-} enumFromThen (C# x1) (C# x2) = efdChar (ord# x1) (ord# x2) + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromThenTo #-} enumFromThenTo (C# x1) (C# x2) (C# y) = efdtChar (ord# x1) (ord# x2) (ord# y) @@ -472,17 +501,21 @@ instance Enum Int where toEnum x = x fromEnum x = x + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFrom #-} enumFrom (I# x) = eftInt x maxInt# where !(I# maxInt#) = maxInt -- Blarg: technically I guess enumFrom isn't strict! + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromTo #-} enumFromTo (I# x) (I# y) = eftInt x y + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromThen #-} enumFromThen (I# x1) (I# x2) = efdInt x1 x2 + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromThenTo #-} enumFromThenTo (I# x1) (I# x2) (I# y) = efdtInt x1 x2 y @@ -812,13 +845,20 @@ instance Enum Integer where toEnum (I# n) = smallInteger n fromEnum n = I# (integerToInt n) + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFrom #-} + enumFrom x = enumDeltaInteger x 1 + + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromThen #-} + enumFromThen x y = enumDeltaInteger x (y-x) + + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromTo #-} + enumFromTo x lim = enumDeltaToInteger x 1 lim + + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromThenTo #-} - enumFrom x = enumDeltaInteger x 1 - enumFromThen x y = enumDeltaInteger x (y-x) - enumFromTo x lim = enumDeltaToInteger x 1 lim enumFromThenTo x y lim = enumDeltaToInteger x (y-x) lim -- See Note [How the Enum rules work] @@ -927,6 +967,7 @@ instance Enum Natural where toEnum = intToNatural #if defined(MIN_VERSION_integer_gmp) + -- This is the integer-gmp special case. The general case is after the endif. fromEnum (NatS# w) | i >= 0 = i | otherwise = errorWithoutStackTrace "fromEnum: out of Int range" @@ -936,11 +977,13 @@ instance Enum Natural where fromEnum n = fromEnum (naturalToInteger n) enumFrom x = enumDeltaNatural x (wordToNaturalBase 1##) + enumFromThen x y | x <= y = enumDeltaNatural x (y-x) | otherwise = enumNegDeltaToNatural x (x-y) (wordToNaturalBase 0##) enumFromTo x lim = enumDeltaToNatural x (wordToNaturalBase 1##) lim + enumFromThenTo x y lim | x <= y = enumDeltaToNatural x (y-x) lim | otherwise = enumNegDeltaToNatural x (x-y) lim ===================================== libraries/base/GHC/Word.hs ===================================== @@ -892,10 +892,44 @@ instance Enum Word64 where | x <= fromIntegral (maxBound::Int) = I# (word2Int# x#) | otherwise = fromEnumError "Word64" x - enumFrom = integralEnumFrom - enumFromThen = integralEnumFromThen - enumFromTo = integralEnumFromTo - enumFromThenTo = integralEnumFromThenTo + +#if WORD_SIZE_IN_BITS < 64 + enumFrom = integralEnumFrom + enumFromThen = integralEnumFromThen + enumFromTo = integralEnumFromTo + enumFromThenTo = integralEnumFromThenTo +#else + -- See Note [Stable Unfolding for list producers] in GHC.Enum + {-# INLINABLE enumFrom #-} + enumFrom w + = map wordToWord64 + $ enumFrom (word64ToWord w) + + -- See Note [Stable Unfolding for list producers] in GHC.Enum + {-# INLINABLE enumFromThen #-} + enumFromThen w s + = map wordToWord64 + $ enumFromThen (word64ToWord w) (word64ToWord s) + + -- See Note [Stable Unfolding for list producers] in GHC.Enum + {-# INLINABLE enumFromTo #-} + enumFromTo w1 w2 + = map wordToWord64 + $ enumFromTo (word64ToWord w1) (word64ToWord w2) + + -- See Note [Stable Unfolding for list producers] in GHC.Enum + {-# INLINABLE enumFromThenTo #-} + enumFromThenTo w1 s w2 + = map wordToWord64 + $ enumFromThenTo (word64ToWord w1) (word64ToWord s) (word64ToWord w2) + +word64ToWord :: Word64 -> Word +word64ToWord (W64# w#) = (W# w#) + +wordToWord64 :: Word -> Word64 +wordToWord64 (W# w#) = (W64# w#) +#endif + -- | @since 2.01 instance Integral Word64 where ===================================== testsuite/tests/perf/should_run/T15185.hs ===================================== @@ -0,0 +1,25 @@ +{-# LANGUAGE TypeApplications #-} + +-- Ensure that we do list fusion on `foldr f z [from..to]` for sized `Int` and +-- `Word` types. Related tickets: #15185, #8763. + +import Control.Exception (evaluate) +import Data.Int +import Data.Word + +fact :: Integral t => t -> t +fact n = product [1..n] + +main :: IO () +main = do + _ <- evaluate (fact @Int 50) + _ <- evaluate (fact @Int64 50) + _ <- evaluate (fact @Int32 50) + _ <- evaluate (fact @Int16 50) + _ <- evaluate (fact @Int8 50) + _ <- evaluate (fact @Word 50) + _ <- evaluate (fact @Word64 50) + _ <- evaluate (fact @Word32 50) + _ <- evaluate (fact @Word16 50) + _ <- evaluate (fact @Word8 50) + pure () ===================================== testsuite/tests/perf/should_run/all.T ===================================== @@ -367,6 +367,11 @@ test('T15578', compile_and_run, ['-O2']) +test( 'T15185' + , [collect_stats('bytes allocated', 5), only_ways(['normal'])] + , compile_and_run + , ['-O'] ) + # Test performance of creating Uniques. test('UniqLoop', [collect_stats('bytes allocated',5), View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7dc556068289dac776d1497dcb32b2d76d5e7373...8f9092daf67e55278eedfcb43ad94e019e7a3732 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7dc556068289dac776d1497dcb32b2d76d5e7373...8f9092daf67e55278eedfcb43ad94e019e7a3732 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 18 20:18:17 2020 From: gitlab at gitlab.haskell.org (Bodigrim) Date: Mon, 18 May 2020 16:18:17 -0400 Subject: [Git][ghc/ghc][wip/fromListN] Apply suggestion to libraries/base/GHC/Exts.hs Message-ID: <5ec2ed89a19df_76473f9f51cf02083192b2@gitlab.haskell.org.mail> Bodigrim pushed to branch wip/fromListN at Glasgow Haskell Compiler / GHC Commits: 47b953f7 by Bodigrim at 2020-05-18T16:17:14-04:00 Apply suggestion to libraries/base/GHC/Exts.hs - - - - - 1 changed file: - libraries/base/GHC/Exts.hs Changes: ===================================== libraries/base/GHC/Exts.hs ===================================== @@ -181,7 +181,7 @@ class IsList l where -- 'fromList'. If the given number does not equal to the input list's length -- the behaviour of 'fromListN' is not specified. -- - -- prop> fromListN (length xs) == fromList xs + -- prop> fromListN (length xs) xs == fromList xs fromListN :: Int -> [Item l] -> l fromListN _ = fromList View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/47b953f725db286ad1b90e3ceec9e5d027079c24 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/47b953f725db286ad1b90e3ceec9e5d027079c24 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 18 20:48:22 2020 From: gitlab at gitlab.haskell.org (Vilem-Benjamin Liepelt) Date: Mon, 18 May 2020 16:48:22 -0400 Subject: [Git][ghc/ghc][wip/buggymcbugfix/15185-enum-int] 3 commits: Add INLINABLE pragmas to Enum list producers Message-ID: <5ec2f496a4249_7647c0434fc3289d6@gitlab.haskell.org.mail> Vilem-Benjamin Liepelt pushed to branch wip/buggymcbugfix/15185-enum-int at Glasgow Haskell Compiler / GHC Commits: 360cf25a by buggymcbugfix at 2020-05-18T23:45:43+03:00 Add INLINABLE pragmas to Enum list producers The INLINABLE pragmas ensure that we export stable (unoptimised) unfoldings in the interface file so we can do list fusion at usage sites. Related tickets: #15185, #8763, #18178. - - - - - 00bdfb31 by buggymcbugfix at 2020-05-18T23:45:43+03:00 Piggyback on Enum Word methods for Word64 If we are on a 64 bit platform, we can use the efficient Enum Word methods for the Enum Word64 instance. - - - - - 67db811f by buggymcbugfix at 2020-05-18T23:45:43+03:00 Document INLINE(ABLE) pragmas that enable fusion - - - - - 4 changed files: - libraries/base/GHC/Enum.hs - libraries/base/GHC/Word.hs - + testsuite/tests/perf/should_run/T15185.hs - testsuite/tests/perf/should_run/all.T Changes: ===================================== libraries/base/GHC/Enum.hs ===================================== @@ -139,17 +139,34 @@ class Enum a where -- * @enumFromThenTo 6 8 2 :: [Int] = []@ enumFromThenTo :: a -> a -> a -> [a] - succ = toEnum . (+ 1) . fromEnum - pred = toEnum . (subtract 1) . fromEnum - enumFrom x = map toEnum [fromEnum x ..] - enumFromThen x y = map toEnum [fromEnum x, fromEnum y ..] - enumFromTo x y = map toEnum [fromEnum x .. fromEnum y] + succ = toEnum . (+ 1) . fromEnum + + pred = toEnum . (subtract 1) . fromEnum + + -- See Note [Stable Unfolding for list producers] + {-# INLINABLE enumFrom #-} + enumFrom x = map toEnum [fromEnum x ..] + + -- See Note [Stable Unfolding for list producers] + {-# INLINABLE enumFromThen #-} + enumFromThen x y = map toEnum [fromEnum x, fromEnum y ..] + + -- See Note [Stable Unfolding for list producers] + {-# INLINABLE enumFromTo #-} + enumFromTo x y = map toEnum [fromEnum x .. fromEnum y] + + -- See Note [Stable Unfolding for list producers] + {-# INLINABLE enumFromThenTo #-} enumFromThenTo x1 x2 y = map toEnum [fromEnum x1, fromEnum x2 .. fromEnum y] +-- See Note [Stable Unfolding for list producers] +{-# INLINABLE boundedEnumFrom #-} -- Default methods for bounded enumerations boundedEnumFrom :: (Enum a, Bounded a) => a -> [a] boundedEnumFrom n = map toEnum [fromEnum n .. fromEnum (maxBound `asTypeOf` n)] +-- See Note [Stable Unfolding for list producers] +{-# INLINABLE boundedEnumFromThen #-} boundedEnumFromThen :: (Enum a, Bounded a) => a -> a -> [a] boundedEnumFromThen n1 n2 | i_n2 >= i_n1 = map toEnum [i_n1, i_n2 .. fromEnum (maxBound `asTypeOf` n1)] @@ -158,6 +175,14 @@ boundedEnumFromThen n1 n2 i_n1 = fromEnum n1 i_n2 = fromEnum n2 +{- +Note [Stable Unfolding for list producers] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The INLINABLE/INLINE pragmas ensure that we export stable (unoptimised) +unfoldings in the interface file so we can do list fusion at usage sites. +-} + ------------------------------------------------------------------------ -- Helper functions ------------------------------------------------------------------------ @@ -343,16 +368,20 @@ instance Enum Char where toEnum = chr fromEnum = ord + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFrom #-} enumFrom (C# x) = eftChar (ord# x) 0x10FFFF# -- Blarg: technically I guess enumFrom isn't strict! + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromTo #-} enumFromTo (C# x) (C# y) = eftChar (ord# x) (ord# y) + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromThen #-} enumFromThen (C# x1) (C# x2) = efdChar (ord# x1) (ord# x2) + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromThenTo #-} enumFromThenTo (C# x1) (C# x2) (C# y) = efdtChar (ord# x1) (ord# x2) (ord# y) @@ -472,17 +501,21 @@ instance Enum Int where toEnum x = x fromEnum x = x + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFrom #-} enumFrom (I# x) = eftInt x maxInt# where !(I# maxInt#) = maxInt -- Blarg: technically I guess enumFrom isn't strict! + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromTo #-} enumFromTo (I# x) (I# y) = eftInt x y + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromThen #-} enumFromThen (I# x1) (I# x2) = efdInt x1 x2 + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromThenTo #-} enumFromThenTo (I# x1) (I# x2) (I# y) = efdtInt x1 x2 y @@ -812,13 +845,20 @@ instance Enum Integer where toEnum (I# n) = smallInteger n fromEnum n = I# (integerToInt n) + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFrom #-} + enumFrom x = enumDeltaInteger x 1 + + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromThen #-} + enumFromThen x y = enumDeltaInteger x (y-x) + + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromTo #-} + enumFromTo x lim = enumDeltaToInteger x 1 lim + + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromThenTo #-} - enumFrom x = enumDeltaInteger x 1 - enumFromThen x y = enumDeltaInteger x (y-x) - enumFromTo x lim = enumDeltaToInteger x 1 lim enumFromThenTo x y lim = enumDeltaToInteger x (y-x) lim -- See Note [How the Enum rules work] @@ -927,6 +967,7 @@ instance Enum Natural where toEnum = intToNatural #if defined(MIN_VERSION_integer_gmp) + -- This is the integer-gmp special case. The general case is after the endif. fromEnum (NatS# w) | i >= 0 = i | otherwise = errorWithoutStackTrace "fromEnum: out of Int range" @@ -936,11 +977,13 @@ instance Enum Natural where fromEnum n = fromEnum (naturalToInteger n) enumFrom x = enumDeltaNatural x (wordToNaturalBase 1##) + enumFromThen x y | x <= y = enumDeltaNatural x (y-x) | otherwise = enumNegDeltaToNatural x (x-y) (wordToNaturalBase 0##) enumFromTo x lim = enumDeltaToNatural x (wordToNaturalBase 1##) lim + enumFromThenTo x y lim | x <= y = enumDeltaToNatural x (y-x) lim | otherwise = enumNegDeltaToNatural x (x-y) lim ===================================== libraries/base/GHC/Word.hs ===================================== @@ -892,10 +892,44 @@ instance Enum Word64 where | x <= fromIntegral (maxBound::Int) = I# (word2Int# x#) | otherwise = fromEnumError "Word64" x - enumFrom = integralEnumFrom - enumFromThen = integralEnumFromThen - enumFromTo = integralEnumFromTo - enumFromThenTo = integralEnumFromThenTo + +#if WORD_SIZE_IN_BITS < 64 + enumFrom = integralEnumFrom + enumFromThen = integralEnumFromThen + enumFromTo = integralEnumFromTo + enumFromThenTo = integralEnumFromThenTo +#else + -- See Note [Stable Unfolding for list producers] in GHC.Enum + {-# INLINABLE enumFrom #-} + enumFrom w + = map wordToWord64 + $ enumFrom (word64ToWord w) + + -- See Note [Stable Unfolding for list producers] in GHC.Enum + {-# INLINABLE enumFromThen #-} + enumFromThen w s + = map wordToWord64 + $ enumFromThen (word64ToWord w) (word64ToWord s) + + -- See Note [Stable Unfolding for list producers] in GHC.Enum + {-# INLINABLE enumFromTo #-} + enumFromTo w1 w2 + = map wordToWord64 + $ enumFromTo (word64ToWord w1) (word64ToWord w2) + + -- See Note [Stable Unfolding for list producers] in GHC.Enum + {-# INLINABLE enumFromThenTo #-} + enumFromThenTo w1 s w2 + = map wordToWord64 + $ enumFromThenTo (word64ToWord w1) (word64ToWord s) (word64ToWord w2) + +word64ToWord :: Word64 -> Word +word64ToWord (W64# w#) = (W# w#) + +wordToWord64 :: Word -> Word64 +wordToWord64 (W# w#) = (W64# w#) +#endif + -- | @since 2.01 instance Integral Word64 where ===================================== testsuite/tests/perf/should_run/T15185.hs ===================================== @@ -0,0 +1,25 @@ +{-# LANGUAGE TypeApplications #-} + +-- Ensure that we do list fusion on `foldr f z [from..to]` for sized `Int` and +-- `Word` types. Related tickets: #15185, #8763. + +import Control.Exception (evaluate) +import Data.Int +import Data.Word + +fact :: Integral t => t -> t +fact n = product [1..n] + +main :: IO () +main = do + _ <- evaluate (fact @Int 50) + _ <- evaluate (fact @Int64 50) + _ <- evaluate (fact @Int32 50) + _ <- evaluate (fact @Int16 50) + _ <- evaluate (fact @Int8 50) + _ <- evaluate (fact @Word 50) + _ <- evaluate (fact @Word64 50) + _ <- evaluate (fact @Word32 50) + _ <- evaluate (fact @Word16 50) + _ <- evaluate (fact @Word8 50) + pure () ===================================== testsuite/tests/perf/should_run/all.T ===================================== @@ -367,6 +367,11 @@ test('T15578', compile_and_run, ['-O2']) +test('T15185', + [collect_stats('bytes allocated', 5), only_ways(['normal'])], + compile_and_run, + ['-O']) + # Test performance of creating Uniques. test('UniqLoop', [collect_stats('bytes allocated',5), View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8f9092daf67e55278eedfcb43ad94e019e7a3732...67db811fc336391d7b15f571e86442095d5cc6d4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8f9092daf67e55278eedfcb43ad94e019e7a3732...67db811fc336391d7b15f571e86442095d5cc6d4 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 18 21:51:03 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Mon, 18 May 2020 17:51:03 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 8 commits: nonmoving: Optimise the write barrier Message-ID: <5ec30347f2d78_764711d44a483374e3@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 5437aaf2 by Ben Gamari at 2020-05-18T17:49:08-04:00 nonmoving: Optimise the write barrier - - - - - 91b7a6cf by Richard Eisenberg at 2020-05-18T17:49:09-04:00 MR template should ask for key part - - - - - 33f49ba2 by Sebastian Graf at 2020-05-18T17:49:09-04:00 Make `Int`'s `mod` and `rem` strict in their first arguments They used to be strict until 4d2ac2d (9 years ago). It's obviously better to be strict for performance reasons. It also blocks #18067. NoFib results: ``` -------------------------------------------------------------------------------- Program Allocs Instrs -------------------------------------------------------------------------------- integer -1.1% +0.4% wheel-sieve2 +21.2% +20.7% -------------------------------------------------------------------------------- Min -1.1% -0.0% Max +21.2% +20.7% Geometric Mean +0.2% +0.2% ``` The regression in `wheel-sieve2` is due to reboxing that likely will go away with the resolution of #18067. See !3282 for details. Fixes #18187. - - - - - de20432d by Ryan Scott at 2020-05-18T17:49:10-04:00 Add orderingTyCon to wiredInTyCons (#18185) `Ordering` needs to be wired in for use in the built-in `CmpNat` and `CmpSymbol` type families, but somehow it was never added to the list of `wiredInTyCons`, leading to the various oddities observed in #18185. Easily fixed by moving `orderingTyCon` from `basicKnownKeyNames` to `wiredInTyCons`. Fixes #18185. - - - - - ff4e12df by Galen Huntington at 2020-05-18T17:49:12-04:00 Clarify pitfalls of NegativeLiterals; see #18022. - - - - - c1e6bf91 by Alexey Kuleshevich at 2020-05-18T17:49:17-04:00 Fix wording in primops documentation to reflect the correct reasoning: * Besides resizing functions, shrinking ones also mutate the size of a mutable array and because of those two `sizeofMutabeByteArray` and `sizeofSmallMutableArray` are now deprecated * Change reference in documentation to the newer functions `getSizeof*` instead of `sizeof*` for shrinking functions * Fix incorrect mention of "byte" instead of "small" - - - - - cded819e by Andreas Klebinger at 2020-05-18T17:49:17-04:00 Don't variable-length encode magic iface constant. We changed to use variable length encodings for many types by default, including Word32. This makes sense for numbers but not when Word32 is meant to represent four bytes. I added a FixedLengthEncoding newtype to Binary who's instances interpret their argument as a collection of bytes instead of a number. We then use this when writing/reading magic numbers to the iface file. I also took the libery to remove the dummy iface field. This fixes #18180. - - - - - 480e69ca by Krzysztof Gogolewski at 2020-05-18T17:49:18-04:00 Add a regression test for #11506 The testcase works now. See explanation in https://gitlab.haskell.org/ghc/ghc/issues/11506#note_273202 - - - - - 12 changed files: - .gitlab/merge_request_templates/merge-request.md - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Iface/Binary.hs - compiler/GHC/Utils/Binary.hs - docs/users_guide/exts/negative_literals.rst - libraries/base/GHC/Real.hs - rts/Updates.h - + testsuite/tests/typecheck/should_compile/T11506.hs - + testsuite/tests/typecheck/should_compile/T18185.hs - testsuite/tests/typecheck/should_compile/all.T Changes: ===================================== .gitlab/merge_request_templates/merge-request.md ===================================== @@ -1,5 +1,10 @@ Thank you for your contribution to GHC! +**Please read the checklist below to make sure your contribution fulfills these +expectations. Also please answer the following question in your MR description:** + +**Where is the key part of this patch? That is, what should reviewers look at first?** + Please take a few moments to verify that your commits fulfill the following: * [ ] are either individually buildable or squashed @@ -10,7 +15,7 @@ Please take a few moments to verify that your commits fulfill the following: likely should add a [Note][notes] and cross-reference it from the relevant places. * [ ] add a [testcase to the testsuite](https://gitlab.haskell.org/ghc/ghc/wikis/building/running-tests/adding). - * [ ] if your MR affects library interfaces (e.g. changes `base`) please add + * [ ] if your MR affects library interfaces (e.g. changes `base`) or affects whether GHC will accept user-written code, please add the ~"user facing" label. * [ ] updates the users guide if applicable * [ ] mentions new features in the release notes for the next release ===================================== compiler/GHC/Builtin/Names.hs ===================================== @@ -428,10 +428,6 @@ basicKnownKeyNames -- Annotation type checking toAnnotationWrapperName - -- The Ordering type - , orderingTyConName - , ordLTDataConName, ordEQDataConName, ordGTDataConName - -- The SPEC type for SpecConstr , specTyConName ===================================== compiler/GHC/Builtin/Types.hs ===================================== @@ -202,8 +202,11 @@ names in GHC.Builtin.Names, so they use wTcQual, wDataQual, etc -- that occurs in this list that name will be assigned the wired-in key we -- define here. -- --- Because of their infinite nature, this list excludes tuples, Any and implicit --- parameter TyCons (see Note [Built-in syntax and the OrigNameCache]). +-- Because of their infinite nature, this list excludes +-- * tuples, including boxed, unboxed and constraint tuples +--- (mkTupleTyCon, unitTyCon, pairTyCon) +-- * unboxed sums (sumTyCon) +-- See Note [Infinite families of known-key names] in GHC.Builtin.Names -- -- See also Note [Known-key names] wiredInTyCons :: [TyCon] @@ -224,6 +227,7 @@ wiredInTyCons = [ -- Units are not treated like other tuples, because they , wordTyCon , word8TyCon , listTyCon + , orderingTyCon , maybeTyCon , heqTyCon , eqTyCon ===================================== compiler/GHC/Builtin/primops.txt.pp ===================================== @@ -1254,7 +1254,7 @@ primop ShrinkSmallMutableArrayOp_Char "shrinkSmallMutableArray#" GenPrimOp SmallMutableArray# s a -> Int# -> State# s -> State# s {Shrink mutable array to new specified size, in the specified state thread. The new size argument must be less than or - equal to the current size as reported by {\tt sizeofSmallMutableArray\#}.} + equal to the current size as reported by {\tt getSizeofSmallMutableArray\#}.} with out_of_line = True has_side_effects = True @@ -1279,8 +1279,8 @@ primop SizeofSmallArrayOp "sizeofSmallArray#" GenPrimOp primop SizeofSmallMutableArrayOp "sizeofSmallMutableArray#" GenPrimOp SmallMutableArray# s a -> Int# {Return the number of elements in the array. Note that this is deprecated - as it is unsafe in the presence of resize operations on the - same byte array.} + as it is unsafe in the presence of shrink and resize operations on the + same small mutable array.} with deprecated_msg = { Use 'getSizeofSmallMutableArray#' instead } primop GetSizeofSmallMutableArrayOp "getSizeofSmallMutableArray#" GenPrimOp @@ -1451,7 +1451,7 @@ primop ShrinkMutableByteArrayOp_Char "shrinkMutableByteArray#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> State# s {Shrink mutable byte array to new specified size (in bytes), in the specified state thread. The new size argument must be less than or - equal to the current size as reported by {\tt sizeofMutableByteArray\#}.} + equal to the current size as reported by {\tt getSizeofMutableByteArray\#}.} with out_of_line = True has_side_effects = True @@ -1484,7 +1484,7 @@ primop SizeofByteArrayOp "sizeofByteArray#" GenPrimOp primop SizeofMutableByteArrayOp "sizeofMutableByteArray#" GenPrimOp MutableByteArray# s -> Int# {Return the size of the array in bytes. Note that this is deprecated as it is - unsafe in the presence of resize operations on the same byte + unsafe in the presence of shrink and resize operations on the same mutable byte array.} with deprecated_msg = { Use 'getSizeofMutableByteArray#' instead } ===================================== compiler/GHC/Iface/Binary.hs ===================================== @@ -123,20 +123,9 @@ readBinIface_ dflags checkHiWay traceBinIFaceReading hi_path ncu = do -- (This magic number does not change when we change -- GHC interface file format) magic <- get bh - wantedGot "Magic" (binaryInterfaceMagic platform) magic ppr + wantedGot "Magic" (binaryInterfaceMagic platform) magic (ppr . unFixedLength) errorOnMismatch "magic number mismatch: old/corrupt interface file?" - (binaryInterfaceMagic platform) magic - - -- Note [dummy iface field] - -- read a dummy 32/64 bit value. This field used to hold the - -- dictionary pointer in old interface file formats, but now - -- the dictionary pointer is after the version (where it - -- should be). Also, the serialisation of value of type "Bin - -- a" used to depend on the word size of the machine, now they - -- are always 32 bits. - case platformWordSize platform of - PW4 -> do _ <- Binary.get bh :: IO Word32; return () - PW8 -> do _ <- Binary.get bh :: IO Word64; return () + (unFixedLength $ binaryInterfaceMagic platform) (unFixedLength magic) -- Check the interface file version and ways. check_ver <- get bh @@ -198,13 +187,6 @@ writeBinIface dflags hi_path mod_iface = do let platform = targetPlatform dflags put_ bh (binaryInterfaceMagic platform) - -- dummy 32/64-bit field before the version/way for - -- compatibility with older interface file formats. - -- See Note [dummy iface field] above. - case platformWordSize platform of - PW4 -> Binary.put_ bh (0 :: Word32) - PW8 -> Binary.put_ bh (0 :: Word64) - -- The version and way descriptor go next put_ bh (show hiVersion) let way_descr = getWayDescr dflags @@ -290,10 +272,10 @@ putWithUserData log_action bh payload = do initBinMemSize :: Int initBinMemSize = 1024 * 1024 -binaryInterfaceMagic :: Platform -> Word32 +binaryInterfaceMagic :: Platform -> FixedLengthEncoding Word32 binaryInterfaceMagic platform - | target32Bit platform = 0x1face - | otherwise = 0x1face64 + | target32Bit platform = FixedLengthEncoding 0x1face + | otherwise = FixedLengthEncoding 0x1face64 -- ----------------------------------------------------------------------------- ===================================== compiler/GHC/Utils/Binary.hs ===================================== @@ -52,6 +52,9 @@ module GHC.Utils.Binary putSLEB128, getSLEB128, + -- * Fixed length encoding + FixedLengthEncoding(..), + -- * Lazy Binary I/O lazyGet, lazyPut, @@ -314,18 +317,18 @@ putWord8 h !w = putPrim h 1 (\op -> poke op w) getWord8 :: BinHandle -> IO Word8 getWord8 h = getPrim h 1 peek --- putWord16 :: BinHandle -> Word16 -> IO () --- putWord16 h w = putPrim h 2 (\op -> do --- pokeElemOff op 0 (fromIntegral (w `shiftR` 8)) --- pokeElemOff op 1 (fromIntegral (w .&. 0xFF)) --- ) +putWord16 :: BinHandle -> Word16 -> IO () +putWord16 h w = putPrim h 2 (\op -> do + pokeElemOff op 0 (fromIntegral (w `shiftR` 8)) + pokeElemOff op 1 (fromIntegral (w .&. 0xFF)) + ) --- getWord16 :: BinHandle -> IO Word16 --- getWord16 h = getPrim h 2 (\op -> do --- w0 <- fromIntegral <$> peekElemOff op 0 --- w1 <- fromIntegral <$> peekElemOff op 1 --- return $! w0 `shiftL` 8 .|. w1 --- ) +getWord16 :: BinHandle -> IO Word16 +getWord16 h = getPrim h 2 (\op -> do + w0 <- fromIntegral <$> peekElemOff op 0 + w1 <- fromIntegral <$> peekElemOff op 1 + return $! w0 `shiftL` 8 .|. w1 + ) putWord32 :: BinHandle -> Word32 -> IO () putWord32 h w = putPrim h 4 (\op -> do @@ -348,38 +351,38 @@ getWord32 h = getPrim h 4 (\op -> do w3 ) --- putWord64 :: BinHandle -> Word64 -> IO () --- putWord64 h w = putPrim h 8 (\op -> do --- pokeElemOff op 0 (fromIntegral (w `shiftR` 56)) --- pokeElemOff op 1 (fromIntegral ((w `shiftR` 48) .&. 0xFF)) --- pokeElemOff op 2 (fromIntegral ((w `shiftR` 40) .&. 0xFF)) --- pokeElemOff op 3 (fromIntegral ((w `shiftR` 32) .&. 0xFF)) --- pokeElemOff op 4 (fromIntegral ((w `shiftR` 24) .&. 0xFF)) --- pokeElemOff op 5 (fromIntegral ((w `shiftR` 16) .&. 0xFF)) --- pokeElemOff op 6 (fromIntegral ((w `shiftR` 8) .&. 0xFF)) --- pokeElemOff op 7 (fromIntegral (w .&. 0xFF)) --- ) - --- getWord64 :: BinHandle -> IO Word64 --- getWord64 h = getPrim h 8 (\op -> do --- w0 <- fromIntegral <$> peekElemOff op 0 --- w1 <- fromIntegral <$> peekElemOff op 1 --- w2 <- fromIntegral <$> peekElemOff op 2 --- w3 <- fromIntegral <$> peekElemOff op 3 --- w4 <- fromIntegral <$> peekElemOff op 4 --- w5 <- fromIntegral <$> peekElemOff op 5 --- w6 <- fromIntegral <$> peekElemOff op 6 --- w7 <- fromIntegral <$> peekElemOff op 7 - --- return $! (w0 `shiftL` 56) .|. --- (w1 `shiftL` 48) .|. --- (w2 `shiftL` 40) .|. --- (w3 `shiftL` 32) .|. --- (w4 `shiftL` 24) .|. --- (w5 `shiftL` 16) .|. --- (w6 `shiftL` 8) .|. --- w7 --- ) +putWord64 :: BinHandle -> Word64 -> IO () +putWord64 h w = putPrim h 8 (\op -> do + pokeElemOff op 0 (fromIntegral (w `shiftR` 56)) + pokeElemOff op 1 (fromIntegral ((w `shiftR` 48) .&. 0xFF)) + pokeElemOff op 2 (fromIntegral ((w `shiftR` 40) .&. 0xFF)) + pokeElemOff op 3 (fromIntegral ((w `shiftR` 32) .&. 0xFF)) + pokeElemOff op 4 (fromIntegral ((w `shiftR` 24) .&. 0xFF)) + pokeElemOff op 5 (fromIntegral ((w `shiftR` 16) .&. 0xFF)) + pokeElemOff op 6 (fromIntegral ((w `shiftR` 8) .&. 0xFF)) + pokeElemOff op 7 (fromIntegral (w .&. 0xFF)) + ) + +getWord64 :: BinHandle -> IO Word64 +getWord64 h = getPrim h 8 (\op -> do + w0 <- fromIntegral <$> peekElemOff op 0 + w1 <- fromIntegral <$> peekElemOff op 1 + w2 <- fromIntegral <$> peekElemOff op 2 + w3 <- fromIntegral <$> peekElemOff op 3 + w4 <- fromIntegral <$> peekElemOff op 4 + w5 <- fromIntegral <$> peekElemOff op 5 + w6 <- fromIntegral <$> peekElemOff op 6 + w7 <- fromIntegral <$> peekElemOff op 7 + + return $! (w0 `shiftL` 56) .|. + (w1 `shiftL` 48) .|. + (w2 `shiftL` 40) .|. + (w3 `shiftL` 32) .|. + (w4 `shiftL` 24) .|. + (w5 `shiftL` 16) .|. + (w6 `shiftL` 8) .|. + w7 + ) putByte :: BinHandle -> Word8 -> IO () putByte bh !w = putWord8 bh w @@ -512,6 +515,35 @@ getSLEB128 bh = do let !signed = testBit byte 6 return (val',shift',signed) +-- ----------------------------------------------------------------------------- +-- Fixed length encoding instances + +-- Sometimes words are used to represent a certain bit pattern instead +-- of a number. Using FixedLengthEncoding we will write the pattern as +-- is to the interface file without the variable length encoding we usually +-- apply. + +-- | Encode the argument in it's full length. This is different from many default +-- binary instances which make no guarantee about the actual encoding and +-- might do things use variable length encoding. +newtype FixedLengthEncoding a = FixedLengthEncoding { unFixedLength :: a } + +instance Binary (FixedLengthEncoding Word8) where + put_ h (FixedLengthEncoding x) = putByte h x + get h = FixedLengthEncoding <$> getByte h + +instance Binary (FixedLengthEncoding Word16) where + put_ h (FixedLengthEncoding x) = putWord16 h x + get h = FixedLengthEncoding <$> getWord16 h + +instance Binary (FixedLengthEncoding Word32) where + put_ h (FixedLengthEncoding x) = putWord32 h x + get h = FixedLengthEncoding <$> getWord32 h + +instance Binary (FixedLengthEncoding Word64) where + put_ h (FixedLengthEncoding x) = putWord64 h x + get h = FixedLengthEncoding <$> getWord64 h + -- ----------------------------------------------------------------------------- -- Primitive Word writes ===================================== docs/users_guide/exts/negative_literals.rst ===================================== @@ -8,16 +8,24 @@ Negative literals :since: 7.8.1 - Enable the use of un-parenthesized negative numeric literals. + Enable negative numeric literals. The literal ``-123`` is, according to Haskell98 and Haskell 2010, +two tokens, a unary minus (``-``) and the number 123, and is desugared as ``negate (fromInteger 123)``. The language extension -:extension:`NegativeLiterals` means that it is instead desugared as -``fromInteger (-123)``. +:extension:`NegativeLiterals` causes it to be treated as a single +token and desugared as ``fromInteger (-123)``. -This can make a difference when the positive and negative range of a -numeric data type don't match up. For example, in 8-bit arithmetic -128 -is representable, but +128 is not. So ``negate (fromInteger 128)`` will -elicit an unexpected integer-literal-overflow message. +This can be useful when the positive and negative range of a numeric +data type don't match up. For example, in 8-bit arithmetic -128 +is representable, but +128 is not. So ``negate (fromInteger 128)`` +will elicit an unexpected integer-literal-overflow message. +Whitespace can be inserted, as in ``- 123``, to force interpretation +as two tokens. + +One pitfall is that with :extension:`NegativeLiterals`, ``x-1`` will +be parsed as ``x`` applied to the argument ``-1``, which is usually +not what you want. ``x - 1`` or even ``x- 1`` can be used instead +for subtraction. ===================================== libraries/base/GHC/Real.hs ===================================== @@ -334,11 +334,8 @@ instance Integral Int where -- in GHC.Int | otherwise = a `quotInt` b - a `rem` b + !a `rem` b -- See Note [Special case of mod and rem is lazy] | b == 0 = divZeroError - -- The quotRem CPU instruction fails for minBound `quotRem` -1, - -- but minBound `rem` -1 is well-defined (0). We therefore - -- special-case it. | b == (-1) = 0 | otherwise = a `remInt` b @@ -348,11 +345,8 @@ instance Integral Int where -- in GHC.Int | otherwise = a `divInt` b - a `mod` b + !a `mod` b -- See Note [Special case of mod and rem is lazy] | b == 0 = divZeroError - -- The divMod CPU instruction fails for minBound `divMod` -1, - -- but minBound `mod` -1 is well-defined (0). We therefore - -- special-case it. | b == (-1) = 0 | otherwise = a `modInt` b @@ -368,6 +362,15 @@ instance Integral Int where | b == (-1) && a == minBound = (overflowError, 0) | otherwise = a `divModInt` b +{- Note [Special case of mod and rem is lazy] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The `quotRem`/`divMod` CPU instruction fails for minBound `quotRem` -1, but +minBound `rem` -1 is well-defined (0). We therefore special-case for `b == -1`, +but not for `a == minBound` because of Note [Order of tests] in GHC.Int. But +now we have to make sure the function stays strict in a, to guarantee unboxing. +Hence the bang on a, see #18187. +-} + -------------------------------------------------------------- -- Instances for @Word@ -------------------------------------------------------------- ===================================== rts/Updates.h ===================================== @@ -50,22 +50,21 @@ \ prim_write_barrier; \ OVERWRITING_CLOSURE(p1); \ - IF_NONMOVING_WRITE_BARRIER_ENABLED { \ - ccall updateRemembSetPushThunk_(BaseReg, p1 "ptr"); \ - } \ - StgInd_indirectee(p1) = p2; \ - prim_write_barrier; \ - SET_INFO(p1, stg_BLACKHOLE_info); \ - LDV_RECORD_CREATE(p1); \ bd = Bdescr(p1); \ if (bdescr_gen_no(bd) != 0 :: bits16) { \ + IF_NONMOVING_WRITE_BARRIER_ENABLED { \ + ccall updateRemembSetPushThunk_(BaseReg, p1 "ptr"); \ + } \ recordMutableCap(p1, TO_W_(bdescr_gen_no(bd))); \ TICK_UPD_OLD_IND(); \ - and_then; \ } else { \ TICK_UPD_NEW_IND(); \ - and_then; \ - } + } \ + StgInd_indirectee(p1) = p2; \ + prim_write_barrier; \ + SET_INFO(p1, stg_BLACKHOLE_info); \ + LDV_RECORD_CREATE(p1); \ + and_then; #else /* !CMINUSMINUS */ @@ -73,28 +72,26 @@ INLINE_HEADER void updateWithIndirection (Capability *cap, StgClosure *p1, StgClosure *p2) { - bdescr *bd; - ASSERT( (P_)p1 != (P_)p2 ); /* not necessarily true: ASSERT( !closure_IND(p1) ); */ /* occurs in RaiseAsync.c:raiseAsync() */ /* See Note [Heap memory barriers] in SMP.h */ write_barrier(); - OVERWRITING_CLOSURE(p1); - IF_NONMOVING_WRITE_BARRIER_ENABLED { - updateRemembSetPushThunk(cap, (StgThunk*)p1); - } - ((StgInd *)p1)->indirectee = p2; - write_barrier(); - SET_INFO(p1, &stg_BLACKHOLE_info); - LDV_RECORD_CREATE(p1); - bd = Bdescr((StgPtr)p1); + bdescr *bd = Bdescr((StgPtr)p1); if (bd->gen_no != 0) { + IF_NONMOVING_WRITE_BARRIER_ENABLED { + updateRemembSetPushThunk(cap, (StgThunk*)p1); + } recordMutableCap(p1, cap, bd->gen_no); TICK_UPD_OLD_IND(); } else { TICK_UPD_NEW_IND(); } + OVERWRITING_CLOSURE(p1); + ((StgInd *)p1)->indirectee = p2; + write_barrier(); + SET_INFO(p1, &stg_BLACKHOLE_info); + LDV_RECORD_CREATE(p1); } #endif /* CMINUSMINUS */ ===================================== testsuite/tests/typecheck/should_compile/T11506.hs ===================================== @@ -0,0 +1,13 @@ +{-# LANGUAGE PolyKinds, ExistentialQuantification, ScopedTypeVariables, + TypeFamilies, TypeInType #-} + +module T11506 where + +import Data.Proxy +import Data.Kind + +type family ProxyType where ProxyType = (Proxy :: Type -> Type) + +data T = forall a. MkT (ProxyType a) + +foo (MkT (_ :: Proxy a)) = const True (undefined :: a) ===================================== testsuite/tests/typecheck/should_compile/T18185.hs ===================================== @@ -0,0 +1,31 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeOperators #-} +module T18185 where + +import GHC.TypeLits +import Type.Reflection + +class iss :|+ is ~ oss => AddT (iss :: [Symbol]) (is :: Symbol) (oss :: [Symbol]) where + type iss :|+ is :: [Symbol] + +class (CmpSymbol is ish ~ ord, AddT'I ord is ish ist ~ oss) => AddT' ord is ish ist oss where + type AddT'I ord is ish ist :: [Symbol] + +class (CmpSymbol "a" "a" ~ o) => C1 o +class (CmpNat 1 1 ~ o) => C2 o +class ((CmpSymbol "a" "a" :: Ordering) ~ o) => C3 o +class ((CmpNat 1 1 :: Ordering) ~ o) => C4 o + +f1 :: TypeRep (CmpSymbol "a" "a") +f1 = typeRep + +f2 :: TypeRep (CmpNat 1 1) +f2 = typeRep + +f3 :: TypeRep (CmpSymbol "a" "a" :: Ordering) +f3 = typeRep + +f4 :: TypeRep (CmpNat 1 1 :: Ordering) +f4 = typeRep ===================================== testsuite/tests/typecheck/should_compile/all.T ===================================== @@ -497,6 +497,7 @@ test('RebindNegate', normal, compile, ['']) test('T11319', normal, compile, ['']) test('T11397', normal, compile, ['']) test('T11458', normal, compile, ['']) +test('T11506', normal, compile, ['']) test('T11524', normal, compile, ['']) test('T11552', normal, compile, ['']) test('T11246', normal, compile, ['']) @@ -707,3 +708,4 @@ test('T18036', normal, compile, ['']) test('T18036a', normal, compile, ['']) test('T17873', normal, compile, ['']) test('T18129', expect_broken(18129), compile, ['']) +test('T18185', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5dd21f0d87aa00f21dba0401ddb7989c8af486cd...480e69ca83f73b299a8cb2e42d7e0e9f15b9806d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5dd21f0d87aa00f21dba0401ddb7989c8af486cd...480e69ca83f73b299a8cb2e42d7e0e9f15b9806d You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Mon May 18 21:55:28 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 18 May 2020 17:55:28 -0400 Subject: [Git][ghc/ghc][wip/T17775] 48 commits: Remove further dead code found by a simple Python script. Message-ID: <5ec3045017806_76473f9f637124b43393a4@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: 6f6d72b2 by Brian Foley at 2020-05-08T15:29:25-04:00 Remove further dead code found by a simple Python script. Avoid removing some functions that are part of an API even though they're not used in-tree at the moment. - - - - - 78bf8bf9 by Julien Debon at 2020-05-08T15:29:28-04:00 Add doc examples for Bifoldable See #17929 - - - - - 66f0a847 by Julien Debon at 2020-05-08T15:29:29-04:00 doc (Bitraversable): Add examples to Bitraversable * Add examples to Data.Bitraversable * Fix formatting for (,) in Bitraversable and Bifoldable * Fix mistake on bimapAccumR documentation See #17929 - - - - - 9749fe12 by Baldur Blöndal at 2020-05-08T15:29:32-04:00 Specify kind variables for inferred kinds in base. - - - - - 4e9aef9e by John Ericson at 2020-05-08T15:29:36-04:00 HsSigWcTypeScoping: Pull in documentation from stray location - - - - - f4d5c6df by John Ericson at 2020-05-08T15:29:36-04:00 Rename local `real_fvs` to `implicit_vs` It doesn't make sense to call the "free" variables we are about to implicitly bind the real ones. - - - - - 20570b4b by John Ericson at 2020-05-08T15:29:36-04:00 A few tiny style nits with renaming - Use case rather than guards that repeatedly scrutenize same thing. - No need for view pattern when `L` is fine. - Use type synnonym to convey the intent like elsewhere. - - - - - 09ac8de5 by John Ericson at 2020-05-08T15:29:36-04:00 Add `forAllOrNothing` function with note - - - - - bb35c0e5 by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Document lawlessness of Ap's Num instance - - - - - cdd229ff by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply suggestion to libraries/base/Data/Monoid.hs - - - - - 926d2aab by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply more suggestions from Simon Jakobi - - - - - 7a763cff by Adam Gundry at 2020-05-08T15:29:41-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. - - - - - 88e3c815 by Simon Peyton Jones at 2020-05-08T15:29:41-04:00 Fix specialisation for DFuns When specialising a DFun we must take care to saturate the unfolding. See Note [Specialising DFuns] in Specialise. Fixes #18120 - - - - - 86c77b36 by Greg Steuck at 2020-05-08T15:29:45-04:00 Remove unused SEGMENT_PROT_RWX It's been unused for a year and is problematic on any OS which requires W^X for security. - - - - - 9d97f4b5 by nineonine at 2020-05-08T15:30:03-04:00 Add test for #16167 - - - - - aa318338 by Ryan Scott at 2020-05-08T15:30:04-04:00 Bump exceptions submodule so that dist-boot is .gitignore'd `exceptions` is a stage-0 boot library as of commit 30272412fa437ab8e7a8035db94a278e10513413, which means that building `exceptions` in a GHC tree will generate a `dist-boot` directory. However, this directory was not specified in `exceptions`' `.gitignore` file, which causes it to dirty up the current `git` working directory. Accordingly, this bumps the `exceptions` submodule to commit ghc/packages/exceptions at 23c0b8a50d7592af37ca09beeec16b93080df98f, which adds `dist-boot` to the `.gitignore` file. - - - - - ea86360f by Ömer Sinan Ağacan at 2020-05-08T15:30:30-04:00 Linker.c: initialize n_symbols of ObjectCode with other fields - - - - - 951c1fb0 by Sylvain Henry at 2020-05-09T21:46:38-04:00 Fix unboxed-sums GC ptr-slot rubbish value (#17791) This patch allows boot libraries to use unboxed sums without implicitly depending on `base` package because of `absentSumFieldError`. See updated Note [aBSENT_SUM_FIELD_ERROR_ID] in GHC.Core.Make - - - - - b352d63c by Ben Gamari at 2020-05-09T21:47:14-04:00 rts: Make non-existent linker search path merely a warning As noted in #18105, previously this resulted in a rather intrusive error message. This is in contrast to the general expectation that search paths are merely places to look, not places that must exist. Fixes #18105. - - - - - cf4f1e2f by Ben Gamari at 2020-05-13T02:02:33-04:00 rts/CNF: Fix fixup comparison function Previously we would implicitly convert the difference between two words to an int, resulting in an integer overflow on 64-bit machines. Fixes #16992 - - - - - a03da9bf by Ömer Sinan Ağacan at 2020-05-13T02:03:16-04:00 Pack some of IdInfo fields into a bit field This reduces residency of compiler quite a bit on some programs. Example stats when building T10370: Before: 2,871,242,832 bytes allocated in the heap 4,693,328,008 bytes copied during GC 33,941,448 bytes maximum residency (276 sample(s)) 375,976 bytes maximum slop 83 MiB total memory in use (0 MB lost due to fragmentation) After: 2,858,897,344 bytes allocated in the heap 4,629,255,440 bytes copied during GC 32,616,624 bytes maximum residency (278 sample(s)) 314,400 bytes maximum slop 80 MiB total memory in use (0 MB lost due to fragmentation) So -3.9% residency, -1.3% bytes copied and -0.4% allocations. Fixes #17497 Metric Decrease: T9233 T9675 - - - - - 670c3e5c by Ben Gamari at 2020-05-13T02:03:54-04:00 get-win32-tarballs: Fix base URL Revert a change previously made for testing purposes. - - - - - 8ad8dc41 by Ben Gamari at 2020-05-13T02:03:54-04:00 get-win32-tarballs: Improve diagnostics output - - - - - 8c0740b7 by Simon Jakobi at 2020-05-13T02:04:33-04:00 docs: Add examples for Data.Semigroup.Arg{Min,Max} Context: #17153 - - - - - cb22348f by Ben Gamari at 2020-05-13T02:05:11-04:00 Add few cleanups of the CAF logic Give the NameSet of non-CAFfy names a proper newtype to distinguish it from all of the other NameSets floating about. - - - - - 90e38b81 by Emeka Nkurumeh at 2020-05-13T02:05:51-04:00 fix printf warning when using with ghc with clang on mingw - - - - - 86d8ac22 by Sebastian Graf at 2020-05-13T02:06:29-04:00 CprAnal: Don't attach CPR sigs to expandable bindings (#18154) Instead, look through expandable unfoldings in `cprTransform`. See the new Note [CPR for expandable unfoldings]: ``` Long static data structures (whether top-level or not) like xs = x1 : xs1 xs1 = x2 : xs2 xs2 = x3 : xs3 should not get CPR signatures, because they * Never get WW'd, so their CPR signature should be irrelevant after analysis (in fact the signature might even be harmful for that reason) * Would need to be inlined/expanded to see their constructed product * Recording CPR on them blows up interface file sizes and is redundant with their unfolding. In case of Nested CPR, this blow-up can be quadratic! But we can't just stop giving DataCon application bindings the CPR property, for example fac 0 = 1 fac n = n * fac (n-1) fac certainly has the CPR property and should be WW'd! But FloatOut will transform the first clause to lvl = 1 fac 0 = lvl If lvl doesn't have the CPR property, fac won't either. But lvl doesn't have a CPR signature to extrapolate into a CPR transformer ('cprTransform'). So instead we keep on cprAnal'ing through *expandable* unfoldings for these arity 0 bindings via 'cprExpandUnfolding_maybe'. In practice, GHC generates a lot of (nested) TyCon and KindRep bindings, one for each data declaration. It's wasteful to attach CPR signatures to each of them (and intractable in case of Nested CPR). ``` Fixes #18154. - - - - - e34bf656 by Ben Gamari at 2020-05-13T02:07:08-04:00 users-guide: Add discussion of shared object naming Fixes #18074. - - - - - 5d0f2445 by Ben Gamari at 2020-05-13T02:07:47-04:00 testsuite: Print sign of performance changes Executes the minor formatting change in the tabulated performance changes suggested in #18135. - - - - - 9e4b981f by Ben Gamari at 2020-05-13T02:08:24-04:00 testsuite: Add testcase for #18129 - - - - - 266310c3 by Ivan-Yudin at 2020-05-13T02:09:03-04:00 doc: Reformulate the opening paragraph of Ch. 4 in User's guide Removes mentioning of Hugs (it is not helpful for new users anymore). Changes the wording for the rest of the paragraph. Fixes #18132. - - - - - 55e35c0b by Baldur Blöndal at 2020-05-13T20:02:48-04:00 Predicate, Equivalence derive via `.. -> a -> All' - - - - - d7e0b57f by Alp Mestanogullari at 2020-05-13T20:03:30-04:00 hadrian: add a --freeze2 option to freeze stage 1 and 2 - - - - - d880d6b2 by Artem Pelenitsyn at 2020-05-13T20:04:11-04:00 Don't reload environment files on every setSessionDynFlags Makes `interpretPackageEnv` (which loads envirinment files) a part of `parseDynamicFlags` (parsing command-line arguments, which is typically done once) instead of `setSessionDynFlags` (which is typically called several times). Making several (transitive) calls to `interpretPackageEnv`, as before, caused #18125 #16318, which should be fixed now. - - - - - 102cfd67 by Ryan Scott at 2020-05-13T20:04:46-04:00 Factor out HsPatSigType for pat sigs/RULE term sigs (#16762) This implements chunks (2) and (3) of https://gitlab.haskell.org/ghc/ghc/issues/16762#note_270170. Namely, it introduces a dedicated `HsPatSigType` AST type, which represents the types that can appear in pattern signatures and term-level `RULE` binders. Previously, these were represented with `LHsSigWcType`. Although `LHsSigWcType` is isomorphic to `HsPatSigType`, the intended semantics of the two types are slightly different, as evidenced by the fact that they have different code paths in the renamer and typechecker. See also the new `Note [Pattern signature binders and scoping]` in `GHC.Hs.Types`. - - - - - b17574f7 by Hécate at 2020-05-13T20:05:28-04:00 fix(documentation): Fix the RST links to GHC.Prim - - - - - df021fb1 by Baldur Blöndal at 2020-05-13T20:06:06-04:00 Document (->) using inferred quantification for its runtime representations. Fixes #18142. - - - - - 1a93ea57 by Takenobu Tani at 2020-05-13T20:06:54-04:00 Tweak man page for ghc command This commit updates the ghc command's man page as followings: * Enable `man_show_urls` to show URL addresses in the `DESCRIPTION` section of ghc.rst, because sphinx currently removes hyperlinks for man pages. * Add a `SEE ALSO` section to point to the GHC homepage - - - - - a951e1ba by Takenobu Tani at 2020-05-13T20:07:37-04:00 GHCi: Add link to the user's guide in help message This commit adds a link to the user's guide in ghci's `:help` message. Newcomers could easily reach to details of ghci. - - - - - 404581ea by Jeff Happily at 2020-05-13T20:08:15-04:00 Handle single unused import - - - - - 1c999e5d by Ben Gamari at 2020-05-13T20:09:07-04:00 Ensure that printMinimalImports closes handle Fixes #18166. - - - - - c9f5a8f4 by Ben Gamari at 2020-05-13T20:09:51-04:00 hadrian: Tell testsuite driver about LLVM availability This reflects the logic present in the Make build system into Hadrian. Fixes #18167. - - - - - c05c0659 by Simon Jakobi at 2020-05-14T03:31:21-04:00 Improve some folds over Uniq[D]FM * Replace some non-deterministic lazy folds with strict folds. * Replace some O(n log n) folds in deterministic order with O(n) non-deterministic folds. * Replace some folds with set-operations on the underlying IntMaps. This reduces max residency when compiling `nofib/spectral/simple/Main.hs` with -O0 by about 1%. Maximum residency when compiling Cabal also seems reduced on the order of 3-9%. - - - - - 477f13bb by Simon Jakobi at 2020-05-14T03:31:58-04:00 Use Data.IntMap.disjoint Data.IntMap gained a dedicated `disjoint` function in containers-0.6.2.1. This patch applies this function where appropriate in hopes of modest compiler performance improvements. Closes #16806. - - - - - e9c0110c by Ben Gamari at 2020-05-14T12:25:53-04:00 IdInfo: Add reference to bitfield-packing ticket - - - - - 9bd20e83 by Sebastian Graf at 2020-05-15T10:42:09-04:00 DmdAnal: Improve handling of precise exceptions This patch does two things: Fix possible unsoundness in what was called the "IO hack" and implement part 2.1 of the "fixing precise exceptions" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions, which, in combination with !2956, supersedes !3014 and !2525. **IO hack** The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is called `exprMayThrowPreciseException` now. I came up with two testcases exemplifying possible unsoundness (if twisted enough) in the old approach: - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. - `T13380e`: Demonstrating unsoundness of the "IO hack" when we have Nested CPR. Not currently relevant, as we don't have Nested CPR yet. - `T13380f`: Demonstrating unsoundness of the "IO hack" for safe FFI calls. Basically, the IO hack assumed that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future, see `T13380e`. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380{d,e}` (and will hopefully be robust to Nested CPR). **Precise exceptions** In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that was terribly unprincipled. That unprincipledness resulted in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception (and the existing IO hack doesn't detect that) Fixing both issues in !3014 turned out to be too complicated and had the potential to regress in the future. Hence we decided to only fix `T13380b` and augment the `Divergence` lattice with a new middle-layer element, `ExnOrDiv`, which means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. See the wiki page on Step 2.1 for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#dead-code-elimination-for-raiseio-with-isdeadenddiv-introducing-exnordiv-step-21 - - - - - 568d7279 by Ben Gamari at 2020-05-15T10:42:46-04:00 GHC.Cmm.Opt: Handle MO_XX_Conv This MachOp was introduced by 2c959a1894311e59cd2fd469c1967491c1e488f3 but a wildcard match in cmmMachOpFoldM hid the fact that it wasn't handled. Ideally we would eliminate the match but this appears to be a larger task. Fixes #18141. - - - - - ace31631 by Simon Peyton Jones at 2020-05-18T15:18:09-04:00 Simple subsumption This patch simplifies GHC to use simple subsumption. Ticket #17775 Implements GHC proposal #287 https://github.com/ghc-proposals/ghc-proposals/blob/master/ proposals/0287-simplify-subsumption.rst All the motivation is described there; I will not repeat it here. The implementation payload: * tcSubType and friends become noticably simpler, because it no longer uses eta-expansion when checking subsumption. * No deeplyInstantiate or deeplySkolemise That in turn means that some tests fail, by design; they can all be fixed by eta expansion. There is a list of such changes below. Implementing the patch led me into a variety of sticky corners, so the patch includes several othe changes, some quite significant: * I made String wired-in, so that "foo" :: String rather than "foo" :: [Char] This improves error messages, and fixes #15679 * The pattern match checker relies on knowing about in-scope equality constraints, andd adds them to the desugarer's environment using addTyCsDs. But the co_fn in a FunBind was missed, and for some reason simple-subsumption ends up with dictionaries there. So I added a call to addTyCsDs. This is really part of #18049. * I moved the ic_telescope field out of Implication and into ForAllSkol instead. This is a nice win; just expresses the code much better. * There was a bug in GHC.Tc.TyCl.Instance.tcDataFamInstHeader. We called checkDataKindSig inside tc_kind_sig, /before/ solveEqualities and zonking. Obviously wrong, easily fixed. * solveLocalEqualitiesX: there was a whole mess in here, around failing fast enough. I discovered a bad latent bug where we could successfully kind-check a type signature, and use it, but have unsolved constraints that could fill in coercion holes in that signature -- aargh. It's all explained in Note [Failure in local type signatures] in GHC.Tc.Solver. Much better now. * I fixed a serious bug in anonymous type holes. IN f :: Int -> (forall a. a -> _) -> Int that "_" should be a unification variable at the /outer/ level; it cannot be instantiated to 'a'. This was plain wrong. New fields mode_lvl and mode_holes in TcTyMode, and auxiliary data type GHC.Tc.Gen.HsType.HoleMode. This fixes #16292, but makes no progress towards the more ambitious #16082 * I got sucked into an enormous refactoring of the reporting of equality errors in GHC.Tc.Errors, especially in mkEqErr1 mkTyVarEqErr misMatchMsg misMatchMsgOrCND In particular, the very tricky mkExpectedActualMsg function is gone. It took me a full day. But the result is far easier to understand. (Still not easy!) This led to various minor improvements in error output, and an enormous number of test-case error wibbles. One particular point: for occurs-check errors I now just say Can't match 'a' against '[a]' rather than using the intimidating language of "occurs check". * Pretty-printing AbsBinds Tests review * Eta expansions T11305: one eta expansion T12082: one eta expansion (undefined) T13585a: one eta expansion T3102: one eta expansion T3692: two eta expansions (tricky) T2239: two eta expansions T16473: one eta determ004: two eta expansions (undefined) annfail06: two eta (undefined) T17923: four eta expansions (a strange program indeed!) tcrun035: one eta expansion * Ambiguity check at higher rank. Now that we have simple subsumption, a type like f :: (forall a. Eq a => Int) -> Int is no longer ambiguous, because we could write g :: (forall a. Eq a => Int) -> Int g = f and it'd typecheck just fine. But f's type is a bit suspicious, and we might want to consider making the ambiguity check do a check on each sub-term. Meanwhile, these tests are accepted, whereas they were previously rejected as ambiguous: T7220a T15438 T10503 T9222 * Some more interesting error message wibbles T13381: Fine: one error (Int ~ Exp Int) rather than two (Int ~ Exp Int, Exp Int ~ Int) T9834: Small change in error (improvement) T10619: Improved T2414: Small change, due to order of unification, fine T2534: A very simple case in which a change of unification order means we get tow unsolved constraints instead of one tc211: bizarre impredicative tests; just accept this for now - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/PPC/Cond.hs - compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.hs - compiler/GHC/CmmToAsm/SPARC/Cond.hs - compiler/GHC/CmmToAsm/X86/Cond.hs - compiler/GHC/CmmToLlvm/Base.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/FamInstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/LiberateCase.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/Specialise.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2a57ffcd2e5d98ced8743403ac3f2a6df21abed3...ace3163101eec6f8b79d1c18700abb63dbc9edc9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2a57ffcd2e5d98ced8743403ac3f2a6df21abed3...ace3163101eec6f8b79d1c18700abb63dbc9edc9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 19 06:11:03 2020 From: gitlab at gitlab.haskell.org (Alp Mestanogullari) Date: Tue, 19 May 2020 02:11:03 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/alp/error-adt Message-ID: <5ec378774fa74_76473f9f501544e03997e6@gitlab.haskell.org.mail> Alp Mestanogullari pushed new branch wip/alp/error-adt at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/alp/error-adt You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 19 06:11:04 2020 From: gitlab at gitlab.haskell.org (Alp Mestanogullari) Date: Tue, 19 May 2020 02:11:04 -0400 Subject: [Git][ghc/ghc] Deleted branch wip/alp/error-adt Message-ID: <5ec3787866b9a_764711929a1c4002e4@gitlab.haskell.org.mail> Alp Mestanogullari deleted branch wip/alp/error-adt at Glasgow Haskell Compiler / GHC -- You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 19 12:17:04 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Tue, 19 May 2020 08:17:04 -0400 Subject: [Git][ghc/ghc][wip/T17619] 638 commits: Simplify mrStr Message-ID: <5ec3ce407b4cb_746ae4cd0c590b@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T17619 at Glasgow Haskell Compiler / GHC Commits: b2e0323f by Gabor Greif at 2020-01-03T21:22:36-05:00 Simplify mrStr - - - - - 3c9dc06b by Brian Wignall at 2020-01-04T15:55:06-05:00 Fix typos, via a Levenshtein-style corrector - - - - - d561c8f6 by Sylvain Henry at 2020-01-04T15:55:46-05:00 Add Cmm related hooks * stgToCmm hook * cmmToRawCmm hook These hooks are used by Asterius and could be useful to other clients of the GHC API. It increases the Parser dependencies (test CountParserDeps) to 184. It's still less than 200 which was the initial request (cf https://mail.haskell.org/pipermail/ghc-devs/2019-September/018122.html) so I think it's ok to merge this. - - - - - ae6b6276 by Oleg Grenrus at 2020-01-04T15:56:22-05:00 Update to Cabal submodule to v3.2.0.0-alpha3 Metric Increase: haddock.Cabal - - - - - 073f7cfd by Vladislav Zavialov at 2020-01-04T15:56:59-05:00 Add lexerDbg to dump the tokens fed to the parser This a small utility function that comes in handy when debugging the lexer and the parser. - - - - - 558d4d4a by Sylvain Henry at 2020-01-04T15:57:38-05:00 Split integerGmpInternals test in several parts This is to prepare for ghc-bignum which implements some but not all of gmp functions. - - - - - 4056b966 by Ben Gamari at 2020-01-04T15:58:15-05:00 testsuite: Mark cgrun057 as fragile on all platforms I have seen this fail both on x86-64/Debian 9 and armv7/Debian 9 See #17554. - - - - - 5ffea0c6 by Tamar Christina at 2020-01-06T18:38:37-05:00 Fix overflow. - - - - - 99a9f51b by Sylvain Henry at 2020-01-06T18:39:22-05:00 Module hierarchy: Iface (cf #13009) - - - - - 7aa4a061 by Ben Gamari at 2020-01-07T13:11:48-05:00 configure: Only check GCC version if CC is GCC Also refactor FP_GCC_EXTRA_FLAGS in a few ways: * We no longer support compilers which lack support for -fno-builtin and -fwrapv so remove the condition on GccVersion * These flags are only necessary when using the via-C backend so make them conditional on Unregisterised. Fixes #15742. - - - - - 0805ed7e by John Ericson at 2020-01-07T13:12:25-05:00 Use non-empty lists to remove partiality in matching code - - - - - 7844f3a8 by Ben Gamari at 2020-01-07T13:13:02-05:00 testsuite: Mark T17073 as broken on Windows Due to #17607. - - - - - acf40cae by Ben Gamari at 2020-01-07T13:13:02-05:00 gitlab-ci: Disallow Windows from failing - - - - - 34bc02c7 by Ben Gamari at 2020-01-07T13:13:02-05:00 configure: Find Python3 for testsuite In addition, we prefer the Mingw64 Python distribution on Windows due to #17483. - - - - - e35fe8d5 by Ben Gamari at 2020-01-07T13:13:02-05:00 testsuite: Fix Windows platform test Previously we used platform.system() and while this worked fine (e.g. returned `Windows`, as expected) locally under both msys and MingW64 Python distributions, it inexplicably returned `MINGW64_NT-10.0` under MingW64 Python on CI. It seems os.name is more reliable so we now use that instead.. - - - - - 48ef6217 by Ben Gamari at 2020-01-07T13:13:39-05:00 gitlab-ci: Rename push-test-metrics.sh to test-metrics.sh Refactoring to follow. - - - - - 2234fa92 by Ben Gamari at 2020-01-07T13:13:39-05:00 gitlab-ci: Pull test metrics before running testsuite Otherwise the testsuite driver may not have an up-to-date baseline. - - - - - 1ca9adbc by Sylvain Henry at 2020-01-07T13:14:18-05:00 Remove `parallel` check from configure.ac `parallel` is no longer a submodule since 3cb063c805ec841ca33b8371ef8aba9329221b6c - - - - - b69a3460 by Ryan Scott at 2020-01-07T13:14:57-05:00 Monomorphize HsModule to GhcPs (#17642) Analyzing the call sites for `HsModule` reveals that it is only ever used with parsed code (i.e., `GhcPs`). This simplifies `HsModule` by concretizing its `pass` parameter to always be `GhcPs`. Fixes #17642. - - - - - d491a679 by Sylvain Henry at 2020-01-08T06:16:31-05:00 Module hierarchy: Renamer (cf #13009) - - - - - d589410f by Ben Gamari at 2020-01-08T06:17:09-05:00 Bump haskeline submodule to 0.8.0.1 (cherry picked from commit feb3b955402d53c3875dd7a9a39f322827e5bd69) - - - - - 923a1272 by Ryan Scott at 2020-01-08T06:17:47-05:00 Print Core type applications with no whitespace after @ (#17643) This brings the pretty-printer for Core in line with how visible type applications are normally printed: namely, with no whitespace after the `@` character (i.e., `f @a` instead of `f @ a`). While I'm in town, I also give the same treatment to type abstractions (i.e., `\(@a)` instead of `\(@ a)`) and coercion applications (i.e., `f @~x` instead of `f @~ x`). Fixes #17643. - - - - - 49f83a0d by Adam Sandberg Eriksson at 2020-01-12T21:28:09-05:00 improve docs for HeaderInfo.getImports [skip ci] - - - - - 9129210f by Matthew Pickering at 2020-01-12T21:28:47-05:00 Overloaded Quotation Brackets (#246) This patch implements overloaded quotation brackets which generalise the desugaring of all quotation forms in terms of a new minimal interface. The main change is that a quotation, for example, [e| 5 |], will now have type `Quote m => m Exp` rather than `Q Exp`. The `Quote` typeclass contains a single method for generating new names which is used when desugaring binding structures. The return type of functions from the `Lift` type class, `lift` and `liftTyped` have been restricted to `forall m . Quote m => m Exp` rather than returning a result in a Q monad. More details about the feature can be read in the GHC proposal. https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0246-overloaded-bracket.rst - - - - - 350e2b78 by Richard Eisenberg at 2020-01-12T21:29:27-05:00 Don't zap to Any; error instead This changes GHC's treatment of so-called Naughty Quantification Candidates to issue errors, instead of zapping to Any. Close #16775. No new test cases, because existing ones cover this well. - - - - - 0b5ddc7f by Brian Wignall at 2020-01-12T21:30:08-05:00 Fix more typos, via an improved Levenshtein-style corrector - - - - - f732dbec by Ben Gamari at 2020-01-12T21:30:49-05:00 gitlab-ci: Retain bindists used by head.hackage for longer Previously we would keep them for two weeks. However, on the stable branches two weeks can easily elapse with no pushes. - - - - - c8636da5 by Sylvain Henry at 2020-01-12T21:31:30-05:00 Fix LANG=C for readelf invocation in T14999 The test fails when used with LANG=fr_FR.UTF-8 - - - - - 077a88de by Jean-Baptiste Mazon at 2020-01-12T21:32:08-05:00 users-guide/debug-info: typo “behivior” - - - - - 61916c5d by Simon Peyton Jones at 2020-01-12T21:32:44-05:00 Add comments about TH levels - - - - - 1fd766ca by Simon Peyton Jones at 2020-01-12T21:32:44-05:00 Comments about constraint floating - - - - - de01427e by Simon Peyton Jones at 2020-01-12T21:32:45-05:00 Minor refactor around quantified constraints This patch clarifies a dark corner of quantified constraints. * See Note [Yukky eq_sel for a HoleDest] in TcSMonad * Minor refactor, breaking out new function TcInteract.doTopReactEqPred - - - - - 30be3bf1 by Simon Peyton Jones at 2020-01-12T21:32:45-05:00 Comments in TcHsType - - - - - c5977d4d by Sebastian Graf at 2020-01-16T05:58:58-05:00 Better documentation for mkEtaWW [skip ci] So that hopefully I understand it faster next time. Also got rid of the confusing `orig_expr`, which makes the call site in `etaExpand` look out of sync with the passed `n` (which is not the original `n`). - - - - - 22c0bdc3 by John Ericson at 2020-01-16T05:59:37-05:00 Handle TagToEnum in the same big case as the other primops Before, it was a panic because it was handled above. But there must have been an error in my reasoning (another caller?) because #17442 reported the panic was hit. But, rather than figuring out what happened, I can just make it impossible by construction. By adding just a bit more bureaucracy in the return types, I can handle TagToEnum in the same case as all the others, so the big case is is now total, and the panic is removed. Fixes #17442 - - - - - ee5d63f4 by John Ericson at 2020-01-16T05:59:37-05:00 Get rid of OpDest `OpDest` was basically a defunctionalization. Just turn the code that cased on it into those functions, and call them directly. - - - - - 1ff55226 by John Ericson at 2020-01-16T06:00:16-05:00 Remove special case case of bool during STG -> C-- Allow removing the no longer needed cgPrimOp, getting rid of a small a small layer violation too. Change which made the special case no longer needed was #6135 / 6579a6c73082387f82b994305011f011d9d8382b, which dates back to 2013, making me feel better. - - - - - f416fe64 by Adam Wespiser at 2020-01-16T06:00:53-05:00 replace dead html link (fixes #17661) - - - - - f6bf2ce8 by Sebastian Graf at 2020-01-16T06:01:32-05:00 Revert "`exprOkForSpeculation` for Note [IO hack in the demand analyser]" This reverts commit ce64b397777408731c6dd3f5c55ea8415f9f565b on the grounds of the regression it would introduce in a couple of packages. Fixes #17653. Also undoes a slight metric increase in #13701 introduced by that commit that we didn't see prior to !1983. Metric Decrease: T13701 - - - - - a71323ff by Ben Gamari at 2020-01-17T08:43:16-05:00 gitlab-ci: Don't FORCE_SYMLINKS on Windows Not all runners have symlink permissions enabled. - - - - - 0499e3bc by Ömer Sinan Ağacan at 2020-01-20T15:31:33-05:00 Fix +RTS -Z flag documentation Stack squeezing is done on context switch, not on GC or stack overflow. Fix the documentation. Fixes #17685 [ci skip] - - - - - a661df91 by Ömer Sinan Ağacan at 2020-01-20T15:32:13-05:00 Document Stg.FVs module Fixes #17662 [ci skip] - - - - - db24e480 by Ben Gamari at 2020-01-20T15:32:52-05:00 llvmGen: Don't trash STG registers Fixes #13904. - - - - - f3d7fdb3 by Ben Gamari at 2020-01-20T15:32:52-05:00 llvmGen: Fix typo in readnone attribute - - - - - 442751c6 by Ben Gamari at 2020-01-20T15:32:52-05:00 llvmGen: Add lower-expect to the -O0 optimisation set @kavon says that this will improve block layout for stack checks. - - - - - e90ecc93 by Ben Gamari at 2020-01-20T15:32:52-05:00 llvmGen: Fix #14251 Fixes the calling convention for functions passing raw SSE-register values by adding padding as needed to get the values in the right registers. This problem cropped up when some args were unused an dropped from the live list. This folds together 2e23e1c7de01c92b038e55ce53d11bf9db993dd4 and 73273be476a8cc6c13368660b042b3b0614fd928 previously from @kavon. Metric Increase: T12707 ManyConstructors - - - - - 66e511a4 by Ben Gamari at 2020-01-20T15:33:28-05:00 testsuite: Preserve more information in framework failures Namely print the entire exception in hopes that this will help track down #17649. - - - - - b62b8cea by Ömer Sinan Ağacan at 2020-01-20T15:34:06-05:00 Remove deprecated -smp flag It was deprecated in 2012 with 46258b40 - - - - - 0c04a86a by Ben Gamari at 2020-01-20T15:34:43-05:00 gitlab-ci: Reenable submodule linter - - - - - 2bfabd22 by Ben Gamari at 2020-01-20T15:34:43-05:00 gitlab-ci: Allow submodule cleaning to fail on Windows Currently CI is inexplicably failing with ``` $ git submodule foreach git clean -xdf fatal: not a git repository: libffi-tarballs/../.git/modules/libffi-tarballs ``` I have no idea how this working tree got into such a state but we do need to fail more gracefully when it happens. Consequently, we allow the cleaning step to fail. - - - - - 14bced99 by Xavier Denis at 2020-01-20T15:35:21-05:00 Put the docs for :instances in alphabetical position - - - - - 7e0bb82b by Ben Gamari at 2020-01-20T15:35:57-05:00 Add missing Note [Improvement from Ground Wanteds] Closes #17659. - - - - - 17e43a7c by Ben Gamari at 2020-01-20T15:36:32-05:00 unregisterised: Fix declaration for stg_NO_FINALIZER Previously it had a redundant _entry suffix. We never noticed this previously presumably because we never generated references to it (however hard to believe this may be). However, it did start failing in !1304. - - - - - 3dae006f by PHO at 2020-01-20T15:37:08-05:00 Avoid ./configure failure on NetBSD - - - - - 738e2912 by Ben Gamari at 2020-01-24T13:42:56-05:00 testsuite: Widen acceptance window of T1969 I have seen >20% fluctuations in this number, leading to spurious failures. - - - - - ad4eb7a7 by Gabor Greif at 2020-01-25T05:19:07-05:00 Document the fact, that openFileBlocking can consume an OS thread indefinitely. Also state that a deadlock can happen with the non-threaded runtime. [ci skip] - - - - - be910728 by Sebastian Graf at 2020-01-25T05:19:46-05:00 `-ddump-str-signatures` dumps Text, not STG [skip ci] - - - - - 0e57d8a1 by Ömer Sinan Ağacan at 2020-01-25T05:20:27-05:00 Fix chaining tagged and untagged ptrs in compacting GC Currently compacting GC has the invariant that in a chain all fields are tagged the same. However this does not really hold: root pointers are not tagged, so when we thread a root we initialize a chain without a tag. When the pointed objects is evaluated and we have more pointers to it from the heap, we then add *tagged* fields to the chain (because pointers to it from the heap are tagged), ending up chaining fields with different tags (pointers from roots are NOT tagged, pointers from heap are). This breaks the invariant and as a result compacting GC turns tagged pointers into non-tagged. This later causes problem in the generated code where we do reads assuming that the pointer is aligned, e.g. 0x7(%rax) -- assumes that pointer is tagged 1 which causes misaligned reads. This caused #17088. We fix this using the "pointer tagging for large families" patch (#14373, !1742): - With the pointer tagging patch the GC can know what the tagged pointer to a CONSTR should be (previously we'd need to know the family size -- large families are always tagged 1, small families are tagged depending on the constructor). - Since we now know what the tags should be we no longer need to store the pointer tag in the info table pointers when forming chains in the compacting GC. As a result we no longer need to tag pointers in chains with 1/2 depending on whether the field points to an info table pointer, or to another field: an info table pointer is always tagged 0, everything else in the chain is tagged 1. The lost tags in pointers can be retrieved by looking at the info table. Finally, instead of using tag 1 for fields and tag 0 for info table pointers, we use two different tags for fields: - 1 for fields that have untagged pointers - 2 for fields that have tagged pointers When unchaining we then look at the pointer to a field, and depending on its tag we either leave a tagged pointer or an untagged pointer in the field. This allows chaining untagged and tagged fields together in compacting GC. Fixes #17088 Nofib results ------------- Binaries are smaller because of smaller `Compact.c` code. make mode=fast EXTRA_RUNTEST_OPTS="-cachegrind" EXTRA_HC_OPTS="-with-rtsopts=-c" NoFibRuns=1 -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS -0.3% 0.0% +0.0% +0.0% +0.0% CSD -0.3% 0.0% +0.0% +0.0% +0.0% FS -0.3% 0.0% +0.0% -0.0% -0.0% S -0.3% 0.0% +5.4% +0.8% +3.9% VS -0.3% 0.0% +0.0% -0.0% -0.0% VSD -0.3% 0.0% -0.0% -0.0% -0.2% VSM -0.3% 0.0% +0.0% +0.0% +0.0% anna -0.1% 0.0% +0.0% +0.0% +0.0% ansi -0.3% 0.0% +0.1% +0.0% +0.0% atom -0.2% 0.0% +0.0% +0.0% +0.0% awards -0.2% 0.0% +0.0% 0.0% -0.0% banner -0.3% 0.0% +0.0% +0.0% +0.0% bernouilli -0.3% 0.0% +0.1% +0.0% +0.0% binary-trees -0.2% 0.0% +0.0% 0.0% +0.0% boyer -0.3% 0.0% +0.2% +0.0% +0.0% boyer2 -0.2% 0.0% +0.2% +0.1% +0.0% bspt -0.2% 0.0% +0.0% +0.0% +0.0% cacheprof -0.2% 0.0% +0.0% +0.0% +0.0% calendar -0.3% 0.0% +0.0% +0.0% +0.0% cichelli -0.3% 0.0% +1.1% +0.2% +0.5% circsim -0.2% 0.0% +0.0% -0.0% -0.0% clausify -0.3% 0.0% +0.0% -0.0% -0.0% comp_lab_zift -0.2% 0.0% +0.0% +0.0% +0.0% compress -0.3% 0.0% +0.0% +0.0% +0.0% compress2 -0.3% 0.0% +0.0% -0.0% -0.0% constraints -0.3% 0.0% +0.2% +0.1% +0.1% cryptarithm1 -0.3% 0.0% +0.0% -0.0% 0.0% cryptarithm2 -0.3% 0.0% +0.0% +0.0% +0.0% cse -0.3% 0.0% +0.0% +0.0% +0.0% digits-of-e1 -0.3% 0.0% +0.0% +0.0% +0.0% digits-of-e2 -0.3% 0.0% +0.0% +0.0% -0.0% dom-lt -0.2% 0.0% +0.0% +0.0% +0.0% eliza -0.2% 0.0% +0.0% +0.0% +0.0% event -0.3% 0.0% +0.1% +0.0% -0.0% exact-reals -0.2% 0.0% +0.0% +0.0% +0.0% exp3_8 -0.3% 0.0% +0.0% +0.0% +0.0% expert -0.2% 0.0% +0.0% +0.0% +0.0% fannkuch-redux -0.3% 0.0% -0.0% -0.0% -0.0% fasta -0.3% 0.0% +0.0% +0.0% +0.0% fem -0.2% 0.0% +0.1% +0.0% +0.0% fft -0.2% 0.0% +0.0% -0.0% -0.0% fft2 -0.2% 0.0% +0.0% -0.0% +0.0% fibheaps -0.3% 0.0% +0.0% -0.0% -0.0% fish -0.3% 0.0% +0.0% +0.0% +0.0% fluid -0.2% 0.0% +0.4% +0.1% +0.1% fulsom -0.2% 0.0% +0.0% +0.0% +0.0% gamteb -0.2% 0.0% +0.1% +0.0% +0.0% gcd -0.3% 0.0% +0.0% +0.0% +0.0% gen_regexps -0.3% 0.0% +0.0% -0.0% -0.0% genfft -0.3% 0.0% +0.0% +0.0% +0.0% gg -0.2% 0.0% +0.7% +0.3% +0.2% grep -0.2% 0.0% +0.0% +0.0% +0.0% hidden -0.2% 0.0% +0.0% +0.0% +0.0% hpg -0.2% 0.0% +0.1% +0.0% +0.0% ida -0.3% 0.0% +0.0% +0.0% +0.0% infer -0.2% 0.0% +0.0% -0.0% -0.0% integer -0.3% 0.0% +0.0% +0.0% +0.0% integrate -0.2% 0.0% +0.0% +0.0% +0.0% k-nucleotide -0.2% 0.0% +0.0% +0.0% -0.0% kahan -0.3% 0.0% -0.0% -0.0% -0.0% knights -0.3% 0.0% +0.0% -0.0% -0.0% lambda -0.3% 0.0% +0.0% -0.0% -0.0% last-piece -0.3% 0.0% +0.0% +0.0% +0.0% lcss -0.3% 0.0% +0.0% +0.0% 0.0% life -0.3% 0.0% +0.0% -0.0% -0.0% lift -0.2% 0.0% +0.0% +0.0% +0.0% linear -0.2% 0.0% +0.0% +0.0% +0.0% listcompr -0.3% 0.0% +0.0% +0.0% +0.0% listcopy -0.3% 0.0% +0.0% +0.0% +0.0% maillist -0.3% 0.0% +0.0% -0.0% -0.0% mandel -0.2% 0.0% +0.0% +0.0% +0.0% mandel2 -0.3% 0.0% +0.0% +0.0% +0.0% mate -0.2% 0.0% +0.0% +0.0% +0.0% minimax -0.3% 0.0% +0.0% +0.0% +0.0% mkhprog -0.2% 0.0% +0.0% +0.0% +0.0% multiplier -0.3% 0.0% +0.0% -0.0% -0.0% n-body -0.2% 0.0% -0.0% -0.0% -0.0% nucleic2 -0.2% 0.0% +0.0% +0.0% +0.0% para -0.2% 0.0% +0.0% -0.0% -0.0% paraffins -0.3% 0.0% +0.0% -0.0% -0.0% parser -0.2% 0.0% +0.0% +0.0% +0.0% parstof -0.2% 0.0% +0.8% +0.2% +0.2% pic -0.2% 0.0% +0.1% -0.1% -0.1% pidigits -0.3% 0.0% +0.0% +0.0% +0.0% power -0.2% 0.0% +0.0% -0.0% -0.0% pretty -0.3% 0.0% -0.0% -0.0% -0.1% primes -0.3% 0.0% +0.0% +0.0% -0.0% primetest -0.2% 0.0% +0.0% -0.0% -0.0% prolog -0.3% 0.0% +0.0% -0.0% -0.0% puzzle -0.3% 0.0% +0.0% +0.0% +0.0% queens -0.3% 0.0% +0.0% +0.0% +0.0% reptile -0.2% 0.0% +0.2% +0.1% +0.0% reverse-complem -0.3% 0.0% +0.0% +0.0% +0.0% rewrite -0.3% 0.0% +0.0% -0.0% -0.0% rfib -0.2% 0.0% +0.0% +0.0% -0.0% rsa -0.2% 0.0% +0.0% +0.0% +0.0% scc -0.3% 0.0% -0.0% -0.0% -0.1% sched -0.3% 0.0% +0.0% +0.0% +0.0% scs -0.2% 0.0% +0.1% +0.0% +0.0% simple -0.2% 0.0% +3.4% +1.0% +1.8% solid -0.2% 0.0% +0.0% +0.0% +0.0% sorting -0.3% 0.0% +0.0% +0.0% +0.0% spectral-norm -0.2% 0.0% -0.0% -0.0% -0.0% sphere -0.2% 0.0% +0.0% +0.0% +0.0% symalg -0.2% 0.0% +0.0% +0.0% +0.0% tak -0.3% 0.0% +0.0% +0.0% -0.0% transform -0.2% 0.0% +0.2% +0.1% +0.1% treejoin -0.3% 0.0% +0.2% -0.0% -0.1% typecheck -0.3% 0.0% +0.0% +0.0% +0.0% veritas -0.1% 0.0% +0.0% +0.0% +0.0% wang -0.2% 0.0% +0.0% -0.0% -0.0% wave4main -0.3% 0.0% +0.0% -0.0% -0.0% wheel-sieve1 -0.3% 0.0% +0.0% -0.0% -0.0% wheel-sieve2 -0.3% 0.0% +0.0% -0.0% -0.0% x2n1 -0.3% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min -0.3% 0.0% -0.0% -0.1% -0.2% Max -0.1% 0.0% +5.4% +1.0% +3.9% Geometric Mean -0.3% -0.0% +0.1% +0.0% +0.1% -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- circsim -0.2% 0.0% +1.6% +0.4% +0.7% constraints -0.3% 0.0% +4.3% +1.5% +2.3% fibheaps -0.3% 0.0% +3.5% +1.2% +1.3% fulsom -0.2% 0.0% +3.6% +1.2% +1.8% gc_bench -0.3% 0.0% +4.1% +1.3% +2.3% hash -0.3% 0.0% +6.6% +2.2% +3.6% lcss -0.3% 0.0% +0.7% +0.2% +0.7% mutstore1 -0.3% 0.0% +4.8% +1.4% +2.8% mutstore2 -0.3% 0.0% +3.4% +1.0% +1.7% power -0.2% 0.0% +2.7% +0.6% +1.9% spellcheck -0.3% 0.0% +1.1% +0.4% +0.4% -------------------------------------------------------------------------------- Min -0.3% 0.0% +0.7% +0.2% +0.4% Max -0.2% 0.0% +6.6% +2.2% +3.6% Geometric Mean -0.3% +0.0% +3.3% +1.0% +1.8% Metric changes -------------- While it sounds ridiculous, this change causes increased allocations in the following tests. We concluded that this change can't cause a difference in allocations and decided to land this patch. Fluctuations in "bytes allocated" metric is tracked in #17686. Metric Increase: Naperian T10547 T12150 T12234 T12425 T13035 T5837 T6048 - - - - - 8038cbd9 by Sebastian Graf at 2020-01-25T05:21:05-05:00 PmCheck: Formulate as translation between Clause Trees We used to check `GrdVec`s arising from multiple clauses and guards in isolation. That resulted in a split between `pmCheck` and `pmCheckGuards`, the implementations of which were similar, but subtly different in detail. Also the throttling mechanism described in `Note [Countering exponential blowup]` ultimately got quite complicated because it had to cater for both checking functions. This patch realises that pattern match checking doesn't just consider single guarded RHSs, but that it's always a whole set of clauses, each of which can have multiple guarded RHSs in turn. We do so by translating a list of `Match`es to a `GrdTree`: ```haskell data GrdTree = Rhs !RhsInfo | Guard !PmGrd !GrdTree -- captures lef-to-right match semantics | Sequence !GrdTree !GrdTree -- captures top-to-bottom match semantics | Empty -- For -XEmptyCase, neutral element of Sequence ``` Then we have a function `checkGrdTree` that matches a given `GrdTree` against an incoming set of values, represented by `Deltas`: ```haskell checkGrdTree :: GrdTree -> Deltas -> CheckResult ... ``` Throttling is isolated to the `Sequence` case and becomes as easy as one would expect: When the union of uncovered values becomes too big, just return the original incoming `Deltas` instead (which is always a superset of the union, thus a sound approximation). The returned `CheckResult` contains two things: 1. The set of values that were not covered by any of the clauses, for exhaustivity warnings. 2. The `AnnotatedTree` that enriches the syntactic structure of the input program with divergence and inaccessibility information. This is `AnnotatedTree`: ```haskell data AnnotatedTree = AccessibleRhs !RhsInfo | InaccessibleRhs !RhsInfo | MayDiverge !AnnotatedTree | SequenceAnn !AnnotatedTree !AnnotatedTree | EmptyAnn ``` Crucially, `MayDiverge` asserts that the tree may force diverging values, so not all of its wrapped clauses can be redundant. While the set of uncovered values can be used to generate the missing equations for warning messages, redundant and proper inaccessible equations can be extracted from `AnnotatedTree` by `redundantAndInaccessibleRhss`. For this to work properly, the interface to the Oracle had to change. There's only `addPmCts` now, which takes a bag of `PmCt`s. There's a whole bunch of `PmCt` variants to replace the different oracle functions from before. The new `AnnotatedTree` structure allows for more accurate warning reporting (as evidenced by a number of changes spread throughout GHC's code base), thus we fix #17465. Fixes #17646 on the go. Metric Decrease: T11822 T9233 PmSeriesS haddock.compiler - - - - - 86966d48 by Sebastian Graf at 2020-01-25T05:21:05-05:00 PmCheck: Properly handle constructor-bound type variables In https://gitlab.haskell.org/ghc/ghc/merge_requests/2192#note_246551 Simon convinced me that ignoring type variables existentially bound by data constructors have to be the same way as value binders. Sadly I couldn't think of a regression test, but I'm confident that this change strictly improves on the status quo. - - - - - c3fde723 by Ryan Scott at 2020-01-25T05:21:40-05:00 Handle local fixity declarations in DsMeta properly `DsMeta.rep_sig` used to skip over `FixSig` entirely, which had the effect of causing local fixity declarations to be dropped when quoted in Template Haskell. But there is no good reason for this state of affairs, as the code in `DsMeta.repFixD` (which handles top-level fixity declarations) handles local fixity declarations just fine. This patch factors out the necessary parts of `repFixD` so that they can be used in `rep_sig` as well. There was one minor complication: the fixity signatures for class methods in each `HsGroup` were stored both in `FixSig`s _and_ the list of `LFixitySig`s for top-level fixity signatures, so I needed to take action to prevent fixity signatures for class methods being converted to `Dec`s twice. I tweaked `RnSource.add` to avoid putting these fixity signatures in two places and added `Note [Top-level fixity signatures in an HsGroup]` in `GHC.Hs.Decls` to explain the new design. Fixes #17608. Bumps the Haddock submodule. - - - - - 6e2d9ee2 by Sylvain Henry at 2020-01-25T05:22:20-05:00 Module hierarchy: Cmm (cf #13009) - - - - - 8b726534 by PHO at 2020-01-25T05:23:01-05:00 Fix rts allocateExec() on NetBSD Similar to SELinux, NetBSD "PaX mprotect" prohibits marking a page mapping both writable and executable at the same time. Use libffi which knows how to work around it. - - - - - 6eb566a0 by Xavier Denis at 2020-01-25T05:23:39-05:00 Add ghc-in-ghci for stack based builds - - - - - b1a32170 by Xavier Denis at 2020-01-25T05:23:39-05:00 Create ghci.cabal.sh - - - - - 0a5e4f5f by Sylvain Henry at 2020-01-25T05:24:19-05:00 Split glasgow_exts into several files (#17316) - - - - - b3e5c678 by Ben Gamari at 2020-01-25T05:24:57-05:00 hadrian: Throw error on duplicate-named flavours Throw an error if the user requests a flavour for which there is more than one match. Fixes #17156. - - - - - 0940b59a by Ryan Scott at 2020-01-25T08:15:05-05:00 Do not bring visible foralls into scope in hsScopedTvs Previously, `hsScopedTvs` (and its cousin `hsWcScopedTvs`) pretended that visible dependent quantification could not possibly happen at the term level, and cemented that assumption with an `ASSERT`: ```hs hsScopedTvs (HsForAllTy { hst_fvf = vis_flag, ... }) = ASSERT( vis_flag == ForallInvis ) ... ``` It turns out that this assumption is wrong. You can end up tripping this `ASSERT` if you stick it to the man and write a type for a term that uses visible dependent quantification anyway, like in this example: ```hs {-# LANGUAGE ScopedTypeVariables #-} x :: forall a -> a -> a x = x ``` That won't typecheck, but that's not the point. Before the typechecker has a chance to reject this, the renamer will try to use `hsScopedTvs` to bring `a` into scope over the body of `x`, since `a` is quantified by a `forall`. This, in turn, causes the `ASSERT` to fail. Bummer. Instead of walking on this dangerous ground, this patch makes GHC adopt a more hardline stance by pattern-matching directly on `ForallInvis` in `hsScopedTvs`: ```hs hsScopedTvs (HsForAllTy { hst_fvf = ForallInvis, ... }) = ... ``` Now `a` will not be brought over the body of `x` at all (which is how it should be), there's no chance of the `ASSERT` failing anymore (as it's gone), and best of all, the behavior of `hsScopedTvs` does not change. Everyone wins! Fixes #17687. - - - - - 1132602f by Ryan Scott at 2020-01-27T10:03:42-05:00 Use splitLHs{ForAll,Sigma}TyInvis throughout the codebase Richard points out in #17688 that we use `splitLHsForAllTy` and `splitLHsSigmaTy` in places that we ought to be using the corresponding `-Invis` variants instead, identifying two bugs that are caused by this oversight: * Certain TH-quoted type signatures, such as those that appear in quoted `SPECIALISE` pragmas, silently turn visible `forall`s into invisible `forall`s. * When quoted, the type `forall a -> (a ~ a) => a` will turn into `forall a -> a` due to a bug in `DsMeta.repForall` that drops contexts that follow visible `forall`s. These are both ultimately caused by the fact that `splitLHsForAllTy` and `splitLHsSigmaTy` split apart visible `forall`s in addition to invisible ones. This patch cleans things up: * We now use `splitLHsForAllTyInvis` and `splitLHsSigmaTyInvis` throughout the codebase. Relatedly, the `splitLHsForAllTy` and `splitLHsSigmaTy` have been removed, as they are easy to misuse. * `DsMeta.repForall` now only handles invisible `forall`s to reduce the chance for confusion with visible `forall`s, which need to be handled differently. I also renamed it from `repForall` to `repForallT` to emphasize that its distinguishing characteristic is the fact that it desugars down to `L.H.TH.Syntax.ForallT`. Fixes #17688. - - - - - 97d0b0a3 by Matthew Pickering at 2020-01-27T10:04:19-05:00 Make Block.h compile with c++ compilers - - - - - 4bada77d by Tom Ellis at 2020-01-27T12:30:46-05:00 Disable two warnings for files that trigger them incomplete-uni-patterns and incomplete-record-updates will be in -Wall at a future date, so prepare for that by disabling those warnings on files that trigger them. - - - - - 0188404a by Tom Ellis at 2020-01-27T12:30:46-05:00 Add two warnings to stage 2 build - - - - - acae02c1 by Tom Ellis at 2020-01-27T12:30:46-05:00 Add two warnings to Hadrian - - - - - bf38a20e by Sylvain Henry at 2020-01-31T02:46:15-05:00 Call `interpretPackageEnv` from `setSessionDynFlags` interpretPackageEnv modifies the flags by reading the dreaded package environments. It is much less surprising to call it from `setSessionDynFlags` instead of reading package environments as a side-effect of `initPackages`. - - - - - 29c701c1 by Sylvain Henry at 2020-01-31T02:46:15-05:00 Refactor package related code The package terminology is a bit of a mess. Cabal packages contain components. Instances of these components when built with some flags/options/dependencies are called units. Units are registered into package databases and their metadata are called PackageConfig. GHC only knows about package databases containing units. It is a sad mismatch not fixed by this patch (we would have to rename parameters such as `package-id <unit-id>` which would affect users). This patch however fixes the following internal names: - Renames PackageConfig into UnitInfo. - Rename systemPackageConfig into globalPackageDatabase[Path] - Rename PkgConfXX into PkgDbXX - Rename pkgIdMap into unitIdMap - Rename ModuleToPkgDbAll into ModuleNameProvidersMap - Rename lookupPackage into lookupUnit - Add comments on DynFlags package related fields It also introduces a new `PackageDatabase` datatype instead of explicitly passing the following tuple: `(FilePath,[PackageConfig])`. The `pkgDatabase` field in `DynFlags` now contains the unit info for each unit of each package database exactly as they have been read from disk. Previously the command-line flag `-distrust-all-packages` would modify these unit info. Now this flag only affects the "dynamic" consolidated package state found in `pkgState` field. It makes sense because `initPackages` could be called first with this `distrust-all-packages` flag set and then again (using ghc-api) without and it should work (package databases are not read again from disk when `initPackages` is called the second time). Bump haddock submodule - - - - - 942c7148 by Ben Gamari at 2020-01-31T02:46:54-05:00 rename: Eliminate usage of mkVarOccUnique Replacing it with `newSysName`. Fixes #17061. - - - - - 41117d71 by Ben Gamari at 2020-01-31T02:47:31-05:00 base: Use one-shot kqueue on macOS The underlying reason requiring that one-shot usage be disabled (#13903) has been fixed. Closes #15768. - - - - - 01b15b83 by Ben Gamari at 2020-01-31T02:48:08-05:00 testsuite: Don't crash on encoding failure in print If the user doesn't use a Unicode locale then the testsuite driver would previously throw framework failures due to encoding failures. We now rather use the `replace` error-handling strategy. - - - - - c846618a by Ömer Sinan Ağacan at 2020-01-31T12:21:10+03:00 Do CafInfo/SRT analysis in Cmm This patch removes all CafInfo predictions and various hacks to preserve predicted CafInfos from the compiler and assigns final CafInfos to interface Ids after code generation. SRT analysis is extended to support static data, and Cmm generator is modified to allow generating static_link fields after SRT analysis. This also fixes `-fcatch-bottoms`, which introduces error calls in case expressions in CorePrep, which runs *after* CoreTidy (which is where we decide on CafInfos) and turns previously non-CAFFY things into CAFFY. Fixes #17648 Fixes #9718 Evaluation ========== NoFib ----- Boot with: `make boot mode=fast` Run: `make mode=fast EXTRA_RUNTEST_OPTS="-cachegrind" NoFibRuns=1` -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS -0.0% 0.0% -0.0% -0.0% -0.0% CSD -0.0% 0.0% -0.0% -0.0% -0.0% FS -0.0% 0.0% -0.0% -0.0% -0.0% S -0.0% 0.0% -0.0% -0.0% -0.0% VS -0.0% 0.0% -0.0% -0.0% -0.0% VSD -0.0% 0.0% -0.0% -0.0% -0.5% VSM -0.0% 0.0% -0.0% -0.0% -0.0% anna -0.1% 0.0% -0.0% -0.0% -0.0% ansi -0.0% 0.0% -0.0% -0.0% -0.0% atom -0.0% 0.0% -0.0% -0.0% -0.0% awards -0.0% 0.0% -0.0% -0.0% -0.0% banner -0.0% 0.0% -0.0% -0.0% -0.0% bernouilli -0.0% 0.0% -0.0% -0.0% -0.0% binary-trees -0.0% 0.0% -0.0% -0.0% -0.0% boyer -0.0% 0.0% -0.0% -0.0% -0.0% boyer2 -0.0% 0.0% -0.0% -0.0% -0.0% bspt -0.0% 0.0% -0.0% -0.0% -0.0% cacheprof -0.0% 0.0% -0.0% -0.0% -0.0% calendar -0.0% 0.0% -0.0% -0.0% -0.0% cichelli -0.0% 0.0% -0.0% -0.0% -0.0% circsim -0.0% 0.0% -0.0% -0.0% -0.0% clausify -0.0% 0.0% -0.0% -0.0% -0.0% comp_lab_zift -0.0% 0.0% -0.0% -0.0% -0.0% compress -0.0% 0.0% -0.0% -0.0% -0.0% compress2 -0.0% 0.0% -0.0% -0.0% -0.0% constraints -0.0% 0.0% -0.0% -0.0% -0.0% cryptarithm1 -0.0% 0.0% -0.0% -0.0% -0.0% cryptarithm2 -0.0% 0.0% -0.0% -0.0% -0.0% cse -0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e1 -0.0% 0.0% -0.0% -0.0% -0.0% digits-of-e2 -0.0% 0.0% -0.0% -0.0% -0.0% dom-lt -0.0% 0.0% -0.0% -0.0% -0.0% eliza -0.0% 0.0% -0.0% -0.0% -0.0% event -0.0% 0.0% -0.0% -0.0% -0.0% exact-reals -0.0% 0.0% -0.0% -0.0% -0.0% exp3_8 -0.0% 0.0% -0.0% -0.0% -0.0% expert -0.0% 0.0% -0.0% -0.0% -0.0% fannkuch-redux -0.0% 0.0% -0.0% -0.0% -0.0% fasta -0.0% 0.0% -0.0% -0.0% -0.0% fem -0.0% 0.0% -0.0% -0.0% -0.0% fft -0.0% 0.0% -0.0% -0.0% -0.0% fft2 -0.0% 0.0% -0.0% -0.0% -0.0% fibheaps -0.0% 0.0% -0.0% -0.0% -0.0% fish -0.0% 0.0% -0.0% -0.0% -0.0% fluid -0.1% 0.0% -0.0% -0.0% -0.0% fulsom -0.0% 0.0% -0.0% -0.0% -0.0% gamteb -0.0% 0.0% -0.0% -0.0% -0.0% gcd -0.0% 0.0% -0.0% -0.0% -0.0% gen_regexps -0.0% 0.0% -0.0% -0.0% -0.0% genfft -0.0% 0.0% -0.0% -0.0% -0.0% gg -0.0% 0.0% -0.0% -0.0% -0.0% grep -0.0% 0.0% -0.0% -0.0% -0.0% hidden -0.0% 0.0% -0.0% -0.0% -0.0% hpg -0.1% 0.0% -0.0% -0.0% -0.0% ida -0.0% 0.0% -0.0% -0.0% -0.0% infer -0.0% 0.0% -0.0% -0.0% -0.0% integer -0.0% 0.0% -0.0% -0.0% -0.0% integrate -0.0% 0.0% -0.0% -0.0% -0.0% k-nucleotide -0.0% 0.0% -0.0% -0.0% -0.0% kahan -0.0% 0.0% -0.0% -0.0% -0.0% knights -0.0% 0.0% -0.0% -0.0% -0.0% lambda -0.0% 0.0% -0.0% -0.0% -0.0% last-piece -0.0% 0.0% -0.0% -0.0% -0.0% lcss -0.0% 0.0% -0.0% -0.0% -0.0% life -0.0% 0.0% -0.0% -0.0% -0.0% lift -0.0% 0.0% -0.0% -0.0% -0.0% linear -0.1% 0.0% -0.0% -0.0% -0.0% listcompr -0.0% 0.0% -0.0% -0.0% -0.0% listcopy -0.0% 0.0% -0.0% -0.0% -0.0% maillist -0.0% 0.0% -0.0% -0.0% -0.0% mandel -0.0% 0.0% -0.0% -0.0% -0.0% mandel2 -0.0% 0.0% -0.0% -0.0% -0.0% mate -0.0% 0.0% -0.0% -0.0% -0.0% minimax -0.0% 0.0% -0.0% -0.0% -0.0% mkhprog -0.0% 0.0% -0.0% -0.0% -0.0% multiplier -0.0% 0.0% -0.0% -0.0% -0.0% n-body -0.0% 0.0% -0.0% -0.0% -0.0% nucleic2 -0.0% 0.0% -0.0% -0.0% -0.0% para -0.0% 0.0% -0.0% -0.0% -0.0% paraffins -0.0% 0.0% -0.0% -0.0% -0.0% parser -0.1% 0.0% -0.0% -0.0% -0.0% parstof -0.1% 0.0% -0.0% -0.0% -0.0% pic -0.0% 0.0% -0.0% -0.0% -0.0% pidigits -0.0% 0.0% -0.0% -0.0% -0.0% power -0.0% 0.0% -0.0% -0.0% -0.0% pretty -0.0% 0.0% -0.3% -0.4% -0.4% primes -0.0% 0.0% -0.0% -0.0% -0.0% primetest -0.0% 0.0% -0.0% -0.0% -0.0% prolog -0.0% 0.0% -0.0% -0.0% -0.0% puzzle -0.0% 0.0% -0.0% -0.0% -0.0% queens -0.0% 0.0% -0.0% -0.0% -0.0% reptile -0.0% 0.0% -0.0% -0.0% -0.0% reverse-complem -0.0% 0.0% -0.0% -0.0% -0.0% rewrite -0.0% 0.0% -0.0% -0.0% -0.0% rfib -0.0% 0.0% -0.0% -0.0% -0.0% rsa -0.0% 0.0% -0.0% -0.0% -0.0% scc -0.0% 0.0% -0.3% -0.5% -0.4% sched -0.0% 0.0% -0.0% -0.0% -0.0% scs -0.0% 0.0% -0.0% -0.0% -0.0% simple -0.1% 0.0% -0.0% -0.0% -0.0% solid -0.0% 0.0% -0.0% -0.0% -0.0% sorting -0.0% 0.0% -0.0% -0.0% -0.0% spectral-norm -0.0% 0.0% -0.0% -0.0% -0.0% sphere -0.0% 0.0% -0.0% -0.0% -0.0% symalg -0.0% 0.0% -0.0% -0.0% -0.0% tak -0.0% 0.0% -0.0% -0.0% -0.0% transform -0.0% 0.0% -0.0% -0.0% -0.0% treejoin -0.0% 0.0% -0.0% -0.0% -0.0% typecheck -0.0% 0.0% -0.0% -0.0% -0.0% veritas -0.0% 0.0% -0.0% -0.0% -0.0% wang -0.0% 0.0% -0.0% -0.0% -0.0% wave4main -0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 -0.0% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 -0.0% 0.0% -0.0% -0.0% -0.0% x2n1 -0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min -0.1% 0.0% -0.3% -0.5% -0.5% Max -0.0% 0.0% -0.0% -0.0% -0.0% Geometric Mean -0.0% -0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- circsim -0.1% 0.0% -0.0% -0.0% -0.0% constraints -0.0% 0.0% -0.0% -0.0% -0.0% fibheaps -0.0% 0.0% -0.0% -0.0% -0.0% gc_bench -0.0% 0.0% -0.0% -0.0% -0.0% hash -0.0% 0.0% -0.0% -0.0% -0.0% lcss -0.0% 0.0% -0.0% -0.0% -0.0% power -0.0% 0.0% -0.0% -0.0% -0.0% spellcheck -0.0% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min -0.1% 0.0% -0.0% -0.0% -0.0% Max -0.0% 0.0% -0.0% -0.0% -0.0% Geometric Mean -0.0% +0.0% -0.0% -0.0% -0.0% Manual inspection of programs in testsuite/tests/programs --------------------------------------------------------- I built these programs with a bunch of dump flags and `-O` and compared STG, Cmm, and Asm dumps and file sizes. (Below the numbers in parenthesis show number of modules in the program) These programs have identical compiler (same .hi and .o sizes, STG, and Cmm and Asm dumps): - Queens (1), andre_monad (1), cholewo-eval (2), cvh_unboxing (3), andy_cherry (7), fun_insts (1), hs-boot (4), fast2haskell (2), jl_defaults (1), jq_readsPrec (1), jules_xref (1), jtod_circint (4), jules_xref2 (1), lennart_range (1), lex (1), life_space_leak (1), bargon-mangler-bug (7), record_upd (1), rittri (1), sanders_array (1), strict_anns (1), thurston-module-arith (2), okeefe_neural (1), joao-circular (6), 10queens (1) Programs with different compiler outputs: - jl_defaults (1): For some reason GHC HEAD marks a lot of top-level `[Int]` closures as CAFFY for no reason. With this patch we no longer make them CAFFY and generate less SRT entries. For some reason Main.o is slightly larger with this patch (1.3%) and the executable sizes are the same. (I'd expect both to be smaller) - launchbury (1): Same as jl_defaults: top-level `[Int]` closures marked as CAFFY for no reason. Similarly `Main.o` is 1.4% larger but the executable sizes are the same. - galois_raytrace (13): Differences are in the Parse module. There are a lot, but some of the changes are caused by the fact that for some reason (I think a bug) GHC HEAD marks the dictionary for `Functor Identity` as CAFFY. Parse.o is 0.4% larger, the executable size is the same. - north_array: We now generate less SRT entries because some of array primops used in this program like `NewArrayOp` get eliminated during Stg-to-Cmm and turn some CAFFY things into non-CAFFY. Main.o gets 24% larger (9224 bytes from 9000 bytes), executable sizes are the same. - seward-space-leak: Difference in this program is better shown by this smaller example: module Lib where data CDS = Case [CDS] [(Int, CDS)] | Call CDS CDS instance Eq CDS where Case sels1 rets1 == Case sels2 rets2 = sels1 == sels2 && rets1 == rets2 Call a1 b1 == Call a2 b2 = a1 == a2 && b1 == b2 _ == _ = False In this program GHC HEAD builds a new SRT for the recursive group of `(==)`, `(/=)` and the dictionary closure. Then `/=` points to `==` in its SRT field, and `==` uses the SRT object as its SRT. With this patch we use the closure for `/=` as the SRT and add `==` there. Then `/=` gets an empty SRT field and `==` points to `/=` in its SRT field. This change looks fine to me. Main.o gets 0.07% larger, executable sizes are identical. head.hackage ------------ head.hackage's CI script builds 428 packages from Hackage using this patch with no failures. Compiler performance -------------------- The compiler perf tests report that the compiler allocates slightly more (worst case observed so far is 4%). However most programs in the test suite are small, single file programs. To benchmark compiler performance on something more realistic I build Cabal (the library, 236 modules) with different optimisation levels. For the "max residency" row I run GHC with `+RTS -s -A100k -i0 -h` for more accurate numbers. Other rows are generated with just `-s`. (This is because `-i0` causes running GC much more frequently and as a result "bytes copied" gets inflated by more than 25x in some cases) * -O0 | | GHC HEAD | This MR | Diff | | --------------- | -------------- | -------------- | ------ | | Bytes allocated | 54,413,350,872 | 54,701,099,464 | +0.52% | | Bytes copied | 4,926,037,184 | 4,990,638,760 | +1.31% | | Max residency | 421,225,624 | 424,324,264 | +0.73% | * -O1 | | GHC HEAD | This MR | Diff | | --------------- | --------------- | --------------- | ------ | | Bytes allocated | 245,849,209,992 | 246,562,088,672 | +0.28% | | Bytes copied | 26,943,452,560 | 27,089,972,296 | +0.54% | | Max residency | 982,643,440 | 991,663,432 | +0.91% | * -O2 | | GHC HEAD | This MR | Diff | | --------------- | --------------- | --------------- | ------ | | Bytes allocated | 291,044,511,408 | 291,863,910,912 | +0.28% | | Bytes copied | 37,044,237,616 | 36,121,690,472 | -2.49% | | Max residency | 1,071,600,328 | 1,086,396,256 | +1.38% | Extra compiler allocations -------------------------- Runtime allocations of programs are as reported above (NoFib section). The compiler now allocates more than before. Main source of allocation in this patch compared to base commit is the new SRT algorithm (GHC.Cmm.Info.Build). Below is some of the extra work we do with this patch, numbers generated by profiled stage 2 compiler when building a pathological case (the test 'ManyConstructors') with '-O2': - We now sort the final STG for a module, which means traversing the entire program, generating free variable set for each top-level binding, doing SCC analysis, and re-ordering the program. In ManyConstructors this step allocates 97,889,952 bytes. - We now do SRT analysis on static data, which in a program like ManyConstructors causes analysing 10,000 bindings that we would previously just skip. This step allocates 70,898,352 bytes. - We now maintain an SRT map for the entire module as we compile Cmm groups: data ModuleSRTInfo = ModuleSRTInfo { ... , moduleSRTMap :: SRTMap } (SRTMap is just a strict Map from the 'containers' library) This map gets an entry for most bindings in a module (exceptions are THUNKs and CAFFY static functions). For ManyConstructors this map gets 50015 entries. - Once we're done with code generation we generate a NameSet from SRTMap for the non-CAFFY names in the current module. This set gets the same number of entries as the SRTMap. - Finally we update CafInfos in ModDetails for the non-CAFFY Ids, using the NameSet generated in the previous step. This usually does the least amount of allocation among the work listed here. Only place with this patch where we do less work in the CAF analysis in the tidying pass (CoreTidy). However that doesn't save us much, as the pass still needs to traverse the whole program and update IdInfos for other reasons. Only thing we don't here do is the `hasCafRefs` pass over the RHS of bindings, which is a stateless pass that returns a boolean value, so it doesn't allocate much. (Metric changes blow are all increased allocations) Metric changes -------------- Metric Increase: ManyAlternatives ManyConstructors T13035 T14683 T1969 T9961 - - - - - 2a87a565 by Andreas Klebinger at 2020-01-31T12:21:10+03:00 A few optimizations in STG and Cmm parts: (Guided by the profiler output) - Add a few bang patterns, INLINABLE annotations, and a seqList in a few places in Cmm and STG parts. - Do not add external variables as dependencies in STG dependency analysis (GHC.Stg.DepAnal). - - - - - bef704b6 by Simon Peyton Jones at 2020-02-01T02:28:45-05:00 Improve skolemisation This patch avoids skolemiseUnboundMetaTyVar making up a fresh Name when it doesn't need to. See Note [Skolemising and identity] Improves error messsages for partial type signatures. - - - - - cd110423 by Simon Peyton Jones at 2020-02-01T02:28:45-05:00 Improve pretty-printing for TyConBinders In particular, show their kinds. - - - - - 913287a0 by Simon Peyton Jones at 2020-02-01T02:28:45-05:00 Fix scoping of TyCon binders in TcTyClsDecls This patch fixes #17566 by refactoring the way we decide the final identity of the tyvars in the TyCons of a possibly-recursive nest of type and class decls, possibly with associated types. It's all laid out in Note [Swizzling the tyvars before generaliseTcTyCon] Main changes: * We have to generalise each decl (with its associated types) all at once: TcTyClsDecls.generaliseTyClDecl * The main new work is done in TcTyClsDecls.swizzleTcTyConBndrs * The mysterious TcHsSyn.zonkRecTyVarBndrs dies altogether Other smaller things: * A little refactoring, moving bindTyClTyVars from tcTyClDecl1 to tcDataDefn, tcSynRhs, etc. Clearer, reduces the number of parameters * Reduce the amount of swizzling required. Specifically, bindExplicitTKBndrs_Q_Tv doesn't need to clone a new Name for the TyVarTv, and not cloning means that in the vasly common case, swizzleTyConBndrs is a no-op In detail: Rename newTyVarTyVar --> cloneTyVarTyVar Add newTyVarTyTyVar that doesn't clone Use the non-cloning newTyVarTyVar in bindExplicitTKBndrs_Q_Tv Rename newFlexiKindedTyVarTyVar --> cloneFlexiKindedTyVarTyVar * Define new utility function and use it HsDecls.familyDeclName :: FamilyDecl (GhcPass p) -> IdP (GhcPass p) Updates haddock submodule. - - - - - 58ed6c4a by Ben Gamari at 2020-02-01T02:29:23-05:00 rts/M32Alloc: Don't attempt to unmap non-existent pages The m32 allocator's `pages` list may contain NULLs in the case that the page was flushed. Some `munmap` implementations (e.g. FreeBSD's) don't like it if we pass them NULL. Don't do that. - - - - - 859db7d6 by Ömer Sinan Ağacan at 2020-02-01T14:18:49+03:00 Improve/fix -fcatch-bottoms documentation Old documentation suggests that -fcatch-bottoms only adds a default alternative to bottoming case expression, but that's not true. We use a very simplistic "is exhaustive" check and add default alternatives to any case expression that does not cover all constructors of the type. In case of GADTs this simple check assumes all constructors should be covered, even the ones ruled out by the type of the scrutinee. Update the documentation to reflect this. (Originally noticed in #17648) [ci skip] - - - - - 54dfa94a by John Ericson at 2020-02-03T21:14:24-05:00 Fix docs for FrontendResult Other variant was removed in ac1a379363618a6f2f17fff65ce9129164b6ef30 but docs were no changed. - - - - - 5e63d9c0 by John Ericson at 2020-02-03T21:15:02-05:00 Refactor HscMain.finish I found the old control flow a bit hard to follow; I rewrote it to first decide whether to desugar, and then use that choice when computing whether to simplify / what sort of interface file to write. I hope eventually we will always write post-tc interface files, which will make the logic of this function even simpler, and continue the thrust of this refactor. - - - - - e580e5b8 by Stefan Schulze Frielinghaus at 2020-02-04T09:29:00-05:00 Do not build StgCRunAsm.S for unregisterised builds For unregisterised builds StgRun/StgReturn are implemented via a mini interpreter in StgCRun.c and therefore would collide with the implementations in StgCRunAsm.S. - - - - - e3b0bd97 by Stefan Schulze Frielinghaus at 2020-02-04T09:29:00-05:00 fixup! fixup! Do not build StgCRunAsm.S for unregisterised builds - - - - - eb629fab by John Ericson at 2020-02-04T09:29:38-05:00 Delete some superfluous helper functions in HscMain The driver code is some of the nastiest in GHC, and I am worried about being able to untangle all the tech debt. In `HscMain` we have a number of helpers which are either not-used or little used. I delete them so we can reduce cognative load, distilling the essential complexity away from the cruft. - - - - - c90eca55 by Sebastian Graf at 2020-02-05T09:21:29-05:00 PmCheck: Record type constraints arising from existentials in `PmCoreCt`s In #17703 (a follow-up of !2192), we established that contrary to my belief, type constraints arising from existentials in code like ```hs data Ex where Ex :: a -> Ex f _ | let x = Ex @Int 15 = case x of Ex -> ... ``` are in fact useful. This commit makes a number of refactorings and improvements to comments, but fundamentally changes `addCoreCt.core_expr` to record the type constraint `a ~ Int` in addition to `x ~ Ex @a y` and `y ~ 15`. Fixes #17703. - - - - - 6d3b5d57 by Ömer Sinan Ağacan at 2020-02-05T09:22:10-05:00 testlib: Extend existing *_opts in extra_*_opts Previously we'd override the existing {run,hc} opts in extra_{run,hc}_opts, which caused flakiness in T1969, see #17712. extra_{run,hc}_opts now extends {run,hc} opts, instead of overriding. Also we shrank the allocation area for T1969 in order to increase residency sampling frequency. Fixes #17712 - - - - - 9c89a48d by Ömer Sinan Ağacan at 2020-02-05T09:22:52-05:00 Remove CafInfo-related code from STG lambda lift pass After c846618ae0 we don't have accurate CafInfos for Ids in the current module and we're free to introduce new CAFFY or non-CAFFY bindings or change CafInfos of existing binders; so no we no longer need to maintain CafInfos in Core or STG passes. - - - - - 70ddb8bf by Ryan Scott at 2020-02-05T09:23:30-05:00 Add regression test for #17773 - - - - - e8004e5d by Ben Gamari at 2020-02-05T13:55:19-05:00 gitlab-ci: Allow Windows builds to fail again Due to T7702 and the process issues described in #17777. - - - - - 29b72c00 by Ben Gamari at 2020-02-06T11:55:41-05:00 VarSet: Introduce nonDetFoldVarSet - - - - - c4e6b35d by Ben Gamari at 2020-02-06T11:55:41-05:00 Move closeOverKinds and friends to TyCoFVs - - - - - ed2f0e5c by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Reform the free variable finders for types This patch delivers on (much of) #17509. * Introduces the shallow vs deep free variable distinction * Introduce TyCoRep.foldType, foldType :: Monoid a => TyCoFolder env a -> env -> Type -> a and use it in the free variable finders. * Substitution in TyCoSubst * ASSERTs are on for checkValidSubst * checkValidSubst uses shallowTyCoVarsOfTypes etc Quite a few things still to do * We could use foldType in lots of other places * We could use mapType for substitution. (Check that we get good code!) * Some (but not yet all) clients of substitution can now save time by using shallowTyCoVarsOfTypes * All calls to tyCoVarsOfTypes should be inspected; most of them should be shallow. Maybe. * Currently shallowTyCoVarsOfTypes still returns unification variables, but not CoVarHoles. Reason: we need to return unification variables in some of the calls in TcSimplify, eg when promoting. * We should do the same thing for tyCoFVsOfTypes, which is currently unchanged. * tyCoFVsOfTypes returns CoVarHoles, because of the use in TcSimplify.mkResidualConstraints. See Note [Emitting the residual implication in simplifyInfer] * #17509 talks about "relevant" variables too. - - - - - 01a1f4fb by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Use foldTyCo for noFreeVarsOfType - - - - - 0e59afd6 by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Simplify closeOverKinds - - - - - 9ca5c88e by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Use foldTyCo for coVarsOfType - - - - - 5541b87c by Simon Peyton Jones at 2020-02-06T11:55:41-05:00 Use foldTyCo for exactTyCoVarsOfType This entailed * Adding a tcf_view field to TyCoFolder * Moving exactTyCoVarsOtType to TcType. It properly belongs there, since only the typechecker calls this function. But it also means that we can "see" and inline tcView. Metric Decrease: T14683 - - - - - 7c122851 by Simon Peyton Jones at 2020-02-06T11:56:02-05:00 Comments only - - - - - 588acb99 by Adam Sandberg Eriksson at 2020-02-08T10:15:38-05:00 slightly better named cost-centres for simple pattern bindings #17006 ``` main = do print $ g [1..100] a where g xs x = map (`mod` x) xs a :: Int = 324 ``` The above program previously attributed the cost of computing 324 to a cost centre named `(...)`, with this change the cost is attributed to `a` instead. This change only affects simple pattern bindings (decorated variables: type signatures, parens, ~ annotations and ! annotations). - - - - - 309f8cfd by Richard Eisenberg at 2020-02-08T10:16:33-05:00 Remove unnecessary parentheses - - - - - 7755ffc2 by Richard Eisenberg at 2020-02-08T10:16:33-05:00 Introduce IsPass; refactor wrappers. There are two main payloads of this patch: 1. This introduces IsPass, which allows e.g. printing code to ask what pass it is running in (Renamed vs Typechecked) and thus print extension fields. See Note [IsPass] in Hs.Extension 2. This moves the HsWrap constructor into an extension field, where it rightly belongs. This is done for HsExpr and HsCmd, but not for HsPat, which is left as an exercise for the reader. There is also some refactoring around SyntaxExprs, but this is really just incidental. This patch subsumes !1721 (sorry @chreekat). Along the way, there is a bit of refactoring in GHC.Hs.Extension, including the removal of NameOrRdrName in favor of NoGhcTc. This meant that we had no real need for GHC.Hs.PlaceHolder, so I got rid of it. Updates haddock submodule. ------------------------- Metric Decrease: haddock.compiler ------------------------- - - - - - 7d452be4 by Dylan Yudaken at 2020-02-08T10:17:17-05:00 Fix hs_try_putmvar losing track of running cap If hs_try_putmvar was called through an unsafe import, it would lose track of the running cap causing a deadlock - - - - - c2e301ae by Ben Gamari at 2020-02-08T10:17:55-05:00 compiler: Qualify imports of Data.List - - - - - aede171a by Ben Gamari at 2020-02-08T10:17:55-05:00 testsuite: Fix -Wcompat-unqualified-imports issues - - - - - 4435a8e0 by Ben Gamari at 2020-02-08T10:17:55-05:00 Introduce -Wcompat-unqualified-imports This implements the warning proposed in option (B) of the Data.List.singleton CLC [discussion][]. This warning, which is included in `-Wcompat` is intended to help users identify imports of modules that will change incompatibly in future GHC releases. This currently only includes `Data.List` due to the expected specialisation and addition of `Data.List.singleton`. Fixes #17244. [discussion]: https://groups.google.com/d/msg/haskell-core-libraries/q3zHLmzBa5E/PmlAs_kYAQAJ - - - - - 28b5349a by Ben Gamari at 2020-02-08T10:17:55-05:00 Bump stm and process submodules - - - - - 7d04b9f2 by Ben Gamari at 2020-02-08T10:18:31-05:00 hadrian: Allow override of Cabal configuration in hadrian.settings Fixes #17612 by adding a `cabal.configure.opts` key for `hadrian.settings`. - - - - - 88bf81aa by Andreas Klebinger at 2020-02-08T10:19:10-05:00 Optimize unpackCString# to allocate less. unpackCString# is a recursive function which for each iteration returns a Cons cell containing the current Char, and a thunk for unpacking the rest of the string. In this patch we change from storing addr + offset inside this thunk to storing only the addr, simply incrementing the address on each iteration. This saves one word of allocation per unpacked character. For a program like "main = print "<largishString>" this amounts to 2-3% fewer % in bytes allocated. I also removed the now redundant local unpack definitions. This removes one call per unpack operation. - - - - - bec76733 by Ben Gamari at 2020-02-08T10:19:57-05:00 Fix GhcThreaded setting This adopts a patch from NetBSD's packaging fixing the `GhcThreaded` option of the make build system. In addition we introduce a `ghcThreaded` option in hadrian's `Flavour` type. Also fix Hadrian's treatment of the `Use Threaded` entry in `settings`. Previously it would incorrectly claim `Use Threaded = True` if we were building the `threaded` runtime way. However, this is inconsistent with the `make` build system, which defines it to be whether the `ghc` executable is linked against the threaded runtime. Fixes #17692. - - - - - 545cf1e1 by Ben Gamari at 2020-02-08T10:20:37-05:00 hadrian: Depend upon libray dependencies when configuring packages This will hopefully fix #17631. - - - - - 047d3d75 by Ben Gamari at 2020-02-08T10:21:16-05:00 testsuite: Add test for #15316 This is the full testcase for T15316. - - - - - 768e5866 by Julien Debon at 2020-02-08T10:22:07-05:00 doc(Data.List): Add some examples to Data.List - - - - - 3900cb83 by Julien Debon at 2020-02-08T10:22:07-05:00 Apply suggestion to libraries/base/GHC/List.hs - - - - - bd666766 by Ben Gamari at 2020-02-08T10:22:45-05:00 users-guide: Clarify that bundled patsyns were introduced in GHC 8.0 Closes #17094. - - - - - 95741ea1 by Pepe Iborra at 2020-02-08T10:23:23-05:00 Update to hie-bios 0.3.2 style program cradle - - - - - fb5c1912 by Sylvain Henry at 2020-02-08T10:24:07-05:00 Remove redundant case This alternative is redundant and triggers no warning when building with 8.6.5 - - - - - 5d83d948 by Matthew Pickering at 2020-02-08T10:24:43-05:00 Add mkHieFileWithSource which doesn't read the source file from disk cc/ @pepeiborra - - - - - dfdae56d by Andreas Klebinger at 2020-02-08T10:25:20-05:00 Rename ghcAssert to stgAssert in hp2ps/Main.h. This fixes #17763 - - - - - 658f7ac6 by Ben Gamari at 2020-02-08T10:26:00-05:00 includes: Avoid using single-line comments in HsFFI.h While single-line comments are supported by C99, dtrace on SmartOS apparently doesn't support them yet. - - - - - c95920a6 by Ömer Sinan Ağacan at 2020-02-08T10:26:42-05:00 Import qualified Prelude in parser This is in preparation of backwards-incompatible changes in happy. See https://github.com/simonmar/happy/issues/166 - - - - - b6dc319a by Ömer Sinan Ağacan at 2020-02-08T10:27:23-05:00 Add regression test for #12760 The bug seems to be fixed in the meantime, make sure it stays fixed. Closes #12760 - - - - - b3857b62 by Ben Gamari at 2020-02-08T10:28:03-05:00 base: Drop out-of-date comment The comment in GHC.Base claimed that ($) couldn't be used in that module as it was wired-in. However, this is no longer true; ($) is merely known key and is defined in Haskell (with a RuntimeRep-polymorphic type) in GHC.Base. The one piece of magic that ($) retains is that it a special typing rule to allow type inference with higher-rank types (e.g. `runST $ blah`; see Note [Typing rule for ($)] in TcExpr). - - - - - 1183ae94 by Daniel Gröber at 2020-02-08T10:29:00-05:00 rts: Fix Arena blocks accounting for MBlock sized allocations When requesting more than BLOCKS_PER_MBLOCK blocks allocGroup can return a different number of blocks than requested. Here we use the number of requested blocks, however arenaFree will subtract the actual number of blocks we got from arena_blocks (possibly) resulting in a negative value and triggering ASSERT(arena_blocks >= 0). - - - - - 97d59db5 by Daniel Gröber at 2020-02-08T10:29:48-05:00 rts: Fix need_prealloc being reset when retainer profiling is on - - - - - 1f630025 by Krzysztof Gogolewski at 2020-02-09T02:52:27-05:00 Add a test for #15712 - - - - - 2ac784ab by Ben Gamari at 2020-02-09T02:53:05-05:00 hadrian: Add --test-metrics argument Allowing the test metric output to be captured to a file, a la the METRIC_FILE environment variable of the make build system. - - - - - f432d8c6 by Ben Gamari at 2020-02-09T02:53:05-05:00 hadrian: Fix --test-summary argument This appears to be a cut-and-paste error. - - - - - a906595f by Arnaud Spiwack at 2020-02-09T02:53:50-05:00 Fix an outdated note link This link appears to have been forgotten in 0dad81ca5fd1f63bf8a3b6ad09787559e8bd05c0 . - - - - - 3ae83da1 by Alp Mestanogullari at 2020-02-09T02:54:28-05:00 hadrian: Windows fixes (bindists, CI) This commit implements a few Windows-specific fixes which get us from a CI job that can't even get as far as starting the testsuite driver, to a state where we can run the entire testssuite (but have test failures to fix). - Don't forget about a potential extension for the haddock program, when preparing the bindist. - Build the timeout program, used by the testsuite driver on Windows in place of the Python script used elsewhere, using the boot compiler. We could alternatively build it with the compiler that we're going to test but this would be a lot more tedious to write. - Implement a wrapper-script less installation procedure for Windows, in `hadrian/bindist/Makefile. - Make dependencies a bit more accurate in the aforementioned Makefile. - Update Windows/Hadrian CI job accordingly. This patch fixes #17486. - - - - - 82f9be8c by Roland Senn at 2020-02-09T02:55:06-05:00 Fix #14628: Panic (No skolem Info) in GHCi This patch implements the [sugggestion from Simon (PJ)](https://gitlab.haskell.org/ghc/ghc/issues/14628#note_146559): - Make `TcErrors.getSkolemInfo` return a `SkolemInfo` rather than an `Implication`. - If `getSkolemInfo` gets `RuntimeUnk`s, just return a new data constructor in `SkolemInfo`, called `RuntimeUnkSkol`. - In `TcErrors.pprSkols` print something sensible for a `RuntimeUnkSkol`. The `getSkolemInfo` function paniced while formating suggestions to add type annotations (subfunction `suggestAddSig`) to a *"Couldn't match type ‘x’ with ‘y’"* error message. The `getSkolemInfo` function didn't find any Implication value and paniced. With this patch the `getSkolemInfo` function does no longer panic, if it finds `RuntimeUnkSkol`s. As the panic occured while processing an error message, we don't need to implement any new error message! - - - - - b2e18e26 by Andreas Klebinger at 2020-02-09T02:55:46-05:00 Fix -ddump-stg-final. Once again make sure this dumps the STG used for codegen. - - - - - 414e2f62 by Sylvain Henry at 2020-02-09T02:56:26-05:00 Force -fPIC for intree GMP (fix #17799) Configure intree GMP with `--with-pic` instead of patching it. Moreover the correct patching was only done for x86_64/darwin (see #17799). - - - - - f0fd72ee by Sebastian Graf at 2020-02-09T17:22:38-05:00 8.10 Release notes for improvements to the pattern-match checker [skip ci] A little late to the game, but better late than never. - - - - - 00dc0f7e by Ömer Sinan Ağacan at 2020-02-09T17:23:17-05:00 Add regression test for #13142 Closes #13142 - - - - - f3e737bb by Sebastian Graf at 2020-02-10T20:04:09-05:00 Fix long distance info for record updates For record updates where the `record_expr` is a variable, as in #17783: ```hs data PartialRec = No | Yes { a :: Int, b :: Bool } update No = No update r@(Yes {}) = r { b = False } ``` We should make use of long distance info in `-Wincomplete-record-updates` checking. But the call to `matchWrapper` in the `RecUpd` case didn't specify a scrutinee expression, which would correspond to the `record_expr` `r` here. That is fixed now. Fixes #17783. - - - - - 5670881d by Tamar Christina at 2020-02-10T20:05:04-05:00 Fs: Fix UNC remapping code. - - - - - 375b3c45 by Oleg Grenrus at 2020-02-11T05:07:30-05:00 Add singleton to Data.OldList - - - - - de32beff by Richard Eisenberg at 2020-02-11T05:08:10-05:00 Do not create nested quantified constraints Previously, we would accidentally make constraints like forall a. C a => forall b. D b => E a b c as we traversed superclasses. No longer! This patch also expands Note [Eagerly expand given superclasses] to work over quantified constraints; necessary for T16502b. Close #17202 and #16502. test cases: typecheck/should_compile/T{17202,16502{,b}} - - - - - e319570e by Ben Gamari at 2020-02-11T05:08:47-05:00 rts: Use nanosleep instead of usleep usleep was removed in POSIX.1-2008. - - - - - b75e7486 by Ben Gamari at 2020-02-11T05:09:24-05:00 rts: Remove incorrect assertions around MSG_THROWTO messages Previously we would assert that threads which are sending a `MSG_THROWTO` message must have their blocking status be blocked on the message. In the usual case of a thread throwing to another thread this is guaranteed by `stg_killThreadzh`. However, `throwToSelf`, used by the GC to kill threads which ran out of heap, failed to guarantee this. Noted while debugging #17785. - - - - - aba51b65 by Sylvain Henry at 2020-02-11T05:10:04-05:00 Add arithmetic exception primops (#14664) - - - - - b157399f by Ben Gamari at 2020-02-11T05:10:40-05:00 configure: Don't assume Gnu linker on Solaris Compl Yue noticed that the linker was dumping the link map on SmartOS. This is because Smartos uses the Solaris linker, which uses the `-64` flag, not `-m64` like Gnu ld, to indicate that it should link for 64-bits. Fix the configure script to handle the Solaris linker correctly. - - - - - d8d73d77 by Simon Peyton Jones at 2020-02-11T05:11:18-05:00 Notes only: telescopes This documentation-only patch fixes #17793 - - - - - 58a4ddef by Alp Mestanogullari at 2020-02-11T05:12:17-05:00 hadrian: build (and ship) iserv on Windows - - - - - 82023524 by Matthew Pickering at 2020-02-11T18:04:17-05:00 TemplateHaskellQuotes: Allow nested splices There is no issue with nested splices as they do not require any compile time code execution. All execution is delayed until the top-level splice. - - - - - 50e24edd by Ömer Sinan Ağacan at 2020-02-11T18:04:57-05:00 Remove Hadrian's copy of (Data.Functor.<&>) The function was added to base with base-4.11 (GHC 8.4) - - - - - f82a2f90 by Sylvain Henry at 2020-02-12T01:56:46-05:00 Document GMP build [skip ci] - - - - - da7f7479 by Sylvain Henry at 2020-02-12T01:57:27-05:00 Module hierarchy: ByteCode and Runtime (cf #13009) Update haddock submodule - - - - - 04f51297 by Ömer Sinan Ağacan at 2020-02-12T01:58:11-05:00 Fix naming of tests for #12923 - - - - - 31fc3321 by Ömer Sinan Ağacan at 2020-02-12T01:58:11-05:00 Add regression test for #12926 Closes #12926 - - - - - f0c0ee7d by Krzysztof Gogolewski at 2020-02-12T01:58:51-05:00 Fix order of arguments in specializer (#17801) See https://gitlab.haskell.org/ghc/ghc/issues/17801#note_253330 No regression test, as it's hard to trigger. - - - - - 059c3c9d by Sebastian Graf at 2020-02-12T11:00:58+01:00 Separate CPR analysis from the Demand analyser The reasons for that can be found in the wiki: https://gitlab.haskell.org/ghc/ghc/wikis/nested-cpr/split-off-cpr We now run CPR after demand analysis (except for after the final demand analysis run just before code gen). CPR got its own dump flags (`-ddump-cpr-anal`, `-ddump-cpr-signatures`), but not its own flag to activate/deactivate. It will run with `-fstrictness`/`-fworker-wrapper`. As explained on the wiki page, this step is necessary for a sane Nested CPR analysis. And it has quite positive impact on compiler performance: Metric Decrease: T9233 T9675 T9961 T15263 - - - - - f5ffd8d9 by Ben Gamari at 2020-02-12T17:22:37-05:00 base: Expose GHC.Unicode.unicodeVersion This exposes a Data.Version.Version representing the version of the Unicode database used by `base`. This should clear up some confusion I have seen in tickets regarding with which Unicode versions a given GHC can be expected to work. While in town I also regenerated (but did not update) the Unicode database with database 12.0.0. Strangely, the file cited in the README no longer existed. Consequently, I used https://www.unicode.org/Public/12.0.0/ucd/UnicodeData.txt and was slightly surprised to find that there were a few changes. - - - - - 6c2585e0 by Ben Gamari at 2020-02-12T17:22:37-05:00 base: Update Unicode database to 12.1.0 Using `curl https://www.unicode.org/Public/12.1.0/ucd/UnicodeData.txt | libraries/base/cbits/ubconfc 12.1.0`. - - - - - df084681 by Krzysztof Gogolewski at 2020-02-12T23:58:52+01:00 Always display inferred variables using braces We now always show "forall {a}. T" for inferred variables, previously this was controlled by -fprint-explicit-foralls. This implements part 1 of https://github.com/ghc-proposals/ghc-proposals/pull/179. Part of GHC ticket #16320. Furthermore, when printing a levity restriction error, we now display the HsWrap of the expression. This lets users see the full elaboration with -fprint-typechecker-elaboration (see also #17670) - - - - - 16d643cf by Sylvain Henry at 2020-02-13T09:16:04-05:00 Remove -ddump-srts flag This flag is deemed not useful. - - - - - fa28ae95 by Sylvain Henry at 2020-02-13T09:16:04-05:00 Fix flag documentation (#17826) - - - - - 1bfd8259 by Sylvain Henry at 2020-02-13T09:16:43-05:00 Ensure that Hadrian is built correctly before using it When Hadrian failed to build, the script would pick a previously built Hadrian (if available) instead of failing. - - - - - cd6e786a by Ömer Sinan Ağacan at 2020-02-14T05:29:56-05:00 Add test for #17648 - - - - - 9f2c3677 by Sylvain Henry at 2020-02-14T05:30:39-05:00 GMP expects the Target platform as --host parameter - - - - - aa6086fd by Oleg Grenrus at 2020-02-14T05:31:16-05:00 Add explicit LANGUAGE Safe to template-haskell (cherry picked from commit a5e0f376821ca882880b03b07b451aa574e289ec) - - - - - af6a0c36 by Ben Gamari at 2020-02-14T05:31:53-05:00 hadrian: Add execution and target architecture to stage-compilation figure - - - - - cf739945 by Sylvain Henry at 2020-02-14T05:32:37-05:00 Module hierarchy: HsToCore (cf #13009) - - - - - 719db318 by Simon Peyton Jones at 2020-02-14T05:33:16-05:00 De-duplicate overlapping Notes Documentation only. Fixes #17827 - - - - - 7550417a by Sylvain Henry at 2020-02-14T05:33:56-05:00 Hadrian: drop Sphinx flag checking for PDF documentation (#17825) It seems that Sphinx produces the ghc-flags.txt in doc/users_guide/_build rather than pdfRoot. We could copy ghc-flags.txt into pdfRoot (like happens naturally in the HTML case) but the benefit is pretty small. Let's just only check the HTML case. - - - - - 813842f4 by Ben Gamari at 2020-02-14T10:16:36-05:00 make: Be more selective in building windows-extra-src tarball - - - - - 0725f4bb by Ben Gamari at 2020-02-14T10:16:36-05:00 Rework handling of win32 toolchain tarballs - - - - - 565ce7ae by Ben Gamari at 2020-02-14T10:16:36-05:00 gitlab-ci: Consolidate CI logic This moves nearly all of the CI logic to .gitlab/ci.sh. This improves things in a number of ways: * it's harder for inconsistencies to arise between architectures * it's easier to share logic between architectures * on Windows, it's easier to ensure that all CI steps are executed from within a properly initialized mingw session. While in town I also add a FreeBSD build job and update the Windows job to use the gitlab-runner PowerShell executor, since cmd.exe will be deprecated soon (fixing #17699). - - - - - 9cbace74 by Ben Gamari at 2020-02-14T10:16:36-05:00 gitlab-ci: Deduplicate nightly job configuration - - - - - 6e837144 by Ben Gamari at 2020-02-14T10:16:36-05:00 integer-gmp: Fix unused command-line argument -L is only needed during linking. - - - - - e5ee07ab by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Don't ask sed to operate in-place on symlinks Some sed implementations (e.g. FreeBSD) refuse to operate in-place on symlinks. - - - - - 71e5e68f by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Disable tests that assume name of libstdc++ on FreeBSD - - - - - 7b2da0f4 by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite: Mark T6132 as broken on FreeBSD - - - - - 8ef7a15a by Ben Gamari at 2020-02-14T10:16:36-05:00 testsuite/T16930: Don't rely on gnu grep specific --include In BSD grep this flag only affects directory recursion. - - - - - 6060003e by Ben Gamari at 2020-02-14T10:16:36-05:00 Pass -Wno-unused-command-line-arguments during link on FreeBSD FreeBSD cc throws a warning if we pass -pthread without actually using any pthread symbols. - - - - - 97497bae by Ben Gamari at 2020-02-14T10:16:36-05:00 base: Always clamp reads/writes to 2GB in length Previously we did this only on Darwin due to #17414. However, even on other platforms >2GB writes are on shaky ground. POSIX explicitly says that the result is implementation-specified and Linux will write at most 0x7ffff000, even on 64-bit platforms. Moreover, getting the sign of the syscall result correct is tricky, as demonstrated by the fact that T17414 currently fails on FreeBSD. For simplicity we now just uniformly clamp to 0x7ffff000 on all platforms. - - - - - 49be2a3f by Ben Gamari at 2020-02-14T10:16:36-05:00 configure: Fix sphinx version test The check for the "v" prefix is redundant. - - - - - f7f7a556 by Ben Gamari at 2020-02-14T10:16:37-05:00 users-guide: Fix unknown link targets - - - - - a204102c by Ben Gamari at 2020-02-14T10:16:37-05:00 docs/compare-flags: Don't use python f-strings - - - - - 92e15a37 by Ben Gamari at 2020-02-14T10:16:37-05:00 gitlab-ci: Fix various shellcheck warnings - - - - - 459f7c6e by Ben Gamari at 2020-02-14T10:16:37-05:00 hadrian: Drop empty arguments from target list Fixes #17748. - - - - - c06df28d by Ben Gamari at 2020-02-14T10:16:37-05:00 users-guide: Fix "invalid file" failure I have no idea how this worked previously. Different Python version? - - - - - 3fe8444f by Ben Gamari at 2020-02-14T10:16:59-05:00 testsuite: Mark T7702 as fragile on Windows Due to #16799. There was previously an attempt to mark it as broken but the `opsys` name was incorrect. - - - - - fe02f781 by Ben Gamari at 2020-02-14T10:16:59-05:00 testsuite: Assert the opsys names are known Previously opsys would take any string. This meant it was very easy for a typo to silently render the predicate ineffective. Fix this by checking the given operating system name against a list of known values. - - - - - 149e2a3a by Ben Gamari at 2020-02-14T10:16:59-05:00 compare-flags: Don't rely on encoding flag of subprocess.check_output Apparently it isn't supported by some slightly older Python versions. - - - - - 798d59f6 by Ben Gamari at 2020-02-14T10:16:59-05:00 rts: Add more debug output to failed path in onIOComplete This will help track down #17035. - - - - - e35f3f98 by Ben Gamari at 2020-02-14T10:16:59-05:00 gitlab-ci: Allow i386 Windows builds to fail again Due to the resistance of #17736 to resolution. - - - - - 261a3cf8 by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Build integer-simple job in the validate flavour - - - - - b613a961 by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Always use mingw64 python on Windows - - - - - 1bc8c8cd by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Allow Windows build to fail due to #17777 The fact that `exec` isn't POSIX compliant means that things can break in arbitrarily bad ways. Sometimes things happen to work correctly but sadly this isn't always the case. - - - - - ac63020d by Ben Gamari at 2020-02-14T10:17:00-05:00 gitlab-ci: Drop unnecessary GHC_VERSION check - - - - - 6926f369 by Ben Gamari at 2020-02-14T10:17:00-05:00 Bump process submodule Folds in the second part of Phyx's Windows process exit fixes [1], hopefully finally resolving issue #17480. [1] https://github.com/haskell/process/pull/160 - - - - - 584eee71 by Tamar Christina at 2020-02-14T10:17:00-05:00 SysTools: Use "process job" when spawning processes on Windows GHC should make calls using process jobs when calling out to GCC and LD. The reason is these use the exec () family of posix functions. Window's process model doesn't allow replacement of processes so this is emulated by creating a new process and immediately exiting the old one. Because of this when using normal Windows wait functions you would return even without the child process having finished. In this case if you are depending on data from the child you will enter a race condition. The usual fix for this is to use process jobs and wait for the termination of all children that have ever been spawn by the process you called. But also waiting for the freeing of all resources. - - - - - ecabfa28 by Tamar Christina at 2020-02-14T10:17:00-05:00 Revert "compiler: Disable atomic renaming on Windows" The original reason this was disabled should be fixed by the previous commit. This reverts commit 1c1b63d63efe8b0f789aa7d5b87cfac3edd213eb. - - - - - 06d60c66 by Ben Gamari at 2020-02-14T10:17:00-05:00 Bump Cabal submodule - - - - - 8cabb384 by Ben Gamari at 2020-02-14T10:17:00-05:00 compare-flags: Fix output - - - - - 8cf646d3 by Ben Gamari at 2020-02-14T10:17:00-05:00 users-guide: Document -ddump-srts - - - - - 932307a5 by Ben Gamari at 2020-02-14T10:17:00-05:00 users-guide: Fix broken reference - - - - - e77818de by Ben Gamari at 2020-02-15T09:26:55-05:00 Accept performance changes These manifested in the integer-simple job. Metric Decrease: T12227 T5549 T14936 T4830 Conversions T5237 T8766 T4801 T10359 Metric Increase: T12234 T6048 T3294 T14683 T3064 T9872b T9872c T783 T5837 T10678 T14697 T5631 T9203 T13719 T12707 T13056 T9630 T10547 T9872d T1969 WWRec T10370 T5321FD haddock.Cabal T5642 T9872a T15263 T12425 MultiLayerModules T5205 T9233 T13379 haddock.base T9020 T13035 T12150 T9961 - - - - - 785008c1 by Ben Gamari at 2020-02-15T09:30:13-05:00 testsuite: Sort test names in expected change output - - - - - 9e851472 by Ömer Sinan Ağacan at 2020-02-16T10:38:41+03:00 Revert "users-guide: Document -ddump-srts" This reverts commit 8cf646d36b02b8ea1c289cb52781c9171853b514. The flag was removed by 16d643cf. [ci skip] - - - - - 9792c816 by Ben Gamari at 2020-02-16T09:47:08-05:00 testsuite: Probe whether symlinks are usable on Windows Closes #17706. - - - - - ee1e5342 by Vladislav Zavialov at 2020-02-16T09:47:44-05:00 Fix the "unused terminals: 2" warning in Parser.y - - - - - b4a8ce52 by Roland Senn at 2020-02-18T20:14:42-05:00 If a :reload finds syntax errors in the module graph, remove the loaded modules. (Fixes #17549) The processing in `compiler/main/GhcMake.hs` computes the ModuleGraph. If it finds errors in the module header or in the import specifications, then the new module graph is incomplete and should not be used. The code before #17549 just reported the errors and left the old ModuleGraph in place. The new code of this MR replaces the old ModuleGraph with an empty one. - - - - - d7029cc0 by Sylvain Henry at 2020-02-18T20:15:30-05:00 Hadrian: refactor GMP in-tree build support (#17756) * Hadrian doesn't use integer-gmp/config.mk file anymore to determine if building GMP in-tree is required. "config.mk" is created by Cabal when the integer-gmp package is configured and this file is still untracked by Hadrian. This led to a tricky configure "race" because "config.mk" is built by the "setup-config" rule, but this rule is also used to find dependencies, in particular the "ghc-gmp.h" header, but the creation of this file was depending (without being tracked) on "config.mk". Now Hadrian only builds in-tree GMP if `--with-intree-gmp` is passed to the top-level configure script. * in-tree GMP isn't built once for all in a fixed stage (Stage1) anymore. It is built per stage which is required if we build a cross-compiler * switching between in-tree and external GMP is now supported without having to clean the build directory first. * "wrappers.c" now includes "ghc-gmp.h" instead of "ghc.h". It helps ensuring that the build system generates "ghc-gmp.h". * build in-tree GMP in "<root>/stageN/gmp/gmpbuild" and produce useful artefacts (libgmp.a, gmp.h, objs/*.o) in "<root>/stageN/gmp" - - - - - 40d917fb by Vladislav Zavialov at 2020-02-18T20:16:07-05:00 Remove the MonadFail P instance There were two issues with this instance: * its existence meant that a pattern match failure in the P monad would produce a user-visible parse error, but the error message would not be helpful to the user * due to the MFP migration strategy, we had to use CPP in Lexer.x, and that created issues for #17750 Updates haddock submodule. - - - - - 5a1ce45d by Joshua Price at 2020-02-18T20:16:47-05:00 Fix unboxed tuple size limit (#17837) - - - - - 192caf58 by Vladislav Zavialov at 2020-02-18T20:17:24-05:00 Fix testsuite driver output (#17847) - - - - - 1500f089 by Sylvain Henry at 2020-02-18T20:18:12-05:00 Modules: Llvm (#13009) - - - - - d53e81c0 by Niklas Hambüchen at 2020-02-20T10:36:22-05:00 8.10 Release notes for atomic .o writes [skip ci] - - - - - 19680ee5 by Niklas Hambüchen at 2020-02-20T10:37:53-05:00 8.10 Release notes for --disable-delayed-os-memory-return [skip ci] - - - - - 74ad75e8 by Simon Peyton Jones at 2020-02-20T21:17:57-05:00 Re-implement unsafe coercions in terms of unsafe equality proofs (Commit message written by Omer, most of the code is written by Simon and Richard) See Note [Implementing unsafeCoerce] for how unsafe equality proofs and the new unsafeCoerce# are implemented. New notes added: - [Checking for levity polymorphism] in CoreLint.hs - [Implementing unsafeCoerce] in base/Unsafe/Coerce.hs - [Patching magic definitions] in Desugar.hs - [Wiring in unsafeCoerce#] in Desugar.hs Only breaking change in this patch is unsafeCoerce# is not exported from GHC.Exts, instead of GHC.Prim. Fixes #17443 Fixes #16893 NoFib ----- -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS -0.1% 0.0% -0.0% -0.0% -0.0% CSD -0.1% 0.0% -0.0% -0.0% -0.0% FS -0.1% 0.0% -0.0% -0.0% -0.0% S -0.1% 0.0% -0.0% -0.0% -0.0% VS -0.1% 0.0% -0.0% -0.0% -0.0% VSD -0.1% 0.0% -0.0% -0.0% -0.1% VSM -0.1% 0.0% -0.0% -0.0% -0.0% anna -0.0% 0.0% -0.0% -0.0% -0.0% ansi -0.1% 0.0% -0.0% -0.0% -0.0% atom -0.1% 0.0% -0.0% -0.0% -0.0% awards -0.1% 0.0% -0.0% -0.0% -0.0% banner -0.1% 0.0% -0.0% -0.0% -0.0% bernouilli -0.1% 0.0% -0.0% -0.0% -0.0% binary-trees -0.1% 0.0% -0.0% -0.0% -0.0% boyer -0.1% 0.0% -0.0% -0.0% -0.0% boyer2 -0.1% 0.0% -0.0% -0.0% -0.0% bspt -0.1% 0.0% -0.0% -0.0% -0.0% cacheprof -0.1% 0.0% -0.0% -0.0% -0.0% calendar -0.1% 0.0% -0.0% -0.0% -0.0% cichelli -0.1% 0.0% -0.0% -0.0% -0.0% circsim -0.1% 0.0% -0.0% -0.0% -0.0% clausify -0.1% 0.0% -0.0% -0.0% -0.0% comp_lab_zift -0.1% 0.0% -0.0% -0.0% -0.0% compress -0.1% 0.0% -0.0% -0.0% -0.0% compress2 -0.1% 0.0% -0.0% -0.0% -0.0% constraints -0.1% 0.0% -0.0% -0.0% -0.0% cryptarithm1 -0.1% 0.0% -0.0% -0.0% -0.0% cryptarithm2 -0.1% 0.0% -0.0% -0.0% -0.0% cse -0.1% 0.0% -0.0% -0.0% -0.0% digits-of-e1 -0.1% 0.0% -0.0% -0.0% -0.0% digits-of-e2 -0.1% 0.0% -0.0% -0.0% -0.0% dom-lt -0.1% 0.0% -0.0% -0.0% -0.0% eliza -0.1% 0.0% -0.0% -0.0% -0.0% event -0.1% 0.0% -0.0% -0.0% -0.0% exact-reals -0.1% 0.0% -0.0% -0.0% -0.0% exp3_8 -0.1% 0.0% -0.0% -0.0% -0.0% expert -0.1% 0.0% -0.0% -0.0% -0.0% fannkuch-redux -0.1% 0.0% -0.0% -0.0% -0.0% fasta -0.1% 0.0% -0.5% -0.3% -0.4% fem -0.1% 0.0% -0.0% -0.0% -0.0% fft -0.1% 0.0% -0.0% -0.0% -0.0% fft2 -0.1% 0.0% -0.0% -0.0% -0.0% fibheaps -0.1% 0.0% -0.0% -0.0% -0.0% fish -0.1% 0.0% -0.0% -0.0% -0.0% fluid -0.1% 0.0% -0.0% -0.0% -0.0% fulsom -0.1% 0.0% +0.0% +0.0% +0.0% gamteb -0.1% 0.0% -0.0% -0.0% -0.0% gcd -0.1% 0.0% -0.0% -0.0% -0.0% gen_regexps -0.1% 0.0% -0.0% -0.0% -0.0% genfft -0.1% 0.0% -0.0% -0.0% -0.0% gg -0.1% 0.0% -0.0% -0.0% -0.0% grep -0.1% 0.0% -0.0% -0.0% -0.0% hidden -0.1% 0.0% -0.0% -0.0% -0.0% hpg -0.1% 0.0% -0.0% -0.0% -0.0% ida -0.1% 0.0% -0.0% -0.0% -0.0% infer -0.1% 0.0% -0.0% -0.0% -0.0% integer -0.1% 0.0% -0.0% -0.0% -0.0% integrate -0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide -0.1% 0.0% -0.0% -0.0% -0.0% kahan -0.1% 0.0% -0.0% -0.0% -0.0% knights -0.1% 0.0% -0.0% -0.0% -0.0% lambda -0.1% 0.0% -0.0% -0.0% -0.0% last-piece -0.1% 0.0% -0.0% -0.0% -0.0% lcss -0.1% 0.0% -0.0% -0.0% -0.0% life -0.1% 0.0% -0.0% -0.0% -0.0% lift -0.1% 0.0% -0.0% -0.0% -0.0% linear -0.1% 0.0% -0.0% -0.0% -0.0% listcompr -0.1% 0.0% -0.0% -0.0% -0.0% listcopy -0.1% 0.0% -0.0% -0.0% -0.0% maillist -0.1% 0.0% -0.0% -0.0% -0.0% mandel -0.1% 0.0% -0.0% -0.0% -0.0% mandel2 -0.1% 0.0% -0.0% -0.0% -0.0% mate -0.1% 0.0% -0.0% -0.0% -0.0% minimax -0.1% 0.0% -0.0% -0.0% -0.0% mkhprog -0.1% 0.0% -0.0% -0.0% -0.0% multiplier -0.1% 0.0% -0.0% -0.0% -0.0% n-body -0.1% 0.0% -0.0% -0.0% -0.0% nucleic2 -0.1% 0.0% -0.0% -0.0% -0.0% para -0.1% 0.0% -0.0% -0.0% -0.0% paraffins -0.1% 0.0% -0.0% -0.0% -0.0% parser -0.1% 0.0% -0.0% -0.0% -0.0% parstof -0.1% 0.0% -0.0% -0.0% -0.0% pic -0.1% 0.0% -0.0% -0.0% -0.0% pidigits -0.1% 0.0% -0.0% -0.0% -0.0% power -0.1% 0.0% -0.0% -0.0% -0.0% pretty -0.1% 0.0% -0.1% -0.1% -0.1% primes -0.1% 0.0% -0.0% -0.0% -0.0% primetest -0.1% 0.0% -0.0% -0.0% -0.0% prolog -0.1% 0.0% -0.0% -0.0% -0.0% puzzle -0.1% 0.0% -0.0% -0.0% -0.0% queens -0.1% 0.0% -0.0% -0.0% -0.0% reptile -0.1% 0.0% -0.0% -0.0% -0.0% reverse-complem -0.1% 0.0% -0.0% -0.0% -0.0% rewrite -0.1% 0.0% -0.0% -0.0% -0.0% rfib -0.1% 0.0% -0.0% -0.0% -0.0% rsa -0.1% 0.0% -0.0% -0.0% -0.0% scc -0.1% 0.0% -0.1% -0.1% -0.1% sched -0.1% 0.0% -0.0% -0.0% -0.0% scs -0.1% 0.0% -0.0% -0.0% -0.0% simple -0.1% 0.0% -0.0% -0.0% -0.0% solid -0.1% 0.0% -0.0% -0.0% -0.0% sorting -0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm -0.1% 0.0% -0.0% -0.0% -0.0% sphere -0.1% 0.0% -0.0% -0.0% -0.0% symalg -0.1% 0.0% -0.0% -0.0% -0.0% tak -0.1% 0.0% -0.0% -0.0% -0.0% transform -0.1% 0.0% -0.0% -0.0% -0.0% treejoin -0.1% 0.0% -0.0% -0.0% -0.0% typecheck -0.1% 0.0% -0.0% -0.0% -0.0% veritas -0.0% 0.0% -0.0% -0.0% -0.0% wang -0.1% 0.0% -0.0% -0.0% -0.0% wave4main -0.1% 0.0% -0.0% -0.0% -0.0% wheel-sieve1 -0.1% 0.0% -0.0% -0.0% -0.0% wheel-sieve2 -0.1% 0.0% -0.0% -0.0% -0.0% x2n1 -0.1% 0.0% -0.0% -0.0% -0.0% -------------------------------------------------------------------------------- Min -0.1% 0.0% -0.5% -0.3% -0.4% Max -0.0% 0.0% +0.0% +0.0% +0.0% Geometric Mean -0.1% -0.0% -0.0% -0.0% -0.0% Test changes ------------ - break006 is marked as broken, see #17833 - The compiler allocates less when building T14683 (an unsafeCoerce#- heavy happy-generated code) on 64-platforms. Allocates more on 32-bit platforms. - Rest of the increases are tiny amounts (still enough to pass the threshold) in micro-benchmarks. I briefly looked at each one in a profiling build: most of the increased allocations seem to be because of random changes in the generated code. Metric Decrease: T14683 Metric Increase: T12150 T12234 T12425 T13035 T14683 T5837 T6048 Co-Authored-By: Richard Eisenberg <rae at cs.brynmawr.edu> Co-Authored-By: Ömer Sinan Ağacan <omeragacan at gmail.com> - - - - - 6880d6aa by Sylvain Henry at 2020-02-20T21:18:48-05:00 Disentangle DynFlags and SDoc Remove several uses of `sdocWithDynFlags`. The remaining ones are mostly CodeGen related (e.g. depend on target platform constants) and will be fixed separately. Metric Decrease: T12425 T9961 WWRec T1969 T14683 - - - - - 70a90110 by Julien Debon at 2020-02-20T21:19:27-05:00 doc(List): Add examples to GHC.List * Add examples * Cleanup documentation * Clarify merge process and Marge bot - - - - - c8439fc7 by Peter Trommler at 2020-02-20T21:20:05-05:00 Fix testsuite on powerpc64le Remove expect broken on recomp tests, #11260 was closed by !2264 and #11323 most likely by !2264 as well. GHCi scripts tests work on GHCi but not the external interpreter, adjust test configuration accordingly. Fixes unexpected passes. Mark test requiring DWARF expect fail on powerpc64[le] for #11261. - - - - - 65b7256a by Ömer Sinan Ağacan at 2020-02-20T21:20:45-05:00 Use concatMap(M) instead of `concat . map` and the monadic variant - - - - - 8b76d457 by Roland Senn at 2020-02-20T21:21:28-05:00 Fix #17832: Weird handling of exports named main in 8.10-rc1 Switching from `lookupGlobalOccRn_maybe` to `lookupInfoOccRn` to check whether a `main` function is in scope. Unfortunately `lookupGlobalOccRn_maybe` complains if there are multiple `main` functions in scope. - - - - - 466e1ad5 by Krzysztof Gogolewski at 2020-02-20T21:22:11-05:00 Use TTG for HsSplicedT constructor The constructor HsSplicedT occurs only in the GhcTc pass. This enforces this fact statically via TTG. - - - - - 4e622fca by Alexis King at 2020-02-20T21:22:49-05:00 Normalize types when dropping absent arguments from workers fixes #17852 - - - - - a533e547 by Adam Sandberg Eriksson at 2020-02-20T21:23:31-05:00 Mention users guide and release notes in merge request template - - - - - 05251b17 by Ben Gamari at 2020-02-20T21:24:08-05:00 gitlab-ci: Fix typo in BIN_DIST_PREP_TAR_COMP variable name - - - - - f44c7e67 by Ben Gamari at 2020-02-20T21:24:46-05:00 gitlab-ci: Avoid duplicating ~/.cabal contents with every build Previously our attempt to cache the cabal store would `cp cabal-cache ~/.cabal`. However, if the latter already existed this meant that we would end up with ~/.cabal/cabal-cache. Not only would this not help caching but it would exponentially grow the size of ~/.cabal. Not good! - - - - - c5ec9965 by Ben Gamari at 2020-02-20T21:56:13-05:00 GHC.Hs.Extension: Use Type instead of * - - - - - 89cb4cc4 by Ben Gamari at 2020-02-20T21:56:13-05:00 Use Type instead of * in GHC - - - - - 04eb0d6c by Ben Gamari at 2020-02-20T21:56:13-05:00 Enable -Wstar-is-type in -Wall As noted in [proposal 0143][proposal] this is supposed to happen in 8.12. Also fix an incorrect claim in the users guide that -Wstar-is-type is enabled by default. [proposal]: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0143-remove-star-kind.rst - - - - - 6de966f1 by Andreas Klebinger at 2020-02-20T21:56:15-05:00 Fix #17724 by having occAnal preserve used bindings. It sometimes happened that occAnal would remove bindings as dead code by relying on bindings to be in dependency order. The fix was contributed by SPJ. - - - - - abd7f962 by Ben Gamari at 2020-02-20T21:56:15-05:00 users-guide: Mention dependency on `exceptions` in release notes Fixes #17845. - - - - - 58175379 by Sylvain Henry at 2020-02-20T21:56:20-05:00 Hadrian: minor GMP refactoring Somehow I forgot to totally remove `gmpContext` in d7029cc09edc052c2f97effe33233c53340fcce0. This patch fixes it and adds some additional comments. - - - - - 33fa8d94 by Ryan Scott at 2020-02-20T21:56:21-05:00 Generalize liftData to work over any Quote (#17857) The Overloaded Quotations proposal generalized the type of `lift` to work over any `Quote`, but not the type of `liftData`, leading to #17857. Thankfully, generalizing `liftData` is extremely straightforward. Fixes #17857. - - - - - 3cea6795 by Sylvain Henry at 2020-02-20T21:56:23-05:00 Make: fix sdist target (#17848) - - - - - e2cce997 by Sylvain Henry at 2020-02-20T21:56:23-05:00 Hadrian: fix source-dist target (#17849) - - - - - 0a4c89b2 by Matthew Pickering at 2020-02-21T20:44:45-05:00 Special case `mkTyConApp liftedTypeKind []` We really need to make sure that these are shared because otherwise GHC will allocate thousands of identical `TyConApp` nodes. See #17292 ------------------------- Metric Decrease: haddock.Cabal T14683 ------------------------- - - - - - 0482f58a by Matthew Pickering at 2020-02-21T20:45:21-05:00 TH: wrapGenSyns, don't split the element type too much The invariant which allowed the pervious method of splitting the type of the body to find the type of the elements didn't work in the new overloaded quotation world as the type can be something like `WriterT () m a` rather than `Q a` like before. Fixes #17839 - - - - - be7068a6 by Vladislav Zavialov at 2020-02-21T20:45:59-05:00 Parser API annotations: RealSrcLoc During parsing, GHC collects lexical information about AST nodes and stores it in a map. It is needed to faithfully restore original source code, e.g. compare these expressions: a = b a = b The position of the equality sign is not recorded in the AST, so it must be stored elsewhere. This system is described in Note [Api annotations]. Before this patch, the mapping was represented by: Map (SrcSpan, AnnKeywordId) SrcSpan After this patch, the mapping is represented by: Map (RealSrcSpan, AnnKeywordId) RealSrcSpan The motivation behind this change is to avoid using the Ord SrcSpan instance (required by Map here), as it interferes with #17632 (see the discussion there). SrcSpan is isomorphic to Either String RealSrcSpan, but we shouldn't use those strings as Map keys. Those strings are intended as hints to the user, e.g. "<interactive>" or "<compiler-generated code>", so they are not a valid way to identify nodes in the source code. - - - - - 240f5bf6 by Sylvain Henry at 2020-02-21T20:46:40-05:00 Modules: Driver (#13009) submodule updates: nofib, haddock - - - - - 9d094111 by Sylvain Henry at 2020-02-21T20:47:19-05:00 Hadrian: `docs` rule needs `configure` (#17840) - - - - - 1674353a by Ben Gamari at 2020-02-23T17:31:19-05:00 fs: Port fixes from ghc-jailbreak repository * Override rename, unlink, and remove * Factor out wchar conversion - - - - - 853210f2 by Adam Sandberg Ericsson at 2020-02-23T17:32:03-05:00 show gcc linker options in configure summary - - - - - 2831544a by Adam Sandberg Ericsson at 2020-02-23T17:32:44-05:00 hadrian: docs depend on stage1 ghc - - - - - 1d9df9e0 by Adam Sandberg Ericsson at 2020-02-23T17:33:23-05:00 ci: after 5ce63d52fed the linux bindist for doc-tarball has changed name - - - - - 26e8fff3 by Vladislav Zavialov at 2020-02-24T02:05:30-05:00 Remove Ord SrcLoc, Ord SrcSpan Before this patch, GHC relied on Ord SrcSpan to identify source elements, by using SrcSpan as Map keys: blackList :: Map SrcSpan () -- compiler/GHC/HsToCore/Coverage.hs instanceMap :: Map SrcSpan Name -- compiler/GHC/HsToCore/Docs.hs Firstly, this design is not valid in presence of UnhelpfulSpan, as it distinguishes between UnhelpfulSpan "X" and UnhelpfulSpan "Y", but those strings are messages for the user, unfit to serve as identifiers for source elements. Secondly, this design made it hard to extend SrcSpan with additional data. Recall that the definition of SrcSpan is: data SrcSpan = RealSrcSpan !RealSrcSpan | UnhelpfulSpan !FastString Say we want to extend the RealSrcSpan constructor with additional information: data SrcSpan = RealSrcSpan !RealSrcSpan !AdditionalInformation | UnhelpfulSpan !FastString getAdditionalInformation :: SrcSpan -> AdditionalInformation getAdditionalInformation (RealSrcSpan _ a) = a Now, in order for Map SrcSpan to keep working correctly, we must *ignore* additional information when comparing SrcSpan values: instance Ord SrcSpan where compare (RealSrcSpan r1 _) (RealSrcSpan r2 _) = compare r1 r2 ... However, this would violate an important law: a == b therefore f a == f b Ignoring AdditionalInformation in comparisons would mean that with f=getAdditionalInformation, the law above does not hold. A more robust design is to avoid Ord SrcSpan altogether, which is what this patch implements. The mappings are changed to use RealSrcSpan instead: blackList :: Set RealSrcSpan -- compiler/GHC/HsToCore/Coverage.hs instanceMap :: Map RealSrcSpan Name -- compiler/GHC/HsToCore/Docs.hs All SrcSpan comparisons are now done with explicit comparison strategies: SrcLoc.leftmost_smallest SrcLoc.leftmost_largest SrcLoc.rightmost_smallest These strategies are not subject to the law mentioned above and can easily discard both the string stored in UnhelpfulSpan and AdditionalInformation. Updates haddock submodule. - - - - - 5aa6c188 by Ben Gamari at 2020-02-24T02:06:09-05:00 users-guide: Shuffle text - - - - - e3f17413 by Ben Gamari at 2020-02-24T02:06:09-05:00 users-guide: Drop old release notes - - - - - 84dd9610 by Ben Gamari at 2020-02-24T02:06:09-05:00 Bump directory submodule to 1.3.6.0 - - - - - e295a024 by Stefan Pavikevik at 2020-02-24T20:53:44-05:00 check for safe arguments, raising error when invalid (fix #17720) - - - - - 354e2787 by Krzysztof Gogolewski at 2020-02-24T20:54:35-05:00 Comments, small refactor * Remove outdated Note [HsForAllTy tyvar binders] and [Context quantification]. Since the wildcard refactor 1e041b7382, HsForAllTy no longer has an flag controlling explicity. The field `hsq_implicit` is gone too. The current situation is covered by Note [HsType binders] which is already linked from LHsQTyVars. * Small refactor in CoreLint, extracting common code to a function * Remove "not so sure about WpFun" in TcEvidence, per Richard's comment https://gitlab.haskell.org/ghc/ghc/merge_requests/852#note_223226 * Use mkIfThenElse in Foreign/Call, as it does exactly what we need. - - - - - 1b1067d1 by Sylvain Henry at 2020-02-24T20:55:25-05:00 Modules: CmmToAsm (#13009) - - - - - 621468f6 by Alexis King at 2020-02-26T15:08:09-05:00 Treat coercions as arguments for floating and inlining This reverts commit 8924224ecfa065ebc67b96a90d01cf9d2edd0e77 and fixes #17787. - - - - - def486c9 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Allow libnuma library path to be specified - - - - - ed03d4e7 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Refactor gmp arguments Move the gmp configuration to its own binding. - - - - - 09b88384 by Ben Gamari at 2020-02-26T15:08:47-05:00 hadrian: Tell Cabal about integer-gmp library location - - - - - 161e08c5 by Krzysztof Gogolewski at 2020-02-26T15:09:30-05:00 Remove dead code * FailablePattern can no longer be created since ab51bee40c82 Therefore, Opt_WarnMissingMonadFailInstances has no effect anymore. * XWrap is no longer used, it was moved to an extension field - - - - - e0d09db3 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Use 8.8.3 to bootstrap on Windows This should fix #17861. - - - - - 972bcf3a by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Fix symlink test Needs to `write` bytes, not str. - - - - - 273e60de by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Add shell subcommand for debugging within CI environment - - - - - 43b13ed3 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Fix colors on Darwin Darwin sh doesn't support \e. - - - - - 217546a7 by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Flush stdout buffers in InitEventLogging Otherwise we are sensitive to libc's buffering strategy. Similar to the issue fixed in 543dfaab166c81f46ac4af76918ce32190aaab22. - - - - - c7d4fa55 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Add run_hadrian subcommand I've ruined two trees already by failing to pass --flavour to hadrian. Let's factor this out so it can be reused during troubleshooting. - - - - - 7dc54873 by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Allow tests to be marked as broken on the command line This allows us to work-around distribution-specific breakage easily. - - - - - 25e2458e by Ben Gamari at 2020-02-26T15:10:09-05:00 hadrian: Add --broken-test flag This exposes the flag of the same name supported by the testsuite driver. - - - - - 55769996 by Ben Gamari at 2020-02-26T15:10:09-05:00 gitlab-ci: Mark some tests as broken on Alpine - - - - - 9ee7f87d by Ben Gamari at 2020-02-26T15:10:09-05:00 SysTools: Don't use process jobs if they are broken - - - - - bfaa3961 by Ben Gamari at 2020-02-26T15:10:09-05:00 Bump hsc2hs submodule Fixes name of C compiler. - - - - - b2b49a0a by Ben Gamari at 2020-02-26T15:10:09-05:00 testsuite: Make hasMetricsFile RHS more descriptive - - - - - 817f93ea by Sylvain Henry at 2020-02-26T15:10:58-05:00 Modules: Core (#13009) Update haddock submodule - - - - - 74311e10 by Sebastian Graf at 2020-02-27T16:22:45-05:00 PmCheck: Implement Long-distance information with Covered sets Consider ```hs data T = A | B | C f :: T -> Int f A = 1 f x = case x of A -> 2 B -> 3 C -> 4 ``` Clearly, the RHS returning 2 is redundant. But we don't currently see that, because our approximation to the covered set of the inner case expression just picks up the positive information from surrounding pattern matches. It lacks the context sensivity that `x` can't be `A` anymore! Therefore, we adopt the conceptually and practically superior approach of reusing the covered set of a particular GRHS from an outer pattern match. In this case, we begin checking the `case` expression with the covered set of `f`s second clause, which encodes the information that `x` can't be `A` anymore. After this MR, we will successfully warn about the RHS returning 2 being redundant. Perhaps surprisingly, this was a great simplification to the code of both the coverage checker and the desugarer. Found a redundant case alternative in `unix` submodule, so we have to bump it with a fix. Metric Decrease: T12227 - - - - - 59c023ba by Adam Sandberg Ericsson at 2020-02-27T16:23:25-05:00 configure: correctly generate LIBRARY_template_haskell_VERSION - - - - - 9be82389 by Krzysztof Gogolewski at 2020-02-28T02:35:35-05:00 boot: Remove remote origin check Previously, we used relative paths in submodules. When cloning from GitHub, they had to be manually tweaked. Since a76b233d we use absolute paths, so this workaround can be removed. - - - - - f4b6b594 by Ben Gamari at 2020-02-28T02:36:12-05:00 nonmoving: Fix marking in compact regions Previously we were tracing the object we were asked to mark, even if it lives in a compact region. However, there is no need to do this; we need only to mark the region itself as live. I have seen a segfault due to this due to the concurrent mark seeing a an object in the process of being compacted by the mutator. - - - - - f97d1fb6 by Alp Mestanogullari at 2020-02-28T02:36:59-05:00 base: use an explicit import list in System.Environment.ExecutablePath This was making -Werror builds fail on Windows (at least with Hadrian). - - - - - 66f5d6d6 by Simon Peyton Jones at 2020-02-28T22:03:23-05:00 Improve error handling for VTA + deferred type errors This fixes #17792 See Note [VTA for out-of-scope functions] in TcExpr - - - - - 37f12603 by Ilias Tsitsimpis at 2020-02-28T22:04:04-05:00 llvm-targets: Add arm-unknown-linux-gnueabi Add arm-unknown-linux-gnueabi, which is used by Debian's ARM EABI port (armel), as an LLVM target. - - - - - 327b29e1 by Vladislav Zavialov at 2020-02-29T05:06:31-05:00 Monotonic locations (#17632) When GHC is parsing a file generated by a tool, e.g. by the C preprocessor, the tool may insert #line pragmas to adjust the locations reported to the user. As the result, the locations recorded in RealSrcLoc are not monotonic. Elements that appear later in the StringBuffer are not guaranteed to have a higher line/column number. In fact, there are no guarantees whatsoever, as #line pragmas can arbitrarily modify locations. This lack of guarantees makes ideas such as #17544 infeasible. This patch adds an additional bit of information to every SrcLoc: newtype BufPos = BufPos { bufPos :: Int } A BufPos represents the location in the StringBuffer, unaffected by any pragmas. Updates haddock submodule. Metric Increase: haddock.Cabal haddock.base haddock.compiler MultiLayerModules Naperian parsing001 T12150 - - - - - 99d2de86 by Ben Gamari at 2020-02-29T05:07:10-05:00 plugins: Ensure that loadInterface plugins can see annotations loadInterface replaces the `mi_decls`, `mi_insts`, `mi_fam_insts`, `mi_rules`, `mi_anns` fields of ModIface with `undefined` before inserting the interface into the EPS. However, we still want to give loadInterface plugins access to these fields. Consequently, we want to pass the unmodified `ModIface` the plugin. - - - - - a999ee96 by Xavier Denis at 2020-02-29T05:07:50-05:00 Rename ghci.sh and build.sh to ghci and build respectively Convert hadrian buildscripts to unsuffixed, dashed form final cleanups - - - - - b5fb58fd by Ömer Sinan Ağacan at 2020-02-29T05:08:36-05:00 Document and refactor a few things around bitmap scavenging - Added a few comments in StgPAP - Added a few comments and assertions in scavenge_small_bitmap and walk_large_bitmap - Did tiny refactor in GHC.Data.Bitmap: added some comments, deleted dead code, used PlatformWordSize type. - - - - - 18757cab by Sylvain Henry at 2020-02-29T05:09:25-05:00 Refactor runtime interpreter code In #14335 we want to be able to use both the internal interpreter (for the plugins) and the external interpreter (for TH and GHCi) at the same time. This patch performs some preliminary refactoring: the `hsc_interp` field of HscEnv replaces `hsc_iserv` and is now used to indicate which interpreter (internal, external) to use to execute TH and GHCi. Opt_ExternalInterpreter flag and iserv options in DynFlags are now queried only when we set the session DynFlags. It should help making GHC multi-target in the future by selecting an interpreter according to the selected target. - - - - - b86a6395 by Adam Sandberg Ericsson at 2020-02-29T05:10:06-05:00 docs: correct relative links to haddocks from users guide (fixes #17866) - - - - - 0f55df7f by Adam Sandberg Ericsson at 2020-02-29T05:10:06-05:00 docs: correct link to th haddocks from users guide - - - - - 252e5117 by Jean-Baptiste Mazon at 2020-02-29T05:10:46-05:00 rts: enforce POSIX numeric locale for heap profiles - - - - - 34c7d230 by Sylvain Henry at 2020-02-29T05:11:27-05:00 Fix Hadrian's ``--configure`` (fix #17883) - - - - - 04d30137 by Ömer Sinan Ağacan at 2020-02-29T05:12:06-05:00 Simplify IfaceIdInfo type IfaceIdInfo type is confusing: there's practically no difference between `NoInfo` and `HasInfo []`. The comments say NoInfo is used when -fomit-interface-pragmas is enabled, but we don't need to distinguish `NoInfo` from `HasInfo []` in when reading the interface so the distinction is not important. This patch simplifies the type by removing NoInfo. When we have no info we use an empty list. With this change we no longer read the info list lazily when reading an IfaceInfoItem, but when reading an IfaceId the ifIdInfo field is read lazily, so I doubt this is going to be a problem. - - - - - 3979485b by Roland Senn at 2020-02-29T17:36:59+01:00 Show breakpoint locations of breakpoints which were ignored during :force (#2950) GHCi is split up into 2 major parts: The user-interface (UI) and the byte-code interpreter. With `-fexternal-interpreter` they even run in different processes. Communication between the UI and the Interpreter (called `iserv`) is done using messages over a pipe. This is called `Remote GHCI` and explained in the Note [Remote GHCi] in `compiler/ghci/GHCi.hs`. To process a `:force` command the UI sends a `Seq` message to the `iserv` process. Then `iserv` does the effective evaluation of the value. When during this process a breakpoint is hit, the `iserv` process has no additional information to enhance the `Ignoring breakpoint` output with the breakpoint location. To be able to print additional breakpoint information, there are 2 possible implementation choices: 1. Store the needed information in the `iserv` process. 2. Print the `Ignoring breakpoint` from the UI process. For option 1 we need to store the breakpoint info redundantely in 2 places and this is bad. Therfore option 2 was implemented in this MR: - The user enters a `force` command - The UI sends a `Seq` message to the `iserv` process. - If processing of the `Seq` message hits a breakpoint, the `iserv` process returns control to the UI process. - The UI looks up the source location of the breakpoint, and prints the enhanced `Ignoring breakpoint` output. - The UI sends a `ResumeSeq` message to the `iserv` process, to continue forcing. - - - - - 3cf7303b by Krzysztof Gogolewski at 2020-03-02T01:18:33-05:00 Remove dead code * The names in PrelName and THNames are no longer used since TH merged types and kinds, Typeable is kind-polymorphic, .net support was removed * unqualQuasiQuote no longer used since 6f8ff0bbad3b9fa3 - - - - - dbea7e9d by Ilias Tsitsimpis at 2020-03-02T01:19:12-05:00 Do not define hs_atomic{read,write}64() on non-64bit Do not define hs_atomicread64() and hs_atomicwrite64() on machines where WORD_SIZE_IN_BITS is less than 64, just like we do with the rest of the atomic functions which work on 64-bit values. Without this, compilation fails on MIPSel and PowerPC with the following error: /usr/bin/ld: /<<PKGBUILDDIR>>/libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.3_p.a(atomic.p_o): in function `hs_atomicread64': atomic.c:(.text.hs_atomicread64+0x8): undefined reference to `__sync_add_and_fetch_8' /usr/bin/ld: /<<PKGBUILDDIR>>/libraries/ghc-prim/dist-install/build/libHSghc-prim-0.5.3_p.a(atomic.p_o): in function `hs_atomicwrite64': atomic.c:(.text.hs_atomicwrite64+0x38): undefined reference to `__sync_bool_compare_and_swap_8' Fixes #17886. - - - - - 7c0c76fb by Roland Senn at 2020-03-02T17:13:55-05:00 Set `ImpredicativeTypes` during :print command. (#14828) If ImpredicativeTypes is not enabled, then `:print <term>` will fail if the type of <term> has nested `forall`s or `=>`s. This is because the GHCi debugger's internals will attempt to unify a metavariable with the type of <term> and then display the result, but if the type has nested `forall`s or `=>`s, then unification will fail. As a result, `:print` will bail out and the unhelpful result will be `<term> = (_t1::t1)` (where `t1` is a metavariable). Beware: <term> can have nested `forall`s even if its definition doesn't use RankNTypes! Here is an example from #14828: class Functor f where fmap :: (a -> b) -> f a -> f b Somewhat surprisingly, `:print fmap` considers the type of fmap to have nested foralls. This is because the GHCi debugger sees the type `fmap :: forall f. Functor f => forall a b. (a -> b) -> f a -> f b`. We could envision deeply instantiating this type to get the type `forall f a b. Functor f => (a -> b) -> f a -> f b`, but this trick wouldn't work for higher-rank types. Instead, we adopt a simpler fix: enable `ImpredicativeTypes` when using `:print` and friends in the GHCi debugger. This is allows metavariables to unify with types that have nested (or higher-rank) `forall`s/`=>`s, which makes `:print fmap` display as `fmap = (_t1::forall a b. Functor f => (a -> b) -> f a -> f b)`, as expected. Although ImpredicativeTypes is a somewhat unpredictable from a type inference perspective, there is no danger in using it in the GHCi debugger, since all of the terms that the GHCi debugger deals with have already been typechecked. - - - - - 2a2f51d7 by Sylvain Henry at 2020-03-02T17:14:38-05:00 Use configure script to detect that we should use in-tree GMP on Windows - - - - - 8c663c2c by Andreas Klebinger at 2020-03-04T16:12:14+01:00 Be explicit about how stack usage of mvar primops are covered. This fixes #17893 [skip-ci] - - - - - cedd6f30 by Ben Gamari at 2020-03-05T14:53:12-05:00 rts: Add getCurrentThreadCPUTime helper - - - - - ace618cd by Ben Gamari at 2020-03-05T14:53:12-05:00 nonmoving-gc: Track time usage of nonmoving marking - - - - - 022b5ad5 by Ben Gamari at 2020-03-05T14:53:12-05:00 Stats: Add sync pauses to +RTS -S output - - - - - 06763234 by Ben Gamari at 2020-03-05T14:53:12-05:00 rts: Report nonmoving collector statistics in machine-readable output - - - - - 70d2b995 by Ben Gamari at 2020-03-09T06:10:52-04:00 nonmoving: Fix collection of sparks Previously sparks living in the non-moving heap would be promptly GC'd by the minor collector since pruneSparkQueue uses the BF_EVACUATED flag, which non-moving heap blocks do not have set. Fix this by implementing proper support in pruneSparkQueue for determining reachability in the non-moving heap. The story is told in Note [Spark management in the nonmoving heap]. - - - - - 9668781a by Ben Gamari at 2020-03-09T06:11:30-04:00 gitlab-ci: Disable Sphinx documentation in Alpine build - - - - - 8eb2c263 by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 Fix Windows breakage by not touching locales on Windows - - - - - b8dab057 by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 rts: ensure C numerics in heap profiles using Windows locales if needed - - - - - 7d95260f by Jean-Baptiste Mazon at 2020-03-09T16:33:37-04:00 rts: refactor and comment profile locales - - - - - 5b627813 by Ryan Scott at 2020-03-09T16:34:14-04:00 Use InstanceSigs in GND/DerivingVia-generated code (#17899) Aside from making the generated code easier to read when `-ddump-deriv` is enabled, this makes the error message in `T15073` substantially simpler (see the updated `T15073` expected stderr). Fixes #17899. - - - - - 70b50778 by Ben Gamari at 2020-03-10T02:05:42-04:00 SysTools: Ensure that error parser can handle absolute paths on Windows This fixes #17786, where the error parser fails to correctly handle the drive name in absolute Windows paths. Unfortunately I couldn't find a satisfactory way to test this. - - - - - 85b861d8 by Ben Gamari at 2020-03-10T02:05:42-04:00 testsuite: Add test for #17786 This isn't pretty but it's perhaps better than nothing. - - - - - ee2c50cb by Sylvain Henry at 2020-03-10T02:06:33-04:00 Hadrian: track missing configure results - - - - - ca8f51d4 by Ömer Sinan Ağacan at 2020-03-10T02:07:22-04:00 Add regression test for T17904 Closes #17904 - - - - - 5fa9cb82 by Richard Eisenberg at 2020-03-10T12:29:46-04:00 anyRewritableTyVar now looks in RuntimeReps Previously, anyRewritableTyVar looked only at the arg and res of `arg -> res`, but their RuntimeReps are also subject to rewriting. Easy to fix. Test case: typecheck/should_compile/T17024 Fixes #17024. - - - - - 5ba01d83 by Ben Price at 2020-03-10T12:30:27-04:00 Clarify a Lint message When developing a plugin I had a shadowing problem, where I generated code app = \f{v r7B} x{v r7B} -> f{v r7B} x{v r7B} This is obviously wrong, since the occurrence of `f` to the right of the arrow refers to the `x` binder (they share a Unique). However, it is rather confusing when Lint reports Mismatch in type between binder and occurrence Var: x{v rB7} since it is printing the binder, rather than the occurrence. It is rather easy to read this as claiming there is something wrong with the `x` occurrence! We change the report to explicitly print both the binder and the occurrence variables. - - - - - 7b2c827b by Simon Peyton Jones at 2020-03-10T12:31:15-04:00 Comments only Clarify code added in #17852 and MR !2724 - - - - - 3300eeac by Krzysztof Gogolewski at 2020-03-10T12:31:54-04:00 Misc cleanup - Remove Note [Existentials in shift_con_pat]. The function shift_con_pat has been removed 15 years ago in 23f40f0e9be6d4. - Remove kcLookupTcTyCon - it's the same as tcLookupTcTyCon - Remove ASSERT in tyConAppArgN. It's already done by getNth, and it's the only reason getNth exists. - Remove unused function nextRole - - - - - abf5736b by Krzysztof Gogolewski at 2020-03-10T18:05:01+01:00 Typos in comments [skip ci] - - - - - bb586f89 by Ben Gamari at 2020-03-11T00:14:59-04:00 rts: Prefer darwin-specific getCurrentThreadCPUTime macOS Catalina now supports a non-POSIX-compliant version of clock_gettime which cannot use the clock_gettime codepath. Fixes #17906. - - - - - 20800b9a by Sylvain Henry at 2020-03-11T08:17:19-04:00 Split GHC.Iface.Utils module * GHC.Iface.Recomp: recompilation avoidance stuff * GHC.Iface.Make: mkIface* Moved `writeIfaceFile` into GHC.Iface.Load alongside `readIface` and renamed it `writeIface` for consistency. - - - - - 1daa2029 by Greg Steuck at 2020-03-11T08:17:56-04:00 Fixed a minor typo in codegen.rst - - - - - 0bc23338 by Ryan Scott at 2020-03-11T08:18:32-04:00 Re-quantify when generalising over rewrite rule types Previously, `tcRules` would check for naughty quantification candidates (see `Note [Naughty quantification candidates]` in `TcMType`) when generalising over the type of a rewrite rule. This caused sensible-looking rewrite rules (like those in #17710) to be rejected. A more permissing (and easier-to-implement) approach is to do what is described in `Note [Generalising in tcTyFamInstEqnGuts]` in `TcTyClsDecls`: just re-quantify all the type variable binders, regardless of the order in which the user specified them. After all, the notion of type variable specificity has no real meaning in rewrite rules, since one cannot "visibly apply" a rewrite rule. I have written up this wisdom in `Note [Re-quantify type variables in rules]` in `TcRules`. As a result of this patch, compiling the `ExplicitForAllRules1` test case now generates one fewer warning than it used to. As far as I can tell, this is benign, since the thing that the disappearing warning talked about was also mentioned in an entirely separate warning. Fixes #17710. - - - - - 336eac7e by Ben Gamari at 2020-03-11T08:19:08-04:00 testsuite: Mark ghci056 and ghcilink004 as fragile in unreg As noted in #17018. Also fix fragile declaration of T13786, which only runs in the normal way. - - - - - c61b9b02 by Simon Peyton Jones at 2020-03-11T08:19:44-04:00 Deepen call stack for isIn I see quite a few warnings like: WARNING: file compiler/utils/Util.hs, line 593 Over-long elem in unionLists But the call stack is uninformative. Better to add HasDebugCallStack to isIn. Ditto isn'tIn. - - - - - 3aa9b35f by Ömer Sinan Ağacan at 2020-03-11T08:20:27-04:00 Zero any slop after compaction in compacting GC In copying GC, with the relevant debug flags enabled, we release the old blocks after a GC, and the block allocator zeroes the space before releasing a block. This effectively zeros the old heap. In compacting GC we reuse the blocks and previously we didn't zero the unused space in a compacting generation after compaction. With this patch we zero the slop between the free pointer and the end of the block when we're done with compaction and when switching to a new block (because the current block doesn't have enough space for the next object we're shifting). - - - - - 8e6febce by Sylvain Henry at 2020-03-11T20:33:37-04:00 Refactor GHC.Driver.Session (Ways and Flags) * extract flags and ways into their own modules (with some renaming) * remove one SOURCE import of GHC.Driver.Session from GHC.Driver.Phases * when GHC uses dynamic linking (WayDyn), `interpWays` was only reporting WayDyn even if the host was profiled (WayProf). Now it returns both as expected (might fix #16803). * `mkBuildTag :: [Way] -> String` wasn't reporting a canonical tag for differently ordered lists. Now we sort and nub the list to fix this. - - - - - bc41e471 by Sylvain Henry at 2020-03-11T20:33:37-04:00 Refactor interpreterDynamic and interpreterProfiled * `interpreterDynamic` and `interpreterProfiled` now take `Interp` parameters instead of DynFlags * slight refactoring of `ExternalInterp` so that we can read the iserv configuration (which is pure) without reading an MVar. - - - - - a6989971 by Sylvain Henry at 2020-03-11T20:33:37-04:00 Use a Set to represent Ways Should make `member` queries faster and avoid messing up with missing `nubSort`. Metric Increase: hie002 - - - - - cb93a1a4 by Ryan Scott at 2020-03-11T20:34:14-04:00 Make DeriveFunctor-generated code require fewer beta reductions Issue #17880 demonstrates that `DeriveFunctor`-generated code is surprisingly fragile when rank-_n_ types are involved. The culprit is that `$fmap` (the algorithm used to generate `fmap` implementations) was too keen on applying arguments with rank-_n_ types to lambdas, which fail to typecheck more often than not. In this patch, I change `$fmap` (both the specification and the implementation) to produce code that avoids creating as many lambdas, avoiding problems when rank-_n_ field types arise. See the comments titled "Functor instances" in `TcGenFunctor` for a more detailed description. Not only does this fix #17880, but it also ensures that the code that `DeriveFunctor` generates will continue to work after simplified subsumption is implemented (see #17775). What is truly amazing is that #17880 is actually a regression (introduced in GHC 7.6.3) caused by commit 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e, the fix #7436. Prior to that commit, the version of `$fmap` that was used was almost identical to the one used in this patch! Why did that commit change `$fmap` then? It was to avoid severe performance issues that would arise for recursive `fmap` implementations, such as in the example below: ```hs data List a = Nil | Cons a (List a) deriving Functor -- ===> instance Functor List where fmap f Nil = Nil fmap f (Cons x xs) = Cons (f x) (fmap (\y -> f y) xs) ``` The fact that `\y -> f y` was eta expanded caused significant performance overheads. Commit 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e fixed this performance issue, but it went too far. As a result, this patch partially reverts 49ca2a37bef18aa57235ff1dbbf1cc0434979b1e. To ensure that the performance issues pre-#7436 do not resurface, I have taken some precautionary measures: * I have added a special case to `$fmap` for situations where the last type variable in an application of some type occurs directly. If this special case fires, we avoid creating a lambda expression. This ensures that we generate `fmap f (Cons x xs) = Cons (f x) (fmap f xs)` in the derived `Functor List` instance above. For more details, see `Note [Avoid unnecessary eta expansion in derived fmap implementations]` in `TcGenFunctor`. * I have added a `T7436b` test case to ensure that the performance of this derived `Functor List`-style code does not regress. When implementing this, I discovered that `$replace`, the algorithm which generates implementations of `(<$)`, has a special case that is very similar to the `$fmap` special case described above. `$replace` marked this special case with a custom `Replacer` data type, which was a bit overkill. In order to use the same machinery for both `Functor` methods, I ripped out `Replacer` and instead implemented a simple way to detect the special case. See the updated commentary in `Note [Deriving <$]` for more details. - - - - - 1f9db3e7 by Kirill Elagin at 2020-03-12T09:45:51-04:00 pretty-printer: Properly parenthesise LastStmt After ApplicatveDo strips the last `return` during renaming, the pretty printer has to restore it. However, if the return was followed by `$`, the dollar was stripped too and not restored. For example, the last stamement in: ``` foo = do x <- ... ... return $ f x ``` would be printed as: ``` return f x ``` This commit preserved the dolar, so it becomes: ``` return $ f x ``` - - - - - 5cb93af7 by Kirill Elagin at 2020-03-12T09:45:51-04:00 pretty-printer: Do not print ApplicativeDo join * Do not print `join` in ApplictiveStmt, unless ppr-debug * Print parens around multiple parallel binds When ApplicativeDo is enabled, the renamer analyses the statements of a `do` block and in certain cases marks them as needing to be rewritten using `join`. For example, if you have: ``` foo = do a <- e1 b <- e2 doSomething a b ``` it will be desugared into: ``` foo = join (doSomething <$> e1 <*> e2) ``` After renaming but before desugaring the expression is stored essentially as: ``` foo = do [will need join] (a <- e1 | b <- e2) [no return] doSomething a b ``` Before this change, the pretty printer would print a call to `join`, even though it is not needed at this stage at all. The expression will be actually rewritten into one using join only at desugaring, at which point a literal call to join will be inserted. - - - - - 3a259092 by Simon Peyton Jones at 2020-03-12T09:46:29-04:00 Expose compulsory unfoldings always The unsafeCoerce# patch requires that unsafeCoerce# has a compulsory unfolding that is always available. So we have to be careful to expose compulsory unfoldings unconditionally and consistently. We didn't get this quite right: #17871. This patch fixes it. No real surprises here. See Note [Always expose compulsory unfoldings] in GHC.Iface.Tidy - - - - - 6a65b8c2 by Alp Mestanogullari at 2020-03-13T02:29:20-04:00 hadrian: improve dependency tracking for the check-* programs The code in Rules.Register responsible for finding all the build artifacts that Cabal installs when registering a library (static/shared libs, .hi files, ...) was looking in the wrong place. This patch fixes that logic and makes sure we gather all those artifacts in a list to declare that the rule for a given `.conf` file, our proxy for "Hadrian, please install this package in the package db for this stage", also produces those artifacts under the said package database. We also were completely missing some logic to declare that the check-* programs have dependencies besides their source code, at least when testing an in-tree compiler. Finally, this patch also removes redundant packages from 'testsuitePackages', since they should already be covered by the stage<N>Packages lists from Settings.Default. With this patch, after a complete build and freezing stage 1, a change to `compiler/parser/Parser.y` results in rebuilding the ghc lib, reinstalling it, and rebuilding the few programs that depend on it, _including_ `check-ppr` and `check-api-annotations` (therefore fixing #17273). - - - - - 44fad4a9 by Sylvain Henry at 2020-03-13T02:30:22-04:00 Rename isDllName I wanted to fix the dangling comment in `isDllName` ("This is the cause of #", #8696 is already mentioned earlier). I took the opportunity to change the function name to better reflect what it does. - - - - - 2f292db8 by Paavo at 2020-03-13T02:31:03-04:00 Update documentation for closureSize - - - - - f124ff0d by Ben Gamari at 2020-03-13T02:31:40-04:00 gitlab-ci: Rework triggering of release builds Use a push option instead of tagging. - - - - - 7f25557a by Ben Gamari at 2020-03-13T10:38:09-04:00 gitlab-ci: Distinguish integer-simple test envs Previously two integer-simple jobs declared the same test environment. One (the nightly job) was built in the perf way, the other in the validate way. Consequently they had appreciably different performance characteristics, causing in the nightly job to spuriously fail with performance changes. - - - - - c12a2ec5 by Simon Peyton Jones at 2020-03-14T05:25:30-04:00 Fix Lint Ticket #17590 pointed out a bug in the way the linter dealt with type lets, exposed by the new uniqAway story. The fix is described in Note [Linting type lets]. I ended up putting the in-scope Ids in a different env field, le_ids, rather than (as before) sneaking them into the TCvSubst. Surprisingly tiresome, but done. Metric Decrease: hie002 - - - - - b989845e by Sylvain Henry at 2020-03-14T05:26:11-04:00 Hadrian: fix absolute buildroot support (#17822) Shake's "**" wildcard doesn't match absolute root. We must use "//" instead. - - - - - 4f117135 by Sylvain Henry at 2020-03-14T05:26:49-04:00 Make: refactor GMP rules Document and use simpler rules for the ghc-gmp.h header. - - - - - 7432b327 by Sylvain Henry at 2020-03-14T05:27:28-04:00 Use correct option name (-opti) (fix #17314) s/pgmo/opti - - - - - 8f7dd571 by Judah Jacobson at 2020-03-14T05:28:07-04:00 Allow overriding LD_STAGE0 and AR_STAGE0 in the configure script. Previously it was possible to override the stage0 C compiler via `CC_STAGE0`, but you couldn't override `ld` or `ar` in stage0. This change allows overriding them by setting `LD_STAGE0` or `AR_STAGE0`, respectively. Our team uses this feature internally to take more control of our GHC build and make it run more hermetically. - - - - - 7c3e39a9 by Judah Jacobson at 2020-03-14T05:28:07-04:00 Use AC_ARG_VAR for LD_STAGE0 and AR_STAGE0. - - - - - 20d4d676 by Ben Gamari at 2020-03-14T05:28:43-04:00 nonmoving: Don't traverse filled segment list in pause The non-moving collector would previously walk the entire filled segment list during the preparatory pause. However, this is far more work than is strictly necessary. We can rather get away with merely collecting the allocators' filled segment list heads and process the lists themselves during the concurrent phase. This can significantly reduce the maximum gen1 GC pause time in programs with high rates of long-lived allocations. - - - - - fdfa2d01 by Ben Gamari at 2020-03-14T05:29:18-04:00 nonmoving: Remove redundant bitmap clearing nonmovingSweep already clears the bitmap in the sweep loop. There is no reason to do so a second time. - - - - - 2f8c7767 by Simon Peyton Jones at 2020-03-14T05:29:55-04:00 Simple refactor of cheapEqExpr No change in functionality. Just seems tidier (and signficantly more efficient) to deal with ticks directly than to call stripTicksTopE. - - - - - 88f7a762 by Simon Peyton Jones at 2020-03-14T05:29:55-04:00 Improve CSE.combineAlts This patch improves the way that CSE combines identical alternatives. See #17901. I'm still not happy about the duplication between CSE.combineAlts and GHC.Core.Utils.combineIdenticalAlts; see the Notes with those functions. But this patch is a step forward. Metric Decrease: T12425 T5642 - - - - - 8b95ddd3 by Ben Gamari at 2020-03-14T05:30:31-04:00 gitlab-ci: Add integer-simple release build for Windows Closes #16144. - - - - - e3c374cc by Simon Peyton Jones at 2020-03-14T05:31:07-04:00 Wrap an implication around class-sig kind errors Ticket #17841 showed that we can get a kind error in a class signature, but lack an enclosing implication that binds its skolems. This patch * Adds the wrapping implication: the new call to checkTvConstraints in tcClassDecl1 * Simplifies the API to checkTvConstraints, which was not otherwise called at all. * Simplifies TcErrors.report_unsolved by *not* initialising the TidyEnv from the typechecker lexical envt. It's enough to do so from the free vars of the unsolved constraints; and we get silly renamings if we add variables twice: once from the lexical scope and once from the implication constraint. - - - - - 73133a3b by Simon Peyton Jones at 2020-03-14T05:31:07-04:00 Refactoring in TcSMonad This patch is just refactoring: no change in behaviour. I removed the rather complicated checkConstraintsTcS checkTvConstraintsTcS in favour of simpler functions emitImplicationTcS emitTvImplicationTcS pushLevelNoWorkList The last of these is a little strange, but overall it's much better I think. - - - - - 93c88c26 by Ben Gamari at 2020-03-14T05:31:42-04:00 base: Make `open` calls interruptible As noted in #17912, `open` system calls were `safe` rather than `interruptible`. Consequently, the program could not be interrupted with SIGINT if stuck in a slow open operation. Fix this by marking `c_safe_open` as interruptible. - - - - - bee4cdad by Vladislav Zavialov at 2020-03-14T05:32:18-04:00 Remove second tcLookupTcTyCon in tcDataDefn Before this patch, tcDataDefn used to call tcLookupTcTyCon twice in a row: 1. in bindTyClTyVars itself 2. in the continuation passed to it Now bindTyClTyVars passes the TcTyCon to the continuation, making the second lookup unnecessary. - - - - - 3f116d35 by Cale Gibbard at 2020-03-14T19:34:42-04:00 Enable stage1 build of haddock The submodule has already been bumped to contain the fix. - - - - - 49e9d739 by Ömer Sinan Ağacan at 2020-03-14T19:35:24-04:00 rts: Fix printClosure when printing fwd ptrs - - - - - 1de3ab4a by Krzysztof Gogolewski at 2020-03-14T19:36:04-04:00 Remove unused field var_inline (#17915) - - - - - d30aeb4b by Krzysztof Gogolewski at 2020-03-15T03:57:41-04:00 Document restriction on SCC pragma syntax Currently, the names of cost centres must be quoted or be lowercase identifiers. Fixes #17916. - - - - - b4774598 by Brian Foley at 2020-03-15T03:58:18-04:00 Remove some dead code >From the notes.ghc.drop list found using weeder in #17713 - - - - - dd6ffe6b by Viktor Dukhovni at 2020-03-15T03:58:55-04:00 Note platform-specific Foreign.C.Types in context Also fix the markup in the general note at the top of the module. Haddock (usability trade-off), does not support multi-line emphasised text. - - - - - 2e82465f by Sylvain Henry at 2020-03-15T10:57:10-04:00 Refactor CmmToAsm (disentangle DynFlags) This patch disentangles a bit more DynFlags from the native code generator (CmmToAsm). In more details: - add a new NCGConfig datatype in GHC.CmmToAsm.Config which contains the configuration of a native code generation session - explicitly pass NCGConfig/Platform arguments when necessary - as a consequence `sdocWithPlatform` is gone and there are only a few `sdocWithDynFlags` left - remove the use of `unsafeGlobalDynFlags` from GHC.CmmToAsm.CFG - remove `sdocDebugLevel` (now we pass the debug level via NCGConfig) There are still some places where DynFlags is used, especially because of pretty-printing (CLabel), because of Cmm helpers (such as `cmmExprType`) and because of `Outputable` instance for the instructions. These are left for future refactoring as this patch is already big. - - - - - c35c545d by Judah Jacobson at 2020-03-15T10:57:48-04:00 Add a -no-haddock flag. This flag undoes the effect of a previous "-haddock" flag. Having both flags makes it easier for build systems to enable Haddock parsing in a set of global flags, but then disable it locally for specific targets (e.g., third-party packages whose comments don't pass the validation in the latest GHC). I added the flag to expected-undocumented-flags.txt since `-haddock` was alreadyin that list. - - - - - cfcc3c9a by Ömer Sinan Ağacan at 2020-03-15T10:58:27-04:00 Fix global_link of TSOs for threads reachable via dead weaks Fixes #17785 Here's how the problem occurs: - In generation 0 we have a TSO that is finished (i.e. it has no more work to do or it is killed). - The TSO only becomes reachable after collectDeadWeakPtrs(). - After collectDeadWeakPtrs() we switch to WeakDone phase where we don't move TSOs to different lists anymore (like the next gen's thread list or the resurrected_threads list). - So the TSO will never be moved to a generation's thread list, but it will be promoted to generation 1. - Generation 1 collected via mark-compact, and because the TSO is reachable it is marked, and its `global_link` field, which is bogus at this point (because the TSO is not in a list), will be threaded. - Chaos ensues. In other words, when these conditions hold: - A TSO is reachable only after collectDeadWeakPtrs() - It's finished (what_next is ThreadComplete or ThreadKilled) - It's retained by mark-compact collector (moving collector doesn't evacuate the global_list field) We end up doing random mutations on the heap because the TSO's global_list field is not valid, but it still looks like a heap pointer so we thread it during compacting GC. The fix is simple: when we traverse old_threads lists to resurrect unreachable threads the threads that won't be resurrected currently stays on the old_threads lists. Those threads will never be visited again by MarkWeak so we now reset the global_list fields. This way compacting GC does not thread pointers to nowhere. Testing ------- The reproducer in #17785 is quite large and hard to build, because of the dependencies, so I'm not adding a regression test. In my testing the reproducer would take a less than 5 seconds to run, and once in every ~5 runs would fail with a segfault or an assertion error. In other cases it also fails with a test failure. Because the tests never fail with the bug fix, assuming the code is correct, this also means that this bug can sometimes lead to incorrect runtime results. After the fix I was able to run the reproducer repeatedly for about an hour, with no runtime crashes or test failures. To run the reproducer clone the git repo: $ git clone https://github.com/osa1/streamly --branch ghc-segfault Then clone primitive and atomic-primops from their git repos and point to the clones in cabal.project.local. The project should then be buildable using GHC HEAD. Run the executable `properties` with `+RTS -c -DZ`. In addition to the reproducer above I run the test suite using: $ make slowtest EXTRA_HC_OPTS="-debug -with-rtsopts=-DS \ -with-rtsopts=-c +RTS -c -RTS" SKIPWAY='nonmoving nonmoving_thr' This enables compacting GC always in both GHC when building the test programs and when running the test programs, and also enables sanity checking when running the test programs. These set of flags are not compatible for all tests so there are some failures, but I got the same set of failures with this patch compared to GHC HEAD. - - - - - 818b3c38 by Lysxia at 2020-03-16T23:52:42-04:00 base: add strict IO functions: readFile', getContents', hGetContents' - - - - - 18a346a4 by Sylvain Henry at 2020-03-16T23:53:24-04:00 Modules: Core (#13009) Update submodule: haddock - - - - - 92327e3a by Ömer Sinan Ağacan at 2020-03-16T23:54:04-04:00 Update sanity checking for TSOs: - Remove an invalid assumption about GC checking what_next field. The GC doesn't care about what_next at all, if a TSO is reachable then all its pointers are followed (other than global_tso, which is only followed by compacting GC). - Remove checkSTACK in checkTSO: TSO stacks will be visited in checkHeapChain, or checkLargeObjects etc. - Add an assertion in checkTSO to check that the global_link field is sane. - Did some refactor to remove forward decls in checkGlobalTSOList and added braces around single-statement if statements. - - - - - e1aa4052 by PHO at 2020-03-17T07:36:09-04:00 Don't use non-portable operator "==" in configure.ac The test operator "==" is a Bash extension and produces a wrong result if /bin/sh is not Bash. - - - - - 89f034dd by Maximilian Tagher at 2020-03-17T07:36:48-04:00 Document the units of -ddump-timings Right now, in the output of -ddump-timings to a file, you can't tell what the units are: ``` CodeGen [TemplateTestImports]: alloc=22454880 time=14.597 ``` I believe bytes/milliseconds are the correct units, but confirmation would be appreciated. I'm basing it off of this snippet from `withTiming'`: ``` when (verbosity dflags >= 2 && prtimings == PrintTimings) $ liftIO $ logInfo dflags (defaultUserStyle dflags) (text "!!!" <+> what <> colon <+> text "finished in" <+> doublePrec 2 time <+> text "milliseconds" <> comma <+> text "allocated" <+> doublePrec 3 (realToFrac alloc / 1024 / 1024) <+> text "megabytes") ``` which implies time is in milliseconds, and allocations in bytes (which divided by 1024 would be KB, and again would be MB) - - - - - beffa147 by Simon Peyton Jones at 2020-03-17T07:37:25-04:00 Implement mapTyCo like foldTyCo This patch makes mapType use the successful idiom described in TyCoRep Note [Specialising foldType] I have not yet changed any functions to use mapType, though there may be some suitable candidates. This patch should be a no-op in terms of functionality but, because it inlines the mapper itself, I'm hoping that there may be some modest perf improvements. Metric Decrease: T5631 T5642 T3064 T9020 T14683 hie002 haddock.Cabal haddock.base haddock.compiler - - - - - 5800ebfe by Ömer Sinan Ağacan at 2020-03-17T07:38:08-04:00 Don't update ModDetails with CafInfos when opts are disabled This is consistent with the interface file behavior where we omit HsNoCafRefs annotations with -fomit-interface-pragmas (implied by -O0). ModDetails and ModIface are just different representations of the same thing, so they really need to be in sync. This patch does the right thing and does not need too much explanation, but here's an example of a problem not doing this causes in !2842: -- MyInteger.hs module MyInteger ( MyInteger (MyInteger) , ToMyInteger (toMyInteger) ) where newtype MyInteger = MyInteger Integer class ToMyInteger a where toMyInteger :: a -> MyInteger instance ToMyInteger Integer where toMyInteger = MyInteger {- . succ -} -- Main.hs module Main ( main ) where import MyInteger (MyInteger (MyInteger), toMyInteger) main :: IO () main = do let (MyInteger i) = (id . toMyInteger) (41 :: Integer) print i If I build this with -O0, without this fix, we generate a ModDetails with accurate LFInfo for toMyInteger (MyInteger.$fToMyIntegerInteger) which says that it's a LFReEntrant with arity 1. This means in the use site (Main) we tag the value: R3 = MyInteger.$fToMyIntegerInteger_closure + 1; R2 = GHC.Base.id_closure; R1 = GHC.Base.._closure; Sp = Sp - 16; call stg_ap_ppp_fast(R4, R3, R2, R1) args: 24, res: 0, upd: 24; Now we change the definition by uncommenting the `succ` part and it becomes a thunk: MyInteger.$fToMyIntegerInteger [InlPrag=INLINE (sat-args=0)] :: MyInteger.ToMyInteger GHC.Integer.Type.Integer [GblId[DFunId(nt)]] = {} \u [] $ctoMyInteger_rEA; and its LFInfo is now LFThunk. This change in LFInfo makes a difference in the use site: we can no longer tag it. But becuase the interface fingerprint does not change (because ModIface does not change) we don't rebuild Main and tag the thunk. (1.2% increase in allocations when building T12545 on armv7 because we generate more code without CafInfos) Metric Increase: T12545 - - - - - 5b632dad by Paavo at 2020-03-17T07:38:48-04:00 Add example for Data.Semigroup.diff - - - - - 4d85d68b by Paavo at 2020-03-17T07:38:48-04:00 Clean up - - - - - 75168d07 by Paavo at 2020-03-17T07:38:48-04:00 Make example collapsible - - - - - 53ff2cd0 by Richard Eisenberg at 2020-03-17T13:46:57+00:00 Fix #17021 by checking more return kinds All the details are in new Note [Datatype return kinds] in TcTyClsDecls. Test case: typecheck/should_fail/T17021{,b} typecheck/should_compile/T17021a Updates haddock submodule - - - - - 528df8ec by Sylvain Henry at 2020-03-18T10:06:43-04:00 Modules: Core operations (#13009) - - - - - 4e8a71c1 by Richard Eisenberg at 2020-03-18T10:07:19-04:00 Add release note about fix to #16502. We thought we needed to update the manual, but the fix for #16502 actually brings the implementation in line with the manual. So we just alert users of how to update their code. - - - - - 5cbf9934 by Andreas Klebinger at 2020-03-19T00:39:27-04:00 Update "GHC differences to the FFI Chapter" in user guide. The old entry had a heavy focus on how things had been. Which is not what I generally look for in a user guide. I also added a small section on behaviour of nested safe ffi calls. [skip-ci] - - - - - b03fd3bc by Sebastian Graf at 2020-03-19T00:40:06-04:00 PmCheck: Use ConLikeSet to model negative info In #17911, Simon recognised many warnings stemming from over-long list unions while coverage checking Cabal's `LicenseId` module. This patch introduces a new `PmAltConSet` type which uses a `UniqDSet` instead of an association list for `ConLike`s. For `PmLit`s, it will still use an assocation list, though, because a similar map data structure would entail a lot of busy work. Fixes #17911. - - - - - 64f20756 by Sylvain Henry at 2020-03-19T12:16:49-04:00 Refactoring: use Platform instead of DynFlags when possible Metric Decrease: ManyConstructors T12707 T13035 T1969 - - - - - cb1785d9 by Ömer Sinan Ağacan at 2020-03-19T12:16:54-04:00 FastString: fix eager reading of string ptr in hashStr This read causes NULL dereferencing when len is 0. Fixes #17909 In the reproducer in #17909 this bug is triggered as follows: - SimplOpt.dealWithStringLiteral is called with a single-char string ("=" in #17909) - tailFS gets called on the FastString of the single-char string. - tailFS checks the length of the string, which is 1, and calls mkFastStringByteString on the tail of the ByteString, which is an empty ByteString as the original ByteString has only one char. - ByteString's unsafeUseAsCStringLen returns (NULL, 0) for the empty ByteString, which is passed to mkFastStringWith. - mkFastStringWith gets hash of the NULL pointer via hashStr, which fails on empty strings because of this bug. - - - - - 73a7383e by Richard Eisenberg at 2020-03-20T20:42:56-04:00 Simplify treatment of heterogeneous equality Previously, if we had a [W] (a :: k1) ~ (rhs :: k2), we would spit out a [D] k1 ~ k2 and part the W as irreducible, hoping for a unification. But we needn't do this. Instead, we now spit out a [W] co :: k2 ~ k1 and then use co to cast the rhs of the original Wanted. This means that we retain the connection between the spat-out constraint and the original. The problem with this new approach is that we cannot use the casted equality for substitution; it's too like wanteds-rewriting- wanteds. So, we forbid CTyEqCans that mention coercion holes. All the details are in Note [Equalities with incompatible kinds] in TcCanonical. There are a few knock-on effects, documented where they occur. While debugging an error in this patch, Simon and I ran into infelicities in how patterns and matches are printed; we made small improvements. This patch includes mitigations for #17828, which causes spurious pattern-match warnings. When #17828 is fixed, these lines should be removed. - - - - - faa36e5b by Sylvain Henry at 2020-03-20T20:43:41-04:00 Hadrian: ignore in-tree GMP objects with ``--lint`` - - - - - 9a96ff6b by Richard Eisenberg at 2020-03-20T20:44:17-04:00 Update core spec to reflect changes to Core. Key changes: * Adds a new rule for forall-coercions over coercion variables, which was implemented but conspicuously missing from the spec. * Adds treatment for FunCo. * Adds treatment for ForAllTy over coercion variables. * Improves commentary (including restoring a Note lost in 03d4852658e1b7407abb4da84b1b03bfa6f6db3b) in the source. No changes to running code. - - - - - 7e0451c6 by Sergej Jaskiewicz at 2020-03-20T20:44:55-04:00 Fix event message in withTiming' This typo caused generating 'end' events without the corresponding 'begin' events. - - - - - 1542a626 by Ben Gamari at 2020-03-22T22:37:47-04:00 fs.h: Add missing declarations on Windows - - - - - 3bcf2ccd by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump process submodule Avoids redundant case alternative warning. - - - - - 3b363ef9 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Normalize slashes in ghc-api annotations output Enable `normalise_slashes` on `annotations`, `listcomps`, and `parseTree` to fix Windows failures. - - - - - 25fc9429 by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - 7f58ec6d by Ben Gamari at 2020-03-22T22:37:47-04:00 testsuite: Fix TOP of T17786 - - - - - aadcd909 by GHC GitLab CI at 2020-03-22T22:37:47-04:00 testsuite: Update expected output on Windows - - - - - dc1eb10d by GHC GitLab CI at 2020-03-22T22:37:47-04:00 hadrian: Fix executable extension passed to testsuite driver - - - - - 58f62e2c by GHC GitLab CI at 2020-03-22T22:37:47-04:00 gitlab-ci: Require that Windows-hadrian job passes - - - - - 8dd2415d by Ben Gamari at 2020-03-22T22:37:47-04:00 hadrian: Eliminate redundant .exe from GHC path Previously we were invoking: bash -c "c:/GitLabRunner/builds/eEQrxK4p/0/ghc/ghc/toolchain/bin/ghc.exe.exe testsuite/mk/ghc-config.hs -o _build/test/bin/ghc-config.exe" - - - - - 373621f6 by Ben Gamari at 2020-03-22T22:37:47-04:00 Bump hsc2hs submodule - - - - - abc02b40 by Hécate at 2020-03-22T22:38:33-04:00 Annotate the non-total function in Data.Foldable as such - - - - - 19f12557 by Josef Svenningsson at 2020-03-23T14:05:33-04:00 Fix ApplicativeDo regression #17835 A previous fix for #15344 made sure that monadic 'fail' is used properly when translating ApplicativeDo. However, it didn't properly account for when a 'fail' will be inserted which resulted in some programs failing with a type error. - - - - - 2643ba46 by Paavo at 2020-03-24T08:31:32-04:00 Add example and doc for Arg (Fixes #17153) - - - - - 703221f4 by Roland Senn at 2020-03-25T14:45:04-04:00 Use export list of Main module in function TcRnDriver.hs:check_main (Fix #16453) - Provide the export list of the `Main` module as parameter to the `compiler/typecheck/TcRnDriver.hs:check_main` function. - Instead of `lookupOccRn_maybe` call the function `lookupInfoOccRn`. It returns the list `mains_all` of all the main functions in scope. - Select from this list `mains_all` all `main` functions that are in the export list of the `Main` module. - If this new list contains exactly one single `main` function, then typechecking continues. - Otherwise issue an appropriate error message. - - - - - 3e27205a by Sebastian Graf at 2020-03-25T14:45:40-04:00 Remove -fkill-absence and -fkill-one-shot flags They seem to be a benchmarking vestige of the Cardinality paper and probably shouldn't have been merged to HEAD in the first place. - - - - - 262e42aa by Peter Trommler at 2020-03-25T22:41:39-04:00 Do not panic on linker errors - - - - - 0de03cd7 by Sylvain Henry at 2020-03-25T22:42:02-04:00 DynFlags refactoring III Use Platform instead of DynFlags when possible: * `tARGET_MIN_INT` et al. replaced with `platformMinInt` et al. * no more DynFlags in PreRules: added a new `RuleOpts` datatype * don't use `wORD_SIZE` in the compiler * make `wordAlignment` use `Platform` * make `dOUBLE_SIZE` a constant Metric Decrease: T13035 T1969 - - - - - 7a04920b by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: fix a typo in liftA doc This change removes an extra '|' that should not be rendered in the liftA documentation. Tracking: #17929 - - - - - 1c5a15f7 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add Control.Applicative optional example This change adds an optional example. Tracking: #17929 - - - - - 6d172e63 by Tristan Cacqueray at 2020-03-25T22:42:06-04:00 Base: add markup around Except - - - - - eb2162c8 by John Ericson at 2020-03-26T12:37:08-04:00 Remove unused `ghciTablesNextToCode` from compiler proper - - - - - f51efc4b by Joachim Breitner at 2020-03-26T12:37:09-04:00 Prepare to use run-time tablesNextToCode in compiler exclusively Factor out CPP as much as possible to prepare for runtime determinattion. Progress towards #15548 - - - - - 1c446220 by Joachim Breitner at 2020-03-26T12:37:09-04:00 Use run-time tablesNextToCode in compiler exclusively (#15548) Summary: - There is no more use of the TABLES_NEXT_TO_CODE CPP macro in `compiler/`. GHCI_TABLES_NEXT_TO_CODE is also removed entirely. The field within `PlatformMisc` within `DynFlags` is used instead. - The field is still not exposed as a CLI flag. We might consider some way to ensure the right RTS / libraries are used before doing that. Original reviewers: Original subscribers: TerrorJack, rwbarton, carter Original Differential Revision: https://phabricator.haskell.org/D5082 - - - - - 1941ef4f by Sylvain Henry at 2020-03-29T17:28:51-04:00 Modules: Types (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - 1c7c6f1a by Sylvain Henry at 2020-03-29T17:28:51-04:00 Remove GHC.Types.Unique.Map module This module isn't used anywhere in GHC. - - - - - f1a6c73d by Sylvain Henry at 2020-03-29T17:28:51-04:00 Merge GHC.Types.CostCentre.Init into GHC.Driver.CodeOutput - - - - - 54250f2d by Simon Peyton Jones at 2020-03-29T17:29:30-04:00 Demand analysis: simplify the demand for a RHS Ticket #17932 showed that we were using a stupid demand for the RHS of a let-binding, when the result is a product. This was the result of a "fix" in 2013, which (happily) turns out to no longer be necessary. So I just deleted the code, which simplifies the demand analyser, and fixes #17932. That in turn uncovered that the anticipation of worker/wrapper in CPR analysis was inaccurate, hence the logic that decides whether to unbox an argument in WW was extracted into a function `wantToUnbox`, now consulted by CPR analysis. I tried nofib, and got 0.0% perf changes. All this came up when messing about with !2873 (ticket #17917), but is idependent of it. Unfortunately, this patch regresses #4267 and realised that it is now blocked on #16335. - - - - - 03060b2f by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 on Windows Fixes line ending normalization issue. - - - - - 1f7995ba by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Fix T17786 Fix missing quoting and expected exit code. - - - - - ef9c608e by Ben Gamari at 2020-03-29T17:30:05-04:00 testsuite: Mark T12971 as broken on Windows Due to #17945. - - - - - e54500c1 by Sylvain Henry at 2020-03-29T17:30:47-04:00 Store ComponentId details As far as GHC is concerned, installed package components ("units") are identified by an opaque ComponentId string provided by Cabal. But we don't want to display it to users (as it contains a hash) so GHC queries the database to retrieve some infos about the original source package (name, version, component name). This patch caches these infos in the ComponentId itself so that we don't need to provide DynFlags (which contains installed package informations) to print a ComponentId. In the future we want GHC to support several independent package states (e.g. for plugins and for target code), hence we need to avoid implicitly querying a single global package state. - - - - - 7e7cb714 by Marius Bakke at 2020-03-29T17:31:27-04:00 testsuite: Remove test that dlopens a PIE object. glibc 2.30 disallowed dlopening PIE objects, so just remove the test. Fixes #17952. - - - - - 6c8f80d8 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Correct haddocks for testBit in Data.Bits It conflated the nth bit with the bit at offset n. Now we instead give the definition in terms of `bit and `.&.` on top of clearer phrasing. - - - - - c916f190 by Andreas Klebinger at 2020-03-29T17:32:04-04:00 Apply suggestion to libraries/base/Data/Bits.hs - - - - - 64bf7f51 by Ben Gamari at 2020-03-29T17:32:41-04:00 gitlab-ci: Add FreeBSD release job - - - - - a0d8e92e by Ryan Scott at 2020-03-29T17:33:20-04:00 Run checkNewDataCon before constraint-solving newtype constructors Within `checkValidDataCon`, we used to run `checkValidType` on the argument types of a newtype constructor before running `checkNewDataCon`, which ensures that the user does not attempt non-sensical things such as newtypes with multiple arguments or constraints. This works out in most situations, but this falls over on a corner case revealed in #17955: ```hs newtype T = Coercible () T => T () ``` `checkValidType`, among other things, peforms an ambiguity check on the context of a data constructor, and that it turn invokes the constraint solver. It turns out that there is a special case in the constraint solver for representational equalities (read: `Coercible` constraints) that causes newtypes to be unwrapped (see `Note [Unwrap newtypes first]` in `TcCanonical`). This special case does not know how to cope with an ill formed newtype like `T`, so it ends up panicking. The solution is surprisingly simple: just invoke `checkNewDataCon` before `checkValidType` to ensure that the illicit newtype constructor context is detected before the constraint solver can run amok with it. Fixes #17955. - - - - - 45eb9d8c by Krzysztof Gogolewski at 2020-03-29T17:33:59-04:00 Minor cleanup - Simplify mkBuildExpr, the function newTyVars was called only on a one-element list. - TTG: use noExtCon in more places. This is more future-proof. - In zonkExpr, panic instead of printing a warning. - - - - - f024b6e3 by Sylvain Henry at 2020-03-30T12:48:39+02:00 Expect T4267 to pass Since 54250f2d8de910b094070c1b48f086030df634b1 we expected T4267 to fail, but it passes on CI. - - - - - 57b888c0 by Ryan Scott at 2020-03-31T10:54:20-04:00 Require GHC 8.8 as the minimum compiler for bootstrapping This allows us to remove several bits of CPP that are either always true or no longer reachable. As an added bonus, we no longer need to worry about importing `Control.Monad.Fail.fail` qualified to avoid clashing with `Control.Monad.fail`, since the latter is now the same as the former. - - - - - 33f09551 by Ryan Scott at 2020-03-31T10:54:57-04:00 Add regression test for #17963 The panic in #17963 happened to be fixed by commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70. This patch adds a regression test to ensure that it remains fixed. Fixes #17963. - - - - - 09a36e80 by Ömer Sinan Ağacan at 2020-03-31T10:55:37-04:00 Simplify stderrSupportsAnsiColors The combinator andM is used only once, and the code is shorter and simpler if you inline it. - - - - - 95bccdd0 by Ben Gamari at 2020-03-31T10:56:19-04:00 base: Ensure that encoding global variables aren't inlined As noted in #17970, these (e.g. `getFileSystemEncoding` and `setFileSystemEncoding`) previously had unfoldings, which would break their global-ness. While not strictly necessary, I also add a NOINLINE on `initLocaleEncoding` since it is used in `System.IO`, ensuring that we only system's query the locale encoding once. Fixes #17970. - - - - - 982aaa83 by Andreas Klebinger at 2020-03-31T10:56:55-04:00 Update hadrian index revision. Required in order to build hadrian using ghc-8.10 - - - - - 4b9c5864 by Ben Gamari at 2020-03-31T10:57:32-04:00 integer-gmp: Bump version and add changelog entry - - - - - 9b39f2e6 by Ryan Scott at 2020-04-01T01:20:00-04:00 Clean up "Eta reduction for data families" Notes Before, there were two distinct Notes named "Eta reduction for data families". This renames one of them to "Implementing eta reduction for data families" to disambiguate the two and fixes references in other parts of the codebase to ensure that they are pointing to the right place. Fixes #17313. [ci skip] - - - - - 7627eab5 by Ryan Scott at 2020-04-01T01:20:38-04:00 Fix the changelog/@since information for hGetContents'/getContents'/readFile' Fixes #17979. [ci skip] - - - - - 0002db1b by Sylvain Henry at 2020-04-01T01:21:27-04:00 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957) Metric Decrease: T13035 T1969 - - - - - 7b217179 by Sebastian Graf at 2020-04-01T15:03:24-04:00 PmCheck: Adjust recursion depth for inhabitation test In #17977, we ran into the reduction depth limit of the typechecker. That was only a symptom of a much broader issue: The recursion depth of the coverage checker for trying to instantiate strict fields in the `nonVoid` test was far too high (100, the `defaultMaxTcBound`). As a result, we were performing quite poorly on `T17977`. Short of a proper termination analysis to prove emptyness of a type, we just arbitrarily default to a much lower recursion limit of 3. Fixes #17977. - - - - - 3c09f636 by Andreas Klebinger at 2020-04-01T15:03:59-04:00 Make hadrian pass on the no-colour setting to GHC. Fixes #17983. - - - - - b943b25d by Simon Peyton Jones at 2020-04-02T01:45:58-04:00 Re-engineer the binder-swap transformation The binder-swap transformation is implemented by the occurrence analyser -- see Note [Binder swap] in OccurAnal. However it had a very nasty corner in it, for the case where the case scrutinee was a GlobalId. This led to trouble and hacks, and ultimately to #16296. This patch re-engineers how the occurrence analyser implements the binder-swap, by actually carrying out a substitution rather than by adding a let-binding. It's all described in Note [The binder-swap substitution]. I did a few other things along the way * Fix a bug in StgCse, which could allow a loop breaker to be CSE'd away. See Note [Care with loop breakers] in StgCse. I think it can only show up if occurrence analyser sets up bad loop breakers, but still. * Better commenting in SimplUtils.prepareAlts * A little refactoring in CoreUnfold; nothing significant e.g. rename CoreUnfold.mkTopUnfolding to mkFinalUnfolding * Renamed CoreSyn.isFragileUnfolding to hasCoreUnfolding * Move mkRuleInfo to CoreFVs We observed respectively 4.6% and 5.9% allocation decreases for the following tests: Metric Decrease: T9961 haddock.base - - - - - 42d68364 by Sebastian Graf at 2020-04-02T01:46:34-04:00 Preserve precise exceptions in strictness analysis Fix #13380 and #17676 by 1. Changing `raiseIO#` to have `topDiv` instead of `botDiv` 2. Give it special treatment in `Simplifier.Util.mkArgInfo`, treating it as if it still had `botDiv`, to recover dead code elimination. This is the first commit of the plan outlined in https://gitlab.haskell.org/ghc/ghc/-/merge_requests/2525#note_260886. - - - - - 0a88dd11 by Ömer Sinan Ağacan at 2020-04-02T01:47:25-04:00 Fix a pointer format string in RTS - - - - - 5beac042 by Ömer Sinan Ağacan at 2020-04-02T01:48:05-04:00 Remove unused closure stg_IND_direct - - - - - 88f38b03 by Ben Gamari at 2020-04-02T01:48:42-04:00 Session: Memoize stderrSupportsAnsiColors Not only is this a reasonable efficiency measure but it avoids making reentrant calls into ncurses, which is not thread-safe. See #17922. - - - - - 27740f24 by Ryan Scott at 2020-04-02T01:49:21-04:00 Make Hadrian build with Cabal-3.2 GHC 8.10 ships with `Cabal-3.2.0.0`, so it would be convenient to make Hadrian supporting building against 3.2.* instead of having to rebuild the entirety of `Cabal-3.0.0.0`. There is one API change in `Cabal-3.2.*` that affects Hadrian: the `synopsis` and `description` functions now return `ShortText` instead of `String`. Since Hadrian manipulates these `String`s in various places, I found that the simplest fix was to use CPP to convert `ShortText` to `String`s where appropriate. - - - - - 49802002 by Sylvain Henry at 2020-04-02T01:50:00-04:00 Update Stack resolver for hadrian/build-stack Broken by 57b888c0e90be7189285a6b078c30b26d0923809 - - - - - 30a63e79 by Ryan Scott at 2020-04-02T01:50:36-04:00 Fix two ASSERT buglets in reifyDataCon Two `ASSERT`s in `reifyDataCon` were always using `arg_tys`, but `arg_tys` is not meaningful for GADT constructors. In fact, it's worse than non-meaningful, since using `arg_tys` when reifying a GADT constructor can lead to failed `ASSERT`ions, as #17305 demonstrates. This patch applies the simplest possible fix to the immediate problem. The `ASSERT`s now use `r_arg_tys` instead of `arg_tys`, as the former makes sure to give something meaningful for GADT constructors. This makes the panic go away at the very least. There is still an underlying issue with the way the internals of `reifyDataCon` work, as described in https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227023, but we leave that as future work, since fixing the underlying issue is much trickier (see https://gitlab.haskell.org/ghc/ghc/issues/17305#note_227087). - - - - - ef7576c4 by Zubin Duggal at 2020-04-03T06:24:56-04:00 Add outputable instances for the types in GHC.Iface.Ext.Types, add -ddump-hie flag to dump pretty printed contents of the .hie file Metric Increase: hie002 Because of the regression on i386: compile_time/bytes allocated increased from i386-linux-deb9 baseline @ HEAD~10: Expected hie002 (normal) compile_time/bytes allocated: 583014888.0 +/-10% Lower bound hie002 (normal) compile_time/bytes allocated: 524713399 Upper bound hie002 (normal) compile_time/bytes allocated: 641316377 Actual hie002 (normal) compile_time/bytes allocated: 877986292 Deviation hie002 (normal) compile_time/bytes allocated: 50.6 % *** unexpected stat test failure for hie002(normal) - - - - - 9462452a by Andreas Klebinger at 2020-04-03T06:25:33-04:00 Improve and refactor StgToCmm codegen for DataCons. We now differentiate three cases of constructor bindings: 1)Bindings which we can "replace" with a reference to an existing closure. Reference the replacement closure when accessing the binding. 2)Bindings which we can "replace" as above. But we still generate a closure which will be referenced by modules importing this binding. 3)For any other binding generate a closure. Then reference it. Before this patch 1) did only apply to local bindings and we didn't do 2) at all. - - - - - a214d214 by Moritz Bruder at 2020-04-03T06:26:11-04:00 Add singleton to NonEmpty in libraries/base This adds a definition to construct a singleton non-empty list (Data.List.NonEmpty) according to issue #17851. - - - - - f7597aa0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Testsuite: measure compiler stats for T16190 We were mistakenly measuring program stats - - - - - a485c3c4 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Move blob handling into StgToCmm Move handling of big literal strings from CmmToAsm to StgToCmm. It avoids the use of `sdocWithDynFlags` (cf #10143). We might need to move this handling even higher in the pipeline in the future (cf #17960): this patch will make it easier. - - - - - cc2918a0 by Sylvain Henry at 2020-04-03T06:26:54-04:00 Refactor CmmStatics In !2959 we noticed that there was some redundant code (in GHC.Cmm.Utils and GHC.Cmm.StgToCmm.Utils) used to deal with `CmmStatics` datatype (before SRT generation) and `RawCmmStatics` datatype (after SRT generation). This patch removes this redundant code by using a single GADT for (Raw)CmmStatics. - - - - - 9e60273d by Maxim Koltsov at 2020-04-03T06:27:32-04:00 Fix haddock formatting in Control.Monad.ST.Lazy.Imp.hs - - - - - 1b7e8a94 by Andreas Klebinger at 2020-04-03T06:28:08-04:00 Turn newlines into spaces for hadrian/ghci. The newlines break the command on windows. - - - - - 4291bdda by Simon Peyton Jones at 2020-04-03T06:28:44-04:00 Major improvements to the specialiser This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy at sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments! - - - - - 40a85563 by Ömer Sinan Ağacan at 2020-04-03T18:26:19+03:00 Revert accidental change in 9462452 [ci skip] - - - - - bd75e5da by Ryan Scott at 2020-04-04T07:07:58-04:00 Enable ImpredicativeTypes internally when typechecking selector bindings This is necessary for certain record selectors with higher-rank types, such as the examples in #18005. See `Note [Impredicative record selectors]` in `TcTyDecls`. Fixes #18005. - - - - - dcfe29c8 by Ömer Sinan Ağacan at 2020-04-06T13:16:08-04:00 Don't override proc CafInfos in ticky builds Fixes #17947 When we have a ticky label for a proc, IdLabels for the ticky counter and proc entry share the same Name. This caused overriding proc CafInfos with the ticky CafInfos (i.e. NoCafRefs) during SRT analysis. We now ignore the ticky labels when building SRTMaps. This makes sense because: - When building the current module they don't need to be in SRTMaps as they're initialized as non-CAFFY (see mkRednCountsLabel), so they don't take part in the dependency analysis and they're never added to SRTs. (Reminder: a "dependency" in the SRT analysis is a CAFFY dependency, non-CAFFY uses are not considered as dependencies for the algorithm) - They don't appear in the interfaces as they're not exported, so it doesn't matter for cross-module concerns whether they're in the SRTMap or not. See also the new Note [Ticky labels in SRT analysis]. - - - - - cec2c71f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Fix an tricky specialiser loop Issue #17151 was a very tricky example of a bug in which the specialiser accidentally constructs a recurive dictionary, so that everything turns into bottom. I have fixed variants of this bug at least twice before: see Note [Avoiding loops]. It was a bit of a struggle to isolate the problem, greatly aided by the work that Alexey Kuleshevich did in distilling a test case. Once I'd understood the problem, it was not difficult to fix, though it did lead me a bit of refactoring in specImports. - - - - - e850d14f by Simon Peyton Jones at 2020-04-06T13:16:44-04:00 Refactoring only This refactors DictBinds into a data type rather than a pair. No change in behaviour, just better code - - - - - f38e8d61 by Daniel Gröber at 2020-04-07T02:00:05-04:00 rts: ProfHeap: Fix memory leak when not compiled with profiling If we're doing heap profiling on an unprofiled executable we keep allocating new space in initEra via nextEra on each profiler run but we don't have a corresponding freeEra call. We do free the last era in endHeapProfiling but previous eras will have been overwritten by initEra and will never get free()ed. Metric Decrease: space_leak_001 - - - - - bcd66859 by Sebastian Graf at 2020-04-07T02:00:41-04:00 Re-export GHC.Magic.noinline from base - - - - - 3d2991f8 by Ben Gamari at 2020-04-07T18:36:09-04:00 simplifier: Kill off ufKeenessFactor We used to have another factor, ufKeenessFactor, which would scale the discounts before they were subtracted from the size. This was justified with the following comment: -- We multiple the raw discounts (args_discount and result_discount) -- ty opt_UnfoldingKeenessFactor because the former have to do with -- *size* whereas the discounts imply that there's some extra -- *efficiency* to be gained (e.g. beta reductions, case reductions) -- by inlining. However, this is highly suspect since it means that we subtract a *scaled* size from an absolute size, resulting in crazy (e.g. negative) scores in some cases (#15304). We consequently killed off ufKeenessFactor and bumped up the ufUseThreshold to compensate. Adjustment of unfolding use threshold ===================================== Since this removes a discount from our inlining heuristic, I revisited our default choice of -funfolding-use-threshold to minimize the change in overall inlining behavior. Specifically, I measured runtime allocations and executable size of nofib and the testsuite performance tests built using compilers (and core libraries) built with several values of -funfolding-use-threshold. This comes as a result of a quantitative comparison of testsuite performance and code size as a function of ufUseThreshold, comparing GHC trees using values of 50, 60, 70, 80, 90, and 100. The test set consisted of nofib and the testsuite performance tests. A full summary of these measurements are found in the description of !2608 Comparing executable sizes (relative to the base commit) across all nofib tests, we see that sizes are similar to the baseline: gmean min max median thresh 50 -6.36% -7.04% -4.82% -6.46% 60 -5.04% -5.97% -3.83% -5.11% 70 -2.90% -3.84% -2.31% -2.92% 80 -0.75% -2.16% -0.42% -0.73% 90 +0.24% -0.41% +0.55% +0.26% 100 +1.36% +0.80% +1.64% +1.37% baseline +0.00% +0.00% +0.00% +0.00% Likewise, looking at runtime allocations we see that 80 gives slightly better optimisation than the baseline: gmean min max median thresh 50 +0.16% -0.16% +4.43% +0.00% 60 +0.09% -0.00% +3.10% +0.00% 70 +0.04% -0.09% +2.29% +0.00% 80 +0.02% -1.17% +2.29% +0.00% 90 -0.02% -2.59% +1.86% +0.00% 100 +0.00% -2.59% +7.51% -0.00% baseline +0.00% +0.00% +0.00% +0.00% Finally, I had to add a NOINLINE in T4306 to ensure that `upd` is worker-wrappered as the test expects. This makes me wonder whether the inlining heuristic is now too liberal as `upd` is quite a large function. The same measure was taken in T12600. Wall clock time compiling Cabal with -O0 thresh 50 60 70 80 90 100 baseline build-Cabal 93.88 89.58 92.59 90.09 100.26 94.81 89.13 Also, this change happens to avoid the spurious test output in `plugin-recomp-change` and `plugin-recomp-change-prof` (see #17308). Metric Decrease: hie002 T12234 T13035 T13719 T14683 T4801 T5631 T5642 T9020 T9872d T9961 Metric Increase: T12150 T12425 T13701 T14697 T15426 T1969 T3064 T5837 T6048 T9203 T9872a T9872b T9872c T9872d haddock.Cabal haddock.base haddock.compiler - - - - - 255418da by Sylvain Henry at 2020-04-07T18:36:49-04:00 Modules: type-checker (#13009) Update Haddock submodule - - - - - 04b6cf94 by Ryan Scott at 2020-04-07T19:43:20-04:00 Make NoExtCon fields strict This changes every unused TTG extension constructor to be strict in its field so that the pattern-match coverage checker is smart enough any such constructors are unreachable in pattern matches. This lets us remove nearly every use of `noExtCon` in the GHC API. The only ones we cannot remove are ones underneath uses of `ghcPass`, but that is only because GHC 8.8's and 8.10's coverage checkers weren't smart enough to perform this kind of reasoning. GHC HEAD's coverage checker, on the other hand, _is_ smart enough, so we guard these uses of `noExtCon` with CPP for now. Bumps the `haddock` submodule. Fixes #17992. - - - - - 7802fa17 by Ryan Scott at 2020-04-08T16:43:44-04:00 Handle promoted data constructors in typeToLHsType correctly Instead of using `nlHsTyVar`, which hardcodes `NotPromoted`, have `typeToLHsType` pick between `Promoted` and `NotPromoted` by checking if a type constructor is promoted using `isPromotedDataCon`. Fixes #18020. - - - - - ce481361 by Ben Gamari at 2020-04-09T16:17:21-04:00 hadrian: Use --export-dynamic when linking iserv As noticed in #17962, the make build system currently does this (see 3ce0e0ba) but the change was never ported to Hadrian. - - - - - fa66f143 by Ben Gamari at 2020-04-09T16:17:21-04:00 iserv: Don't pass --export-dynamic on FreeBSD This is definitely a hack but it's probably the best we can do for now. Hadrian does the right thing here by passing --export-dynamic only to the linker. - - - - - 39075176 by Ömer Sinan Ağacan at 2020-04-09T16:18:00-04:00 Fix CNF handling in compacting GC Fixes #17937 Previously compacting GC simply ignored CNFs. This is mostly fine as most (see "What about small compacts?" below) CNF objects don't have outgoing pointers, and are "large" (allocated in large blocks) and large objects are not moved or compacted. However if we do GC *during* sharing-preserving compaction then the CNF will have a hash table mapping objects that have been moved to the CNF to their location in the CNF, to be able to preserve sharing. This case is handled in the copying collector, in `scavenge_compact`, where we evacuate hash table entries and then rehash the table. Compacting GC ignored this case. We now visit CNFs in all generations when threading pointers to the compacted heap and thread hash table keys. A visited CNF is added to the list `nfdata_chain`. After compaction is done, we re-visit the CNFs in that list and rehash the tables. The overhead is minimal: the list is static in `Compact.c`, and link field is added to `StgCompactNFData` closure. Programs that don't use CNFs should not be affected. To test this CNF tests are now also run in a new way 'compacting_gc', which just passes `-c` to the RTS, enabling compacting GC for the oldest generation. Before this patch the result would be: Unexpected failures: compact_gc.run compact_gc [bad exit code (139)] (compacting_gc) compact_huge_array.run compact_huge_array [bad exit code (1)] (compacting_gc) With this patch all tests pass. I can also pass `-c -DS` without any failures. What about small compacts? Small CNFs are still not handled by the compacting GC. However so far I'm unable to write a test that triggers a runtime panic ("update_fwd: unknown/strange object") by allocating a small CNF in a compated heap. It's possible that I'm missing something and it's not possible to have a small CNF. NoFib Results: -------------------------------------------------------------------------------- Program Size Allocs Instrs Reads Writes -------------------------------------------------------------------------------- CS +0.1% 0.0% 0.0% +0.0% +0.0% CSD +0.1% 0.0% 0.0% 0.0% 0.0% FS +0.1% 0.0% 0.0% 0.0% 0.0% S +0.1% 0.0% 0.0% 0.0% 0.0% VS +0.1% 0.0% 0.0% 0.0% 0.0% VSD +0.1% 0.0% +0.0% +0.0% -0.0% VSM +0.1% 0.0% +0.0% -0.0% 0.0% anna +0.0% 0.0% -0.0% -0.0% -0.0% ansi +0.1% 0.0% +0.0% +0.0% +0.0% atom +0.1% 0.0% +0.0% +0.0% +0.0% awards +0.1% 0.0% +0.0% +0.0% +0.0% banner +0.1% 0.0% +0.0% +0.0% +0.0% bernouilli +0.1% 0.0% 0.0% -0.0% +0.0% binary-trees +0.1% 0.0% -0.0% -0.0% 0.0% boyer +0.1% 0.0% +0.0% +0.0% +0.0% boyer2 +0.1% 0.0% +0.0% +0.0% +0.0% bspt +0.1% 0.0% -0.0% -0.0% -0.0% cacheprof +0.1% 0.0% -0.0% -0.0% -0.0% calendar +0.1% 0.0% +0.0% +0.0% +0.0% cichelli +0.1% 0.0% +0.0% +0.0% +0.0% circsim +0.1% 0.0% +0.0% +0.0% +0.0% clausify +0.1% 0.0% -0.0% +0.0% +0.0% comp_lab_zift +0.1% 0.0% +0.0% +0.0% +0.0% compress +0.1% 0.0% +0.0% +0.0% 0.0% compress2 +0.1% 0.0% -0.0% 0.0% 0.0% constraints +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm1 +0.1% 0.0% +0.0% +0.0% +0.0% cryptarithm2 +0.1% 0.0% +0.0% +0.0% +0.0% cse +0.1% 0.0% +0.0% +0.0% +0.0% digits-of-e1 +0.1% 0.0% +0.0% -0.0% -0.0% digits-of-e2 +0.1% 0.0% -0.0% -0.0% -0.0% dom-lt +0.1% 0.0% +0.0% +0.0% +0.0% eliza +0.1% 0.0% +0.0% +0.0% +0.0% event +0.1% 0.0% +0.0% +0.0% +0.0% exact-reals +0.1% 0.0% +0.0% +0.0% +0.0% exp3_8 +0.1% 0.0% +0.0% -0.0% 0.0% expert +0.1% 0.0% +0.0% +0.0% +0.0% fannkuch-redux +0.1% 0.0% -0.0% 0.0% 0.0% fasta +0.1% 0.0% -0.0% +0.0% +0.0% fem +0.1% 0.0% -0.0% +0.0% 0.0% fft +0.1% 0.0% -0.0% +0.0% +0.0% fft2 +0.1% 0.0% +0.0% +0.0% +0.0% fibheaps +0.1% 0.0% +0.0% +0.0% +0.0% fish +0.1% 0.0% +0.0% +0.0% +0.0% fluid +0.0% 0.0% +0.0% +0.0% +0.0% fulsom +0.1% 0.0% -0.0% +0.0% 0.0% gamteb +0.1% 0.0% +0.0% +0.0% 0.0% gcd +0.1% 0.0% +0.0% +0.0% +0.0% gen_regexps +0.1% 0.0% -0.0% +0.0% 0.0% genfft +0.1% 0.0% +0.0% +0.0% +0.0% gg +0.1% 0.0% 0.0% +0.0% +0.0% grep +0.1% 0.0% -0.0% +0.0% +0.0% hidden +0.1% 0.0% +0.0% -0.0% 0.0% hpg +0.1% 0.0% -0.0% -0.0% -0.0% ida +0.1% 0.0% +0.0% +0.0% +0.0% infer +0.1% 0.0% +0.0% 0.0% -0.0% integer +0.1% 0.0% +0.0% +0.0% +0.0% integrate +0.1% 0.0% -0.0% -0.0% -0.0% k-nucleotide +0.1% 0.0% +0.0% +0.0% 0.0% kahan +0.1% 0.0% +0.0% +0.0% +0.0% knights +0.1% 0.0% -0.0% -0.0% -0.0% lambda +0.1% 0.0% +0.0% +0.0% -0.0% last-piece +0.1% 0.0% +0.0% 0.0% 0.0% lcss +0.1% 0.0% +0.0% +0.0% 0.0% life +0.1% 0.0% -0.0% +0.0% +0.0% lift +0.1% 0.0% +0.0% +0.0% +0.0% linear +0.1% 0.0% -0.0% +0.0% 0.0% listcompr +0.1% 0.0% +0.0% +0.0% +0.0% listcopy +0.1% 0.0% +0.0% +0.0% +0.0% maillist +0.1% 0.0% +0.0% -0.0% -0.0% mandel +0.1% 0.0% +0.0% +0.0% 0.0% mandel2 +0.1% 0.0% +0.0% +0.0% +0.0% mate +0.1% 0.0% +0.0% 0.0% +0.0% minimax +0.1% 0.0% -0.0% 0.0% -0.0% mkhprog +0.1% 0.0% +0.0% +0.0% +0.0% multiplier +0.1% 0.0% +0.0% 0.0% 0.0% n-body +0.1% 0.0% +0.0% +0.0% +0.0% nucleic2 +0.1% 0.0% +0.0% +0.0% +0.0% para +0.1% 0.0% 0.0% +0.0% +0.0% paraffins +0.1% 0.0% +0.0% -0.0% 0.0% parser +0.1% 0.0% -0.0% -0.0% -0.0% parstof +0.1% 0.0% +0.0% +0.0% +0.0% pic +0.1% 0.0% -0.0% -0.0% 0.0% pidigits +0.1% 0.0% +0.0% -0.0% -0.0% power +0.1% 0.0% +0.0% +0.0% +0.0% pretty +0.1% 0.0% -0.0% -0.0% -0.1% primes +0.1% 0.0% -0.0% -0.0% -0.0% primetest +0.1% 0.0% -0.0% -0.0% -0.0% prolog +0.1% 0.0% -0.0% -0.0% -0.0% puzzle +0.1% 0.0% -0.0% -0.0% -0.0% queens +0.1% 0.0% +0.0% +0.0% +0.0% reptile +0.1% 0.0% -0.0% -0.0% +0.0% reverse-complem +0.1% 0.0% +0.0% 0.0% -0.0% rewrite +0.1% 0.0% -0.0% -0.0% -0.0% rfib +0.1% 0.0% +0.0% +0.0% +0.0% rsa +0.1% 0.0% -0.0% +0.0% -0.0% scc +0.1% 0.0% -0.0% -0.0% -0.1% sched +0.1% 0.0% +0.0% +0.0% +0.0% scs +0.1% 0.0% +0.0% +0.0% +0.0% simple +0.1% 0.0% -0.0% -0.0% -0.0% solid +0.1% 0.0% +0.0% +0.0% +0.0% sorting +0.1% 0.0% -0.0% -0.0% -0.0% spectral-norm +0.1% 0.0% +0.0% +0.0% +0.0% sphere +0.1% 0.0% -0.0% -0.0% -0.0% symalg +0.1% 0.0% -0.0% -0.0% -0.0% tak +0.1% 0.0% +0.0% +0.0% +0.0% transform +0.1% 0.0% +0.0% +0.0% +0.0% treejoin +0.1% 0.0% +0.0% -0.0% -0.0% typecheck +0.1% 0.0% +0.0% +0.0% +0.0% veritas +0.0% 0.0% +0.0% +0.0% +0.0% wang +0.1% 0.0% 0.0% +0.0% +0.0% wave4main +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve1 +0.1% 0.0% +0.0% +0.0% +0.0% wheel-sieve2 +0.1% 0.0% +0.0% +0.0% +0.0% x2n1 +0.1% 0.0% +0.0% +0.0% +0.0% -------------------------------------------------------------------------------- Min +0.0% 0.0% -0.0% -0.0% -0.1% Max +0.1% 0.0% +0.0% +0.0% +0.0% Geometric Mean +0.1% -0.0% -0.0% -0.0% -0.0% Bumping numbers of nonsensical perf tests: Metric Increase: T12150 T12234 T12425 T13035 T5837 T6048 It's simply not possible for this patch to increase allocations, and I've wasted enough time on these test in the past (see #17686). I think these tests should not be perf tests, but for now I'll bump the numbers. - - - - - dce50062 by Sylvain Henry at 2020-04-09T16:18:44-04:00 Rts: show errno on failure (#18033) - - - - - 045139f4 by Hécate at 2020-04-09T23:10:44-04:00 Add an example to liftIO and explain its purpose - - - - - 101fab6e by Sebastian Graf at 2020-04-09T23:11:21-04:00 Special case `isConstraintKindCon` on `AlgTyCon` Previously, the `tyConUnique` record selector would unfold into a huge case expression that would be inlined in all call sites, such as the `INLINE`-annotated `coreView`, see #18026. `constraintKindTyConKey` only occurs as the `Unique` of an `AlgTyCon` anyway, so we can make the code a lot more compact, but have to move it to GHC.Core.TyCon. Metric Decrease: T12150 T12234 - - - - - f5212dfc by Sebastian Graf at 2020-04-09T23:11:57-04:00 DmdAnal: No need to attach a StrictSig to DataCon workers In GHC.Types.Id.Make we were giving a strictness signature to every data constructor wrapper Id that we weren't looking at in demand analysis anyway. We used to use its CPR info, but that has its own CPR signature now. `Note [Data-con worker strictness]` then felt very out of place, so I moved it to GHC.Core.DataCon. - - - - - 75a185dc by Sylvain Henry at 2020-04-09T23:12:37-04:00 Hadrian: fix --summary - - - - - 723062ed by Ömer Sinan Ağacan at 2020-04-10T09:18:14+03:00 testsuite: Move no_lint to the top level, tweak hie002 - We don't want to benchmark linting so disable lints in hie002 perf test - Move no_lint to the top-level to be able to use it in tests other than those in `testsuite/tests/perf/compiler`. - Filter out -dstg-lint in no_lint. - hie002 allocation numbers on 32-bit are unstable, so skip it on 32-bit Metric Decrease: hie002 ManyConstructors T12150 T12234 T13035 T1969 T4801 T9233 T9961 - - - - - bcafaa82 by Peter Trommler at 2020-04-10T19:29:33-04:00 Testsuite: mark T11531 fragile The test depends on a link editor allowing undefined symbols in an ELF shared object. This is the standard but it seems some distributions patch their link editor. See the report by @hsyl20 in #11531. Fixes #11531 - - - - - 0889f5ee by Takenobu Tani at 2020-04-12T11:44:52+09:00 testsuite: Fix comment for a language extension [skip ci] - - - - - cd4f92b5 by Simon Peyton Jones at 2020-04-12T11:20:58-04:00 Significant refactor of Lint This refactoring of Lint was triggered by #17923, which is fixed by this patch. The main change is this. Instead of lintType :: Type -> LintM LintedKind we now have lintType :: Type -> LintM LintedType Previously, all of typeKind was effectively duplicate in lintType. Moreover, since we have an ambient substitution, we still had to apply the substition here and there, sometimes more than once. It was all very tricky, in the end, and made my head hurt. Now, lintType returns a fully linted type, with all substitutions performed on it. This is much simpler. The same thing is needed for Coercions. Instead of lintCoercion :: OutCoercion -> LintM (LintedKind, LintedKind, LintedType, LintedType, Role) we now have lintCoercion :: Coercion -> LintM LintedCoercion Much simpler! The code is shorter and less bug-prone. There are a lot of knock on effects. But life is now better. Metric Decrease: T1969 - - - - - 0efaf301 by Josh Meredith at 2020-04-12T11:21:34-04:00 Implement extensible interface files - - - - - 54ca66a7 by Ryan Scott at 2020-04-12T11:22:10-04:00 Use conLikeUserTyVarBinders to quantify field selector types This patch: 1. Writes up a specification for how the types of top-level field selectors should be determined in a new section of the GHC User's Guide, and 2. Makes GHC actually implement that specification by using `conLikeUserTyVarBinders` in `mkOneRecordSelector` to preserve the order and specificity of type variables written by the user. Fixes #18023. - - - - - 35799dda by Ben Gamari at 2020-04-12T11:22:50-04:00 hadrian: Don't --export-dynamic on Darwin When fixing #17962 I neglected to consider that --export-dynamic is only supported on ELF platforms. - - - - - e8029816 by Alexis King at 2020-04-12T11:23:27-04:00 Add an INLINE pragma to Control.Category.>>> This fixes #18013 by adding INLINE pragmas to both Control.Category.>>> and GHC.Desugar.>>>. The functional change in this patch is tiny (just two lines of pragmas!), but an accompanying Note explains in gory detail what’s going on. - - - - - 0da186c1 by Krzysztof Gogolewski at 2020-04-14T07:55:20-04:00 Change zipWith to zipWithEqual in a few places - - - - - 074c1ccd by Andreas Klebinger at 2020-04-14T07:55:55-04:00 Small change to the windows ticker. We already have a function to go from time to ms so use it. Also expand on the state of timer resolution. - - - - - b69cc884 by Alp Mestanogullari at 2020-04-14T07:56:38-04:00 hadrian: get rid of unnecessary levels of nesting in source-dist - - - - - d0c3b069 by Julien Debon at 2020-04-14T07:57:16-04:00 doc (Foldable): Add examples to Data.Foldable See #17929 - - - - - 5b08e0c0 by Ben Gamari at 2020-04-14T23:28:20-04:00 StgCRun: Enable unwinding only on Linux It's broken on macOS due and SmartOS due to assembler differences (#15207) so let's be conservative in enabling it. Also, refactor things to make the intent clearer. - - - - - 27cc2e7b by Ben Gamari at 2020-04-14T23:28:57-04:00 rts: Don't mark evacuate_large as inline This function has two callsites and is quite large. GCC consequently decides not to inline and warns instead. Given the situation, I can't blame it. Let's just remove the inline specifier. - - - - - 9853fc5e by Ben Gamari at 2020-04-14T23:29:48-04:00 base: Enable large file support for OFD locking impl. Not only is this a good idea in general but this should also avoid issue #17950 by ensuring that off_t is 64-bits. - - - - - 7b41f21b by Matthew Pickering at 2020-04-14T23:30:24-04:00 Hadrian: Make -i paths absolute The primary reason for this change is that ghcide does not work with relative paths. It also matches what cabal and stack do, they always pass absolute paths. - - - - - 41230e26 by Daniel Gröber at 2020-04-14T23:31:01-04:00 Zero out pinned block alignment slop when profiling The heap profiler currently cannot traverse pinned blocks because of alignment slop. This used to just be a minor annoyance as the whole block is accounted into a special cost center rather than the respective object's CCS, cf. #7275. However for the new root profiler we would like to be able to visit _every_ closure on the heap. We need to do this so we can get rid of the current 'flip' bit hack in the heap traversal code. Since info pointers are always non-zero we can in principle skip all the slop in the profiler if we can rely on it being zeroed. This assumption caused problems in the past though, commit a586b33f8e ("rts: Correct handling of LARGE ARR_WORDS in LDV profiler"), part of !1118, tried to use the same trick for BF_LARGE objects but neglected to take into account that shrink*Array# functions don't ensure that slop is zeroed when not compiling with profiling. Later, commit 0c114c6599 ("Handle large ARR_WORDS in heap census (fix as we will only be assuming slop is zeroed when profiling is on. This commit also reduces the ammount of slop we introduce in the first place by calculating the needed alignment before doing the allocation for small objects where we know the next available address. For large objects we don't know how much alignment we'll have to do yet since those details are hidden behind the allocateMightFail function so there we continue to allocate the maximum additional words we'll need to do the alignment. So we don't have to duplicate all this logic in the cmm code we pull it into the RTS allocatePinned function instead. Metric Decrease: T7257 haddock.Cabal haddock.base - - - - - 15fa9bd6 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Expand and add more notes regarding slop - - - - - caf3f444 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: allocatePinned: Fix confusion about word/byte units - - - - - c3c0f662 by Daniel Gröber at 2020-04-14T23:31:01-04:00 rts: Underline some Notes as is conventional - - - - - e149dea9 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Fix nomenclature in OVERWRITING_CLOSURE macros The additional commentary introduced by commit 8916e64e5437 ("Implement shrinkSmallMutableArray# and resizeSmallMutableArray#.") unfortunately got this wrong. We set 'prim' to true in overwritingClosureOfs because we _don't_ want to call LDV_recordDead(). The reason is because of this "inherently used" distinction made in the LDV profiler so I rename the variable to be more appropriate. - - - - - 1dd3d18c by Daniel Gröber at 2020-04-14T23:31:38-04:00 Remove call to LDV_RECORD_CREATE for array resizing - - - - - 19de2fb0 by Daniel Gröber at 2020-04-14T23:31:38-04:00 rts: Assert LDV_recordDead is not called for inherently used closures The comments make it clear LDV_recordDead should not be called for inhererently used closures, so add an assertion to codify this fact. - - - - - 0b934e30 by Ryan Scott at 2020-04-14T23:32:14-04:00 Bump template-haskell version to 2.17.0.0 This requires bumping the `exceptions` and `text` submodules to bring in commits that bump their respective upper version bounds on `template-haskell`. Fixes #17645. Fixes #17696. Note that the new `text` commit includes a fair number of additions to the Haddocks in that library. As a result, Haddock has to do more work during the `haddock.Cabal` test case, increasing the number of allocations it requires. Therefore, ------------------------- Metric Increase: haddock.Cabal ------------------------- - - - - - 22cc8e51 by Ryan Scott at 2020-04-15T17:48:47-04:00 Fix #18052 by using pprPrefixOcc in more places This fixes several small oversights in the choice of pretty-printing function to use. Fixes #18052. - - - - - ec77b2f1 by Daniel Gröber at 2020-04-15T17:49:24-04:00 rts: ProfHeap: Fix wrong time in last heap profile sample We've had this longstanding issue in the heap profiler, where the time of the last sample in the profile is sometimes way off causing the rendered graph to be quite useless for long runs. It seems to me the problem is that we use mut_user_time() for the last sample as opposed to getRTSStats(), which we use when calling heapProfile() in GC.c. The former is equivalent to getProcessCPUTime() but the latter does some additional stuff: getProcessCPUTime() - end_init_cpu - stats.gc_cpu_ns - stats.nonmoving_gc_cpu_ns So to fix this just use getRTSStats() in both places. - - - - - 85fc32f0 by Sylvain Henry at 2020-04-17T12:45:25-04:00 Hadrian: fix dyn_o/dyn_hi rule (#17534) - - - - - bfde3b76 by Ryan Scott at 2020-04-17T12:46:02-04:00 Fix #18065 by fixing an InstCo oversight in Core Lint There was a small thinko in Core Lint's treatment of `InstCo` coercions that ultimately led to #18065. The fix: add an apostrophe. That's it! Fixes #18065. Co-authored-by: Simon Peyton Jones <simonpj at microsoft.com> - - - - - a05348eb by Cale Gibbard at 2020-04-17T13:08:47-04:00 Change the fail operator argument of BindStmt to be a Maybe Don't use noSyntaxExpr for it. There is no good way to defensively case on that, nor is it clear one ought to do so. - - - - - 79e27144 by John Ericson at 2020-04-17T13:08:47-04:00 Use trees that grow for rebindable operators for `<-` binds Also add more documentation. - - - - - 18bc16ed by Cale Gibbard at 2020-04-17T13:08:47-04:00 Use FailOperator in more places, define a couple datatypes (XBindStmtRn and XBindStmtTc) to help clarify the meaning of XBindStmt in the renamer and typechecker - - - - - 84cc8394 by Simon Peyton Jones at 2020-04-18T13:20:29-04:00 Add a missing zonk in tcHsPartialType I omitted a vital zonk when refactoring tcHsPartialType in commit 48fb3482f8cbc8a4b37161021e846105f980eed4 Author: Simon Peyton Jones <simonpj at microsoft.com> Date: Wed Jun 5 08:55:17 2019 +0100 Fix typechecking of partial type signatures This patch fixes it and adds commentary to explain why. Fixes #18008 - - - - - 2ee96ac1 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Bump FreeBSD bootstrap compiler to 8.10.1 - - - - - 434312e5 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Enable FreeBSD job for so-labelled MRs - - - - - ddffb227 by Ben Gamari at 2020-04-18T13:21:05-04:00 gitlab-ci: Use rules syntax for conditional jobs - - - - - e2586828 by Ben Gamari at 2020-04-18T13:21:05-04:00 Bump hsc2hs submodule - - - - - 15ab6cd5 by Ömer Sinan Ağacan at 2020-04-18T13:21:44-04:00 Improve prepForeignCall error reporting Show parameters and description of the error code when ffi_prep_cif fails. This may be helpful for debugging #17018. - - - - - 3ca52151 by Sylvain Henry at 2020-04-18T20:04:14+02:00 GHC.Core.Opt renaming * GHC.Core.Op => GHC.Core.Opt * GHC.Core.Opt.Simplify.Driver => GHC.Core.Opt.Driver * GHC.Core.Opt.Tidy => GHC.Core.Tidy * GHC.Core.Opt.WorkWrap.Lib => GHC.Core.Opt.WorkWrap.Utils As discussed in: * https://mail.haskell.org/pipermail/ghc-devs/2020-April/018758.html * https://gitlab.haskell.org/ghc/ghc/issues/13009#note_264650 - - - - - 15312bbb by Sylvain Henry at 2020-04-18T20:04:46+02:00 Modules (#13009) * SysTools * Parser * GHC.Builtin * GHC.Iface.Recomp * Settings Update Haddock submodule Metric Decrease: Naperian parsing001 - - - - - eaed0a32 by Alexis King at 2020-04-19T03:16:44-04:00 Add missing addInScope call for letrec binders in OccurAnal This fixes #18044, where a shadowed variable was incorrectly substituted by the binder swap on the RHS of a floated-in letrec. This can only happen when the uniques line up *just* right, so writing a regression test would be very difficult, but at least the fix is small and straightforward. - - - - - 36882493 by Shayne Fletcher at 2020-04-20T04:36:43-04:00 Derive Ord instance for Extension Metric Increase: T12150 T12234 - - - - - b43365ad by Simon Peyton Jones at 2020-04-20T04:37:20-04:00 Fix a buglet in redundant-constraint warnings Ticket #18036 pointed out that we were reporting a redundant constraint when it really really wasn't. Turned out to be a buglet in the SkolemInfo for the relevant implication constraint. Easily fixed! - - - - - d5fae7da by Ömer Sinan Ağacan at 2020-04-20T14:39:28-04:00 Mark T12010 fragile on 32-bit - - - - - bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - ffd7eef2 by Takenobu Tani at 2020-04-22T23:09:50-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - e8a5d81b by Jonathan DK Gibbons at 2020-04-22T23:10:28-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - dcb7fe5a by John Ericson at 2020-04-22T23:10:28-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - cde23cd4 by John Ericson at 2020-04-22T23:10:28-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - 72cb6bcc by John Ericson at 2020-04-22T23:10:28-04:00 Generalize type of `matchCanFail` - - - - - 401f7bb3 by John Ericson at 2020-04-22T23:10:28-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 6c9fae23 by Alexis King at 2020-04-22T23:11:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 48b8951e by Roland Senn at 2020-04-22T23:11:51-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 34a45ee6 by Peter Trommler at 2020-04-22T23:12:27-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - ffde2348 by Simon Peyton Jones at 2020-04-22T23:13:06-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 6f84aca3 by Ben Gamari at 2020-04-22T23:13:43-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - c29f0fa6 by Andreas Klebinger at 2020-04-22T23:14:21-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 4b4a8b60 by Ben Gamari at 2020-04-22T23:14:57-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 831b6642 by Moritz Angermann at 2020-04-22T23:15:33-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - c409961a by Ryan Scott at 2020-04-22T23:16:12-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 125aa2b8 by Ömer Sinan Ağacan at 2020-04-22T23:16:51-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - 8ea37b01 by Sylvain Henry at 2020-04-22T23:17:34-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - cd8409c2 by Ryan Scott at 2020-04-23T11:39:24-04:00 Create di_scoped_tvs for associated data family instances properly See `Note [Associated data family instances and di_scoped_tvs]` in `GHC.Tc.TyCl.Instance`, which explains all of the moving parts. Fixes #18055. - - - - - 339e8ece by Ben Gamari at 2020-04-23T11:40:02-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 5946c85a by Ben Gamari at 2020-04-23T11:40:38-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - c42754d5 by John Ericson at 2020-04-23T18:32:43-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 72da0c29 by mniip at 2020-04-23T18:33:21-04:00 Add :doc to GHC.Prim - - - - - 2c23e2e3 by mniip at 2020-04-23T18:33:21-04:00 Include docs for non-primop entries in primops.txt as well - - - - - 0ac29c88 by mniip at 2020-04-23T18:33:21-04:00 GHC.Prim docs: note and test - - - - - b0fbfc75 by John Ericson at 2020-04-24T12:07:14-04:00 Switch order on `GhcMake.IsBoot` In !1798 we were requested to replace many `Bool`s with this data type. But those bools had `False` meaning `NotBoot`, so the `Ord` instance would be flipped if we use this data-type as-is. Since the planned formally-`Bool` occurrences vastly outnumber the current occurrences, we figured it would be better to conform the `Ord` instance to how the `Bool` is used now, fixing any issues, rather than fix them currently with the bigger refactor later in !1798. That way, !1798 can be a "pure" refactor with no behavioral changes. - - - - - af332442 by Sylvain Henry at 2020-04-26T13:55:14-04:00 Modules: Utils and Data (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - cd4434c8 by Sylvain Henry at 2020-04-26T13:55:16-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 22bf5c73 by Ömer Sinan Ağacan at 2020-04-26T13:55:22-04:00 Tweak includes in non-moving GC headers We don't use hash tables in non-moving GC so remove the includes. This breaks Compact.c as existing includes no longer include Hash.h, so include Hash.h explicitly in Compact.c. - - - - - 99823ed2 by Sylvain Henry at 2020-04-27T20:24:46-04:00 TH: fix Show/Eq/Ord instances for Bytes (#16457) We shouldn't compare pointer values but the actual bytes. - - - - - c62271a2 by Alp Mestanogullari at 2020-04-27T20:25:33-04:00 hadrian: always capture both stdout and stderr when running a builder fails The idea being that when a builder('s command) fails, we quite likely want to have all the information available to figure out why. Depending on the builder _and_ the particular problem, the useful bits of information can be printed on stdout or stderr. We accomplish this by defining a simple wrapper for Shake's `cmd` function, that just _always_ captures both streams in case the command returns a non-zero exit code, and by using this wrapper everywhere in `hadrian/src/Builder.hs`. Fixes #18089. - - - - - 4b9764db by Ryan Scott at 2020-04-28T15:40:04-04:00 Define a Quote IO instance Fixes #18103. - - - - - 518a63d4 by Ryan Scott at 2020-04-28T15:40:42-04:00 Make boxed 1-tuples have known keys Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. - - - - - 2cfc4ab9 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Document backpack fields in DynFlags - - - - - 10a2ba90 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 69562e34 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 9e2c8e0e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - ea717aa4 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 10d15f1e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 8bfb0219 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - 71484b09 by Alexis King at 2020-04-30T01:57:35-04:00 Allow block arguments in arrow control operators Arrow control operators have their own entries in the grammar, so they did not cooperate with BlockArguments. This was just a minor oversight, so this patch adjusts the grammar to add the desired behavior. fixes #18050 - - - - - a48cd2a0 by Alexis King at 2020-04-30T01:57:35-04:00 Allow LambdaCase to be used as a command in proc notation - - - - - f4d3773c by Alexis King at 2020-04-30T01:57:35-04:00 Document BlockArguments/LambdaCase support in arrow notation - - - - - 5bdfdd13 by Simon Peyton Jones at 2020-04-30T01:58:15-04:00 Add tests for #17873 - - - - - 19b701c2 by Simon Peyton Jones at 2020-04-30T07:30:13-04:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - 014ef4a3 by Matthew Pickering at 2020-04-30T07:30:50-04:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 2aa67611 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - 54dad3cf by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - 99ff8145 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 05b0a9fd by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 Remove OneShotInfo field of LFReEntrant, document OneShotInfo The field is only used in withNewTickyCounterFun and it's easier to directly pass a parameter for one-shot info to withNewTickyCounterFun instead of passing it via LFReEntrant. This also makes !2842 simpler. Other changes: - New Note (by SPJ) [OneShotInfo overview] added. - Arity argument of thunkCode removed as it's always 0. - - - - - a43620c6 by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 GHC.StgToCmm.Ticky: remove a few unused stuff - - - - - 780de9e1 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Use platform in Iface Binary - - - - - f8386c7b by Sylvain Henry at 2020-05-01T10:37:39-04:00 Refactor PprDebug handling If `-dppr-debug` is set, then PprUser and PprDump styles are silently replaced with PprDebug style. This was done in `mkUserStyle` and `mkDumpStyle` smart constructors. As a consequence they needed a DynFlags parameter. Now we keep the original PprUser and PprDump styles until they are used to create an `SDocContext`. I.e. the substitution is only performed in `initSDocContext`. - - - - - b3df9e78 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Remove PprStyle param of logging actions Use `withPprStyle` instead to apply a specific style to a SDoc. - - - - - de9fc995 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Fully remove PprDebug PprDebug was a pain to deal with consistently as it is implied by `-dppr-debug` but it isn't really a PprStyle. We remove it completely and query the appropriate SDoc flag instead (`sdocPprDebug`) via helpers (`getPprDebug` and its friends). - - - - - 8b51fcbd by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Only call checkSingle if we would report warnings - - - - - fd7ea0fe by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 7bfe9ac5 by Ben Gamari at 2020-05-03T04:41:33-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. - - - - - c560dd07 by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Move eventlog documentation users guide - - - - - 02543d5e by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Add documentation for non-moving GC events - - - - - b465dd45 by Alexis King at 2020-05-03T04:42:12-04:00 Flatten nested casts in the simple optimizer Normally, we aren’t supposed to generated any nested casts, since mkCast takes care to flatten them, but the simple optimizer didn’t use mkCast, so they could show up after inlining. This isn’t really a problem, since the simplifier will clean them up immediately anyway, but it can clutter the -ddump-ds output, and it’s an extremely easy fix. closes #18112 - - - - - 8bdc03d6 by Simon Peyton Jones at 2020-05-04T01:56:59-04:00 Don't return a panic in tcNestedSplice In GHC.Tc.Gen.Splice.tcNestedSplice we were returning a typechecked expression of "panic". That is usually OK, because the result is discarded. But it happens that tcApp now looks at the typechecked expression, trivially, to ask if it is tagToEnum. So being bottom is bad. Moreover a debug-trace might print it out. So better to return a civilised expression, even though it is usually discarded. - - - - - 0bf640b1 by Baldur Blöndal at 2020-05-04T01:57:36-04:00 Don't require parentheses around via type (`-XDerivingVia'). Fixes #18130". - - - - - 30272412 by Artem Pelenitsyn at 2020-05-04T13:19:59-04:00 Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) - - - - - b9f7c08f by jneira at 2020-05-04T13:20:37-04:00 Remove unused hs-boot file - - - - - 1d8f80cd by Sylvain Henry at 2020-05-05T03:22:46-04:00 Remove references to -package-key * remove references to `-package-key` which has been removed in 2016 (240ddd7c39536776e955e881d709bbb039b48513) * remove support for `-this-package-key` which has been deprecated at the same time - - - - - 7bc3a65b by Sylvain Henry at 2020-05-05T03:23:31-04:00 Remove SpecConstrAnnotation (#13681) This has been deprecated since 2013. Use GHC.Types.SPEC instead. Make GHC.Exts "not-home" for haddock Metric Decrease: haddock.base - - - - - 3c862f63 by DenisFrezzato at 2020-05-05T03:24:15-04:00 Fix Haskell98 short description in documentation - - - - - 2420c555 by Ryan Scott at 2020-05-05T03:24:53-04:00 Add regression tests for #16244, #16245, #16758 Commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70 ended up fixing quite a few bugs: * This commit fixes #16244 completely. A regression test has been added. * This commit fixes one program from #16245. (The program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211369 still panics, and the program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211400 still loops infinitely.) A regression test has been added for this program. * This commit fixes #16758. Accordingly, this patch removes the `expect_broken` label from the `T16758` test case, moves it from `should_compile` to `should_fail` (as it should produce an error message), and checks in the expected stderr. - - - - - 40c71c2c by Sylvain Henry at 2020-05-05T03:25:31-04:00 Fix colorized error messages (#18128) In b3df9e780fb2f5658412c644849cd0f1e6f50331 I broke colorized messages by using "dump" style instead of "user" style. This commits fixes it. - - - - - 7ab6ab09 by Richard Eisenberg at 2020-05-06T04:39:32-04:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG ------------------------- - - - - - 420b957d by Ben Gamari at 2020-05-06T04:40:08-04:00 rts: Zero block flags with -DZ Block flags are very useful for determining the state of a block. However, some block allocator users don't touch them, leading to misleading values. Ensure that we zero then when zero-on-gc is set. This is safe and makes the flags more useful during debugging. - - - - - 740b3b8d by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix incorrect failed_to_evac value during deadlock gc Previously we would incorrectly set the failed_to_evac flag if we evacuated a value due to a deadlock GC. This would cause us to mark more things as dirty than strictly necessary. It also turned up a nasty but which I will fix next. - - - - - b2d72c75 by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - 9f3e6884 by Zubin Duggal at 2020-05-06T04:41:08-04:00 Allow atomic update of NameCache in readHieFile The situation arises in ghcide where multiple different threads may need to update the name cache, therefore with the older interface it could happen that you start reading a hie file with name cache A and produce name cache A + B, but another thread in the meantime updated the namecache to A + C. Therefore if you write the new namecache you will lose the A' updates from the second thread. Updates haddock submodule - - - - - edec6a6c by Ryan Scott at 2020-05-06T04:41:57-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _)`. Fixes #18127. - - - - - a95e7fe0 by Ömer Sinan Ağacan at 2020-05-06T04:42:39-04:00 ELF linker: increment curSymbol after filling in fields of current entry The bug was introduced in a8b7cef4d45 which added a field to the `symbols` array elements and then updated this code incorrectly: - oc->symbols[curSymbol++] = nm; + oc->symbols[curSymbol++].name = nm; + oc->symbols[curSymbol].addr = symbol->addr; - - - - - cab1871a by Sylvain Henry at 2020-05-06T04:43:21-04:00 Move LeadingUnderscore into Platform (#17957) Avoid direct use of DynFlags to know if symbols must be prefixed by an underscore. - - - - - 94e7c563 by Sylvain Henry at 2020-05-06T04:43:21-04:00 Don't use DynFlags in showLinkerState (#17957) - - - - - 9afd9251 by Ryan Scott at 2020-05-06T04:43:58-04:00 Refactoring: Use bindSigTyVarsFV in rnMethodBinds `rnMethodBinds` was explicitly using `xoptM` to determine if `ScopedTypeVariables` is enabled before bringing type variables bound by the class/instance header into scope. However, this `xoptM` logic is already performed by the `bindSigTyVarsFV` function. This patch uses `bindSigTyVarsFV` in `rnMethodBinds` to reduce the number of places where we need to consult if `ScopedTypeVariables` is on. This is purely refactoring, and there should be no user-visible change in behavior. - - - - - 6f6d72b2 by Brian Foley at 2020-05-08T15:29:25-04:00 Remove further dead code found by a simple Python script. Avoid removing some functions that are part of an API even though they're not used in-tree at the moment. - - - - - 78bf8bf9 by Julien Debon at 2020-05-08T15:29:28-04:00 Add doc examples for Bifoldable See #17929 - - - - - 66f0a847 by Julien Debon at 2020-05-08T15:29:29-04:00 doc (Bitraversable): Add examples to Bitraversable * Add examples to Data.Bitraversable * Fix formatting for (,) in Bitraversable and Bifoldable * Fix mistake on bimapAccumR documentation See #17929 - - - - - 9749fe12 by Baldur Blöndal at 2020-05-08T15:29:32-04:00 Specify kind variables for inferred kinds in base. - - - - - 4e9aef9e by John Ericson at 2020-05-08T15:29:36-04:00 HsSigWcTypeScoping: Pull in documentation from stray location - - - - - f4d5c6df by John Ericson at 2020-05-08T15:29:36-04:00 Rename local `real_fvs` to `implicit_vs` It doesn't make sense to call the "free" variables we are about to implicitly bind the real ones. - - - - - 20570b4b by John Ericson at 2020-05-08T15:29:36-04:00 A few tiny style nits with renaming - Use case rather than guards that repeatedly scrutenize same thing. - No need for view pattern when `L` is fine. - Use type synnonym to convey the intent like elsewhere. - - - - - 09ac8de5 by John Ericson at 2020-05-08T15:29:36-04:00 Add `forAllOrNothing` function with note - - - - - bb35c0e5 by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Document lawlessness of Ap's Num instance - - - - - cdd229ff by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply suggestion to libraries/base/Data/Monoid.hs - - - - - 926d2aab by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply more suggestions from Simon Jakobi - - - - - 7a763cff by Adam Gundry at 2020-05-08T15:29:41-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. - - - - - 88e3c815 by Simon Peyton Jones at 2020-05-08T15:29:41-04:00 Fix specialisation for DFuns When specialising a DFun we must take care to saturate the unfolding. See Note [Specialising DFuns] in Specialise. Fixes #18120 - - - - - 86c77b36 by Greg Steuck at 2020-05-08T15:29:45-04:00 Remove unused SEGMENT_PROT_RWX It's been unused for a year and is problematic on any OS which requires W^X for security. - - - - - 9d97f4b5 by nineonine at 2020-05-08T15:30:03-04:00 Add test for #16167 - - - - - aa318338 by Ryan Scott at 2020-05-08T15:30:04-04:00 Bump exceptions submodule so that dist-boot is .gitignore'd `exceptions` is a stage-0 boot library as of commit 30272412fa437ab8e7a8035db94a278e10513413, which means that building `exceptions` in a GHC tree will generate a `dist-boot` directory. However, this directory was not specified in `exceptions`' `.gitignore` file, which causes it to dirty up the current `git` working directory. Accordingly, this bumps the `exceptions` submodule to commit ghc/packages/exceptions at 23c0b8a50d7592af37ca09beeec16b93080df98f, which adds `dist-boot` to the `.gitignore` file. - - - - - ea86360f by Ömer Sinan Ağacan at 2020-05-08T15:30:30-04:00 Linker.c: initialize n_symbols of ObjectCode with other fields - - - - - 951c1fb0 by Sylvain Henry at 2020-05-09T21:46:38-04:00 Fix unboxed-sums GC ptr-slot rubbish value (#17791) This patch allows boot libraries to use unboxed sums without implicitly depending on `base` package because of `absentSumFieldError`. See updated Note [aBSENT_SUM_FIELD_ERROR_ID] in GHC.Core.Make - - - - - b352d63c by Ben Gamari at 2020-05-09T21:47:14-04:00 rts: Make non-existent linker search path merely a warning As noted in #18105, previously this resulted in a rather intrusive error message. This is in contrast to the general expectation that search paths are merely places to look, not places that must exist. Fixes #18105. - - - - - cf4f1e2f by Ben Gamari at 2020-05-13T02:02:33-04:00 rts/CNF: Fix fixup comparison function Previously we would implicitly convert the difference between two words to an int, resulting in an integer overflow on 64-bit machines. Fixes #16992 - - - - - a03da9bf by Ömer Sinan Ağacan at 2020-05-13T02:03:16-04:00 Pack some of IdInfo fields into a bit field This reduces residency of compiler quite a bit on some programs. Example stats when building T10370: Before: 2,871,242,832 bytes allocated in the heap 4,693,328,008 bytes copied during GC 33,941,448 bytes maximum residency (276 sample(s)) 375,976 bytes maximum slop 83 MiB total memory in use (0 MB lost due to fragmentation) After: 2,858,897,344 bytes allocated in the heap 4,629,255,440 bytes copied during GC 32,616,624 bytes maximum residency (278 sample(s)) 314,400 bytes maximum slop 80 MiB total memory in use (0 MB lost due to fragmentation) So -3.9% residency, -1.3% bytes copied and -0.4% allocations. Fixes #17497 Metric Decrease: T9233 T9675 - - - - - 670c3e5c by Ben Gamari at 2020-05-13T02:03:54-04:00 get-win32-tarballs: Fix base URL Revert a change previously made for testing purposes. - - - - - 8ad8dc41 by Ben Gamari at 2020-05-13T02:03:54-04:00 get-win32-tarballs: Improve diagnostics output - - - - - 8c0740b7 by Simon Jakobi at 2020-05-13T02:04:33-04:00 docs: Add examples for Data.Semigroup.Arg{Min,Max} Context: #17153 - - - - - cb22348f by Ben Gamari at 2020-05-13T02:05:11-04:00 Add few cleanups of the CAF logic Give the NameSet of non-CAFfy names a proper newtype to distinguish it from all of the other NameSets floating about. - - - - - 90e38b81 by Emeka Nkurumeh at 2020-05-13T02:05:51-04:00 fix printf warning when using with ghc with clang on mingw - - - - - 86d8ac22 by Sebastian Graf at 2020-05-13T02:06:29-04:00 CprAnal: Don't attach CPR sigs to expandable bindings (#18154) Instead, look through expandable unfoldings in `cprTransform`. See the new Note [CPR for expandable unfoldings]: ``` Long static data structures (whether top-level or not) like xs = x1 : xs1 xs1 = x2 : xs2 xs2 = x3 : xs3 should not get CPR signatures, because they * Never get WW'd, so their CPR signature should be irrelevant after analysis (in fact the signature might even be harmful for that reason) * Would need to be inlined/expanded to see their constructed product * Recording CPR on them blows up interface file sizes and is redundant with their unfolding. In case of Nested CPR, this blow-up can be quadratic! But we can't just stop giving DataCon application bindings the CPR property, for example fac 0 = 1 fac n = n * fac (n-1) fac certainly has the CPR property and should be WW'd! But FloatOut will transform the first clause to lvl = 1 fac 0 = lvl If lvl doesn't have the CPR property, fac won't either. But lvl doesn't have a CPR signature to extrapolate into a CPR transformer ('cprTransform'). So instead we keep on cprAnal'ing through *expandable* unfoldings for these arity 0 bindings via 'cprExpandUnfolding_maybe'. In practice, GHC generates a lot of (nested) TyCon and KindRep bindings, one for each data declaration. It's wasteful to attach CPR signatures to each of them (and intractable in case of Nested CPR). ``` Fixes #18154. - - - - - e34bf656 by Ben Gamari at 2020-05-13T02:07:08-04:00 users-guide: Add discussion of shared object naming Fixes #18074. - - - - - 5d0f2445 by Ben Gamari at 2020-05-13T02:07:47-04:00 testsuite: Print sign of performance changes Executes the minor formatting change in the tabulated performance changes suggested in #18135. - - - - - 9e4b981f by Ben Gamari at 2020-05-13T02:08:24-04:00 testsuite: Add testcase for #18129 - - - - - 266310c3 by Ivan-Yudin at 2020-05-13T02:09:03-04:00 doc: Reformulate the opening paragraph of Ch. 4 in User's guide Removes mentioning of Hugs (it is not helpful for new users anymore). Changes the wording for the rest of the paragraph. Fixes #18132. - - - - - 55e35c0b by Baldur Blöndal at 2020-05-13T20:02:48-04:00 Predicate, Equivalence derive via `.. -> a -> All' - - - - - d7e0b57f by Alp Mestanogullari at 2020-05-13T20:03:30-04:00 hadrian: add a --freeze2 option to freeze stage 1 and 2 - - - - - d880d6b2 by Artem Pelenitsyn at 2020-05-13T20:04:11-04:00 Don't reload environment files on every setSessionDynFlags Makes `interpretPackageEnv` (which loads envirinment files) a part of `parseDynamicFlags` (parsing command-line arguments, which is typically done once) instead of `setSessionDynFlags` (which is typically called several times). Making several (transitive) calls to `interpretPackageEnv`, as before, caused #18125 #16318, which should be fixed now. - - - - - 102cfd67 by Ryan Scott at 2020-05-13T20:04:46-04:00 Factor out HsPatSigType for pat sigs/RULE term sigs (#16762) This implements chunks (2) and (3) of https://gitlab.haskell.org/ghc/ghc/issues/16762#note_270170. Namely, it introduces a dedicated `HsPatSigType` AST type, which represents the types that can appear in pattern signatures and term-level `RULE` binders. Previously, these were represented with `LHsSigWcType`. Although `LHsSigWcType` is isomorphic to `HsPatSigType`, the intended semantics of the two types are slightly different, as evidenced by the fact that they have different code paths in the renamer and typechecker. See also the new `Note [Pattern signature binders and scoping]` in `GHC.Hs.Types`. - - - - - b17574f7 by Hécate at 2020-05-13T20:05:28-04:00 fix(documentation): Fix the RST links to GHC.Prim - - - - - df021fb1 by Baldur Blöndal at 2020-05-13T20:06:06-04:00 Document (->) using inferred quantification for its runtime representations. Fixes #18142. - - - - - 1a93ea57 by Takenobu Tani at 2020-05-13T20:06:54-04:00 Tweak man page for ghc command This commit updates the ghc command's man page as followings: * Enable `man_show_urls` to show URL addresses in the `DESCRIPTION` section of ghc.rst, because sphinx currently removes hyperlinks for man pages. * Add a `SEE ALSO` section to point to the GHC homepage - - - - - a951e1ba by Takenobu Tani at 2020-05-13T20:07:37-04:00 GHCi: Add link to the user's guide in help message This commit adds a link to the user's guide in ghci's `:help` message. Newcomers could easily reach to details of ghci. - - - - - 404581ea by Jeff Happily at 2020-05-13T20:08:15-04:00 Handle single unused import - - - - - 1c999e5d by Ben Gamari at 2020-05-13T20:09:07-04:00 Ensure that printMinimalImports closes handle Fixes #18166. - - - - - c9f5a8f4 by Ben Gamari at 2020-05-13T20:09:51-04:00 hadrian: Tell testsuite driver about LLVM availability This reflects the logic present in the Make build system into Hadrian. Fixes #18167. - - - - - c05c0659 by Simon Jakobi at 2020-05-14T03:31:21-04:00 Improve some folds over Uniq[D]FM * Replace some non-deterministic lazy folds with strict folds. * Replace some O(n log n) folds in deterministic order with O(n) non-deterministic folds. * Replace some folds with set-operations on the underlying IntMaps. This reduces max residency when compiling `nofib/spectral/simple/Main.hs` with -O0 by about 1%. Maximum residency when compiling Cabal also seems reduced on the order of 3-9%. - - - - - 477f13bb by Simon Jakobi at 2020-05-14T03:31:58-04:00 Use Data.IntMap.disjoint Data.IntMap gained a dedicated `disjoint` function in containers-0.6.2.1. This patch applies this function where appropriate in hopes of modest compiler performance improvements. Closes #16806. - - - - - e9c0110c by Ben Gamari at 2020-05-14T12:25:53-04:00 IdInfo: Add reference to bitfield-packing ticket - - - - - 9bd20e83 by Sebastian Graf at 2020-05-15T10:42:09-04:00 DmdAnal: Improve handling of precise exceptions This patch does two things: Fix possible unsoundness in what was called the "IO hack" and implement part 2.1 of the "fixing precise exceptions" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions, which, in combination with !2956, supersedes !3014 and !2525. **IO hack** The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is called `exprMayThrowPreciseException` now. I came up with two testcases exemplifying possible unsoundness (if twisted enough) in the old approach: - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. - `T13380e`: Demonstrating unsoundness of the "IO hack" when we have Nested CPR. Not currently relevant, as we don't have Nested CPR yet. - `T13380f`: Demonstrating unsoundness of the "IO hack" for safe FFI calls. Basically, the IO hack assumed that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future, see `T13380e`. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380{d,e}` (and will hopefully be robust to Nested CPR). **Precise exceptions** In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that was terribly unprincipled. That unprincipledness resulted in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception (and the existing IO hack doesn't detect that) Fixing both issues in !3014 turned out to be too complicated and had the potential to regress in the future. Hence we decided to only fix `T13380b` and augment the `Divergence` lattice with a new middle-layer element, `ExnOrDiv`, which means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. See the wiki page on Step 2.1 for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#dead-code-elimination-for-raiseio-with-isdeadenddiv-introducing-exnordiv-step-21 - - - - - 568d7279 by Ben Gamari at 2020-05-15T10:42:46-04:00 GHC.Cmm.Opt: Handle MO_XX_Conv This MachOp was introduced by 2c959a1894311e59cd2fd469c1967491c1e488f3 but a wildcard match in cmmMachOpFoldM hid the fact that it wasn't handled. Ideally we would eliminate the match but this appears to be a larger task. Fixes #18141. - - - - - 1069e168 by Ben Gamari at 2020-05-19T08:14:09-04:00 simplCore: Ignore ticks in rule templates This fixes #17619, where a tick snuck in to the template of a rule, resulting in a panic during rule matching. The tick in question was introduced via post-inlining, as discussed in `Note [Simplifying rules]`. The solution we decided upon was to simply ignore ticks in the rule template, as discussed in `Note [Tick annotations in RULE matching]`. Fixes #18162. Fixes #17619. - - - - - 17 changed files: - .ghcid - .gitlab-ci.yml - + .gitlab/ci.sh - − .gitlab/darwin-init.sh - .gitlab/linters/check-cpp.py - .gitlab/merge_request_templates/merge-request.md - − .gitlab/prepare-system.sh - − .gitlab/push-test-metrics.sh - + .gitlab/test-metrics.sh - − .gitlab/win32-init.sh - CODEOWNERS - HACKING.md - aclocal.m4 - boot - + compiler/GHC.hs - + compiler/GHC/Builtin/Names.hs - + compiler/GHC/Builtin/Names.hs-boot The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/807c323c46c8788ec4fde204d10b9729abe9b0f9...1069e16838dfdbf9d4dca31d07d51f968d15d548 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/807c323c46c8788ec4fde204d10b9729abe9b0f9...1069e16838dfdbf9d4dca31d07d51f968d15d548 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 19 13:17:46 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Tue, 19 May 2020 09:17:46 -0400 Subject: [Git][ghc/ghc][wip/andreask/xchg_primop] Make exchange a sized operation as it should be. Message-ID: <5ec3dc7a93187_6e263f9ee25e3aec37242@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/xchg_primop at Glasgow Haskell Compiler / GHC Commits: e1069583 by Andreas Klebinger at 2020-05-19T15:16:10+02:00 Make exchange a sized operation as it should be. - - - - - 18 changed files: - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm/CPrim.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.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/CodeGen.hs - compiler/GHC/StgToCmm/Prim.hs - − compiler/codeGen/StgCmmPrim.hs - configure.ac - includes/stg/Prim.h - libraries/ghc-prim/cbits/atomic.c - rts/package.conf.in - rts/rts.cabal.in Changes: ===================================== compiler/GHC/Builtin/primops.txt.pp ===================================== @@ -2475,8 +2475,8 @@ primop WriteOffAddrOp_Word64 "writeWord64OffAddr#" GenPrimOp primop InterlockedExchangeAddr "interlockedExchangeAddr#" GenPrimOp Addr# -> Addr# -> Addr# - {The atomic exchange operation. Atomically exchanges a pair of addresses and - returns the old value.} + {The atomic exchange operation. Atomically exchanges the value at the first address + with the Addr# given as second argument. Implies a full barrier.} with has_side_effects = True ------------------------------------------------------------------------ ===================================== compiler/GHC/Cmm/MachOp.hs ===================================== @@ -632,7 +632,9 @@ data CallishMachOp | MO_AtomicRead Width | MO_AtomicWrite Width | MO_Cmpxchg Width - | MO_Xchg + -- Should be an AtomicRMW variant eventually. + -- Has at least aquire semantics. + | MO_Xchg Width deriving (Eq, Show) -- | The operation to perform atomically. ===================================== compiler/GHC/Cmm/Parser.y ===================================== @@ -1022,7 +1022,12 @@ callishMachOps = listToUFM $ ( "cmpxchg8", (MO_Cmpxchg W8,)), ( "cmpxchg16", (MO_Cmpxchg W16,)), ( "cmpxchg32", (MO_Cmpxchg W32,)), - ( "cmpxchg64", (MO_Cmpxchg W64,)) + ( "cmpxchg64", (MO_Cmpxchg W64,)), + + ( "xchg8", (MO_Xchg W8,)), + ( "xchg16", (MO_Xchg W16,)), + ( "xchg32", (MO_Xchg W32,)), + ( "xchg64", (MO_Xchg W64,)) -- ToDo: the rest, maybe -- edit: which rest? ===================================== compiler/GHC/CmmToAsm/CPrim.hs ===================================== @@ -106,8 +106,14 @@ atomicRMWLabel w amop = "hs_atomic_" ++ pprFunName amop ++ pprWidth w pprFunName AMO_Or = "or" pprFunName AMO_Xor = "xor" -xchgLabel :: String -xchgLabel = "hs_xchg" +xchgLabel :: Width -> String +xchgLabel w = "hs_xchg" ++ pprWidth w + where + pprWidth W8 = "8" + pprWidth W16 = "16" + pprWidth W32 = "32" + pprWidth W64 = "64" + pprWidth w = pprPanic "xchgLabel: Unsupported word width " (ppr w) cmpxchgLabel :: Width -> String cmpxchgLabel w = "hs_cmpxchg" ++ pprWidth w ===================================== compiler/GHC/CmmToAsm/PPC/CodeGen.hs ===================================== @@ -2024,7 +2024,7 @@ genCCall' config gcp target dest_regs args MO_Ctz _ -> unsupported MO_AtomicRMW {} -> unsupported MO_Cmpxchg w -> (fsLit $ cmpxchgLabel w, False) - MO_Xchg -> (fsLit $ xchgLabel, False) + MO_Xchg w -> (fsLit $ xchgLabel w, False) MO_AtomicRead _ -> unsupported MO_AtomicWrite _ -> unsupported ===================================== compiler/GHC/CmmToAsm/SPARC/CodeGen.hs ===================================== @@ -677,7 +677,7 @@ outOfLineMachOp_table mop MO_Ctz w -> fsLit $ ctzLabel w MO_AtomicRMW w amop -> fsLit $ atomicRMWLabel w amop MO_Cmpxchg w -> fsLit $ cmpxchgLabel w - MO_Xchg -> fsLit xchgLabel + MO_Xchg w -> fsLit $ xchgLabel w MO_AtomicRead w -> fsLit $ atomicReadLabel w MO_AtomicWrite w -> fsLit $ atomicWriteLabel w ===================================== compiler/GHC/CmmToAsm/X86/CodeGen.hs ===================================== @@ -2518,10 +2518,11 @@ genCCall' _ is32Bit (PrimTarget (MO_Cmpxchg width)) [dst] [addr, old, new] _ = d where format = intFormat width -genCCall' config is32Bit (PrimTarget MO_Xchg) [dst] [addr, value] _ = do +genCCall' config is32Bit (PrimTarget (MO_Xchg width)) [dst] [addr, value] _ = do let dst_r = getRegisterReg platform (CmmLocal dst) Amode amode addr_code <- getSimpleAmode is32Bit addr (newval, newval_code) <- getSomeReg value + -- Copy the value into the target register, perform the exchange. let code = toOL [ MOV format (OpReg newval) (OpReg dst_r) , XCHG format (OpAddr amode) dst_r @@ -2529,8 +2530,6 @@ genCCall' config is32Bit (PrimTarget MO_Xchg) [dst] [addr, value] _ = do return $ addr_code `appOL` newval_code `appOL` code where format = intFormat width - width | is32Bit = W32 - | otherwise = W64 platform = ncgPlatform config genCCall' _ is32Bit target dest_regs args bid = do @@ -3228,7 +3227,7 @@ outOfLineCmmOp bid mop res args MO_AtomicRead _ -> fsLit "atomicread" MO_AtomicWrite _ -> fsLit "atomicwrite" MO_Cmpxchg _ -> fsLit "cmpxchg" - MO_Xchg -> fsLit "xchg" + MO_Xchg _ -> should_be_inline MO_UF_Conv _ -> unsupported @@ -3248,6 +3247,11 @@ outOfLineCmmOp bid mop res args (MO_Prefetch_Data _ ) -> unsupported unsupported = panic ("outOfLineCmmOp: " ++ show mop ++ " not supported here") + -- If we generate a call for the given primop + -- something went wrong. + should_be_inline = panic ("outOfLineCmmOp: " ++ show mop + ++ " should be handled inline") + -- ----------------------------------------------------------------------------- -- Generating a table-branch ===================================== compiler/GHC/CmmToAsm/X86/Instr.hs ===================================== @@ -462,6 +462,7 @@ x86_regUsageOfInstr platform instr usageMM :: Operand -> Operand -> RegUsage usageMM (OpReg src) (OpReg dst) = mkRU [src, dst] [src, dst] usageMM (OpReg src) (OpAddr ea) = mkRU (use_EA ea [src]) [src] + usageMM (OpAddr ea) (OpReg dst) = mkRU (use_EA ea [dst]) [dst] usageMM _ _ = panic "X86.RegInfo.usageMM: no match" -- 3 operand form; first operand Read; second Modified; third Modified ===================================== compiler/GHC/CmmToAsm/X86/Ppr.hs ===================================== @@ -824,7 +824,7 @@ pprInstr platform i = case i of SETCC cond op -> pprCondInstr (sLit "set") cond (pprOperand platform II8 op) - (XCHG format src val) + XCHG format src val -> pprFormatOpReg (sLit "xchg") format src val JXX cond blockid ===================================== compiler/GHC/CmmToC.hs ===================================== @@ -831,7 +831,7 @@ pprCallishMachOp_for_C mop (MO_Ctz w) -> ptext (sLit $ ctzLabel w) (MO_AtomicRMW w amop) -> ptext (sLit $ atomicRMWLabel w amop) (MO_Cmpxchg w) -> ptext (sLit $ cmpxchgLabel w) - MO_Xchg -> ptext (sLit $ xchgLabel) + (MO_Xchg w) -> ptext (sLit $ xchgLabel w) (MO_AtomicRead w) -> ptext (sLit $ atomicReadLabel w) (MO_AtomicWrite w) -> ptext (sLit $ atomicWriteLabel w) (MO_UF_Conv w) -> ptext (sLit $ word2FloatLabel w) ===================================== compiler/GHC/CmmToLlvm/CodeGen.hs ===================================== @@ -281,7 +281,7 @@ genCall (PrimTarget (MO_Cmpxchg _width)) retVar' <- doExprW targetTy $ ExtractV retVar 0 statement $ Store retVar' dstVar -genCall (PrimTarget MO_Xchg) [] [addr, val] = runStmtsDecls $ do +genCall (PrimTarget (MO_Xchg _width)) [] [addr, val] = runStmtsDecls $ do addrVar <- exprToVarW addr valVar <- exprToVarW val let ptrTy = pLift $ getVarType valVar @@ -864,7 +864,7 @@ cmmPrimOpFunctions mop = do MO_AtomicRMW _ _ -> unsupported MO_AtomicWrite _ -> unsupported MO_Cmpxchg _ -> unsupported - MO_Xchg -> unsupported + MO_Xchg _ -> unsupported -- | Tail function calls genJump :: CmmExpr -> [GlobalReg] -> LlvmM StmtData ===================================== compiler/GHC/StgToCmm/Prim.hs ===================================== @@ -856,6 +856,10 @@ emitPrimOp dflags = \case Word2DoubleOp -> \[w] -> opAllDone $ \[res] -> do emitPrimCall [res] (MO_UF_Conv W64) [w] +-- Atomic operations + InterlockedExchangeAddr -> \[src, value] -> opAllDone $ \[res] -> + emitPrimCall [res] (MO_Xchg (wordWidth platform)) [src, value] + -- SIMD primops (VecBroadcastOp vcat n w) -> \[e] -> opAllDone $ \[res] -> do checkVecCompatibility dflags vcat n w ===================================== compiler/codeGen/StgCmmPrim.hs deleted ===================================== The diff for this file was not included because it is too large. ===================================== configure.ac ===================================== @@ -730,6 +730,8 @@ dnl unregisterised, Sparc, and PPC backends. FP_GCC_SUPPORTS__ATOMICS if test $CONF_GCC_SUPPORTS__ATOMICS = YES ; then AC_DEFINE([HAVE_C11_ATOMICS], [1], [Does GCC support __atomic primitives?]) +else + AC_MSG_ERROR([C compiler needs to support __atomic primitives.]) fi FP_GCC_EXTRA_FLAGS ===================================== includes/stg/Prim.h ===================================== @@ -50,7 +50,10 @@ void hs_atomicwrite8(StgWord x, StgWord val); void hs_atomicwrite16(StgWord x, StgWord val); void hs_atomicwrite32(StgWord x, StgWord val); void hs_atomicwrite64(StgWord x, StgWord64 val); -StgWord hs_xchg(StgPtr x, StgWord val); +StgWord hs_xchg8(StgPtr x, StgWord val); +StgWord hs_xchg16(StgPtr x, StgWord val); +StgWord hs_xchg32(StgPtr x, StgWord val); +StgWord hs_xchg64(StgPtr x, StgWord val); /* libraries/ghc-prim/cbits/bswap.c */ StgWord16 hs_bswap16(StgWord16 x); ===================================== libraries/ghc-prim/cbits/atomic.c ===================================== @@ -10,6 +10,8 @@ // according to the ABI and is not what GHC does when it generates // calls to these functions. +//TODO: We now require gcc-5, so we should use __atomic__op variants. + // FetchAddByteArrayOp_Int extern StgWord hs_atomic_add8(StgWord x, StgWord val); @@ -320,11 +322,33 @@ hs_cmpxchg64(StgWord x, StgWord64 old, StgWord64 new) // Atomic exchange operations -extern StgWord hs_xchg(StgPtr x, StgWord val); +extern StgWord hs_xchg8(StgPtr x, StgWord val); +StgWord +hs_xchg8(StgPtr x, StgWord val) +{ + return (StgWord) __atomic_exchange_1((volatile StgPtr) x, val, __ATOMIC_ACQUIRE); +} + +extern StgWord hs_xchg16(StgPtr x, StgWord val); +StgWord +hs_xchg16(StgPtr x, StgWord val) +{ + return (StgWord) __atomic_exchange_2(x, val, __ATOMIC_ACQUIRE); +} + +extern StgWord hs_xchg32(StgPtr x, StgWord val); +StgWord +hs_xchg32(StgPtr x, StgWord val) +{ + return (StgWord) __atomic_exchange_4((volatile StgPtr) x, val, __ATOMIC_ACQUIRE); +} + +//GCC provides this even on 32bit. +extern StgWord hs_xchg64(StgPtr x, StgWord val); StgWord -hs_xchg(StgPtr x, StgWord val) +hs_xchg64(StgPtr x, StgWord val) { - return __sync_lock_test_and_set((volatile StgPtr) x, val); + return (StgWord) __atomic_exchange_8((volatile StgPtr) x, val, __ATOMIC_ACQUIRE); } // AtomicReadByteArrayOp_Int ===================================== rts/package.conf.in ===================================== @@ -168,7 +168,10 @@ ld-options: #if WORD_SIZE_IN_BITS == 64 , "-Wl,-u,_hs_cmpxchg64" #endif - , "-Wl,-u,_hs_xchg" + , "-Wl,-u,_hs_xchg8" + , "-Wl,-u,_hs_xchg16" + , "-Wl,-u,_hs_xchg32" + , "-Wl,-u,_hs_xchg64" , "-Wl,-u,_hs_atomicread8" , "-Wl,-u,_hs_atomicread16" , "-Wl,-u,_hs_atomicread32" @@ -274,7 +277,10 @@ ld-options: #if WORD_SIZE_IN_BITS == 64 , "-Wl,-u,hs_cmpxchg64" #endif - , "-Wl,-u,hs_xchg" + , "-Wl,-u,hs_xchg8" + , "-Wl,-u,hs_xchg16" + , "-Wl,-u,hs_xchg32" + , "-Wl,-u,hs_xchg64" , "-Wl,-u,hs_atomicread8" , "-Wl,-u,hs_atomicread16" , "-Wl,-u,hs_atomicread32" ===================================== rts/rts.cabal.in ===================================== @@ -264,7 +264,10 @@ library "-Wl,-u,_hs_cmpxchg8" "-Wl,-u,_hs_cmpxchg16" "-Wl,-u,_hs_cmpxchg32" - "-Wl,-u,_hs_xchg" + "-Wl,-u,_hs_xchg8" + "-Wl,-u,_hs_xchg16" + "-Wl,-u,_hs_xchg32" + "-Wl,-u,_hs_xchg64" "-Wl,-u,_hs_atomicread8" "-Wl,-u,_hs_atomicread16" "-Wl,-u,_hs_atomicread32" @@ -340,7 +343,10 @@ library "-Wl,-u,hs_cmpxchg8" "-Wl,-u,hs_cmpxchg16" "-Wl,-u,hs_cmpxchg32" - "-Wl,-u,hs_xchg" + "-Wl,-u,hs_xchg8" + "-Wl,-u,hs_xchg16" + "-Wl,-u,hs_xchg32" + "-Wl,-u,hs_xchg64" "-Wl,-u,hs_atomicread8" "-Wl,-u,hs_atomicread16" "-Wl,-u,hs_atomicread32" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e10695837a82c1cf2fbd04773cbdae8b49a0ba58 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e10695837a82c1cf2fbd04773cbdae8b49a0ba58 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 19 13:20:47 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Tue, 19 May 2020 09:20:47 -0400 Subject: [Git][ghc/ghc][wip/andreask/xchg_primop] Make exchange a sized operation as it should be. Message-ID: <5ec3dd2f3b201_6e26b5ea8d43754d@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/xchg_primop at Glasgow Haskell Compiler / GHC Commits: e0df3d73 by Andreas Klebinger at 2020-05-19T15:17:58+02:00 Make exchange a sized operation as it should be. - - - - - 18 changed files: - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm/CPrim.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.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/CodeGen.hs - compiler/GHC/StgToCmm/Prim.hs - − compiler/codeGen/StgCmmPrim.hs - configure.ac - includes/stg/Prim.h - libraries/ghc-prim/cbits/atomic.c - rts/package.conf.in - rts/rts.cabal.in Changes: ===================================== compiler/GHC/Builtin/primops.txt.pp ===================================== @@ -2474,9 +2474,9 @@ primop WriteOffAddrOp_Word64 "writeWord64OffAddr#" GenPrimOp can_fail = True primop InterlockedExchangeAddr "interlockedExchangeAddr#" GenPrimOp - Addr# -> Addr# -> Addr# - {The atomic exchange operation. Atomically exchanges a pair of addresses and - returns the old value.} + Addr# -> Int# -> Addr# + {The atomic exchange operation. Atomically exchanges the value at the first address + with the Addr# given as second argument. Implies a read barrier.} with has_side_effects = True ------------------------------------------------------------------------ ===================================== compiler/GHC/Cmm/MachOp.hs ===================================== @@ -632,7 +632,9 @@ data CallishMachOp | MO_AtomicRead Width | MO_AtomicWrite Width | MO_Cmpxchg Width - | MO_Xchg + -- Should be an AtomicRMW variant eventually. + -- Has at least aquire semantics. + | MO_Xchg Width deriving (Eq, Show) -- | The operation to perform atomically. ===================================== compiler/GHC/Cmm/Parser.y ===================================== @@ -1022,7 +1022,12 @@ callishMachOps = listToUFM $ ( "cmpxchg8", (MO_Cmpxchg W8,)), ( "cmpxchg16", (MO_Cmpxchg W16,)), ( "cmpxchg32", (MO_Cmpxchg W32,)), - ( "cmpxchg64", (MO_Cmpxchg W64,)) + ( "cmpxchg64", (MO_Cmpxchg W64,)), + + ( "xchg8", (MO_Xchg W8,)), + ( "xchg16", (MO_Xchg W16,)), + ( "xchg32", (MO_Xchg W32,)), + ( "xchg64", (MO_Xchg W64,)) -- ToDo: the rest, maybe -- edit: which rest? ===================================== compiler/GHC/CmmToAsm/CPrim.hs ===================================== @@ -106,8 +106,14 @@ atomicRMWLabel w amop = "hs_atomic_" ++ pprFunName amop ++ pprWidth w pprFunName AMO_Or = "or" pprFunName AMO_Xor = "xor" -xchgLabel :: String -xchgLabel = "hs_xchg" +xchgLabel :: Width -> String +xchgLabel w = "hs_xchg" ++ pprWidth w + where + pprWidth W8 = "8" + pprWidth W16 = "16" + pprWidth W32 = "32" + pprWidth W64 = "64" + pprWidth w = pprPanic "xchgLabel: Unsupported word width " (ppr w) cmpxchgLabel :: Width -> String cmpxchgLabel w = "hs_cmpxchg" ++ pprWidth w ===================================== compiler/GHC/CmmToAsm/PPC/CodeGen.hs ===================================== @@ -2024,7 +2024,7 @@ genCCall' config gcp target dest_regs args MO_Ctz _ -> unsupported MO_AtomicRMW {} -> unsupported MO_Cmpxchg w -> (fsLit $ cmpxchgLabel w, False) - MO_Xchg -> (fsLit $ xchgLabel, False) + MO_Xchg w -> (fsLit $ xchgLabel w, False) MO_AtomicRead _ -> unsupported MO_AtomicWrite _ -> unsupported ===================================== compiler/GHC/CmmToAsm/SPARC/CodeGen.hs ===================================== @@ -677,7 +677,7 @@ outOfLineMachOp_table mop MO_Ctz w -> fsLit $ ctzLabel w MO_AtomicRMW w amop -> fsLit $ atomicRMWLabel w amop MO_Cmpxchg w -> fsLit $ cmpxchgLabel w - MO_Xchg -> fsLit xchgLabel + MO_Xchg w -> fsLit $ xchgLabel w MO_AtomicRead w -> fsLit $ atomicReadLabel w MO_AtomicWrite w -> fsLit $ atomicWriteLabel w ===================================== compiler/GHC/CmmToAsm/X86/CodeGen.hs ===================================== @@ -2518,10 +2518,11 @@ genCCall' _ is32Bit (PrimTarget (MO_Cmpxchg width)) [dst] [addr, old, new] _ = d where format = intFormat width -genCCall' config is32Bit (PrimTarget MO_Xchg) [dst] [addr, value] _ = do +genCCall' config is32Bit (PrimTarget (MO_Xchg width)) [dst] [addr, value] _ = do let dst_r = getRegisterReg platform (CmmLocal dst) Amode amode addr_code <- getSimpleAmode is32Bit addr (newval, newval_code) <- getSomeReg value + -- Copy the value into the target register, perform the exchange. let code = toOL [ MOV format (OpReg newval) (OpReg dst_r) , XCHG format (OpAddr amode) dst_r @@ -2529,8 +2530,6 @@ genCCall' config is32Bit (PrimTarget MO_Xchg) [dst] [addr, value] _ = do return $ addr_code `appOL` newval_code `appOL` code where format = intFormat width - width | is32Bit = W32 - | otherwise = W64 platform = ncgPlatform config genCCall' _ is32Bit target dest_regs args bid = do @@ -3228,7 +3227,7 @@ outOfLineCmmOp bid mop res args MO_AtomicRead _ -> fsLit "atomicread" MO_AtomicWrite _ -> fsLit "atomicwrite" MO_Cmpxchg _ -> fsLit "cmpxchg" - MO_Xchg -> fsLit "xchg" + MO_Xchg _ -> should_be_inline MO_UF_Conv _ -> unsupported @@ -3248,6 +3247,11 @@ outOfLineCmmOp bid mop res args (MO_Prefetch_Data _ ) -> unsupported unsupported = panic ("outOfLineCmmOp: " ++ show mop ++ " not supported here") + -- If we generate a call for the given primop + -- something went wrong. + should_be_inline = panic ("outOfLineCmmOp: " ++ show mop + ++ " should be handled inline") + -- ----------------------------------------------------------------------------- -- Generating a table-branch ===================================== compiler/GHC/CmmToAsm/X86/Instr.hs ===================================== @@ -462,6 +462,7 @@ x86_regUsageOfInstr platform instr usageMM :: Operand -> Operand -> RegUsage usageMM (OpReg src) (OpReg dst) = mkRU [src, dst] [src, dst] usageMM (OpReg src) (OpAddr ea) = mkRU (use_EA ea [src]) [src] + usageMM (OpAddr ea) (OpReg dst) = mkRU (use_EA ea [dst]) [dst] usageMM _ _ = panic "X86.RegInfo.usageMM: no match" -- 3 operand form; first operand Read; second Modified; third Modified ===================================== compiler/GHC/CmmToAsm/X86/Ppr.hs ===================================== @@ -824,7 +824,7 @@ pprInstr platform i = case i of SETCC cond op -> pprCondInstr (sLit "set") cond (pprOperand platform II8 op) - (XCHG format src val) + XCHG format src val -> pprFormatOpReg (sLit "xchg") format src val JXX cond blockid ===================================== compiler/GHC/CmmToC.hs ===================================== @@ -831,7 +831,7 @@ pprCallishMachOp_for_C mop (MO_Ctz w) -> ptext (sLit $ ctzLabel w) (MO_AtomicRMW w amop) -> ptext (sLit $ atomicRMWLabel w amop) (MO_Cmpxchg w) -> ptext (sLit $ cmpxchgLabel w) - MO_Xchg -> ptext (sLit $ xchgLabel) + (MO_Xchg w) -> ptext (sLit $ xchgLabel w) (MO_AtomicRead w) -> ptext (sLit $ atomicReadLabel w) (MO_AtomicWrite w) -> ptext (sLit $ atomicWriteLabel w) (MO_UF_Conv w) -> ptext (sLit $ word2FloatLabel w) ===================================== compiler/GHC/CmmToLlvm/CodeGen.hs ===================================== @@ -281,7 +281,7 @@ genCall (PrimTarget (MO_Cmpxchg _width)) retVar' <- doExprW targetTy $ ExtractV retVar 0 statement $ Store retVar' dstVar -genCall (PrimTarget MO_Xchg) [] [addr, val] = runStmtsDecls $ do +genCall (PrimTarget (MO_Xchg _width)) [] [addr, val] = runStmtsDecls $ do addrVar <- exprToVarW addr valVar <- exprToVarW val let ptrTy = pLift $ getVarType valVar @@ -864,7 +864,7 @@ cmmPrimOpFunctions mop = do MO_AtomicRMW _ _ -> unsupported MO_AtomicWrite _ -> unsupported MO_Cmpxchg _ -> unsupported - MO_Xchg -> unsupported + MO_Xchg _ -> unsupported -- | Tail function calls genJump :: CmmExpr -> [GlobalReg] -> LlvmM StmtData ===================================== compiler/GHC/StgToCmm/Prim.hs ===================================== @@ -856,6 +856,10 @@ emitPrimOp dflags = \case Word2DoubleOp -> \[w] -> opAllDone $ \[res] -> do emitPrimCall [res] (MO_UF_Conv W64) [w] +-- Atomic operations + InterlockedExchangeAddr -> \[src, value] -> opAllDone $ \[res] -> + emitPrimCall [res] (MO_Xchg (wordWidth platform)) [src, value] + -- SIMD primops (VecBroadcastOp vcat n w) -> \[e] -> opAllDone $ \[res] -> do checkVecCompatibility dflags vcat n w ===================================== compiler/codeGen/StgCmmPrim.hs deleted ===================================== The diff for this file was not included because it is too large. ===================================== configure.ac ===================================== @@ -730,6 +730,8 @@ dnl unregisterised, Sparc, and PPC backends. FP_GCC_SUPPORTS__ATOMICS if test $CONF_GCC_SUPPORTS__ATOMICS = YES ; then AC_DEFINE([HAVE_C11_ATOMICS], [1], [Does GCC support __atomic primitives?]) +else + AC_MSG_ERROR([C compiler needs to support __atomic primitives.]) fi FP_GCC_EXTRA_FLAGS ===================================== includes/stg/Prim.h ===================================== @@ -50,7 +50,10 @@ void hs_atomicwrite8(StgWord x, StgWord val); void hs_atomicwrite16(StgWord x, StgWord val); void hs_atomicwrite32(StgWord x, StgWord val); void hs_atomicwrite64(StgWord x, StgWord64 val); -StgWord hs_xchg(StgPtr x, StgWord val); +StgWord hs_xchg8(StgPtr x, StgWord val); +StgWord hs_xchg16(StgPtr x, StgWord val); +StgWord hs_xchg32(StgPtr x, StgWord val); +StgWord hs_xchg64(StgPtr x, StgWord val); /* libraries/ghc-prim/cbits/bswap.c */ StgWord16 hs_bswap16(StgWord16 x); ===================================== libraries/ghc-prim/cbits/atomic.c ===================================== @@ -10,6 +10,8 @@ // according to the ABI and is not what GHC does when it generates // calls to these functions. +//TODO: We now require gcc-5, so we should use __atomic__op variants. + // FetchAddByteArrayOp_Int extern StgWord hs_atomic_add8(StgWord x, StgWord val); @@ -320,11 +322,33 @@ hs_cmpxchg64(StgWord x, StgWord64 old, StgWord64 new) // Atomic exchange operations -extern StgWord hs_xchg(StgPtr x, StgWord val); +extern StgWord hs_xchg8(StgPtr x, StgWord val); +StgWord +hs_xchg8(StgPtr x, StgWord val) +{ + return (StgWord) __atomic_exchange_1((volatile StgPtr) x, val, __ATOMIC_ACQUIRE); +} + +extern StgWord hs_xchg16(StgPtr x, StgWord val); +StgWord +hs_xchg16(StgPtr x, StgWord val) +{ + return (StgWord) __atomic_exchange_2(x, val, __ATOMIC_ACQUIRE); +} + +extern StgWord hs_xchg32(StgPtr x, StgWord val); +StgWord +hs_xchg32(StgPtr x, StgWord val) +{ + return (StgWord) __atomic_exchange_4((volatile StgPtr) x, val, __ATOMIC_ACQUIRE); +} + +//GCC provides this even on 32bit. +extern StgWord hs_xchg64(StgPtr x, StgWord val); StgWord -hs_xchg(StgPtr x, StgWord val) +hs_xchg64(StgPtr x, StgWord val) { - return __sync_lock_test_and_set((volatile StgPtr) x, val); + return (StgWord) __atomic_exchange_8((volatile StgPtr) x, val, __ATOMIC_ACQUIRE); } // AtomicReadByteArrayOp_Int ===================================== rts/package.conf.in ===================================== @@ -168,7 +168,10 @@ ld-options: #if WORD_SIZE_IN_BITS == 64 , "-Wl,-u,_hs_cmpxchg64" #endif - , "-Wl,-u,_hs_xchg" + , "-Wl,-u,_hs_xchg8" + , "-Wl,-u,_hs_xchg16" + , "-Wl,-u,_hs_xchg32" + , "-Wl,-u,_hs_xchg64" , "-Wl,-u,_hs_atomicread8" , "-Wl,-u,_hs_atomicread16" , "-Wl,-u,_hs_atomicread32" @@ -274,7 +277,10 @@ ld-options: #if WORD_SIZE_IN_BITS == 64 , "-Wl,-u,hs_cmpxchg64" #endif - , "-Wl,-u,hs_xchg" + , "-Wl,-u,hs_xchg8" + , "-Wl,-u,hs_xchg16" + , "-Wl,-u,hs_xchg32" + , "-Wl,-u,hs_xchg64" , "-Wl,-u,hs_atomicread8" , "-Wl,-u,hs_atomicread16" , "-Wl,-u,hs_atomicread32" ===================================== rts/rts.cabal.in ===================================== @@ -264,7 +264,10 @@ library "-Wl,-u,_hs_cmpxchg8" "-Wl,-u,_hs_cmpxchg16" "-Wl,-u,_hs_cmpxchg32" - "-Wl,-u,_hs_xchg" + "-Wl,-u,_hs_xchg8" + "-Wl,-u,_hs_xchg16" + "-Wl,-u,_hs_xchg32" + "-Wl,-u,_hs_xchg64" "-Wl,-u,_hs_atomicread8" "-Wl,-u,_hs_atomicread16" "-Wl,-u,_hs_atomicread32" @@ -340,7 +343,10 @@ library "-Wl,-u,hs_cmpxchg8" "-Wl,-u,hs_cmpxchg16" "-Wl,-u,hs_cmpxchg32" - "-Wl,-u,hs_xchg" + "-Wl,-u,hs_xchg8" + "-Wl,-u,hs_xchg16" + "-Wl,-u,hs_xchg32" + "-Wl,-u,hs_xchg64" "-Wl,-u,hs_atomicread8" "-Wl,-u,hs_atomicread16" "-Wl,-u,hs_atomicread32" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e0df3d73f5c39b7cf4868c6493f6eec3d22b0ff5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e0df3d73f5c39b7cf4868c6493f6eec3d22b0ff5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 19 13:37:03 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Tue, 19 May 2020 09:37:03 -0400 Subject: [Git][ghc/ghc][wip/andreask/xchg_primop] 2 commits: Make exchange a sized operation as it should be. Message-ID: <5ec3e0ffb88c4_6e261207f9743795c@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/xchg_primop at Glasgow Haskell Compiler / GHC Commits: 23d9413e by Andreas Klebinger at 2020-05-19T15:18:37+02:00 Make exchange a sized operation as it should be. - - - - - 440eb15b by Andreas Klebinger at 2020-05-19T15:36:01+02:00 Make 64bit version a error on 32bit platforms. Add Exchange on Int#. - - - - - 18 changed files: - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm/CPrim.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.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/CodeGen.hs - compiler/GHC/StgToCmm/Prim.hs - − compiler/codeGen/StgCmmPrim.hs - configure.ac - includes/stg/Prim.h - libraries/ghc-prim/cbits/atomic.c - rts/package.conf.in - rts/rts.cabal.in Changes: ===================================== compiler/GHC/Builtin/primops.txt.pp ===================================== @@ -2475,8 +2475,14 @@ primop WriteOffAddrOp_Word64 "writeWord64OffAddr#" GenPrimOp primop InterlockedExchangeAddr "interlockedExchangeAddr#" GenPrimOp Addr# -> Addr# -> Addr# - {The atomic exchange operation. Atomically exchanges a pair of addresses and - returns the old value.} + {The atomic exchange operation. Atomically exchanges the value at the first address + with the Addr# given as second argument. Implies a read barrier.} + with has_side_effects = True + +primop InterlockedExchangeInt "interlockedExchangeInt#" GenPrimOp + Addr# -> Int# -> Int# + {The atomic exchange operation. Atomically exchanges the value at the address + with the given value. Returns the old value. Implies a read barrier.} with has_side_effects = True ------------------------------------------------------------------------ ===================================== compiler/GHC/Cmm/MachOp.hs ===================================== @@ -632,7 +632,9 @@ data CallishMachOp | MO_AtomicRead Width | MO_AtomicWrite Width | MO_Cmpxchg Width - | MO_Xchg + -- Should be an AtomicRMW variant eventually. + -- Has at least aquire semantics. + | MO_Xchg Width deriving (Eq, Show) -- | The operation to perform atomically. ===================================== compiler/GHC/Cmm/Parser.y ===================================== @@ -1022,7 +1022,12 @@ callishMachOps = listToUFM $ ( "cmpxchg8", (MO_Cmpxchg W8,)), ( "cmpxchg16", (MO_Cmpxchg W16,)), ( "cmpxchg32", (MO_Cmpxchg W32,)), - ( "cmpxchg64", (MO_Cmpxchg W64,)) + ( "cmpxchg64", (MO_Cmpxchg W64,)), + + ( "xchg8", (MO_Xchg W8,)), + ( "xchg16", (MO_Xchg W16,)), + ( "xchg32", (MO_Xchg W32,)), + ( "xchg64", (MO_Xchg W64,)) -- ToDo: the rest, maybe -- edit: which rest? ===================================== compiler/GHC/CmmToAsm/CPrim.hs ===================================== @@ -106,8 +106,14 @@ atomicRMWLabel w amop = "hs_atomic_" ++ pprFunName amop ++ pprWidth w pprFunName AMO_Or = "or" pprFunName AMO_Xor = "xor" -xchgLabel :: String -xchgLabel = "hs_xchg" +xchgLabel :: Width -> String +xchgLabel w = "hs_xchg" ++ pprWidth w + where + pprWidth W8 = "8" + pprWidth W16 = "16" + pprWidth W32 = "32" + pprWidth W64 = "64" + pprWidth w = pprPanic "xchgLabel: Unsupported word width " (ppr w) cmpxchgLabel :: Width -> String cmpxchgLabel w = "hs_cmpxchg" ++ pprWidth w ===================================== compiler/GHC/CmmToAsm/PPC/CodeGen.hs ===================================== @@ -2024,7 +2024,7 @@ genCCall' config gcp target dest_regs args MO_Ctz _ -> unsupported MO_AtomicRMW {} -> unsupported MO_Cmpxchg w -> (fsLit $ cmpxchgLabel w, False) - MO_Xchg -> (fsLit $ xchgLabel, False) + MO_Xchg w -> (fsLit $ xchgLabel w, False) MO_AtomicRead _ -> unsupported MO_AtomicWrite _ -> unsupported ===================================== compiler/GHC/CmmToAsm/SPARC/CodeGen.hs ===================================== @@ -677,7 +677,7 @@ outOfLineMachOp_table mop MO_Ctz w -> fsLit $ ctzLabel w MO_AtomicRMW w amop -> fsLit $ atomicRMWLabel w amop MO_Cmpxchg w -> fsLit $ cmpxchgLabel w - MO_Xchg -> fsLit xchgLabel + MO_Xchg w -> fsLit $ xchgLabel w MO_AtomicRead w -> fsLit $ atomicReadLabel w MO_AtomicWrite w -> fsLit $ atomicWriteLabel w ===================================== compiler/GHC/CmmToAsm/X86/CodeGen.hs ===================================== @@ -2518,10 +2518,13 @@ genCCall' _ is32Bit (PrimTarget (MO_Cmpxchg width)) [dst] [addr, old, new] _ = d where format = intFormat width -genCCall' config is32Bit (PrimTarget MO_Xchg) [dst] [addr, value] _ = do +genCCall' config is32Bit (PrimTarget (MO_Xchg width)) [dst] [addr, value] _ + | (is32Bit && width == W64) = panic "gencCall: 64bit atomic exchange not supported on 32bit platforms" + | otherwise = do let dst_r = getRegisterReg platform (CmmLocal dst) Amode amode addr_code <- getSimpleAmode is32Bit addr (newval, newval_code) <- getSomeReg value + -- Copy the value into the target register, perform the exchange. let code = toOL [ MOV format (OpReg newval) (OpReg dst_r) , XCHG format (OpAddr amode) dst_r @@ -2529,8 +2532,6 @@ genCCall' config is32Bit (PrimTarget MO_Xchg) [dst] [addr, value] _ = do return $ addr_code `appOL` newval_code `appOL` code where format = intFormat width - width | is32Bit = W32 - | otherwise = W64 platform = ncgPlatform config genCCall' _ is32Bit target dest_regs args bid = do @@ -3228,7 +3229,7 @@ outOfLineCmmOp bid mop res args MO_AtomicRead _ -> fsLit "atomicread" MO_AtomicWrite _ -> fsLit "atomicwrite" MO_Cmpxchg _ -> fsLit "cmpxchg" - MO_Xchg -> fsLit "xchg" + MO_Xchg _ -> should_be_inline MO_UF_Conv _ -> unsupported @@ -3248,6 +3249,11 @@ outOfLineCmmOp bid mop res args (MO_Prefetch_Data _ ) -> unsupported unsupported = panic ("outOfLineCmmOp: " ++ show mop ++ " not supported here") + -- If we generate a call for the given primop + -- something went wrong. + should_be_inline = panic ("outOfLineCmmOp: " ++ show mop + ++ " should be handled inline") + -- ----------------------------------------------------------------------------- -- Generating a table-branch ===================================== compiler/GHC/CmmToAsm/X86/Instr.hs ===================================== @@ -462,6 +462,7 @@ x86_regUsageOfInstr platform instr usageMM :: Operand -> Operand -> RegUsage usageMM (OpReg src) (OpReg dst) = mkRU [src, dst] [src, dst] usageMM (OpReg src) (OpAddr ea) = mkRU (use_EA ea [src]) [src] + usageMM (OpAddr ea) (OpReg dst) = mkRU (use_EA ea [dst]) [dst] usageMM _ _ = panic "X86.RegInfo.usageMM: no match" -- 3 operand form; first operand Read; second Modified; third Modified ===================================== compiler/GHC/CmmToAsm/X86/Ppr.hs ===================================== @@ -824,7 +824,7 @@ pprInstr platform i = case i of SETCC cond op -> pprCondInstr (sLit "set") cond (pprOperand platform II8 op) - (XCHG format src val) + XCHG format src val -> pprFormatOpReg (sLit "xchg") format src val JXX cond blockid ===================================== compiler/GHC/CmmToC.hs ===================================== @@ -831,7 +831,7 @@ pprCallishMachOp_for_C mop (MO_Ctz w) -> ptext (sLit $ ctzLabel w) (MO_AtomicRMW w amop) -> ptext (sLit $ atomicRMWLabel w amop) (MO_Cmpxchg w) -> ptext (sLit $ cmpxchgLabel w) - MO_Xchg -> ptext (sLit $ xchgLabel) + (MO_Xchg w) -> ptext (sLit $ xchgLabel w) (MO_AtomicRead w) -> ptext (sLit $ atomicReadLabel w) (MO_AtomicWrite w) -> ptext (sLit $ atomicWriteLabel w) (MO_UF_Conv w) -> ptext (sLit $ word2FloatLabel w) ===================================== compiler/GHC/CmmToLlvm/CodeGen.hs ===================================== @@ -281,7 +281,7 @@ genCall (PrimTarget (MO_Cmpxchg _width)) retVar' <- doExprW targetTy $ ExtractV retVar 0 statement $ Store retVar' dstVar -genCall (PrimTarget MO_Xchg) [] [addr, val] = runStmtsDecls $ do +genCall (PrimTarget (MO_Xchg _width)) [] [addr, val] = runStmtsDecls $ do addrVar <- exprToVarW addr valVar <- exprToVarW val let ptrTy = pLift $ getVarType valVar @@ -864,7 +864,7 @@ cmmPrimOpFunctions mop = do MO_AtomicRMW _ _ -> unsupported MO_AtomicWrite _ -> unsupported MO_Cmpxchg _ -> unsupported - MO_Xchg -> unsupported + MO_Xchg _ -> unsupported -- | Tail function calls genJump :: CmmExpr -> [GlobalReg] -> LlvmM StmtData ===================================== compiler/GHC/StgToCmm/Prim.hs ===================================== @@ -856,6 +856,12 @@ emitPrimOp dflags = \case Word2DoubleOp -> \[w] -> opAllDone $ \[res] -> do emitPrimCall [res] (MO_UF_Conv W64) [w] +-- Atomic operations + InterlockedExchangeAddr -> \[src, value] -> opAllDone $ \[res] -> + emitPrimCall [res] (MO_Xchg (wordWidth platform)) [src, value] + InterlockedExchangeInt -> \[src, value] -> opAllDone $ \[res] -> + emitPrimCall [res] (MO_Xchg (wordWidth platform)) [src, value] + -- SIMD primops (VecBroadcastOp vcat n w) -> \[e] -> opAllDone $ \[res] -> do checkVecCompatibility dflags vcat n w ===================================== compiler/codeGen/StgCmmPrim.hs deleted ===================================== The diff for this file was not included because it is too large. ===================================== configure.ac ===================================== @@ -730,6 +730,8 @@ dnl unregisterised, Sparc, and PPC backends. FP_GCC_SUPPORTS__ATOMICS if test $CONF_GCC_SUPPORTS__ATOMICS = YES ; then AC_DEFINE([HAVE_C11_ATOMICS], [1], [Does GCC support __atomic primitives?]) +else + AC_MSG_ERROR([C compiler needs to support __atomic primitives.]) fi FP_GCC_EXTRA_FLAGS ===================================== includes/stg/Prim.h ===================================== @@ -50,7 +50,10 @@ void hs_atomicwrite8(StgWord x, StgWord val); void hs_atomicwrite16(StgWord x, StgWord val); void hs_atomicwrite32(StgWord x, StgWord val); void hs_atomicwrite64(StgWord x, StgWord64 val); -StgWord hs_xchg(StgPtr x, StgWord val); +StgWord hs_xchg8(StgPtr x, StgWord val); +StgWord hs_xchg16(StgPtr x, StgWord val); +StgWord hs_xchg32(StgPtr x, StgWord val); +StgWord hs_xchg64(StgPtr x, StgWord val); /* libraries/ghc-prim/cbits/bswap.c */ StgWord16 hs_bswap16(StgWord16 x); ===================================== libraries/ghc-prim/cbits/atomic.c ===================================== @@ -10,6 +10,8 @@ // according to the ABI and is not what GHC does when it generates // calls to these functions. +//TODO: We now require gcc-5, so we should use __atomic__op variants. + // FetchAddByteArrayOp_Int extern StgWord hs_atomic_add8(StgWord x, StgWord val); @@ -320,13 +322,37 @@ hs_cmpxchg64(StgWord x, StgWord64 old, StgWord64 new) // Atomic exchange operations -extern StgWord hs_xchg(StgPtr x, StgWord val); +extern StgWord hs_xchg8(StgPtr x, StgWord val); +StgWord +hs_xchg8(StgPtr x, StgWord val) +{ + return (StgWord) __atomic_exchange_1((volatile StgPtr) x, val, __ATOMIC_ACQUIRE); +} + +extern StgWord hs_xchg16(StgPtr x, StgWord val); StgWord -hs_xchg(StgPtr x, StgWord val) +hs_xchg16(StgPtr x, StgWord val) { - return __sync_lock_test_and_set((volatile StgPtr) x, val); + return (StgWord) __atomic_exchange_2(x, val, __ATOMIC_ACQUIRE); } +extern StgWord hs_xchg32(StgPtr x, StgWord val); +StgWord +hs_xchg32(StgPtr x, StgWord val) +{ + return (StgWord) __atomic_exchange_4((volatile StgPtr) x, val, __ATOMIC_ACQUIRE); +} + +#if WORD_SIZE_IN_BITS == 64 +//GCC provides this even on 32bit, but StgWord is still 32 bits. +extern StgWord hs_xchg64(StgPtr x, StgWord val); +StgWord +hs_xchg64(StgPtr x, StgWord val) +{ + return (StgWord) __atomic_exchange_8((volatile StgPtr) x, val, __ATOMIC_ACQUIRE); +} +#endif + // AtomicReadByteArrayOp_Int // Implies a full memory barrier (see compiler/GHC/Builtin/primops.txt.pp) // __ATOMIC_SEQ_CST: Full barrier in both directions (hoisting and sinking ===================================== rts/package.conf.in ===================================== @@ -168,7 +168,10 @@ ld-options: #if WORD_SIZE_IN_BITS == 64 , "-Wl,-u,_hs_cmpxchg64" #endif - , "-Wl,-u,_hs_xchg" + , "-Wl,-u,_hs_xchg8" + , "-Wl,-u,_hs_xchg16" + , "-Wl,-u,_hs_xchg32" + , "-Wl,-u,_hs_xchg64" , "-Wl,-u,_hs_atomicread8" , "-Wl,-u,_hs_atomicread16" , "-Wl,-u,_hs_atomicread32" @@ -274,7 +277,10 @@ ld-options: #if WORD_SIZE_IN_BITS == 64 , "-Wl,-u,hs_cmpxchg64" #endif - , "-Wl,-u,hs_xchg" + , "-Wl,-u,hs_xchg8" + , "-Wl,-u,hs_xchg16" + , "-Wl,-u,hs_xchg32" + , "-Wl,-u,hs_xchg64" , "-Wl,-u,hs_atomicread8" , "-Wl,-u,hs_atomicread16" , "-Wl,-u,hs_atomicread32" ===================================== rts/rts.cabal.in ===================================== @@ -264,7 +264,10 @@ library "-Wl,-u,_hs_cmpxchg8" "-Wl,-u,_hs_cmpxchg16" "-Wl,-u,_hs_cmpxchg32" - "-Wl,-u,_hs_xchg" + "-Wl,-u,_hs_xchg8" + "-Wl,-u,_hs_xchg16" + "-Wl,-u,_hs_xchg32" + "-Wl,-u,_hs_xchg64" "-Wl,-u,_hs_atomicread8" "-Wl,-u,_hs_atomicread16" "-Wl,-u,_hs_atomicread32" @@ -340,7 +343,10 @@ library "-Wl,-u,hs_cmpxchg8" "-Wl,-u,hs_cmpxchg16" "-Wl,-u,hs_cmpxchg32" - "-Wl,-u,hs_xchg" + "-Wl,-u,hs_xchg8" + "-Wl,-u,hs_xchg16" + "-Wl,-u,hs_xchg32" + "-Wl,-u,hs_xchg64" "-Wl,-u,hs_atomicread8" "-Wl,-u,hs_atomicread16" "-Wl,-u,hs_atomicread32" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e0df3d73f5c39b7cf4868c6493f6eec3d22b0ff5...440eb15b2fca58366a0a1df425f7fb4dfc27b36a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e0df3d73f5c39b7cf4868c6493f6eec3d22b0ff5...440eb15b2fca58366a0a1df425f7fb4dfc27b36a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 19 13:45:27 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Tue, 19 May 2020 09:45:27 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/more-barriers Message-ID: <5ec3e2f79f13_6e2612bfc3ec409b@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/more-barriers at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/more-barriers You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 19 13:58:11 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Tue, 19 May 2020 09:58:11 -0400 Subject: [Git][ghc/ghc][wip/more-barriers] Correct closure observation, construction, and mutation on weak memory machines. Message-ID: <5ec3e5f339512_6e263f9ee2d72ed44438f@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/more-barriers at Glasgow Haskell Compiler / GHC Commits: 62e19a6d by Travis Whitaker at 2020-05-19T09:55:49-04:00 Correct closure observation, construction, and mutation on weak memory machines. Here the following changes are introduced: - A read barrier machine op is added to Cmm. - The order in which a closure's fields are read and written is changed. - Memory barriers are added to RTS code to ensure correctness on out-or-order machines with weak memory ordering. Cmm has a new CallishMachOp called MO_ReadBarrier. On weak memory machines, this is lowered to an instruction that ensures memory reads that occur after said instruction in program order are not performed before reads coming before said instruction in program order. On machines with strong memory ordering properties (e.g. X86, SPARC in TSO mode) no such instruction is necessary, so MO_ReadBarrier is simply erased. However, such an instruction is necessary on weakly ordered machines, e.g. ARM and PowerPC. Weam memory ordering has consequences for how closures are observed and mutated. For example, consider a closure that needs to be updated to an indirection. In order for the indirection to be safe for concurrent observers to enter, said observers must read the indirection's info table before they read the indirectee. Furthermore, the entering observer makes assumptions about the closure based on its info table contents, e.g. an INFO_TYPE of IND imples the closure has an indirectee pointer that is safe to follow. When a closure is updated with an indirection, both its info table and its indirectee must be written. With weak memory ordering, these two writes can be arbitrarily reordered, and perhaps even interleaved with other threads' reads and writes (in the absence of memory barrier instructions). Consider this example of a bad reordering: - An updater writes to a closure's info table (INFO_TYPE is now IND). - A concurrent observer branches upon reading the closure's INFO_TYPE as IND. - A concurrent observer reads the closure's indirectee and enters it. (!!!) - An updater writes the closure's indirectee. Here the update to the indirectee comes too late and the concurrent observer has jumped off into the abyss. Speculative execution can also cause us issues, consider: - An observer is about to case on a value in closure's info table. - The observer speculatively reads one or more of closure's fields. - An updater writes to closure's info table. - The observer takes a branch based on the new info table value, but with the old closure fields! - The updater writes to the closure's other fields, but its too late. Because of these effects, reads and writes to a closure's info table must be ordered carefully with respect to reads and writes to the closure's other fields, and memory barriers must be placed to ensure that reads and writes occur in program order. Specifically, updates to a closure must follow the following pattern: - Update the closure's (non-info table) fields. - Write barrier. - Update the closure's info table. Observing a closure's fields must follow the following pattern: - Read the closure's info pointer. - Read barrier. - Read the closure's (non-info table) fields. This patch updates RTS code to obey this pattern. This should fix long-standing SMP bugs on ARM (specifically newer aarch64 microarchitectures supporting out-of-order execution) and PowerPC. This fixesd issue #15449. - - - - - 17 changed files: - rts/Apply.cmm - rts/Compact.cmm - rts/Interpreter.c - rts/Messages.c - rts/PrimOps.cmm - rts/RaiseAsync.c - rts/RtsAPI.c - rts/StgMiscClosures.cmm - rts/ThreadPaused.c - rts/Threads.c - rts/Weak.c - rts/sm/CNF.c - rts/sm/Compact.c - rts/sm/Evac.c - rts/sm/GCAux.c - rts/sm/Scav.c - rts/sm/Storage.c Changes: ===================================== rts/Apply.cmm ===================================== @@ -66,6 +66,7 @@ again: // Note [Heap memory barriers] in SMP.h. untaggedfun = UNTAG(fun); info = %INFO_PTR(untaggedfun); + prim_read_barrier; switch [INVALID_OBJECT .. N_CLOSURE_TYPES] (TO_W_( %INFO_TYPE(%STD_INFO(info)) )) { case @@ -106,6 +107,7 @@ again: CCS_ALLOC(BYTES_TO_WDS(SIZEOF_StgPAP), CCS_OVERHEAD); P_ pap; pap = Hp - SIZEOF_StgPAP + WDS(1); + prim_write_barrier; SET_HDR(pap, stg_PAP_info, CCCS); StgPAP_arity(pap) = arity; if (arity <= TAG_MASK) { @@ -134,6 +136,7 @@ again: pap = Hp - size + WDS(1); // We'll lose the original PAP, so we should enter its CCS ccall enterFunCCS(BaseReg "ptr", StgHeader_ccs(untaggedfun) "ptr"); + prim_write_barrier; SET_HDR(pap, stg_PAP_info, CCCS); StgPAP_arity(pap) = StgPAP_arity(untaggedfun); StgPAP_n_args(pap) = StgPAP_n_args(untaggedfun); @@ -284,6 +287,7 @@ for: info = %GET_FUN_INFO(UNTAG(R1)); W_ type; type = TO_W_(StgFunInfoExtra_fun_type(info)); + prim_read_barrier; if (type == ARG_GEN) { jump StgFunInfoExtra_slow_apply(info) [R1]; } @@ -362,6 +366,7 @@ for: info = %GET_FUN_INFO(UNTAG(R1)); W_ type; type = TO_W_(StgFunInfoExtra_fun_type(info)); + prim_read_barrier; if (type == ARG_GEN) { jump StgFunInfoExtra_slow_apply(info) [R1]; } @@ -426,12 +431,14 @@ for: TICK_ENT_VIA_NODE(); #if defined(NO_ARG_REGS) + prim_read_barrier; jump %GET_ENTRY(UNTAG(R1)) [R1]; #else W_ info; info = %GET_FUN_INFO(UNTAG(R1)); W_ type; type = TO_W_(StgFunInfoExtra_fun_type(info)); + prim_read_barrier; if (type == ARG_GEN) { jump StgFunInfoExtra_slow_apply(info) [R1]; } ===================================== rts/Compact.cmm ===================================== @@ -72,6 +72,7 @@ eval: tag = GETTAG(p); p = UNTAG(p); info = %INFO_PTR(p); + prim_read_barrier; type = TO_W_(%INFO_TYPE(%STD_INFO(info))); switch [0 .. N_CLOSURE_TYPES] type { @@ -171,7 +172,6 @@ eval: cards = SIZEOF_StgMutArrPtrs + WDS(ptrs); ALLOCATE(compact, BYTES_TO_WDS(size), p, to, tag); P_[pp] = tag | to; - SET_HDR(to, StgHeader_info(p), StgHeader_ccs(p)); StgMutArrPtrs_ptrs(to) = ptrs; StgMutArrPtrs_size(to) = StgMutArrPtrs_size(p); prim %memcpy(to + cards, p + cards , size - cards, 1); @@ -185,6 +185,7 @@ eval: i = i + 1; goto loop0; } + SET_HDR(to, StgHeader_info(p), StgHeader_ccs(p)); return(); } @@ -201,7 +202,6 @@ eval: ptrs = StgSmallMutArrPtrs_ptrs(p); ALLOCATE(compact, BYTES_TO_WDS(SIZEOF_StgSmallMutArrPtrs) + ptrs, p, to, tag); P_[pp] = tag | to; - SET_HDR(to, StgHeader_info(p), StgHeader_ccs(p)); StgSmallMutArrPtrs_ptrs(to) = ptrs; i = 0; loop1: @@ -213,6 +213,7 @@ eval: i = i + 1; goto loop1; } + SET_HDR(to, StgHeader_info(p), StgHeader_ccs(p)); return(); } @@ -238,7 +239,6 @@ eval: ALLOCATE(compact, size, p, to, tag); P_[pp] = tag | to; - SET_HDR(to, StgHeader_info(p), StgHeader_ccs(p)); // First, copy the non-pointers if (nptrs > 0) { @@ -248,6 +248,7 @@ eval: i = i + 1; if (i < ptrs + nptrs) ( likely: True ) goto loop2; } + SET_HDR(to, StgHeader_info(p), StgHeader_ccs(p)); // Next, recursively compact and copy the pointers if (ptrs == 0) { return(); } ===================================== rts/Interpreter.c ===================================== @@ -249,6 +249,7 @@ StgClosure * newEmptyPAP (Capability *cap, uint32_t arity) { StgPAP *pap = (StgPAP *)allocate(cap, sizeofW(StgPAP)); + write_barrier(); SET_HDR(pap, &stg_PAP_info, cap->r.rCCCS); pap->arity = arity; pap->n_args = 0; @@ -273,7 +274,7 @@ StgClosure * copyPAP (Capability *cap, StgPAP *oldpap) for (i = 0; i < ((StgPAP *)pap)->n_args; i++) { pap->payload[i] = oldpap->payload[i]; } - // No write barrier is needed here as this is a new allocation + write_barrier(); SET_HDR(pap, &stg_PAP_info, cap->r.rCCCS); return (StgClosure *)pap; } @@ -482,8 +483,9 @@ eval_obj: { StgUpdateFrame *__frame; __frame = (StgUpdateFrame *)Sp; - SET_INFO((StgClosure *)__frame, (StgInfoTable *)&stg_upd_frame_info); __frame->updatee = (StgClosure *)(ap); + write_barrier(); + SET_INFO((StgClosure *)__frame, (StgInfoTable *)&stg_upd_frame_info); } ENTER_CCS_THUNK(cap,ap); @@ -809,7 +811,7 @@ do_apply: for (i = 0; i < m; i++) { new_pap->payload[pap->n_args + i] = (StgClosure *)SpW(i); } - // No write barrier is needed here as this is a new allocation + write_barrier(); SET_HDR(new_pap,&stg_PAP_info,cap->r.rCCCS); tagged_obj = (StgClosure *)new_pap; Sp_addW(m); @@ -852,7 +854,7 @@ do_apply: for (i = 0; i < m; i++) { pap->payload[i] = (StgClosure *)SpW(i); } - // No write barrier is needed here as this is a new allocation + write_barrier(); SET_HDR(pap, &stg_PAP_info,cap->r.rCCCS); tagged_obj = (StgClosure *)pap; Sp_addW(m); @@ -1097,7 +1099,7 @@ run_BCO: new_aps->payload[i] = (StgClosure *)SpW(i-2); } - // No write barrier is needed here as this is a new allocation + write_barrier(); SET_HDR(new_aps,&stg_AP_STACK_info,cap->r.rCCCS); // Arrange the stack to call the breakpoint IO action, and @@ -1424,41 +1426,37 @@ run_BCO: case bci_ALLOC_AP: { int n_payload = BCO_NEXT; - StgAP *ap = (StgAP*)allocate(cap, AP_sizeW(n_payload)); - SpW(-1) = (W_)ap; + StgAP* ap = (StgAP*)allocate(cap, AP_sizeW(n_payload)); ap->n_args = n_payload; ap->arity = 0; - // No write barrier is needed here as this is a new allocation - // visible only from our stack + write_barrier(); SET_HDR(ap, &stg_AP_info, cap->r.rCCCS) + SpW(-1) = (W_)ap; Sp_subW(1); goto nextInsn; } case bci_ALLOC_AP_NOUPD: { int n_payload = BCO_NEXT; - StgAP *ap = (StgAP*)allocate(cap, AP_sizeW(n_payload)); - SpW(-1) = (W_)ap; + StgAP* ap = (StgAP*)allocate(cap, AP_sizeW(n_payload)); ap->n_args = n_payload; ap->arity = 0; - // No write barrier is needed here as this is a new allocation - // visible only from our stack + write_barrier(); SET_HDR(ap, &stg_AP_NOUPD_info, cap->r.rCCCS) + SpW(-1) = (W_)ap; Sp_subW(1); goto nextInsn; } case bci_ALLOC_PAP: { - StgPAP* pap; int arity = BCO_NEXT; int n_payload = BCO_NEXT; - pap = (StgPAP*)allocate(cap, PAP_sizeW(n_payload)); - SpW(-1) = (W_)pap; + StgPAP* pap = (StgPAP*)allocate(cap, PAP_sizeW(n_payload)); pap->n_args = n_payload; pap->arity = arity; - // No write barrier is needed here as this is a new allocation - // visible only from our stack + write_barrier(); SET_HDR(pap, &stg_PAP_info, cap->r.rCCCS) + SpW(-1) = (W_)pap; Sp_subW(1); goto nextInsn; } @@ -1529,6 +1527,7 @@ run_BCO: int o_itbl = BCO_GET_LARGE_ARG; int n_words = BCO_NEXT; StgInfoTable* itbl = INFO_PTR_TO_STRUCT((StgInfoTable *)BCO_LIT(o_itbl)); + load_load_barrier(); int request = CONSTR_sizeW( itbl->layout.payload.ptrs, itbl->layout.payload.nptrs ); StgClosure* con = (StgClosure*)allocate_NONUPD(cap,request); @@ -1538,8 +1537,7 @@ run_BCO: } Sp_addW(n_words); Sp_subW(1); - // No write barrier is needed here as this is a new allocation - // visible only from our stack + write_barrier(); SET_HDR(con, (StgInfoTable*)BCO_LIT(o_itbl), cap->r.rCCCS); SpW(0) = (W_)con; IF_DEBUG(interpreter, ===================================== rts/Messages.c ===================================== @@ -28,6 +28,7 @@ void sendMessage(Capability *from_cap, Capability *to_cap, Message *msg) #if defined(DEBUG) { const StgInfoTable *i = msg->header.info; + load_load_barrier(); if (i != &stg_MSG_THROWTO_info && i != &stg_MSG_BLACKHOLE_info && i != &stg_MSG_TRY_WAKEUP_info && @@ -70,6 +71,7 @@ executeMessage (Capability *cap, Message *m) loop: write_barrier(); // allow m->header to be modified by another thread i = m->header.info; + load_load_barrier(); if (i == &stg_MSG_TRY_WAKEUP_info) { StgTSO *tso = ((MessageWakeup *)m)->tso; @@ -302,6 +304,7 @@ loop: recordClosureMutated(cap,(StgClosure*)msg); if (info == &stg_BLOCKING_QUEUE_CLEAN_info) { + write_barrier(); bq->header.info = &stg_BLOCKING_QUEUE_DIRTY_info; // No barrier is necessary here: we are only exposing the // closure to the GC. See Note [Heap memory barriers] in SMP.h. @@ -334,6 +337,7 @@ StgTSO * blackHoleOwner (StgClosure *bh) StgClosure *p; info = bh->header.info; + load_load_barrier(); if (info != &stg_BLACKHOLE_info && info != &stg_CAF_BLACKHOLE_info && @@ -349,6 +353,7 @@ loop: // and turns this into an infinite loop. p = UNTAG_CLOSURE((StgClosure*)VOLATILE_LOAD(&((StgInd*)bh)->indirectee)); info = p->header.info; + load_load_barrier(); if (info == &stg_IND_info) goto loop; ===================================== rts/PrimOps.cmm ===================================== @@ -68,8 +68,9 @@ stg_newByteArrayzh ( W_ n ) jump stg_raisezh(base_GHCziIOziException_heapOverflow_closure); } TICK_ALLOC_PRIM(SIZEOF_StgArrBytes,WDS(payload_words),0); - SET_HDR(p, stg_ARR_WORDS_info, CCCS); StgArrBytes_bytes(p) = n; + prim_write_barrier; + SET_HDR(p, stg_ARR_WORDS_info, CCCS); return (p); } @@ -98,9 +99,9 @@ stg_newPinnedByteArrayzh ( W_ n ) } TICK_ALLOC_PRIM(SIZEOF_StgArrBytes,WDS(payload_words),0); - /* No write barrier needed since this is a new allocation. */ - SET_HDR(p, stg_ARR_WORDS_info, CCCS); StgArrBytes_bytes(p) = n; + prim_write_barrier; + SET_HDR(p, stg_ARR_WORDS_info, CCCS); return (p); } @@ -133,9 +134,9 @@ stg_newAlignedPinnedByteArrayzh ( W_ n, W_ alignment ) } TICK_ALLOC_PRIM(SIZEOF_StgArrBytes,WDS(payload_words),0); - /* No write barrier needed since this is a new allocation. */ - SET_HDR(p, stg_ARR_WORDS_info, CCCS); StgArrBytes_bytes(p) = n; + prim_write_barrier; + SET_HDR(p, stg_ARR_WORDS_info, CCCS); return (p); } @@ -268,8 +269,6 @@ stg_newArrayzh ( W_ n /* words */, gcptr init ) } TICK_ALLOC_PRIM(SIZEOF_StgMutArrPtrs, WDS(size), 0); - /* No write barrier needed since this is a new allocation. */ - SET_HDR(arr, stg_MUT_ARR_PTRS_DIRTY_info, CCCS); StgMutArrPtrs_ptrs(arr) = n; StgMutArrPtrs_size(arr) = size; @@ -282,6 +281,9 @@ stg_newArrayzh ( W_ n /* words */, gcptr init ) goto for; } + prim_write_barrier; + SET_HDR(arr, stg_MUT_ARR_PTRS_DIRTY_info, CCCS); + return (arr); } @@ -293,11 +295,13 @@ stg_unsafeThawArrayzh ( gcptr arr ) // mut_list so no need to add it again. MUT_ARR_PTRS_FROZEN_CLEAN means it's // not and we should add it to a mut_list. if (StgHeader_info(arr) != stg_MUT_ARR_PTRS_FROZEN_DIRTY_info) { + prim_write_barrier; // see below: SET_INFO(arr,stg_MUT_ARR_PTRS_DIRTY_info); // must be done after SET_INFO, because it ASSERTs closure_MUTABLE(): recordMutable(arr); return (arr); } else { + prim_write_barrier; SET_INFO(arr,stg_MUT_ARR_PTRS_DIRTY_info); return (arr); } @@ -390,7 +394,6 @@ stg_newArrayArrayzh ( W_ n /* words */ ) } TICK_ALLOC_PRIM(SIZEOF_StgMutArrPtrs, WDS(size), 0); - SET_HDR(arr, stg_MUT_ARR_PTRS_DIRTY_info, W_[CCCS]); StgMutArrPtrs_ptrs(arr) = n; StgMutArrPtrs_size(arr) = size; @@ -403,6 +406,9 @@ stg_newArrayArrayzh ( W_ n /* words */ ) goto for; } + prim_write_barrier; + SET_HDR(arr, stg_MUT_ARR_PTRS_DIRTY_info, W_[CCCS]); + return (arr); } @@ -425,8 +431,6 @@ stg_newSmallArrayzh ( W_ n /* words */, gcptr init ) } TICK_ALLOC_PRIM(SIZEOF_StgSmallMutArrPtrs, WDS(n), 0); - /* No write barrier needed since this is a new allocation. */ - SET_HDR(arr, stg_SMALL_MUT_ARR_PTRS_DIRTY_info, CCCS); StgSmallMutArrPtrs_ptrs(arr) = n; // Initialise all elements of the array with the value in R2 @@ -441,6 +445,9 @@ stg_newSmallArrayzh ( W_ n /* words */, gcptr init ) goto for; } + prim_write_barrier; + SET_HDR(arr, stg_SMALL_MUT_ARR_PTRS_DIRTY_info, CCCS); + return (arr); } @@ -449,11 +456,13 @@ stg_unsafeThawSmallArrayzh ( gcptr arr ) // See stg_unsafeThawArrayzh if (StgHeader_info(arr) != stg_SMALL_MUT_ARR_PTRS_FROZEN_DIRTY_info) { SET_INFO(arr, stg_SMALL_MUT_ARR_PTRS_DIRTY_info); + prim_write_barrier; recordMutable(arr); // must be done after SET_INFO, because it ASSERTs closure_MUTABLE() return (arr); } else { SET_INFO(arr, stg_SMALL_MUT_ARR_PTRS_DIRTY_info); + prim_write_barrier; return (arr); } } @@ -511,12 +520,13 @@ stg_copySmallArrayzh ( gcptr src, W_ src_off, gcptr dst, W_ dst_off, W_ n) dst, dst_off, n); } - SET_INFO(dst, stg_SMALL_MUT_ARR_PTRS_DIRTY_info); - dst_p = dst + SIZEOF_StgSmallMutArrPtrs + WDS(dst_off); src_p = src + SIZEOF_StgSmallMutArrPtrs + WDS(src_off); bytes = WDS(n); prim %memcpy(dst_p, src_p, bytes, SIZEOF_W); + + prim_write_barrier; + SET_INFO(dst, stg_SMALL_MUT_ARR_PTRS_DIRTY_info); } return (); @@ -532,8 +542,6 @@ stg_copySmallMutableArrayzh ( gcptr src, W_ src_off, gcptr dst, W_ dst_off, W_ n dst, dst_off, n); } - SET_INFO(dst, stg_SMALL_MUT_ARR_PTRS_DIRTY_info); - dst_p = dst + SIZEOF_StgSmallMutArrPtrs + WDS(dst_off); src_p = src + SIZEOF_StgSmallMutArrPtrs + WDS(src_off); bytes = WDS(n); @@ -542,6 +550,9 @@ stg_copySmallMutableArrayzh ( gcptr src, W_ src_off, gcptr dst, W_ dst_off, W_ n } else { prim %memcpy(dst_p, src_p, bytes, SIZEOF_W); } + + prim_write_barrier; + SET_INFO(dst, stg_SMALL_MUT_ARR_PTRS_DIRTY_info); } return (); @@ -583,9 +594,9 @@ stg_newMutVarzh ( gcptr init ) ALLOC_PRIM_P (SIZEOF_StgMutVar, stg_newMutVarzh, init); mv = Hp - SIZEOF_StgMutVar + WDS(1); - /* No write barrier needed since this is a new allocation. */ - SET_HDR(mv,stg_MUT_VAR_DIRTY_info,CCCS); StgMutVar_var(mv) = init; + prim_write_barrier; + SET_HDR(mv,stg_MUT_VAR_DIRTY_info,CCCS); return (mv); } @@ -668,16 +679,18 @@ stg_atomicModifyMutVar2zh ( gcptr mv, gcptr f ) TICK_ALLOC_THUNK_2(); CCCS_ALLOC(THUNK_2_SIZE); z = Hp - THUNK_2_SIZE + WDS(1); - SET_HDR(z, stg_ap_2_upd_info, CCCS); LDV_RECORD_CREATE(z); StgThunk_payload(z,0) = f; + prim_write_barrier; + SET_HDR(z, stg_ap_2_upd_info, CCCS); TICK_ALLOC_THUNK_1(); CCCS_ALLOC(THUNK_1_SIZE); y = z - THUNK_1_SIZE; - SET_HDR(y, stg_sel_0_upd_info, CCCS); LDV_RECORD_CREATE(y); StgThunk_payload(y,0) = z; + prim_write_barrier; + SET_HDR(y, stg_sel_0_upd_info, CCCS); retry: x = StgMutVar_var(mv); @@ -728,9 +741,10 @@ stg_atomicModifyMutVarzuzh ( gcptr mv, gcptr f ) TICK_ALLOC_THUNK(); CCCS_ALLOC(THUNK_SIZE); z = Hp - THUNK_SIZE + WDS(1); - SET_HDR(z, stg_ap_2_upd_info, CCCS); LDV_RECORD_CREATE(z); StgThunk_payload(z,0) = f; + prim_write_barrier; + SET_HDR(z, stg_ap_2_upd_info, CCCS); retry: x = StgMutVar_var(mv); @@ -763,8 +777,6 @@ stg_mkWeakzh ( gcptr key, ALLOC_PRIM (SIZEOF_StgWeak) w = Hp - SIZEOF_StgWeak + WDS(1); - // No memory barrier needed as this is a new allocation. - SET_HDR(w, stg_WEAK_info, CCCS); StgWeak_key(w) = key; StgWeak_value(w) = value; @@ -772,6 +784,10 @@ stg_mkWeakzh ( gcptr key, StgWeak_cfinalizers(w) = stg_NO_FINALIZER_closure; StgWeak_link(w) = Capability_weak_ptr_list_hd(MyCapability()); + + prim_write_barrier; + SET_HDR(w, stg_WEAK_info, CCCS); + Capability_weak_ptr_list_hd(MyCapability()) = w; if (Capability_weak_ptr_list_tl(MyCapability()) == NULL) { Capability_weak_ptr_list_tl(MyCapability()) = w; @@ -798,13 +814,15 @@ stg_addCFinalizzerToWeakzh ( W_ fptr, // finalizer ALLOC_PRIM (SIZEOF_StgCFinalizerList) c = Hp - SIZEOF_StgCFinalizerList + WDS(1); - SET_HDR(c, stg_C_FINALIZER_LIST_info, CCCS); StgCFinalizerList_fptr(c) = fptr; StgCFinalizerList_ptr(c) = ptr; StgCFinalizerList_eptr(c) = eptr; StgCFinalizerList_flag(c) = flag; + prim_write_barrier; + SET_HDR(c, stg_C_FINALIZER_LIST_info, CCCS); + LOCK_CLOSURE(w, info); if (info == stg_DEAD_WEAK_info) { @@ -1544,12 +1562,12 @@ stg_newMVarzh () ALLOC_PRIM_ (SIZEOF_StgMVar, stg_newMVarzh); mvar = Hp - SIZEOF_StgMVar + WDS(1); - // No memory barrier needed as this is a new allocation. - SET_HDR(mvar,stg_MVAR_DIRTY_info,CCCS); - // MVARs start dirty: generation 0 has no mutable list StgMVar_head(mvar) = stg_END_TSO_QUEUE_closure; StgMVar_tail(mvar) = stg_END_TSO_QUEUE_closure; StgMVar_value(mvar) = stg_END_TSO_QUEUE_closure; + prim_write_barrier; + SET_HDR(mvar,stg_MVAR_DIRTY_info,CCCS); + // MVARs start dirty: generation 0 has no mutable list return (mvar); } @@ -1962,12 +1980,13 @@ stg_readMVarzh ( P_ mvar, /* :: MVar a */ ) StgMVarTSOQueue_link(q) = StgMVar_head(mvar); StgMVarTSOQueue_tso(q) = CurrentTSO; - SET_HDR(q, stg_MVAR_TSO_QUEUE_info, CCS_SYSTEM); prim_write_barrier; + SET_HDR(q, stg_MVAR_TSO_QUEUE_info, CCS_SYSTEM); StgTSO__link(CurrentTSO) = q; StgTSO_block_info(CurrentTSO) = mvar; StgTSO_why_blocked(CurrentTSO) = BlockedOnMVarRead::I16; + // TODO: Barrier needed here? StgMVar_head(mvar) = q; if (StgMVar_tail(mvar) == stg_END_TSO_QUEUE_closure) { @@ -2074,8 +2093,6 @@ stg_newBCOzh ( P_ instrs, ALLOC_PRIM (bytes); bco = Hp - bytes + WDS(1); - // No memory barrier necessary as this is a new allocation. - SET_HDR(bco, stg_BCO_info, CCS_MAIN); StgBCO_instrs(bco) = instrs; StgBCO_literals(bco) = literals; @@ -2093,6 +2110,9 @@ for: goto for; } + prim_write_barrier; + SET_HDR(bco, stg_BCO_info, CCS_MAIN); + return (bco); } @@ -2111,12 +2131,13 @@ stg_mkApUpd0zh ( P_ bco ) CCCS_ALLOC(SIZEOF_StgAP); ap = Hp - SIZEOF_StgAP + WDS(1); - // No memory barrier necessary as this is a new allocation. - SET_HDR(ap, stg_AP_info, CCS_MAIN); StgAP_n_args(ap) = HALF_W_(0); StgAP_fun(ap) = bco; + prim_write_barrier; + SET_HDR(ap, stg_AP_info, CCS_MAIN); + return (ap); } @@ -2145,7 +2166,6 @@ stg_unpackClosurezh ( P_ closure ) dat_arr = Hp - dat_arr_sz + WDS(1); - SET_HDR(dat_arr, stg_ARR_WORDS_info, CCCS); StgArrBytes_bytes(dat_arr) = WDS(len); p = 0; for: @@ -2160,6 +2180,9 @@ for: // Follow the pointers ("ptr" ptrArray) = foreign "C" heap_view_closurePtrs(MyCapability() "ptr", clos "ptr"); + prim_write_barrier; + SET_HDR(dat_arr, stg_ARR_WORDS_info, CCCS); + return (info, dat_arr, ptrArray); } ===================================== rts/RaiseAsync.c ===================================== @@ -922,6 +922,7 @@ raiseAsync(Capability *cap, StgTSO *tso, StgClosure *exception, ap->payload[i] = (StgClosure *)*sp++; } + write_barrier(); SET_HDR(ap,&stg_AP_STACK_NOUPD_info,stack->header.prof.ccs); TICK_ALLOC_SE_THK(WDS(words+1),0); @@ -960,6 +961,7 @@ raiseAsync(Capability *cap, StgTSO *tso, StgClosure *exception, // raise = (StgThunk *)allocate(cap,sizeofW(StgThunk)+1); TICK_ALLOC_SE_THK(WDS(1),0); + write_barrier(); SET_HDR(raise,&stg_raise_info,cf->header.prof.ccs); raise->payload[0] = exception; @@ -1040,8 +1042,9 @@ raiseAsync(Capability *cap, StgTSO *tso, StgClosure *exception, atomically = (StgThunk*)allocate(cap,sizeofW(StgThunk)+1); TICK_ALLOC_SE_THK(1,0); - SET_HDR(atomically,&stg_atomically_info,af->header.prof.ccs); atomically->payload[0] = af->code; + write_barrier(); + SET_HDR(atomically,&stg_atomically_info,af->header.prof.ccs); // discard stack up to and including the ATOMICALLY_FRAME frame += sizeofW(StgAtomicallyFrame); ===================================== rts/RtsAPI.c ===================================== @@ -30,8 +30,9 @@ HaskellObj rts_mkChar (Capability *cap, HsChar c) { StgClosure *p = (StgClosure *)allocate(cap, CONSTR_sizeW(0,1)); - SET_HDR(p, Czh_con_info, CCS_SYSTEM); p->payload[0] = (StgClosure *)(StgWord)(StgChar)c; + write_barrier(); + SET_HDR(p, Czh_con_info, CCS_SYSTEM); return p; } @@ -39,8 +40,9 @@ HaskellObj rts_mkInt (Capability *cap, HsInt i) { StgClosure *p = (StgClosure *)allocate(cap,CONSTR_sizeW(0,1)); - SET_HDR(p, Izh_con_info, CCS_SYSTEM); p->payload[0] = (StgClosure *)(StgInt)i; + write_barrier(); + SET_HDR(p, Izh_con_info, CCS_SYSTEM); return p; } @@ -48,9 +50,10 @@ HaskellObj rts_mkInt8 (Capability *cap, HsInt8 i) { StgClosure *p = (StgClosure *)allocate(cap,CONSTR_sizeW(0,1)); - SET_HDR(p, I8zh_con_info, CCS_SYSTEM); /* Make sure we mask out the bits above the lowest 8 */ p->payload[0] = (StgClosure *)(StgInt)i; + write_barrier(); + SET_HDR(p, I8zh_con_info, CCS_SYSTEM); return p; } @@ -58,9 +61,10 @@ HaskellObj rts_mkInt16 (Capability *cap, HsInt16 i) { StgClosure *p = (StgClosure *)allocate(cap,CONSTR_sizeW(0,1)); - SET_HDR(p, I16zh_con_info, CCS_SYSTEM); /* Make sure we mask out the relevant bits */ p->payload[0] = (StgClosure *)(StgInt)i; + write_barrier(); + SET_HDR(p, I16zh_con_info, CCS_SYSTEM); return p; } @@ -68,8 +72,9 @@ HaskellObj rts_mkInt32 (Capability *cap, HsInt32 i) { StgClosure *p = (StgClosure *)allocate(cap,CONSTR_sizeW(0,1)); - SET_HDR(p, I32zh_con_info, CCS_SYSTEM); p->payload[0] = (StgClosure *)(StgInt)i; + write_barrier(); + SET_HDR(p, I32zh_con_info, CCS_SYSTEM); return p; } @@ -77,8 +82,9 @@ HaskellObj rts_mkInt64 (Capability *cap, HsInt64 i) { StgClosure *p = (StgClosure *)allocate(cap,CONSTR_sizeW(0,2)); - SET_HDR(p, I64zh_con_info, CCS_SYSTEM); ASSIGN_Int64((P_)&(p->payload[0]), i); + write_barrier(); + SET_HDR(p, I64zh_con_info, CCS_SYSTEM); return p; } @@ -86,8 +92,9 @@ HaskellObj rts_mkWord (Capability *cap, HsWord i) { StgClosure *p = (StgClosure *)allocate(cap,CONSTR_sizeW(0,1)); - SET_HDR(p, Wzh_con_info, CCS_SYSTEM); p->payload[0] = (StgClosure *)(StgWord)i; + write_barrier(); + SET_HDR(p, Wzh_con_info, CCS_SYSTEM); return p; } @@ -96,8 +103,9 @@ rts_mkWord8 (Capability *cap, HsWord8 w) { /* see rts_mkInt* comments */ StgClosure *p = (StgClosure *)allocate(cap,CONSTR_sizeW(0,1)); - SET_HDR(p, W8zh_con_info, CCS_SYSTEM); p->payload[0] = (StgClosure *)(StgWord)(w & 0xff); + write_barrier(); + SET_HDR(p, W8zh_con_info, CCS_SYSTEM); return p; } @@ -106,8 +114,9 @@ rts_mkWord16 (Capability *cap, HsWord16 w) { /* see rts_mkInt* comments */ StgClosure *p = (StgClosure *)allocate(cap,CONSTR_sizeW(0,1)); - SET_HDR(p, W16zh_con_info, CCS_SYSTEM); p->payload[0] = (StgClosure *)(StgWord)(w & 0xffff); + write_barrier(); + SET_HDR(p, W16zh_con_info, CCS_SYSTEM); return p; } @@ -116,8 +125,9 @@ rts_mkWord32 (Capability *cap, HsWord32 w) { /* see rts_mkInt* comments */ StgClosure *p = (StgClosure *)allocate(cap,CONSTR_sizeW(0,1)); - SET_HDR(p, W32zh_con_info, CCS_SYSTEM); p->payload[0] = (StgClosure *)(StgWord)(w & 0xffffffff); + write_barrier(); + SET_HDR(p, W32zh_con_info, CCS_SYSTEM); return p; } @@ -126,8 +136,9 @@ rts_mkWord64 (Capability *cap, HsWord64 w) { StgClosure *p = (StgClosure *)allocate(cap,CONSTR_sizeW(0,2)); /* see mk_Int8 comment */ - SET_HDR(p, W64zh_con_info, CCS_SYSTEM); ASSIGN_Word64((P_)&(p->payload[0]), w); + write_barrier(); + SET_HDR(p, W64zh_con_info, CCS_SYSTEM); return p; } @@ -136,8 +147,9 @@ HaskellObj rts_mkFloat (Capability *cap, HsFloat f) { StgClosure *p = (StgClosure *)allocate(cap,CONSTR_sizeW(0,1)); - SET_HDR(p, Fzh_con_info, CCS_SYSTEM); ASSIGN_FLT((P_)p->payload, (StgFloat)f); + write_barrier(); + SET_HDR(p, Fzh_con_info, CCS_SYSTEM); return p; } @@ -145,8 +157,9 @@ HaskellObj rts_mkDouble (Capability *cap, HsDouble d) { StgClosure *p = (StgClosure *)allocate(cap,CONSTR_sizeW(0,sizeofW(StgDouble))); - SET_HDR(p, Dzh_con_info, CCS_SYSTEM); ASSIGN_DBL((P_)p->payload, (StgDouble)d); + write_barrier(); + SET_HDR(p, Dzh_con_info, CCS_SYSTEM); return p; } @@ -154,8 +167,9 @@ HaskellObj rts_mkStablePtr (Capability *cap, HsStablePtr s) { StgClosure *p = (StgClosure *)allocate(cap,sizeofW(StgHeader)+1); - SET_HDR(p, StablePtr_con_info, CCS_SYSTEM); p->payload[0] = (StgClosure *)s; + write_barrier(); + SET_HDR(p, StablePtr_con_info, CCS_SYSTEM); return p; } @@ -163,8 +177,9 @@ HaskellObj rts_mkPtr (Capability *cap, HsPtr a) { StgClosure *p = (StgClosure *)allocate(cap,sizeofW(StgHeader)+1); - SET_HDR(p, Ptr_con_info, CCS_SYSTEM); p->payload[0] = (StgClosure *)a; + write_barrier(); + SET_HDR(p, Ptr_con_info, CCS_SYSTEM); return p; } @@ -172,8 +187,9 @@ HaskellObj rts_mkFunPtr (Capability *cap, HsFunPtr a) { StgClosure *p = (StgClosure *)allocate(cap,sizeofW(StgHeader)+1); - SET_HDR(p, FunPtr_con_info, CCS_SYSTEM); p->payload[0] = (StgClosure *)a; + write_barrier(); + SET_HDR(p, FunPtr_con_info, CCS_SYSTEM); return p; } @@ -202,9 +218,10 @@ rts_apply (Capability *cap, HaskellObj f, HaskellObj arg) // Here we don't want to use CCS_SYSTEM, because it's a hidden cost centre, // and evaluating Haskell code under a hidden cost centre leads to // confusing profiling output. (#7753) - SET_HDR(ap, (StgInfoTable *)&stg_ap_2_upd_info, CCS_MAIN); ap->payload[0] = f; ap->payload[1] = arg; + write_barrier(); + SET_HDR(ap, (StgInfoTable *)&stg_ap_2_upd_info, CCS_MAIN); return (StgClosure *)ap; } ===================================== rts/StgMiscClosures.cmm ===================================== @@ -308,9 +308,8 @@ retry: MessageBlackHole_tso(msg) = CurrentTSO; MessageBlackHole_bh(msg) = node; + prim_write_barrier; SET_HDR(msg, stg_MSG_BLACKHOLE_info, CCS_SYSTEM); - // messageBlackHole has appropriate memory barriers when this object is exposed. - // See Note [Heap memory barriers]. (r) = ccall messageBlackHole(MyCapability() "ptr", msg "ptr"); @@ -370,6 +369,7 @@ INFO_TABLE(stg_WHITEHOLE, 0,0, WHITEHOLE, "WHITEHOLE", "WHITEHOLE") loop: // spin until the WHITEHOLE is updated info = StgHeader_info(node); + prim_read_barrier; if (info == stg_WHITEHOLE_info) { #if defined(PROF_SPIN) W_[whitehole_lockClosure_spin] = ===================================== rts/ThreadPaused.c ===================================== @@ -220,10 +220,9 @@ threadPaused(Capability *cap, StgTSO *tso) frame = (StgClosure *)tso->stackobj->sp; - // N.B. We know that the TSO is owned by the current capability so no - // memory barriers are needed here. while ((P_)frame < stack_end) { info = get_ret_itbl(frame); + load_load_barrier(); switch (info->i.type) { @@ -231,6 +230,7 @@ threadPaused(Capability *cap, StgTSO *tso) // If we've already marked this frame, then stop here. frame_info = frame->header.info; + load_load_barrier(); if (frame_info == (StgInfoTable *)&stg_marked_upd_frame_info) { if (prev_was_update_frame) { words_to_squeeze += sizeofW(StgUpdateFrame); @@ -240,10 +240,12 @@ threadPaused(Capability *cap, StgTSO *tso) goto end; } + write_barrier(); SET_INFO(frame, (StgInfoTable *)&stg_marked_upd_frame_info); bh = ((StgUpdateFrame *)frame)->updatee; bh_info = bh->header.info; + load_load_barrier(); IF_NONMOVING_WRITE_BARRIER_ENABLED { updateRemembSetPushClosure(cap, (StgClosure *) bh); } ===================================== rts/Threads.c ===================================== @@ -82,11 +82,12 @@ createThread(Capability *cap, W_ size) stack_size = round_to_mblocks(size - sizeofW(StgTSO)); stack = (StgStack *)allocate(cap, stack_size); TICK_ALLOC_STACK(stack_size); - SET_HDR(stack, &stg_STACK_info, cap->r.rCCCS); stack->stack_size = stack_size - sizeofW(StgStack); stack->sp = stack->stack + stack->stack_size; stack->dirty = STACK_DIRTY; stack->marking = 0; + write_barrier(); + SET_HDR(stack, &stg_STACK_info, cap->r.rCCCS); tso = (StgTSO *)allocate(cap, sizeofW(StgTSO)); TICK_ALLOC_TSO(); @@ -117,6 +118,9 @@ createThread(Capability *cap, W_ size) tso->prof.cccs = CCS_MAIN; #endif + write_barrier(); + SET_HDR(tso, &stg_TSO_info, CCS_SYSTEM); + // put a stop frame on the stack stack->sp -= sizeofW(StgStopFrame); SET_HDR((StgClosure*)stack->sp, @@ -276,9 +280,8 @@ tryWakeupThread (Capability *cap, StgTSO *tso) MessageWakeup *msg; msg = (MessageWakeup *)allocate(cap,sizeofW(MessageWakeup)); msg->tso = tso; - SET_HDR(msg, &stg_MSG_TRY_WAKEUP_info, CCS_SYSTEM); - // Ensure that writes constructing Message are committed before sending. write_barrier(); + SET_HDR(msg, &stg_MSG_TRY_WAKEUP_info, CCS_SYSTEM); sendMessage(cap, tso->cap, (Message*)msg); debugTraceCap(DEBUG_sched, cap, "message: try wakeup thread %ld on cap %d", (W_)tso->id, tso->cap->no); @@ -405,6 +408,8 @@ checkBlockingQueues (Capability *cap, StgTSO *tso) { StgBlockingQueue *bq, *next; StgClosure *p; + const StgInfoTable *bqinfo; + const StgInfoTable *pinfo; debugTraceCap(DEBUG_sched, cap, "collision occurred; checking blocking queues for thread %ld", @@ -623,13 +628,14 @@ threadStackOverflow (Capability *cap, StgTSO *tso) new_stack = (StgStack*) allocate(cap, chunk_size); cap->r.rCurrentTSO = NULL; - SET_HDR(new_stack, &stg_STACK_info, old_stack->header.prof.ccs); TICK_ALLOC_STACK(chunk_size); new_stack->dirty = 0; // begin clean, we'll mark it dirty below new_stack->marking = 0; new_stack->stack_size = chunk_size - sizeofW(StgStack); new_stack->sp = new_stack->stack + new_stack->stack_size; + write_barrier(); + SET_HDR(new_stack, &stg_STACK_info, old_stack->header.prof.ccs); tso->tot_stack_size += new_stack->stack_size; @@ -678,8 +684,9 @@ threadStackOverflow (Capability *cap, StgTSO *tso) } else { new_stack->sp -= sizeofW(StgUnderflowFrame); frame = (StgUnderflowFrame*)new_stack->sp; - frame->info = &stg_stack_underflow_frame_info; frame->next_chunk = old_stack; + write_barrier(); + frame->info = &stg_stack_underflow_frame_info; } // copy the stack chunk between tso->sp and sp to @@ -694,8 +701,6 @@ threadStackOverflow (Capability *cap, StgTSO *tso) new_stack->sp -= chunk_words; } - // No write barriers needed; all of the writes above are to structured - // owned by our capability. tso->stackobj = new_stack; // we're about to run it, better mark it dirty @@ -784,6 +789,8 @@ bool performTryPutMVar(Capability *cap, StgMVar *mvar, StgClosure *value) q = mvar->head; loop: + qinfo = q->header.info; + load_load_barrier(); if (q == (StgMVarTSOQueue*)&stg_END_TSO_QUEUE_closure) { /* No further takes, the MVar is now full. */ if (info == &stg_MVAR_CLEAN_info) { ===================================== rts/Weak.c ===================================== @@ -42,6 +42,7 @@ void runAllCFinalizers(StgWeak *list) { StgWeak *w; + const StgInfoTable *winfo; Task *task; task = myTask(); @@ -138,6 +139,7 @@ scheduleFinalizers(Capability *cap, StgWeak *list) // there's a later call to finalizeWeak# on this weak pointer, // we don't run the finalizer again. SET_HDR(w, &stg_DEAD_WEAK_info, w->header.prof.ccs); + write_barrier(); } n_finalizers += i; @@ -150,8 +152,6 @@ scheduleFinalizers(Capability *cap, StgWeak *list) size = n + mutArrPtrsCardTableSize(n); arr = (StgMutArrPtrs *)allocate(cap, sizeofW(StgMutArrPtrs) + size); TICK_ALLOC_PRIM(sizeofW(StgMutArrPtrs), n, 0); - // No write barrier needed here; this array is only going to referred to by this core. - SET_HDR(arr, &stg_MUT_ARR_PTRS_FROZEN_CLEAN_info, CCS_SYSTEM); arr->ptrs = n; arr->size = size; @@ -167,6 +167,9 @@ scheduleFinalizers(Capability *cap, StgWeak *list) arr->payload[i] = (StgClosure *)(W_)(-1); } + write_barrier(); + SET_HDR(arr, &stg_MUT_ARR_PTRS_FROZEN_CLEAN_info, CCS_SYSTEM); + t = createIOThread(cap, RtsFlags.GcFlags.initialStkSize, rts_apply(cap, ===================================== rts/sm/CNF.c ===================================== @@ -376,7 +376,6 @@ compactNew (Capability *cap, StgWord size) ALLOCATE_NEW); self = firstBlockGetCompact(block); - SET_HDR((StgClosure*)self, &stg_COMPACT_NFDATA_CLEAN_info, CCS_SYSTEM); self->autoBlockW = aligned_size / sizeof(StgWord); self->nursery = block; self->last = block; @@ -394,6 +393,9 @@ compactNew (Capability *cap, StgWord size) debugTrace(DEBUG_compact, "compactNew: size %" FMT_Word, size); + write_barrier(); + SET_HDR((StgClosure*)self, &stg_COMPACT_NFDATA_CLEAN_info, CCS_SYSTEM); + return self; } @@ -546,6 +548,7 @@ insertCompactHash (Capability *cap, { insertHashTable(str->hash, (StgWord)p, (const void*)to); const StgInfoTable **strinfo = &str->header.info; + load_load_barrier(); if (*strinfo == &stg_COMPACT_NFDATA_CLEAN_info) { *strinfo = &stg_COMPACT_NFDATA_DIRTY_info; recordClosureMutated(cap, (StgClosure*)str); @@ -690,6 +693,7 @@ verify_consistency_block (StgCompactNFData *str, StgCompactNFDataBlock *block) ASSERT(LOOKS_LIKE_CLOSURE_PTR(q)); info = get_itbl(q); + load_load_barrier(); switch (info->type) { case CONSTR_1_0: check_object_in_compact(str, UNTAG_CLOSURE(q->payload[0])); @@ -929,6 +933,7 @@ fixup_block(StgCompactNFDataBlock *block, StgWord *fixup_table, uint32_t count) while (p < bd->free) { ASSERT(LOOKS_LIKE_CLOSURE_PTR(p)); info = get_itbl((StgClosure*)p); + load_load_barrier(); switch (info->type) { case CONSTR_1_0: ===================================== rts/sm/Compact.c ===================================== @@ -197,6 +197,7 @@ STATIC_INLINE StgInfoTable* get_threaded_info( P_ p ) { W_ q = (W_)GET_INFO(UNTAG_CLOSURE((StgClosure *)p)); + load_load_barrier(); loop: switch (GET_PTR_TAG(q)) @@ -382,6 +383,7 @@ thread_stack(P_ p, P_ stack_end) StgRetFun *ret_fun = (StgRetFun *)p; StgFunInfoTable *fun_info = FUN_INFO_PTR_TO_STRUCT(get_threaded_info((P_)ret_fun->fun)); + load_load_barrier(); // *before* threading it! thread(&ret_fun->fun); p = thread_arg_block(fun_info, ret_fun->payload); @@ -400,6 +402,7 @@ thread_PAP_payload (StgClosure *fun, StgClosure **payload, W_ size) { StgFunInfoTable *fun_info = FUN_INFO_PTR_TO_STRUCT(get_threaded_info((P_)fun)); + load_load_barrier(); ASSERT(fun_info->i.type != PAP); P_ p = (P_)payload; @@ -620,6 +623,8 @@ update_fwd_large( bdescr *bd ) static /* STATIC_INLINE */ P_ thread_obj (const StgInfoTable *info, P_ p) { + load_load_barrier(); + switch (info->type) { case THUNK_0_1: return p + sizeofW(StgThunk) + 1; @@ -851,6 +856,7 @@ update_fwd_compact( bdescr *blocks ) // definitely have enough room. Also see bug #1147. StgInfoTable *iptr = get_threaded_info(p); StgInfoTable *info = INFO_PTR_TO_STRUCT(iptr); + load_load_barrier(); P_ q = p; ===================================== rts/sm/Evac.c ===================================== @@ -157,6 +157,7 @@ copy_tag(StgClosure **p, const StgInfoTable *info, { const StgInfoTable *new_info; new_info = (const StgInfoTable *)cas((StgPtr)&src->header.info, (W_)info, MK_FORWARDING_PTR(to)); + load_load_barrier(); if (new_info != info) { #if defined(PROFILING) // We copied this object at the same time as another @@ -175,8 +176,11 @@ copy_tag(StgClosure **p, const StgInfoTable *info, } } #else - src->header.info = (const StgInfoTable *)MK_FORWARDING_PTR(to); + // if somebody else reads the forwarding pointer, we better make + // sure there's a closure at the end of it. + write_barrier(); *p = TAG_CLOSURE(tag,(StgClosure*)to); + src->header.info = (const StgInfoTable *)MK_FORWARDING_PTR(to); #endif /* defined(PARALLEL_GC) */ #if defined(PROFILING) @@ -251,6 +255,7 @@ spin: } #else info = (W_)src->header.info; + load_load_barrier(); #endif /* PARALLEL_GC */ to = alloc_for_copy(size_to_reserve, gen_no); @@ -703,6 +708,7 @@ loop: gen_no = bd->dest_no; info = q->header.info; + load_load_barrier(); if (IS_FORWARDING_PTR(info)) { /* Already evacuated, just return the forwarding address. @@ -813,11 +819,14 @@ loop: StgClosure *r; const StgInfoTable *i; r = ((StgInd*)q)->indirectee; + load_load_barrier(); if (GET_CLOSURE_TAG(r) == 0) { i = r->header.info; + load_load_barrier(); if (IS_FORWARDING_PTR(i)) { r = (StgClosure *)UN_FORWARDING_PTR(i); i = r->header.info; + load_load_barrier(); } if (i == &stg_TSO_info || i == &stg_WHITEHOLE_info @@ -1016,6 +1025,7 @@ evacuate_BLACKHOLE(StgClosure **p) } gen_no = bd->dest_no; info = q->header.info; + load_load_barrier(); if (IS_FORWARDING_PTR(info)) { StgClosure *e = (StgClosure*)UN_FORWARDING_PTR(info); @@ -1208,6 +1218,7 @@ selector_chain: #else // Save the real info pointer (NOTE: not the same as get_itbl()). info_ptr = (StgWord)p->header.info; + load_load_barrier(); SET_INFO((StgClosure *)p,&stg_WHITEHOLE_info); #endif /* THREADED_RTS */ @@ -1226,6 +1237,7 @@ selector_loop: // that evacuate() doesn't mind if it gets passed a to-space pointer. info = (StgInfoTable*)selectee->header.info; + load_load_barrier(); if (IS_FORWARDING_PTR(info)) { // We don't follow pointers into to-space; the constructor @@ -1235,6 +1247,7 @@ selector_loop: } info = INFO_PTR_TO_STRUCT(info); + load_load_barrier(); switch (info->type) { case WHITEHOLE: goto bale_out; // about to be evacuated by another thread (or a loop). @@ -1282,6 +1295,7 @@ selector_loop: if (!IS_FORWARDING_PTR(info_ptr)) { info = INFO_PTR_TO_STRUCT((StgInfoTable *)info_ptr); + load_load_barrier(); switch (info->type) { case IND: case IND_STATIC: @@ -1333,9 +1347,11 @@ selector_loop: // indirection, as in evacuate(). if (GET_CLOSURE_TAG(r) == 0) { i = r->header.info; + load_load_barrier(); if (IS_FORWARDING_PTR(i)) { r = (StgClosure *)UN_FORWARDING_PTR(i); i = r->header.info; + load_load_barrier(); } if (i == &stg_TSO_info || i == &stg_WHITEHOLE_info ===================================== rts/sm/GCAux.c ===================================== @@ -84,6 +84,7 @@ isAlive(StgClosure *p) } info = q->header.info; + load_load_barrier(); if (IS_FORWARDING_PTR(info)) { // alive! @@ -131,6 +132,7 @@ revertCAFs( void ) SET_INFO((StgClosure *)c, c->saved_info); c->saved_info = NULL; + write_barrier(); // We must reset static_link lest the major GC finds that // static_flag==3 and will consequently ignore references // into code that we are trying to unload. This would result ===================================== rts/sm/Scav.c ===================================== @@ -386,6 +386,7 @@ scavenge_thunk_srt(const StgInfoTable *info) if (!major_gc) return; thunk_info = itbl_to_thunk_itbl(info); + load_load_barrier(); if (thunk_info->i.srt) { StgClosure *srt = (StgClosure*)GET_SRT(thunk_info); evacuate(&srt); @@ -400,6 +401,7 @@ scavenge_fun_srt(const StgInfoTable *info) if (!major_gc) return; fun_info = itbl_to_fun_itbl(info); + load_load_barrier(); if (fun_info->i.srt) { StgClosure *srt = (StgClosure*)GET_FUN_SRT(fun_info); evacuate(&srt); @@ -462,6 +464,7 @@ scavenge_block (bdescr *bd) evacuate((StgClosure **)&mvar->value); gct->eager_promotion = saved_eager_promotion; + write_barrier(); if (gct->failed_to_evac) { mvar->header.info = &stg_MVAR_DIRTY_info; } else { @@ -479,6 +482,7 @@ scavenge_block (bdescr *bd) evacuate((StgClosure **)&tvar->first_watch_queue_entry); gct->eager_promotion = saved_eager_promotion; + write_barrier(); if (gct->failed_to_evac) { tvar->header.info = &stg_TVAR_DIRTY_info; } else { @@ -613,6 +617,7 @@ scavenge_block (bdescr *bd) evacuate(&((StgMutVar *)p)->var); gct->eager_promotion = saved_eager_promotion; + write_barrier(); if (gct->failed_to_evac) { ((StgClosure *)q)->header.info = &stg_MUT_VAR_DIRTY_info; } else { @@ -632,6 +637,7 @@ scavenge_block (bdescr *bd) evacuate((StgClosure**)&bq->link); gct->eager_promotion = saved_eager_promotion; + write_barrier(); if (gct->failed_to_evac) { bq->header.info = &stg_BLOCKING_QUEUE_DIRTY_info; } else { @@ -684,6 +690,7 @@ scavenge_block (bdescr *bd) p = scavenge_mut_arr_ptrs((StgMutArrPtrs*)p); + write_barrier(); if (gct->failed_to_evac) { ((StgClosure *)q)->header.info = &stg_MUT_ARR_PTRS_DIRTY_info; } else { @@ -701,6 +708,7 @@ scavenge_block (bdescr *bd) { p = scavenge_mut_arr_ptrs((StgMutArrPtrs*)p); + write_barrier(); if (gct->failed_to_evac) { ((StgClosure *)q)->header.info = &stg_MUT_ARR_PTRS_FROZEN_DIRTY_info; } else { @@ -726,6 +734,7 @@ scavenge_block (bdescr *bd) } gct->eager_promotion = saved_eager_promotion; + write_barrier(); if (gct->failed_to_evac) { ((StgClosure *)q)->header.info = &stg_SMALL_MUT_ARR_PTRS_DIRTY_info; } else { @@ -747,6 +756,7 @@ scavenge_block (bdescr *bd) evacuate((StgClosure **)p); } + write_barrier(); if (gct->failed_to_evac) { ((StgClosure *)q)->header.info = &stg_SMALL_MUT_ARR_PTRS_FROZEN_DIRTY_info; } else { @@ -887,6 +897,7 @@ scavenge_mark_stack(void) evacuate((StgClosure **)&mvar->value); gct->eager_promotion = saved_eager_promotion; + write_barrier(); if (gct->failed_to_evac) { mvar->header.info = &stg_MVAR_DIRTY_info; } else { @@ -903,6 +914,7 @@ scavenge_mark_stack(void) evacuate((StgClosure **)&tvar->first_watch_queue_entry); gct->eager_promotion = saved_eager_promotion; + write_barrier(); if (gct->failed_to_evac) { tvar->header.info = &stg_TVAR_DIRTY_info; } else { @@ -1009,6 +1021,7 @@ scavenge_mark_stack(void) evacuate(&((StgMutVar *)p)->var); gct->eager_promotion = saved_eager_promotion; + write_barrier(); if (gct->failed_to_evac) { ((StgClosure *)q)->header.info = &stg_MUT_VAR_DIRTY_info; } else { @@ -1028,6 +1041,7 @@ scavenge_mark_stack(void) evacuate((StgClosure**)&bq->link); gct->eager_promotion = saved_eager_promotion; + write_barrier(); if (gct->failed_to_evac) { bq->header.info = &stg_BLOCKING_QUEUE_DIRTY_info; } else { @@ -1076,6 +1090,7 @@ scavenge_mark_stack(void) scavenge_mut_arr_ptrs((StgMutArrPtrs *)p); + write_barrier(); if (gct->failed_to_evac) { ((StgClosure *)q)->header.info = &stg_MUT_ARR_PTRS_DIRTY_info; } else { @@ -1095,6 +1110,7 @@ scavenge_mark_stack(void) scavenge_mut_arr_ptrs((StgMutArrPtrs *)p); + write_barrier(); if (gct->failed_to_evac) { ((StgClosure *)q)->header.info = &stg_MUT_ARR_PTRS_FROZEN_DIRTY_info; } else { @@ -1122,6 +1138,7 @@ scavenge_mark_stack(void) } gct->eager_promotion = saved_eager; + write_barrier(); if (gct->failed_to_evac) { ((StgClosure *)q)->header.info = &stg_SMALL_MUT_ARR_PTRS_DIRTY_info; } else { @@ -1143,6 +1160,7 @@ scavenge_mark_stack(void) evacuate((StgClosure **)p); } + write_barrier(); if (gct->failed_to_evac) { ((StgClosure *)q)->header.info = &stg_SMALL_MUT_ARR_PTRS_FROZEN_DIRTY_info; } else { @@ -1249,6 +1267,7 @@ scavenge_one(StgPtr p) evacuate((StgClosure **)&mvar->value); gct->eager_promotion = saved_eager_promotion; + write_barrier(); if (gct->failed_to_evac) { mvar->header.info = &stg_MVAR_DIRTY_info; } else { @@ -1265,6 +1284,7 @@ scavenge_one(StgPtr p) evacuate((StgClosure **)&tvar->first_watch_queue_entry); gct->eager_promotion = saved_eager_promotion; + write_barrier(); if (gct->failed_to_evac) { tvar->header.info = &stg_TVAR_DIRTY_info; } else { @@ -1329,6 +1349,7 @@ scavenge_one(StgPtr p) evacuate(&((StgMutVar *)p)->var); gct->eager_promotion = saved_eager_promotion; + write_barrier(); if (gct->failed_to_evac) { ((StgClosure *)q)->header.info = &stg_MUT_VAR_DIRTY_info; } else { @@ -1348,6 +1369,7 @@ scavenge_one(StgPtr p) evacuate((StgClosure**)&bq->link); gct->eager_promotion = saved_eager_promotion; + write_barrier(); if (gct->failed_to_evac) { bq->header.info = &stg_BLOCKING_QUEUE_DIRTY_info; } else { @@ -1396,6 +1418,7 @@ scavenge_one(StgPtr p) scavenge_mut_arr_ptrs((StgMutArrPtrs *)p); + write_barrier(); if (gct->failed_to_evac) { ((StgClosure *)p)->header.info = &stg_MUT_ARR_PTRS_DIRTY_info; } else { @@ -1413,6 +1436,7 @@ scavenge_one(StgPtr p) // follow everything scavenge_mut_arr_ptrs((StgMutArrPtrs *)p); + write_barrier(); if (gct->failed_to_evac) { ((StgClosure *)p)->header.info = &stg_MUT_ARR_PTRS_FROZEN_DIRTY_info; } else { @@ -1440,6 +1464,7 @@ scavenge_one(StgPtr p) } gct->eager_promotion = saved_eager; + write_barrier(); if (gct->failed_to_evac) { ((StgClosure *)q)->header.info = &stg_SMALL_MUT_ARR_PTRS_DIRTY_info; } else { @@ -1461,6 +1486,7 @@ scavenge_one(StgPtr p) evacuate((StgClosure **)p); } + write_barrier(); if (gct->failed_to_evac) { ((StgClosure *)q)->header.info = &stg_SMALL_MUT_ARR_PTRS_FROZEN_DIRTY_info; } else { @@ -1613,6 +1639,7 @@ scavenge_mutable_list(bdescr *bd, generation *gen) mutlist_TREC_CHUNK++; break; case MUT_PRIM: pinfo = ((StgClosure*)p)->header.info; + load_load_barrier(); if (pinfo == &stg_TVAR_WATCH_QUEUE_info) mutlist_TVAR_WATCH_QUEUE++; else if (pinfo == &stg_TREC_HEADER_info) @@ -1645,6 +1672,7 @@ scavenge_mutable_list(bdescr *bd, generation *gen) scavenge_mut_arr_ptrs_marked((StgMutArrPtrs *)p); + write_barrier(); if (gct->failed_to_evac) { ((StgClosure *)p)->header.info = &stg_MUT_ARR_PTRS_DIRTY_info; } else { ===================================== rts/sm/Storage.c ===================================== @@ -500,9 +500,8 @@ lockCAF (StgRegTable *reg, StgIndStatic *caf) bh = (StgInd *)allocate(cap, sizeofW(*bh)); } bh->indirectee = (StgClosure *)cap->r.rCurrentTSO; - SET_HDR(bh, &stg_CAF_BLACKHOLE_info, caf->header.prof.ccs); - // Ensure that above writes are visible before we introduce reference as CAF indirectee. write_barrier(); + SET_HDR(bh, &stg_CAF_BLACKHOLE_info, caf->header.prof.ccs); caf->indirectee = (StgClosure *)bh; write_barrier(); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/62e19a6d0889187dfbce0ba2f404849b90b1ef02 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/62e19a6d0889187dfbce0ba2f404849b90b1ef02 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 19 14:19:32 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Tue, 19 May 2020 10:19:32 -0400 Subject: [Git][ghc/ghc][wip/T17775] Simple subsumption Message-ID: <5ec3eaf48288f_6e261104590055161@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: d84724b4 by Simon Peyton Jones at 2020-05-19T10:19:12-04:00 Simple subsumption This patch simplifies GHC to use simple subsumption. Ticket #17775 Implements GHC proposal #287 https://github.com/ghc-proposals/ghc-proposals/blob/master/ proposals/0287-simplify-subsumption.rst All the motivation is described there; I will not repeat it here. The implementation payload: * tcSubType and friends become noticably simpler, because it no longer uses eta-expansion when checking subsumption. * No deeplyInstantiate or deeplySkolemise That in turn means that some tests fail, by design; they can all be fixed by eta expansion. There is a list of such changes below. Implementing the patch led me into a variety of sticky corners, so the patch includes several othe changes, some quite significant: * I made String wired-in, so that "foo" :: String rather than "foo" :: [Char] This improves error messages, and fixes #15679 * The pattern match checker relies on knowing about in-scope equality constraints, andd adds them to the desugarer's environment using addTyCsDs. But the co_fn in a FunBind was missed, and for some reason simple-subsumption ends up with dictionaries there. So I added a call to addTyCsDs. This is really part of #18049. * I moved the ic_telescope field out of Implication and into ForAllSkol instead. This is a nice win; just expresses the code much better. * There was a bug in GHC.Tc.TyCl.Instance.tcDataFamInstHeader. We called checkDataKindSig inside tc_kind_sig, /before/ solveEqualities and zonking. Obviously wrong, easily fixed. * solveLocalEqualitiesX: there was a whole mess in here, around failing fast enough. I discovered a bad latent bug where we could successfully kind-check a type signature, and use it, but have unsolved constraints that could fill in coercion holes in that signature -- aargh. It's all explained in Note [Failure in local type signatures] in GHC.Tc.Solver. Much better now. * I fixed a serious bug in anonymous type holes. IN f :: Int -> (forall a. a -> _) -> Int that "_" should be a unification variable at the /outer/ level; it cannot be instantiated to 'a'. This was plain wrong. New fields mode_lvl and mode_holes in TcTyMode, and auxiliary data type GHC.Tc.Gen.HsType.HoleMode. This fixes #16292, but makes no progress towards the more ambitious #16082 * I got sucked into an enormous refactoring of the reporting of equality errors in GHC.Tc.Errors, especially in mkEqErr1 mkTyVarEqErr misMatchMsg misMatchMsgOrCND In particular, the very tricky mkExpectedActualMsg function is gone. It took me a full day. But the result is far easier to understand. (Still not easy!) This led to various minor improvements in error output, and an enormous number of test-case error wibbles. One particular point: for occurs-check errors I now just say Can't match 'a' against '[a]' rather than using the intimidating language of "occurs check". * Pretty-printing AbsBinds Tests review * Eta expansions T11305: one eta expansion T12082: one eta expansion (undefined) T13585a: one eta expansion T3102: one eta expansion T3692: two eta expansions (tricky) T2239: two eta expansions T16473: one eta determ004: two eta expansions (undefined) annfail06: two eta (undefined) T17923: four eta expansions (a strange program indeed!) tcrun035: one eta expansion * Ambiguity check at higher rank. Now that we have simple subsumption, a type like f :: (forall a. Eq a => Int) -> Int is no longer ambiguous, because we could write g :: (forall a. Eq a => Int) -> Int g = f and it'd typecheck just fine. But f's type is a bit suspicious, and we might want to consider making the ambiguity check do a check on each sub-term. Meanwhile, these tests are accepted, whereas they were previously rejected as ambiguous: T7220a T15438 T10503 T9222 * Some more interesting error message wibbles T13381: Fine: one error (Int ~ Exp Int) rather than two (Int ~ Exp Int, Exp Int ~ Int) T9834: Small change in error (improvement) T10619: Improved T2414: Small change, due to order of unification, fine T2534: A very simple case in which a change of unification order means we get tow unsolved constraints instead of one tc211: bizarre impredicative tests; just accept this for now - - - - - 21 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Types.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Splice.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Default.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Expr.hs-boot - compiler/GHC/Tc/Gen/Foreign.hs - compiler/GHC/Tc/Gen/HsType.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d84724b4657540c784b16cdb777e6174c66c821c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d84724b4657540c784b16cdb777e6174c66c821c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 19 14:50:08 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Tue, 19 May 2020 10:50:08 -0400 Subject: [Git][ghc/ghc][wip/andreask/xchg_primop] Make exchange an IO action as it should be. Message-ID: <5ec3f2206dee7_6e26af1b5e46969f@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/xchg_primop at Glasgow Haskell Compiler / GHC Commits: c9a41cf4 by Andreas Klebinger at 2020-05-19T16:48:57+02:00 Make exchange an IO action as it should be. - - - - - 4 changed files: - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/StgToCmm/Prim.hs - libraries/base/GHC/Ptr.hs Changes: ===================================== compiler/GHC/Builtin/primops.txt.pp ===================================== @@ -2473,14 +2473,14 @@ primop WriteOffAddrOp_Word64 "writeWord64OffAddr#" GenPrimOp with has_side_effects = True can_fail = True -primop InterlockedExchangeAddr "interlockedExchangeAddr#" GenPrimOp - Addr# -> Addr# -> Addr# +primop InterlockedExchange_Addr "interlockedExchangeAddr#" GenPrimOp + Addr# -> Addr# -> State# s -> (# State# s, Addr# #) {The atomic exchange operation. Atomically exchanges the value at the first address with the Addr# given as second argument. Implies a read barrier.} with has_side_effects = True -primop InterlockedExchangeInt "interlockedExchangeInt#" GenPrimOp - Addr# -> Int# -> Int# +primop InterlockedExchange_Int "interlockedExchangeInt#" GenPrimOp + Addr# -> Int# -> State# s -> (# State# s, Int# #) {The atomic exchange operation. Atomically exchanges the value at the address with the given value. Returns the old value. Implies a read barrier.} with has_side_effects = True ===================================== compiler/GHC/Cmm/MachOp.hs ===================================== @@ -633,7 +633,7 @@ data CallishMachOp | MO_AtomicWrite Width | MO_Cmpxchg Width -- Should be an AtomicRMW variant eventually. - -- Has at least aquire semantics. + -- Has at least acquire semantics. | MO_Xchg Width deriving (Eq, Show) ===================================== compiler/GHC/StgToCmm/Prim.hs ===================================== @@ -857,9 +857,9 @@ emitPrimOp dflags = \case emitPrimCall [res] (MO_UF_Conv W64) [w] -- Atomic operations - InterlockedExchangeAddr -> \[src, value] -> opAllDone $ \[res] -> + InterlockedExchange_Addr -> \[src, value] -> opAllDone $ \[res] -> emitPrimCall [res] (MO_Xchg (wordWidth platform)) [src, value] - InterlockedExchangeInt -> \[src, value] -> opAllDone $ \[res] -> + InterlockedExchange_Int -> \[src, value] -> opAllDone $ \[res] -> emitPrimCall [res] (MO_Xchg (wordWidth platform)) [src, value] -- SIMD primops ===================================== libraries/base/GHC/Ptr.hs ===================================== @@ -1,5 +1,6 @@ {-# LANGUAGE Unsafe #-} {-# LANGUAGE CPP, NoImplicitPrelude, MagicHash, RoleAnnotations #-} +{-# LANGUAGE UnboxedTuples #-} {-# OPTIONS_HADDOCK not-home #-} ----------------------------------------------------------------------------- @@ -169,9 +170,11 @@ castPtrToFunPtr (Ptr addr) = FunPtr addr -- Atomic operations for Ptr {-# INLINE exchangePtr #-} -exchangePtr :: Ptr (Ptr a) -> Ptr b -> Ptr c -exchangePtr (Ptr dst) (Ptr val) - = Ptr (interlockedExchangeAddr# dst val) +exchangePtr :: Ptr (Ptr a) -> Ptr b -> IO (Ptr c) +exchangePtr (Ptr dst) (Ptr val) = + IO $ \s -> + case (interlockedExchangeAddr# dst val s) of + (# s2, old_val #) -> (# s2, Ptr old_val #) ------------------------------------------------------------------------ -- Show instances for Ptr and FunPtr View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c9a41cf4add38fd82706dc15204628835cae9ede -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c9a41cf4add38fd82706dc15204628835cae9ede You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 19 15:49:29 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Tue, 19 May 2020 11:49:29 -0400 Subject: [Git][ghc/ghc][wip/T17775] Simple subsumption Message-ID: <5ec400094b3a8_6e263f9ee294e3e489955@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: a2fda5e1 by Simon Peyton Jones at 2020-05-19T16:46:32+01:00 Simple subsumption This patch simplifies GHC to use simple subsumption. Ticket #17775 Implements GHC proposal #287 https://github.com/ghc-proposals/ghc-proposals/blob/master/ proposals/0287-simplify-subsumption.rst All the motivation is described there; I will not repeat it here. The implementation payload: * tcSubType and friends become noticably simpler, because it no longer uses eta-expansion when checking subsumption. * No deeplyInstantiate or deeplySkolemise That in turn means that some tests fail, by design; they can all be fixed by eta expansion. There is a list of such changes below. Implementing the patch led me into a variety of sticky corners, so the patch includes several othe changes, some quite significant: * I made String wired-in, so that "foo" :: String rather than "foo" :: [Char] This improves error messages, and fixes #15679 * The pattern match checker relies on knowing about in-scope equality constraints, andd adds them to the desugarer's environment using addTyCsDs. But the co_fn in a FunBind was missed, and for some reason simple-subsumption ends up with dictionaries there. So I added a call to addTyCsDs. This is really part of #18049. * I moved the ic_telescope field out of Implication and into ForAllSkol instead. This is a nice win; just expresses the code much better. * There was a bug in GHC.Tc.TyCl.Instance.tcDataFamInstHeader. We called checkDataKindSig inside tc_kind_sig, /before/ solveEqualities and zonking. Obviously wrong, easily fixed. * solveLocalEqualitiesX: there was a whole mess in here, around failing fast enough. I discovered a bad latent bug where we could successfully kind-check a type signature, and use it, but have unsolved constraints that could fill in coercion holes in that signature -- aargh. It's all explained in Note [Failure in local type signatures] in GHC.Tc.Solver. Much better now. * I fixed a serious bug in anonymous type holes. IN f :: Int -> (forall a. a -> _) -> Int that "_" should be a unification variable at the /outer/ level; it cannot be instantiated to 'a'. This was plain wrong. New fields mode_lvl and mode_holes in TcTyMode, and auxiliary data type GHC.Tc.Gen.HsType.HoleMode. This fixes #16292, but makes no progress towards the more ambitious #16082 * I got sucked into an enormous refactoring of the reporting of equality errors in GHC.Tc.Errors, especially in mkEqErr1 mkTyVarEqErr misMatchMsg misMatchMsgOrCND In particular, the very tricky mkExpectedActualMsg function is gone. It took me a full day. But the result is far easier to understand. (Still not easy!) This led to various minor improvements in error output, and an enormous number of test-case error wibbles. One particular point: for occurs-check errors I now just say Can't match 'a' against '[a]' rather than using the intimidating language of "occurs check". * Pretty-printing AbsBinds Tests review * Eta expansions T11305: one eta expansion T12082: one eta expansion (undefined) T13585a: one eta expansion T3102: one eta expansion T3692: two eta expansions (tricky) T2239: two eta expansions T16473: one eta determ004: two eta expansions (undefined) annfail06: two eta (undefined) T17923: four eta expansions (a strange program indeed!) tcrun035: one eta expansion * Ambiguity check at higher rank. Now that we have simple subsumption, a type like f :: (forall a. Eq a => Int) -> Int is no longer ambiguous, because we could write g :: (forall a. Eq a => Int) -> Int g = f and it'd typecheck just fine. But f's type is a bit suspicious, and we might want to consider making the ambiguity check do a check on each sub-term. Meanwhile, these tests are accepted, whereas they were previously rejected as ambiguous: T7220a T15438 T10503 T9222 * Some more interesting error message wibbles T13381: Fine: one error (Int ~ Exp Int) rather than two (Int ~ Exp Int, Exp Int ~ Int) T9834: Small change in error (improvement) T10619: Improved T2414: Small change, due to order of unification, fine T2534: A very simple case in which a change of unification order means we get tow unsolved constraints instead of one tc211: bizarre impredicative tests; just accept this for now - - - - - 21 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Types.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Rename/Splice.hs - compiler/GHC/Tc/Errors.hs - compiler/GHC/Tc/Errors/Hole.hs - compiler/GHC/Tc/Gen/Arrow.hs - compiler/GHC/Tc/Gen/Bind.hs - compiler/GHC/Tc/Gen/Default.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Gen/Expr.hs-boot - compiler/GHC/Tc/Gen/Foreign.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Match.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a2fda5e1e85fa237c8aa0b2a08510d47bf2c3d4b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a2fda5e1e85fa237c8aa0b2a08510d47bf2c3d4b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 19 16:12:37 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Tue, 19 May 2020 12:12:37 -0400 Subject: [Git][ghc/ghc][wip/andreask/xchg_primop] WIP: Testcase Message-ID: <5ec405759e3a8_6e2612daa69496567@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/xchg_primop at Glasgow Haskell Compiler / GHC Commits: 616ca149 by Andreas Klebinger at 2020-05-19T18:11:14+02:00 WIP: Testcase - - - - - 2 changed files: - testsuite/tests/codeGen/should_run/all.T - + testsuite/tests/codeGen/should_run/cg_xchg001.hs Changes: ===================================== testsuite/tests/codeGen/should_run/all.T ===================================== @@ -205,3 +205,4 @@ test('T15892', test('T16617', normal, compile_and_run, ['']) test('T16449_2', exit_code(0), compile_and_run, ['']) test('T16846', [only_ways(['optasm']), exit_code(1)], compile_and_run, ['']) +test('cg_xchg001', normal, compile_and_run, ['']) \ No newline at end of file ===================================== testsuite/tests/codeGen/should_run/cg_xchg001.hs ===================================== @@ -0,0 +1,134 @@ +{-# LANGUAGE CPP, MagicHash, BlockArguments, UnboxedTuples #-} + +-- Tests for the atomic exchange primop. + +-- We initialize a value with 1, and then perform exchanges on it +-- with two different values. At the end all the values should still +-- be present. + +module Main ( main ) where + +import Data.Bits +import GHC.Int +import GHC.Prim +import GHC.Word +import Control.Monad +import Control.Concurrent +import Foreign.Marshal.Alloc +import Foreign.Storable +import Data.List + +import GHC.Exts +import GHC.Types + +#include "MachDeps.h" + +main = do + alloca $ \ptr_i -> do + poke ptr_i (1 :: Int) + w1 <- newEmptyMVar :: IO (MVar Int) + forkIO $ do + v <- swapN 50000 2 ptr_i + putMVar w1 v + + v2 <- swapN 50000 3 ptr_i + v1 <- takeMVar w1 + print $ sort $ [1,v1,v2] + +swapN :: Int -> Int -> Ptr Int -> IO Int +swapN 0 val ptr = return val +swapN n val ptr = do + val' <- swap ptr val + swapN (n-1) val' ptr + + +swap :: Ptr Int -> Int -> IO Int +swap (Ptr ptr) (I# val) = do + IO $ \s -> case (interlockedExchangeInt# ptr val s) of + (# s2, old_val #) -> (# s2, I# old_val #) + + +-- imul2 :: Int -> Int -> (Int,Int,Int) +-- imul2 (I# x) (I# y) = case timesInt2# x y of +-- (# c, h, l #) -> (I# c, I# h, I# l) + +-- checkImul2 :: Int -> Int -> IO () +-- checkImul2 x y = do +-- -- First we compare against Integer result. Note that this test will become +-- -- moot when Integer implementation will use this primitive +-- let +-- w2 = fromIntegral x * (fromIntegral y :: Integer) +-- (c,h,l) = imul2 x y +-- w = case c of +-- 0 -> fromIntegral l +-- _ -> int2ToInteger h l + +-- unless (w == w2) do +-- putStrLn $ mconcat +-- [ "Failed: " +-- , show x +-- , " * " +-- , show y +-- , "\n Got: " +-- , show w +-- , "\n Expected: " +-- , show w2 +-- ] + +-- -- Now we compare with a generic version using unsigned multiply. +-- -- This reimplements the fallback generic version that the compiler uses when +-- -- the mach-op isn't available so it'd better be correct too. +-- let (c',h',l') = genericIMul2 x y + +-- unless ((c,h,l) == (c',h',l')) do +-- putStrLn $ mconcat +-- [ "Failed: " +-- , show x +-- , " * " +-- , show y +-- , "\n Got: " +-- , show (c,h,l) +-- , "\n Expected: " +-- , show (c',h',l') +-- ] + +-- addWordC :: Word -> Word -> (Word,Word) +-- addWordC (W# x) (W# y) = case addWordC# x y of +-- (# l,c #) -> (W# (int2Word# c), W# l) + +-- int2ToInteger :: Int -> Int -> Integer +-- int2ToInteger h l +-- | h < 0 = case addWordC (complement (fromIntegral l)) 1 of +-- (c,w) -> -1 * word2ToInteger (c + complement (fromIntegral h)) w +-- | otherwise = word2ToInteger (fromIntegral h) (fromIntegral l) +-- where +-- word2ToInteger :: Word -> Word -> Integer +-- word2ToInteger x y = (fromIntegral x) `shiftL` WORD_SIZE_IN_BITS + fromIntegral y + +-- timesWord2 :: Word -> Word -> (Int,Int) +-- timesWord2 (W# x) (W# y) = case timesWord2# x y of +-- (# h, l #) -> (I# (word2Int# h), I# (word2Int# l)) + +-- genericIMul2 :: Int -> Int -> (Int,Int,Int) +-- genericIMul2 x y = (c,h,l) +-- where +-- (p,l) = timesWord2 (fromIntegral x) (fromIntegral y) +-- h = p - f x y - f y x +-- c = if h == carryFill l then 0 else 1 +-- f u v = carryFill u .&. v + +-- -- Return either 00..00 or FF..FF depending on the carry +-- carryFill :: Int -> Int +-- carryFill x = x `shiftR` (WORD_SIZE_IN_BITS - 1) + + +-- main = do +-- checkImul2 10 10 +-- checkImul2 10 (-10) +-- checkImul2 minBound (-1) +-- checkImul2 maxBound (-1) +-- checkImul2 minBound 0 +-- checkImul2 maxBound 0 +-- checkImul2 minBound minBound +-- checkImul2 minBound maxBound +-- checkImul2 maxBound maxBound View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/616ca149331800c7e21bc9e8311198aeca0c74cd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/616ca149331800c7e21bc9e8311198aeca0c74cd You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 19 16:16:46 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Tue, 19 May 2020 12:16:46 -0400 Subject: [Git][ghc/ghc][wip/andreask/xchg_primop] Add testcase. Message-ID: <5ec4066ebf5df_6e26119603b4974eb@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/xchg_primop at Glasgow Haskell Compiler / GHC Commits: 57952bd7 by Andreas Klebinger at 2020-05-19T18:15:42+02:00 Add testcase. - - - - - 2 changed files: - testsuite/tests/codeGen/should_run/all.T - + testsuite/tests/codeGen/should_run/cg_xchg001.hs Changes: ===================================== testsuite/tests/codeGen/should_run/all.T ===================================== @@ -205,3 +205,4 @@ test('T15892', test('T16617', normal, compile_and_run, ['']) test('T16449_2', exit_code(0), compile_and_run, ['']) test('T16846', [only_ways(['optasm']), exit_code(1)], compile_and_run, ['']) +test('cg_xchg001', normal, compile_and_run, ['']) \ No newline at end of file ===================================== testsuite/tests/codeGen/should_run/cg_xchg001.hs ===================================== @@ -0,0 +1,50 @@ +{-# LANGUAGE CPP, MagicHash, BlockArguments, UnboxedTuples #-} + +-- Tests for the atomic exchange primop. + +-- We initialize a value with 1, and then perform exchanges on it +-- with two different values. At the end all the values should still +-- be present. + +module Main ( main ) where + +import Data.Bits +import GHC.Int +import GHC.Prim +import GHC.Word +import Control.Monad +import Control.Concurrent +import Foreign.Marshal.Alloc +import Foreign.Storable +import Data.List + +import GHC.Exts +import GHC.Types + +#include "MachDeps.h" + +main = do + alloca $ \ptr_i -> do + poke ptr_i (1 :: Int) + w1 <- newEmptyMVar :: IO (MVar Int) + forkIO $ do + v <- swapN 50000 2 ptr_i + putMVar w1 v + + v2 <- swapN 50000 3 ptr_i + v1 <- takeMVar w1 + v0 <- peek ptr_i + print $ sort [v0,v1,v2] + +swapN :: Int -> Int -> Ptr Int -> IO Int +swapN 0 val ptr = return val +swapN n val ptr = do + val' <- swap ptr val + swapN (n-1) val' ptr + + +swap :: Ptr Int -> Int -> IO Int +swap (Ptr ptr) (I# val) = do + IO $ \s -> case (interlockedExchangeInt# ptr val s) of + (# s2, old_val #) -> (# s2, I# old_val #) + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/57952bd7bb4aa3d715e2725decab8bbf77a1ff55 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/57952bd7bb4aa3d715e2725decab8bbf77a1ff55 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 19 16:32:41 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Tue, 19 May 2020 12:32:41 -0400 Subject: [Git][ghc/ghc][wip/andreask/xchg_primop] winio: Add Atomic Exchange PrimOp and implement Atomic Ptr exchanges. Message-ID: <5ec40a2974ff8_6e26ddf25d41018b3@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/xchg_primop at Glasgow Haskell Compiler / GHC Commits: 6e059959 by Tamar Christina at 2020-05-19T18:30:01+02:00 winio: Add Atomic Exchange PrimOp and implement Atomic Ptr exchanges. - - - - - 21 changed files: - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm/CPrim.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.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/CodeGen.hs - compiler/GHC/StgToCmm/Prim.hs - configure.ac - includes/stg/Prim.h - libraries/base/GHC/Ptr.hs - libraries/ghc-prim/cbits/atomic.c - libraries/ghc-prim/changelog.md - rts/package.conf.in - rts/rts.cabal.in - testsuite/tests/codeGen/should_run/all.T - + testsuite/tests/codeGen/should_run/cg_xchg001.hs Changes: ===================================== compiler/GHC/Builtin/primops.txt.pp ===================================== @@ -2473,6 +2473,18 @@ primop WriteOffAddrOp_Word64 "writeWord64OffAddr#" GenPrimOp with has_side_effects = True can_fail = True +primop InterlockedExchange_Addr "interlockedExchangeAddr#" GenPrimOp + Addr# -> Addr# -> State# s -> (# State# s, Addr# #) + {The atomic exchange operation. Atomically exchanges the value at the first address + with the Addr# given as second argument. Implies a read barrier.} + with has_side_effects = True + +primop InterlockedExchange_Int "interlockedExchangeInt#" GenPrimOp + Addr# -> Int# -> State# s -> (# State# s, Int# #) + {The atomic exchange operation. Atomically exchanges the value at the address + with the given value. Returns the old value. Implies a read barrier.} + with has_side_effects = True + ------------------------------------------------------------------------ section "Mutable variables" {Operations on MutVar\#s.} ===================================== compiler/GHC/Cmm/MachOp.hs ===================================== @@ -632,6 +632,9 @@ data CallishMachOp | MO_AtomicRead Width | MO_AtomicWrite Width | MO_Cmpxchg Width + -- Should be an AtomicRMW variant eventually. + -- Sequential consistent. + | MO_Xchg Width deriving (Eq, Show) -- | The operation to perform atomically. ===================================== compiler/GHC/Cmm/Parser.y ===================================== @@ -1022,7 +1022,12 @@ callishMachOps = listToUFM $ ( "cmpxchg8", (MO_Cmpxchg W8,)), ( "cmpxchg16", (MO_Cmpxchg W16,)), ( "cmpxchg32", (MO_Cmpxchg W32,)), - ( "cmpxchg64", (MO_Cmpxchg W64,)) + ( "cmpxchg64", (MO_Cmpxchg W64,)), + + ( "xchg8", (MO_Xchg W8,)), + ( "xchg16", (MO_Xchg W16,)), + ( "xchg32", (MO_Xchg W32,)), + ( "xchg64", (MO_Xchg W64,)) -- ToDo: the rest, maybe -- edit: which rest? ===================================== compiler/GHC/CmmToAsm/CPrim.hs ===================================== @@ -4,6 +4,7 @@ module GHC.CmmToAsm.CPrim , atomicWriteLabel , atomicRMWLabel , cmpxchgLabel + , xchgLabel , popCntLabel , pdepLabel , pextLabel @@ -105,6 +106,15 @@ atomicRMWLabel w amop = "hs_atomic_" ++ pprFunName amop ++ pprWidth w pprFunName AMO_Or = "or" pprFunName AMO_Xor = "xor" +xchgLabel :: Width -> String +xchgLabel w = "hs_xchg" ++ pprWidth w + where + pprWidth W8 = "8" + pprWidth W16 = "16" + pprWidth W32 = "32" + pprWidth W64 = "64" + pprWidth w = pprPanic "xchgLabel: Unsupported word width " (ppr w) + cmpxchgLabel :: Width -> String cmpxchgLabel w = "hs_cmpxchg" ++ pprWidth w where ===================================== compiler/GHC/CmmToAsm/PPC/CodeGen.hs ===================================== @@ -2024,6 +2024,7 @@ genCCall' config gcp target dest_regs args MO_Ctz _ -> unsupported MO_AtomicRMW {} -> unsupported MO_Cmpxchg w -> (fsLit $ cmpxchgLabel w, False) + MO_Xchg w -> (fsLit $ xchgLabel w, False) MO_AtomicRead _ -> unsupported MO_AtomicWrite _ -> unsupported ===================================== compiler/GHC/CmmToAsm/SPARC/CodeGen.hs ===================================== @@ -677,6 +677,7 @@ outOfLineMachOp_table mop MO_Ctz w -> fsLit $ ctzLabel w MO_AtomicRMW w amop -> fsLit $ atomicRMWLabel w amop MO_Cmpxchg w -> fsLit $ cmpxchgLabel w + MO_Xchg w -> fsLit $ xchgLabel w MO_AtomicRead w -> fsLit $ atomicReadLabel w MO_AtomicWrite w -> fsLit $ atomicWriteLabel w ===================================== compiler/GHC/CmmToAsm/X86/CodeGen.hs ===================================== @@ -2518,6 +2518,22 @@ genCCall' _ is32Bit (PrimTarget (MO_Cmpxchg width)) [dst] [addr, old, new] _ = d where format = intFormat width +genCCall' config is32Bit (PrimTarget (MO_Xchg width)) [dst] [addr, value] _ + | (is32Bit && width == W64) = panic "gencCall: 64bit atomic exchange not supported on 32bit platforms" + | otherwise = do + let dst_r = getRegisterReg platform (CmmLocal dst) + Amode amode addr_code <- getSimpleAmode is32Bit addr + (newval, newval_code) <- getSomeReg value + -- Copy the value into the target register, perform the exchange. + let code = toOL + [ MOV format (OpReg newval) (OpReg dst_r) + , XCHG format (OpAddr amode) dst_r + ] + return $ addr_code `appOL` newval_code `appOL` code + where + format = intFormat width + platform = ncgPlatform config + genCCall' _ is32Bit target dest_regs args bid = do platform <- ncgPlatform <$> getConfig case (target, dest_regs) of @@ -3213,6 +3229,7 @@ outOfLineCmmOp bid mop res args MO_AtomicRead _ -> fsLit "atomicread" MO_AtomicWrite _ -> fsLit "atomicwrite" MO_Cmpxchg _ -> fsLit "cmpxchg" + MO_Xchg _ -> should_be_inline MO_UF_Conv _ -> unsupported @@ -3232,6 +3249,11 @@ outOfLineCmmOp bid mop res args (MO_Prefetch_Data _ ) -> unsupported unsupported = panic ("outOfLineCmmOp: " ++ show mop ++ " not supported here") + -- If we generate a call for the given primop + -- something went wrong. + should_be_inline = panic ("outOfLineCmmOp: " ++ show mop + ++ " should be handled inline") + -- ----------------------------------------------------------------------------- -- Generating a table-branch ===================================== compiler/GHC/CmmToAsm/X86/Instr.hs ===================================== @@ -329,6 +329,7 @@ data Instr | LOCK Instr -- lock prefix | XADD Format Operand Operand -- src (r), dst (r/m) | CMPXCHG Format Operand Operand -- src (r), dst (r/m), eax implicit + | XCHG Format Operand Reg -- src (r/m), dst (r/m) | MFENCE data PrefetchVariant = NTA | Lvl0 | Lvl1 | Lvl2 @@ -431,6 +432,7 @@ x86_regUsageOfInstr platform instr LOCK i -> x86_regUsageOfInstr platform i XADD _ src dst -> usageMM src dst CMPXCHG _ src dst -> usageRMM src dst (OpReg eax) + XCHG _ src dst -> usageMM src (OpReg dst) MFENCE -> noUsage _other -> panic "regUsage: unrecognised instr" @@ -460,6 +462,7 @@ x86_regUsageOfInstr platform instr usageMM :: Operand -> Operand -> RegUsage usageMM (OpReg src) (OpReg dst) = mkRU [src, dst] [src, dst] usageMM (OpReg src) (OpAddr ea) = mkRU (use_EA ea [src]) [src] + usageMM (OpAddr ea) (OpReg dst) = mkRU (use_EA ea [dst]) [dst] usageMM _ _ = panic "X86.RegInfo.usageMM: no match" -- 3 operand form; first operand Read; second Modified; third Modified @@ -589,6 +592,7 @@ x86_patchRegsOfInstr instr env LOCK i -> LOCK (x86_patchRegsOfInstr i env) XADD fmt src dst -> patch2 (XADD fmt) src dst CMPXCHG fmt src dst -> patch2 (CMPXCHG fmt) src dst + XCHG fmt src dst -> XCHG fmt (patchOp src) (env dst) MFENCE -> instr _other -> panic "patchRegs: unrecognised instr" ===================================== compiler/GHC/CmmToAsm/X86/Ppr.hs ===================================== @@ -824,6 +824,9 @@ pprInstr platform i = case i of SETCC cond op -> pprCondInstr (sLit "set") cond (pprOperand platform II8 op) + XCHG format src val + -> pprFormatOpReg (sLit "xchg") format src val + JXX cond blockid -> pprCondInstr (sLit "j") cond (ppr lab) where lab = blockLbl blockid ===================================== compiler/GHC/CmmToC.hs ===================================== @@ -831,6 +831,7 @@ pprCallishMachOp_for_C mop (MO_Ctz w) -> ptext (sLit $ ctzLabel w) (MO_AtomicRMW w amop) -> ptext (sLit $ atomicRMWLabel w amop) (MO_Cmpxchg w) -> ptext (sLit $ cmpxchgLabel w) + (MO_Xchg w) -> ptext (sLit $ xchgLabel w) (MO_AtomicRead w) -> ptext (sLit $ atomicReadLabel w) (MO_AtomicWrite w) -> ptext (sLit $ atomicWriteLabel w) (MO_UF_Conv w) -> ptext (sLit $ word2FloatLabel w) ===================================== compiler/GHC/CmmToLlvm/CodeGen.hs ===================================== @@ -281,6 +281,14 @@ genCall (PrimTarget (MO_Cmpxchg _width)) retVar' <- doExprW targetTy $ ExtractV retVar 0 statement $ Store retVar' dstVar +genCall (PrimTarget (MO_Xchg _width)) [] [addr, val] = runStmtsDecls $ do + addrVar <- exprToVarW addr + valVar <- exprToVarW val + let ptrTy = pLift $ getVarType valVar + ptrExpr = Cast LM_Inttoptr addrVar ptrTy + ptrVar <- doExprW ptrTy ptrExpr + statement $ Expr $ AtomicRMW LAO_Xchg ptrVar valVar SyncSeqCst + genCall (PrimTarget (MO_AtomicWrite _width)) [] [addr, val] = runStmtsDecls $ do addrVar <- exprToVarW addr valVar <- exprToVarW val @@ -856,6 +864,7 @@ cmmPrimOpFunctions mop = do MO_AtomicRMW _ _ -> unsupported MO_AtomicWrite _ -> unsupported MO_Cmpxchg _ -> unsupported + MO_Xchg _ -> unsupported -- | Tail function calls genJump :: CmmExpr -> [GlobalReg] -> LlvmM StmtData ===================================== compiler/GHC/StgToCmm/Prim.hs ===================================== @@ -856,6 +856,12 @@ emitPrimOp dflags = \case Word2DoubleOp -> \[w] -> opAllDone $ \[res] -> do emitPrimCall [res] (MO_UF_Conv W64) [w] +-- Atomic operations + InterlockedExchange_Addr -> \[src, value] -> opAllDone $ \[res] -> + emitPrimCall [res] (MO_Xchg (wordWidth platform)) [src, value] + InterlockedExchange_Int -> \[src, value] -> opAllDone $ \[res] -> + emitPrimCall [res] (MO_Xchg (wordWidth platform)) [src, value] + -- SIMD primops (VecBroadcastOp vcat n w) -> \[e] -> opAllDone $ \[res] -> do checkVecCompatibility dflags vcat n w ===================================== configure.ac ===================================== @@ -730,6 +730,8 @@ dnl unregisterised, Sparc, and PPC backends. FP_GCC_SUPPORTS__ATOMICS if test $CONF_GCC_SUPPORTS__ATOMICS = YES ; then AC_DEFINE([HAVE_C11_ATOMICS], [1], [Does GCC support __atomic primitives?]) +else + AC_MSG_ERROR([C compiler needs to support __atomic primitives.]) fi FP_GCC_EXTRA_FLAGS ===================================== includes/stg/Prim.h ===================================== @@ -50,6 +50,10 @@ void hs_atomicwrite8(StgWord x, StgWord val); void hs_atomicwrite16(StgWord x, StgWord val); void hs_atomicwrite32(StgWord x, StgWord val); void hs_atomicwrite64(StgWord x, StgWord64 val); +StgWord hs_xchg8(StgPtr x, StgWord val); +StgWord hs_xchg16(StgPtr x, StgWord val); +StgWord hs_xchg32(StgPtr x, StgWord val); +StgWord hs_xchg64(StgPtr x, StgWord val); /* libraries/ghc-prim/cbits/bswap.c */ StgWord16 hs_bswap16(StgWord16 x); ===================================== libraries/base/GHC/Ptr.hs ===================================== @@ -1,5 +1,6 @@ {-# LANGUAGE Unsafe #-} {-# LANGUAGE CPP, NoImplicitPrelude, MagicHash, RoleAnnotations #-} +{-# LANGUAGE UnboxedTuples #-} {-# OPTIONS_HADDOCK not-home #-} ----------------------------------------------------------------------------- @@ -22,7 +23,10 @@ module GHC.Ptr ( nullFunPtr, castFunPtr, -- * Unsafe functions - castFunPtrToPtr, castPtrToFunPtr + castFunPtrToPtr, castPtrToFunPtr, + + -- * Atomic operations + exchangePtr ) where import GHC.Base @@ -162,6 +166,15 @@ castFunPtrToPtr (FunPtr addr) = Ptr addr castPtrToFunPtr :: Ptr a -> FunPtr b castPtrToFunPtr (Ptr addr) = FunPtr addr +------------------------------------------------------------------------ +-- Atomic operations for Ptr + +{-# INLINE exchangePtr #-} +exchangePtr :: Ptr (Ptr a) -> Ptr b -> IO (Ptr c) +exchangePtr (Ptr dst) (Ptr val) = + IO $ \s -> + case (interlockedExchangeAddr# dst val s) of + (# s2, old_val #) -> (# s2, Ptr old_val #) ------------------------------------------------------------------------ -- Show instances for Ptr and FunPtr ===================================== libraries/ghc-prim/cbits/atomic.c ===================================== @@ -318,6 +318,39 @@ hs_cmpxchg64(StgWord x, StgWord64 old, StgWord64 new) } #endif +// Atomic exchange operations + +extern StgWord hs_xchg8(StgPtr x, StgWord val); +StgWord +hs_xchg8(StgPtr x, StgWord val) +{ + return (StgWord) __atomic_exchange_1((volatile StgPtr) x, val, __ATOMIC_SEQ_CST); +} + +extern StgWord hs_xchg16(StgPtr x, StgWord val); +StgWord +hs_xchg16(StgPtr x, StgWord val) +{ + return (StgWord) __atomic_exchange_2(x, val, __ATOMIC_SEQ_CST); +} + +extern StgWord hs_xchg32(StgPtr x, StgWord val); +StgWord +hs_xchg32(StgPtr x, StgWord val) +{ + return (StgWord) __atomic_exchange_4((volatile StgPtr) x, val, __ATOMIC_SEQ_CST); +} + +#if WORD_SIZE_IN_BITS == 64 +//GCC provides this even on 32bit, but StgWord is still 32 bits. +extern StgWord hs_xchg64(StgPtr x, StgWord val); +StgWord +hs_xchg64(StgPtr x, StgWord val) +{ + return (StgWord) __atomic_exchange_8((volatile StgPtr) x, val, __ATOMIC_SEQ_CST); +} +#endif + // AtomicReadByteArrayOp_Int // Implies a full memory barrier (see compiler/GHC/Builtin/primops.txt.pp) // __ATOMIC_SEQ_CST: Full barrier in both directions (hoisting and sinking ===================================== libraries/ghc-prim/changelog.md ===================================== @@ -1,3 +1,12 @@ +## TBD + +- Shipped with GHC 8.12.1 + +- Add primops for atomic exchange: + + interlockedExchangeAddr# :: Addr# -> Addr# -> State# s -> (# State# s, Addr# #) + interlockedExchangeInt# :: Addr# -> Int# -> State# s -> (# State# s, Int# #) + ## 0.6.1 (edit as necessary) - Shipped with GHC 8.10.1 ===================================== rts/package.conf.in ===================================== @@ -168,6 +168,10 @@ ld-options: #if WORD_SIZE_IN_BITS == 64 , "-Wl,-u,_hs_cmpxchg64" #endif + , "-Wl,-u,_hs_xchg8" + , "-Wl,-u,_hs_xchg16" + , "-Wl,-u,_hs_xchg32" + , "-Wl,-u,_hs_xchg64" , "-Wl,-u,_hs_atomicread8" , "-Wl,-u,_hs_atomicread16" , "-Wl,-u,_hs_atomicread32" @@ -273,6 +277,10 @@ ld-options: #if WORD_SIZE_IN_BITS == 64 , "-Wl,-u,hs_cmpxchg64" #endif + , "-Wl,-u,hs_xchg8" + , "-Wl,-u,hs_xchg16" + , "-Wl,-u,hs_xchg32" + , "-Wl,-u,hs_xchg64" , "-Wl,-u,hs_atomicread8" , "-Wl,-u,hs_atomicread16" , "-Wl,-u,hs_atomicread32" ===================================== rts/rts.cabal.in ===================================== @@ -264,6 +264,10 @@ library "-Wl,-u,_hs_cmpxchg8" "-Wl,-u,_hs_cmpxchg16" "-Wl,-u,_hs_cmpxchg32" + "-Wl,-u,_hs_xchg8" + "-Wl,-u,_hs_xchg16" + "-Wl,-u,_hs_xchg32" + "-Wl,-u,_hs_xchg64" "-Wl,-u,_hs_atomicread8" "-Wl,-u,_hs_atomicread16" "-Wl,-u,_hs_atomicread32" @@ -339,6 +343,10 @@ library "-Wl,-u,hs_cmpxchg8" "-Wl,-u,hs_cmpxchg16" "-Wl,-u,hs_cmpxchg32" + "-Wl,-u,hs_xchg8" + "-Wl,-u,hs_xchg16" + "-Wl,-u,hs_xchg32" + "-Wl,-u,hs_xchg64" "-Wl,-u,hs_atomicread8" "-Wl,-u,hs_atomicread16" "-Wl,-u,hs_atomicread32" ===================================== testsuite/tests/codeGen/should_run/all.T ===================================== @@ -205,3 +205,4 @@ test('T15892', test('T16617', normal, compile_and_run, ['']) test('T16449_2', exit_code(0), compile_and_run, ['']) test('T16846', [only_ways(['optasm']), exit_code(1)], compile_and_run, ['']) +test('cg_xchg001', normal, compile_and_run, ['']) \ No newline at end of file ===================================== testsuite/tests/codeGen/should_run/cg_xchg001.hs ===================================== @@ -0,0 +1,51 @@ +{-# LANGUAGE CPP, MagicHash, BlockArguments, UnboxedTuples #-} + +-- Tests for the atomic exchange primop. + +-- We initialize a value with 1, and then perform exchanges on it +-- with two different values. At the end all the values should still +-- be present. + +module Main ( main ) where + +import Data.Bits +import GHC.Int +import GHC.Prim +import GHC.Word +import Control.Monad +import Control.Concurrent +import Foreign.Marshal.Alloc +import Foreign.Storable +import Data.List + +import GHC.Exts +import GHC.Types + +#include "MachDeps.h" + +main = do + alloca $ \ptr_i -> do + poke ptr_i (1 :: Int) + w1 <- newEmptyMVar :: IO (MVar Int) + forkIO $ do + v <- swapN 50000 2 ptr_i + putMVar w1 v + + v2 <- swapN 50000 3 ptr_i + v1 <- takeMVar w1 + v0 <- peek ptr_i + -- Should be [1,2,3] + print $ sort [v0,v1,v2] + +swapN :: Int -> Int -> Ptr Int -> IO Int +swapN 0 val ptr = return val +swapN n val ptr = do + val' <- swap ptr val + swapN (n-1) val' ptr + + +swap :: Ptr Int -> Int -> IO Int +swap (Ptr ptr) (I# val) = do + IO $ \s -> case (interlockedExchangeInt# ptr val s) of + (# s2, old_val #) -> (# s2, I# old_val #) + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6e059959953ef7759bbabdab7b396ca313ec05ae -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6e059959953ef7759bbabdab7b396ca313ec05ae You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 19 16:32:57 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Tue, 19 May 2020 12:32:57 -0400 Subject: [Git][ghc/ghc][wip/andreask/xchg_primop] winio: Add Atomic Exchange PrimOp and implement Atomic Ptr exchanges. Message-ID: <5ec40a3954540_6e26123486d810238b@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/xchg_primop at Glasgow Haskell Compiler / GHC Commits: 278330b5 by Tamar Christina at 2020-05-19T18:30:53+02:00 winio: Add Atomic Exchange PrimOp and implement Atomic Ptr exchanges. The initial version was rewritten by Tamar Christina. It was rewritten in large parts by Andreas Klebinger. - - - - - 21 changed files: - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm/CPrim.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.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/CodeGen.hs - compiler/GHC/StgToCmm/Prim.hs - configure.ac - includes/stg/Prim.h - libraries/base/GHC/Ptr.hs - libraries/ghc-prim/cbits/atomic.c - libraries/ghc-prim/changelog.md - rts/package.conf.in - rts/rts.cabal.in - testsuite/tests/codeGen/should_run/all.T - + testsuite/tests/codeGen/should_run/cg_xchg001.hs Changes: ===================================== compiler/GHC/Builtin/primops.txt.pp ===================================== @@ -2473,6 +2473,18 @@ primop WriteOffAddrOp_Word64 "writeWord64OffAddr#" GenPrimOp with has_side_effects = True can_fail = True +primop InterlockedExchange_Addr "interlockedExchangeAddr#" GenPrimOp + Addr# -> Addr# -> State# s -> (# State# s, Addr# #) + {The atomic exchange operation. Atomically exchanges the value at the first address + with the Addr# given as second argument. Implies a read barrier.} + with has_side_effects = True + +primop InterlockedExchange_Int "interlockedExchangeInt#" GenPrimOp + Addr# -> Int# -> State# s -> (# State# s, Int# #) + {The atomic exchange operation. Atomically exchanges the value at the address + with the given value. Returns the old value. Implies a read barrier.} + with has_side_effects = True + ------------------------------------------------------------------------ section "Mutable variables" {Operations on MutVar\#s.} ===================================== compiler/GHC/Cmm/MachOp.hs ===================================== @@ -632,6 +632,9 @@ data CallishMachOp | MO_AtomicRead Width | MO_AtomicWrite Width | MO_Cmpxchg Width + -- Should be an AtomicRMW variant eventually. + -- Sequential consistent. + | MO_Xchg Width deriving (Eq, Show) -- | The operation to perform atomically. ===================================== compiler/GHC/Cmm/Parser.y ===================================== @@ -1022,7 +1022,12 @@ callishMachOps = listToUFM $ ( "cmpxchg8", (MO_Cmpxchg W8,)), ( "cmpxchg16", (MO_Cmpxchg W16,)), ( "cmpxchg32", (MO_Cmpxchg W32,)), - ( "cmpxchg64", (MO_Cmpxchg W64,)) + ( "cmpxchg64", (MO_Cmpxchg W64,)), + + ( "xchg8", (MO_Xchg W8,)), + ( "xchg16", (MO_Xchg W16,)), + ( "xchg32", (MO_Xchg W32,)), + ( "xchg64", (MO_Xchg W64,)) -- ToDo: the rest, maybe -- edit: which rest? ===================================== compiler/GHC/CmmToAsm/CPrim.hs ===================================== @@ -4,6 +4,7 @@ module GHC.CmmToAsm.CPrim , atomicWriteLabel , atomicRMWLabel , cmpxchgLabel + , xchgLabel , popCntLabel , pdepLabel , pextLabel @@ -105,6 +106,15 @@ atomicRMWLabel w amop = "hs_atomic_" ++ pprFunName amop ++ pprWidth w pprFunName AMO_Or = "or" pprFunName AMO_Xor = "xor" +xchgLabel :: Width -> String +xchgLabel w = "hs_xchg" ++ pprWidth w + where + pprWidth W8 = "8" + pprWidth W16 = "16" + pprWidth W32 = "32" + pprWidth W64 = "64" + pprWidth w = pprPanic "xchgLabel: Unsupported word width " (ppr w) + cmpxchgLabel :: Width -> String cmpxchgLabel w = "hs_cmpxchg" ++ pprWidth w where ===================================== compiler/GHC/CmmToAsm/PPC/CodeGen.hs ===================================== @@ -2024,6 +2024,7 @@ genCCall' config gcp target dest_regs args MO_Ctz _ -> unsupported MO_AtomicRMW {} -> unsupported MO_Cmpxchg w -> (fsLit $ cmpxchgLabel w, False) + MO_Xchg w -> (fsLit $ xchgLabel w, False) MO_AtomicRead _ -> unsupported MO_AtomicWrite _ -> unsupported ===================================== compiler/GHC/CmmToAsm/SPARC/CodeGen.hs ===================================== @@ -677,6 +677,7 @@ outOfLineMachOp_table mop MO_Ctz w -> fsLit $ ctzLabel w MO_AtomicRMW w amop -> fsLit $ atomicRMWLabel w amop MO_Cmpxchg w -> fsLit $ cmpxchgLabel w + MO_Xchg w -> fsLit $ xchgLabel w MO_AtomicRead w -> fsLit $ atomicReadLabel w MO_AtomicWrite w -> fsLit $ atomicWriteLabel w ===================================== compiler/GHC/CmmToAsm/X86/CodeGen.hs ===================================== @@ -2518,6 +2518,22 @@ genCCall' _ is32Bit (PrimTarget (MO_Cmpxchg width)) [dst] [addr, old, new] _ = d where format = intFormat width +genCCall' config is32Bit (PrimTarget (MO_Xchg width)) [dst] [addr, value] _ + | (is32Bit && width == W64) = panic "gencCall: 64bit atomic exchange not supported on 32bit platforms" + | otherwise = do + let dst_r = getRegisterReg platform (CmmLocal dst) + Amode amode addr_code <- getSimpleAmode is32Bit addr + (newval, newval_code) <- getSomeReg value + -- Copy the value into the target register, perform the exchange. + let code = toOL + [ MOV format (OpReg newval) (OpReg dst_r) + , XCHG format (OpAddr amode) dst_r + ] + return $ addr_code `appOL` newval_code `appOL` code + where + format = intFormat width + platform = ncgPlatform config + genCCall' _ is32Bit target dest_regs args bid = do platform <- ncgPlatform <$> getConfig case (target, dest_regs) of @@ -3213,6 +3229,7 @@ outOfLineCmmOp bid mop res args MO_AtomicRead _ -> fsLit "atomicread" MO_AtomicWrite _ -> fsLit "atomicwrite" MO_Cmpxchg _ -> fsLit "cmpxchg" + MO_Xchg _ -> should_be_inline MO_UF_Conv _ -> unsupported @@ -3232,6 +3249,11 @@ outOfLineCmmOp bid mop res args (MO_Prefetch_Data _ ) -> unsupported unsupported = panic ("outOfLineCmmOp: " ++ show mop ++ " not supported here") + -- If we generate a call for the given primop + -- something went wrong. + should_be_inline = panic ("outOfLineCmmOp: " ++ show mop + ++ " should be handled inline") + -- ----------------------------------------------------------------------------- -- Generating a table-branch ===================================== compiler/GHC/CmmToAsm/X86/Instr.hs ===================================== @@ -329,6 +329,7 @@ data Instr | LOCK Instr -- lock prefix | XADD Format Operand Operand -- src (r), dst (r/m) | CMPXCHG Format Operand Operand -- src (r), dst (r/m), eax implicit + | XCHG Format Operand Reg -- src (r/m), dst (r/m) | MFENCE data PrefetchVariant = NTA | Lvl0 | Lvl1 | Lvl2 @@ -431,6 +432,7 @@ x86_regUsageOfInstr platform instr LOCK i -> x86_regUsageOfInstr platform i XADD _ src dst -> usageMM src dst CMPXCHG _ src dst -> usageRMM src dst (OpReg eax) + XCHG _ src dst -> usageMM src (OpReg dst) MFENCE -> noUsage _other -> panic "regUsage: unrecognised instr" @@ -460,6 +462,7 @@ x86_regUsageOfInstr platform instr usageMM :: Operand -> Operand -> RegUsage usageMM (OpReg src) (OpReg dst) = mkRU [src, dst] [src, dst] usageMM (OpReg src) (OpAddr ea) = mkRU (use_EA ea [src]) [src] + usageMM (OpAddr ea) (OpReg dst) = mkRU (use_EA ea [dst]) [dst] usageMM _ _ = panic "X86.RegInfo.usageMM: no match" -- 3 operand form; first operand Read; second Modified; third Modified @@ -589,6 +592,7 @@ x86_patchRegsOfInstr instr env LOCK i -> LOCK (x86_patchRegsOfInstr i env) XADD fmt src dst -> patch2 (XADD fmt) src dst CMPXCHG fmt src dst -> patch2 (CMPXCHG fmt) src dst + XCHG fmt src dst -> XCHG fmt (patchOp src) (env dst) MFENCE -> instr _other -> panic "patchRegs: unrecognised instr" ===================================== compiler/GHC/CmmToAsm/X86/Ppr.hs ===================================== @@ -824,6 +824,9 @@ pprInstr platform i = case i of SETCC cond op -> pprCondInstr (sLit "set") cond (pprOperand platform II8 op) + XCHG format src val + -> pprFormatOpReg (sLit "xchg") format src val + JXX cond blockid -> pprCondInstr (sLit "j") cond (ppr lab) where lab = blockLbl blockid ===================================== compiler/GHC/CmmToC.hs ===================================== @@ -831,6 +831,7 @@ pprCallishMachOp_for_C mop (MO_Ctz w) -> ptext (sLit $ ctzLabel w) (MO_AtomicRMW w amop) -> ptext (sLit $ atomicRMWLabel w amop) (MO_Cmpxchg w) -> ptext (sLit $ cmpxchgLabel w) + (MO_Xchg w) -> ptext (sLit $ xchgLabel w) (MO_AtomicRead w) -> ptext (sLit $ atomicReadLabel w) (MO_AtomicWrite w) -> ptext (sLit $ atomicWriteLabel w) (MO_UF_Conv w) -> ptext (sLit $ word2FloatLabel w) ===================================== compiler/GHC/CmmToLlvm/CodeGen.hs ===================================== @@ -281,6 +281,14 @@ genCall (PrimTarget (MO_Cmpxchg _width)) retVar' <- doExprW targetTy $ ExtractV retVar 0 statement $ Store retVar' dstVar +genCall (PrimTarget (MO_Xchg _width)) [] [addr, val] = runStmtsDecls $ do + addrVar <- exprToVarW addr + valVar <- exprToVarW val + let ptrTy = pLift $ getVarType valVar + ptrExpr = Cast LM_Inttoptr addrVar ptrTy + ptrVar <- doExprW ptrTy ptrExpr + statement $ Expr $ AtomicRMW LAO_Xchg ptrVar valVar SyncSeqCst + genCall (PrimTarget (MO_AtomicWrite _width)) [] [addr, val] = runStmtsDecls $ do addrVar <- exprToVarW addr valVar <- exprToVarW val @@ -856,6 +864,7 @@ cmmPrimOpFunctions mop = do MO_AtomicRMW _ _ -> unsupported MO_AtomicWrite _ -> unsupported MO_Cmpxchg _ -> unsupported + MO_Xchg _ -> unsupported -- | Tail function calls genJump :: CmmExpr -> [GlobalReg] -> LlvmM StmtData ===================================== compiler/GHC/StgToCmm/Prim.hs ===================================== @@ -856,6 +856,12 @@ emitPrimOp dflags = \case Word2DoubleOp -> \[w] -> opAllDone $ \[res] -> do emitPrimCall [res] (MO_UF_Conv W64) [w] +-- Atomic operations + InterlockedExchange_Addr -> \[src, value] -> opAllDone $ \[res] -> + emitPrimCall [res] (MO_Xchg (wordWidth platform)) [src, value] + InterlockedExchange_Int -> \[src, value] -> opAllDone $ \[res] -> + emitPrimCall [res] (MO_Xchg (wordWidth platform)) [src, value] + -- SIMD primops (VecBroadcastOp vcat n w) -> \[e] -> opAllDone $ \[res] -> do checkVecCompatibility dflags vcat n w ===================================== configure.ac ===================================== @@ -730,6 +730,8 @@ dnl unregisterised, Sparc, and PPC backends. FP_GCC_SUPPORTS__ATOMICS if test $CONF_GCC_SUPPORTS__ATOMICS = YES ; then AC_DEFINE([HAVE_C11_ATOMICS], [1], [Does GCC support __atomic primitives?]) +else + AC_MSG_ERROR([C compiler needs to support __atomic primitives.]) fi FP_GCC_EXTRA_FLAGS ===================================== includes/stg/Prim.h ===================================== @@ -50,6 +50,10 @@ void hs_atomicwrite8(StgWord x, StgWord val); void hs_atomicwrite16(StgWord x, StgWord val); void hs_atomicwrite32(StgWord x, StgWord val); void hs_atomicwrite64(StgWord x, StgWord64 val); +StgWord hs_xchg8(StgPtr x, StgWord val); +StgWord hs_xchg16(StgPtr x, StgWord val); +StgWord hs_xchg32(StgPtr x, StgWord val); +StgWord hs_xchg64(StgPtr x, StgWord val); /* libraries/ghc-prim/cbits/bswap.c */ StgWord16 hs_bswap16(StgWord16 x); ===================================== libraries/base/GHC/Ptr.hs ===================================== @@ -1,5 +1,6 @@ {-# LANGUAGE Unsafe #-} {-# LANGUAGE CPP, NoImplicitPrelude, MagicHash, RoleAnnotations #-} +{-# LANGUAGE UnboxedTuples #-} {-# OPTIONS_HADDOCK not-home #-} ----------------------------------------------------------------------------- @@ -22,7 +23,10 @@ module GHC.Ptr ( nullFunPtr, castFunPtr, -- * Unsafe functions - castFunPtrToPtr, castPtrToFunPtr + castFunPtrToPtr, castPtrToFunPtr, + + -- * Atomic operations + exchangePtr ) where import GHC.Base @@ -162,6 +166,15 @@ castFunPtrToPtr (FunPtr addr) = Ptr addr castPtrToFunPtr :: Ptr a -> FunPtr b castPtrToFunPtr (Ptr addr) = FunPtr addr +------------------------------------------------------------------------ +-- Atomic operations for Ptr + +{-# INLINE exchangePtr #-} +exchangePtr :: Ptr (Ptr a) -> Ptr b -> IO (Ptr c) +exchangePtr (Ptr dst) (Ptr val) = + IO $ \s -> + case (interlockedExchangeAddr# dst val s) of + (# s2, old_val #) -> (# s2, Ptr old_val #) ------------------------------------------------------------------------ -- Show instances for Ptr and FunPtr ===================================== libraries/ghc-prim/cbits/atomic.c ===================================== @@ -318,6 +318,39 @@ hs_cmpxchg64(StgWord x, StgWord64 old, StgWord64 new) } #endif +// Atomic exchange operations + +extern StgWord hs_xchg8(StgPtr x, StgWord val); +StgWord +hs_xchg8(StgPtr x, StgWord val) +{ + return (StgWord) __atomic_exchange_1((volatile StgPtr) x, val, __ATOMIC_SEQ_CST); +} + +extern StgWord hs_xchg16(StgPtr x, StgWord val); +StgWord +hs_xchg16(StgPtr x, StgWord val) +{ + return (StgWord) __atomic_exchange_2(x, val, __ATOMIC_SEQ_CST); +} + +extern StgWord hs_xchg32(StgPtr x, StgWord val); +StgWord +hs_xchg32(StgPtr x, StgWord val) +{ + return (StgWord) __atomic_exchange_4((volatile StgPtr) x, val, __ATOMIC_SEQ_CST); +} + +#if WORD_SIZE_IN_BITS == 64 +//GCC provides this even on 32bit, but StgWord is still 32 bits. +extern StgWord hs_xchg64(StgPtr x, StgWord val); +StgWord +hs_xchg64(StgPtr x, StgWord val) +{ + return (StgWord) __atomic_exchange_8((volatile StgPtr) x, val, __ATOMIC_SEQ_CST); +} +#endif + // AtomicReadByteArrayOp_Int // Implies a full memory barrier (see compiler/GHC/Builtin/primops.txt.pp) // __ATOMIC_SEQ_CST: Full barrier in both directions (hoisting and sinking ===================================== libraries/ghc-prim/changelog.md ===================================== @@ -1,3 +1,12 @@ +## TBD + +- Shipped with GHC 8.12.1 + +- Add primops for atomic exchange: + + interlockedExchangeAddr# :: Addr# -> Addr# -> State# s -> (# State# s, Addr# #) + interlockedExchangeInt# :: Addr# -> Int# -> State# s -> (# State# s, Int# #) + ## 0.6.1 (edit as necessary) - Shipped with GHC 8.10.1 ===================================== rts/package.conf.in ===================================== @@ -168,6 +168,10 @@ ld-options: #if WORD_SIZE_IN_BITS == 64 , "-Wl,-u,_hs_cmpxchg64" #endif + , "-Wl,-u,_hs_xchg8" + , "-Wl,-u,_hs_xchg16" + , "-Wl,-u,_hs_xchg32" + , "-Wl,-u,_hs_xchg64" , "-Wl,-u,_hs_atomicread8" , "-Wl,-u,_hs_atomicread16" , "-Wl,-u,_hs_atomicread32" @@ -273,6 +277,10 @@ ld-options: #if WORD_SIZE_IN_BITS == 64 , "-Wl,-u,hs_cmpxchg64" #endif + , "-Wl,-u,hs_xchg8" + , "-Wl,-u,hs_xchg16" + , "-Wl,-u,hs_xchg32" + , "-Wl,-u,hs_xchg64" , "-Wl,-u,hs_atomicread8" , "-Wl,-u,hs_atomicread16" , "-Wl,-u,hs_atomicread32" ===================================== rts/rts.cabal.in ===================================== @@ -264,6 +264,10 @@ library "-Wl,-u,_hs_cmpxchg8" "-Wl,-u,_hs_cmpxchg16" "-Wl,-u,_hs_cmpxchg32" + "-Wl,-u,_hs_xchg8" + "-Wl,-u,_hs_xchg16" + "-Wl,-u,_hs_xchg32" + "-Wl,-u,_hs_xchg64" "-Wl,-u,_hs_atomicread8" "-Wl,-u,_hs_atomicread16" "-Wl,-u,_hs_atomicread32" @@ -339,6 +343,10 @@ library "-Wl,-u,hs_cmpxchg8" "-Wl,-u,hs_cmpxchg16" "-Wl,-u,hs_cmpxchg32" + "-Wl,-u,hs_xchg8" + "-Wl,-u,hs_xchg16" + "-Wl,-u,hs_xchg32" + "-Wl,-u,hs_xchg64" "-Wl,-u,hs_atomicread8" "-Wl,-u,hs_atomicread16" "-Wl,-u,hs_atomicread32" ===================================== testsuite/tests/codeGen/should_run/all.T ===================================== @@ -205,3 +205,4 @@ test('T15892', test('T16617', normal, compile_and_run, ['']) test('T16449_2', exit_code(0), compile_and_run, ['']) test('T16846', [only_ways(['optasm']), exit_code(1)], compile_and_run, ['']) +test('cg_xchg001', normal, compile_and_run, ['']) \ No newline at end of file ===================================== testsuite/tests/codeGen/should_run/cg_xchg001.hs ===================================== @@ -0,0 +1,51 @@ +{-# LANGUAGE CPP, MagicHash, BlockArguments, UnboxedTuples #-} + +-- Tests for the atomic exchange primop. + +-- We initialize a value with 1, and then perform exchanges on it +-- with two different values. At the end all the values should still +-- be present. + +module Main ( main ) where + +import Data.Bits +import GHC.Int +import GHC.Prim +import GHC.Word +import Control.Monad +import Control.Concurrent +import Foreign.Marshal.Alloc +import Foreign.Storable +import Data.List + +import GHC.Exts +import GHC.Types + +#include "MachDeps.h" + +main = do + alloca $ \ptr_i -> do + poke ptr_i (1 :: Int) + w1 <- newEmptyMVar :: IO (MVar Int) + forkIO $ do + v <- swapN 50000 2 ptr_i + putMVar w1 v + + v2 <- swapN 50000 3 ptr_i + v1 <- takeMVar w1 + v0 <- peek ptr_i + -- Should be [1,2,3] + print $ sort [v0,v1,v2] + +swapN :: Int -> Int -> Ptr Int -> IO Int +swapN 0 val ptr = return val +swapN n val ptr = do + val' <- swap ptr val + swapN (n-1) val' ptr + + +swap :: Ptr Int -> Int -> IO Int +swap (Ptr ptr) (I# val) = do + IO $ \s -> case (interlockedExchangeInt# ptr val s) of + (# s2, old_val #) -> (# s2, I# old_val #) + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/278330b5fb4fc246b467ecc686068b0bacabc79b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/278330b5fb4fc246b467ecc686068b0bacabc79b You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 19 16:41:05 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Tue, 19 May 2020 12:41:05 -0400 Subject: [Git][ghc/ghc][wip/andreask/xchg_primop] winio: Add Atomic Exchange PrimOp and implement Atomic Ptr exchanges. Message-ID: <5ec40c216ce4_6e2612d6fae4103567@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/xchg_primop at Glasgow Haskell Compiler / GHC Commits: 8960491c by Tamar Christina at 2020-05-19T18:39:08+02:00 winio: Add Atomic Exchange PrimOp and implement Atomic Ptr exchanges. The initial version was rewritten by Tamar Christina. It was rewritten in large parts by Andreas Klebinger. - - - - - 24 changed files: - aclocal.m4 - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm/CPrim.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.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/CodeGen.hs - compiler/GHC/StgToCmm/Prim.hs - configure.ac - docs/users_guide/8.12.1-notes.rst - includes/stg/Prim.h - libraries/base/GHC/Ptr.hs - libraries/ghc-prim/cbits/atomic.c - libraries/ghc-prim/changelog.md - rts/package.conf.in - rts/rts.cabal.in - testsuite/tests/codeGen/should_run/all.T - + testsuite/tests/codeGen/should_run/cg_xchg001.hs - + testsuite/tests/codeGen/should_run/cg_xchg001.stdout Changes: ===================================== aclocal.m4 ===================================== @@ -1341,8 +1341,9 @@ AC_DEFUN([FP_GCC_VERSION], [ AC_MSG_CHECKING([version of gcc]) fp_cv_gcc_version="`$CC -v 2>&1 | sed -n -e '1,/version /s/.*version [[^0-9]]*\([[0-9.]]*\).*/\1/p'`" AC_MSG_RESULT([$fp_cv_gcc_version]) - FP_COMPARE_VERSIONS([$fp_cv_gcc_version], [-lt], [4.6], - [AC_MSG_ERROR([Need at least gcc version 4.6 (4.7+ recommended)])]) + # 4.7 is needed for __atomic_ builtins. + FP_COMPARE_VERSIONS([$fp_cv_gcc_version], [-lt], [4.7], + [AC_MSG_ERROR([Need at least gcc version 4.7 (newer recommended)])]) ]) AC_SUBST([GccVersion], [$fp_cv_gcc_version]) else ===================================== compiler/GHC/Builtin/primops.txt.pp ===================================== @@ -2473,6 +2473,18 @@ primop WriteOffAddrOp_Word64 "writeWord64OffAddr#" GenPrimOp with has_side_effects = True can_fail = True +primop InterlockedExchange_Addr "interlockedExchangeAddr#" GenPrimOp + Addr# -> Addr# -> State# s -> (# State# s, Addr# #) + {The atomic exchange operation. Atomically exchanges the value at the first address + with the Addr# given as second argument. Implies a read barrier.} + with has_side_effects = True + +primop InterlockedExchange_Int "interlockedExchangeInt#" GenPrimOp + Addr# -> Int# -> State# s -> (# State# s, Int# #) + {The atomic exchange operation. Atomically exchanges the value at the address + with the given value. Returns the old value. Implies a read barrier.} + with has_side_effects = True + ------------------------------------------------------------------------ section "Mutable variables" {Operations on MutVar\#s.} ===================================== compiler/GHC/Cmm/MachOp.hs ===================================== @@ -632,6 +632,9 @@ data CallishMachOp | MO_AtomicRead Width | MO_AtomicWrite Width | MO_Cmpxchg Width + -- Should be an AtomicRMW variant eventually. + -- Sequential consistent. + | MO_Xchg Width deriving (Eq, Show) -- | The operation to perform atomically. ===================================== compiler/GHC/Cmm/Parser.y ===================================== @@ -1022,7 +1022,12 @@ callishMachOps = listToUFM $ ( "cmpxchg8", (MO_Cmpxchg W8,)), ( "cmpxchg16", (MO_Cmpxchg W16,)), ( "cmpxchg32", (MO_Cmpxchg W32,)), - ( "cmpxchg64", (MO_Cmpxchg W64,)) + ( "cmpxchg64", (MO_Cmpxchg W64,)), + + ( "xchg8", (MO_Xchg W8,)), + ( "xchg16", (MO_Xchg W16,)), + ( "xchg32", (MO_Xchg W32,)), + ( "xchg64", (MO_Xchg W64,)) -- ToDo: the rest, maybe -- edit: which rest? ===================================== compiler/GHC/CmmToAsm/CPrim.hs ===================================== @@ -4,6 +4,7 @@ module GHC.CmmToAsm.CPrim , atomicWriteLabel , atomicRMWLabel , cmpxchgLabel + , xchgLabel , popCntLabel , pdepLabel , pextLabel @@ -105,6 +106,15 @@ atomicRMWLabel w amop = "hs_atomic_" ++ pprFunName amop ++ pprWidth w pprFunName AMO_Or = "or" pprFunName AMO_Xor = "xor" +xchgLabel :: Width -> String +xchgLabel w = "hs_xchg" ++ pprWidth w + where + pprWidth W8 = "8" + pprWidth W16 = "16" + pprWidth W32 = "32" + pprWidth W64 = "64" + pprWidth w = pprPanic "xchgLabel: Unsupported word width " (ppr w) + cmpxchgLabel :: Width -> String cmpxchgLabel w = "hs_cmpxchg" ++ pprWidth w where ===================================== compiler/GHC/CmmToAsm/PPC/CodeGen.hs ===================================== @@ -2024,6 +2024,7 @@ genCCall' config gcp target dest_regs args MO_Ctz _ -> unsupported MO_AtomicRMW {} -> unsupported MO_Cmpxchg w -> (fsLit $ cmpxchgLabel w, False) + MO_Xchg w -> (fsLit $ xchgLabel w, False) MO_AtomicRead _ -> unsupported MO_AtomicWrite _ -> unsupported ===================================== compiler/GHC/CmmToAsm/SPARC/CodeGen.hs ===================================== @@ -677,6 +677,7 @@ outOfLineMachOp_table mop MO_Ctz w -> fsLit $ ctzLabel w MO_AtomicRMW w amop -> fsLit $ atomicRMWLabel w amop MO_Cmpxchg w -> fsLit $ cmpxchgLabel w + MO_Xchg w -> fsLit $ xchgLabel w MO_AtomicRead w -> fsLit $ atomicReadLabel w MO_AtomicWrite w -> fsLit $ atomicWriteLabel w ===================================== compiler/GHC/CmmToAsm/X86/CodeGen.hs ===================================== @@ -2518,6 +2518,22 @@ genCCall' _ is32Bit (PrimTarget (MO_Cmpxchg width)) [dst] [addr, old, new] _ = d where format = intFormat width +genCCall' config is32Bit (PrimTarget (MO_Xchg width)) [dst] [addr, value] _ + | (is32Bit && width == W64) = panic "gencCall: 64bit atomic exchange not supported on 32bit platforms" + | otherwise = do + let dst_r = getRegisterReg platform (CmmLocal dst) + Amode amode addr_code <- getSimpleAmode is32Bit addr + (newval, newval_code) <- getSomeReg value + -- Copy the value into the target register, perform the exchange. + let code = toOL + [ MOV format (OpReg newval) (OpReg dst_r) + , XCHG format (OpAddr amode) dst_r + ] + return $ addr_code `appOL` newval_code `appOL` code + where + format = intFormat width + platform = ncgPlatform config + genCCall' _ is32Bit target dest_regs args bid = do platform <- ncgPlatform <$> getConfig case (target, dest_regs) of @@ -3213,6 +3229,7 @@ outOfLineCmmOp bid mop res args MO_AtomicRead _ -> fsLit "atomicread" MO_AtomicWrite _ -> fsLit "atomicwrite" MO_Cmpxchg _ -> fsLit "cmpxchg" + MO_Xchg _ -> should_be_inline MO_UF_Conv _ -> unsupported @@ -3232,6 +3249,11 @@ outOfLineCmmOp bid mop res args (MO_Prefetch_Data _ ) -> unsupported unsupported = panic ("outOfLineCmmOp: " ++ show mop ++ " not supported here") + -- If we generate a call for the given primop + -- something went wrong. + should_be_inline = panic ("outOfLineCmmOp: " ++ show mop + ++ " should be handled inline") + -- ----------------------------------------------------------------------------- -- Generating a table-branch ===================================== compiler/GHC/CmmToAsm/X86/Instr.hs ===================================== @@ -329,6 +329,7 @@ data Instr | LOCK Instr -- lock prefix | XADD Format Operand Operand -- src (r), dst (r/m) | CMPXCHG Format Operand Operand -- src (r), dst (r/m), eax implicit + | XCHG Format Operand Reg -- src (r/m), dst (r/m) | MFENCE data PrefetchVariant = NTA | Lvl0 | Lvl1 | Lvl2 @@ -431,6 +432,7 @@ x86_regUsageOfInstr platform instr LOCK i -> x86_regUsageOfInstr platform i XADD _ src dst -> usageMM src dst CMPXCHG _ src dst -> usageRMM src dst (OpReg eax) + XCHG _ src dst -> usageMM src (OpReg dst) MFENCE -> noUsage _other -> panic "regUsage: unrecognised instr" @@ -460,6 +462,7 @@ x86_regUsageOfInstr platform instr usageMM :: Operand -> Operand -> RegUsage usageMM (OpReg src) (OpReg dst) = mkRU [src, dst] [src, dst] usageMM (OpReg src) (OpAddr ea) = mkRU (use_EA ea [src]) [src] + usageMM (OpAddr ea) (OpReg dst) = mkRU (use_EA ea [dst]) [dst] usageMM _ _ = panic "X86.RegInfo.usageMM: no match" -- 3 operand form; first operand Read; second Modified; third Modified @@ -589,6 +592,7 @@ x86_patchRegsOfInstr instr env LOCK i -> LOCK (x86_patchRegsOfInstr i env) XADD fmt src dst -> patch2 (XADD fmt) src dst CMPXCHG fmt src dst -> patch2 (CMPXCHG fmt) src dst + XCHG fmt src dst -> XCHG fmt (patchOp src) (env dst) MFENCE -> instr _other -> panic "patchRegs: unrecognised instr" ===================================== compiler/GHC/CmmToAsm/X86/Ppr.hs ===================================== @@ -824,6 +824,9 @@ pprInstr platform i = case i of SETCC cond op -> pprCondInstr (sLit "set") cond (pprOperand platform II8 op) + XCHG format src val + -> pprFormatOpReg (sLit "xchg") format src val + JXX cond blockid -> pprCondInstr (sLit "j") cond (ppr lab) where lab = blockLbl blockid ===================================== compiler/GHC/CmmToC.hs ===================================== @@ -831,6 +831,7 @@ pprCallishMachOp_for_C mop (MO_Ctz w) -> ptext (sLit $ ctzLabel w) (MO_AtomicRMW w amop) -> ptext (sLit $ atomicRMWLabel w amop) (MO_Cmpxchg w) -> ptext (sLit $ cmpxchgLabel w) + (MO_Xchg w) -> ptext (sLit $ xchgLabel w) (MO_AtomicRead w) -> ptext (sLit $ atomicReadLabel w) (MO_AtomicWrite w) -> ptext (sLit $ atomicWriteLabel w) (MO_UF_Conv w) -> ptext (sLit $ word2FloatLabel w) ===================================== compiler/GHC/CmmToLlvm/CodeGen.hs ===================================== @@ -281,6 +281,14 @@ genCall (PrimTarget (MO_Cmpxchg _width)) retVar' <- doExprW targetTy $ ExtractV retVar 0 statement $ Store retVar' dstVar +genCall (PrimTarget (MO_Xchg _width)) [] [addr, val] = runStmtsDecls $ do + addrVar <- exprToVarW addr + valVar <- exprToVarW val + let ptrTy = pLift $ getVarType valVar + ptrExpr = Cast LM_Inttoptr addrVar ptrTy + ptrVar <- doExprW ptrTy ptrExpr + statement $ Expr $ AtomicRMW LAO_Xchg ptrVar valVar SyncSeqCst + genCall (PrimTarget (MO_AtomicWrite _width)) [] [addr, val] = runStmtsDecls $ do addrVar <- exprToVarW addr valVar <- exprToVarW val @@ -856,6 +864,7 @@ cmmPrimOpFunctions mop = do MO_AtomicRMW _ _ -> unsupported MO_AtomicWrite _ -> unsupported MO_Cmpxchg _ -> unsupported + MO_Xchg _ -> unsupported -- | Tail function calls genJump :: CmmExpr -> [GlobalReg] -> LlvmM StmtData ===================================== compiler/GHC/StgToCmm/Prim.hs ===================================== @@ -856,6 +856,12 @@ emitPrimOp dflags = \case Word2DoubleOp -> \[w] -> opAllDone $ \[res] -> do emitPrimCall [res] (MO_UF_Conv W64) [w] +-- Atomic operations + InterlockedExchange_Addr -> \[src, value] -> opAllDone $ \[res] -> + emitPrimCall [res] (MO_Xchg (wordWidth platform)) [src, value] + InterlockedExchange_Int -> \[src, value] -> opAllDone $ \[res] -> + emitPrimCall [res] (MO_Xchg (wordWidth platform)) [src, value] + -- SIMD primops (VecBroadcastOp vcat n w) -> \[e] -> opAllDone $ \[res] -> do checkVecCompatibility dflags vcat n w ===================================== configure.ac ===================================== @@ -730,6 +730,8 @@ dnl unregisterised, Sparc, and PPC backends. FP_GCC_SUPPORTS__ATOMICS if test $CONF_GCC_SUPPORTS__ATOMICS = YES ; then AC_DEFINE([HAVE_C11_ATOMICS], [1], [Does GCC support __atomic primitives?]) +else + AC_MSG_ERROR([C compiler needs to support __atomic primitives.]) fi FP_GCC_EXTRA_FLAGS ===================================== docs/users_guide/8.12.1-notes.rst ===================================== @@ -148,11 +148,11 @@ Arrow notation ``hsGroupTopLevelFixitySigs`` function, which collects all top-level fixity signatures, including those for class methods defined inside classes. -- The ``Exception`` module was boiled down acknowledging the existence of +- The ``Exception`` module was boiled down acknowledging the existence of the ``exceptions`` dependency. In particular, the ``ExceptionMonad`` class is not a proper class anymore, but a mere synonym for ``MonadThrow``, - ``MonadCatch``, ``MonadMask`` (all from ``exceptions``) and ``MonadIO``. - All of ``g*``-functions from the module (``gtry``, ``gcatch``, etc.) are + ``MonadCatch``, ``MonadMask`` (all from ``exceptions``) and ``MonadIO``. + All of ``g*``-functions from the module (``gtry``, ``gcatch``, etc.) are erased, and their ``exceptions``-alternatives are meant to be used in the GHC code instead. @@ -162,6 +162,12 @@ Arrow notation Build system ~~~~~~~~~~~~ +Bootstrapping requirements +------------------ + +Starting with 8.12.1 GHC requires a C compiler which supports +__atomic_op_n builtins. This raises the requirement for GCC to 4.7. + Included libraries ------------------ ===================================== includes/stg/Prim.h ===================================== @@ -50,6 +50,10 @@ void hs_atomicwrite8(StgWord x, StgWord val); void hs_atomicwrite16(StgWord x, StgWord val); void hs_atomicwrite32(StgWord x, StgWord val); void hs_atomicwrite64(StgWord x, StgWord64 val); +StgWord hs_xchg8(StgPtr x, StgWord val); +StgWord hs_xchg16(StgPtr x, StgWord val); +StgWord hs_xchg32(StgPtr x, StgWord val); +StgWord hs_xchg64(StgPtr x, StgWord val); /* libraries/ghc-prim/cbits/bswap.c */ StgWord16 hs_bswap16(StgWord16 x); ===================================== libraries/base/GHC/Ptr.hs ===================================== @@ -1,5 +1,6 @@ {-# LANGUAGE Unsafe #-} {-# LANGUAGE CPP, NoImplicitPrelude, MagicHash, RoleAnnotations #-} +{-# LANGUAGE UnboxedTuples #-} {-# OPTIONS_HADDOCK not-home #-} ----------------------------------------------------------------------------- @@ -22,7 +23,10 @@ module GHC.Ptr ( nullFunPtr, castFunPtr, -- * Unsafe functions - castFunPtrToPtr, castPtrToFunPtr + castFunPtrToPtr, castPtrToFunPtr, + + -- * Atomic operations + exchangePtr ) where import GHC.Base @@ -162,6 +166,15 @@ castFunPtrToPtr (FunPtr addr) = Ptr addr castPtrToFunPtr :: Ptr a -> FunPtr b castPtrToFunPtr (Ptr addr) = FunPtr addr +------------------------------------------------------------------------ +-- Atomic operations for Ptr + +{-# INLINE exchangePtr #-} +exchangePtr :: Ptr (Ptr a) -> Ptr b -> IO (Ptr c) +exchangePtr (Ptr dst) (Ptr val) = + IO $ \s -> + case (interlockedExchangeAddr# dst val s) of + (# s2, old_val #) -> (# s2, Ptr old_val #) ------------------------------------------------------------------------ -- Show instances for Ptr and FunPtr ===================================== libraries/ghc-prim/cbits/atomic.c ===================================== @@ -318,6 +318,39 @@ hs_cmpxchg64(StgWord x, StgWord64 old, StgWord64 new) } #endif +// Atomic exchange operations + +extern StgWord hs_xchg8(StgPtr x, StgWord val); +StgWord +hs_xchg8(StgPtr x, StgWord val) +{ + return (StgWord) __atomic_exchange_1((volatile StgPtr) x, val, __ATOMIC_SEQ_CST); +} + +extern StgWord hs_xchg16(StgPtr x, StgWord val); +StgWord +hs_xchg16(StgPtr x, StgWord val) +{ + return (StgWord) __atomic_exchange_2(x, val, __ATOMIC_SEQ_CST); +} + +extern StgWord hs_xchg32(StgPtr x, StgWord val); +StgWord +hs_xchg32(StgPtr x, StgWord val) +{ + return (StgWord) __atomic_exchange_4((volatile StgPtr) x, val, __ATOMIC_SEQ_CST); +} + +#if WORD_SIZE_IN_BITS == 64 +//GCC provides this even on 32bit, but StgWord is still 32 bits. +extern StgWord hs_xchg64(StgPtr x, StgWord val); +StgWord +hs_xchg64(StgPtr x, StgWord val) +{ + return (StgWord) __atomic_exchange_8((volatile StgPtr) x, val, __ATOMIC_SEQ_CST); +} +#endif + // AtomicReadByteArrayOp_Int // Implies a full memory barrier (see compiler/GHC/Builtin/primops.txt.pp) // __ATOMIC_SEQ_CST: Full barrier in both directions (hoisting and sinking ===================================== libraries/ghc-prim/changelog.md ===================================== @@ -1,3 +1,12 @@ +## TBD + +- Shipped with GHC 8.12.1 + +- Add primops for atomic exchange: + + interlockedExchangeAddr# :: Addr# -> Addr# -> State# s -> (# State# s, Addr# #) + interlockedExchangeInt# :: Addr# -> Int# -> State# s -> (# State# s, Int# #) + ## 0.6.1 (edit as necessary) - Shipped with GHC 8.10.1 ===================================== rts/package.conf.in ===================================== @@ -168,6 +168,10 @@ ld-options: #if WORD_SIZE_IN_BITS == 64 , "-Wl,-u,_hs_cmpxchg64" #endif + , "-Wl,-u,_hs_xchg8" + , "-Wl,-u,_hs_xchg16" + , "-Wl,-u,_hs_xchg32" + , "-Wl,-u,_hs_xchg64" , "-Wl,-u,_hs_atomicread8" , "-Wl,-u,_hs_atomicread16" , "-Wl,-u,_hs_atomicread32" @@ -273,6 +277,10 @@ ld-options: #if WORD_SIZE_IN_BITS == 64 , "-Wl,-u,hs_cmpxchg64" #endif + , "-Wl,-u,hs_xchg8" + , "-Wl,-u,hs_xchg16" + , "-Wl,-u,hs_xchg32" + , "-Wl,-u,hs_xchg64" , "-Wl,-u,hs_atomicread8" , "-Wl,-u,hs_atomicread16" , "-Wl,-u,hs_atomicread32" ===================================== rts/rts.cabal.in ===================================== @@ -264,6 +264,10 @@ library "-Wl,-u,_hs_cmpxchg8" "-Wl,-u,_hs_cmpxchg16" "-Wl,-u,_hs_cmpxchg32" + "-Wl,-u,_hs_xchg8" + "-Wl,-u,_hs_xchg16" + "-Wl,-u,_hs_xchg32" + "-Wl,-u,_hs_xchg64" "-Wl,-u,_hs_atomicread8" "-Wl,-u,_hs_atomicread16" "-Wl,-u,_hs_atomicread32" @@ -339,6 +343,10 @@ library "-Wl,-u,hs_cmpxchg8" "-Wl,-u,hs_cmpxchg16" "-Wl,-u,hs_cmpxchg32" + "-Wl,-u,hs_xchg8" + "-Wl,-u,hs_xchg16" + "-Wl,-u,hs_xchg32" + "-Wl,-u,hs_xchg64" "-Wl,-u,hs_atomicread8" "-Wl,-u,hs_atomicread16" "-Wl,-u,hs_atomicread32" ===================================== testsuite/tests/codeGen/should_run/all.T ===================================== @@ -205,3 +205,4 @@ test('T15892', test('T16617', normal, compile_and_run, ['']) test('T16449_2', exit_code(0), compile_and_run, ['']) test('T16846', [only_ways(['optasm']), exit_code(1)], compile_and_run, ['']) +test('cg_xchg001', normal, compile_and_run, ['']) \ No newline at end of file ===================================== testsuite/tests/codeGen/should_run/cg_xchg001.hs ===================================== @@ -0,0 +1,51 @@ +{-# LANGUAGE CPP, MagicHash, BlockArguments, UnboxedTuples #-} + +-- Tests for the atomic exchange primop. + +-- We initialize a value with 1, and then perform exchanges on it +-- with two different values. At the end all the values should still +-- be present. + +module Main ( main ) where + +import Data.Bits +import GHC.Int +import GHC.Prim +import GHC.Word +import Control.Monad +import Control.Concurrent +import Foreign.Marshal.Alloc +import Foreign.Storable +import Data.List (sort) + +import GHC.Exts +import GHC.Types + +#include "MachDeps.h" + +main = do + alloca $ \ptr_i -> do + poke ptr_i (1 :: Int) + w1 <- newEmptyMVar :: IO (MVar Int) + forkIO $ do + v <- swapN 50000 2 ptr_i + putMVar w1 v + + v2 <- swapN 50000 3 ptr_i + v1 <- takeMVar w1 + v0 <- peek ptr_i + -- Should be [1,2,3] + print $ sort [v0,v1,v2] + +swapN :: Int -> Int -> Ptr Int -> IO Int +swapN 0 val ptr = return val +swapN n val ptr = do + val' <- swap ptr val + swapN (n-1) val' ptr + + +swap :: Ptr Int -> Int -> IO Int +swap (Ptr ptr) (I# val) = do + IO $ \s -> case (interlockedExchangeInt# ptr val s) of + (# s2, old_val #) -> (# s2, I# old_val #) + ===================================== testsuite/tests/codeGen/should_run/cg_xchg001.stdout ===================================== @@ -0,0 +1 @@ +[1,2,3] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8960491c812ef7e89c9d0ea2c9a0efa0cefafae9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8960491c812ef7e89c9d0ea2c9a0efa0cefafae9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 19 17:00:04 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Tue, 19 May 2020 13:00:04 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/andreask/wio/gcc_driver Message-ID: <5ec410949f8a0_6e2611738d4811145e@gitlab.haskell.org.mail> Andreas Klebinger pushed new branch wip/andreask/wio/gcc_driver at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/andreask/wio/gcc_driver You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 19 17:11:08 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Tue, 19 May 2020 13:11:08 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18069 Message-ID: <5ec4132c3226b_6e2611ecc3fc1144a@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/T18069 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18069 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Tue May 19 17:11:08 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Tue, 19 May 2020 13:11:08 -0400 Subject: [Git][ghc/ghc][wip/T18069] SysTools.Process: Handle exceptions in readCreateProcessWithExitCode' Message-ID: <5ec4132cbd878_6e2611ecc3fc11469e@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18069 at Glasgow Haskell Compiler / GHC Commits: c35a78a2 by Ben Gamari at 2020-05-19T13:08:43-04:00 SysTools.Process: Handle exceptions in readCreateProcessWithExitCode' In #18069 we are observing MVar deadlocks from somewhere in ghc.exe. This use of MVar stood out as being one of the more likely culprits. Here we make sure that it is exception-safe. - - - - - 1 changed file: - compiler/GHC/SysTools/Process.hs Changes: ===================================== compiler/GHC/SysTools/Process.hs ===================================== @@ -41,6 +41,15 @@ enableProcessJobs opts = opts { use_process_jobs = True } enableProcessJobs opts = opts #endif +#if !MIN_VERSION_base(4,15,0) +-- TODO: This can be dropped with GHC 8.16 +hGetContents' :: Handle -> IO String +hGetContents' hdl = do + output <- hGetContents hdl + evaluate $ length output + return output +#endif + -- Similar to System.Process.readCreateProcessWithExitCode, but stderr is -- inherited from the parent process, and output to stderr is not captured. readCreateProcessWithExitCode' @@ -51,13 +60,18 @@ readCreateProcessWithExitCode' proc = do createProcess proc{ std_out = CreatePipe } -- fork off a thread to start consuming the output - output <- hGetContents outh outMVar <- newEmptyMVar - _ <- forkIO $ evaluate (length output) >> putMVar outMVar () + let onError exc = takeMVar outMVar (Left exc) + _ <- forkIO $ handleAll onError $ do + output <- hGetContents' outh + putMVar outMVar $ Right output -- wait on the output - takeMVar outMVar + result <- takeMVar outMVar hClose outh + output <- case result of + Left exc -> throwIO exc + Right output -> return output -- wait on the process ex <- waitForProcess pid View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c35a78a2429444b601774b73f53de5f08a675a7c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c35a78a2429444b601774b73f53de5f08a675a7c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 20 10:35:49 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Wed, 20 May 2020 06:35:49 -0400 Subject: [Git][ghc/ghc][wip/andreask/xchg_primop] winio: Add Atomic Exchange PrimOp and implement Atomic Ptr exchanges. Message-ID: <5ec508056d626_6e263f9ee2d57e042032be@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/xchg_primop at Glasgow Haskell Compiler / GHC Commits: ae57157e by Tamar Christina at 2020-05-20T12:35:34+02:00 winio: Add Atomic Exchange PrimOp and implement Atomic Ptr exchanges. The initial version was rewritten by Tamar Christina. It was rewritten in large parts by Andreas Klebinger. - - - - - 24 changed files: - aclocal.m4 - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm/CPrim.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.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/CodeGen.hs - compiler/GHC/StgToCmm/Prim.hs - configure.ac - docs/users_guide/8.12.1-notes.rst - includes/stg/Prim.h - libraries/base/GHC/Ptr.hs - libraries/ghc-prim/cbits/atomic.c - libraries/ghc-prim/changelog.md - rts/package.conf.in - rts/rts.cabal.in - testsuite/tests/codeGen/should_run/all.T - + testsuite/tests/codeGen/should_run/cg_xchg001.hs - + testsuite/tests/codeGen/should_run/cg_xchg001.stdout Changes: ===================================== aclocal.m4 ===================================== @@ -1341,8 +1341,9 @@ AC_DEFUN([FP_GCC_VERSION], [ AC_MSG_CHECKING([version of gcc]) fp_cv_gcc_version="`$CC -v 2>&1 | sed -n -e '1,/version /s/.*version [[^0-9]]*\([[0-9.]]*\).*/\1/p'`" AC_MSG_RESULT([$fp_cv_gcc_version]) - FP_COMPARE_VERSIONS([$fp_cv_gcc_version], [-lt], [4.6], - [AC_MSG_ERROR([Need at least gcc version 4.6 (4.7+ recommended)])]) + # 4.7 is needed for __atomic_ builtins. + FP_COMPARE_VERSIONS([$fp_cv_gcc_version], [-lt], [4.7], + [AC_MSG_ERROR([Need at least gcc version 4.7 (newer recommended)])]) ]) AC_SUBST([GccVersion], [$fp_cv_gcc_version]) else ===================================== compiler/GHC/Builtin/primops.txt.pp ===================================== @@ -2473,6 +2473,18 @@ primop WriteOffAddrOp_Word64 "writeWord64OffAddr#" GenPrimOp with has_side_effects = True can_fail = True +primop InterlockedExchange_Addr "interlockedExchangeAddr#" GenPrimOp + Addr# -> Addr# -> State# s -> (# State# s, Addr# #) + {The atomic exchange operation. Atomically exchanges the value at the first address + with the Addr# given as second argument. Implies a read barrier.} + with has_side_effects = True + +primop InterlockedExchange_Int "interlockedExchangeInt#" GenPrimOp + Addr# -> Int# -> State# s -> (# State# s, Int# #) + {The atomic exchange operation. Atomically exchanges the value at the address + with the given value. Returns the old value. Implies a read barrier.} + with has_side_effects = True + ------------------------------------------------------------------------ section "Mutable variables" {Operations on MutVar\#s.} ===================================== compiler/GHC/Cmm/MachOp.hs ===================================== @@ -632,6 +632,9 @@ data CallishMachOp | MO_AtomicRead Width | MO_AtomicWrite Width | MO_Cmpxchg Width + -- Should be an AtomicRMW variant eventually. + -- Sequential consistent. + | MO_Xchg Width deriving (Eq, Show) -- | The operation to perform atomically. ===================================== compiler/GHC/Cmm/Parser.y ===================================== @@ -1022,7 +1022,12 @@ callishMachOps = listToUFM $ ( "cmpxchg8", (MO_Cmpxchg W8,)), ( "cmpxchg16", (MO_Cmpxchg W16,)), ( "cmpxchg32", (MO_Cmpxchg W32,)), - ( "cmpxchg64", (MO_Cmpxchg W64,)) + ( "cmpxchg64", (MO_Cmpxchg W64,)), + + ( "xchg8", (MO_Xchg W8,)), + ( "xchg16", (MO_Xchg W16,)), + ( "xchg32", (MO_Xchg W32,)), + ( "xchg64", (MO_Xchg W64,)) -- ToDo: the rest, maybe -- edit: which rest? ===================================== compiler/GHC/CmmToAsm/CPrim.hs ===================================== @@ -4,6 +4,7 @@ module GHC.CmmToAsm.CPrim , atomicWriteLabel , atomicRMWLabel , cmpxchgLabel + , xchgLabel , popCntLabel , pdepLabel , pextLabel @@ -105,6 +106,15 @@ atomicRMWLabel w amop = "hs_atomic_" ++ pprFunName amop ++ pprWidth w pprFunName AMO_Or = "or" pprFunName AMO_Xor = "xor" +xchgLabel :: Width -> String +xchgLabel w = "hs_xchg" ++ pprWidth w + where + pprWidth W8 = "8" + pprWidth W16 = "16" + pprWidth W32 = "32" + pprWidth W64 = "64" + pprWidth w = pprPanic "xchgLabel: Unsupported word width " (ppr w) + cmpxchgLabel :: Width -> String cmpxchgLabel w = "hs_cmpxchg" ++ pprWidth w where ===================================== compiler/GHC/CmmToAsm/PPC/CodeGen.hs ===================================== @@ -2024,6 +2024,7 @@ genCCall' config gcp target dest_regs args MO_Ctz _ -> unsupported MO_AtomicRMW {} -> unsupported MO_Cmpxchg w -> (fsLit $ cmpxchgLabel w, False) + MO_Xchg w -> (fsLit $ xchgLabel w, False) MO_AtomicRead _ -> unsupported MO_AtomicWrite _ -> unsupported ===================================== compiler/GHC/CmmToAsm/SPARC/CodeGen.hs ===================================== @@ -677,6 +677,7 @@ outOfLineMachOp_table mop MO_Ctz w -> fsLit $ ctzLabel w MO_AtomicRMW w amop -> fsLit $ atomicRMWLabel w amop MO_Cmpxchg w -> fsLit $ cmpxchgLabel w + MO_Xchg w -> fsLit $ xchgLabel w MO_AtomicRead w -> fsLit $ atomicReadLabel w MO_AtomicWrite w -> fsLit $ atomicWriteLabel w ===================================== compiler/GHC/CmmToAsm/X86/CodeGen.hs ===================================== @@ -2518,6 +2518,22 @@ genCCall' _ is32Bit (PrimTarget (MO_Cmpxchg width)) [dst] [addr, old, new] _ = d where format = intFormat width +genCCall' config is32Bit (PrimTarget (MO_Xchg width)) [dst] [addr, value] _ + | (is32Bit && width == W64) = panic "gencCall: 64bit atomic exchange not supported on 32bit platforms" + | otherwise = do + let dst_r = getRegisterReg platform (CmmLocal dst) + Amode amode addr_code <- getSimpleAmode is32Bit addr + (newval, newval_code) <- getSomeReg value + -- Copy the value into the target register, perform the exchange. + let code = toOL + [ MOV format (OpReg newval) (OpReg dst_r) + , XCHG format (OpAddr amode) dst_r + ] + return $ addr_code `appOL` newval_code `appOL` code + where + format = intFormat width + platform = ncgPlatform config + genCCall' _ is32Bit target dest_regs args bid = do platform <- ncgPlatform <$> getConfig case (target, dest_regs) of @@ -3213,6 +3229,7 @@ outOfLineCmmOp bid mop res args MO_AtomicRead _ -> fsLit "atomicread" MO_AtomicWrite _ -> fsLit "atomicwrite" MO_Cmpxchg _ -> fsLit "cmpxchg" + MO_Xchg _ -> should_be_inline MO_UF_Conv _ -> unsupported @@ -3232,6 +3249,11 @@ outOfLineCmmOp bid mop res args (MO_Prefetch_Data _ ) -> unsupported unsupported = panic ("outOfLineCmmOp: " ++ show mop ++ " not supported here") + -- If we generate a call for the given primop + -- something went wrong. + should_be_inline = panic ("outOfLineCmmOp: " ++ show mop + ++ " should be handled inline") + -- ----------------------------------------------------------------------------- -- Generating a table-branch ===================================== compiler/GHC/CmmToAsm/X86/Instr.hs ===================================== @@ -329,6 +329,7 @@ data Instr | LOCK Instr -- lock prefix | XADD Format Operand Operand -- src (r), dst (r/m) | CMPXCHG Format Operand Operand -- src (r), dst (r/m), eax implicit + | XCHG Format Operand Reg -- src (r/m), dst (r/m) | MFENCE data PrefetchVariant = NTA | Lvl0 | Lvl1 | Lvl2 @@ -431,6 +432,7 @@ x86_regUsageOfInstr platform instr LOCK i -> x86_regUsageOfInstr platform i XADD _ src dst -> usageMM src dst CMPXCHG _ src dst -> usageRMM src dst (OpReg eax) + XCHG _ src dst -> usageMM src (OpReg dst) MFENCE -> noUsage _other -> panic "regUsage: unrecognised instr" @@ -460,6 +462,7 @@ x86_regUsageOfInstr platform instr usageMM :: Operand -> Operand -> RegUsage usageMM (OpReg src) (OpReg dst) = mkRU [src, dst] [src, dst] usageMM (OpReg src) (OpAddr ea) = mkRU (use_EA ea [src]) [src] + usageMM (OpAddr ea) (OpReg dst) = mkRU (use_EA ea [dst]) [dst] usageMM _ _ = panic "X86.RegInfo.usageMM: no match" -- 3 operand form; first operand Read; second Modified; third Modified @@ -589,6 +592,7 @@ x86_patchRegsOfInstr instr env LOCK i -> LOCK (x86_patchRegsOfInstr i env) XADD fmt src dst -> patch2 (XADD fmt) src dst CMPXCHG fmt src dst -> patch2 (CMPXCHG fmt) src dst + XCHG fmt src dst -> XCHG fmt (patchOp src) (env dst) MFENCE -> instr _other -> panic "patchRegs: unrecognised instr" ===================================== compiler/GHC/CmmToAsm/X86/Ppr.hs ===================================== @@ -824,6 +824,9 @@ pprInstr platform i = case i of SETCC cond op -> pprCondInstr (sLit "set") cond (pprOperand platform II8 op) + XCHG format src val + -> pprFormatOpReg (sLit "xchg") format src val + JXX cond blockid -> pprCondInstr (sLit "j") cond (ppr lab) where lab = blockLbl blockid ===================================== compiler/GHC/CmmToC.hs ===================================== @@ -831,6 +831,7 @@ pprCallishMachOp_for_C mop (MO_Ctz w) -> ptext (sLit $ ctzLabel w) (MO_AtomicRMW w amop) -> ptext (sLit $ atomicRMWLabel w amop) (MO_Cmpxchg w) -> ptext (sLit $ cmpxchgLabel w) + (MO_Xchg w) -> ptext (sLit $ xchgLabel w) (MO_AtomicRead w) -> ptext (sLit $ atomicReadLabel w) (MO_AtomicWrite w) -> ptext (sLit $ atomicWriteLabel w) (MO_UF_Conv w) -> ptext (sLit $ word2FloatLabel w) ===================================== compiler/GHC/CmmToLlvm/CodeGen.hs ===================================== @@ -281,6 +281,14 @@ genCall (PrimTarget (MO_Cmpxchg _width)) retVar' <- doExprW targetTy $ ExtractV retVar 0 statement $ Store retVar' dstVar +genCall (PrimTarget (MO_Xchg _width)) [] [addr, val] = runStmtsDecls $ do + addrVar <- exprToVarW addr + valVar <- exprToVarW val + let ptrTy = pLift $ getVarType valVar + ptrExpr = Cast LM_Inttoptr addrVar ptrTy + ptrVar <- doExprW ptrTy ptrExpr + statement $ Expr $ AtomicRMW LAO_Xchg ptrVar valVar SyncSeqCst + genCall (PrimTarget (MO_AtomicWrite _width)) [] [addr, val] = runStmtsDecls $ do addrVar <- exprToVarW addr valVar <- exprToVarW val @@ -856,6 +864,7 @@ cmmPrimOpFunctions mop = do MO_AtomicRMW _ _ -> unsupported MO_AtomicWrite _ -> unsupported MO_Cmpxchg _ -> unsupported + MO_Xchg _ -> unsupported -- | Tail function calls genJump :: CmmExpr -> [GlobalReg] -> LlvmM StmtData ===================================== compiler/GHC/StgToCmm/Prim.hs ===================================== @@ -856,6 +856,12 @@ emitPrimOp dflags = \case Word2DoubleOp -> \[w] -> opAllDone $ \[res] -> do emitPrimCall [res] (MO_UF_Conv W64) [w] +-- Atomic operations + InterlockedExchange_Addr -> \[src, value] -> opAllDone $ \[res] -> + emitPrimCall [res] (MO_Xchg (wordWidth platform)) [src, value] + InterlockedExchange_Int -> \[src, value] -> opAllDone $ \[res] -> + emitPrimCall [res] (MO_Xchg (wordWidth platform)) [src, value] + -- SIMD primops (VecBroadcastOp vcat n w) -> \[e] -> opAllDone $ \[res] -> do checkVecCompatibility dflags vcat n w ===================================== configure.ac ===================================== @@ -730,6 +730,8 @@ dnl unregisterised, Sparc, and PPC backends. FP_GCC_SUPPORTS__ATOMICS if test $CONF_GCC_SUPPORTS__ATOMICS = YES ; then AC_DEFINE([HAVE_C11_ATOMICS], [1], [Does GCC support __atomic primitives?]) +else + AC_MSG_ERROR([C compiler needs to support __atomic primitives.]) fi FP_GCC_EXTRA_FLAGS ===================================== docs/users_guide/8.12.1-notes.rst ===================================== @@ -148,11 +148,11 @@ Arrow notation ``hsGroupTopLevelFixitySigs`` function, which collects all top-level fixity signatures, including those for class methods defined inside classes. -- The ``Exception`` module was boiled down acknowledging the existence of +- The ``Exception`` module was boiled down acknowledging the existence of the ``exceptions`` dependency. In particular, the ``ExceptionMonad`` class is not a proper class anymore, but a mere synonym for ``MonadThrow``, - ``MonadCatch``, ``MonadMask`` (all from ``exceptions``) and ``MonadIO``. - All of ``g*``-functions from the module (``gtry``, ``gcatch``, etc.) are + ``MonadCatch``, ``MonadMask`` (all from ``exceptions``) and ``MonadIO``. + All of ``g*``-functions from the module (``gtry``, ``gcatch``, etc.) are erased, and their ``exceptions``-alternatives are meant to be used in the GHC code instead. @@ -162,6 +162,12 @@ Arrow notation Build system ~~~~~~~~~~~~ +Bootstrapping requirements +-------------------------- + +Starting with 8.12.1 GHC requires a C compiler which supports +__atomic_op_n builtins. This raises the requirement for GCC to 4.7. + Included libraries ------------------ ===================================== includes/stg/Prim.h ===================================== @@ -50,6 +50,10 @@ void hs_atomicwrite8(StgWord x, StgWord val); void hs_atomicwrite16(StgWord x, StgWord val); void hs_atomicwrite32(StgWord x, StgWord val); void hs_atomicwrite64(StgWord x, StgWord64 val); +StgWord hs_xchg8(StgPtr x, StgWord val); +StgWord hs_xchg16(StgPtr x, StgWord val); +StgWord hs_xchg32(StgPtr x, StgWord val); +StgWord hs_xchg64(StgPtr x, StgWord val); /* libraries/ghc-prim/cbits/bswap.c */ StgWord16 hs_bswap16(StgWord16 x); ===================================== libraries/base/GHC/Ptr.hs ===================================== @@ -1,5 +1,6 @@ {-# LANGUAGE Unsafe #-} {-# LANGUAGE CPP, NoImplicitPrelude, MagicHash, RoleAnnotations #-} +{-# LANGUAGE UnboxedTuples #-} {-# OPTIONS_HADDOCK not-home #-} ----------------------------------------------------------------------------- @@ -22,7 +23,10 @@ module GHC.Ptr ( nullFunPtr, castFunPtr, -- * Unsafe functions - castFunPtrToPtr, castPtrToFunPtr + castFunPtrToPtr, castPtrToFunPtr, + + -- * Atomic operations + exchangePtr ) where import GHC.Base @@ -162,6 +166,15 @@ castFunPtrToPtr (FunPtr addr) = Ptr addr castPtrToFunPtr :: Ptr a -> FunPtr b castPtrToFunPtr (Ptr addr) = FunPtr addr +------------------------------------------------------------------------ +-- Atomic operations for Ptr + +{-# INLINE exchangePtr #-} +exchangePtr :: Ptr (Ptr a) -> Ptr b -> IO (Ptr c) +exchangePtr (Ptr dst) (Ptr val) = + IO $ \s -> + case (interlockedExchangeAddr# dst val s) of + (# s2, old_val #) -> (# s2, Ptr old_val #) ------------------------------------------------------------------------ -- Show instances for Ptr and FunPtr ===================================== libraries/ghc-prim/cbits/atomic.c ===================================== @@ -318,6 +318,39 @@ hs_cmpxchg64(StgWord x, StgWord64 old, StgWord64 new) } #endif +// Atomic exchange operations + +extern StgWord hs_xchg8(StgPtr x, StgWord val); +StgWord +hs_xchg8(StgPtr x, StgWord val) +{ + return (StgWord) __atomic_exchange_1((volatile StgPtr) x, val, __ATOMIC_SEQ_CST); +} + +extern StgWord hs_xchg16(StgPtr x, StgWord val); +StgWord +hs_xchg16(StgPtr x, StgWord val) +{ + return (StgWord) __atomic_exchange_2(x, val, __ATOMIC_SEQ_CST); +} + +extern StgWord hs_xchg32(StgPtr x, StgWord val); +StgWord +hs_xchg32(StgPtr x, StgWord val) +{ + return (StgWord) __atomic_exchange_4((volatile StgPtr) x, val, __ATOMIC_SEQ_CST); +} + +#if WORD_SIZE_IN_BITS == 64 +//GCC provides this even on 32bit, but StgWord is still 32 bits. +extern StgWord hs_xchg64(StgPtr x, StgWord val); +StgWord +hs_xchg64(StgPtr x, StgWord val) +{ + return (StgWord) __atomic_exchange_8((volatile StgPtr) x, val, __ATOMIC_SEQ_CST); +} +#endif + // AtomicReadByteArrayOp_Int // Implies a full memory barrier (see compiler/GHC/Builtin/primops.txt.pp) // __ATOMIC_SEQ_CST: Full barrier in both directions (hoisting and sinking ===================================== libraries/ghc-prim/changelog.md ===================================== @@ -1,3 +1,12 @@ +## TBD + +- Shipped with GHC 8.12.1 + +- Add primops for atomic exchange: + + interlockedExchangeAddr# :: Addr# -> Addr# -> State# s -> (# State# s, Addr# #) + interlockedExchangeInt# :: Addr# -> Int# -> State# s -> (# State# s, Int# #) + ## 0.6.1 (edit as necessary) - Shipped with GHC 8.10.1 ===================================== rts/package.conf.in ===================================== @@ -168,6 +168,10 @@ ld-options: #if WORD_SIZE_IN_BITS == 64 , "-Wl,-u,_hs_cmpxchg64" #endif + , "-Wl,-u,_hs_xchg8" + , "-Wl,-u,_hs_xchg16" + , "-Wl,-u,_hs_xchg32" + , "-Wl,-u,_hs_xchg64" , "-Wl,-u,_hs_atomicread8" , "-Wl,-u,_hs_atomicread16" , "-Wl,-u,_hs_atomicread32" @@ -273,6 +277,10 @@ ld-options: #if WORD_SIZE_IN_BITS == 64 , "-Wl,-u,hs_cmpxchg64" #endif + , "-Wl,-u,hs_xchg8" + , "-Wl,-u,hs_xchg16" + , "-Wl,-u,hs_xchg32" + , "-Wl,-u,hs_xchg64" , "-Wl,-u,hs_atomicread8" , "-Wl,-u,hs_atomicread16" , "-Wl,-u,hs_atomicread32" ===================================== rts/rts.cabal.in ===================================== @@ -264,6 +264,10 @@ library "-Wl,-u,_hs_cmpxchg8" "-Wl,-u,_hs_cmpxchg16" "-Wl,-u,_hs_cmpxchg32" + "-Wl,-u,_hs_xchg8" + "-Wl,-u,_hs_xchg16" + "-Wl,-u,_hs_xchg32" + "-Wl,-u,_hs_xchg64" "-Wl,-u,_hs_atomicread8" "-Wl,-u,_hs_atomicread16" "-Wl,-u,_hs_atomicread32" @@ -339,6 +343,10 @@ library "-Wl,-u,hs_cmpxchg8" "-Wl,-u,hs_cmpxchg16" "-Wl,-u,hs_cmpxchg32" + "-Wl,-u,hs_xchg8" + "-Wl,-u,hs_xchg16" + "-Wl,-u,hs_xchg32" + "-Wl,-u,hs_xchg64" "-Wl,-u,hs_atomicread8" "-Wl,-u,hs_atomicread16" "-Wl,-u,hs_atomicread32" ===================================== testsuite/tests/codeGen/should_run/all.T ===================================== @@ -205,3 +205,4 @@ test('T15892', test('T16617', normal, compile_and_run, ['']) test('T16449_2', exit_code(0), compile_and_run, ['']) test('T16846', [only_ways(['optasm']), exit_code(1)], compile_and_run, ['']) +test('cg_xchg001', normal, compile_and_run, ['']) \ No newline at end of file ===================================== testsuite/tests/codeGen/should_run/cg_xchg001.hs ===================================== @@ -0,0 +1,51 @@ +{-# LANGUAGE CPP, MagicHash, BlockArguments, UnboxedTuples #-} + +-- Tests for the atomic exchange primop. + +-- We initialize a value with 1, and then perform exchanges on it +-- with two different values. At the end all the values should still +-- be present. + +module Main ( main ) where + +import Data.Bits +import GHC.Int +import GHC.Prim +import GHC.Word +import Control.Monad +import Control.Concurrent +import Foreign.Marshal.Alloc +import Foreign.Storable +import Data.List (sort) + +import GHC.Exts +import GHC.Types + +#include "MachDeps.h" + +main = do + alloca $ \ptr_i -> do + poke ptr_i (1 :: Int) + w1 <- newEmptyMVar :: IO (MVar Int) + forkIO $ do + v <- swapN 50000 2 ptr_i + putMVar w1 v + + v2 <- swapN 50000 3 ptr_i + v1 <- takeMVar w1 + v0 <- peek ptr_i + -- Should be [1,2,3] + print $ sort [v0,v1,v2] + +swapN :: Int -> Int -> Ptr Int -> IO Int +swapN 0 val ptr = return val +swapN n val ptr = do + val' <- swap ptr val + swapN (n-1) val' ptr + + +swap :: Ptr Int -> Int -> IO Int +swap (Ptr ptr) (I# val) = do + IO $ \s -> case (interlockedExchangeInt# ptr val s) of + (# s2, old_val #) -> (# s2, I# old_val #) + ===================================== testsuite/tests/codeGen/should_run/cg_xchg001.stdout ===================================== @@ -0,0 +1 @@ +[1,2,3] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ae57157e8c178f543ab4114348bff42c12c7cd87 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ae57157e8c178f543ab4114348bff42c12c7cd87 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 20 14:14:25 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Wed, 20 May 2020 10:14:25 -0400 Subject: [Git][ghc/ghc][wip/andreask/xchg_primop] winio: Add Atomic Exchange PrimOp and implement Atomic Ptr exchanges. Message-ID: <5ec53b415dadb_6e26114c4d282208e2@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/xchg_primop at Glasgow Haskell Compiler / GHC Commits: 5f41b811 by Tamar Christina at 2020-05-20T16:14:09+02:00 winio: Add Atomic Exchange PrimOp and implement Atomic Ptr exchanges. The initial version was rewritten by Tamar Christina. It was rewritten in large parts by Andreas Klebinger. - - - - - 24 changed files: - aclocal.m4 - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/MachOp.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/CmmToAsm/CPrim.hs - compiler/GHC/CmmToAsm/PPC/CodeGen.hs - compiler/GHC/CmmToAsm/SPARC/CodeGen.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/CodeGen.hs - compiler/GHC/StgToCmm/Prim.hs - configure.ac - docs/users_guide/8.12.1-notes.rst - includes/stg/Prim.h - libraries/base/GHC/Ptr.hs - libraries/ghc-prim/cbits/atomic.c - libraries/ghc-prim/changelog.md - rts/package.conf.in - rts/rts.cabal.in - testsuite/tests/codeGen/should_run/all.T - + testsuite/tests/codeGen/should_run/cg_xchg001.hs - + testsuite/tests/codeGen/should_run/cg_xchg001.stdout Changes: ===================================== aclocal.m4 ===================================== @@ -1341,8 +1341,9 @@ AC_DEFUN([FP_GCC_VERSION], [ AC_MSG_CHECKING([version of gcc]) fp_cv_gcc_version="`$CC -v 2>&1 | sed -n -e '1,/version /s/.*version [[^0-9]]*\([[0-9.]]*\).*/\1/p'`" AC_MSG_RESULT([$fp_cv_gcc_version]) - FP_COMPARE_VERSIONS([$fp_cv_gcc_version], [-lt], [4.6], - [AC_MSG_ERROR([Need at least gcc version 4.6 (4.7+ recommended)])]) + # 4.7 is needed for __atomic_ builtins. + FP_COMPARE_VERSIONS([$fp_cv_gcc_version], [-lt], [4.7], + [AC_MSG_ERROR([Need at least gcc version 4.7 (newer recommended)])]) ]) AC_SUBST([GccVersion], [$fp_cv_gcc_version]) else ===================================== compiler/GHC/Builtin/primops.txt.pp ===================================== @@ -2473,6 +2473,18 @@ primop WriteOffAddrOp_Word64 "writeWord64OffAddr#" GenPrimOp with has_side_effects = True can_fail = True +primop InterlockedExchange_Addr "interlockedExchangeAddr#" GenPrimOp + Addr# -> Addr# -> State# s -> (# State# s, Addr# #) + {The atomic exchange operation. Atomically exchanges the value at the first address + with the Addr# given as second argument. Implies a read barrier.} + with has_side_effects = True + +primop InterlockedExchange_Int "interlockedExchangeInt#" GenPrimOp + Addr# -> Int# -> State# s -> (# State# s, Int# #) + {The atomic exchange operation. Atomically exchanges the value at the address + with the given value. Returns the old value. Implies a read barrier.} + with has_side_effects = True + ------------------------------------------------------------------------ section "Mutable variables" {Operations on MutVar\#s.} ===================================== compiler/GHC/Cmm/MachOp.hs ===================================== @@ -632,6 +632,9 @@ data CallishMachOp | MO_AtomicRead Width | MO_AtomicWrite Width | MO_Cmpxchg Width + -- Should be an AtomicRMW variant eventually. + -- Sequential consistent. + | MO_Xchg Width deriving (Eq, Show) -- | The operation to perform atomically. ===================================== compiler/GHC/Cmm/Parser.y ===================================== @@ -1022,7 +1022,12 @@ callishMachOps = listToUFM $ ( "cmpxchg8", (MO_Cmpxchg W8,)), ( "cmpxchg16", (MO_Cmpxchg W16,)), ( "cmpxchg32", (MO_Cmpxchg W32,)), - ( "cmpxchg64", (MO_Cmpxchg W64,)) + ( "cmpxchg64", (MO_Cmpxchg W64,)), + + ( "xchg8", (MO_Xchg W8,)), + ( "xchg16", (MO_Xchg W16,)), + ( "xchg32", (MO_Xchg W32,)), + ( "xchg64", (MO_Xchg W64,)) -- ToDo: the rest, maybe -- edit: which rest? ===================================== compiler/GHC/CmmToAsm/CPrim.hs ===================================== @@ -4,6 +4,7 @@ module GHC.CmmToAsm.CPrim , atomicWriteLabel , atomicRMWLabel , cmpxchgLabel + , xchgLabel , popCntLabel , pdepLabel , pextLabel @@ -105,6 +106,15 @@ atomicRMWLabel w amop = "hs_atomic_" ++ pprFunName amop ++ pprWidth w pprFunName AMO_Or = "or" pprFunName AMO_Xor = "xor" +xchgLabel :: Width -> String +xchgLabel w = "hs_xchg" ++ pprWidth w + where + pprWidth W8 = "8" + pprWidth W16 = "16" + pprWidth W32 = "32" + pprWidth W64 = "64" + pprWidth w = pprPanic "xchgLabel: Unsupported word width " (ppr w) + cmpxchgLabel :: Width -> String cmpxchgLabel w = "hs_cmpxchg" ++ pprWidth w where ===================================== compiler/GHC/CmmToAsm/PPC/CodeGen.hs ===================================== @@ -2024,6 +2024,7 @@ genCCall' config gcp target dest_regs args MO_Ctz _ -> unsupported MO_AtomicRMW {} -> unsupported MO_Cmpxchg w -> (fsLit $ cmpxchgLabel w, False) + MO_Xchg w -> (fsLit $ xchgLabel w, False) MO_AtomicRead _ -> unsupported MO_AtomicWrite _ -> unsupported ===================================== compiler/GHC/CmmToAsm/SPARC/CodeGen.hs ===================================== @@ -677,6 +677,7 @@ outOfLineMachOp_table mop MO_Ctz w -> fsLit $ ctzLabel w MO_AtomicRMW w amop -> fsLit $ atomicRMWLabel w amop MO_Cmpxchg w -> fsLit $ cmpxchgLabel w + MO_Xchg w -> fsLit $ xchgLabel w MO_AtomicRead w -> fsLit $ atomicReadLabel w MO_AtomicWrite w -> fsLit $ atomicWriteLabel w ===================================== compiler/GHC/CmmToAsm/X86/CodeGen.hs ===================================== @@ -2518,6 +2518,22 @@ genCCall' _ is32Bit (PrimTarget (MO_Cmpxchg width)) [dst] [addr, old, new] _ = d where format = intFormat width +genCCall' config is32Bit (PrimTarget (MO_Xchg width)) [dst] [addr, value] _ + | (is32Bit && width == W64) = panic "gencCall: 64bit atomic exchange not supported on 32bit platforms" + | otherwise = do + let dst_r = getRegisterReg platform (CmmLocal dst) + Amode amode addr_code <- getSimpleAmode is32Bit addr + (newval, newval_code) <- getSomeReg value + -- Copy the value into the target register, perform the exchange. + let code = toOL + [ MOV format (OpReg newval) (OpReg dst_r) + , XCHG format (OpAddr amode) dst_r + ] + return $ addr_code `appOL` newval_code `appOL` code + where + format = intFormat width + platform = ncgPlatform config + genCCall' _ is32Bit target dest_regs args bid = do platform <- ncgPlatform <$> getConfig case (target, dest_regs) of @@ -3213,6 +3229,7 @@ outOfLineCmmOp bid mop res args MO_AtomicRead _ -> fsLit "atomicread" MO_AtomicWrite _ -> fsLit "atomicwrite" MO_Cmpxchg _ -> fsLit "cmpxchg" + MO_Xchg _ -> should_be_inline MO_UF_Conv _ -> unsupported @@ -3232,6 +3249,11 @@ outOfLineCmmOp bid mop res args (MO_Prefetch_Data _ ) -> unsupported unsupported = panic ("outOfLineCmmOp: " ++ show mop ++ " not supported here") + -- If we generate a call for the given primop + -- something went wrong. + should_be_inline = panic ("outOfLineCmmOp: " ++ show mop + ++ " should be handled inline") + -- ----------------------------------------------------------------------------- -- Generating a table-branch ===================================== compiler/GHC/CmmToAsm/X86/Instr.hs ===================================== @@ -329,6 +329,7 @@ data Instr | LOCK Instr -- lock prefix | XADD Format Operand Operand -- src (r), dst (r/m) | CMPXCHG Format Operand Operand -- src (r), dst (r/m), eax implicit + | XCHG Format Operand Reg -- src (r/m), dst (r/m) | MFENCE data PrefetchVariant = NTA | Lvl0 | Lvl1 | Lvl2 @@ -431,6 +432,7 @@ x86_regUsageOfInstr platform instr LOCK i -> x86_regUsageOfInstr platform i XADD _ src dst -> usageMM src dst CMPXCHG _ src dst -> usageRMM src dst (OpReg eax) + XCHG _ src dst -> usageMM src (OpReg dst) MFENCE -> noUsage _other -> panic "regUsage: unrecognised instr" @@ -460,6 +462,7 @@ x86_regUsageOfInstr platform instr usageMM :: Operand -> Operand -> RegUsage usageMM (OpReg src) (OpReg dst) = mkRU [src, dst] [src, dst] usageMM (OpReg src) (OpAddr ea) = mkRU (use_EA ea [src]) [src] + usageMM (OpAddr ea) (OpReg dst) = mkRU (use_EA ea [dst]) [dst] usageMM _ _ = panic "X86.RegInfo.usageMM: no match" -- 3 operand form; first operand Read; second Modified; third Modified @@ -589,6 +592,7 @@ x86_patchRegsOfInstr instr env LOCK i -> LOCK (x86_patchRegsOfInstr i env) XADD fmt src dst -> patch2 (XADD fmt) src dst CMPXCHG fmt src dst -> patch2 (CMPXCHG fmt) src dst + XCHG fmt src dst -> XCHG fmt (patchOp src) (env dst) MFENCE -> instr _other -> panic "patchRegs: unrecognised instr" ===================================== compiler/GHC/CmmToAsm/X86/Ppr.hs ===================================== @@ -824,6 +824,9 @@ pprInstr platform i = case i of SETCC cond op -> pprCondInstr (sLit "set") cond (pprOperand platform II8 op) + XCHG format src val + -> pprFormatOpReg (sLit "xchg") format src val + JXX cond blockid -> pprCondInstr (sLit "j") cond (ppr lab) where lab = blockLbl blockid ===================================== compiler/GHC/CmmToC.hs ===================================== @@ -831,6 +831,7 @@ pprCallishMachOp_for_C mop (MO_Ctz w) -> ptext (sLit $ ctzLabel w) (MO_AtomicRMW w amop) -> ptext (sLit $ atomicRMWLabel w amop) (MO_Cmpxchg w) -> ptext (sLit $ cmpxchgLabel w) + (MO_Xchg w) -> ptext (sLit $ xchgLabel w) (MO_AtomicRead w) -> ptext (sLit $ atomicReadLabel w) (MO_AtomicWrite w) -> ptext (sLit $ atomicWriteLabel w) (MO_UF_Conv w) -> ptext (sLit $ word2FloatLabel w) ===================================== compiler/GHC/CmmToLlvm/CodeGen.hs ===================================== @@ -281,6 +281,14 @@ genCall (PrimTarget (MO_Cmpxchg _width)) retVar' <- doExprW targetTy $ ExtractV retVar 0 statement $ Store retVar' dstVar +genCall (PrimTarget (MO_Xchg _width)) [] [addr, val] = runStmtsDecls $ do + addrVar <- exprToVarW addr + valVar <- exprToVarW val + let ptrTy = pLift $ getVarType valVar + ptrExpr = Cast LM_Inttoptr addrVar ptrTy + ptrVar <- doExprW ptrTy ptrExpr + statement $ Expr $ AtomicRMW LAO_Xchg ptrVar valVar SyncSeqCst + genCall (PrimTarget (MO_AtomicWrite _width)) [] [addr, val] = runStmtsDecls $ do addrVar <- exprToVarW addr valVar <- exprToVarW val @@ -856,6 +864,7 @@ cmmPrimOpFunctions mop = do MO_AtomicRMW _ _ -> unsupported MO_AtomicWrite _ -> unsupported MO_Cmpxchg _ -> unsupported + MO_Xchg _ -> unsupported -- | Tail function calls genJump :: CmmExpr -> [GlobalReg] -> LlvmM StmtData ===================================== compiler/GHC/StgToCmm/Prim.hs ===================================== @@ -856,6 +856,12 @@ emitPrimOp dflags = \case Word2DoubleOp -> \[w] -> opAllDone $ \[res] -> do emitPrimCall [res] (MO_UF_Conv W64) [w] +-- Atomic operations + InterlockedExchange_Addr -> \[src, value] -> opAllDone $ \[res] -> + emitPrimCall [res] (MO_Xchg (wordWidth platform)) [src, value] + InterlockedExchange_Int -> \[src, value] -> opAllDone $ \[res] -> + emitPrimCall [res] (MO_Xchg (wordWidth platform)) [src, value] + -- SIMD primops (VecBroadcastOp vcat n w) -> \[e] -> opAllDone $ \[res] -> do checkVecCompatibility dflags vcat n w ===================================== configure.ac ===================================== @@ -730,6 +730,8 @@ dnl unregisterised, Sparc, and PPC backends. FP_GCC_SUPPORTS__ATOMICS if test $CONF_GCC_SUPPORTS__ATOMICS = YES ; then AC_DEFINE([HAVE_C11_ATOMICS], [1], [Does GCC support __atomic primitives?]) +else + AC_MSG_ERROR([C compiler needs to support __atomic primitives.]) fi FP_GCC_EXTRA_FLAGS ===================================== docs/users_guide/8.12.1-notes.rst ===================================== @@ -148,11 +148,11 @@ Arrow notation ``hsGroupTopLevelFixitySigs`` function, which collects all top-level fixity signatures, including those for class methods defined inside classes. -- The ``Exception`` module was boiled down acknowledging the existence of +- The ``Exception`` module was boiled down acknowledging the existence of the ``exceptions`` dependency. In particular, the ``ExceptionMonad`` class is not a proper class anymore, but a mere synonym for ``MonadThrow``, - ``MonadCatch``, ``MonadMask`` (all from ``exceptions``) and ``MonadIO``. - All of ``g*``-functions from the module (``gtry``, ``gcatch``, etc.) are + ``MonadCatch``, ``MonadMask`` (all from ``exceptions``) and ``MonadIO``. + All of ``g*``-functions from the module (``gtry``, ``gcatch``, etc.) are erased, and their ``exceptions``-alternatives are meant to be used in the GHC code instead. @@ -162,6 +162,12 @@ Arrow notation Build system ~~~~~~~~~~~~ +Bootstrapping requirements +-------------------------- + +Starting with 8.12.1 GHC requires a C compiler which supports +__atomic_op_n builtins. This raises the requirement for GCC to 4.7. + Included libraries ------------------ ===================================== includes/stg/Prim.h ===================================== @@ -50,6 +50,10 @@ void hs_atomicwrite8(StgWord x, StgWord val); void hs_atomicwrite16(StgWord x, StgWord val); void hs_atomicwrite32(StgWord x, StgWord val); void hs_atomicwrite64(StgWord x, StgWord64 val); +StgWord hs_xchg8(StgPtr x, StgWord val); +StgWord hs_xchg16(StgPtr x, StgWord val); +StgWord hs_xchg32(StgPtr x, StgWord val); +StgWord hs_xchg64(StgPtr x, StgWord val); /* libraries/ghc-prim/cbits/bswap.c */ StgWord16 hs_bswap16(StgWord16 x); ===================================== libraries/base/GHC/Ptr.hs ===================================== @@ -1,5 +1,6 @@ {-# LANGUAGE Unsafe #-} {-# LANGUAGE CPP, NoImplicitPrelude, MagicHash, RoleAnnotations #-} +{-# LANGUAGE UnboxedTuples #-} {-# OPTIONS_HADDOCK not-home #-} ----------------------------------------------------------------------------- @@ -22,7 +23,10 @@ module GHC.Ptr ( nullFunPtr, castFunPtr, -- * Unsafe functions - castFunPtrToPtr, castPtrToFunPtr + castFunPtrToPtr, castPtrToFunPtr, + + -- * Atomic operations + exchangePtr ) where import GHC.Base @@ -162,6 +166,15 @@ castFunPtrToPtr (FunPtr addr) = Ptr addr castPtrToFunPtr :: Ptr a -> FunPtr b castPtrToFunPtr (Ptr addr) = FunPtr addr +------------------------------------------------------------------------ +-- Atomic operations for Ptr + +{-# INLINE exchangePtr #-} +exchangePtr :: Ptr (Ptr a) -> Ptr b -> IO (Ptr c) +exchangePtr (Ptr dst) (Ptr val) = + IO $ \s -> + case (interlockedExchangeAddr# dst val s) of + (# s2, old_val #) -> (# s2, Ptr old_val #) ------------------------------------------------------------------------ -- Show instances for Ptr and FunPtr ===================================== libraries/ghc-prim/cbits/atomic.c ===================================== @@ -318,6 +318,39 @@ hs_cmpxchg64(StgWord x, StgWord64 old, StgWord64 new) } #endif +// Atomic exchange operations + +extern StgWord hs_xchg8(StgPtr x, StgWord val); +StgWord +hs_xchg8(StgPtr x, StgWord val) +{ + return (StgWord) __atomic_exchange_n((StgWord8 *) x, (StgWord8) val, __ATOMIC_SEQ_CST); +} + +extern StgWord hs_xchg16(StgPtr x, StgWord val); +StgWord +hs_xchg16(StgPtr x, StgWord val) +{ + return (StgWord) __atomic_exchange_n((StgWord16 *)x, (StgWord16) val, __ATOMIC_SEQ_CST); +} + +extern StgWord hs_xchg32(StgPtr x, StgWord val); +StgWord +hs_xchg32(StgPtr x, StgWord val) +{ + return (StgWord) __atomic_exchange_n((StgWord32 *) x, (StgWord32) val, __ATOMIC_SEQ_CST); +} + +#if WORD_SIZE_IN_BITS == 64 +//GCC provides this even on 32bit, but StgWord is still 32 bits. +extern StgWord hs_xchg64(StgPtr x, StgWord val); +StgWord +hs_xchg64(StgPtr x, StgWord val) +{ + return (StgWord) __atomic_exchange_n((StgWord64 *) x, (StgWord64) val, __ATOMIC_SEQ_CST); +} +#endif + // AtomicReadByteArrayOp_Int // Implies a full memory barrier (see compiler/GHC/Builtin/primops.txt.pp) // __ATOMIC_SEQ_CST: Full barrier in both directions (hoisting and sinking ===================================== libraries/ghc-prim/changelog.md ===================================== @@ -1,3 +1,12 @@ +## TBD + +- Shipped with GHC 8.12.1 + +- Add primops for atomic exchange: + + interlockedExchangeAddr# :: Addr# -> Addr# -> State# s -> (# State# s, Addr# #) + interlockedExchangeInt# :: Addr# -> Int# -> State# s -> (# State# s, Int# #) + ## 0.6.1 (edit as necessary) - Shipped with GHC 8.10.1 ===================================== rts/package.conf.in ===================================== @@ -168,6 +168,10 @@ ld-options: #if WORD_SIZE_IN_BITS == 64 , "-Wl,-u,_hs_cmpxchg64" #endif + , "-Wl,-u,_hs_xchg8" + , "-Wl,-u,_hs_xchg16" + , "-Wl,-u,_hs_xchg32" + , "-Wl,-u,_hs_xchg64" , "-Wl,-u,_hs_atomicread8" , "-Wl,-u,_hs_atomicread16" , "-Wl,-u,_hs_atomicread32" @@ -273,6 +277,10 @@ ld-options: #if WORD_SIZE_IN_BITS == 64 , "-Wl,-u,hs_cmpxchg64" #endif + , "-Wl,-u,hs_xchg8" + , "-Wl,-u,hs_xchg16" + , "-Wl,-u,hs_xchg32" + , "-Wl,-u,hs_xchg64" , "-Wl,-u,hs_atomicread8" , "-Wl,-u,hs_atomicread16" , "-Wl,-u,hs_atomicread32" ===================================== rts/rts.cabal.in ===================================== @@ -264,6 +264,10 @@ library "-Wl,-u,_hs_cmpxchg8" "-Wl,-u,_hs_cmpxchg16" "-Wl,-u,_hs_cmpxchg32" + "-Wl,-u,_hs_xchg8" + "-Wl,-u,_hs_xchg16" + "-Wl,-u,_hs_xchg32" + "-Wl,-u,_hs_xchg64" "-Wl,-u,_hs_atomicread8" "-Wl,-u,_hs_atomicread16" "-Wl,-u,_hs_atomicread32" @@ -339,6 +343,10 @@ library "-Wl,-u,hs_cmpxchg8" "-Wl,-u,hs_cmpxchg16" "-Wl,-u,hs_cmpxchg32" + "-Wl,-u,hs_xchg8" + "-Wl,-u,hs_xchg16" + "-Wl,-u,hs_xchg32" + "-Wl,-u,hs_xchg64" "-Wl,-u,hs_atomicread8" "-Wl,-u,hs_atomicread16" "-Wl,-u,hs_atomicread32" ===================================== testsuite/tests/codeGen/should_run/all.T ===================================== @@ -205,3 +205,4 @@ test('T15892', test('T16617', normal, compile_and_run, ['']) test('T16449_2', exit_code(0), compile_and_run, ['']) test('T16846', [only_ways(['optasm']), exit_code(1)], compile_and_run, ['']) +test('cg_xchg001', normal, compile_and_run, ['']) \ No newline at end of file ===================================== testsuite/tests/codeGen/should_run/cg_xchg001.hs ===================================== @@ -0,0 +1,51 @@ +{-# LANGUAGE CPP, MagicHash, BlockArguments, UnboxedTuples #-} + +-- Tests for the atomic exchange primop. + +-- We initialize a value with 1, and then perform exchanges on it +-- with two different values. At the end all the values should still +-- be present. + +module Main ( main ) where + +import Data.Bits +import GHC.Int +import GHC.Prim +import GHC.Word +import Control.Monad +import Control.Concurrent +import Foreign.Marshal.Alloc +import Foreign.Storable +import Data.List (sort) + +import GHC.Exts +import GHC.Types + +#include "MachDeps.h" + +main = do + alloca $ \ptr_i -> do + poke ptr_i (1 :: Int) + w1 <- newEmptyMVar :: IO (MVar Int) + forkIO $ do + v <- swapN 50000 2 ptr_i + putMVar w1 v + + v2 <- swapN 50000 3 ptr_i + v1 <- takeMVar w1 + v0 <- peek ptr_i + -- Should be [1,2,3] + print $ sort [v0,v1,v2] + +swapN :: Int -> Int -> Ptr Int -> IO Int +swapN 0 val ptr = return val +swapN n val ptr = do + val' <- swap ptr val + swapN (n-1) val' ptr + + +swap :: Ptr Int -> Int -> IO Int +swap (Ptr ptr) (I# val) = do + IO $ \s -> case (interlockedExchangeInt# ptr val s) of + (# s2, old_val #) -> (# s2, I# old_val #) + ===================================== testsuite/tests/codeGen/should_run/cg_xchg001.stdout ===================================== @@ -0,0 +1 @@ +[1,2,3] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5f41b811209d851d31fbc1398a45e3523bff4f27 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5f41b811209d851d31fbc1398a45e3523bff4f27 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 20 16:25:40 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 20 May 2020 12:25:40 -0400 Subject: [Git][ghc/ghc][wip/T18069] SysTools.Process: Handle exceptions in readCreateProcessWithExitCode' Message-ID: <5ec55a044665d_6e263f9ee2d57e042658eb@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18069 at Glasgow Haskell Compiler / GHC Commits: 1b7719bf by Ben Gamari at 2020-05-20T12:25:31-04:00 SysTools.Process: Handle exceptions in readCreateProcessWithExitCode' In #18069 we are observing MVar deadlocks from somewhere in ghc.exe. This use of MVar stood out as being one of the more likely culprits. Here we make sure that it is exception-safe. - - - - - 1 changed file: - compiler/GHC/SysTools/Process.hs Changes: ===================================== compiler/GHC/SysTools/Process.hs ===================================== @@ -41,6 +41,15 @@ enableProcessJobs opts = opts { use_process_jobs = True } enableProcessJobs opts = opts #endif +#if !MIN_VERSION_base(4,15,0) +-- TODO: This can be dropped with GHC 8.16 +hGetContents' :: Handle -> IO String +hGetContents' hdl = do + output <- hGetContents hdl + _ <- evaluate $ length output + return output +#endif + -- Similar to System.Process.readCreateProcessWithExitCode, but stderr is -- inherited from the parent process, and output to stderr is not captured. readCreateProcessWithExitCode' @@ -51,13 +60,19 @@ readCreateProcessWithExitCode' proc = do createProcess proc{ std_out = CreatePipe } -- fork off a thread to start consuming the output - output <- hGetContents outh outMVar <- newEmptyMVar - _ <- forkIO $ evaluate (length output) >> putMVar outMVar () + let onError :: SomeException -> IO () + onError exc = putMVar outMVar (Left exc) + forkIO $ handle onError $ do + output <- hGetContents' outh + putMVar outMVar $ Right output -- wait on the output - takeMVar outMVar + result <- takeMVar outMVar hClose outh + output <- case result of + Left exc -> throwIO exc + Right output -> return output -- wait on the process ex <- waitForProcess pid View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1b7719bfa0c19f68e357cd0de7a742dd2d92d44c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1b7719bfa0c19f68e357cd0de7a742dd2d92d44c You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 20 16:26:28 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 20 May 2020 12:26:28 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18206 Message-ID: <5ec55a34e9406_6e2612cf46a02662e6@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/T18206 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18206 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 20 17:02:13 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Wed, 20 May 2020 13:02:13 -0400 Subject: [Git][ghc/ghc][wip/andreask/refactor_cmm_weights] Refactor linear reg alloc to remember past assignments. Message-ID: <5ec56295f2690_6e263f9ee2d57e042741bc@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/refactor_cmm_weights at Glasgow Haskell Compiler / GHC Commits: 76ca9357 by Andreas Klebinger at 2020-05-20T19:01:35+02:00 Refactor linear reg alloc to remember past assignments. When assigning registers we now first try registers we assigned to in the past, instead of picking the "first" one. This is in extremely helpful when dealing with loops for which variables are dead for part of the loop. This is important for patterns like this: foo = arg1 loop: use(foo) ... foo = getVal() goto loop; There we: * assign foo to the register of arg1. * use foo, it's dead after this use as it's overwritten after. * do other things. * look for a register to put foo in. If we pick an arbitrary one it might differ from the register the start of the loop expect's foo to be in. To fix this we simply look for past register assignments for the given variable. If we find one and the register is free we use that register. This reduces the need for fixup blocks which match the register assignment between blocks. In the example above between the end and the head of the loop. This patch also moves branch weight estimation ahead of register allocation and adds a flag to control it (cmm-static-pred). * It means the linear allocator is more likely to assign the hotter code paths first. * If it assign these first we are: + Less likely to spill on the hot path. + Less likely to introduce fixup blocks on the hot path. These two measure combined are surprisingly effective. Based on nofib we get in the mean: * -0.9% instructions executed * -0.1% reads/writes * -0.2% code size. * -0.1% compiler allocations. * -0.9% compile time. * -0.8% runtime. Most of the benefits are simply a result of removing redundant moves and spills. Reduced compiler allocations likely are the result of less code being generated. (The added lookup is mostly non-allocating). - - - - - 15 changed files: - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Reg/Linear.hs - compiler/GHC/CmmToAsm/Reg/Linear/Base.hs - compiler/GHC/CmmToAsm/Reg/Linear/PPC.hs - compiler/GHC/CmmToAsm/Reg/Linear/SPARC.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/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Utils/Outputable.hs - docs/users_guide/using-optimisation.rst Changes: ===================================== compiler/GHC/CmmToAsm.hs ===================================== @@ -728,7 +728,7 @@ cmmNativeGen dflags this_mod modLoc ncgImpl us fileIds dbgMap cmm count let optimizedCFG :: Maybe CFG optimizedCFG = - optimizeCFG (cfgWeightInfo dflags) cmm <$!> postShortCFG + optimizeCFG (gopt Opt_CmmStaticPred dflags) (cfgWeightInfo dflags) cmm <$!> postShortCFG maybeDumpCfg dflags optimizedCFG "CFG Weights - Final" proc_name ===================================== compiler/GHC/CmmToAsm/BlockLayout.hs ===================================== @@ -636,22 +636,8 @@ sequenceChain :: forall a i. (Instruction i, Outputable i) -> [GenBasicBlock i] -- ^ Blocks placed in sequence. sequenceChain _info _weights [] = [] sequenceChain _info _weights [x] = [x] -sequenceChain info weights' blocks@((BasicBlock entry _):_) = - let weights :: CFG - weights = --pprTrace "cfg'" (pprEdgeWeights cfg') - cfg' - where - (_, globalEdgeWeights) = {-# SCC mkGlobalWeights #-} mkGlobalWeights entry weights' - cfg' = {-# SCC rewriteEdges #-} - mapFoldlWithKey - (\cfg from m -> - mapFoldlWithKey - (\cfg to w -> setEdgeWeight cfg (EdgeWeight w) from to ) - cfg m ) - weights' - globalEdgeWeights - - directEdges :: [CfgEdge] +sequenceChain info weights blocks@((BasicBlock entry _):_) = + let directEdges :: [CfgEdge] directEdges = sortBy (flip compare) $ catMaybes . map relevantWeight $ (infoEdgeList weights) where relevantWeight :: CfgEdge -> Maybe CfgEdge ===================================== compiler/GHC/CmmToAsm/CFG.hs ===================================== @@ -670,11 +670,21 @@ findBackEdges root cfg = typedEdges = classifyEdges root getSuccs edges :: [((BlockId,BlockId),EdgeType)] - -optimizeCFG :: D.CfgWeights -> RawCmmDecl -> CFG -> CFG -optimizeCFG _ (CmmData {}) cfg = cfg -optimizeCFG weights (CmmProc info _lab _live graph) cfg = - {-# SCC optimizeCFG #-} +optimizeCFG :: Bool -> D.CfgWeights -> RawCmmDecl -> CFG -> CFG +optimizeCFG _ _ (CmmData {}) cfg = cfg +optimizeCFG doStaticPred weights proc@(CmmProc _info _lab _live graph) cfg = + (if doStaticPred then staticPredCfg (g_entry graph) else id) $ + optHsPatterns weights proc $ cfg + +-- | Modify branch weights based on educated guess on +-- patterns GHC tends to produce and how they affect +-- performance. +-- +-- Most importantly we penalize jumps across info tables. +optHsPatterns :: D.CfgWeights -> RawCmmDecl -> CFG -> CFG +optHsPatterns _ (CmmData {}) cfg = cfg +optHsPatterns weights (CmmProc info _lab _live graph) cfg = + {-# SCC optHsPatterns #-} -- pprTrace "Initial:" (pprEdgeWeights cfg) $ -- pprTrace "Initial:" (ppr $ mkGlobalWeights (g_entry graph) cfg) $ @@ -749,6 +759,21 @@ optimizeCFG weights (CmmProc info _lab _live graph) cfg = | CmmSource { trans_cmmNode = CmmCondBranch {} } <- source = True | otherwise = False +-- | Convert block-local branch weights to global weights. +staticPredCfg :: BlockId -> CFG -> CFG +staticPredCfg entry cfg = cfg' + where + (_, globalEdgeWeights) = {-# SCC mkGlobalWeights #-} + mkGlobalWeights entry cfg + cfg' = {-# SCC rewriteEdges #-} + mapFoldlWithKey + (\cfg from m -> + mapFoldlWithKey + (\cfg to w -> setEdgeWeight cfg (EdgeWeight w) from to ) + cfg m ) + cfg + globalEdgeWeights + -- | Determine loop membership of blocks based on SCC analysis -- This is faster but only gives yes/no answers. loopMembers :: HasDebugCallStack => CFG -> LabelMap Bool @@ -922,6 +947,10 @@ revPostorderFrom cfg root = -- reverse post order. Which is required for diamond control flow to work probably. -- -- We also apply a few prediction heuristics (based on the same paper) +-- +-- The returned result represents frequences. +-- For blocks it's the expected number of executions and +-- for edges is the number of traversals. {-# NOINLINE mkGlobalWeights #-} {-# SCC mkGlobalWeights #-} ===================================== compiler/GHC/CmmToAsm/Instr.hs ===================================== @@ -37,7 +37,10 @@ import GHC.CmmToAsm.Config -- (for allocation purposes, anyway). -- data RegUsage - = RU [Reg] [Reg] + = RU { + reads :: [Reg], + writes :: [Reg] + } -- | No regs read or written to. noUsage :: RegUsage ===================================== compiler/GHC/CmmToAsm/Reg/Linear.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE BangPatterns, CPP, ScopedTypeVariables #-} +{-# LANGUAGE ConstraintKinds #-} {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} @@ -137,6 +138,7 @@ import GHC.Platform import Data.Maybe import Data.List import Control.Monad +import Control.Applicative -- ----------------------------------------------------------------------------- -- Top level of the register allocator @@ -229,8 +231,13 @@ linearRegAlloc config entry_ids block_live sccs go f = linearRegAlloc' config f entry_ids block_live sccs platform = ncgPlatform config +-- | Constraints on the instruction instances used by the +-- linear allocator. +type OutputableRegConstraint freeRegs instr = + (FR freeRegs, Outputable freeRegs, Outputable instr, Instruction instr) + linearRegAlloc' - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => NCGConfig -> freeRegs -> [BlockId] -- ^ entry points @@ -246,7 +253,7 @@ linearRegAlloc' config initFreeRegs entry_ids block_live sccs return (blocks, stats, getStackUse stack) -linearRA_SCCs :: (FR freeRegs, Instruction instr, Outputable instr) +linearRA_SCCs :: OutputableRegConstraint freeRegs instr => [BlockId] -> BlockMap RegSet -> [NatBasicBlock instr] @@ -281,7 +288,7 @@ linearRA_SCCs entry_ids block_live blocksAcc (CyclicSCC blocks : sccs) more sanity checking to guard against this eventuality. -} -process :: (FR freeRegs, Instruction instr, Outputable instr) +process :: OutputableRegConstraint freeRegs instr => [BlockId] -> BlockMap RegSet -> [GenBasicBlock (LiveInstr instr)] @@ -325,15 +332,18 @@ process entry_ids block_live (b@(BasicBlock id _) : blocks) -- | Do register allocation on this basic block -- processBlock - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ live regs on entry to each basic block -> LiveBasicBlock instr -- ^ block to do register allocation on -> RegM freeRegs [NatBasicBlock instr] -- ^ block with registers allocated processBlock block_live (BasicBlock id instrs) - = do initBlock id block_live + = do -- pprTraceM "processBlock" $ text "" $$ ppr (BasicBlock id instrs) + initBlock id block_live + (instrs', fixups) <- linearRA block_live [] [] id instrs + -- pprTraceM "blockResult" $ ppr (instrs', fixups) return $ BasicBlock id instrs' : fixups @@ -369,7 +379,7 @@ initBlock id block_live -- | Do allocation for a sequence of instructions. linearRA - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ map of what vregs are live on entry to each block. -> [instr] -- ^ accumulator for instructions already processed. -> [NatBasicBlock instr] -- ^ accumulator for blocks of fixup code. @@ -396,7 +406,7 @@ linearRA block_live accInstr accFixups id (instr:instrs) -- | Do allocation for a single instruction. raInsn - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ 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 @@ -476,7 +486,7 @@ isInReg src assig | Just (InReg _) <- lookupUFM assig src = True | otherwise = False -genRaInsn :: (FR freeRegs, Instruction instr, Outputable instr) +genRaInsn :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -> [instr] -> BlockId @@ -486,6 +496,7 @@ genRaInsn :: (FR freeRegs, Instruction instr, Outputable instr) -> RegM freeRegs ([instr], [NatBasicBlock instr]) genRaInsn block_live new_instrs block_id instr r_dying w_dying = do +-- pprTraceM "genRaInsn" $ ppr (block_id, instr) platform <- getPlatform case regUsageOfInstr platform instr of { RU read written -> do @@ -525,6 +536,8 @@ genRaInsn block_live new_instrs block_id instr r_dying w_dying = do (fixup_blocks, adjusted_instr) <- joinToTargets block_live block_id instr +-- when (not $ null fixup_blocks) $ pprTraceM "genRA:FixBlocks" $ ppr fixup_blocks + -- Debugging - show places where the reg alloc inserted -- assignment fixup blocks. -- when (not $ null fixup_blocks) $ @@ -737,7 +750,7 @@ data SpillLoc = ReadMem StackSlot -- reading from register only in memory -- the list of free registers and free stack slots. allocateRegsAndSpill - :: (FR freeRegs, Outputable instr, Instruction instr) + :: forall freeRegs instr. (FR freeRegs, Outputable instr, Instruction instr) => Bool -- True <=> reading (load up spilled regs) -> [VirtualReg] -- don't push these out -> [instr] -- spill insns @@ -749,7 +762,8 @@ allocateRegsAndSpill _ _ spills alloc [] = return (spills, reverse alloc) allocateRegsAndSpill reading keep spills alloc (r:rs) - = do assig <- getAssigR + = do assig <- getAssigR :: RegM freeRegs (RegMap Loc) + -- pprTraceM "allocateRegsAndSpill:assig" (ppr (r:rs) $$ ppr assig) let doSpill = allocRegsAndSpill_spill reading keep spills alloc r rs assig case lookupUFM assig r of -- case (1a): already in a register @@ -779,6 +793,26 @@ allocateRegsAndSpill reading keep spills alloc (r:rs) | otherwise -> doSpill WriteNew +-- | Given a virtual reg find a preferred real register. +-- The preferred register is simply the first one the variable +-- was assigned to (if any). This way when we allocate for a loop +-- variables are likely to end up in the same registers at the +-- end and start of the loop, avoiding redundant reg-reg moves. +-- Note: I tried returning a list of past assignments, but that +-- turned out to barely matter but added a few tenths of +-- a percent to compile time. +findPrefRealReg :: forall freeRegs u. Uniquable u + => u -> RegM freeRegs (Maybe RealReg) +findPrefRealReg vreg = do + bassig <- getBlockAssigR :: RegM freeRegs (BlockMap (freeRegs,RegMap Loc)) + return $ foldr (findVirtRegAssig) Nothing bassig + where + findVirtRegAssig :: (freeRegs,RegMap Loc) -> Maybe RealReg -> Maybe RealReg + findVirtRegAssig assig z = + z <|> case lookupUFM (snd assig) vreg of + Just (InReg real_reg) -> Just real_reg + Just (InBoth real_reg _) -> Just real_reg + _ -> z -- reading is redundant with reason, but we keep it around because it's -- convenient and it maintains the recursive structure of the allocator. -- EZY @@ -795,18 +829,26 @@ allocRegsAndSpill_spill :: (FR freeRegs, Instruction instr, Outputable instr) allocRegsAndSpill_spill reading keep spills alloc r rs assig spill_loc = do platform <- getPlatform freeRegs <- getFreeRegsR - let freeRegs_thisClass = frGetFreeRegs platform (classOfVirtualReg r) freeRegs + let freeRegs_thisClass = frGetFreeRegs platform (classOfVirtualReg r) freeRegs :: [RealReg] - case freeRegs_thisClass of + -- Can we put the variable into a register it already was? + pref_reg <- findPrefRealReg r + case freeRegs_thisClass of -- case (2): we have a free register - (my_reg : _) -> - do spills' <- loadTemp r spill_loc my_reg spills + (first_free : _) -> + do let final_reg + | Just reg <- pref_reg + , reg `elem` freeRegs_thisClass + = reg + | otherwise + = first_free + spills' <- loadTemp r spill_loc final_reg spills - setAssigR (addToUFM assig r $! newLocation spill_loc my_reg) - setFreeRegsR $ frAllocateReg platform my_reg freeRegs + setAssigR (addToUFM assig r $! newLocation spill_loc final_reg) + setFreeRegsR $ frAllocateReg platform final_reg freeRegs - allocateRegsAndSpill reading keep spills' (my_reg : alloc) rs + allocateRegsAndSpill reading keep spills' (final_reg : alloc) rs -- case (3): we need to push something out to free up a register @@ -814,7 +856,8 @@ allocRegsAndSpill_spill reading keep spills alloc r rs assig spill_loc do let inRegOrBoth (InReg _) = True inRegOrBoth (InBoth _ _) = True inRegOrBoth _ = False - let candidates' = + let candidates' :: UniqFM Loc + candidates' = flip delListFromUFM keep $ filterUFM inRegOrBoth $ assig ===================================== compiler/GHC/CmmToAsm/Reg/Linear/Base.hs ===================================== @@ -30,6 +30,7 @@ import GHC.Types.Unique.FM import GHC.Types.Unique.Supply import GHC.Cmm.BlockId +data ReadingOrWriting = Reading | Writing deriving (Eq,Ord) -- | Used to store the register assignment on entry to a basic block. -- We use this to handle join points, where multiple branch instructions @@ -138,6 +139,8 @@ data RA_State freeRegs , ra_config :: !NCGConfig -- | (from,fixup,to) : We inserted fixup code between from and to - , ra_fixups :: [(BlockId,BlockId,BlockId)] } + , ra_fixups :: [(BlockId,BlockId,BlockId)] + + } ===================================== compiler/GHC/CmmToAsm/Reg/Linear/PPC.hs ===================================== @@ -1,3 +1,5 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} + -- | Free regs map for PowerPC module GHC.CmmToAsm.Reg.Linear.PPC where @@ -27,6 +29,9 @@ import Data.Bits data FreeRegs = FreeRegs !Word32 !Word32 deriving( Show ) -- The Show is used in an ASSERT +instance Outputable FreeRegs where + ppr = text . show + noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/SPARC.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for SPARC module GHC.CmmToAsm.Reg.Linear.SPARC where @@ -38,6 +39,9 @@ data FreeRegs instance Show FreeRegs where show = showFreeRegs +instance Outputable FreeRegs where + ppr = text . showFreeRegs + -- | A reg map where no regs are free to be allocated. noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 0 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/State.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE CPP, PatternSynonyms, DeriveFunctor #-} +{-# LANGUAGE ScopedTypeVariables #-} #if !defined(GHC_LOADED_INTO_GHCI) {-# LANGUAGE UnboxedTuples #-} ===================================== compiler/GHC/CmmToAsm/Reg/Linear/X86.hs ===================================== @@ -1,3 +1,4 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for i386 module GHC.CmmToAsm.Reg.Linear.X86 where @@ -9,12 +10,13 @@ import GHC.Platform.Reg.Class import GHC.Platform.Reg import GHC.Utils.Panic import GHC.Platform +import GHC.Utils.Outputable import Data.Word import Data.Bits newtype FreeRegs = FreeRegs Word32 - deriving Show + deriving (Show,Outputable) noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/X86_64.hs ===================================== @@ -1,3 +1,4 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for x86_64 module GHC.CmmToAsm.Reg.Linear.X86_64 where @@ -9,12 +10,13 @@ import GHC.Platform.Reg.Class import GHC.Platform.Reg import GHC.Utils.Panic import GHC.Platform +import GHC.Utils.Outputable import Data.Word import Data.Bits newtype FreeRegs = FreeRegs Word64 - deriving Show + deriving (Show,Outputable) noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -181,6 +181,7 @@ data GeneralFlag | Opt_LlvmFillUndefWithGarbage -- Testing for undef bugs (hidden flag) | Opt_IrrefutableTuples | Opt_CmmSink + | Opt_CmmStaticPred | Opt_CmmElimCommonBlocks | Opt_AsmShortcutting | Opt_OmitYields ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -3514,6 +3514,7 @@ fFlagsDeps = [ flagSpec "case-folding" Opt_CaseFolding, flagSpec "cmm-elim-common-blocks" Opt_CmmElimCommonBlocks, flagSpec "cmm-sink" Opt_CmmSink, + flagSpec "cmm-static-pred" Opt_CmmStaticPred, flagSpec "cse" Opt_CSE, flagSpec "stg-cse" Opt_StgCSE, flagSpec "stg-lift-lams" Opt_StgLiftLams, @@ -4065,6 +4066,7 @@ optLevelFlags -- see Note [Documenting optimisation flags] , ([1,2], Opt_CmmElimCommonBlocks) , ([2], Opt_AsmShortcutting) , ([1,2], Opt_CmmSink) + , ([1,2], Opt_CmmStaticPred) , ([1,2], Opt_CSE) , ([1,2], Opt_StgCSE) , ([2], Opt_StgLiftLams) ===================================== compiler/GHC/Utils/Outputable.hs ===================================== @@ -837,6 +837,9 @@ instance Outputable Word16 where instance Outputable Word32 where ppr n = integer $ fromIntegral n +instance Outputable Word64 where + ppr n = integer $ fromIntegral n + instance Outputable Word where ppr n = integer $ fromIntegral n ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -214,6 +214,19 @@ by saying ``-fno-wombat``. to their usage sites. It also inlines simple expressions like literals or registers. +.. ghc-flag:: -fcmm-static-pred + :shortdesc: Enable static control flow prediction. Implied by :ghc-flag:`-O`. + :type: dynamic + :reverse: -fno-cmm-static-pred + :category: + + :default: off but enabled with :ghc-flag:`-O`. + + This enables static control flow prediction on the final Cmm + code. If enabled GHC will apply certain heuristics to identify + loops and hot code paths. This information is then used by the + register allocation and code layout passes. + .. ghc-flag:: -fasm-shortcutting :shortdesc: Enable shortcutting on assembly. Implied by :ghc-flag:`-O2`. :type: dynamic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/76ca9357fbb9e89a2c3c85edb8433c946e01c884 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/76ca9357fbb9e89a2c3c85edb8433c946e01c884 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 20 17:26:27 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Wed, 20 May 2020 13:26:27 -0400 Subject: [Git][ghc/ghc][wip/andreask/refactor_cmm_weights] Refactor linear reg alloc to remember past assignments. Message-ID: <5ec568434ac16_6e26114c4d28288857@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/refactor_cmm_weights at Glasgow Haskell Compiler / GHC Commits: 2533c8f6 by Andreas Klebinger at 2020-05-20T19:26:12+02:00 Refactor linear reg alloc to remember past assignments. When assigning registers we now first try registers we assigned to in the past, instead of picking the "first" one. This is in extremely helpful when dealing with loops for which variables are dead for part of the loop. This is important for patterns like this: foo = arg1 loop: use(foo) ... foo = getVal() goto loop; There we: * assign foo to the register of arg1. * use foo, it's dead after this use as it's overwritten after. * do other things. * look for a register to put foo in. If we pick an arbitrary one it might differ from the register the start of the loop expect's foo to be in. To fix this we simply look for past register assignments for the given variable. If we find one and the register is free we use that register. This reduces the need for fixup blocks which match the register assignment between blocks. In the example above between the end and the head of the loop. This patch also moves branch weight estimation ahead of register allocation and adds a flag to control it (cmm-static-pred). * It means the linear allocator is more likely to assign the hotter code paths first. * If it assign these first we are: + Less likely to spill on the hot path. + Less likely to introduce fixup blocks on the hot path. These two measure combined are surprisingly effective. Based on nofib we get in the mean: * -0.9% instructions executed * -0.1% reads/writes * -0.2% code size. * -0.1% compiler allocations. * -0.9% compile time. * -0.8% runtime. Most of the benefits are simply a result of removing redundant moves and spills. Reduced compiler allocations likely are the result of less code being generated. (The added lookup is mostly non-allocating). - - - - - 16 changed files: - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Reg/Linear.hs - compiler/GHC/CmmToAsm/Reg/Linear/Base.hs - compiler/GHC/CmmToAsm/Reg/Linear/PPC.hs - compiler/GHC/CmmToAsm/Reg/Linear/SPARC.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/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Utils/Outputable.hs - docs/users_guide/8.12.1-notes.rst - docs/users_guide/using-optimisation.rst Changes: ===================================== compiler/GHC/CmmToAsm.hs ===================================== @@ -728,7 +728,7 @@ cmmNativeGen dflags this_mod modLoc ncgImpl us fileIds dbgMap cmm count let optimizedCFG :: Maybe CFG optimizedCFG = - optimizeCFG (cfgWeightInfo dflags) cmm <$!> postShortCFG + optimizeCFG (gopt Opt_CmmStaticPred dflags) (cfgWeightInfo dflags) cmm <$!> postShortCFG maybeDumpCfg dflags optimizedCFG "CFG Weights - Final" proc_name ===================================== compiler/GHC/CmmToAsm/BlockLayout.hs ===================================== @@ -636,22 +636,8 @@ sequenceChain :: forall a i. (Instruction i, Outputable i) -> [GenBasicBlock i] -- ^ Blocks placed in sequence. sequenceChain _info _weights [] = [] sequenceChain _info _weights [x] = [x] -sequenceChain info weights' blocks@((BasicBlock entry _):_) = - let weights :: CFG - weights = --pprTrace "cfg'" (pprEdgeWeights cfg') - cfg' - where - (_, globalEdgeWeights) = {-# SCC mkGlobalWeights #-} mkGlobalWeights entry weights' - cfg' = {-# SCC rewriteEdges #-} - mapFoldlWithKey - (\cfg from m -> - mapFoldlWithKey - (\cfg to w -> setEdgeWeight cfg (EdgeWeight w) from to ) - cfg m ) - weights' - globalEdgeWeights - - directEdges :: [CfgEdge] +sequenceChain info weights blocks@((BasicBlock entry _):_) = + let directEdges :: [CfgEdge] directEdges = sortBy (flip compare) $ catMaybes . map relevantWeight $ (infoEdgeList weights) where relevantWeight :: CfgEdge -> Maybe CfgEdge ===================================== compiler/GHC/CmmToAsm/CFG.hs ===================================== @@ -670,11 +670,21 @@ findBackEdges root cfg = typedEdges = classifyEdges root getSuccs edges :: [((BlockId,BlockId),EdgeType)] - -optimizeCFG :: D.CfgWeights -> RawCmmDecl -> CFG -> CFG -optimizeCFG _ (CmmData {}) cfg = cfg -optimizeCFG weights (CmmProc info _lab _live graph) cfg = - {-# SCC optimizeCFG #-} +optimizeCFG :: Bool -> D.CfgWeights -> RawCmmDecl -> CFG -> CFG +optimizeCFG _ _ (CmmData {}) cfg = cfg +optimizeCFG doStaticPred weights proc@(CmmProc _info _lab _live graph) cfg = + (if doStaticPred then staticPredCfg (g_entry graph) else id) $ + optHsPatterns weights proc $ cfg + +-- | Modify branch weights based on educated guess on +-- patterns GHC tends to produce and how they affect +-- performance. +-- +-- Most importantly we penalize jumps across info tables. +optHsPatterns :: D.CfgWeights -> RawCmmDecl -> CFG -> CFG +optHsPatterns _ (CmmData {}) cfg = cfg +optHsPatterns weights (CmmProc info _lab _live graph) cfg = + {-# SCC optHsPatterns #-} -- pprTrace "Initial:" (pprEdgeWeights cfg) $ -- pprTrace "Initial:" (ppr $ mkGlobalWeights (g_entry graph) cfg) $ @@ -749,6 +759,21 @@ optimizeCFG weights (CmmProc info _lab _live graph) cfg = | CmmSource { trans_cmmNode = CmmCondBranch {} } <- source = True | otherwise = False +-- | Convert block-local branch weights to global weights. +staticPredCfg :: BlockId -> CFG -> CFG +staticPredCfg entry cfg = cfg' + where + (_, globalEdgeWeights) = {-# SCC mkGlobalWeights #-} + mkGlobalWeights entry cfg + cfg' = {-# SCC rewriteEdges #-} + mapFoldlWithKey + (\cfg from m -> + mapFoldlWithKey + (\cfg to w -> setEdgeWeight cfg (EdgeWeight w) from to ) + cfg m ) + cfg + globalEdgeWeights + -- | Determine loop membership of blocks based on SCC analysis -- This is faster but only gives yes/no answers. loopMembers :: HasDebugCallStack => CFG -> LabelMap Bool @@ -922,6 +947,10 @@ revPostorderFrom cfg root = -- reverse post order. Which is required for diamond control flow to work probably. -- -- We also apply a few prediction heuristics (based on the same paper) +-- +-- The returned result represents frequences. +-- For blocks it's the expected number of executions and +-- for edges is the number of traversals. {-# NOINLINE mkGlobalWeights #-} {-# SCC mkGlobalWeights #-} ===================================== compiler/GHC/CmmToAsm/Instr.hs ===================================== @@ -37,7 +37,10 @@ import GHC.CmmToAsm.Config -- (for allocation purposes, anyway). -- data RegUsage - = RU [Reg] [Reg] + = RU { + reads :: [Reg], + writes :: [Reg] + } -- | No regs read or written to. noUsage :: RegUsage ===================================== compiler/GHC/CmmToAsm/Reg/Linear.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE BangPatterns, CPP, ScopedTypeVariables #-} +{-# LANGUAGE ConstraintKinds #-} {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} @@ -137,6 +138,7 @@ import GHC.Platform import Data.Maybe import Data.List import Control.Monad +import Control.Applicative -- ----------------------------------------------------------------------------- -- Top level of the register allocator @@ -229,8 +231,13 @@ linearRegAlloc config entry_ids block_live sccs go f = linearRegAlloc' config f entry_ids block_live sccs platform = ncgPlatform config +-- | Constraints on the instruction instances used by the +-- linear allocator. +type OutputableRegConstraint freeRegs instr = + (FR freeRegs, Outputable freeRegs, Outputable instr, Instruction instr) + linearRegAlloc' - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => NCGConfig -> freeRegs -> [BlockId] -- ^ entry points @@ -246,7 +253,7 @@ linearRegAlloc' config initFreeRegs entry_ids block_live sccs return (blocks, stats, getStackUse stack) -linearRA_SCCs :: (FR freeRegs, Instruction instr, Outputable instr) +linearRA_SCCs :: OutputableRegConstraint freeRegs instr => [BlockId] -> BlockMap RegSet -> [NatBasicBlock instr] @@ -281,7 +288,7 @@ linearRA_SCCs entry_ids block_live blocksAcc (CyclicSCC blocks : sccs) more sanity checking to guard against this eventuality. -} -process :: (FR freeRegs, Instruction instr, Outputable instr) +process :: OutputableRegConstraint freeRegs instr => [BlockId] -> BlockMap RegSet -> [GenBasicBlock (LiveInstr instr)] @@ -325,15 +332,18 @@ process entry_ids block_live (b@(BasicBlock id _) : blocks) -- | Do register allocation on this basic block -- processBlock - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ live regs on entry to each basic block -> LiveBasicBlock instr -- ^ block to do register allocation on -> RegM freeRegs [NatBasicBlock instr] -- ^ block with registers allocated processBlock block_live (BasicBlock id instrs) - = do initBlock id block_live + = do -- pprTraceM "processBlock" $ text "" $$ ppr (BasicBlock id instrs) + initBlock id block_live + (instrs', fixups) <- linearRA block_live [] [] id instrs + -- pprTraceM "blockResult" $ ppr (instrs', fixups) return $ BasicBlock id instrs' : fixups @@ -369,7 +379,7 @@ initBlock id block_live -- | Do allocation for a sequence of instructions. linearRA - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ map of what vregs are live on entry to each block. -> [instr] -- ^ accumulator for instructions already processed. -> [NatBasicBlock instr] -- ^ accumulator for blocks of fixup code. @@ -396,7 +406,7 @@ linearRA block_live accInstr accFixups id (instr:instrs) -- | Do allocation for a single instruction. raInsn - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ 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 @@ -476,7 +486,7 @@ isInReg src assig | Just (InReg _) <- lookupUFM assig src = True | otherwise = False -genRaInsn :: (FR freeRegs, Instruction instr, Outputable instr) +genRaInsn :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -> [instr] -> BlockId @@ -486,6 +496,7 @@ genRaInsn :: (FR freeRegs, Instruction instr, Outputable instr) -> RegM freeRegs ([instr], [NatBasicBlock instr]) genRaInsn block_live new_instrs block_id instr r_dying w_dying = do +-- pprTraceM "genRaInsn" $ ppr (block_id, instr) platform <- getPlatform case regUsageOfInstr platform instr of { RU read written -> do @@ -525,6 +536,8 @@ genRaInsn block_live new_instrs block_id instr r_dying w_dying = do (fixup_blocks, adjusted_instr) <- joinToTargets block_live block_id instr +-- when (not $ null fixup_blocks) $ pprTraceM "genRA:FixBlocks" $ ppr fixup_blocks + -- Debugging - show places where the reg alloc inserted -- assignment fixup blocks. -- when (not $ null fixup_blocks) $ @@ -737,7 +750,7 @@ data SpillLoc = ReadMem StackSlot -- reading from register only in memory -- the list of free registers and free stack slots. allocateRegsAndSpill - :: (FR freeRegs, Outputable instr, Instruction instr) + :: forall freeRegs instr. (FR freeRegs, Outputable instr, Instruction instr) => Bool -- True <=> reading (load up spilled regs) -> [VirtualReg] -- don't push these out -> [instr] -- spill insns @@ -749,7 +762,8 @@ allocateRegsAndSpill _ _ spills alloc [] = return (spills, reverse alloc) allocateRegsAndSpill reading keep spills alloc (r:rs) - = do assig <- getAssigR + = do assig <- getAssigR :: RegM freeRegs (RegMap Loc) + -- pprTraceM "allocateRegsAndSpill:assig" (ppr (r:rs) $$ ppr assig) let doSpill = allocRegsAndSpill_spill reading keep spills alloc r rs assig case lookupUFM assig r of -- case (1a): already in a register @@ -779,6 +793,26 @@ allocateRegsAndSpill reading keep spills alloc (r:rs) | otherwise -> doSpill WriteNew +-- | Given a virtual reg find a preferred real register. +-- The preferred register is simply the first one the variable +-- was assigned to (if any). This way when we allocate for a loop +-- variables are likely to end up in the same registers at the +-- end and start of the loop, avoiding redundant reg-reg moves. +-- Note: I tried returning a list of past assignments, but that +-- turned out to barely matter but added a few tenths of +-- a percent to compile time. +findPrefRealReg :: forall freeRegs u. Uniquable u + => u -> RegM freeRegs (Maybe RealReg) +findPrefRealReg vreg = do + bassig <- getBlockAssigR :: RegM freeRegs (BlockMap (freeRegs,RegMap Loc)) + return $ foldr (findVirtRegAssig) Nothing bassig + where + findVirtRegAssig :: (freeRegs,RegMap Loc) -> Maybe RealReg -> Maybe RealReg + findVirtRegAssig assig z = + z <|> case lookupUFM (snd assig) vreg of + Just (InReg real_reg) -> Just real_reg + Just (InBoth real_reg _) -> Just real_reg + _ -> z -- reading is redundant with reason, but we keep it around because it's -- convenient and it maintains the recursive structure of the allocator. -- EZY @@ -795,18 +829,26 @@ allocRegsAndSpill_spill :: (FR freeRegs, Instruction instr, Outputable instr) allocRegsAndSpill_spill reading keep spills alloc r rs assig spill_loc = do platform <- getPlatform freeRegs <- getFreeRegsR - let freeRegs_thisClass = frGetFreeRegs platform (classOfVirtualReg r) freeRegs + let freeRegs_thisClass = frGetFreeRegs platform (classOfVirtualReg r) freeRegs :: [RealReg] - case freeRegs_thisClass of + -- Can we put the variable into a register it already was? + pref_reg <- findPrefRealReg r + case freeRegs_thisClass of -- case (2): we have a free register - (my_reg : _) -> - do spills' <- loadTemp r spill_loc my_reg spills + (first_free : _) -> + do let final_reg + | Just reg <- pref_reg + , reg `elem` freeRegs_thisClass + = reg + | otherwise + = first_free + spills' <- loadTemp r spill_loc final_reg spills - setAssigR (addToUFM assig r $! newLocation spill_loc my_reg) - setFreeRegsR $ frAllocateReg platform my_reg freeRegs + setAssigR (addToUFM assig r $! newLocation spill_loc final_reg) + setFreeRegsR $ frAllocateReg platform final_reg freeRegs - allocateRegsAndSpill reading keep spills' (my_reg : alloc) rs + allocateRegsAndSpill reading keep spills' (final_reg : alloc) rs -- case (3): we need to push something out to free up a register @@ -814,7 +856,8 @@ allocRegsAndSpill_spill reading keep spills alloc r rs assig spill_loc do let inRegOrBoth (InReg _) = True inRegOrBoth (InBoth _ _) = True inRegOrBoth _ = False - let candidates' = + let candidates' :: UniqFM Loc + candidates' = flip delListFromUFM keep $ filterUFM inRegOrBoth $ assig ===================================== compiler/GHC/CmmToAsm/Reg/Linear/Base.hs ===================================== @@ -30,6 +30,7 @@ import GHC.Types.Unique.FM import GHC.Types.Unique.Supply import GHC.Cmm.BlockId +data ReadingOrWriting = Reading | Writing deriving (Eq,Ord) -- | Used to store the register assignment on entry to a basic block. -- We use this to handle join points, where multiple branch instructions @@ -138,6 +139,8 @@ data RA_State freeRegs , ra_config :: !NCGConfig -- | (from,fixup,to) : We inserted fixup code between from and to - , ra_fixups :: [(BlockId,BlockId,BlockId)] } + , ra_fixups :: [(BlockId,BlockId,BlockId)] + + } ===================================== compiler/GHC/CmmToAsm/Reg/Linear/PPC.hs ===================================== @@ -1,3 +1,5 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} + -- | Free regs map for PowerPC module GHC.CmmToAsm.Reg.Linear.PPC where @@ -27,6 +29,9 @@ import Data.Bits data FreeRegs = FreeRegs !Word32 !Word32 deriving( Show ) -- The Show is used in an ASSERT +instance Outputable FreeRegs where + ppr = text . show + noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/SPARC.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for SPARC module GHC.CmmToAsm.Reg.Linear.SPARC where @@ -38,6 +39,9 @@ data FreeRegs instance Show FreeRegs where show = showFreeRegs +instance Outputable FreeRegs where + ppr = text . showFreeRegs + -- | A reg map where no regs are free to be allocated. noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 0 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/State.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE CPP, PatternSynonyms, DeriveFunctor #-} +{-# LANGUAGE ScopedTypeVariables #-} #if !defined(GHC_LOADED_INTO_GHCI) {-# LANGUAGE UnboxedTuples #-} ===================================== compiler/GHC/CmmToAsm/Reg/Linear/X86.hs ===================================== @@ -1,3 +1,4 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for i386 module GHC.CmmToAsm.Reg.Linear.X86 where @@ -9,12 +10,13 @@ import GHC.Platform.Reg.Class import GHC.Platform.Reg import GHC.Utils.Panic import GHC.Platform +import GHC.Utils.Outputable import Data.Word import Data.Bits newtype FreeRegs = FreeRegs Word32 - deriving Show + deriving (Show,Outputable) noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/X86_64.hs ===================================== @@ -1,3 +1,4 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for x86_64 module GHC.CmmToAsm.Reg.Linear.X86_64 where @@ -9,12 +10,13 @@ import GHC.Platform.Reg.Class import GHC.Platform.Reg import GHC.Utils.Panic import GHC.Platform +import GHC.Utils.Outputable import Data.Word import Data.Bits newtype FreeRegs = FreeRegs Word64 - deriving Show + deriving (Show,Outputable) noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -181,6 +181,7 @@ data GeneralFlag | Opt_LlvmFillUndefWithGarbage -- Testing for undef bugs (hidden flag) | Opt_IrrefutableTuples | Opt_CmmSink + | Opt_CmmStaticPred | Opt_CmmElimCommonBlocks | Opt_AsmShortcutting | Opt_OmitYields ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -3514,6 +3514,7 @@ fFlagsDeps = [ flagSpec "case-folding" Opt_CaseFolding, flagSpec "cmm-elim-common-blocks" Opt_CmmElimCommonBlocks, flagSpec "cmm-sink" Opt_CmmSink, + flagSpec "cmm-static-pred" Opt_CmmStaticPred, flagSpec "cse" Opt_CSE, flagSpec "stg-cse" Opt_StgCSE, flagSpec "stg-lift-lams" Opt_StgLiftLams, @@ -4065,6 +4066,7 @@ optLevelFlags -- see Note [Documenting optimisation flags] , ([1,2], Opt_CmmElimCommonBlocks) , ([2], Opt_AsmShortcutting) , ([1,2], Opt_CmmSink) + , ([1,2], Opt_CmmStaticPred) , ([1,2], Opt_CSE) , ([1,2], Opt_StgCSE) , ([2], Opt_StgLiftLams) ===================================== compiler/GHC/Utils/Outputable.hs ===================================== @@ -837,6 +837,9 @@ instance Outputable Word16 where instance Outputable Word32 where ppr n = integer $ fromIntegral n +instance Outputable Word64 where + ppr n = integer $ fromIntegral n + instance Outputable Word where ppr n = integer $ fromIntegral n ===================================== docs/users_guide/8.12.1-notes.rst ===================================== @@ -10,7 +10,14 @@ following sections. Highlights ---------- -- TODO +* NCG + + - The linear register allocator saw improvements reducing the number + of redundant move instructions. Rare edge cases can see double + digit improvements in runtime for inner loops. + + In the mean this improved runtime by about 0.8%. For details + see ticket #17823. Full details ------------ @@ -148,11 +155,11 @@ Arrow notation ``hsGroupTopLevelFixitySigs`` function, which collects all top-level fixity signatures, including those for class methods defined inside classes. -- The ``Exception`` module was boiled down acknowledging the existence of +- The ``Exception`` module was boiled down acknowledging the existence of the ``exceptions`` dependency. In particular, the ``ExceptionMonad`` class is not a proper class anymore, but a mere synonym for ``MonadThrow``, - ``MonadCatch``, ``MonadMask`` (all from ``exceptions``) and ``MonadIO``. - All of ``g*``-functions from the module (``gtry``, ``gcatch``, etc.) are + ``MonadCatch``, ``MonadMask`` (all from ``exceptions``) and ``MonadIO``. + All of ``g*``-functions from the module (``gtry``, ``gcatch``, etc.) are erased, and their ``exceptions``-alternatives are meant to be used in the GHC code instead. ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -214,6 +214,19 @@ by saying ``-fno-wombat``. to their usage sites. It also inlines simple expressions like literals or registers. +.. ghc-flag:: -fcmm-static-pred + :shortdesc: Enable static control flow prediction. Implied by :ghc-flag:`-O`. + :type: dynamic + :reverse: -fno-cmm-static-pred + :category: + + :default: off but enabled with :ghc-flag:`-O`. + + This enables static control flow prediction on the final Cmm + code. If enabled GHC will apply certain heuristics to identify + loops and hot code paths. This information is then used by the + register allocation and code layout passes. + .. ghc-flag:: -fasm-shortcutting :shortdesc: Enable shortcutting on assembly. Implied by :ghc-flag:`-O2`. :type: dynamic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2533c8f61bdf4049b4d7505d9bc7cc6343900cf2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2533c8f61bdf4049b4d7505d9bc7cc6343900cf2 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 20 17:34:18 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 20 May 2020 13:34:18 -0400 Subject: [Git][ghc/ghc][wip/noinline-panic] 134 commits: docs: drop note about not supporting shared libraries on unix systems Message-ID: <5ec56a1a39a88_6e263f9ee2dcbd2c293838@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/noinline-panic at Glasgow Haskell Compiler / GHC Commits: bca02fca by Adam Sandberg Ericsson at 2020-04-21T06:38:45-04:00 docs: drop note about not supporting shared libraries on unix systems [skip ci] - - - - - 6655f933 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Use ParserFlags in GHC.Runtime.Eval (#17957) Instead of passing `DynFlags` to functions such as `isStmt` and `hasImport` in `GHC.Runtime.Eval` we pass `ParserFlags`. It's a much simpler structure that can be created purely with `mkParserFlags'`. - - - - - 70be0fbc by Sylvain Henry at 2020-04-21T06:39:32-04:00 GHC.Runtime: avoid DynFlags (#17957) * add `getPlatform :: TcM Platform` helper * remove unused `DynFlags` parameter from `emptyPLS` - - - - - 35e43d48 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid DynFlags in Ppr code (#17957) * replace `DynFlags` parameters with `SDocContext` parameters for a few Ppr related functions: `bufLeftRenderSDoc`, `printSDoc`, `printSDocLn`, `showSDocOneLine`. * remove the use of `pprCols :: DynFlags -> Int` in Outputable. We already have the information via `sdocLineLength :: SDocContext -> Int` - - - - - ce5c2999 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid using sdocWithDynFlags (#17957) Remove one use of `sdocWithDynFlags` from `GHC.CmmToLlvm.llvmCodeGen'` and from `GHC.Driver.CodeOutput.profilingInitCode` - - - - - f2a98996 by Sylvain Henry at 2020-04-21T06:39:32-04:00 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957) * add a `DynFlags` parameter to `pprCLbl` * put `maybe_underscore` and `pprAsmCLbl` in a `where` clause to avoid `DynFlags` parameters - - - - - 747093b7 by Sylvain Henry at 2020-04-21T06:39:32-04:00 CmmToAsm DynFlags refactoring (#17957) * Remove `DynFlags` parameter from `isDynLinkName`: `isDynLinkName` used to test the global `ExternalDynamicRefs` flag. Now we test it outside of `isDynLinkName` * Add new fields into `NCGConfig`: current unit id, sse/bmi versions, externalDynamicRefs, etc. * Replace many uses of `DynFlags` by `NCGConfig` * Moved `BMI/SSE` datatypes into `GHC.Platform` - - - - - ffd7eef2 by Takenobu Tani at 2020-04-22T23:09:50-04:00 stg-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Stg/Syntax.hs <= stgSyn/StgSyn.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/CostCentre.hs <= profiling/CostCentre.hs This patch also updates old file path [2]: * utils/genapply/Main.hs <= utils/genapply/GenApply.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: commit 0cc4aad36f [skip ci] - - - - - e8a5d81b by Jonathan DK Gibbons at 2020-04-22T23:10:28-04:00 Refactor the `MatchResult` type in the desugarer This way, it does a better job of proving whether or not the fail operator is used. - - - - - dcb7fe5a by John Ericson at 2020-04-22T23:10:28-04:00 Remove panic in dsHandleMonadicFailure Rework dsHandleMonadicFailure to be correct by construction instead of using an unreachable panic. - - - - - cde23cd4 by John Ericson at 2020-04-22T23:10:28-04:00 Inline `adjustMatchResult` It is just `fmap` - - - - - 72cb6bcc by John Ericson at 2020-04-22T23:10:28-04:00 Generalize type of `matchCanFail` - - - - - 401f7bb3 by John Ericson at 2020-04-22T23:10:28-04:00 `MatchResult'` -> `MatchResult` Inline `MatchResult` alias accordingly. - - - - - 6c9fae23 by Alexis King at 2020-04-22T23:11:12-04:00 Mark DataCon wrappers CONLIKE Now that DataCon wrappers don’t inline until phase 0 (see commit b78cc64e923716ac0512c299f42d4d0012306c05), it’s important that case-of-known-constructor and RULE matching be able to see saturated applications of DataCon wrappers in unfoldings. Making them conlike is a natural way to do it, since they are, in fact, precisely the sort of thing the CONLIKE pragma exists to solve. Fixes #18012. This also bumps the version of the parsec submodule to incorporate a patch that avoids a metric increase on the haddock perf tests. The increase was not really a flaw in this patch, as parsec was implicitly relying on inlining heuristics. The patch to parsec just adds some INLINABLE pragmas, and we get a nice performance bump out of it (well beyond the performance we lost from this patch). Metric Decrease: T12234 WWRec haddock.Cabal haddock.base haddock.compiler - - - - - 48b8951e by Roland Senn at 2020-04-22T23:11:51-04:00 Fix tab-completion for :break (#17989) In tab-completion for the `:break` command, only those identifiers should be shown, that are accepted in the `:break` command. Hence these identifiers must be - defined in an interpreted module - top-level - currently in scope - listed in a `ModBreaks` value as a possible breakpoint. The identifiers my be qualified or unqualified. To get all possible top-level breakpoints for tab-completeion with the correct qualification do: 1. Build the list called `pifsBreaks` of all pairs of (Identifier, module-filename) from the `ModBreaks` values. Here all identifiers are unqualified. 2. Build the list called `pifInscope` of all pairs of (Identifiers, module-filename) with identifiers from the `GlobalRdrEnv`. Take only those identifiers that are in scope and have the correct prefix. Here the identifiers may be qualified. 3. From the `pifInscope` list seclect all pairs that can be found in the `pifsBreaks` list, by comparing only the unqualified part of the identifier. The remaining identifiers can be used for tab-completion. This ensures, that we show only identifiers, that can be used in a `:break` command. - - - - - 34a45ee6 by Peter Trommler at 2020-04-22T23:12:27-04:00 PPC NCG: Add DWARF constants and debug labels Fixes #11261 - - - - - ffde2348 by Simon Peyton Jones at 2020-04-22T23:13:06-04:00 Do eager instantation in terms This patch implements eager instantiation, a small but critical change to the type inference engine, #17173. The main change is this: When inferring types, always return an instantiated type (for now, deeply instantiated; in future shallowly instantiated) There is more discussion in https://www.tweag.io/posts/2020-04-02-lazy-eager-instantiation.html There is quite a bit of refactoring in this patch: * The ir_inst field of GHC.Tc.Utils.TcType.InferResultk has entirely gone. So tcInferInst and tcInferNoInst have collapsed into tcInfer. * Type inference of applications, via tcInferApp and tcInferAppHead, are substantially refactored, preparing the way for Quick Look impredicativity. * New pure function GHC.Tc.Gen.Expr.collectHsArgs and applyHsArgs are beatifully dual. We can see the zipper! * GHC.Tc.Gen.Expr.tcArgs is now much nicer; no longer needs to return a wrapper * In HsExpr, HsTypeApp now contains the the actual type argument, and is used in desugaring, rather than putting it in a mysterious wrapper. * I struggled a bit with good error reporting in Unify.matchActualFunTysPart. It's a little bit simpler than before, but still not great. Some smaller things * Rename tcPolyExpr --> tcCheckExpr tcMonoExpr --> tcLExpr * tcPatSig moves from GHC.Tc.Gen.HsType to GHC.Tc.Gen.Pat Metric Decrease: T9961 Reduction of 1.6% in comiler allocation on T9961, I think. - - - - - 6f84aca3 by Ben Gamari at 2020-04-22T23:13:43-04:00 rts: Ensure that sigaction structs are initialized I noticed these may have uninitialized fields when looking into #18037. The reporter says that zeroing them doesn't fix the MSAN failures they observe but zeroing them is the right thing to do regardless. - - - - - c29f0fa6 by Andreas Klebinger at 2020-04-22T23:14:21-04:00 Add "ddump-cmm-opt" as alias for "ddump-opt-cmm". - - - - - 4b4a8b60 by Ben Gamari at 2020-04-22T23:14:57-04:00 llvmGen: Remove -fast-llvm flag Issue #18076 drew my attention to the undocumented `-fast-llvm` flag for the LLVM code generator introduced in 22733532171330136d87533d523f565f2a4f102f. Speaking to Moritz about this, the motivation for this flag was to avoid potential incompatibilities between LLVM and the assembler/linker toolchain by making LLVM responsible for machine-code generation. Unfortunately, this cannot possibly work: the LLVM backend's mangler performs a number of transforms on the assembler generated by LLVM that are necessary for correctness. These are currently: * mangling Haskell functions' symbol types to be `object` instead of `function` on ELF platforms (necessary for tables-next-to-code) * mangling AVX instructions to ensure that we don't assume alignment (which LLVM otherwise does) * mangling Darwin's subsections-via-symbols directives Given that these are all necessary I don't believe that we can support `-fast-llvm`. Let's rather remove it. - - - - - 831b6642 by Moritz Angermann at 2020-04-22T23:15:33-04:00 Fix build warning; add more informative information to the linker; fix linker for empty sections - - - - - c409961a by Ryan Scott at 2020-04-22T23:16:12-04:00 Update commentary and slightly refactor GHC.Tc.Deriv.Infer There was some out-of-date commentary in `GHC.Tc.Deriv.Infer` that has been modernized. Along the way, I removed the `bad` constraints in `simplifyDeriv`, which did not serve any useful purpose (besides being printed in debugging output). Fixes #18073. - - - - - 125aa2b8 by Ömer Sinan Ağacan at 2020-04-22T23:16:51-04:00 Remove leftover comment in tcRnModule', redundant bind The code for the comment was moved in dc8c03b2a5c but the comment was forgotten. - - - - - 8ea37b01 by Sylvain Henry at 2020-04-22T23:17:34-04:00 RTS: workaround a Linux kernel bug in timerfd Reading a timerfd may return 0: https://lkml.org/lkml/2019/8/16/335. This is currently undocumented behavior and documentation "won't happen anytime soon" (https://lkml.org/lkml/2020/2/13/295). With this patch, we just ignore the result instead of crashing. It may fix #18033 but we can't be sure because we don't have enough information. See also this discussion about the kernel bug: https://github.com/Azure/sonic-swss-common/pull/302/files/1f070e7920c2e5d63316c0105bf4481e73d72dc9 - - - - - cd8409c2 by Ryan Scott at 2020-04-23T11:39:24-04:00 Create di_scoped_tvs for associated data family instances properly See `Note [Associated data family instances and di_scoped_tvs]` in `GHC.Tc.TyCl.Instance`, which explains all of the moving parts. Fixes #18055. - - - - - 339e8ece by Ben Gamari at 2020-04-23T11:40:02-04:00 hadrian/ghci: Allow arguments to be passed to GHCi Previously the arguments passed to hadrian/ghci were passed both to `hadrian` and GHCi. This is rather odd given that there are essentially not arguments in the intersection of the two. Let's just pass them to GHCi; this allows `hadrian/ghci -Werror`. - - - - - 5946c85a by Ben Gamari at 2020-04-23T11:40:38-04:00 testsuite: Don't attempt to read .std{err,out} files if they don't exist Simon reports that he was previously seeing framework failures due to an attempt to read the non-existing T13456.stderr. While I don't know exactly what this is due to, it does seem like a non-existing .std{out,err} file should be equivalent to an empty file. Teach the testsuite driver to treat it as such. - - - - - c42754d5 by John Ericson at 2020-04-23T18:32:43-04:00 Trees That Grow refactor for `ConPat` and `CoPat` - `ConPat{In,Out}` -> `ConPat` - `CoPat` -> `XPat (CoPat ..)` Note that `GHC.HS.*` still uses `HsWrap`, but only when `p ~ GhcTc`. After this change, moving the type family instances out of `GHC.HS.*` is sufficient to break the cycle. Add XCollectPat class to decide how binders are collected from XXPat based on the pass. Previously we did this with IsPass, but that doesn't work for Haddock's DocNameI, and the constraint doesn't express what actual distinction is being made. Perhaps a class for collecting binders more generally is in order, but we haven't attempted this yet. Pure refactor of code around ConPat - InPat/OutPat synonyms removed - rename several identifiers - redundant constraints removed - move extension field in ConPat to be first - make ConPat use record syntax more consistently Fix T6145 (ConPatIn became ConPat) Add comments from SPJ. Add comment about haddock's use of CollectPass. Updates haddock submodule. - - - - - 72da0c29 by mniip at 2020-04-23T18:33:21-04:00 Add :doc to GHC.Prim - - - - - 2c23e2e3 by mniip at 2020-04-23T18:33:21-04:00 Include docs for non-primop entries in primops.txt as well - - - - - 0ac29c88 by mniip at 2020-04-23T18:33:21-04:00 GHC.Prim docs: note and test - - - - - b0fbfc75 by John Ericson at 2020-04-24T12:07:14-04:00 Switch order on `GhcMake.IsBoot` In !1798 we were requested to replace many `Bool`s with this data type. But those bools had `False` meaning `NotBoot`, so the `Ord` instance would be flipped if we use this data-type as-is. Since the planned formally-`Bool` occurrences vastly outnumber the current occurrences, we figured it would be better to conform the `Ord` instance to how the `Bool` is used now, fixing any issues, rather than fix them currently with the bigger refactor later in !1798. That way, !1798 can be a "pure" refactor with no behavioral changes. - - - - - af332442 by Sylvain Henry at 2020-04-26T13:55:14-04:00 Modules: Utils and Data (#13009) Update Haddock submodule Metric Increase: haddock.compiler - - - - - cd4434c8 by Sylvain Henry at 2020-04-26T13:55:16-04:00 Fix misleading Ptr phantom type in SerializedCompact (#15653) - - - - - 22bf5c73 by Ömer Sinan Ağacan at 2020-04-26T13:55:22-04:00 Tweak includes in non-moving GC headers We don't use hash tables in non-moving GC so remove the includes. This breaks Compact.c as existing includes no longer include Hash.h, so include Hash.h explicitly in Compact.c. - - - - - 99823ed2 by Sylvain Henry at 2020-04-27T20:24:46-04:00 TH: fix Show/Eq/Ord instances for Bytes (#16457) We shouldn't compare pointer values but the actual bytes. - - - - - c62271a2 by Alp Mestanogullari at 2020-04-27T20:25:33-04:00 hadrian: always capture both stdout and stderr when running a builder fails The idea being that when a builder('s command) fails, we quite likely want to have all the information available to figure out why. Depending on the builder _and_ the particular problem, the useful bits of information can be printed on stdout or stderr. We accomplish this by defining a simple wrapper for Shake's `cmd` function, that just _always_ captures both streams in case the command returns a non-zero exit code, and by using this wrapper everywhere in `hadrian/src/Builder.hs`. Fixes #18089. - - - - - 4b9764db by Ryan Scott at 2020-04-28T15:40:04-04:00 Define a Quote IO instance Fixes #18103. - - - - - 518a63d4 by Ryan Scott at 2020-04-28T15:40:42-04:00 Make boxed 1-tuples have known keys Unlike other tuples, which use special syntax and are "known" by way of a special `isBuiltInOcc_maybe` code path, boxed 1-tuples do not use special syntax. Therefore, in order to make sure that the internals of GHC are aware of the `data Unit a = Unit a` definition in `GHC.Tuple`, we give `Unit` known keys. For the full details, see `Note [One-tuples] (Wrinkle: Make boxed one-tuple names have known keys)` in `GHC.Builtin.Types`. Fixes #18097. - - - - - 2cfc4ab9 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Document backpack fields in DynFlags - - - - - 10a2ba90 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo * Rename InstalledPackageInfo into GenericUnitInfo The name InstalledPackageInfo is only kept for alleged backward compatibility reason in Cabal. ghc-boot has its own stripped down copy of this datatype but it doesn't need to keep the name. Internally we already use type aliases (UnitInfo in GHC, PackageCacheFormat in ghc-pkg). * Rename UnitInfo fields: add "unit" prefix and fix misleading names * Add comments on every UnitInfo field * Rename SourcePackageId into PackageId "Package" already indicates that it's a "source package". Installed package components are called units. Update Haddock submodule - - - - - 69562e34 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Remove unused `emptyGenericUnitInfo` - - - - - 9e2c8e0e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactor UnitInfo load/store from databases Converting between UnitInfo stored in package databases and UnitInfo as they are used in ghc-pkg and ghc was done in a very convoluted way (via BinaryStringRep and DbUnitModuleRep type classes using fun deps, etc.). It was difficult to understand and even more to modify (I wanted to try to use a GADT for UnitId but fun deps got in the way). The new code uses much more straightforward functions to convert between the different representations. Much simpler. - - - - - ea717aa4 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Factorize mungePackagePaths code This patch factorizes the duplicated code used in ghc-pkg and in GHC to munge package paths/urls. It also fixes haddock-html munging in GHC (allowed to be either a file or a url) to mimic ghc-pkg behavior. - - - - - 10d15f1e by Sylvain Henry at 2020-04-30T01:56:56-04:00 Refactoring unit management code Over the years the unit management code has been modified a lot to keep up with changes in Cabal (e.g. support for several library components in the same package), to integrate BackPack, etc. I found it very hard to understand as the terminology wasn't consistent, was referring to past concepts, etc. The terminology is now explained as clearly as I could in the Note "About Units" and the code is refactored to reflect it. ------------------- Many names were misleading: UnitId is not an Id but could be a virtual unit (an indefinite one instantiated on the fly), IndefUnitId constructor may contain a definite instantiated unit, etc. * Rename IndefUnitId into InstantiatedUnit * Rename IndefModule into InstantiatedModule * Rename UnitId type into Unit * Rename IndefiniteUnitId constructor into VirtUnit * Rename DefiniteUnitId constructor into RealUnit * Rename packageConfigId into mkUnit * Rename getPackageDetails into unsafeGetUnitInfo * Rename InstalledUnitId into UnitId Remove references to misleading ComponentId: a ComponentId is just an indefinite unit-id to be instantiated. * Rename ComponentId into IndefUnitId * Rename ComponentDetails into UnitPprInfo * Fix display of UnitPprInfo with empty version: this is now used for units dynamically generated by BackPack Generalize several types (Module, Unit, etc.) so that they can be used with different unit identifier types: UnitKey, UnitId, Unit, etc. * GenModule: Module, InstantiatedModule and InstalledModule are now instances of this type * Generalize DefUnitId, IndefUnitId, Unit, InstantiatedUnit, PackageDatabase Replace BackPack fake "hole" UnitId by a proper HoleUnit constructor. Add basic support for UnitKey. They should be used more in the future to avoid mixing them up with UnitId as we do now. Add many comments. Update Haddock submodule - - - - - 8bfb0219 by Sylvain Henry at 2020-04-30T01:56:56-04:00 Unit: split and rename modules Introduce GHC.Unit.* hierarchy for everything concerning units, packages and modules. Update Haddock submodule - - - - - 71484b09 by Alexis King at 2020-04-30T01:57:35-04:00 Allow block arguments in arrow control operators Arrow control operators have their own entries in the grammar, so they did not cooperate with BlockArguments. This was just a minor oversight, so this patch adjusts the grammar to add the desired behavior. fixes #18050 - - - - - a48cd2a0 by Alexis King at 2020-04-30T01:57:35-04:00 Allow LambdaCase to be used as a command in proc notation - - - - - f4d3773c by Alexis King at 2020-04-30T01:57:35-04:00 Document BlockArguments/LambdaCase support in arrow notation - - - - - 5bdfdd13 by Simon Peyton Jones at 2020-04-30T01:58:15-04:00 Add tests for #17873 - - - - - 19b701c2 by Simon Peyton Jones at 2020-04-30T07:30:13-04:00 Mark rule args as non-tail-called This was just an omission...b I'd failed to call markAllNonTailCall on rule args. I think this bug has been here a long time, but it's quite hard to trigger. Fixes #18098 - - - - - 014ef4a3 by Matthew Pickering at 2020-04-30T07:30:50-04:00 Hadrian: Improve tool-args command to support more components There is a new command to hadrian, tool:path/to/file.hs, which returns the options needed to compile that file in GHCi. This is now used in the ghci script with argument `ghc/Main.hs` but its main purpose is to support the new multi-component branch of ghcide. - - - - - 2aa67611 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Clear bitmap after initializing block size Previously nonmovingInitSegment would clear the bitmap before initializing the segment's block size. This is broken since nonmovingClearBitmap looks at the segment's block size to determine how much bitmap to clear. - - - - - 54dad3cf by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Explicitly memoize block count A profile cast doubt on whether the compiler hoisted the bound out the loop as I would have expected here. It turns out it did but nevertheless it seems clearer to just do this manually. - - - - - 99ff8145 by Ben Gamari at 2020-04-30T21:34:44-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - 05b0a9fd by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 Remove OneShotInfo field of LFReEntrant, document OneShotInfo The field is only used in withNewTickyCounterFun and it's easier to directly pass a parameter for one-shot info to withNewTickyCounterFun instead of passing it via LFReEntrant. This also makes !2842 simpler. Other changes: - New Note (by SPJ) [OneShotInfo overview] added. - Arity argument of thunkCode removed as it's always 0. - - - - - a43620c6 by Ömer Sinan Ağacan at 2020-04-30T21:35:24-04:00 GHC.StgToCmm.Ticky: remove a few unused stuff - - - - - 780de9e1 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Use platform in Iface Binary - - - - - f8386c7b by Sylvain Henry at 2020-05-01T10:37:39-04:00 Refactor PprDebug handling If `-dppr-debug` is set, then PprUser and PprDump styles are silently replaced with PprDebug style. This was done in `mkUserStyle` and `mkDumpStyle` smart constructors. As a consequence they needed a DynFlags parameter. Now we keep the original PprUser and PprDump styles until they are used to create an `SDocContext`. I.e. the substitution is only performed in `initSDocContext`. - - - - - b3df9e78 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Remove PprStyle param of logging actions Use `withPprStyle` instead to apply a specific style to a SDoc. - - - - - de9fc995 by Sylvain Henry at 2020-05-01T10:37:39-04:00 Fully remove PprDebug PprDebug was a pain to deal with consistently as it is implied by `-dppr-debug` but it isn't really a PprStyle. We remove it completely and query the appropriate SDoc flag instead (`sdocPprDebug`) via helpers (`getPprDebug` and its friends). - - - - - 8b51fcbd by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Only call checkSingle if we would report warnings - - - - - fd7ea0fe by Sebastian Graf at 2020-05-01T10:38:16-04:00 PmCheck: Pick up `EvVar`s bound in `HsWrapper`s for long-distance info `HsWrapper`s introduce evidence bindings through `WpEvLam` which the pattern-match coverage checker should be made aware of. Failing to do so caused #18049, where the resulting impreciseness of imcompleteness warnings seemingly contradicted with `-Winaccessible-code`. The solution is simple: Collect all the evidence binders of an `HsWrapper` and add it to the ambient `Deltas` before desugaring the wrapped expression. But that means we pick up many more evidence bindings, even when they wrap around code without a single pattern match to check! That regressed `T3064` by over 300%, so now we are adding long-distance info lazily through judicious use of `unsafeInterleaveIO`. Fixes #18049. - - - - - 7bfe9ac5 by Ben Gamari at 2020-05-03T04:41:33-04:00 rts: Enable tracing of nonmoving heap census with -ln Previously this was not easily available to the user. Fix this. Non-moving collection lifecycle events are now reported with -lg. - - - - - c560dd07 by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Move eventlog documentation users guide - - - - - 02543d5e by Ben Gamari at 2020-05-03T04:41:33-04:00 users guide: Add documentation for non-moving GC events - - - - - b465dd45 by Alexis King at 2020-05-03T04:42:12-04:00 Flatten nested casts in the simple optimizer Normally, we aren’t supposed to generated any nested casts, since mkCast takes care to flatten them, but the simple optimizer didn’t use mkCast, so they could show up after inlining. This isn’t really a problem, since the simplifier will clean them up immediately anyway, but it can clutter the -ddump-ds output, and it’s an extremely easy fix. closes #18112 - - - - - 8bdc03d6 by Simon Peyton Jones at 2020-05-04T01:56:59-04:00 Don't return a panic in tcNestedSplice In GHC.Tc.Gen.Splice.tcNestedSplice we were returning a typechecked expression of "panic". That is usually OK, because the result is discarded. But it happens that tcApp now looks at the typechecked expression, trivially, to ask if it is tagToEnum. So being bottom is bad. Moreover a debug-trace might print it out. So better to return a civilised expression, even though it is usually discarded. - - - - - 0bf640b1 by Baldur Blöndal at 2020-05-04T01:57:36-04:00 Don't require parentheses around via type (`-XDerivingVia'). Fixes #18130". - - - - - 30272412 by Artem Pelenitsyn at 2020-05-04T13:19:59-04:00 Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) - - - - - b9f7c08f by jneira at 2020-05-04T13:20:37-04:00 Remove unused hs-boot file - - - - - 1d8f80cd by Sylvain Henry at 2020-05-05T03:22:46-04:00 Remove references to -package-key * remove references to `-package-key` which has been removed in 2016 (240ddd7c39536776e955e881d709bbb039b48513) * remove support for `-this-package-key` which has been deprecated at the same time - - - - - 7bc3a65b by Sylvain Henry at 2020-05-05T03:23:31-04:00 Remove SpecConstrAnnotation (#13681) This has been deprecated since 2013. Use GHC.Types.SPEC instead. Make GHC.Exts "not-home" for haddock Metric Decrease: haddock.base - - - - - 3c862f63 by DenisFrezzato at 2020-05-05T03:24:15-04:00 Fix Haskell98 short description in documentation - - - - - 2420c555 by Ryan Scott at 2020-05-05T03:24:53-04:00 Add regression tests for #16244, #16245, #16758 Commit e3c374cc5bd7eb49649b9f507f9f7740697e3f70 ended up fixing quite a few bugs: * This commit fixes #16244 completely. A regression test has been added. * This commit fixes one program from #16245. (The program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211369 still panics, and the program in https://gitlab.haskell.org/ghc/ghc/issues/16245#note_211400 still loops infinitely.) A regression test has been added for this program. * This commit fixes #16758. Accordingly, this patch removes the `expect_broken` label from the `T16758` test case, moves it from `should_compile` to `should_fail` (as it should produce an error message), and checks in the expected stderr. - - - - - 40c71c2c by Sylvain Henry at 2020-05-05T03:25:31-04:00 Fix colorized error messages (#18128) In b3df9e780fb2f5658412c644849cd0f1e6f50331 I broke colorized messages by using "dump" style instead of "user" style. This commits fixes it. - - - - - 7ab6ab09 by Richard Eisenberg at 2020-05-06T04:39:32-04:00 Refactor hole constraints. Previously, holes (both expression holes / out of scope variables and partial-type-signature wildcards) were emitted as *constraints* via the CHoleCan constructor. While this worked fine for error reporting, there was a fair amount of faff in keeping these constraints in line. In particular, and unlike other constraints, we could never change a CHoleCan to become CNonCanonical. In addition: * the "predicate" of a CHoleCan constraint was really the type of the hole, which is not a predicate at all * type-level holes (partial type signature wildcards) carried evidence, which was never used * tcNormalise (used in the pattern-match checker) had to create a hole constraint just to extract it again; it was quite messy The new approach is to record holes directly in WantedConstraints. It flows much more nicely now. Along the way, I did some cleaning up of commentary in GHC.Tc.Errors.Hole, which I had a hard time understanding. This was instigated by a future patch that will refactor the way predicates are handled. The fact that CHoleCan's "predicate" wasn't really a predicate is incompatible with that future patch. No test case, because this is meant to be purely internal. It turns out that this change improves the performance of the pattern-match checker, likely because fewer constraints are sloshing about in tcNormalise. I have not investigated deeply, but an improvement is not a surprise here: ------------------------- Metric Decrease: PmSeriesG ------------------------- - - - - - 420b957d by Ben Gamari at 2020-05-06T04:40:08-04:00 rts: Zero block flags with -DZ Block flags are very useful for determining the state of a block. However, some block allocator users don't touch them, leading to misleading values. Ensure that we zero then when zero-on-gc is set. This is safe and makes the flags more useful during debugging. - - - - - 740b3b8d by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix incorrect failed_to_evac value during deadlock gc Previously we would incorrectly set the failed_to_evac flag if we evacuated a value due to a deadlock GC. This would cause us to mark more things as dirty than strictly necessary. It also turned up a nasty but which I will fix next. - - - - - b2d72c75 by Ben Gamari at 2020-05-06T04:40:08-04:00 nonmoving: Fix handling of dirty objects Previously we (incorrectly) relied on failed_to_evac to be "precise". That is, we expected it to only be true if *all* of an object's fields lived outside of the non-moving heap. However, does not match the behavior of failed_to_evac, which is true if *any* of the object's fields weren't promoted (meaning that some others *may* live in the non-moving heap). This is problematic as we skip the non-moving write barrier for dirty objects (which we can only safely do if *all* fields point outside of the non-moving heap). Clearly this arises due to a fundamental difference in the behavior expected of failed_to_evac in the moving and non-moving collector. e.g., in the moving collector it is always safe to conservatively say failed_to_evac=true whereas in the non-moving collector the safe value is false. This issue went unnoticed as I never wrote down the dirtiness invariant enforced by the non-moving collector. We now define this invariant as An object being marked as dirty implies that all of its fields are on the mark queue (or, equivalently, update remembered set). To maintain this invariant we teach nonmovingScavengeOne to push the fields of objects which we fail to evacuate to the update remembered set. This is a simple and reasonably cheap solution and avoids the complexity and fragility that other, more strict alternative invariants would require. All of this is described in a new Note, Note [Dirty flags in the non-moving collector] in NonMoving.c. - - - - - 9f3e6884 by Zubin Duggal at 2020-05-06T04:41:08-04:00 Allow atomic update of NameCache in readHieFile The situation arises in ghcide where multiple different threads may need to update the name cache, therefore with the older interface it could happen that you start reading a hie file with name cache A and produce name cache A + B, but another thread in the meantime updated the namecache to A + C. Therefore if you write the new namecache you will lose the A' updates from the second thread. Updates haddock submodule - - - - - edec6a6c by Ryan Scott at 2020-05-06T04:41:57-04:00 Make isTauTy detect higher-rank contexts Previously, `isTauTy` would only detect higher-rank `forall`s, not higher-rank contexts, which led to some minor bugs observed in #18127. Easily fixed by adding a case for `(FunTy InvisArg _ _)`. Fixes #18127. - - - - - a95e7fe0 by Ömer Sinan Ağacan at 2020-05-06T04:42:39-04:00 ELF linker: increment curSymbol after filling in fields of current entry The bug was introduced in a8b7cef4d45 which added a field to the `symbols` array elements and then updated this code incorrectly: - oc->symbols[curSymbol++] = nm; + oc->symbols[curSymbol++].name = nm; + oc->symbols[curSymbol].addr = symbol->addr; - - - - - cab1871a by Sylvain Henry at 2020-05-06T04:43:21-04:00 Move LeadingUnderscore into Platform (#17957) Avoid direct use of DynFlags to know if symbols must be prefixed by an underscore. - - - - - 94e7c563 by Sylvain Henry at 2020-05-06T04:43:21-04:00 Don't use DynFlags in showLinkerState (#17957) - - - - - 9afd9251 by Ryan Scott at 2020-05-06T04:43:58-04:00 Refactoring: Use bindSigTyVarsFV in rnMethodBinds `rnMethodBinds` was explicitly using `xoptM` to determine if `ScopedTypeVariables` is enabled before bringing type variables bound by the class/instance header into scope. However, this `xoptM` logic is already performed by the `bindSigTyVarsFV` function. This patch uses `bindSigTyVarsFV` in `rnMethodBinds` to reduce the number of places where we need to consult if `ScopedTypeVariables` is on. This is purely refactoring, and there should be no user-visible change in behavior. - - - - - 6f6d72b2 by Brian Foley at 2020-05-08T15:29:25-04:00 Remove further dead code found by a simple Python script. Avoid removing some functions that are part of an API even though they're not used in-tree at the moment. - - - - - 78bf8bf9 by Julien Debon at 2020-05-08T15:29:28-04:00 Add doc examples for Bifoldable See #17929 - - - - - 66f0a847 by Julien Debon at 2020-05-08T15:29:29-04:00 doc (Bitraversable): Add examples to Bitraversable * Add examples to Data.Bitraversable * Fix formatting for (,) in Bitraversable and Bifoldable * Fix mistake on bimapAccumR documentation See #17929 - - - - - 9749fe12 by Baldur Blöndal at 2020-05-08T15:29:32-04:00 Specify kind variables for inferred kinds in base. - - - - - 4e9aef9e by John Ericson at 2020-05-08T15:29:36-04:00 HsSigWcTypeScoping: Pull in documentation from stray location - - - - - f4d5c6df by John Ericson at 2020-05-08T15:29:36-04:00 Rename local `real_fvs` to `implicit_vs` It doesn't make sense to call the "free" variables we are about to implicitly bind the real ones. - - - - - 20570b4b by John Ericson at 2020-05-08T15:29:36-04:00 A few tiny style nits with renaming - Use case rather than guards that repeatedly scrutenize same thing. - No need for view pattern when `L` is fine. - Use type synnonym to convey the intent like elsewhere. - - - - - 09ac8de5 by John Ericson at 2020-05-08T15:29:36-04:00 Add `forAllOrNothing` function with note - - - - - bb35c0e5 by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Document lawlessness of Ap's Num instance - - - - - cdd229ff by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply suggestion to libraries/base/Data/Monoid.hs - - - - - 926d2aab by Joseph C. Sible at 2020-05-08T15:29:40-04:00 Apply more suggestions from Simon Jakobi - - - - - 7a763cff by Adam Gundry at 2020-05-08T15:29:41-04:00 Reject all duplicate declarations involving DuplicateRecordFields (fixes #17965) This fixes a bug that resulted in some programs being accepted that used the same identifier as a field label and another declaration, depending on the order they appeared in the source code. - - - - - 88e3c815 by Simon Peyton Jones at 2020-05-08T15:29:41-04:00 Fix specialisation for DFuns When specialising a DFun we must take care to saturate the unfolding. See Note [Specialising DFuns] in Specialise. Fixes #18120 - - - - - 86c77b36 by Greg Steuck at 2020-05-08T15:29:45-04:00 Remove unused SEGMENT_PROT_RWX It's been unused for a year and is problematic on any OS which requires W^X for security. - - - - - 9d97f4b5 by nineonine at 2020-05-08T15:30:03-04:00 Add test for #16167 - - - - - aa318338 by Ryan Scott at 2020-05-08T15:30:04-04:00 Bump exceptions submodule so that dist-boot is .gitignore'd `exceptions` is a stage-0 boot library as of commit 30272412fa437ab8e7a8035db94a278e10513413, which means that building `exceptions` in a GHC tree will generate a `dist-boot` directory. However, this directory was not specified in `exceptions`' `.gitignore` file, which causes it to dirty up the current `git` working directory. Accordingly, this bumps the `exceptions` submodule to commit ghc/packages/exceptions at 23c0b8a50d7592af37ca09beeec16b93080df98f, which adds `dist-boot` to the `.gitignore` file. - - - - - ea86360f by Ömer Sinan Ağacan at 2020-05-08T15:30:30-04:00 Linker.c: initialize n_symbols of ObjectCode with other fields - - - - - 951c1fb0 by Sylvain Henry at 2020-05-09T21:46:38-04:00 Fix unboxed-sums GC ptr-slot rubbish value (#17791) This patch allows boot libraries to use unboxed sums without implicitly depending on `base` package because of `absentSumFieldError`. See updated Note [aBSENT_SUM_FIELD_ERROR_ID] in GHC.Core.Make - - - - - b352d63c by Ben Gamari at 2020-05-09T21:47:14-04:00 rts: Make non-existent linker search path merely a warning As noted in #18105, previously this resulted in a rather intrusive error message. This is in contrast to the general expectation that search paths are merely places to look, not places that must exist. Fixes #18105. - - - - - cf4f1e2f by Ben Gamari at 2020-05-13T02:02:33-04:00 rts/CNF: Fix fixup comparison function Previously we would implicitly convert the difference between two words to an int, resulting in an integer overflow on 64-bit machines. Fixes #16992 - - - - - a03da9bf by Ömer Sinan Ağacan at 2020-05-13T02:03:16-04:00 Pack some of IdInfo fields into a bit field This reduces residency of compiler quite a bit on some programs. Example stats when building T10370: Before: 2,871,242,832 bytes allocated in the heap 4,693,328,008 bytes copied during GC 33,941,448 bytes maximum residency (276 sample(s)) 375,976 bytes maximum slop 83 MiB total memory in use (0 MB lost due to fragmentation) After: 2,858,897,344 bytes allocated in the heap 4,629,255,440 bytes copied during GC 32,616,624 bytes maximum residency (278 sample(s)) 314,400 bytes maximum slop 80 MiB total memory in use (0 MB lost due to fragmentation) So -3.9% residency, -1.3% bytes copied and -0.4% allocations. Fixes #17497 Metric Decrease: T9233 T9675 - - - - - 670c3e5c by Ben Gamari at 2020-05-13T02:03:54-04:00 get-win32-tarballs: Fix base URL Revert a change previously made for testing purposes. - - - - - 8ad8dc41 by Ben Gamari at 2020-05-13T02:03:54-04:00 get-win32-tarballs: Improve diagnostics output - - - - - 8c0740b7 by Simon Jakobi at 2020-05-13T02:04:33-04:00 docs: Add examples for Data.Semigroup.Arg{Min,Max} Context: #17153 - - - - - cb22348f by Ben Gamari at 2020-05-13T02:05:11-04:00 Add few cleanups of the CAF logic Give the NameSet of non-CAFfy names a proper newtype to distinguish it from all of the other NameSets floating about. - - - - - 90e38b81 by Emeka Nkurumeh at 2020-05-13T02:05:51-04:00 fix printf warning when using with ghc with clang on mingw - - - - - 86d8ac22 by Sebastian Graf at 2020-05-13T02:06:29-04:00 CprAnal: Don't attach CPR sigs to expandable bindings (#18154) Instead, look through expandable unfoldings in `cprTransform`. See the new Note [CPR for expandable unfoldings]: ``` Long static data structures (whether top-level or not) like xs = x1 : xs1 xs1 = x2 : xs2 xs2 = x3 : xs3 should not get CPR signatures, because they * Never get WW'd, so their CPR signature should be irrelevant after analysis (in fact the signature might even be harmful for that reason) * Would need to be inlined/expanded to see their constructed product * Recording CPR on them blows up interface file sizes and is redundant with their unfolding. In case of Nested CPR, this blow-up can be quadratic! But we can't just stop giving DataCon application bindings the CPR property, for example fac 0 = 1 fac n = n * fac (n-1) fac certainly has the CPR property and should be WW'd! But FloatOut will transform the first clause to lvl = 1 fac 0 = lvl If lvl doesn't have the CPR property, fac won't either. But lvl doesn't have a CPR signature to extrapolate into a CPR transformer ('cprTransform'). So instead we keep on cprAnal'ing through *expandable* unfoldings for these arity 0 bindings via 'cprExpandUnfolding_maybe'. In practice, GHC generates a lot of (nested) TyCon and KindRep bindings, one for each data declaration. It's wasteful to attach CPR signatures to each of them (and intractable in case of Nested CPR). ``` Fixes #18154. - - - - - e34bf656 by Ben Gamari at 2020-05-13T02:07:08-04:00 users-guide: Add discussion of shared object naming Fixes #18074. - - - - - 5d0f2445 by Ben Gamari at 2020-05-13T02:07:47-04:00 testsuite: Print sign of performance changes Executes the minor formatting change in the tabulated performance changes suggested in #18135. - - - - - 9e4b981f by Ben Gamari at 2020-05-13T02:08:24-04:00 testsuite: Add testcase for #18129 - - - - - 266310c3 by Ivan-Yudin at 2020-05-13T02:09:03-04:00 doc: Reformulate the opening paragraph of Ch. 4 in User's guide Removes mentioning of Hugs (it is not helpful for new users anymore). Changes the wording for the rest of the paragraph. Fixes #18132. - - - - - 55e35c0b by Baldur Blöndal at 2020-05-13T20:02:48-04:00 Predicate, Equivalence derive via `.. -> a -> All' - - - - - d7e0b57f by Alp Mestanogullari at 2020-05-13T20:03:30-04:00 hadrian: add a --freeze2 option to freeze stage 1 and 2 - - - - - d880d6b2 by Artem Pelenitsyn at 2020-05-13T20:04:11-04:00 Don't reload environment files on every setSessionDynFlags Makes `interpretPackageEnv` (which loads envirinment files) a part of `parseDynamicFlags` (parsing command-line arguments, which is typically done once) instead of `setSessionDynFlags` (which is typically called several times). Making several (transitive) calls to `interpretPackageEnv`, as before, caused #18125 #16318, which should be fixed now. - - - - - 102cfd67 by Ryan Scott at 2020-05-13T20:04:46-04:00 Factor out HsPatSigType for pat sigs/RULE term sigs (#16762) This implements chunks (2) and (3) of https://gitlab.haskell.org/ghc/ghc/issues/16762#note_270170. Namely, it introduces a dedicated `HsPatSigType` AST type, which represents the types that can appear in pattern signatures and term-level `RULE` binders. Previously, these were represented with `LHsSigWcType`. Although `LHsSigWcType` is isomorphic to `HsPatSigType`, the intended semantics of the two types are slightly different, as evidenced by the fact that they have different code paths in the renamer and typechecker. See also the new `Note [Pattern signature binders and scoping]` in `GHC.Hs.Types`. - - - - - b17574f7 by Hécate at 2020-05-13T20:05:28-04:00 fix(documentation): Fix the RST links to GHC.Prim - - - - - df021fb1 by Baldur Blöndal at 2020-05-13T20:06:06-04:00 Document (->) using inferred quantification for its runtime representations. Fixes #18142. - - - - - 1a93ea57 by Takenobu Tani at 2020-05-13T20:06:54-04:00 Tweak man page for ghc command This commit updates the ghc command's man page as followings: * Enable `man_show_urls` to show URL addresses in the `DESCRIPTION` section of ghc.rst, because sphinx currently removes hyperlinks for man pages. * Add a `SEE ALSO` section to point to the GHC homepage - - - - - a951e1ba by Takenobu Tani at 2020-05-13T20:07:37-04:00 GHCi: Add link to the user's guide in help message This commit adds a link to the user's guide in ghci's `:help` message. Newcomers could easily reach to details of ghci. - - - - - 404581ea by Jeff Happily at 2020-05-13T20:08:15-04:00 Handle single unused import - - - - - 1c999e5d by Ben Gamari at 2020-05-13T20:09:07-04:00 Ensure that printMinimalImports closes handle Fixes #18166. - - - - - c9f5a8f4 by Ben Gamari at 2020-05-13T20:09:51-04:00 hadrian: Tell testsuite driver about LLVM availability This reflects the logic present in the Make build system into Hadrian. Fixes #18167. - - - - - c05c0659 by Simon Jakobi at 2020-05-14T03:31:21-04:00 Improve some folds over Uniq[D]FM * Replace some non-deterministic lazy folds with strict folds. * Replace some O(n log n) folds in deterministic order with O(n) non-deterministic folds. * Replace some folds with set-operations on the underlying IntMaps. This reduces max residency when compiling `nofib/spectral/simple/Main.hs` with -O0 by about 1%. Maximum residency when compiling Cabal also seems reduced on the order of 3-9%. - - - - - 477f13bb by Simon Jakobi at 2020-05-14T03:31:58-04:00 Use Data.IntMap.disjoint Data.IntMap gained a dedicated `disjoint` function in containers-0.6.2.1. This patch applies this function where appropriate in hopes of modest compiler performance improvements. Closes #16806. - - - - - e9c0110c by Ben Gamari at 2020-05-14T12:25:53-04:00 IdInfo: Add reference to bitfield-packing ticket - - - - - 9bd20e83 by Sebastian Graf at 2020-05-15T10:42:09-04:00 DmdAnal: Improve handling of precise exceptions This patch does two things: Fix possible unsoundness in what was called the "IO hack" and implement part 2.1 of the "fixing precise exceptions" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions, which, in combination with !2956, supersedes !3014 and !2525. **IO hack** The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is called `exprMayThrowPreciseException` now. I came up with two testcases exemplifying possible unsoundness (if twisted enough) in the old approach: - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. - `T13380e`: Demonstrating unsoundness of the "IO hack" when we have Nested CPR. Not currently relevant, as we don't have Nested CPR yet. - `T13380f`: Demonstrating unsoundness of the "IO hack" for safe FFI calls. Basically, the IO hack assumed that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future, see `T13380e`. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380{d,e}` (and will hopefully be robust to Nested CPR). **Precise exceptions** In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that was terribly unprincipled. That unprincipledness resulted in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception (and the existing IO hack doesn't detect that) Fixing both issues in !3014 turned out to be too complicated and had the potential to regress in the future. Hence we decided to only fix `T13380b` and augment the `Divergence` lattice with a new middle-layer element, `ExnOrDiv`, which means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. See the wiki page on Step 2.1 for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#dead-code-elimination-for-raiseio-with-isdeadenddiv-introducing-exnordiv-step-21 - - - - - 568d7279 by Ben Gamari at 2020-05-15T10:42:46-04:00 GHC.Cmm.Opt: Handle MO_XX_Conv This MachOp was introduced by 2c959a1894311e59cd2fd469c1967491c1e488f3 but a wildcard match in cmmMachOpFoldM hid the fact that it wasn't handled. Ideally we would eliminate the match but this appears to be a larger task. Fixes #18141. - - - - - 0162ce42 by Ben Gamari at 2020-05-20T13:15:50-04:00 compiler: Don't inline panic functions While working on making runRW# simplify (#15127) I noticed that we tend to inline these panic functions pretty ubiquitously. For instance, in `GHC.CmmToAsm.PPC.Regs` we alone inlined `PlainPanic.panic` six times, each of which generating a 20-something term binding, each differing only in the error message string. For instance, ``` -- RHS size: {terms: 17, types: 41, coercions: 0, joins: 0/0} GHC.CmmToAsm.PPC.Regs.regDotColor2 :: GHC.Prim.State# GHC.Prim.RealWorld -> Outputable.SDoc [GblId, Arity=1, Str=<L,U>, Cpr=b, Unf=OtherCon []] GHC.CmmToAsm.PPC.Regs.regDotColor2 = \ (eta_s8Vu [Occ=Once] :: GHC.Prim.State# GHC.Prim.RealWorld) -> case GHC.Prim.getCurrentCCS# @GHC.Base.String @GHC.Prim.RealWorld x1_r7VT eta_s8Vu of { (# s'_s8Vw [Occ=Once], addr_s8Vx [Occ=Once] #) -> case GHC.Stack.CCS.$wgo addr_s8Vx (GHC.Types.[] @[GHC.Types.Char]) s'_s8Vw of { (# ipv_s8Vz [Occ=Once], ipv1_s8VA [Occ=Once] #) -> case PlainPanic.panic1 @GHC.Platform.Reg.Class.RegClass ipv_s8Vz ipv1_s8VA x1_r7VT of { } } } ``` Given how this is a failure path, this seems silly. Frankly, it's surprising that we choose to inline at all. - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/PrimOps.hs-boot - 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/Uniques.hs-boot - compiler/GHC/Builtin/Utils.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Asm.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/CallConv.hs - compiler/GHC/Cmm/CommonBlockElim.hs - compiler/GHC/Cmm/ContFlowOpt.hs - compiler/GHC/Cmm/Dataflow.hs - compiler/GHC/Cmm/Dataflow/Block.hs - compiler/GHC/Cmm/Dataflow/Collections.hs - compiler/GHC/Cmm/Dataflow/Graph.hs - compiler/GHC/Cmm/Dataflow/Label.hs - compiler/GHC/Cmm/DebugBlock.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ecdbf825f74434b14913fd7b3dcd4471430a9f0c...0162ce429c5a4235bcd2f8a743f5dc6d852344db -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ecdbf825f74434b14913fd7b3dcd4471430a9f0c...0162ce429c5a4235bcd2f8a743f5dc6d852344db You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 20 19:58:31 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 20 May 2020 15:58:31 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/modbreaks-crash Message-ID: <5ec58be77f255_6e263f9f0809f9c030681d@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/modbreaks-crash at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/modbreaks-crash You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 20 21:57:58 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 20 May 2020 17:57:58 -0400 Subject: [Git][ghc/ghc][wip/T18069] SysTools.Process: Handle exceptions in readCreateProcessWithExitCode' Message-ID: <5ec5a7e6786a6_6e263f9ee2dcbd2c31413b@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18069 at Glasgow Haskell Compiler / GHC Commits: 2070814e by Ben Gamari at 2020-05-20T17:57:52-04:00 SysTools.Process: Handle exceptions in readCreateProcessWithExitCode' In #18069 we are observing MVar deadlocks from somewhere in ghc.exe. This use of MVar stood out as being one of the more likely culprits. Here we make sure that it is exception-safe. - - - - - 1 changed file: - compiler/GHC/SysTools/Process.hs Changes: ===================================== compiler/GHC/SysTools/Process.hs ===================================== @@ -41,6 +41,15 @@ enableProcessJobs opts = opts { use_process_jobs = True } enableProcessJobs opts = opts #endif +#if !MIN_VERSION_base(4,15,0) +-- TODO: This can be dropped with GHC 8.16 +hGetContents' :: Handle -> IO String +hGetContents' hdl = do + output <- hGetContents hdl + _ <- evaluate $ length output + return output +#endif + -- Similar to System.Process.readCreateProcessWithExitCode, but stderr is -- inherited from the parent process, and output to stderr is not captured. readCreateProcessWithExitCode' @@ -51,13 +60,19 @@ readCreateProcessWithExitCode' proc = do createProcess proc{ std_out = CreatePipe } -- fork off a thread to start consuming the output - output <- hGetContents outh outMVar <- newEmptyMVar - _ <- forkIO $ evaluate (length output) >> putMVar outMVar () + let onError :: SomeException -> IO () + onError exc = putMVar outMVar (Left exc) + _ <- forkIO $ handle onError $ do + output <- hGetContents' outh + putMVar outMVar $ Right output -- wait on the output - takeMVar outMVar + result <- takeMVar outMVar hClose outh + output <- case result of + Left exc -> throwIO exc + Right output -> return output -- wait on the process ex <- waitForProcess pid View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2070814ecfc77bba09a45b7b493a4f846e410c4e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2070814ecfc77bba09a45b7b493a4f846e410c4e You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Wed May 20 22:17:03 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 20 May 2020 18:17:03 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 28 commits: Remove duplicate Note [When to print foralls] in GHC.Core.TyCo.Ppr Message-ID: <5ec5ac5f61951_6e2612cf46a0320473@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 5bcf8606 by Ryan Scott at 2020-05-17T08:46:38-04:00 Remove duplicate Note [When to print foralls] in GHC.Core.TyCo.Ppr There are two different Notes named `[When to print foralls]`. The most up-to-date one is in `GHC.Iface.Type`, but there is a second one in `GHC.Core.TyCo.Ppr`. The latter is less up-to-date, as it was written before GHC switched over to using ifaces to pretty-print types. I decided to just remove the latter and replace it with a reference to the former. [ci skip] - - - - - 8041b082 by Fumiaki Kinoshita at 2020-05-20T18:16:07-04:00 base: Add Generic instances to various datatypes under GHC.* * GHC.Fingerprint.Types: Fingerprint * GHC.RTS.Flags: GiveGCStats, GCFlags, ConcFlags, DebugFlags, CCFlags, DoHeapProfile, ProfFlags, DoTrace, TraceFlags, TickyFlags, ParFlags and RTSFlags * GHC.Stats: RTSStats and GCStats * GHC.ByteOrder: ByteOrder * GHC.Unicode: GeneralCategory * GHC.Stack.Types: SrcLoc Metric Increase: haddock.base - - - - - b430e095 by Gert-Jan Bottu at 2020-05-20T18:16:10-04:00 Explicit Specificity Implementation for Ticket #16393. Explicit specificity allows users to manually create inferred type variables, by marking them with braces. This way, the user determines which variables can be instantiated through visible type application. The additional syntax is included in the parser, allowing users to write braces in type variable binders (type signatures, data constructors etc). This information is passed along through the renamer and verified in the type checker. The AST for type variable binders, data constructors, pattern synonyms, partial signatures and Template Haskell has been updated to include the specificity of type variables. Minor notes: - Bumps haddock submodule - Disables pattern match checking in GHC.Iface.Type with GHC 8.8 - - - - - 9e94937b by Ben Gamari at 2020-05-20T18:16:11-04:00 nonmoving: Optimise the write barrier - - - - - 5684eae3 by Gleb Popov at 2020-05-20T18:16:15-04:00 gitlab-ci: Set locale to C.UTF-8. - - - - - 30f2a2b1 by Stefan Holdermans at 2020-05-20T18:16:18-04:00 Allow spaces in GHCi :script file names This patch updates the user interface of GHCi so that file names passed to the ':script' command may contain spaces escaped with a backslash. For example: :script foo\ bar.script The implementation uses a modified version of 'words' that does not break on escaped spaces. Fixes #18027. - - - - - 013f4c88 by Stefan Holdermans at 2020-05-20T18:16:18-04:00 Add extra tests for GHCi :script syntax checks The syntax for GHCi's ":script" command allows for only a single file name to be passed as an argument. This patch adds a test for the cases in which a file name is missing or multiple file names are passed. Related to #T18027. - - - - - 6217dc8f by Stefan Holdermans at 2020-05-20T18:16:18-04:00 Allow GHCi :script file names in double quotes This patch updates the user interface of GHCi so that file names passed to the ':script' command can be wrapped in double quotes. For example: :script "foo bar.script" The implementation uses a modified version of 'words' that treats character sequences enclosed in double quotes as single words. Fixes #18027. - - - - - 6512ffe2 by Stefan Holdermans at 2020-05-20T18:16:18-04:00 Update documentation for GHCi :script This patch adds the fixes that allow for file names containing spaces to be passed to GHCi's ':script' command to the release notes for 8.12 and expands the user-guide documentation for ':script' by mentioning how such file names can be passed. Related to #18027. - - - - - 222d36a4 by Tuan Le at 2020-05-20T18:16:21-04:00 llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 - - - - - b89b6040 by John Ericson at 2020-05-20T18:16:27-04:00 Use `Checker` for `tc_pat` - - - - - 805341f0 by John Ericson at 2020-05-20T18:16:27-04:00 Use `Checker` for `tc_lpat` and `tc_lpats` - - - - - 9c5a8e66 by John Ericson at 2020-05-20T18:16:27-04:00 More judiciously panic in `ts_pat` - - - - - 954ae448 by John Ericson at 2020-05-20T18:16:27-04:00 Put `PatEnv` first in `GHC.Tc.Gen.Pat.Checker` - - - - - 6f743f52 by John Ericson at 2020-05-20T18:16:27-04:00 Tiny cleaup eta-reduce away a function argument In GHC, not in the code being compiled! - - - - - eb582362 by John Ericson at 2020-05-20T18:16:27-04:00 Use braces with do in `SplicePat` case for consistency - - - - - 6740c700 by buggymcbugfix at 2020-05-20T18:16:28-04:00 Fix spelling mistakes and typos - - - - - 4dd2934f by buggymcbugfix at 2020-05-20T18:16:28-04:00 Add INLINABLE pragmas to Enum list producers The INLINABLE pragmas ensure that we export stable (unoptimised) unfoldings in the interface file so we can do list fusion at usage sites. Related tickets: #15185, #8763, #18178. - - - - - b180ecff by buggymcbugfix at 2020-05-20T18:16:28-04:00 Piggyback on Enum Word methods for Word64 If we are on a 64 bit platform, we can use the efficient Enum Word methods for the Enum Word64 instance. - - - - - c788d2c2 by buggymcbugfix at 2020-05-20T18:16:28-04:00 Document INLINE(ABLE) pragmas that enable fusion - - - - - e268bcbd by Richard Eisenberg at 2020-05-20T18:16:28-04:00 MR template should ask for key part - - - - - baaad2e7 by Sebastian Graf at 2020-05-20T18:16:29-04:00 Make `Int`'s `mod` and `rem` strict in their first arguments They used to be strict until 4d2ac2d (9 years ago). It's obviously better to be strict for performance reasons. It also blocks #18067. NoFib results: ``` -------------------------------------------------------------------------------- Program Allocs Instrs -------------------------------------------------------------------------------- integer -1.1% +0.4% wheel-sieve2 +21.2% +20.7% -------------------------------------------------------------------------------- Min -1.1% -0.0% Max +21.2% +20.7% Geometric Mean +0.2% +0.2% ``` The regression in `wheel-sieve2` is due to reboxing that likely will go away with the resolution of #18067. See !3282 for details. Fixes #18187. - - - - - ec6adc53 by Galen Huntington at 2020-05-20T18:16:37-04:00 Clarify pitfalls of NegativeLiterals; see #18022. - - - - - 28ffe9cc by Alexey Kuleshevich at 2020-05-20T18:16:40-04:00 Fix wording in primops documentation to reflect the correct reasoning: * Besides resizing functions, shrinking ones also mutate the size of a mutable array and because of those two `sizeofMutabeByteArray` and `sizeofSmallMutableArray` are now deprecated * Change reference in documentation to the newer functions `getSizeof*` instead of `sizeof*` for shrinking functions * Fix incorrect mention of "byte" instead of "small" - - - - - 0ea4485d by Andreas Klebinger at 2020-05-20T18:16:41-04:00 Don't variable-length encode magic iface constant. We changed to use variable length encodings for many types by default, including Word32. This makes sense for numbers but not when Word32 is meant to represent four bytes. I added a FixedLengthEncoding newtype to Binary who's instances interpret their argument as a collection of bytes instead of a number. We then use this when writing/reading magic numbers to the iface file. I also took the libery to remove the dummy iface field. This fixes #18180. - - - - - 39529e70 by Krzysztof Gogolewski at 2020-05-20T18:16:41-04:00 Add a regression test for #11506 The testcase works now. See explanation in https://gitlab.haskell.org/ghc/ghc/issues/11506#note_273202 - - - - - dd94af15 by Krzysztof Gogolewski at 2020-05-20T18:16:53-04:00 Sort deterministically metric output Previously, we sorted according to the test name and way, but the metrics (max_bytes_used/peak_megabytes_allocated etc.) were appearing in nondeterministic order. - - - - - e90b54c1 by Sylvain Henry at 2020-05-20T18:16:56-04:00 Move isDynLinkName into GHC.Types.Name It doesn't belong into GHC.Unit.State - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/merge_request_templates/merge-request.md - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm/Data.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/DataCon.hs-boot - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/PatSyn.hs - compiler/GHC/Core/TyCo/Ppr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/CoreToIface.hs-boot - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Types.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Foreign/Call.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Binary.hs - compiler/GHC/Iface/Ext/Ast.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/480e69ca83f73b299a8cb2e42d7e0e9f15b9806d...e90b54c1bf248617b4f20b460dc21c5da9c5a34a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/480e69ca83f73b299a8cb2e42d7e0e9f15b9806d...e90b54c1bf248617b4f20b460dc21c5da9c5a34a You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 21 03:48:26 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 20 May 2020 23:48:26 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 30 commits: base: Add Generic instances to various datatypes under GHC.* Message-ID: <5ec5fa0a1290a_6e261166e55c389432@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 981bc673 by Fumiaki Kinoshita at 2020-05-20T23:47:40-04:00 base: Add Generic instances to various datatypes under GHC.* * GHC.Fingerprint.Types: Fingerprint * GHC.RTS.Flags: GiveGCStats, GCFlags, ConcFlags, DebugFlags, CCFlags, DoHeapProfile, ProfFlags, DoTrace, TraceFlags, TickyFlags, ParFlags and RTSFlags * GHC.Stats: RTSStats and GCStats * GHC.ByteOrder: ByteOrder * GHC.Unicode: GeneralCategory * GHC.Stack.Types: SrcLoc Metric Increase: haddock.base - - - - - 365c1f1f by Gert-Jan Bottu at 2020-05-20T23:47:41-04:00 Explicit Specificity Implementation for Ticket #16393. Explicit specificity allows users to manually create inferred type variables, by marking them with braces. This way, the user determines which variables can be instantiated through visible type application. The additional syntax is included in the parser, allowing users to write braces in type variable binders (type signatures, data constructors etc). This information is passed along through the renamer and verified in the type checker. The AST for type variable binders, data constructors, pattern synonyms, partial signatures and Template Haskell has been updated to include the specificity of type variables. Minor notes: - Bumps haddock submodule - Disables pattern match checking in GHC.Iface.Type with GHC 8.8 - - - - - ab99955b by Ben Price at 2020-05-20T23:47:44-04:00 Lint should say when it is checking a rule It is rather confusing that when lint finds an error in a rule attached to a binder, it reports the error as in the RHS, not the rule: ... In the RHS of foo We add a clarifying line: ... In the RHS of foo In a rule attached to foo The implication that the rule lives inside the RHS is a bit odd, but this niggle is already present for unfoldings, whose pattern we are following. - - - - - 8b17749b by Ben Gamari at 2020-05-20T23:47:45-04:00 nonmoving: Optimise the write barrier - - - - - 7df648d7 by Andreas Klebinger at 2020-05-20T23:47:46-04:00 Refactor linear reg alloc to remember past assignments. When assigning registers we now first try registers we assigned to in the past, instead of picking the "first" one. This is in extremely helpful when dealing with loops for which variables are dead for part of the loop. This is important for patterns like this: foo = arg1 loop: use(foo) ... foo = getVal() goto loop; There we: * assign foo to the register of arg1. * use foo, it's dead after this use as it's overwritten after. * do other things. * look for a register to put foo in. If we pick an arbitrary one it might differ from the register the start of the loop expect's foo to be in. To fix this we simply look for past register assignments for the given variable. If we find one and the register is free we use that register. This reduces the need for fixup blocks which match the register assignment between blocks. In the example above between the end and the head of the loop. This patch also moves branch weight estimation ahead of register allocation and adds a flag to control it (cmm-static-pred). * It means the linear allocator is more likely to assign the hotter code paths first. * If it assign these first we are: + Less likely to spill on the hot path. + Less likely to introduce fixup blocks on the hot path. These two measure combined are surprisingly effective. Based on nofib we get in the mean: * -0.9% instructions executed * -0.1% reads/writes * -0.2% code size. * -0.1% compiler allocations. * -0.9% compile time. * -0.8% runtime. Most of the benefits are simply a result of removing redundant moves and spills. Reduced compiler allocations likely are the result of less code being generated. (The added lookup is mostly non-allocating). - - - - - f9f62e62 by Andreas Klebinger at 2020-05-20T23:47:47-04:00 NCG: Codelayout: Distinguish conditional and other branches. In #18053 we ended up with a suboptimal code layout because the code layout algorithm didn't distinguish between conditional and unconditional control flow. We can completely eliminate unconditional control flow instructions by placing blocks next to each other, not so much for conditionals. In terms of implementation we simply give conditional branches less weight before computing the layout. Fixes #18053 - - - - - ae4d3378 by Gleb Popov at 2020-05-20T23:47:49-04:00 gitlab-ci: Set locale to C.UTF-8. - - - - - 509efa3e by Stefan Holdermans at 2020-05-20T23:47:51-04:00 Allow spaces in GHCi :script file names This patch updates the user interface of GHCi so that file names passed to the ':script' command may contain spaces escaped with a backslash. For example: :script foo\ bar.script The implementation uses a modified version of 'words' that does not break on escaped spaces. Fixes #18027. - - - - - eac7f5a9 by Stefan Holdermans at 2020-05-20T23:47:51-04:00 Add extra tests for GHCi :script syntax checks The syntax for GHCi's ":script" command allows for only a single file name to be passed as an argument. This patch adds a test for the cases in which a file name is missing or multiple file names are passed. Related to #T18027. - - - - - 96fc852a by Stefan Holdermans at 2020-05-20T23:47:51-04:00 Allow GHCi :script file names in double quotes This patch updates the user interface of GHCi so that file names passed to the ':script' command can be wrapped in double quotes. For example: :script "foo bar.script" The implementation uses a modified version of 'words' that treats character sequences enclosed in double quotes as single words. Fixes #18027. - - - - - 1cbb1fac by Stefan Holdermans at 2020-05-20T23:47:51-04:00 Update documentation for GHCi :script This patch adds the fixes that allow for file names containing spaces to be passed to GHCi's ':script' command to the release notes for 8.12 and expands the user-guide documentation for ':script' by mentioning how such file names can be passed. Related to #18027. - - - - - abdf338c by Tuan Le at 2020-05-20T23:47:52-04:00 llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 - - - - - ce449c2c by John Ericson at 2020-05-20T23:47:53-04:00 Use `Checker` for `tc_pat` - - - - - 66d5ce74 by John Ericson at 2020-05-20T23:47:53-04:00 Use `Checker` for `tc_lpat` and `tc_lpats` - - - - - 6418d5c2 by John Ericson at 2020-05-20T23:47:53-04:00 More judiciously panic in `ts_pat` - - - - - 5303f161 by John Ericson at 2020-05-20T23:47:53-04:00 Put `PatEnv` first in `GHC.Tc.Gen.Pat.Checker` - - - - - e366dc56 by John Ericson at 2020-05-20T23:47:53-04:00 Tiny cleaup eta-reduce away a function argument In GHC, not in the code being compiled! - - - - - 58534dc4 by John Ericson at 2020-05-20T23:47:53-04:00 Use braces with do in `SplicePat` case for consistency - - - - - 55e2f9f5 by buggymcbugfix at 2020-05-20T23:47:54-04:00 Fix spelling mistakes and typos - - - - - 40b4f3fd by buggymcbugfix at 2020-05-20T23:47:54-04:00 Add INLINABLE pragmas to Enum list producers The INLINABLE pragmas ensure that we export stable (unoptimised) unfoldings in the interface file so we can do list fusion at usage sites. Related tickets: #15185, #8763, #18178. - - - - - 5f11cb50 by buggymcbugfix at 2020-05-20T23:47:54-04:00 Piggyback on Enum Word methods for Word64 If we are on a 64 bit platform, we can use the efficient Enum Word methods for the Enum Word64 instance. - - - - - 9f5b1b69 by buggymcbugfix at 2020-05-20T23:47:54-04:00 Document INLINE(ABLE) pragmas that enable fusion - - - - - 042e9fdb by Richard Eisenberg at 2020-05-20T23:47:54-04:00 MR template should ask for key part - - - - - fae4e4d8 by Sebastian Graf at 2020-05-20T23:47:55-04:00 Make `Int`'s `mod` and `rem` strict in their first arguments They used to be strict until 4d2ac2d (9 years ago). It's obviously better to be strict for performance reasons. It also blocks #18067. NoFib results: ``` -------------------------------------------------------------------------------- Program Allocs Instrs -------------------------------------------------------------------------------- integer -1.1% +0.4% wheel-sieve2 +21.2% +20.7% -------------------------------------------------------------------------------- Min -1.1% -0.0% Max +21.2% +20.7% Geometric Mean +0.2% +0.2% ``` The regression in `wheel-sieve2` is due to reboxing that likely will go away with the resolution of #18067. See !3282 for details. Fixes #18187. - - - - - d073c2b4 by Galen Huntington at 2020-05-20T23:47:59-04:00 Clarify pitfalls of NegativeLiterals; see #18022. - - - - - 5a0742e3 by Alexey Kuleshevich at 2020-05-20T23:48:01-04:00 Fix wording in primops documentation to reflect the correct reasoning: * Besides resizing functions, shrinking ones also mutate the size of a mutable array and because of those two `sizeofMutabeByteArray` and `sizeofSmallMutableArray` are now deprecated * Change reference in documentation to the newer functions `getSizeof*` instead of `sizeof*` for shrinking functions * Fix incorrect mention of "byte" instead of "small" - - - - - 59055975 by Andreas Klebinger at 2020-05-20T23:48:01-04:00 Don't variable-length encode magic iface constant. We changed to use variable length encodings for many types by default, including Word32. This makes sense for numbers but not when Word32 is meant to represent four bytes. I added a FixedLengthEncoding newtype to Binary who's instances interpret their argument as a collection of bytes instead of a number. We then use this when writing/reading magic numbers to the iface file. I also took the libery to remove the dummy iface field. This fixes #18180. - - - - - 5f5a625b by Krzysztof Gogolewski at 2020-05-20T23:48:02-04:00 Add a regression test for #11506 The testcase works now. See explanation in https://gitlab.haskell.org/ghc/ghc/issues/11506#note_273202 - - - - - db013fcd by Krzysztof Gogolewski at 2020-05-20T23:48:04-04:00 Sort deterministically metric output Previously, we sorted according to the test name and way, but the metrics (max_bytes_used/peak_megabytes_allocated etc.) were appearing in nondeterministic order. - - - - - c2aeb010 by Sylvain Henry at 2020-05-20T23:48:06-04:00 Move isDynLinkName into GHC.Types.Name It doesn't belong into GHC.Unit.State - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/merge_request_templates/merge-request.md - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Reg/Linear.hs - compiler/GHC/CmmToAsm/Reg/Linear/Base.hs - compiler/GHC/CmmToAsm/Reg/Linear/PPC.hs - compiler/GHC/CmmToAsm/Reg/Linear/SPARC.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/CmmToC.hs - compiler/GHC/CmmToLlvm/Data.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/DataCon.hs-boot - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/PatSyn.hs - compiler/GHC/Core/TyCo/Ppr.hs - compiler/GHC/Core/TyCo/Rep.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e90b54c1bf248617b4f20b460dc21c5da9c5a34a...c2aeb0105565f916d0c7ad191a5a69540ffe1a71 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e90b54c1bf248617b4f20b460dc21c5da9c5a34a...c2aeb0105565f916d0c7ad191a5a69540ffe1a71 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 21 09:19:51 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 21 May 2020 05:19:51 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 30 commits: base: Add Generic instances to various datatypes under GHC.* Message-ID: <5ec647b7adefe_6e263f9ee380384445818b@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 3b273ded by Fumiaki Kinoshita at 2020-05-21T05:18:56-04:00 base: Add Generic instances to various datatypes under GHC.* * GHC.Fingerprint.Types: Fingerprint * GHC.RTS.Flags: GiveGCStats, GCFlags, ConcFlags, DebugFlags, CCFlags, DoHeapProfile, ProfFlags, DoTrace, TraceFlags, TickyFlags, ParFlags and RTSFlags * GHC.Stats: RTSStats and GCStats * GHC.ByteOrder: ByteOrder * GHC.Unicode: GeneralCategory * GHC.Stack.Types: SrcLoc Metric Increase: haddock.base - - - - - dc800bb4 by Gert-Jan Bottu at 2020-05-21T05:18:59-04:00 Explicit Specificity Implementation for Ticket #16393. Explicit specificity allows users to manually create inferred type variables, by marking them with braces. This way, the user determines which variables can be instantiated through visible type application. The additional syntax is included in the parser, allowing users to write braces in type variable binders (type signatures, data constructors etc). This information is passed along through the renamer and verified in the type checker. The AST for type variable binders, data constructors, pattern synonyms, partial signatures and Template Haskell has been updated to include the specificity of type variables. Minor notes: - Bumps haddock submodule - Disables pattern match checking in GHC.Iface.Type with GHC 8.8 - - - - - 86698d79 by Ben Price at 2020-05-21T05:19:05-04:00 Lint should say when it is checking a rule It is rather confusing that when lint finds an error in a rule attached to a binder, it reports the error as in the RHS, not the rule: ... In the RHS of foo We add a clarifying line: ... In the RHS of foo In a rule attached to foo The implication that the rule lives inside the RHS is a bit odd, but this niggle is already present for unfoldings, whose pattern we are following. - - - - - 85e10ab6 by Ben Gamari at 2020-05-21T05:19:06-04:00 nonmoving: Optimise the write barrier - - - - - f5d6087b by Andreas Klebinger at 2020-05-21T05:19:07-04:00 Refactor linear reg alloc to remember past assignments. When assigning registers we now first try registers we assigned to in the past, instead of picking the "first" one. This is in extremely helpful when dealing with loops for which variables are dead for part of the loop. This is important for patterns like this: foo = arg1 loop: use(foo) ... foo = getVal() goto loop; There we: * assign foo to the register of arg1. * use foo, it's dead after this use as it's overwritten after. * do other things. * look for a register to put foo in. If we pick an arbitrary one it might differ from the register the start of the loop expect's foo to be in. To fix this we simply look for past register assignments for the given variable. If we find one and the register is free we use that register. This reduces the need for fixup blocks which match the register assignment between blocks. In the example above between the end and the head of the loop. This patch also moves branch weight estimation ahead of register allocation and adds a flag to control it (cmm-static-pred). * It means the linear allocator is more likely to assign the hotter code paths first. * If it assign these first we are: + Less likely to spill on the hot path. + Less likely to introduce fixup blocks on the hot path. These two measure combined are surprisingly effective. Based on nofib we get in the mean: * -0.9% instructions executed * -0.1% reads/writes * -0.2% code size. * -0.1% compiler allocations. * -0.9% compile time. * -0.8% runtime. Most of the benefits are simply a result of removing redundant moves and spills. Reduced compiler allocations likely are the result of less code being generated. (The added lookup is mostly non-allocating). - - - - - 38b11383 by Andreas Klebinger at 2020-05-21T05:19:08-04:00 NCG: Codelayout: Distinguish conditional and other branches. In #18053 we ended up with a suboptimal code layout because the code layout algorithm didn't distinguish between conditional and unconditional control flow. We can completely eliminate unconditional control flow instructions by placing blocks next to each other, not so much for conditionals. In terms of implementation we simply give conditional branches less weight before computing the layout. Fixes #18053 - - - - - 6a4d0bba by Gleb Popov at 2020-05-21T05:19:09-04:00 gitlab-ci: Set locale to C.UTF-8. - - - - - 62531aae by Stefan Holdermans at 2020-05-21T05:19:12-04:00 Allow spaces in GHCi :script file names This patch updates the user interface of GHCi so that file names passed to the ':script' command may contain spaces escaped with a backslash. For example: :script foo\ bar.script The implementation uses a modified version of 'words' that does not break on escaped spaces. Fixes #18027. - - - - - 34c16050 by Stefan Holdermans at 2020-05-21T05:19:12-04:00 Add extra tests for GHCi :script syntax checks The syntax for GHCi's ":script" command allows for only a single file name to be passed as an argument. This patch adds a test for the cases in which a file name is missing or multiple file names are passed. Related to #T18027. - - - - - c3efc5a2 by Stefan Holdermans at 2020-05-21T05:19:12-04:00 Allow GHCi :script file names in double quotes This patch updates the user interface of GHCi so that file names passed to the ':script' command can be wrapped in double quotes. For example: :script "foo bar.script" The implementation uses a modified version of 'words' that treats character sequences enclosed in double quotes as single words. Fixes #18027. - - - - - d5172429 by Stefan Holdermans at 2020-05-21T05:19:12-04:00 Update documentation for GHCi :script This patch adds the fixes that allow for file names containing spaces to be passed to GHCi's ':script' command to the release notes for 8.12 and expands the user-guide documentation for ':script' by mentioning how such file names can be passed. Related to #18027. - - - - - 08117e3c by Tuan Le at 2020-05-21T05:19:15-04:00 llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 - - - - - 100ebb42 by John Ericson at 2020-05-21T05:19:17-04:00 Use `Checker` for `tc_pat` - - - - - 66d4fa64 by John Ericson at 2020-05-21T05:19:17-04:00 Use `Checker` for `tc_lpat` and `tc_lpats` - - - - - 226fd022 by John Ericson at 2020-05-21T05:19:17-04:00 More judiciously panic in `ts_pat` - - - - - 628e4df0 by John Ericson at 2020-05-21T05:19:18-04:00 Put `PatEnv` first in `GHC.Tc.Gen.Pat.Checker` - - - - - e75eee67 by John Ericson at 2020-05-21T05:19:18-04:00 Tiny cleaup eta-reduce away a function argument In GHC, not in the code being compiled! - - - - - 25bf61c7 by John Ericson at 2020-05-21T05:19:18-04:00 Use braces with do in `SplicePat` case for consistency - - - - - cd116fa4 by buggymcbugfix at 2020-05-21T05:19:18-04:00 Fix spelling mistakes and typos - - - - - 75edca97 by buggymcbugfix at 2020-05-21T05:19:18-04:00 Add INLINABLE pragmas to Enum list producers The INLINABLE pragmas ensure that we export stable (unoptimised) unfoldings in the interface file so we can do list fusion at usage sites. Related tickets: #15185, #8763, #18178. - - - - - 4d40d13b by buggymcbugfix at 2020-05-21T05:19:18-04:00 Piggyback on Enum Word methods for Word64 If we are on a 64 bit platform, we can use the efficient Enum Word methods for the Enum Word64 instance. - - - - - f699e239 by buggymcbugfix at 2020-05-21T05:19:18-04:00 Document INLINE(ABLE) pragmas that enable fusion - - - - - 54865b54 by Richard Eisenberg at 2020-05-21T05:19:19-04:00 MR template should ask for key part - - - - - 3cd5b48f by Sebastian Graf at 2020-05-21T05:19:19-04:00 Make `Int`'s `mod` and `rem` strict in their first arguments They used to be strict until 4d2ac2d (9 years ago). It's obviously better to be strict for performance reasons. It also blocks #18067. NoFib results: ``` -------------------------------------------------------------------------------- Program Allocs Instrs -------------------------------------------------------------------------------- integer -1.1% +0.4% wheel-sieve2 +21.2% +20.7% -------------------------------------------------------------------------------- Min -1.1% -0.0% Max +21.2% +20.7% Geometric Mean +0.2% +0.2% ``` The regression in `wheel-sieve2` is due to reboxing that likely will go away with the resolution of #18067. See !3282 for details. Fixes #18187. - - - - - ad9f8255 by Galen Huntington at 2020-05-21T05:19:25-04:00 Clarify pitfalls of NegativeLiterals; see #18022. - - - - - 08f71a11 by Alexey Kuleshevich at 2020-05-21T05:19:26-04:00 Fix wording in primops documentation to reflect the correct reasoning: * Besides resizing functions, shrinking ones also mutate the size of a mutable array and because of those two `sizeofMutabeByteArray` and `sizeofSmallMutableArray` are now deprecated * Change reference in documentation to the newer functions `getSizeof*` instead of `sizeof*` for shrinking functions * Fix incorrect mention of "byte" instead of "small" - - - - - f72020b6 by Andreas Klebinger at 2020-05-21T05:19:26-04:00 Don't variable-length encode magic iface constant. We changed to use variable length encodings for many types by default, including Word32. This makes sense for numbers but not when Word32 is meant to represent four bytes. I added a FixedLengthEncoding newtype to Binary who's instances interpret their argument as a collection of bytes instead of a number. We then use this when writing/reading magic numbers to the iface file. I also took the libery to remove the dummy iface field. This fixes #18180. - - - - - e92eb120 by Krzysztof Gogolewski at 2020-05-21T05:19:27-04:00 Add a regression test for #11506 The testcase works now. See explanation in https://gitlab.haskell.org/ghc/ghc/issues/11506#note_273202 - - - - - 480ab2c2 by Krzysztof Gogolewski at 2020-05-21T05:19:30-04:00 Sort deterministically metric output Previously, we sorted according to the test name and way, but the metrics (max_bytes_used/peak_megabytes_allocated etc.) were appearing in nondeterministic order. - - - - - 6bc1278b by Sylvain Henry at 2020-05-21T05:19:32-04:00 Move isDynLinkName into GHC.Types.Name It doesn't belong into GHC.Unit.State - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/merge_request_templates/merge-request.md - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Reg/Linear.hs - compiler/GHC/CmmToAsm/Reg/Linear/Base.hs - compiler/GHC/CmmToAsm/Reg/Linear/PPC.hs - compiler/GHC/CmmToAsm/Reg/Linear/SPARC.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/CmmToC.hs - compiler/GHC/CmmToLlvm/Data.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/DataCon.hs-boot - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/PatSyn.hs - compiler/GHC/Core/TyCo/Ppr.hs - compiler/GHC/Core/TyCo/Rep.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c2aeb0105565f916d0c7ad191a5a69540ffe1a71...6bc1278b88e6b82343348d4c0a217391eb33a447 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c2aeb0105565f916d0c7ad191a5a69540ffe1a71...6bc1278b88e6b82343348d4c0a217391eb33a447 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 21 11:56:06 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Thu, 21 May 2020 07:56:06 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18078 Message-ID: <5ec66c5656386_6e2660eff2850357b@gitlab.haskell.org.mail> Simon Peyton Jones pushed new branch wip/T18078 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18078 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 21 11:58:05 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Thu, 21 May 2020 07:58:05 -0400 Subject: [Git][ghc/ghc][wip/T18078] 3 commits: DmdAnal: Improve handling of precise exceptions Message-ID: <5ec66ccdad469_6e263f9ee2d57e0450372c@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T18078 at Glasgow Haskell Compiler / GHC Commits: 9bd20e83 by Sebastian Graf at 2020-05-15T10:42:09-04:00 DmdAnal: Improve handling of precise exceptions This patch does two things: Fix possible unsoundness in what was called the "IO hack" and implement part 2.1 of the "fixing precise exceptions" plan in https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions, which, in combination with !2956, supersedes !3014 and !2525. **IO hack** The "IO hack" (which is a fallback to preserve precise exceptions semantics and thus soundness, rather than some smart thing that increases precision) is called `exprMayThrowPreciseException` now. I came up with two testcases exemplifying possible unsoundness (if twisted enough) in the old approach: - `T13380d`: Demonstrating unsoundness of the "IO hack" when resorting to manual state token threading and direct use of primops. More details below. - `T13380e`: Demonstrating unsoundness of the "IO hack" when we have Nested CPR. Not currently relevant, as we don't have Nested CPR yet. - `T13380f`: Demonstrating unsoundness of the "IO hack" for safe FFI calls. Basically, the IO hack assumed that precise exceptions can only be thrown from a case scrutinee of type `(# State# RealWorld, _ #)`. I couldn't come up with a program using the `IO` abstraction that violates this assumption. But it's easy to do so via manual state token threading and direct use of primops, see `T13380d`. Also similar code might be generated by Nested CPR in the (hopefully not too) distant future, see `T13380e`. Hence, we now have a more careful test in `forcesRealWorld` that passes `T13380{d,e}` (and will hopefully be robust to Nested CPR). **Precise exceptions** In #13380 and #17676 we saw that we didn't preserve precise exception semantics in demand analysis. We fixed that with minimal changes in !2956, but that was terribly unprincipled. That unprincipledness resulted in a loss of precision, which is tracked by these new test cases: - `T13380b`: Regression in dead code elimination, because !2956 was too syntactic about `raiseIO#` - `T13380c`: No need to apply the "IO hack" when the IO action may not throw a precise exception (and the existing IO hack doesn't detect that) Fixing both issues in !3014 turned out to be too complicated and had the potential to regress in the future. Hence we decided to only fix `T13380b` and augment the `Divergence` lattice with a new middle-layer element, `ExnOrDiv`, which means either `Diverges` (, throws an imprecise exception) or throws a *precise* exception. See the wiki page on Step 2.1 for more implementational details: https://gitlab.haskell.org/ghc/ghc/wikis/fixing-precise-exceptions#dead-code-elimination-for-raiseio-with-isdeadenddiv-introducing-exnordiv-step-21 - - - - - 568d7279 by Ben Gamari at 2020-05-15T10:42:46-04:00 GHC.Cmm.Opt: Handle MO_XX_Conv This MachOp was introduced by 2c959a1894311e59cd2fd469c1967491c1e488f3 but a wildcard match in cmmMachOpFoldM hid the fact that it wasn't handled. Ideally we would eliminate the match but this appears to be a larger task. Fixes #18141. - - - - - 502a0efa by Simon Peyton Jones at 2020-05-21T12:57:31+01:00 Implement cast worker/wrapper properly The cast worker/wrapper transformation transforms x = e |> co into y = e x = y |> co This is done by the simplifier, but we were being careless about transferring IdInfo from x to y, and about what to do if x is a NOINLNE function. This resulted in a series of bugs: #17673, #18093, #18078. This patch fixes all that: * Main change is in GHC.Core.Opt.Simplify, and the new prepareBinding function, which does this cast worker/wrapper transform. See Note [Cast worker/wrappers]. * There is quite a bit of refactoring around prepareRhs, makeTrivial etc. It's nicer now. * Some wrappers from strictness and cast w/w, notably those for a function with a NOINLINE, should inline very late. There wasn't really a mechanism for that, which was an existing bug really; so I invented a new finalPhase = Phase (-1). It's used for all simplifier runs after the user-visible phase 2,1,0 have run. (No new runs of the simplifier are introduced thereby.) See new Note [Compiler phases] in GHC.Types.Basic; the main changes are in GHC.Core.Opt.Driver * Doing this made me trip over two places where the AnonArgFlag on a FunTy was being lost so we could end up with (Num a -> ty) rather than (Num a => ty) - In coercionLKind/coercionRKind - In contHoleType in the Simplifier I fixed the former by defining mkFunctionType and using it in coercionLKind/RKind. I could have done the same for the latter, but the information is almost to hand. So I fixed the latter by - adding sc_hole_ty to ApplyToVal (like ApplyToTy), - adding as_hole_ty to ValArg (like TyArg) - adding sc_fun_ty to StrictArg Turned out I could then remove ai_type from ArgInfo. This is just moving the deck chairs around, but it worked out nicely. See the new Note [AnonArgFlag] in GHC.Types.Var * When looking at the 'arity decrease' thing (#18093) I discovered that stable unfoldings had a much lower arity than the actual optimised function. That's what led to the arity-decrease message. Simple solution: eta-expand. It's described in Note [Eta-expand stable unfoldings] in GHC.Core.Opt.Simplify I made a test case for #18078, and a very similar one for #17673. The net effect of all this on nofib is very modest, but positive: -------------------------------------------------------------------------------- Program Size Allocs Runtime Elapsed TotalMem -------------------------------------------------------------------------------- anna -0.4% -0.1% -3.1% -3.1% 0.0% fannkuch-redux -0.4% -0.3% -0.1% -0.1% 0.0% maillist -0.4% -0.1% -7.8% -1.0% -14.3% primetest -0.4% -15.6% -7.1% -6.6% 0.0% -------------------------------------------------------------------------------- Min -0.9% -15.6% -13.3% -14.2% -14.3% Max -0.3% 0.0% +12.1% +12.4% 0.0% Geometric Mean -0.4% -0.2% -2.3% -2.2% -0.1% - - - - - 30 changed files: - compiler/GHC.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Core/Arity.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/Driver.hs - compiler/GHC/Core/Opt/FloatIn.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/LiberateCase.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/ForeignCall.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Types/Id/Make.hs - compiler/GHC/Types/Var.hs - + testsuite/tests/cmm/opt/T18141.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c4eb188afb7b97dd96a116c491b1cb007b354bf8...502a0efae33f92b39bc522b4dc21729551cef5d0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c4eb188afb7b97dd96a116c491b1cb007b354bf8...502a0efae33f92b39bc522b4dc21729551cef5d0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 21 13:28:27 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Thu, 21 May 2020 09:28:27 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18213 Message-ID: <5ec681fb88868_6e263f9ee2d57e0450810@gitlab.haskell.org.mail> Simon Peyton Jones pushed new branch wip/T18213 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18213 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 21 13:59:44 2020 From: gitlab at gitlab.haskell.org (Sven Tennie) Date: Thu, 21 May 2020 09:59:44 -0400 Subject: [Git][ghc/ghc][wip/ghc-debug] 2 commits: Add some haddock Message-ID: <5ec68950edba8_6e263f9ed6ad528c512532@gitlab.haskell.org.mail> Sven Tennie pushed to branch wip/ghc-debug at Glasgow Haskell Compiler / GHC Commits: 00c297f8 by Sven Tennie at 2020-05-19T09:07:16+02:00 Add some haddock - - - - - 660eedc8 by Sven Tennie at 2020-05-21T15:59:33+02:00 Decode StgStack with hsc2hs and add some haddock - - - - - 4 changed files: - libraries/ghc-heap/GHC/Exts/Heap.hs - libraries/ghc-heap/GHC/Exts/Heap/Closures.hs - libraries/ghc-heap/GHC/Exts/Heap/FFIClosures.hsc - rts/Heap.c Changes: ===================================== libraries/ghc-heap/GHC/Exts/Heap.hs ===================================== @@ -72,8 +72,16 @@ import Foreign #include "ghcconfig.h" class HasHeapRep (a :: TYPE rep) where - getClosureDataX :: (forall c . c -> IO (Ptr StgInfoTable, [Word], [b])) - -> a -> IO (GenClosure b) + + -- | Decode a closure to it's heap representation ('GenClosure'). + -- Inside a GHC context 'b' is usually a 'GHC.Exts.Heap.Closures.Box' + -- containing a thunk or an evaluated heap object. Outside it can be a + -- 'Word' for "raw" usage of pointers. + getClosureDataX :: + (forall c . c -> IO (Ptr StgInfoTable, [Word], [b])) + -- ^ Helper function to get info table, memory and pointers of the closure + -> a -- ^ Closure to decode + -> IO (GenClosure b) -- Heap representation of the closure instance HasHeapRep (a :: TYPE 'LiftedRep) where getClosureDataX = getClosureX @@ -115,7 +123,11 @@ amap' f (Array i0 i _ arr#) = map g [0 .. i - i0] where g (I# i#) = case indexArray# arr# i# of (# e #) -> f e - +-- | Takes any value (closure) as parameter and returns a tuple of: +-- * A 'Ptr' to the info table +-- * The memory of the closure as @[Word]@ +-- * Pointers of the closure's @struct@ (in C code) in a @[Box]@. +-- The pointers are collected in @Heap.c at . getClosureRaw :: a -> IO (Ptr StgInfoTable, [Word], [Box]) getClosureRaw x = do case unpackClosure# x of @@ -307,32 +319,35 @@ getClosureX get_closure_raw x = do , trec = (pts !! 3) , blocked_exceptions = (pts !! 4) , bq = (pts !! 5) - , what_next = FFIClosures.what_next fields - , why_blocked = FFIClosures.why_blocked fields - , flags = FFIClosures.flags fields - , threadId = FFIClosures.threadId fields - , saved_errno = FFIClosures.saved_errno fields - , dirty = FFIClosures.dirty fields - , alloc_limit = FFIClosures.alloc_limit fields - , tot_stack_size = FFIClosures.tot_stack_size fields + , what_next = FFIClosures.tso_what_next fields + , why_blocked = FFIClosures.tso_why_blocked fields + , flags = FFIClosures.tso_flags fields + , threadId = FFIClosures.tso_threadId fields + , saved_errno = FFIClosures.tso_saved_errno fields + , tso_dirty = FFIClosures.tso_dirty fields + , alloc_limit = FFIClosures.tso_alloc_limit fields + , tot_stack_size = FFIClosures.tso_tot_stack_size fields } ) STACK -> do - unless (length pts >= 1) $ - fail $ "Expected at least 1 ptr argument to STACK, found " + unless (length pts == 1) $ + fail $ "Expected 1 ptr argument to STACK, found " ++ show (length pts) - let splitWord = rawWds !! 0 - pure $ StackClosure itbl -#if defined(WORDS_BIGENDIAN) - (fromIntegral $ shiftR splitWord (wORD_SIZE_IN_BITS `div` 2)) - (fromIntegral splitWord) -#else - (fromIntegral splitWord) - (fromIntegral $ shiftR splitWord (wORD_SIZE_IN_BITS `div` 2)) -#endif - (pts !! 0) - [] + allocaArray (length wds) (\ptr -> do + pokeArray ptr wds + + fields <- FFIClosures.peekStackFields ptr + + pure $ StackClosure + { info = itbl + , size = FFIClosures.stack_size fields + , stack_dirty = FFIClosures.stack_dirty fields + , stackPointer = (pts !! 0) + , stack = FFIClosures.stack fields + , stack_marking = FFIClosures.stack_marking fields + } + ) _ -> pure $ UnsupportedClosure itbl ===================================== libraries/ghc-heap/GHC/Exts/Heap/Closures.hs ===================================== @@ -260,7 +260,9 @@ data GenClosure b , link :: !b -- ^ next weak pointer for the capability, can be NULL. } - -- | StgTSO + -- | Representation of StgTSO: A Thread State Object. + -- The values for 'what_next', 'why_blocked' and 'flags' are defined in + -- @Constants.h at . | TSOClosure { info :: !StgInfoTable -- pointers @@ -276,16 +278,17 @@ data GenClosure b , flags :: Word32 , threadId :: Word64 , saved_errno :: Word32 - , dirty:: Word32 + , tso_dirty:: Word32 -- ^ non-zero => dirty , alloc_limit :: Int64 , tot_stack_size :: Word32 } - + -- Representation of StgStack: The 'tsoStack' of a 'TSOClosure'. | StackClosure { info :: !StgInfoTable - , size :: !HalfWord - , dirty :: !HalfWord - , stackPointer :: !b + , size :: !Word32 -- ^ stack size in *words* + , stack_dirty :: !Word8 -- ^ non-zero => dirty + , stack_marking :: Word8 + , stackPointer :: !b -- ^ current stack pointer , stack :: [Word] } ===================================== libraries/ghc-heap/GHC/Exts/Heap/FFIClosures.hsc ===================================== @@ -8,16 +8,16 @@ import Foreign -- TODO use sum type for what_next, why_blocked, flags? data TSOFields = TSOFields { - what_next :: Word16, - why_blocked :: Word16, - flags :: Word32, + tso_what_next :: Word16, + tso_why_blocked :: Word16, + tso_flags :: Word32, -- Unfortunately block_info is a union without clear discriminator. -- block_info :: TDB, - threadId :: Word64, - saved_errno :: Word32, - dirty:: Word32, - alloc_limit :: Int64, - tot_stack_size :: Word32 + tso_threadId :: Word64, + tso_saved_errno :: Word32, + tso_dirty:: Word32, + tso_alloc_limit :: Int64, + tso_tot_stack_size :: Word32 -- TODO StgTSOProfInfo prof is optionally included, but looks very interesting. } @@ -34,12 +34,36 @@ peekTSOFields ptr = do tot_stack_size' <- (#peek struct StgTSO_, tot_stack_size) ptr return TSOFields { - what_next = what_next', - why_blocked = why_blocked', - flags = flags', - threadId = threadId', - saved_errno = saved_errno', - dirty= dirty', - alloc_limit = alloc_limit', - tot_stack_size = tot_stack_size' + tso_what_next = what_next', + tso_why_blocked = why_blocked', + tso_flags = flags', + tso_threadId = threadId', + tso_saved_errno = saved_errno', + tso_dirty= dirty', + tso_alloc_limit = alloc_limit', + tso_tot_stack_size = tot_stack_size' + } + +data StackFields = StackFields { + stack_size :: Word32, + stack_dirty :: Word8, + stack_marking :: Word8, + stack :: [Word] +} + +-- | Get non-closure fields from @StgStack_@ (@TSO.h@) +peekStackFields :: Ptr a -> IO StackFields +peekStackFields ptr = do + stack_size' <- (#peek struct StgStack_, stack_size) ptr ::IO Word32 + dirty' <- (#peek struct StgStack_, dirty) ptr + marking' <- (#peek struct StgStack_, marking) ptr + + let stackPtr = (#ptr struct StgStack_, stack) ptr + stack' <- peekArray (fromIntegral stack_size') stackPtr + + return StackFields { + stack_size = stack_size', + stack_dirty = dirty', + stack_marking = marking', + stack = stack' } ===================================== rts/Heap.c ===================================== @@ -226,10 +226,9 @@ static StgWord collect_pointers(StgClosure *closure, StgWord size, StgClosure *p break; case STACK: + ASSERT((StgClosure *)((StgStack *)closure)->sp != NULL); ptrs[nptrs++] = (StgClosure *)((StgStack *)closure)->sp; break; - - case WEAK: ptrs[nptrs++] = (StgClosure *)((StgWeak *)closure)->cfinalizers; ptrs[nptrs++] = (StgClosure *)((StgWeak *)closure)->key; View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4e78046b7c166ee69e0200dbb8d4c1f3f3f13930...660eedc8f6e039545c9b5a77ac7be5427c3f3d43 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4e78046b7c166ee69e0200dbb8d4c1f3f3f13930...660eedc8f6e039545c9b5a77ac7be5427c3f3d43 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 21 14:44:33 2020 From: gitlab at gitlab.haskell.org (Sven Tennie) Date: Thu, 21 May 2020 10:44:33 -0400 Subject: [Git][ghc/ghc][wip/ghc-debug] Add comments to RtsApi functions Message-ID: <5ec693d194522_6e2611d4b1b8517873@gitlab.haskell.org.mail> Sven Tennie pushed to branch wip/ghc-debug at Glasgow Haskell Compiler / GHC Commits: 1589e28f by Sven Tennie at 2020-05-21T16:44:14+02:00 Add comments to RtsApi functions - - - - - 1 changed file: - rts/RtsAPI.c Changes: ===================================== rts/RtsAPI.c ===================================== @@ -660,14 +660,18 @@ RtsPaused rts_pause (void) return paused; } -void rts_unpause (RtsPaused paused) +// Counterpart of rts_pause: Continue from a pause. +void rts_unpause (RtsPaused paused) { rts_paused = false; releaseAllCapabilities(n_capabilities, paused.capabilities, paused.pausing_task); freeTask(paused.pausing_task); } - +// Call cb for all StgTSOs. *user is a user defined payload to cb. It's not +// used by the RTS. +// rts_listThreads should only be called when the RTS is paused, i.e. rts_pause +// was called before. void rts_listThreads(ListThreadsCb cb, void *user) { ASSERT(rts_paused); @@ -691,6 +695,11 @@ static void list_roots_helper(void *user, StgClosure **p) { ctx->cb(ctx->user, *p); } +// Call cb for all StgClosures reachable from threadStableNameTable and +// threadStablePtrTable. *user is a user defined payload to cb. It's not +// used by the RTS. +// rts_listMiscRoots should only be called when the RTS is paused, i.e. +// rts_pause was called before. void rts_listMiscRoots (ListRootsCb cb, void *user) { struct list_roots_ctx ctx; @@ -713,7 +722,7 @@ RtsPaused rts_pause (void) return paused; } -void rts_unpause (RtsPaused paused STG_UNUSED) +void rts_unpause (RtsPaused paused STG_UNUSED) { errorBelch("Warning: Unpausing the RTS is only possible for " "multithreaded RTS."); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1589e28f72298023c15915792408bd26ba9f61bc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1589e28f72298023c15915792408bd26ba9f61bc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 21 15:33:16 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 21 May 2020 11:33:16 -0400 Subject: [Git][ghc/ghc][wip/T18069] base: Bump to 4.15.0.0 Message-ID: <5ec69f3c9e532_6e263f9ee380384452770@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18069 at Glasgow Haskell Compiler / GHC Commits: e5072549 by Ben Gamari at 2020-05-21T11:32:59-04:00 base: Bump to 4.15.0.0 - - - - - 1 changed file: - libraries/base/base.cabal Changes: ===================================== libraries/base/base.cabal ===================================== @@ -1,6 +1,6 @@ cabal-version: 3.0 name: base -version: 4.14.0.0 +version: 4.15.0.0 -- NOTE: Don't forget to update ./changelog.md license: BSD-3-Clause View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e5072549841402ab84fd12fea22851d5584105aa -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e5072549841402ab84fd12fea22851d5584105aa You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 21 15:36:03 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 21 May 2020 11:36:03 -0400 Subject: [Git][ghc/ghc][wip/T17619] simplCore: Ignore ticks in rule templates Message-ID: <5ec69fe3c7edf_6e263f9eea2381ec5281f2@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T17619 at Glasgow Haskell Compiler / GHC Commits: 8cbfcac6 by Ben Gamari at 2020-05-21T11:35:57-04:00 simplCore: Ignore ticks in rule templates This fixes #17619, where a tick snuck in to the template of a rule, resulting in a panic during rule matching. The tick in question was introduced via post-inlining, as discussed in `Note [Simplifying rules]`. The solution we decided upon was to simply ignore ticks in the rule template, as discussed in `Note [Tick annotations in RULE matching]`. Fixes #18162. Fixes #17619. - - - - - 2 changed files: - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Rules.hs Changes: ===================================== compiler/GHC/Core/Opt/Simplify/Utils.hs ===================================== @@ -830,6 +830,21 @@ Ticks into the LHS, which makes matching trickier. #10665, #10745. Doing this to either side confounds tools like HERMIT, which seek to reason about and apply the RULES as originally written. See #10829. +There is, however, one case where we are pretty much /forced/ to transform the +LHS of a rule: postInlineUnconditionally. For instance, in the case of + + let f = g @Int in f + +We very much want to inline f into the body of the let. However, to do so (and +be able to safely drop f's binding) we must inline into all occurrences of f, +including those in the LHS of rules. + +This can cause somewhat surprising results; for instance, in #18162 we found +that a rule template contained ticks in its arguments, because +postInlineUnconditionally substituted in a trivial expression that contains +ticks. See Note [Tick annotations in RULE matching] in GHC.Core.Rules for +details. + Note [No eta expansion in stable unfoldings] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If we have a stable unfolding @@ -1251,6 +1266,10 @@ it's best to inline it anyway. We often get a=E; b=a from desugaring, with both a and b marked NOINLINE. But that seems incompatible with our new view that inlining is like a RULE, so I'm sticking to the 'active' story for now. + +NB: unconditional inlining of this sort can introduce ticks in places that +may seem surprising; for instance, the LHS of rules. See Note [Simplfying +rules] for details. -} postInlineUnconditionally ===================================== compiler/GHC/Core/Rules.hs ===================================== @@ -714,11 +714,15 @@ match :: RuleMatchEnv -> CoreExpr -- Target -> Maybe RuleSubst --- We look through certain ticks. See note [Tick annotations in RULE matching] +-- We look through certain ticks. See Note [Tick annotations in RULE matching] match renv subst e1 (Tick t e2) | tickishFloatable t = match renv subst' e1 e2 where subst' = subst { rs_binds = rs_binds subst . mkTick t } +match renv subst (Tick t e1) e2 + -- Ignore ticks in rule template. + | tickishFloatable t + = match renv subst e1 e2 match _ _ e at Tick{} _ = pprPanic "Tick in rule" (ppr e) @@ -1016,7 +1020,7 @@ Hence, (a) the guard (not (isLocallyBoundR v2)) Note [Tick annotations in RULE matching] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -We used to unconditionally look through Notes in both template and +We used to unconditionally look through ticks in both template and expression being matched. This is actually illegal for counting or cost-centre-scoped ticks, because we have no place to put them without changing entry counts and/or costs. So now we just fail the match in @@ -1025,6 +1029,11 @@ these cases. On the other hand, where we are allowed to insert new cost into the tick scope, we can float them upwards to the rule application site. +Moreover, we may encounter ticks in the template of a rule. There are a few +ways in which these may be introduced (e.g. #18162, #17619). Such ticks are +ignored by the matcher. See Note [Simplifying rules] in +GHC.Core.Opt.Simplify.Utils for details. + cf Note [Notes in call patterns] in GHC.Core.Opt.SpecConstr Note [Matching lets] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8cbfcac64e6650badcd99a3d189801e7d9faa3cb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8cbfcac64e6650badcd99a3d189801e7d9faa3cb You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 21 15:43:28 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 21 May 2020 11:43:28 -0400 Subject: [Git][ghc/ghc][wip/modbreaks-crash] 2 commits: Coverage: Don't produce ModBreaks if not HscInterpreted Message-ID: <5ec6a1a065255_6e263f9ee38038445330b3@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/modbreaks-crash at Glasgow Haskell Compiler / GHC Commits: f684a7d5 by Ben Gamari at 2020-05-21T11:43:20-04:00 Coverage: Don't produce ModBreaks if not HscInterpreted emptyModBreaks contains a bottom and consequently it's important that we don't use it unless necessary. - - - - - fabf051d by Ben Gamari at 2020-05-21T11:43:21-04:00 Coverage: Factor out addMixEntry - - - - - 1 changed file: - compiler/GHC/HsToCore/Coverage.hs Changes: ===================================== compiler/GHC/HsToCore/Coverage.hs ===================================== @@ -117,7 +117,7 @@ addTicksToBinds hsc_env mod mod_loc exports tyCons binds dumpIfSet_dyn dflags Opt_D_dump_ticked "HPC" FormatHaskell (pprLHsBinds binds1) - return (binds1, HpcInfo tickCount hashNo, Just modBreaks) + return (binds1, HpcInfo tickCount hashNo, modBreaks) | otherwise = return (binds, emptyHpcInfo False, Nothing) @@ -134,23 +134,23 @@ guessSourceFile binds orig_file = _ -> orig_file -mkModBreaks :: HscEnv -> Module -> Int -> [MixEntry_] -> IO ModBreaks +mkModBreaks :: HscEnv -> Module -> Int -> [MixEntry_] -> IO (Maybe ModBreaks) mkModBreaks hsc_env mod count entries - | HscInterpreted <- hscTarget (hsc_dflags hsc_env) = do + | breakpointsEnabled (hsc_dflags hsc_env) = do breakArray <- GHCi.newBreakArray hsc_env (length entries) ccs <- mkCCSArray hsc_env mod count entries let locsTicks = listArray (0,count-1) [ span | (span,_,_,_) <- entries ] varsTicks = listArray (0,count-1) [ vars | (_,_,vars,_) <- entries ] declsTicks = listArray (0,count-1) [ decls | (_,decls,_,_) <- entries ] - return emptyModBreaks + return $ Just $ emptyModBreaks { modBreaks_flags = breakArray , modBreaks_locs = locsTicks , modBreaks_vars = varsTicks , modBreaks_decls = declsTicks , modBreaks_ccs = ccs } - | otherwise = return emptyModBreaks + | otherwise = return Nothing mkCCSArray :: HscEnv -> Module -> Int -> [MixEntry_] @@ -1008,6 +1008,15 @@ data TickTransState = TT { tickBoxCount:: !Int , ccIndices :: !CostCentreState } +addMixEntry :: MixEntry_ -> TM Int +addMixEntry ent = do + c <- tickBoxCount <$> getState + setState $ \st -> + st { tickBoxCount = c + 1 + , mixEntries = ent : mixEntries st + } + return c + data TickTransEnv = TTE { fileName :: FastString , density :: TickDensity , tte_dflags :: DynFlags @@ -1027,7 +1036,7 @@ data TickishType = ProfNotes | HpcTicks | Breakpoints | SourceNotes coveragePasses :: DynFlags -> [TickishType] coveragePasses dflags = - ifa (hscTarget dflags == HscInterpreted) Breakpoints $ + ifa (breakpointsEnabled dflags) Breakpoints $ ifa (gopt Opt_Hpc dflags) HpcTicks $ ifa (gopt Opt_SccProfilingOn dflags && profAuto dflags /= NoProfAuto) ProfNotes $ @@ -1035,6 +1044,10 @@ coveragePasses dflags = where ifa f x xs | f = x:xs | otherwise = xs +-- | Should we produce 'Breakpoint' ticks? +breakpointsEnabled :: DynFlags -> Bool +breakpointsEnabled dflags = hscTarget dflags == HscInterpreted + -- | Tickishs that only make sense when their source code location -- refers to the current file. This might not always be true due to -- LINE pragmas in the code - which would confuse at least HPC. @@ -1201,11 +1214,7 @@ mkTickish boxLabel countEntries topOnly pos fvs decl_path = do dflags <- getDynFlags env <- getEnv case tickishType env of - HpcTicks -> do - c <- liftM tickBoxCount getState - setState $ \st -> st { tickBoxCount = c + 1 - , mixEntries = me : mixEntries st } - return $ HpcTick (this_mod env) c + HpcTicks -> HpcTick (this_mod env) <$> addMixEntry me ProfNotes -> do let nm = mkFastString cc_name @@ -1214,11 +1223,7 @@ mkTickish boxLabel countEntries topOnly pos fvs decl_path = do count = countEntries && gopt Opt_ProfCountEntries dflags return $ ProfNote cc count True{-scopes-} - Breakpoints -> do - c <- liftM tickBoxCount getState - setState $ \st -> st { tickBoxCount = c + 1 - , mixEntries = me:mixEntries st } - return $ Breakpoint c ids + Breakpoints -> Breakpoint <$> addMixEntry me <*> pure ids SourceNotes | RealSrcSpan pos' _ <- pos -> return $ SourceNote pos' cc_name @@ -1239,22 +1244,15 @@ allocBinTickBox boxLabel pos m = do mkBinTickBoxHpc :: (Bool -> BoxLabel) -> SrcSpan -> LHsExpr GhcTc -> TM (LHsExpr GhcTc) -mkBinTickBoxHpc boxLabel pos e = - TM $ \ env st -> - let meT = (pos,declPath env, [],boxLabel True) - meF = (pos,declPath env, [],boxLabel False) - meE = (pos,declPath env, [],ExpBox False) - c = tickBoxCount st - mes = mixEntries st - in - ( L pos $ HsTick noExtField (HpcTick (this_mod env) c) - $ L pos $ HsBinTick noExtField (c+1) (c+2) e - -- notice that F and T are reversed, - -- because we are building the list in - -- reverse... - , noFVs - , st {tickBoxCount=c+3 , mixEntries=meF:meT:meE:mes} - ) +mkBinTickBoxHpc boxLabel pos e = do + env <- getEnv + binTick <- HsBinTick noExtField + <$> addMixEntry (pos,declPath env, [],boxLabel True) + <*> addMixEntry (pos,declPath env, [],boxLabel False) + <*> pure e + tick <- HpcTick (this_mod env) + <$> addMixEntry (pos,declPath env, [],ExpBox False) + return $ L pos $ HsTick noExtField tick (L pos binTick) mkHpcPos :: SrcSpan -> HpcPos mkHpcPos pos@(RealSrcSpan s _) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ced73b7bf45d44e91ef6bc3ccef698e9270ac63c...fabf051d23887031dc8bb3db5619a11c5d0882b5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ced73b7bf45d44e91ef6bc3ccef698e9270ac63c...fabf051d23887031dc8bb3db5619a11c5d0882b5 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 21 15:56:01 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 21 May 2020 11:56:01 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18210 Message-ID: <5ec6a491211b8_6e263f9ee33d027c53684c@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/T18210 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18210 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 21 16:01:44 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Thu, 21 May 2020 12:01:44 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18191 Message-ID: <5ec6a5e81cd7a_6e263f9ee38038445385fa@gitlab.haskell.org.mail> Ryan Scott pushed new branch wip/T18191 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18191 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 21 16:04:09 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 21 May 2020 12:04:09 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/ignore-revs Message-ID: <5ec6a679421a0_6e263f9ee33d027c53872a@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/ignore-revs at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/ignore-revs You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 21 16:08:01 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 21 May 2020 12:08:01 -0400 Subject: [Git][ghc/ghc][wip/ignore-revs] git: Add ignored commits file Message-ID: <5ec6a7615c50f_6e263f9f0bd8e174540553@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/ignore-revs at Glasgow Haskell Compiler / GHC Commits: fa99702f by Ben Gamari at 2020-05-21T12:07:53-04:00 git: Add ignored commits file This can be used to tell git to ignore bulk renaming commits like the recently-finished module hierarchy refactoring. Configured with, git config --set blame.ignoreRevsFile .git-ignore-revs - - - - - 1 changed file: - + .git-ignore-revs Changes: ===================================== .git-ignore-revs ===================================== @@ -0,0 +1,23 @@ +# Configure git to ignore commits listed in this file with: +# +# git config --set blame.ignoreRevsFile .git-ignore-revs + +# Module Hierarchy Renamings +af332442123878c1b61d236dce46418efcbe8750 +255418da5d264fb2758bc70925adb2094f34adc3 +1941ef4f050c0dfcb68229641fcbbde3a10f1072 +528df8ecb4e2f9c78b1ae4ab7ff8230644e9b643 +18a346a4b5a02b8c62e8eedb91b35c2d8e754b96 +817f93eac4d13f680e8e3e7a25eb403b1864f82e +1b1067d14b656bbbfa7c47f156ec2700c9751549 +240f5bf6f53515535be5bf3ef7632aa69ae21e3e +1500f0898e85316c7c97a2f759d83278a072ab0e +3ca52151881451ce5b3a7740d003e811b586140d +cf739945b8b28ff463dc44925348f20b3c1f22cb +da7f74797e8c322006eba385c9cbdce346dd1d43 +6e2d9ee25bce06ae51d2f1cf8df4f7422106a383 +d491a6795d507eabe35d8aec63c534d29f2d305b +99a9f51bf8207c79241fc0b685fadeb222a61292 +eb6082358cdb5f271a8e4c74044a12f97352c52f +5119296440e6846c553c72b8a93afc5ecfa576f0 +447864a94a1679b5b079e08bb7208a0005381cef View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fa99702f4adfd42dd66469e09052eeee65c9c4c6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fa99702f4adfd42dd66469e09052eeee65c9c4c6 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 21 16:09:53 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 21 May 2020 12:09:53 -0400 Subject: [Git][ghc/ghc][wip/ignore-revs] git: Add ignored commits file Message-ID: <5ec6a7d11fd8a_6e263f9ed4defb5454091e@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/ignore-revs at Glasgow Haskell Compiler / GHC Commits: 3be747f9 by Ben Gamari at 2020-05-21T12:09:41-04:00 git: Add ignored commits file This can be used to tell git to ignore bulk renaming commits like the recently-finished module hierarchy refactoring. Configured with, git config blame.ignoreRevsFile .git-ignore-revs - - - - - 1 changed file: - + .git-ignore-revs Changes: ===================================== .git-ignore-revs ===================================== @@ -0,0 +1,23 @@ +# Configure git to ignore commits listed in this file with: +# +# git config blame.ignoreRevsFile .git-ignore-revs + +# Module Hierarchy Renamings +af332442123878c1b61d236dce46418efcbe8750 +255418da5d264fb2758bc70925adb2094f34adc3 +1941ef4f050c0dfcb68229641fcbbde3a10f1072 +528df8ecb4e2f9c78b1ae4ab7ff8230644e9b643 +18a346a4b5a02b8c62e8eedb91b35c2d8e754b96 +817f93eac4d13f680e8e3e7a25eb403b1864f82e +1b1067d14b656bbbfa7c47f156ec2700c9751549 +240f5bf6f53515535be5bf3ef7632aa69ae21e3e +1500f0898e85316c7c97a2f759d83278a072ab0e +3ca52151881451ce5b3a7740d003e811b586140d +cf739945b8b28ff463dc44925348f20b3c1f22cb +da7f74797e8c322006eba385c9cbdce346dd1d43 +6e2d9ee25bce06ae51d2f1cf8df4f7422106a383 +d491a6795d507eabe35d8aec63c534d29f2d305b +99a9f51bf8207c79241fc0b685fadeb222a61292 +eb6082358cdb5f271a8e4c74044a12f97352c52f +5119296440e6846c553c72b8a93afc5ecfa576f0 +447864a94a1679b5b079e08bb7208a0005381cef View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3be747f98eb0783712bab0d96f2856b7dba468e0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3be747f98eb0783712bab0d96f2856b7dba468e0 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 21 16:10:05 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 21 May 2020 12:10:05 -0400 Subject: [Git][ghc/ghc][master] Remove duplicate Note [When to print foralls] in GHC.Core.TyCo.Ppr Message-ID: <5ec6a7dd662ff_6e2679b9a4054272f@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 5bcf8606 by Ryan Scott at 2020-05-17T08:46:38-04:00 Remove duplicate Note [When to print foralls] in GHC.Core.TyCo.Ppr There are two different Notes named `[When to print foralls]`. The most up-to-date one is in `GHC.Iface.Type`, but there is a second one in `GHC.Core.TyCo.Ppr`. The latter is less up-to-date, as it was written before GHC switched over to using ifaces to pretty-print types. I decided to just remove the latter and replace it with a reference to the former. [ci skip] - - - - - 1 changed file: - compiler/GHC/Core/TyCo/Ppr.hs Changes: ===================================== compiler/GHC/Core/TyCo/Ppr.hs ===================================== @@ -171,7 +171,8 @@ pprSigmaType = pprIfaceSigmaType ShowForAllWhen . tidyToIfaceType pprForAll :: [TyCoVarBinder] -> SDoc pprForAll tvs = pprIfaceForAll (map toIfaceForAllBndr tvs) --- | Print a user-level forall; see Note [When to print foralls] in this module. +-- | Print a user-level forall; see @Note [When to print foralls]@ in +-- "GHC.Iface.Type". pprUserForAll :: [TyCoVarBinder] -> SDoc pprUserForAll = pprUserIfaceForAll . map toIfaceForAllBndr @@ -253,24 +254,6 @@ debug_ppr_ty prec ty@(ForAllTy {}) = ([], ty) {- -Note [When to print foralls] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Mostly we want to print top-level foralls when (and only when) the user specifies --fprint-explicit-foralls. But when kind polymorphism is at work, that suppresses -too much information; see #9018. - -So I'm trying out this rule: print explicit foralls if - a) User specifies -fprint-explicit-foralls, or - b) Any of the quantified type variables has a kind - that mentions a kind variable - -This catches common situations, such as a type siguature - f :: m a -which means - f :: forall k. forall (m :: k->*) (a :: k). m a -We really want to see both the "forall k" and the kind signatures -on m and a. The latter comes from pprTCvBndr. - Note [Infix type variables] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ With TypeOperators you can say View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5bcf86063c0e5b6ee0d162ea64c88fdaad89e620 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5bcf86063c0e5b6ee0d162ea64c88fdaad89e620 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 21 16:10:53 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 21 May 2020 12:10:53 -0400 Subject: [Git][ghc/ghc][master] base: Add Generic instances to various datatypes under GHC.* Message-ID: <5ec6a80d9ddf9_6e263f9eea2381ec5483e5@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 55f0e783 by Fumiaki Kinoshita at 2020-05-21T12:10:44-04:00 base: Add Generic instances to various datatypes under GHC.* * GHC.Fingerprint.Types: Fingerprint * GHC.RTS.Flags: GiveGCStats, GCFlags, ConcFlags, DebugFlags, CCFlags, DoHeapProfile, ProfFlags, DoTrace, TraceFlags, TickyFlags, ParFlags and RTSFlags * GHC.Stats: RTSStats and GCStats * GHC.ByteOrder: ByteOrder * GHC.Unicode: GeneralCategory * GHC.Stack.Types: SrcLoc Metric Increase: haddock.base - - - - - 5 changed files: - libraries/base/GHC/ByteOrder.hs - libraries/base/GHC/Generics.hs - libraries/base/GHC/RTS/Flags.hsc - libraries/base/GHC/Stats.hsc - libraries/base/changelog.md Changes: ===================================== libraries/base/GHC/ByteOrder.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-} +{-# LANGUAGE DeriveGeneric #-} ----------------------------------------------------------------------------- -- | @@ -20,6 +21,8 @@ module GHC.ByteOrder where -- Required for WORDS_BIGENDIAN #include +import GHC.Generics (Generic) + -- | Byte ordering. data ByteOrder = BigEndian -- ^ most-significant-byte occurs in lowest address. @@ -30,6 +33,7 @@ data ByteOrder , Enum -- ^ @since 4.11.0.0 , Read -- ^ @since 4.11.0.0 , Show -- ^ @since 4.11.0.0 + , Generic -- ^ @since 4.15.0.0 ) -- | The byte ordering of the target machine. ===================================== libraries/base/GHC/Generics.hs ===================================== @@ -746,6 +746,9 @@ import GHC.Classes ( Eq(..), Ord(..) ) import GHC.Enum ( Bounded, Enum ) import GHC.Read ( Read(..) ) import GHC.Show ( Show(..), showString ) +import GHC.Stack.Types ( SrcLoc(..) ) +import GHC.Unicode ( GeneralCategory(..) ) +import GHC.Fingerprint.Type ( Fingerprint(..) ) -- Needed for metadata import Data.Proxy ( Proxy(..) ) @@ -1477,6 +1480,14 @@ deriving instance Generic ((,,,,,,) a b c d e f g) -- | @since 4.12.0.0 deriving instance Generic (Down a) +-- | @since 4.15.0.0 +deriving instance Generic SrcLoc + +-- | @since 4.15.0.0 +deriving instance Generic GeneralCategory + +-- | @since 4.15.0.0 +deriving instance Generic Fingerprint -- | @since 4.6.0.0 deriving instance Generic1 [] ===================================== libraries/base/GHC/RTS/Flags.hsc ===================================== @@ -1,3 +1,4 @@ +{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE RecordWildCards #-} @@ -47,6 +48,7 @@ import Foreign.C import GHC.Base import GHC.Enum +import GHC.Generics (Generic) import GHC.IO import GHC.Real import GHC.Show @@ -67,6 +69,7 @@ data GiveGCStats | SummaryGCStats | VerboseGCStats deriving ( Show -- ^ @since 4.8.0.0 + , Generic -- ^ @since 4.15.0.0 ) -- | @since 4.8.0.0 @@ -117,6 +120,7 @@ data GCFlags = GCFlags , numa :: Bool , numaMask :: Word } deriving ( Show -- ^ @since 4.8.0.0 + , Generic -- ^ @since 4.15.0.0 ) -- | Parameters concerning context switching @@ -126,6 +130,7 @@ data ConcFlags = ConcFlags { ctxtSwitchTime :: RtsTime , ctxtSwitchTicks :: Int } deriving ( Show -- ^ @since 4.8.0.0 + , Generic -- ^ @since 4.15.0.0 ) -- | Miscellaneous parameters @@ -144,6 +149,7 @@ data MiscFlags = MiscFlags , linkerMemBase :: Word -- ^ address to ask the OS for memory for the linker, 0 ==> off } deriving ( Show -- ^ @since 4.8.0.0 + , Generic -- ^ @since 4.15.0.0 ) -- | Flags to control debugging output & extra checking in various @@ -168,6 +174,7 @@ data DebugFlags = DebugFlags , hpc :: Bool -- ^ @c@ coverage , sparks :: Bool -- ^ @r@ } deriving ( Show -- ^ @since 4.8.0.0 + , Generic -- ^ @since 4.15.0.0 ) -- | Should the RTS produce a cost-center summary? @@ -180,6 +187,7 @@ data DoCostCentres | CostCentresAll | CostCentresJSON deriving ( Show -- ^ @since 4.8.0.0 + , Generic -- ^ @since 4.15.0.0 ) -- | @since 4.8.0.0 @@ -205,6 +213,7 @@ data CCFlags = CCFlags , profilerTicks :: Int , msecsPerTick :: Int } deriving ( Show -- ^ @since 4.8.0.0 + , Generic -- ^ @since 4.15.0.0 ) -- | What sort of heap profile are we collecting? @@ -220,6 +229,7 @@ data DoHeapProfile | HeapByLDV | HeapByClosureType deriving ( Show -- ^ @since 4.8.0.0 + , Generic -- ^ @since 4.15.0.0 ) -- | @since 4.8.0.0 @@ -262,6 +272,7 @@ data ProfFlags = ProfFlags , retainerSelector :: Maybe String , bioSelector :: Maybe String } deriving ( Show -- ^ @since 4.8.0.0 + , Generic -- ^ @since 4.15.0.0 ) -- | Is event tracing enabled? @@ -272,6 +283,7 @@ data DoTrace | TraceEventLog -- ^ send tracing events to the event log | TraceStderr -- ^ send tracing events to @stderr@ deriving ( Show -- ^ @since 4.8.0.0 + , Generic -- ^ @since 4.15.0.0 ) -- | @since 4.8.0.0 @@ -299,6 +311,7 @@ data TraceFlags = TraceFlags , sparksFull :: Bool -- ^ trace spark events 100% accurately , user :: Bool -- ^ trace user events (emitted from Haskell code) } deriving ( Show -- ^ @since 4.8.0.0 + , Generic -- ^ @since 4.15.0.0 ) -- | Parameters pertaining to ticky-ticky profiler @@ -308,6 +321,7 @@ data TickyFlags = TickyFlags { showTickyStats :: Bool , tickyFile :: Maybe FilePath } deriving ( Show -- ^ @since 4.8.0.0 + , Generic -- ^ @since 4.15.0.0 ) -- | Parameters pertaining to parallelism @@ -326,6 +340,7 @@ data ParFlags = ParFlags , setAffinity :: Bool } deriving ( Show -- ^ @since 4.8.0.0 + , Generic -- ^ @since 4.15.0.0 ) -- | Parameters of the runtime system @@ -342,6 +357,7 @@ data RTSFlags = RTSFlags , tickyFlags :: TickyFlags , parFlags :: ParFlags } deriving ( Show -- ^ @since 4.8.0.0 + , Generic -- ^ @since 4.15.0.0 ) foreign import ccall "&RtsFlags" rtsFlagsPtr :: Ptr RTSFlags ===================================== libraries/base/GHC/Stats.hsc ===================================== @@ -1,3 +1,4 @@ +{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE Trustworthy #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE RecordWildCards #-} @@ -24,6 +25,7 @@ import Control.Monad import Data.Int import Data.Word import GHC.Base +import GHC.Generics (Generic) import GHC.Read ( Read ) import GHC.Show ( Show ) import GHC.IO.Exception @@ -126,6 +128,7 @@ data RTSStats = RTSStats { , gc :: GCDetails } deriving ( Read -- ^ @since 4.10.0.0 , Show -- ^ @since 4.10.0.0 + , Generic -- ^ @since 4.15.0.0 ) -- @@ -174,6 +177,7 @@ data GCDetails = GCDetails { , gcdetails_nonmoving_gc_sync_elapsed_ns :: RtsTime } deriving ( Read -- ^ @since 4.10.0.0 , Show -- ^ @since 4.10.0.0 + , Generic -- ^ @since 4.15.0.0 ) -- | Time values from the RTS, using a fixed resolution of nanoseconds. ===================================== libraries/base/changelog.md ===================================== @@ -19,6 +19,10 @@ * Add `singleton` function for `Data.List.NonEmpty`. + * Add `Generic` instances to `Fingerprint`, `GiveGCStats`, `GCFlags`, + `ConcFlags`, `DebugFlags`, `CCFlags`, `DoHeapProfile`, `ProfFlags`, + `DoTrace`, `TraceFlags`, `TickyFlags`, `ParFlags`, `RTSFlags`, `RTSStats`, + `GCStats`, `ByteOrder`, `GeneralCategory`, `SrcLoc` ## 4.14.0.0 *TBA* * Bundled with GHC 8.10.1 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/55f0e783d234af103cf4e1d51cd31c99961c5abe -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/55f0e783d234af103cf4e1d51cd31c99961c5abe You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 21 16:11:43 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 21 May 2020 12:11:43 -0400 Subject: [Git][ghc/ghc][master] Explicit Specificity Message-ID: <5ec6a83f856e0_6e263f9ee3803844552566@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: a9311cd5 by Gert-Jan Bottu at 2020-05-21T12:11:31-04:00 Explicit Specificity Implementation for Ticket #16393. Explicit specificity allows users to manually create inferred type variables, by marking them with braces. This way, the user determines which variables can be instantiated through visible type application. The additional syntax is included in the parser, allowing users to write braces in type variable binders (type signatures, data constructors etc). This information is passed along through the renamer and verified in the type checker. The AST for type variable binders, data constructors, pattern synonyms, partial signatures and Template Haskell has been updated to include the specificity of type variables. Minor notes: - Bumps haddock submodule - Disables pattern match checking in GHC.Iface.Type with GHC 8.8 - - - - - 30 changed files: - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs - compiler/GHC/Core/DataCon.hs-boot - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/PatSyn.hs - compiler/GHC/Core/TyCo/Ppr.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/CoreToIface.hs-boot - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Types.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Foreign/Call.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Make.hs - compiler/GHC/Iface/Rename.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Iface/Type.hs-boot - compiler/GHC/IfaceToCore.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Bind.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a9311cd53d33439e8fe79967ba5fb85bcd114fec -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a9311cd53d33439e8fe79967ba5fb85bcd114fec You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 21 16:12:27 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 21 May 2020 12:12:27 -0400 Subject: [Git][ghc/ghc][master] Lint should say when it is checking a rule Message-ID: <5ec6a86b38bb1_6e2612540ff8555683@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 24e61aad by Ben Price at 2020-05-21T12:12:17-04:00 Lint should say when it is checking a rule It is rather confusing that when lint finds an error in a rule attached to a binder, it reports the error as in the RHS, not the rule: ... In the RHS of foo We add a clarifying line: ... In the RHS of foo In a rule attached to foo The implication that the rule lives inside the RHS is a bit odd, but this niggle is already present for unfoldings, whose pattern we are following. - - - - - 1 changed file: - compiler/GHC/Core/Lint.hs Changes: ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -659,7 +659,7 @@ lintLetBind top_lvl rec_flag binder rhs rhs_ty ppr binder) _ -> return () - ; mapM_ (lintCoreRule binder binder_ty) (idCoreRules binder) + ; addLoc (RuleOf binder) $ mapM_ (lintCoreRule binder binder_ty) (idCoreRules binder) ; addLoc (UnfoldingOf binder) $ lintIdUnfolding binder binder_ty (idUnfolding binder) } @@ -2293,6 +2293,7 @@ data LintLocInfo = RhsOf Id -- The variable bound | OccOf Id -- Occurrence of id | LambdaBodyOf Id -- The lambda-binder + | RuleOf Id -- Rules attached to a binder | UnfoldingOf Id -- Unfolding of a binder | BodyOfLetRec [Id] -- One of the binders | CaseAlt CoreAlt -- Case alternative @@ -2511,6 +2512,9 @@ dumpLoc (OccOf v) dumpLoc (LambdaBodyOf b) = (getSrcLoc b, text "In the body of lambda with binder" <+> pp_binder b) +dumpLoc (RuleOf b) + = (getSrcLoc b, text "In a rule attached to" <+> pp_binder b) + dumpLoc (UnfoldingOf b) = (getSrcLoc b, text "In the unfolding of" <+> pp_binder b) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/24e61aad37355fa3a5503b11a60ab7b314a3f405 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/24e61aad37355fa3a5503b11a60ab7b314a3f405 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 21 16:13:11 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 21 May 2020 12:13:11 -0400 Subject: [Git][ghc/ghc][master] nonmoving: Optimise the write barrier Message-ID: <5ec6a897c5ba8_6e263f9f0bd8e174557923@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 78c6523c by Ben Gamari at 2020-05-21T12:13:01-04:00 nonmoving: Optimise the write barrier - - - - - 1 changed file: - rts/Updates.h Changes: ===================================== rts/Updates.h ===================================== @@ -50,22 +50,21 @@ \ prim_write_barrier; \ OVERWRITING_CLOSURE(p1); \ - IF_NONMOVING_WRITE_BARRIER_ENABLED { \ - ccall updateRemembSetPushThunk_(BaseReg, p1 "ptr"); \ - } \ - StgInd_indirectee(p1) = p2; \ - prim_write_barrier; \ - SET_INFO(p1, stg_BLACKHOLE_info); \ - LDV_RECORD_CREATE(p1); \ bd = Bdescr(p1); \ if (bdescr_gen_no(bd) != 0 :: bits16) { \ + IF_NONMOVING_WRITE_BARRIER_ENABLED { \ + ccall updateRemembSetPushThunk_(BaseReg, p1 "ptr"); \ + } \ recordMutableCap(p1, TO_W_(bdescr_gen_no(bd))); \ TICK_UPD_OLD_IND(); \ - and_then; \ } else { \ TICK_UPD_NEW_IND(); \ - and_then; \ - } + } \ + StgInd_indirectee(p1) = p2; \ + prim_write_barrier; \ + SET_INFO(p1, stg_BLACKHOLE_info); \ + LDV_RECORD_CREATE(p1); \ + and_then; #else /* !CMINUSMINUS */ @@ -73,28 +72,26 @@ INLINE_HEADER void updateWithIndirection (Capability *cap, StgClosure *p1, StgClosure *p2) { - bdescr *bd; - ASSERT( (P_)p1 != (P_)p2 ); /* not necessarily true: ASSERT( !closure_IND(p1) ); */ /* occurs in RaiseAsync.c:raiseAsync() */ /* See Note [Heap memory barriers] in SMP.h */ write_barrier(); - OVERWRITING_CLOSURE(p1); - IF_NONMOVING_WRITE_BARRIER_ENABLED { - updateRemembSetPushThunk(cap, (StgThunk*)p1); - } - ((StgInd *)p1)->indirectee = p2; - write_barrier(); - SET_INFO(p1, &stg_BLACKHOLE_info); - LDV_RECORD_CREATE(p1); - bd = Bdescr((StgPtr)p1); + bdescr *bd = Bdescr((StgPtr)p1); if (bd->gen_no != 0) { + IF_NONMOVING_WRITE_BARRIER_ENABLED { + updateRemembSetPushThunk(cap, (StgThunk*)p1); + } recordMutableCap(p1, cap, bd->gen_no); TICK_UPD_OLD_IND(); } else { TICK_UPD_NEW_IND(); } + OVERWRITING_CLOSURE(p1); + ((StgInd *)p1)->indirectee = p2; + write_barrier(); + SET_INFO(p1, &stg_BLACKHOLE_info); + LDV_RECORD_CREATE(p1); } #endif /* CMINUSMINUS */ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/78c6523c5106fc56b653fc14fda5741913da8fdc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/78c6523c5106fc56b653fc14fda5741913da8fdc You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 21 16:13:58 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 21 May 2020 12:13:58 -0400 Subject: [Git][ghc/ghc][master] Refactor linear reg alloc to remember past assignments. Message-ID: <5ec6a8c651d24_6e263f9eea2381ec56289f@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 13f6c9d0 by Andreas Klebinger at 2020-05-21T12:13:45-04:00 Refactor linear reg alloc to remember past assignments. When assigning registers we now first try registers we assigned to in the past, instead of picking the "first" one. This is in extremely helpful when dealing with loops for which variables are dead for part of the loop. This is important for patterns like this: foo = arg1 loop: use(foo) ... foo = getVal() goto loop; There we: * assign foo to the register of arg1. * use foo, it's dead after this use as it's overwritten after. * do other things. * look for a register to put foo in. If we pick an arbitrary one it might differ from the register the start of the loop expect's foo to be in. To fix this we simply look for past register assignments for the given variable. If we find one and the register is free we use that register. This reduces the need for fixup blocks which match the register assignment between blocks. In the example above between the end and the head of the loop. This patch also moves branch weight estimation ahead of register allocation and adds a flag to control it (cmm-static-pred). * It means the linear allocator is more likely to assign the hotter code paths first. * If it assign these first we are: + Less likely to spill on the hot path. + Less likely to introduce fixup blocks on the hot path. These two measure combined are surprisingly effective. Based on nofib we get in the mean: * -0.9% instructions executed * -0.1% reads/writes * -0.2% code size. * -0.1% compiler allocations. * -0.9% compile time. * -0.8% runtime. Most of the benefits are simply a result of removing redundant moves and spills. Reduced compiler allocations likely are the result of less code being generated. (The added lookup is mostly non-allocating). - - - - - 16 changed files: - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Reg/Linear.hs - compiler/GHC/CmmToAsm/Reg/Linear/Base.hs - compiler/GHC/CmmToAsm/Reg/Linear/PPC.hs - compiler/GHC/CmmToAsm/Reg/Linear/SPARC.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/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Utils/Outputable.hs - docs/users_guide/8.12.1-notes.rst - docs/users_guide/using-optimisation.rst Changes: ===================================== compiler/GHC/CmmToAsm.hs ===================================== @@ -728,7 +728,7 @@ cmmNativeGen dflags this_mod modLoc ncgImpl us fileIds dbgMap cmm count let optimizedCFG :: Maybe CFG optimizedCFG = - optimizeCFG (cfgWeightInfo dflags) cmm <$!> postShortCFG + optimizeCFG (gopt Opt_CmmStaticPred dflags) (cfgWeightInfo dflags) cmm <$!> postShortCFG maybeDumpCfg dflags optimizedCFG "CFG Weights - Final" proc_name ===================================== compiler/GHC/CmmToAsm/BlockLayout.hs ===================================== @@ -636,22 +636,8 @@ sequenceChain :: forall a i. (Instruction i, Outputable i) -> [GenBasicBlock i] -- ^ Blocks placed in sequence. sequenceChain _info _weights [] = [] sequenceChain _info _weights [x] = [x] -sequenceChain info weights' blocks@((BasicBlock entry _):_) = - let weights :: CFG - weights = --pprTrace "cfg'" (pprEdgeWeights cfg') - cfg' - where - (_, globalEdgeWeights) = {-# SCC mkGlobalWeights #-} mkGlobalWeights entry weights' - cfg' = {-# SCC rewriteEdges #-} - mapFoldlWithKey - (\cfg from m -> - mapFoldlWithKey - (\cfg to w -> setEdgeWeight cfg (EdgeWeight w) from to ) - cfg m ) - weights' - globalEdgeWeights - - directEdges :: [CfgEdge] +sequenceChain info weights blocks@((BasicBlock entry _):_) = + let directEdges :: [CfgEdge] directEdges = sortBy (flip compare) $ catMaybes . map relevantWeight $ (infoEdgeList weights) where relevantWeight :: CfgEdge -> Maybe CfgEdge ===================================== compiler/GHC/CmmToAsm/CFG.hs ===================================== @@ -670,11 +670,21 @@ findBackEdges root cfg = typedEdges = classifyEdges root getSuccs edges :: [((BlockId,BlockId),EdgeType)] - -optimizeCFG :: D.CfgWeights -> RawCmmDecl -> CFG -> CFG -optimizeCFG _ (CmmData {}) cfg = cfg -optimizeCFG weights (CmmProc info _lab _live graph) cfg = - {-# SCC optimizeCFG #-} +optimizeCFG :: Bool -> D.CfgWeights -> RawCmmDecl -> CFG -> CFG +optimizeCFG _ _ (CmmData {}) cfg = cfg +optimizeCFG doStaticPred weights proc@(CmmProc _info _lab _live graph) cfg = + (if doStaticPred then staticPredCfg (g_entry graph) else id) $ + optHsPatterns weights proc $ cfg + +-- | Modify branch weights based on educated guess on +-- patterns GHC tends to produce and how they affect +-- performance. +-- +-- Most importantly we penalize jumps across info tables. +optHsPatterns :: D.CfgWeights -> RawCmmDecl -> CFG -> CFG +optHsPatterns _ (CmmData {}) cfg = cfg +optHsPatterns weights (CmmProc info _lab _live graph) cfg = + {-# SCC optHsPatterns #-} -- pprTrace "Initial:" (pprEdgeWeights cfg) $ -- pprTrace "Initial:" (ppr $ mkGlobalWeights (g_entry graph) cfg) $ @@ -749,6 +759,21 @@ optimizeCFG weights (CmmProc info _lab _live graph) cfg = | CmmSource { trans_cmmNode = CmmCondBranch {} } <- source = True | otherwise = False +-- | Convert block-local branch weights to global weights. +staticPredCfg :: BlockId -> CFG -> CFG +staticPredCfg entry cfg = cfg' + where + (_, globalEdgeWeights) = {-# SCC mkGlobalWeights #-} + mkGlobalWeights entry cfg + cfg' = {-# SCC rewriteEdges #-} + mapFoldlWithKey + (\cfg from m -> + mapFoldlWithKey + (\cfg to w -> setEdgeWeight cfg (EdgeWeight w) from to ) + cfg m ) + cfg + globalEdgeWeights + -- | Determine loop membership of blocks based on SCC analysis -- This is faster but only gives yes/no answers. loopMembers :: HasDebugCallStack => CFG -> LabelMap Bool @@ -922,6 +947,10 @@ revPostorderFrom cfg root = -- reverse post order. Which is required for diamond control flow to work probably. -- -- We also apply a few prediction heuristics (based on the same paper) +-- +-- The returned result represents frequences. +-- For blocks it's the expected number of executions and +-- for edges is the number of traversals. {-# NOINLINE mkGlobalWeights #-} {-# SCC mkGlobalWeights #-} ===================================== compiler/GHC/CmmToAsm/Instr.hs ===================================== @@ -37,7 +37,10 @@ import GHC.CmmToAsm.Config -- (for allocation purposes, anyway). -- data RegUsage - = RU [Reg] [Reg] + = RU { + reads :: [Reg], + writes :: [Reg] + } -- | No regs read or written to. noUsage :: RegUsage ===================================== compiler/GHC/CmmToAsm/Reg/Linear.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE BangPatterns, CPP, ScopedTypeVariables #-} +{-# LANGUAGE ConstraintKinds #-} {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} @@ -137,6 +138,7 @@ import GHC.Platform import Data.Maybe import Data.List import Control.Monad +import Control.Applicative -- ----------------------------------------------------------------------------- -- Top level of the register allocator @@ -229,8 +231,13 @@ linearRegAlloc config entry_ids block_live sccs go f = linearRegAlloc' config f entry_ids block_live sccs platform = ncgPlatform config +-- | Constraints on the instruction instances used by the +-- linear allocator. +type OutputableRegConstraint freeRegs instr = + (FR freeRegs, Outputable freeRegs, Outputable instr, Instruction instr) + linearRegAlloc' - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => NCGConfig -> freeRegs -> [BlockId] -- ^ entry points @@ -246,7 +253,7 @@ linearRegAlloc' config initFreeRegs entry_ids block_live sccs return (blocks, stats, getStackUse stack) -linearRA_SCCs :: (FR freeRegs, Instruction instr, Outputable instr) +linearRA_SCCs :: OutputableRegConstraint freeRegs instr => [BlockId] -> BlockMap RegSet -> [NatBasicBlock instr] @@ -281,7 +288,7 @@ linearRA_SCCs entry_ids block_live blocksAcc (CyclicSCC blocks : sccs) more sanity checking to guard against this eventuality. -} -process :: (FR freeRegs, Instruction instr, Outputable instr) +process :: OutputableRegConstraint freeRegs instr => [BlockId] -> BlockMap RegSet -> [GenBasicBlock (LiveInstr instr)] @@ -325,15 +332,18 @@ process entry_ids block_live (b@(BasicBlock id _) : blocks) -- | Do register allocation on this basic block -- processBlock - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ live regs on entry to each basic block -> LiveBasicBlock instr -- ^ block to do register allocation on -> RegM freeRegs [NatBasicBlock instr] -- ^ block with registers allocated processBlock block_live (BasicBlock id instrs) - = do initBlock id block_live + = do -- pprTraceM "processBlock" $ text "" $$ ppr (BasicBlock id instrs) + initBlock id block_live + (instrs', fixups) <- linearRA block_live [] [] id instrs + -- pprTraceM "blockResult" $ ppr (instrs', fixups) return $ BasicBlock id instrs' : fixups @@ -369,7 +379,7 @@ initBlock id block_live -- | Do allocation for a sequence of instructions. linearRA - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ map of what vregs are live on entry to each block. -> [instr] -- ^ accumulator for instructions already processed. -> [NatBasicBlock instr] -- ^ accumulator for blocks of fixup code. @@ -396,7 +406,7 @@ linearRA block_live accInstr accFixups id (instr:instrs) -- | Do allocation for a single instruction. raInsn - :: (FR freeRegs, Outputable instr, Instruction instr) + :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -- ^ 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 @@ -476,7 +486,7 @@ isInReg src assig | Just (InReg _) <- lookupUFM assig src = True | otherwise = False -genRaInsn :: (FR freeRegs, Instruction instr, Outputable instr) +genRaInsn :: OutputableRegConstraint freeRegs instr => BlockMap RegSet -> [instr] -> BlockId @@ -486,6 +496,7 @@ genRaInsn :: (FR freeRegs, Instruction instr, Outputable instr) -> RegM freeRegs ([instr], [NatBasicBlock instr]) genRaInsn block_live new_instrs block_id instr r_dying w_dying = do +-- pprTraceM "genRaInsn" $ ppr (block_id, instr) platform <- getPlatform case regUsageOfInstr platform instr of { RU read written -> do @@ -525,6 +536,8 @@ genRaInsn block_live new_instrs block_id instr r_dying w_dying = do (fixup_blocks, adjusted_instr) <- joinToTargets block_live block_id instr +-- when (not $ null fixup_blocks) $ pprTraceM "genRA:FixBlocks" $ ppr fixup_blocks + -- Debugging - show places where the reg alloc inserted -- assignment fixup blocks. -- when (not $ null fixup_blocks) $ @@ -737,7 +750,7 @@ data SpillLoc = ReadMem StackSlot -- reading from register only in memory -- the list of free registers and free stack slots. allocateRegsAndSpill - :: (FR freeRegs, Outputable instr, Instruction instr) + :: forall freeRegs instr. (FR freeRegs, Outputable instr, Instruction instr) => Bool -- True <=> reading (load up spilled regs) -> [VirtualReg] -- don't push these out -> [instr] -- spill insns @@ -749,7 +762,8 @@ allocateRegsAndSpill _ _ spills alloc [] = return (spills, reverse alloc) allocateRegsAndSpill reading keep spills alloc (r:rs) - = do assig <- getAssigR + = do assig <- getAssigR :: RegM freeRegs (RegMap Loc) + -- pprTraceM "allocateRegsAndSpill:assig" (ppr (r:rs) $$ ppr assig) let doSpill = allocRegsAndSpill_spill reading keep spills alloc r rs assig case lookupUFM assig r of -- case (1a): already in a register @@ -779,6 +793,26 @@ allocateRegsAndSpill reading keep spills alloc (r:rs) | otherwise -> doSpill WriteNew +-- | Given a virtual reg find a preferred real register. +-- The preferred register is simply the first one the variable +-- was assigned to (if any). This way when we allocate for a loop +-- variables are likely to end up in the same registers at the +-- end and start of the loop, avoiding redundant reg-reg moves. +-- Note: I tried returning a list of past assignments, but that +-- turned out to barely matter but added a few tenths of +-- a percent to compile time. +findPrefRealReg :: forall freeRegs u. Uniquable u + => u -> RegM freeRegs (Maybe RealReg) +findPrefRealReg vreg = do + bassig <- getBlockAssigR :: RegM freeRegs (BlockMap (freeRegs,RegMap Loc)) + return $ foldr (findVirtRegAssig) Nothing bassig + where + findVirtRegAssig :: (freeRegs,RegMap Loc) -> Maybe RealReg -> Maybe RealReg + findVirtRegAssig assig z = + z <|> case lookupUFM (snd assig) vreg of + Just (InReg real_reg) -> Just real_reg + Just (InBoth real_reg _) -> Just real_reg + _ -> z -- reading is redundant with reason, but we keep it around because it's -- convenient and it maintains the recursive structure of the allocator. -- EZY @@ -795,18 +829,26 @@ allocRegsAndSpill_spill :: (FR freeRegs, Instruction instr, Outputable instr) allocRegsAndSpill_spill reading keep spills alloc r rs assig spill_loc = do platform <- getPlatform freeRegs <- getFreeRegsR - let freeRegs_thisClass = frGetFreeRegs platform (classOfVirtualReg r) freeRegs + let freeRegs_thisClass = frGetFreeRegs platform (classOfVirtualReg r) freeRegs :: [RealReg] - case freeRegs_thisClass of + -- Can we put the variable into a register it already was? + pref_reg <- findPrefRealReg r + case freeRegs_thisClass of -- case (2): we have a free register - (my_reg : _) -> - do spills' <- loadTemp r spill_loc my_reg spills + (first_free : _) -> + do let final_reg + | Just reg <- pref_reg + , reg `elem` freeRegs_thisClass + = reg + | otherwise + = first_free + spills' <- loadTemp r spill_loc final_reg spills - setAssigR (addToUFM assig r $! newLocation spill_loc my_reg) - setFreeRegsR $ frAllocateReg platform my_reg freeRegs + setAssigR (addToUFM assig r $! newLocation spill_loc final_reg) + setFreeRegsR $ frAllocateReg platform final_reg freeRegs - allocateRegsAndSpill reading keep spills' (my_reg : alloc) rs + allocateRegsAndSpill reading keep spills' (final_reg : alloc) rs -- case (3): we need to push something out to free up a register @@ -814,7 +856,8 @@ allocRegsAndSpill_spill reading keep spills alloc r rs assig spill_loc do let inRegOrBoth (InReg _) = True inRegOrBoth (InBoth _ _) = True inRegOrBoth _ = False - let candidates' = + let candidates' :: UniqFM Loc + candidates' = flip delListFromUFM keep $ filterUFM inRegOrBoth $ assig ===================================== compiler/GHC/CmmToAsm/Reg/Linear/Base.hs ===================================== @@ -30,6 +30,7 @@ import GHC.Types.Unique.FM import GHC.Types.Unique.Supply import GHC.Cmm.BlockId +data ReadingOrWriting = Reading | Writing deriving (Eq,Ord) -- | Used to store the register assignment on entry to a basic block. -- We use this to handle join points, where multiple branch instructions @@ -138,6 +139,8 @@ data RA_State freeRegs , ra_config :: !NCGConfig -- | (from,fixup,to) : We inserted fixup code between from and to - , ra_fixups :: [(BlockId,BlockId,BlockId)] } + , ra_fixups :: [(BlockId,BlockId,BlockId)] + + } ===================================== compiler/GHC/CmmToAsm/Reg/Linear/PPC.hs ===================================== @@ -1,3 +1,5 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} + -- | Free regs map for PowerPC module GHC.CmmToAsm.Reg.Linear.PPC where @@ -27,6 +29,9 @@ import Data.Bits data FreeRegs = FreeRegs !Word32 !Word32 deriving( Show ) -- The Show is used in an ASSERT +instance Outputable FreeRegs where + ppr = text . show + noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/SPARC.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for SPARC module GHC.CmmToAsm.Reg.Linear.SPARC where @@ -38,6 +39,9 @@ data FreeRegs instance Show FreeRegs where show = showFreeRegs +instance Outputable FreeRegs where + ppr = text . showFreeRegs + -- | A reg map where no regs are free to be allocated. noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 0 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/State.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE CPP, PatternSynonyms, DeriveFunctor #-} +{-# LANGUAGE ScopedTypeVariables #-} #if !defined(GHC_LOADED_INTO_GHCI) {-# LANGUAGE UnboxedTuples #-} ===================================== compiler/GHC/CmmToAsm/Reg/Linear/X86.hs ===================================== @@ -1,3 +1,4 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for i386 module GHC.CmmToAsm.Reg.Linear.X86 where @@ -9,12 +10,13 @@ import GHC.Platform.Reg.Class import GHC.Platform.Reg import GHC.Utils.Panic import GHC.Platform +import GHC.Utils.Outputable import Data.Word import Data.Bits newtype FreeRegs = FreeRegs Word32 - deriving Show + deriving (Show,Outputable) noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 ===================================== compiler/GHC/CmmToAsm/Reg/Linear/X86_64.hs ===================================== @@ -1,3 +1,4 @@ +{-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Free regs map for x86_64 module GHC.CmmToAsm.Reg.Linear.X86_64 where @@ -9,12 +10,13 @@ import GHC.Platform.Reg.Class import GHC.Platform.Reg import GHC.Utils.Panic import GHC.Platform +import GHC.Utils.Outputable import Data.Word import Data.Bits newtype FreeRegs = FreeRegs Word64 - deriving Show + deriving (Show,Outputable) noFreeRegs :: FreeRegs noFreeRegs = FreeRegs 0 ===================================== compiler/GHC/Driver/Flags.hs ===================================== @@ -181,6 +181,7 @@ data GeneralFlag | Opt_LlvmFillUndefWithGarbage -- Testing for undef bugs (hidden flag) | Opt_IrrefutableTuples | Opt_CmmSink + | Opt_CmmStaticPred | Opt_CmmElimCommonBlocks | Opt_AsmShortcutting | Opt_OmitYields ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -3514,6 +3514,7 @@ fFlagsDeps = [ flagSpec "case-folding" Opt_CaseFolding, flagSpec "cmm-elim-common-blocks" Opt_CmmElimCommonBlocks, flagSpec "cmm-sink" Opt_CmmSink, + flagSpec "cmm-static-pred" Opt_CmmStaticPred, flagSpec "cse" Opt_CSE, flagSpec "stg-cse" Opt_StgCSE, flagSpec "stg-lift-lams" Opt_StgLiftLams, @@ -4065,6 +4066,7 @@ optLevelFlags -- see Note [Documenting optimisation flags] , ([1,2], Opt_CmmElimCommonBlocks) , ([2], Opt_AsmShortcutting) , ([1,2], Opt_CmmSink) + , ([1,2], Opt_CmmStaticPred) , ([1,2], Opt_CSE) , ([1,2], Opt_StgCSE) , ([2], Opt_StgLiftLams) ===================================== compiler/GHC/Utils/Outputable.hs ===================================== @@ -837,6 +837,9 @@ instance Outputable Word16 where instance Outputable Word32 where ppr n = integer $ fromIntegral n +instance Outputable Word64 where + ppr n = integer $ fromIntegral n + instance Outputable Word where ppr n = integer $ fromIntegral n ===================================== docs/users_guide/8.12.1-notes.rst ===================================== @@ -10,7 +10,14 @@ following sections. Highlights ---------- -- TODO +* NCG + + - The linear register allocator saw improvements reducing the number + of redundant move instructions. Rare edge cases can see double + digit improvements in runtime for inner loops. + + In the mean this improved runtime by about 0.8%. For details + see ticket #17823. Full details ------------ @@ -155,11 +162,11 @@ Arrow notation ``hsGroupTopLevelFixitySigs`` function, which collects all top-level fixity signatures, including those for class methods defined inside classes. -- The ``Exception`` module was boiled down acknowledging the existence of +- The ``Exception`` module was boiled down acknowledging the existence of the ``exceptions`` dependency. In particular, the ``ExceptionMonad`` class is not a proper class anymore, but a mere synonym for ``MonadThrow``, - ``MonadCatch``, ``MonadMask`` (all from ``exceptions``) and ``MonadIO``. - All of ``g*``-functions from the module (``gtry``, ``gcatch``, etc.) are + ``MonadCatch``, ``MonadMask`` (all from ``exceptions``) and ``MonadIO``. + All of ``g*``-functions from the module (``gtry``, ``gcatch``, etc.) are erased, and their ``exceptions``-alternatives are meant to be used in the GHC code instead. ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -214,6 +214,19 @@ by saying ``-fno-wombat``. to their usage sites. It also inlines simple expressions like literals or registers. +.. ghc-flag:: -fcmm-static-pred + :shortdesc: Enable static control flow prediction. Implied by :ghc-flag:`-O`. + :type: dynamic + :reverse: -fno-cmm-static-pred + :category: + + :default: off but enabled with :ghc-flag:`-O`. + + This enables static control flow prediction on the final Cmm + code. If enabled GHC will apply certain heuristics to identify + loops and hot code paths. This information is then used by the + register allocation and code layout passes. + .. ghc-flag:: -fasm-shortcutting :shortdesc: Enable shortcutting on assembly. Implied by :ghc-flag:`-O2`. :type: dynamic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/13f6c9d0376214b22d4cd16bd3a8cd7b8d864990 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/13f6c9d0376214b22d4cd16bd3a8cd7b8d864990 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 21 16:14:37 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 21 May 2020 12:14:37 -0400 Subject: [Git][ghc/ghc][master] NCG: Codelayout: Distinguish conditional and other branches. Message-ID: <5ec6a8ed47b7a_6e263f9ed4defb54564778@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: edc2cc58 by Andreas Klebinger at 2020-05-21T12:14:25-04:00 NCG: Codelayout: Distinguish conditional and other branches. In #18053 we ended up with a suboptimal code layout because the code layout algorithm didn't distinguish between conditional and unconditional control flow. We can completely eliminate unconditional control flow instructions by placing blocks next to each other, not so much for conditionals. In terms of implementation we simply give conditional branches less weight before computing the layout. Fixes #18053 - - - - - 1 changed file: - compiler/GHC/CmmToAsm/BlockLayout.hs Changes: ===================================== compiler/GHC/CmmToAsm/BlockLayout.hs ===================================== @@ -240,7 +240,44 @@ import Control.Monad (foldM) Assuming that Lwork is large the chance that the "call" ends up in the same cache line is also fairly small. --} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~~~ Note [Layout relevant edge weights] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The input to the chain based code layout algorithm is a CFG + with edges annotated with their frequency. The frequency + of traversal corresponds quite well to the cost of not placing + the connected blocks next to each other. + + However even if having the same frequency certain edges are + inherently more or less relevant to code layout. + + In particular: + + * Edges which cross an info table are less relevant than others. + + If we place the blocks across this edge next to each other + they are still separated by the info table which negates + much of the benefit. It makes it less likely both blocks + will share a cache line reducing the benefits from locality. + But it also prevents us from eliminating jump instructions. + + * Conditional branches and switches are slightly less relevant. + + We can completely remove unconditional jumps by placing them + next to each other. This is not true for conditional branch edges. + We apply a small modifier to them to ensure edges for which we can + eliminate the overhead completely are considered first. See also #18053. + + * Edges constituted by a call are ignored. + + Considering these hardly helped with performance and ignoring + them helps quite a bit to improve compiler performance. + + So we perform a preprocessing step where we apply a multiplicator + to these kinds of edges. + + -} -- | Look at X number of blocks in two chains to determine @@ -640,17 +677,31 @@ sequenceChain info weights blocks@((BasicBlock entry _):_) = let directEdges :: [CfgEdge] directEdges = sortBy (flip compare) $ catMaybes . map relevantWeight $ (infoEdgeList weights) where + -- Apply modifiers to turn edge frequencies into useable weights + -- for computing code layout. + -- See also Note [Layout relevant edge weights] relevantWeight :: CfgEdge -> Maybe CfgEdge relevantWeight edge@(CfgEdge from to edgeInfo) | (EdgeInfo CmmSource { trans_cmmNode = CmmCall {} } _) <- edgeInfo - -- Ignore edges across calls + -- Ignore edges across calls. = Nothing | mapMember to info , w <- edgeWeight edgeInfo - -- The payoff is small if we jump over an info table + -- The payoff is quite small if we jump over an info table = Just (CfgEdge from to edgeInfo { edgeWeight = w/8 }) + | (EdgeInfo CmmSource { trans_cmmNode = exitNode } _) <- edgeInfo + , cantEliminate exitNode + , w <- edgeWeight edgeInfo + -- A small penalty to edge types which + -- we can't optimize away by layout. + -- w * 0.96875 == w - w/32 + = Just (CfgEdge from to edgeInfo { edgeWeight = w * 0.96875 }) | otherwise = Just edge + where + cantEliminate CmmCondBranch {} = True + cantEliminate CmmSwitch {} = True + cantEliminate _ = False blockMap :: LabelMap (GenBasicBlock i) blockMap View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/edc2cc588add3f23b3650f15d3f495943f2c06f9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/edc2cc588add3f23b3650f15d3f495943f2c06f9 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 21 16:15:40 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 21 May 2020 12:15:40 -0400 Subject: [Git][ghc/ghc][master] gitlab-ci: Set locale to C.UTF-8. Message-ID: <5ec6a92cdff81_6e2679b9a40570823@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: b7a6b2f4 by Gleb Popov at 2020-05-21T12:15:26-04:00 gitlab-ci: Set locale to C.UTF-8. - - - - - 3 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - docs/users_guide/compare-flags.py Changes: ===================================== .gitlab-ci.yml ===================================== @@ -2,7 +2,7 @@ variables: GIT_SSL_NO_VERIFY: "1" # Commit of ghc/ci-images repository from which to pull Docker images - DOCKER_REV: 3f731f5d37a156e7ebe10cd32656946083baaf4a + DOCKER_REV: 6223fe0b5942f4fa35bdec92c74566cf195bfb42 # Sequential version number capturing the versions of all tools fetched by # .gitlab/ci.sh. ===================================== .gitlab/ci.sh ===================================== @@ -26,6 +26,9 @@ LT_CYAN="1;36" WHITE="1;37" LT_GRAY="0;37" +export LANG=C.UTF-8 +export LC_ALL=C.UTF-8 + # GitLab Pipelines log section delimiters # https://gitlab.com/gitlab-org/gitlab-foss/issues/14664 start_section() { ===================================== docs/users_guide/compare-flags.py ===================================== @@ -62,7 +62,7 @@ def main() -> None: parser = argparse.ArgumentParser() parser.add_argument('--ghc', type=argparse.FileType('r'), help='path of GHC executable') - parser.add_argument('--doc-flags', type=argparse.FileType('r'), + parser.add_argument('--doc-flags', type=argparse.FileType(mode='r', encoding='UTF-8'), help='path of ghc-flags.txt output from Sphinx') args = parser.parse_args() View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b7a6b2f4c690a9711339462114a538a85dcb7d83 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b7a6b2f4c690a9711339462114a538a85dcb7d83 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 21 16:16:20 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 21 May 2020 12:16:20 -0400 Subject: [Git][ghc/ghc][master] 4 commits: Allow spaces in GHCi :script file names Message-ID: <5ec6a954b4113_6e263f9ed4defb545756ad@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: a8c27cf6 by Stefan Holdermans at 2020-05-21T12:16:08-04:00 Allow spaces in GHCi :script file names This patch updates the user interface of GHCi so that file names passed to the ':script' command may contain spaces escaped with a backslash. For example: :script foo\ bar.script The implementation uses a modified version of 'words' that does not break on escaped spaces. Fixes #18027. - - - - - 82663959 by Stefan Holdermans at 2020-05-21T12:16:08-04:00 Add extra tests for GHCi :script syntax checks The syntax for GHCi's ":script" command allows for only a single file name to be passed as an argument. This patch adds a test for the cases in which a file name is missing or multiple file names are passed. Related to #T18027. - - - - - a0b79e1b by Stefan Holdermans at 2020-05-21T12:16:08-04:00 Allow GHCi :script file names in double quotes This patch updates the user interface of GHCi so that file names passed to the ':script' command can be wrapped in double quotes. For example: :script "foo bar.script" The implementation uses a modified version of 'words' that treats character sequences enclosed in double quotes as single words. Fixes #18027. - - - - - cf566330 by Stefan Holdermans at 2020-05-21T12:16:08-04:00 Update documentation for GHCi :script This patch adds the fixes that allow for file names containing spaces to be passed to GHCi's ':script' command to the release notes for 8.12 and expands the user-guide documentation for ':script' by mentioning how such file names can be passed. Related to #18027. - - - - - 10 changed files: - docs/users_guide/8.12.1-notes.rst - docs/users_guide/ghci.rst - ghc/GHCi/UI.hs - + testsuite/tests/ghci/should_fail/T18027a.script - + testsuite/tests/ghci/should_fail/T18027a.stderr - testsuite/tests/ghci/should_fail/all.T - + testsuite/tests/ghci/should_run/T18027 SPACE IN FILE NAME.script - + testsuite/tests/ghci/should_run/T18027.script - + testsuite/tests/ghci/should_run/T18027.stdout - testsuite/tests/ghci/should_run/all.T Changes: ===================================== docs/users_guide/8.12.1-notes.rst ===================================== @@ -100,6 +100,9 @@ Compiler GHCi ~~~~ +- The ``:script`` command now allows for file names that contain spaces to + passed as arguments: either by enclosing the file names in double quotes or by + escaping spaces in file names with a backslash. (#18027) Runtime system ~~~~~~~~~~~~~~ ===================================== docs/users_guide/ghci.rst ===================================== @@ -2695,9 +2695,11 @@ commonly used commands. .. ghci-cmd:: :script; [⟨n⟩] ⟨filename⟩ - Executes the lines of a file as a series of GHCi commands. This - command is compatible with multiline statements as set by - :ghci-cmd:`:set +m` + Executes the lines of a file as a series of GHCi commands. The syntax for + file-name arguments respects shell quoting rules, i.e., file names + containing spaces can be enclosed in double quotes or with spaces escaped + with a backslash. This command is compatible with multiline statements as + set by :ghci-cmd:`:set +m` .. ghci-cmd:: :set; [⟨option⟩ ...] ===================================== ghc/GHCi/UI.hs ===================================== @@ -2263,10 +2263,26 @@ quit _ = return True scriptCmd :: String -> InputT GHCi () scriptCmd ws = do - case words ws of + case words' ws of [s] -> runScript s _ -> throwGhcException (CmdLineError "syntax: :script ") +-- | A version of 'words' that treats sequences enclosed in double quotes as +-- single words and that does not break on backslash-escaped spaces. +-- E.g., 'words\' "\"lorem ipsum\" dolor"' and 'words\' "lorem\\ ipsum dolor"' +-- yield '["lorem ipsum", "dolor"]'. +-- Used to scan for file paths in 'scriptCmd'. +words' :: String -> [String] +words' s = case dropWhile isSpace s of + "" -> [] + s'@('\"' : _) | [(w, s'')] <- reads s' -> w : words' s'' + s' -> go id s' + where + go acc [] = [acc []] + go acc ('\\' : c : cs) | isSpace c = go (acc . (c :)) cs + go acc (c : cs) | isSpace c = acc [] : words' cs + | otherwise = go (acc . (c :)) cs + runScript :: String -- ^ filename -> InputT GHCi () runScript filename = do ===================================== testsuite/tests/ghci/should_fail/T18027a.script ===================================== @@ -0,0 +1,2 @@ +:script +:script one two ===================================== testsuite/tests/ghci/should_fail/T18027a.stderr ===================================== @@ -0,0 +1,2 @@ +syntax: :script +syntax: :script ===================================== testsuite/tests/ghci/should_fail/all.T ===================================== @@ -4,3 +4,4 @@ test('T15055', normalise_version('ghc'), ghci_script, ['T15055.script']) test('T16013', [], ghci_script, ['T16013.script']) test('T16287', [], ghci_script, ['T16287.script']) test('T18052b', [], ghci_script, ['T18052b.script']) +test('T18027a', [], ghci_script, ['T18027a.script']) ===================================== testsuite/tests/ghci/should_run/T18027 SPACE IN FILE NAME.script ===================================== @@ -0,0 +1 @@ +42 ===================================== testsuite/tests/ghci/should_run/T18027.script ===================================== @@ -0,0 +1,2 @@ +:script T18027\ SPACE\ IN\ FILE\ NAME.script +:script "T18027 SPACE IN FILE NAME.script" ===================================== testsuite/tests/ghci/should_run/T18027.stdout ===================================== @@ -0,0 +1,2 @@ +42 +42 ===================================== testsuite/tests/ghci/should_run/all.T ===================================== @@ -64,3 +64,4 @@ test('T15633b', test('T16096', just_ghci, ghci_script, ['T16096.script']) test('T507', just_ghci, ghci_script, ['T507.script']) +test('T18027', just_ghci, ghci_script, ['T18027.script']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b7a6b2f4c690a9711339462114a538a85dcb7d83...cf5663300c3d8b8b3c7dc2cd0dce2c923ec68987 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b7a6b2f4c690a9711339462114a538a85dcb7d83...cf5663300c3d8b8b3c7dc2cd0dce2c923ec68987 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 21 16:16:57 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 21 May 2020 12:16:57 -0400 Subject: [Git][ghc/ghc][master] llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 Message-ID: <5ec6a97974bc1_6e263f9eea2381ec5771fd@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 0004ccb8 by Tuan Le at 2020-05-21T12:16:46-04:00 llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 - - - - - 6 changed files: - compiler/GHC/Cmm.hs - compiler/GHC/CmmToC.hs - compiler/GHC/CmmToLlvm/Data.hs - + testsuite/tests/codeGen/should_gen_asm/T18137.asm - + testsuite/tests/codeGen/should_gen_asm/T18137.hs - testsuite/tests/codeGen/should_gen_asm/all.T Changes: ===================================== compiler/GHC/Cmm.hs ===================================== @@ -12,7 +12,7 @@ module GHC.Cmm ( CmmBlock, RawCmmDecl, Section(..), SectionType(..), GenCmmStatics(..), type CmmStatics, type RawCmmStatics, CmmStatic(..), - isSecConstant, + SectionProtection(..), sectionProtection, -- ** Blocks containing lists GenBasicBlock(..), blockId, @@ -185,17 +185,33 @@ data SectionType | OtherSection String deriving (Show) --- | Should a data in this section be considered constant -isSecConstant :: Section -> Bool -isSecConstant (Section t _) = case t of - Text -> True - ReadOnlyData -> True - RelocatableReadOnlyData -> True - ReadOnlyData16 -> True - CString -> True - Data -> False - UninitialisedData -> False - (OtherSection _) -> False +data SectionProtection + = ReadWriteSection + | ReadOnlySection + | WriteProtectedSection -- See Note [Relocatable Read-Only Data] + deriving (Eq) + +-- | Should a data in this section be considered constant at runtime +sectionProtection :: Section -> SectionProtection +sectionProtection (Section t _) = case t of + Text -> ReadOnlySection + ReadOnlyData -> ReadOnlySection + RelocatableReadOnlyData -> WriteProtectedSection + ReadOnlyData16 -> ReadOnlySection + CString -> ReadOnlySection + Data -> ReadWriteSection + UninitialisedData -> ReadWriteSection + (OtherSection _) -> ReadWriteSection + +{- +Note [Relocatable Read-Only Data] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Relocatable data are only read-only after relocation at the start of the +program. They should be writable from the source code until then. Failure to +do so would end up in segfaults at execution when using linkers that do not +enforce writability of those sections, such as the gold linker. +-} data Section = Section SectionType CLabel ===================================== compiler/GHC/CmmToC.hs ===================================== @@ -129,6 +129,10 @@ pprTop dflags = \case pprDataExterns platform lits $$ pprWordArray dflags (isSecConstant section) lbl lits where + isSecConstant section = case sectionProtection section of + ReadOnlySection -> True + WriteProtectedSection -> True + _ -> False platform = targetPlatform dflags -- -------------------------------------------------------------------------- ===================================== compiler/GHC/CmmToLlvm/Data.hs ===================================== @@ -83,7 +83,8 @@ genLlvmData (sec, CmmStaticsRaw lbl xs) = do Section CString _ -> if (platformArch platform == ArchS390X) then Just 2 else Just 1 _ -> Nothing - const = if isSecConstant sec then Constant else Global + const = if sectionProtection sec == ReadOnlySection + then Constant else Global varDef = LMGlobalVar label tyAlias link lmsec align const globDef = LMGlobal varDef struct ===================================== testsuite/tests/codeGen/should_gen_asm/T18137.asm ===================================== @@ -0,0 +1 @@ +\.section \.data\.rel\.ro\.RelocRoData_SomeData_closure_tbl,"aw",(?:%|@)progbits \ No newline at end of file ===================================== testsuite/tests/codeGen/should_gen_asm/T18137.hs ===================================== @@ -0,0 +1,6 @@ +module RelocRoData + ( SomeData(..) + ) +where + +data SomeData = SomeConstr ===================================== testsuite/tests/codeGen/should_gen_asm/all.T ===================================== @@ -9,3 +9,4 @@ test('memcpy-unroll-conprop', is_amd64_codegen, compile_cmp_asm, ['cmm', '']) test('memset-unroll', is_amd64_codegen, compile_cmp_asm, ['cmm', '']) test('bytearray-memset-unroll', is_amd64_codegen, compile_grep_asm, ['hs', True, '']) test('bytearray-memcpy-unroll', is_amd64_codegen, compile_grep_asm, ['hs', True, '']) +test('T18137', [when(opsys('darwin'), skip), only_ways(llvm_ways)], compile_grep_asm, ['hs', False, '-fllvm -split-sections']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0004ccb885e534c386ceae21580fc59ec7ad0ede -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0004ccb885e534c386ceae21580fc59ec7ad0ede You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 21 16:17:41 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 21 May 2020 12:17:41 -0400 Subject: [Git][ghc/ghc][master] 6 commits: Use `Checker` for `tc_pat` Message-ID: <5ec6a9a5f0821_6e2612540ff8582312@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 964d3ea2 by John Ericson at 2020-05-21T12:17:30-04:00 Use `Checker` for `tc_pat` - - - - - b797aa42 by John Ericson at 2020-05-21T12:17:30-04:00 Use `Checker` for `tc_lpat` and `tc_lpats` - - - - - 5108e84a by John Ericson at 2020-05-21T12:17:30-04:00 More judiciously panic in `ts_pat` - - - - - 510e0451 by John Ericson at 2020-05-21T12:17:30-04:00 Put `PatEnv` first in `GHC.Tc.Gen.Pat.Checker` - - - - - cb4231db by John Ericson at 2020-05-21T12:17:30-04:00 Tiny cleaup eta-reduce away a function argument In GHC, not in the code being compiled! - - - - - 6890c38d by John Ericson at 2020-05-21T12:17:30-04:00 Use braces with do in `SplicePat` case for consistency - - - - - 1 changed file: - compiler/GHC/Tc/Gen/Pat.hs Changes: ===================================== compiler/GHC/Tc/Gen/Pat.hs ===================================== @@ -4,8 +4,10 @@ -} -{-# LANGUAGE CPP, RankNTypes, TupleSections #-} +{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} @@ -87,7 +89,7 @@ tcLetPat sig_fn no_gen pat pat_ty thing_inside , pe_ctxt = ctxt , pe_orig = PatOrigin } - ; tc_lpat pat pat_ty penv thing_inside } + ; tc_lpat pat_ty penv pat thing_inside } ----------------- tcPats :: HsMatchContext GhcRn @@ -108,7 +110,7 @@ tcPats :: HsMatchContext GhcRn -- 4. Check that no existentials escape tcPats ctxt pats pat_tys thing_inside - = tc_lpats penv pats pat_tys thing_inside + = tc_lpats pat_tys penv pats thing_inside where penv = PE { pe_lazy = False, pe_ctxt = LamPat ctxt, pe_orig = PatOrigin } @@ -117,7 +119,7 @@ tcInferPat :: HsMatchContext GhcRn -> LPat GhcRn -> TcM ((LPat GhcTcId, a), TcSigmaType) tcInferPat ctxt pat thing_inside = tcInfer $ \ exp_ty -> - tc_lpat pat exp_ty penv thing_inside + tc_lpat exp_ty penv pat thing_inside where penv = PE { pe_lazy = False, pe_ctxt = LamPat ctxt, pe_orig = PatOrigin } @@ -134,7 +136,7 @@ tcCheckPat_O :: HsMatchContext GhcRn -> TcM a -- Checker for body -> TcM (LPat GhcTcId, a) tcCheckPat_O ctxt orig pat pat_ty thing_inside - = tc_lpat pat (mkCheckExpType pat_ty) penv thing_inside + = tc_lpat (mkCheckExpType pat_ty) penv pat thing_inside where penv = PE { pe_lazy = False, pe_ctxt = LamPat ctxt, pe_orig = orig } @@ -291,14 +293,17 @@ Hence the getErrCtxt/setErrCtxt stuff in tcMultiple -} -------------------- + type Checker inp out = forall r. - inp - -> PatEnv - -> TcM r - -> TcM (out, r) + PatEnv + -> inp + -> TcM r -- Thing inside + -> TcM ( out + , r -- Result of thing inside + ) tcMultiple :: Checker inp out -> Checker [inp] [out] -tcMultiple tc_pat args penv thing_inside +tcMultiple tc_pat penv args thing_inside = do { err_ctxt <- getErrCtxt ; let loop _ [] = do { res <- thing_inside @@ -306,7 +311,7 @@ tcMultiple tc_pat args penv thing_inside loop penv (arg:args) = do { (p', (ps', res)) - <- tc_pat arg penv $ + <- tc_pat penv arg $ setErrCtxt err_ctxt $ loop penv args -- setErrCtxt: restore context before doing the next pattern @@ -317,52 +322,46 @@ tcMultiple tc_pat args penv thing_inside ; loop penv args } -------------------- -tc_lpat :: LPat GhcRn - -> ExpSigmaType - -> PatEnv - -> TcM a - -> TcM (LPat GhcTcId, a) -tc_lpat (L span pat) pat_ty penv thing_inside +tc_lpat :: ExpSigmaType + -> Checker (LPat GhcRn) (LPat GhcTcId) +tc_lpat pat_ty penv (L span pat) thing_inside = setSrcSpan span $ - do { (pat', res) <- maybeWrapPatCtxt pat (tc_pat penv pat pat_ty) + do { (pat', res) <- maybeWrapPatCtxt pat (tc_pat pat_ty penv pat) thing_inside ; return (L span pat', res) } -tc_lpats :: PatEnv - -> [LPat GhcRn] -> [ExpSigmaType] - -> TcM a - -> TcM ([LPat GhcTcId], a) -tc_lpats penv pats tys thing_inside +tc_lpats :: [ExpSigmaType] + -> Checker [LPat GhcRn] [LPat GhcTcId] +tc_lpats tys penv pats = ASSERT2( equalLength pats tys, ppr pats $$ ppr tys ) - tcMultiple (\(p,t) -> tc_lpat p t) - (zipEqual "tc_lpats" pats tys) - penv thing_inside + tcMultiple (\ penv' (p,t) -> tc_lpat t penv' p) + penv + (zipEqual "tc_lpats" pats tys) -------------------- -tc_pat :: PatEnv - -> Pat GhcRn - -> ExpSigmaType -- Fully refined result type - -> TcM a -- Thing inside - -> TcM (Pat GhcTcId, -- Translated pattern - a) -- Result of thing inside - -tc_pat penv (VarPat x (L l name)) pat_ty thing_inside - = do { (wrap, id) <- tcPatBndr penv name pat_ty +tc_pat :: ExpSigmaType + -- ^ Fully refined result type + -> Checker (Pat GhcRn) (Pat GhcTcId) + -- ^ Translated pattern +tc_pat pat_ty penv ps_pat thing_inside = case ps_pat of + + VarPat x (L l name) -> do + { (wrap, id) <- tcPatBndr penv name pat_ty ; res <- tcExtendIdEnv1 name id thing_inside ; pat_ty <- readExpType pat_ty ; return (mkHsWrapPat wrap (VarPat x (L l id)) pat_ty, res) } -tc_pat penv (ParPat x pat) pat_ty thing_inside - = do { (pat', res) <- tc_lpat pat pat_ty penv thing_inside + ParPat x pat -> do + { (pat', res) <- tc_lpat pat_ty penv pat thing_inside ; return (ParPat x pat', res) } -tc_pat penv (BangPat x pat) pat_ty thing_inside - = do { (pat', res) <- tc_lpat pat pat_ty penv thing_inside + BangPat x pat -> do + { (pat', res) <- tc_lpat pat_ty penv pat thing_inside ; return (BangPat x pat', res) } -tc_pat penv (LazyPat x pat) pat_ty thing_inside - = do { (pat', (res, pat_ct)) - <- tc_lpat pat pat_ty (makeLazy penv) $ + LazyPat x pat -> do + { (pat', (res, pat_ct)) + <- tc_lpat pat_ty (makeLazy penv) pat $ captureConstraints thing_inside -- Ignore refined penv', revert to penv @@ -376,16 +375,16 @@ tc_pat penv (LazyPat x pat) pat_ty thing_inside ; return (LazyPat x pat', res) } -tc_pat _ (WildPat _) pat_ty thing_inside - = do { res <- thing_inside + WildPat _ -> do + { res <- thing_inside ; pat_ty <- expTypeToType pat_ty ; return (WildPat pat_ty, res) } -tc_pat penv (AsPat x (L nm_loc name) pat) pat_ty thing_inside - = do { (wrap, bndr_id) <- setSrcSpan nm_loc (tcPatBndr penv name pat_ty) + AsPat x (L nm_loc name) pat -> do + { (wrap, bndr_id) <- setSrcSpan nm_loc (tcPatBndr penv name pat_ty) ; (pat', res) <- tcExtendIdEnv1 name bndr_id $ - tc_lpat pat (mkCheckExpType $ idType bndr_id) - penv thing_inside + tc_lpat (mkCheckExpType $ idType bndr_id) + penv pat thing_inside -- NB: if we do inference on: -- \ (y@(x::forall a. a->a)) = e -- we'll fail. The as-pattern infers a monotype for 'y', which then @@ -397,8 +396,8 @@ tc_pat penv (AsPat x (L nm_loc name) pat) pat_ty thing_inside ; return (mkHsWrapPat wrap (AsPat x (L nm_loc bndr_id) pat') pat_ty, res) } -tc_pat penv (ViewPat _ expr pat) overall_pat_ty thing_inside - = do { + ViewPat _ expr pat -> do + { -- We use tcInferRho here. -- If we have a view function with types like: -- blah -> forall b. burble @@ -420,25 +419,25 @@ tc_pat penv (ViewPat _ expr pat) overall_pat_ty thing_inside -- expr_wrap1 :: expr_ty "->" (inf_arg_ty -> inf_res_ty) -- Check that overall pattern is more polymorphic than arg type - ; expr_wrap2 <- tc_sub_type penv overall_pat_ty inf_arg_ty - -- expr_wrap2 :: overall_pat_ty "->" inf_arg_ty + ; expr_wrap2 <- tc_sub_type penv pat_ty inf_arg_ty + -- expr_wrap2 :: pat_ty "->" inf_arg_ty -- Pattern must have inf_res_ty - ; (pat', res) <- tc_lpat pat (mkCheckExpType inf_res_ty) penv thing_inside + ; (pat', res) <- tc_lpat (mkCheckExpType inf_res_ty) penv pat thing_inside - ; overall_pat_ty <- readExpType overall_pat_ty + ; pat_ty <- readExpType pat_ty ; let expr_wrap2' = mkWpFun expr_wrap2 idHsWrapper - overall_pat_ty inf_res_ty doc + pat_ty inf_res_ty doc -- expr_wrap2' :: (inf_arg_ty -> inf_res_ty) "->" - -- (overall_pat_ty -> inf_res_ty) + -- (pat_ty -> inf_res_ty) expr_wrap = expr_wrap2' <.> expr_wrap1 doc = text "When checking the view pattern function:" <+> (ppr expr) - ; return (ViewPat overall_pat_ty (mkLHsWrap expr_wrap expr') pat', res)} + ; return (ViewPat pat_ty (mkLHsWrap expr_wrap expr') pat', res)} -- Type signatures in patterns -- See Note [Pattern coercions] below -tc_pat penv (SigPat _ pat sig_ty) pat_ty thing_inside - = do { (inner_ty, tv_binds, wcs, wrap) <- tcPatSig (inPatBind penv) + SigPat _ pat sig_ty -> do + { (inner_ty, tv_binds, wcs, wrap) <- tcPatSig (inPatBind penv) sig_ty pat_ty -- Using tcExtendNameTyVarEnv is appropriate here -- because we're not really bringing fresh tyvars into scope. @@ -446,35 +445,35 @@ tc_pat penv (SigPat _ pat sig_ty) pat_ty thing_inside -- from an outer scope to mention one of these tyvars in its kind. ; (pat', res) <- tcExtendNameTyVarEnv wcs $ tcExtendNameTyVarEnv tv_binds $ - tc_lpat pat (mkCheckExpType inner_ty) penv thing_inside + tc_lpat (mkCheckExpType inner_ty) penv pat thing_inside ; pat_ty <- readExpType pat_ty ; return (mkHsWrapPat wrap (SigPat inner_ty pat' sig_ty) pat_ty, res) } ------------------------ -- Lists, tuples, arrays -tc_pat penv (ListPat Nothing pats) pat_ty thing_inside - = do { (coi, elt_ty) <- matchExpectedPatTy matchExpectedListTy penv pat_ty - ; (pats', res) <- tcMultiple (\p -> tc_lpat p (mkCheckExpType elt_ty)) - pats penv thing_inside + ListPat Nothing pats -> do + { (coi, elt_ty) <- matchExpectedPatTy matchExpectedListTy penv pat_ty + ; (pats', res) <- tcMultiple (tc_lpat $ mkCheckExpType elt_ty) + penv pats thing_inside ; pat_ty <- readExpType pat_ty ; return (mkHsWrapPat coi (ListPat (ListPatTc elt_ty Nothing) pats') pat_ty, res) } -tc_pat penv (ListPat (Just e) pats) pat_ty thing_inside - = do { tau_pat_ty <- expTypeToType pat_ty + ListPat (Just e) pats -> do + { tau_pat_ty <- expTypeToType pat_ty ; ((pats', res, elt_ty), e') <- tcSyntaxOpGen ListOrigin e [SynType (mkCheckExpType tau_pat_ty)] SynList $ \ [elt_ty] -> - do { (pats', res) <- tcMultiple (\p -> tc_lpat p (mkCheckExpType elt_ty)) - pats penv thing_inside + do { (pats', res) <- tcMultiple (tc_lpat $ mkCheckExpType elt_ty) + penv pats thing_inside ; return (pats', res, elt_ty) } ; return (ListPat (ListPatTc elt_ty (Just (tau_pat_ty,e'))) pats', res) } -tc_pat penv (TuplePat _ pats boxity) pat_ty thing_inside - = do { let arity = length pats + TuplePat _ pats boxity -> do + { let arity = length pats tc = tupleTyCon boxity arity -- NB: tupleTyCon does not flatten 1-tuples -- See Note [Don't flatten tuples from HsSyn] in GHC.Core.Make @@ -484,8 +483,8 @@ tc_pat penv (TuplePat _ pats boxity) pat_ty thing_inside -- See Note [Unboxed tuple RuntimeRep vars] in GHC.Core.TyCon ; let con_arg_tys = case boxity of Unboxed -> drop arity arg_tys Boxed -> arg_tys - ; (pats', res) <- tc_lpats penv pats (map mkCheckExpType con_arg_tys) - thing_inside + ; (pats', res) <- tc_lpats (map mkCheckExpType con_arg_tys) + penv pats thing_inside ; dflags <- getDynFlags @@ -506,14 +505,14 @@ tc_pat penv (TuplePat _ pats boxity) pat_ty thing_inside return (mkHsWrapPat coi possibly_mangled_result pat_ty, res) } -tc_pat penv (SumPat _ pat alt arity ) pat_ty thing_inside - = do { let tc = sumTyCon arity + SumPat _ pat alt arity -> do + { let tc = sumTyCon arity ; (coi, arg_tys) <- matchExpectedPatTy (matchExpectedTyConApp tc) penv pat_ty ; -- Drop levity vars, we don't care about them here let con_arg_tys = drop arity arg_tys - ; (pat', res) <- tc_lpat pat (mkCheckExpType (con_arg_tys `getNth` (alt - 1))) - penv thing_inside + ; (pat', res) <- tc_lpat (mkCheckExpType (con_arg_tys `getNth` (alt - 1))) + penv pat thing_inside ; pat_ty <- readExpType pat_ty ; return (mkHsWrapPat coi (SumPat con_arg_tys pat' alt arity) pat_ty , res) @@ -521,13 +520,13 @@ tc_pat penv (SumPat _ pat alt arity ) pat_ty thing_inside ------------------------ -- Data constructors -tc_pat penv (ConPat NoExtField con arg_pats) pat_ty thing_inside - = tcConPat penv con pat_ty arg_pats thing_inside + ConPat NoExtField con arg_pats -> + tcConPat penv con pat_ty arg_pats thing_inside ------------------------ -- Literal patterns -tc_pat penv (LitPat x simple_lit) pat_ty thing_inside - = do { let lit_ty = hsLitType simple_lit + LitPat x simple_lit -> do + { let lit_ty = hsLitType simple_lit ; wrap <- tc_sub_type penv pat_ty lit_ty ; res <- thing_inside ; pat_ty <- readExpType pat_ty @@ -552,8 +551,8 @@ tc_pat penv (LitPat x simple_lit) pat_ty thing_inside -- where lit_ty is the type of the overloaded literal 5. -- -- When there is no negation, neg_lit_ty and lit_ty are the same -tc_pat _ (NPat _ (L l over_lit) mb_neg eq) pat_ty thing_inside - = do { let orig = LiteralOrigin over_lit + NPat _ (L l over_lit) mb_neg eq -> do + { let orig = LiteralOrigin over_lit ; ((lit', mb_neg'), eq') <- tcSyntaxOp orig eq [SynType pat_ty, SynAny] (mkCheckExpType boolTy) $ @@ -601,10 +600,9 @@ AST is used for the subtraction operation. -} -- See Note [NPlusK patterns] -tc_pat penv (NPlusKPat _ (L nm_loc name) - (L loc lit) _ ge minus) pat_ty - thing_inside - = do { pat_ty <- expTypeToType pat_ty + NPlusKPat _ (L nm_loc name) + (L loc lit) _ ge minus -> do + { pat_ty <- expTypeToType pat_ty ; let orig = LiteralOrigin lit ; (lit1', ge') <- tcSyntaxOp orig ge [synKnownType pat_ty, SynRho] @@ -650,12 +648,11 @@ tc_pat penv (NPlusKPat _ (L nm_loc name) -- Here we get rid of it and add the finalizers to the global environment. -- -- See Note [Delaying modFinalizers in untyped splices] in GHC.Rename.Splice. -tc_pat penv (SplicePat _ (HsSpliced _ mod_finalizers (HsSplicedPat pat))) - pat_ty thing_inside - = do addModFinalizersWithLclEnv mod_finalizers - tc_pat penv pat pat_ty thing_inside - -tc_pat _ _other_pat _ _ = panic "tc_pat" -- ConPatOut, SigPatOut + SplicePat _ splice -> case splice of + (HsSpliced _ mod_finalizers (HsSplicedPat pat)) -> do + { addModFinalizersWithLclEnv mod_finalizers + ; tc_pat pat_ty penv pat thing_inside } + _ -> panic "invalid splice in splice pat" {- @@ -871,7 +868,7 @@ tcDataConPat penv (L con_span con_name) data_con pat_ty then do { -- The common case; no class bindings etc -- (see Note [Arrows and patterns]) (arg_pats', res) <- tcConArgs (RealDataCon data_con) arg_tys' - arg_pats penv thing_inside + penv arg_pats thing_inside ; let res_pat = ConPat { pat_con = header , pat_args = arg_pats' , pat_con_ext = ConPatTc @@ -907,7 +904,7 @@ tcDataConPat penv (L con_span con_name) data_con pat_ty ; given <- newEvVars theta' ; (ev_binds, (arg_pats', res)) <- checkConstraints skol_info ex_tvs' given $ - tcConArgs (RealDataCon data_con) arg_tys' arg_pats penv thing_inside + tcConArgs (RealDataCon data_con) arg_tys' penv arg_pats thing_inside ; let res_pat = ConPat { pat_con = header @@ -961,7 +958,7 @@ tcPatSynPat penv (L con_span _) pat_syn pat_ty arg_pats thing_inside ; traceTc "checkConstraints {" Outputable.empty ; (ev_binds, (arg_pats', res)) <- checkConstraints skol_info ex_tvs' prov_dicts' $ - tcConArgs (PatSynCon pat_syn) arg_tys' arg_pats penv thing_inside + tcConArgs (PatSynCon pat_syn) arg_tys' penv arg_pats thing_inside ; traceTc "checkConstraints }" (ppr ev_binds) ; let res_pat = ConPat { pat_con = L con_span $ PatSynCon pat_syn @@ -1070,46 +1067,48 @@ Suppose (coi, tys) = matchExpectedConType data_tc pat_ty tcConArgs :: ConLike -> [TcSigmaType] -> Checker (HsConPatDetails GhcRn) (HsConPatDetails GhcTc) -tcConArgs con_like arg_tys (PrefixCon arg_pats) penv thing_inside - = do { checkTc (con_arity == no_of_args) -- Check correct arity +tcConArgs con_like arg_tys penv con_args thing_inside = case con_args of + PrefixCon arg_pats -> do + { checkTc (con_arity == no_of_args) -- Check correct arity (arityErr (text "constructor") con_like con_arity no_of_args) ; let pats_w_tys = zipEqual "tcConArgs" arg_pats arg_tys - ; (arg_pats', res) <- tcMultiple tcConArg pats_w_tys - penv thing_inside + ; (arg_pats', res) <- tcMultiple tcConArg penv pats_w_tys + thing_inside ; return (PrefixCon arg_pats', res) } - where - con_arity = conLikeArity con_like - no_of_args = length arg_pats + where + con_arity = conLikeArity con_like + no_of_args = length arg_pats -tcConArgs con_like arg_tys (InfixCon p1 p2) penv thing_inside - = do { checkTc (con_arity == 2) -- Check correct arity + InfixCon p1 p2 -> do + { checkTc (con_arity == 2) -- Check correct arity (arityErr (text "constructor") con_like con_arity 2) ; let [arg_ty1,arg_ty2] = arg_tys -- This can't fail after the arity check - ; ([p1',p2'], res) <- tcMultiple tcConArg [(p1,arg_ty1),(p2,arg_ty2)] - penv thing_inside + ; ([p1',p2'], res) <- tcMultiple tcConArg penv [(p1,arg_ty1),(p2,arg_ty2)] + thing_inside ; return (InfixCon p1' p2', res) } - where - con_arity = conLikeArity con_like + where + con_arity = conLikeArity con_like -tcConArgs con_like arg_tys (RecCon (HsRecFields rpats dd)) penv thing_inside - = do { (rpats', res) <- tcMultiple tc_field rpats penv thing_inside + RecCon (HsRecFields rpats dd) -> do + { (rpats', res) <- tcMultiple tc_field penv rpats thing_inside ; return (RecCon (HsRecFields rpats' dd), res) } - where - tc_field :: Checker (LHsRecField GhcRn (LPat GhcRn)) - (LHsRecField GhcTcId (LPat GhcTcId)) - tc_field (L l (HsRecField (L loc (FieldOcc sel (L lr rdr))) pat pun)) - penv thing_inside - = do { sel' <- tcLookupId sel - ; pat_ty <- setSrcSpan loc $ find_field_ty sel - (occNameFS $ rdrNameOcc rdr) - ; (pat', res) <- tcConArg (pat, pat_ty) penv thing_inside - ; return (L l (HsRecField (L loc (FieldOcc sel' (L lr rdr))) pat' - pun), res) } - - - find_field_ty :: Name -> FieldLabelString -> TcM TcType - find_field_ty sel lbl - = case [ty | (fl, ty) <- field_tys, flSelector fl == sel] of + where + tc_field :: Checker (LHsRecField GhcRn (LPat GhcRn)) + (LHsRecField GhcTcId (LPat GhcTcId)) + tc_field penv + (L l (HsRecField (L loc (FieldOcc sel (L lr rdr))) pat pun)) + thing_inside + = do { sel' <- tcLookupId sel + ; pat_ty <- setSrcSpan loc $ find_field_ty sel + (occNameFS $ rdrNameOcc rdr) + ; (pat', res) <- tcConArg penv (pat, pat_ty) thing_inside + ; return (L l (HsRecField (L loc (FieldOcc sel' (L lr rdr))) pat' + pun), res) } + + + find_field_ty :: Name -> FieldLabelString -> TcM TcType + find_field_ty sel lbl + = case [ty | (fl, ty) <- field_tys, flSelector fl == sel ] of -- No matching field; chances are this field label comes from some -- other record type (or maybe none). If this happens, just fail, @@ -1124,15 +1123,14 @@ tcConArgs con_like arg_tys (RecCon (HsRecFields rpats dd)) penv thing_inside traceTc "find_field" (ppr pat_ty <+> ppr extras) ASSERT( null extras ) (return pat_ty) - field_tys :: [(FieldLabel, TcType)] - field_tys = zip (conLikeFieldLabels con_like) arg_tys + field_tys :: [(FieldLabel, TcType)] + field_tys = zip (conLikeFieldLabels con_like) arg_tys -- Don't use zipEqual! If the constructor isn't really a record, then -- dataConFieldLabels will be empty (and each field in the pattern -- will generate an error below). tcConArg :: Checker (LPat GhcRn, TcSigmaType) (LPat GhcTc) -tcConArg (arg_pat, arg_ty) penv thing_inside - = tc_lpat arg_pat (mkCheckExpType arg_ty) penv thing_inside +tcConArg penv (arg_pat, arg_ty) = tc_lpat (mkCheckExpType arg_ty) penv arg_pat addDataConStupidTheta :: DataCon -> [TcType] -> TcM () -- Instantiate the "stupid theta" of the data con, and throw View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0004ccb885e534c386ceae21580fc59ec7ad0ede...6890c38d4568ca444cccc47dd1a86c5e020c3521 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0004ccb885e534c386ceae21580fc59ec7ad0ede...6890c38d4568ca444cccc47dd1a86c5e020c3521 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gitlab at gitlab.haskell.org Thu May 21 16:18:18 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 21 May 2020 12:18:18 -0400 Subject: [Git][ghc/ghc][master] 4 commits: Fix spelling mistakes and typos Message-ID: <5ec6a9ca3f51b_6e263f9eea2381ec586724@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 3451584f by buggymcbugfix at 2020-05-21T12:18:06-04:00 Fix spelling mistakes and typos - - - - - b552e531 by buggymcbugfix at 2020-05-21T12:18:06-04:00 Add INLINABLE pragmas to Enum list producers The INLINABLE pragmas ensure that we export stable (unoptimised) unfoldings in the interface file so we can do list fusion at usage sites. Related tickets: #15185, #8763, #18178. - - - - - e7480063 by buggymcbugfix at 2020-05-21T12:18:06-04:00 Piggyback on Enum Word methods for Word64 If we are on a 64 bit platform, we can use the efficient Enum Word methods for the Enum Word64 instance. - - - - - 892b0c41 by buggymcbugfix at 2020-05-21T12:18:06-04:00 Document INLINE(ABLE) pragmas that enable fusion - - - - - 8 changed files: - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Types/Name/Occurrence.hs - docs/users_guide/debugging.rst - libraries/base/GHC/Enum.hs - libraries/base/GHC/List.hs - libraries/base/GHC/Word.hs - + testsuite/tests/perf/should_run/T15185.hs - testsuite/tests/perf/should_run/all.T Changes: ===================================== compiler/GHC/Tc/Deriv/Generate.hs ===================================== @@ -592,8 +592,8 @@ gen_Enum_binds loc tycon = do [ succ_enum dflags , pred_enum dflags , to_enum dflags - , enum_from dflags - , enum_from_then dflags + , enum_from dflags -- [0 ..] + , enum_from_then dflags -- [0, 1 ..] , from_enum dflags ] aux_binds = listToBag $ map DerivAuxBind ===================================== compiler/GHC/Types/Name/Occurrence.hs ===================================== @@ -624,7 +624,7 @@ mkIPOcc = mk_simple_deriv varName "$i" mkSpecOcc = mk_simple_deriv varName "$s" mkForeignExportOcc = mk_simple_deriv varName "$f" mkRepEqOcc = mk_simple_deriv tvName "$r" -- In RULES involving Coercible -mkClassDataConOcc = mk_simple_deriv dataName "C:" -- Data con for a class +mkClassDataConOcc = mk_simple_deriv dataName "C:" -- Data con for a class mkNewTyCoOcc = mk_simple_deriv tcName "N:" -- Coercion for newtypes mkInstTyCoOcc = mk_simple_deriv tcName "D:" -- Coercion for type functions mkEqPredCoOcc = mk_simple_deriv tcName "$co" ===================================== docs/users_guide/debugging.rst ===================================== @@ -301,7 +301,7 @@ subexpression elimination pass. Rules are filtered by the user provided string, a rule is kept if a prefix of its name matches the string. The pass then checks whether any of these rules could apply to - the program but which didn't file for some reason. For example, specifying + the program but which didn't fire for some reason. For example, specifying ``-drule-check=SPEC`` will check whether there are any applications which might be subject to a rule created by specialisation. ===================================== libraries/base/GHC/Enum.hs ===================================== @@ -139,17 +139,34 @@ class Enum a where -- * @enumFromThenTo 6 8 2 :: [Int] = []@ enumFromThenTo :: a -> a -> a -> [a] - succ = toEnum . (+ 1) . fromEnum - pred = toEnum . (subtract 1) . fromEnum - enumFrom x = map toEnum [fromEnum x ..] - enumFromThen x y = map toEnum [fromEnum x, fromEnum y ..] - enumFromTo x y = map toEnum [fromEnum x .. fromEnum y] + succ = toEnum . (+ 1) . fromEnum + + pred = toEnum . (subtract 1) . fromEnum + + -- See Note [Stable Unfolding for list producers] + {-# INLINABLE enumFrom #-} + enumFrom x = map toEnum [fromEnum x ..] + + -- See Note [Stable Unfolding for list producers] + {-# INLINABLE enumFromThen #-} + enumFromThen x y = map toEnum [fromEnum x, fromEnum y ..] + + -- See Note [Stable Unfolding for list producers] + {-# INLINABLE enumFromTo #-} + enumFromTo x y = map toEnum [fromEnum x .. fromEnum y] + + -- See Note [Stable Unfolding for list producers] + {-# INLINABLE enumFromThenTo #-} enumFromThenTo x1 x2 y = map toEnum [fromEnum x1, fromEnum x2 .. fromEnum y] +-- See Note [Stable Unfolding for list producers] +{-# INLINABLE boundedEnumFrom #-} -- Default methods for bounded enumerations boundedEnumFrom :: (Enum a, Bounded a) => a -> [a] boundedEnumFrom n = map toEnum [fromEnum n .. fromEnum (maxBound `asTypeOf` n)] +-- See Note [Stable Unfolding for list producers] +{-# INLINABLE boundedEnumFromThen #-} boundedEnumFromThen :: (Enum a, Bounded a) => a -> a -> [a] boundedEnumFromThen n1 n2 | i_n2 >= i_n1 = map toEnum [i_n1, i_n2 .. fromEnum (maxBound `asTypeOf` n1)] @@ -158,6 +175,14 @@ boundedEnumFromThen n1 n2 i_n1 = fromEnum n1 i_n2 = fromEnum n2 +{- +Note [Stable Unfolding for list producers] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The INLINABLE/INLINE pragmas ensure that we export stable (unoptimised) +unfoldings in the interface file so we can do list fusion at usage sites. +-} + ------------------------------------------------------------------------ -- Helper functions ------------------------------------------------------------------------ @@ -343,16 +368,20 @@ instance Enum Char where toEnum = chr fromEnum = ord + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFrom #-} enumFrom (C# x) = eftChar (ord# x) 0x10FFFF# -- Blarg: technically I guess enumFrom isn't strict! + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromTo #-} enumFromTo (C# x) (C# y) = eftChar (ord# x) (ord# y) + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromThen #-} enumFromThen (C# x1) (C# x2) = efdChar (ord# x1) (ord# x2) + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromThenTo #-} enumFromThenTo (C# x1) (C# x2) (C# y) = efdtChar (ord# x1) (ord# x2) (ord# y) @@ -472,17 +501,21 @@ instance Enum Int where toEnum x = x fromEnum x = x + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFrom #-} enumFrom (I# x) = eftInt x maxInt# where !(I# maxInt#) = maxInt -- Blarg: technically I guess enumFrom isn't strict! + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromTo #-} enumFromTo (I# x) (I# y) = eftInt x y + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromThen #-} enumFromThen (I# x1) (I# x2) = efdInt x1 x2 + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromThenTo #-} enumFromThenTo (I# x1) (I# x2) (I# y) = efdtInt x1 x2 y @@ -812,13 +845,20 @@ instance Enum Integer where toEnum (I# n) = smallInteger n fromEnum n = I# (integerToInt n) + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFrom #-} + enumFrom x = enumDeltaInteger x 1 + + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromThen #-} + enumFromThen x y = enumDeltaInteger x (y-x) + + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromTo #-} + enumFromTo x lim = enumDeltaToInteger x 1 lim + + -- See Note [Stable Unfolding for list producers] {-# INLINE enumFromThenTo #-} - enumFrom x = enumDeltaInteger x 1 - enumFromThen x y = enumDeltaInteger x (y-x) - enumFromTo x lim = enumDeltaToInteger x 1 lim enumFromThenTo x y lim = enumDeltaToInteger x (y-x) lim -- See Note [How the Enum rules work] @@ -927,6 +967,7 @@ instance Enum Natural where toEnum = intToNatural #if defined(MIN_VERSION_integer_gmp) + -- This is the integer-gmp special case. The general case is after the endif. fromEnum (NatS# w) | i >= 0 = i | otherwise = errorWithoutStackTrace "fromEnum: out of Int range" @@ -936,11 +977,13 @@ instance Enum Natural where fromEnum n = fromEnum (naturalToInteger n) enumFrom x = enumDeltaNatural x (wordToNaturalBase 1##) + enumFromThen x y | x <= y = enumDeltaNatural x (y-x) | otherwise = enumNegDeltaToNatural x (x-y) (wordToNaturalBase 0##) enumFromTo x lim = enumDeltaToNatural x (wordToNaturalBase 1##) lim + enumFromThenTo x y lim | x <= y = enumDeltaToNatural x (y-x) lim | otherwise = enumNegDeltaToNatural x (x-y) lim ===================================== libraries/base/GHC/List.hs ===================================== @@ -277,10 +277,10 @@ to list-producing functions abstracted over cons and nil. Here we call them FB functions because their names usually end with 'FB'. It's a good idea to inline FB functions because: -* They are higher-order functions and therefore benefits from inlining. +* They are higher-order functions and therefore benefit from inlining. * When the final consumer is a left fold, inlining the FB functions is the only - way to make arity expansion to happen. See Note [Left fold via right fold]. + way to make arity expansion happen. See Note [Left fold via right fold]. For this reason we mark all FB functions INLINE [0]. The [0] phase-specifier ensures that calls to FB functions can be written back to the original form ===================================== libraries/base/GHC/Word.hs ===================================== @@ -892,10 +892,44 @@ instance Enum Word64 where | x <= fromIntegral (maxBound::Int) = I# (word2Int# x#) | otherwise = fromEnumError "Word64" x - enumFrom = integralEnumFrom - enumFromThen = integralEnumFromThen - enumFromTo = integralEnumFromTo - enumFromThenTo = integralEnumFromThenTo + +#if WORD_SIZE_IN_BITS < 64 + enumFrom = integralEnumFrom + enumFromThen = integralEnumFromThen + enumFromTo = integralEnumFromTo + enumFromThenTo = integralEnumFromThenTo +#else + -- See Note [Stable Unfolding for list producers] in GHC.Enum + {-# INLINABLE enumFrom #-} + enumFrom w + = map wordToWord64 + $ enumFrom (word64ToWord w) + + -- See Note [Stable Unfolding for list producers] in GHC.Enum + {-# INLINABLE enumFromThen #-} + enumFromThen w s + = map wordToWord64 + $ enumFromThen (word64ToWord w) (word64ToWord s) + + -- See Note [Stable Unfolding for list producers] in GHC.Enum + {-# INLINABLE enumFromTo #-} + enumFromTo w1 w2 + = map wordToWord64 + $ enumFromTo (word64ToWord w1) (word64ToWord w2) + + -- See Note [Stable Unfolding for list producers] in GHC.Enum + {-# INLINABLE enumFromThenTo #-} + enumFromThenTo w1 s w2 + = map wordToWord64 + $ enumFromThenTo (word64ToWord w1) (word64ToWord s) (word64ToWord w2) + +word64ToWord :: Word64 -> Word +word64ToWord (W64# w#) = (W# w#) + +wordToWord64 :: Word -> Word64 +wordToWord64 (W# w#) = (W64# w#) +#endif + -- | @since 2.01 instance Integral Word64 where ===================================== testsuite/tests/perf/should_run/T15185.hs ===================================== @@ -0,0 +1,25 @@ +{-# LANGUAGE TypeApplications #-} + +-- Ensure that we do list fusion on `foldr f z [from..to]` for sized `Int` and +-- `Word` types. Related tickets: #15185, #8763. + +import Control.Exception (evaluate) +import Data.Int +import Data.Word + +fact :: Integral t => t -> t +fact n = product [1..n] + +main :: IO () +main = do + _ <- evaluate (fact @Int 50) + _ <- evaluate (fact @Int64 50) + _ <- evaluate (fact @Int32 50) + _ <- evaluate (fact @Int16 50) + _ <- evaluate (fact @Int8 50) + _ <- evaluate (fact @Word 50) + _ <- evaluate (fact @Word64 50) + _ <- evaluate (fact @Word32 50) + _ <- evaluate (fact @Word16 50) + _ <- evaluate (fact @Word8 50) + pure () ===================================== testsuite/tests/perf/should_run/all.T ===================================== @@ -367,6 +367,11 @@ test('T15578', compile_and_run, ['-O2']) +test('T15185', + [collect_stats('bytes allocated', 5), only_ways(['normal'])], + compile_and_run, + ['-O']) + # Test performance of creating Uniques. test('UniqLoop', [collect_stats('bytes allocated',5), View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6890c38d4568ca444cccc47dd1a86c5e020c3521...892b0c41816fca4eeea42ca03a43aac473311837 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6890c38d4568ca444cccc47dd1a86c5e020c3521...892b0c41816fca4eeea42ca03a43aac473311837 You're receiving this email because of