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 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:56 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 21 May 2020 12:18:56 -0400 Subject: [Git][ghc/ghc][master] MR template should ask for key part Message-ID: <5ec6a9f094bf0_6e263f9ee41f92e05870a6@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 2b363ebb by Richard Eisenberg at 2020-05-21T12:18:45-04:00 MR template should ask for key part - - - - - 1 changed file: - .gitlab/merge_request_templates/merge-request.md 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 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2b363ebb988cbf8c92df24eef5366293a80ecb19 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2b363ebb988cbf8c92df24eef5366293a80ecb19 You're receiving 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:19:49 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 21 May 2020 12:19:49 -0400 Subject: [Git][ghc/ghc][master] Make `Int`'s `mod` and `rem` strict in their first arguments Message-ID: <5ec6aa2592b5c_6e263f9ee3803844593951@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: a95bbd0b by Sebastian Graf at 2020-05-21T12:19:37-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. - - - - - 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/a95bbd0bdf06d7d61b0bef6de77b59ca31b2c32d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a95bbd0bdf06d7d61b0bef6de77b59ca31b2c32d You're receiving 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:20:27 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 21 May 2020 12:20:27 -0400 Subject: [Git][ghc/ghc][master] Clarify pitfalls of NegativeLiterals; see #18022. Message-ID: <5ec6aa4bdb380_6e2679b9a4059577c@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: d3d055b8 by Galen Huntington at 2020-05-21T12:20:18-04:00 Clarify pitfalls of NegativeLiterals; see #18022. - - - - - 1 changed file: - docs/users_guide/exts/negative_literals.rst Changes: ===================================== 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. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d3d055b8d10a549e42d18ae4859bc902f939f534 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d3d055b8d10a549e42d18ae4859bc902f939f534 You're receiving 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:21:12 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 21 May 2020 12:21:12 -0400 Subject: [Git][ghc/ghc][master] Fix wording in primops documentation to reflect the correct reasoning: Message-ID: <5ec6aa78cd11d_6e263f9f0bd8e174599763@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 1b508a9e by Alexey Kuleshevich at 2020-05-21T12:21:02-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" - - - - - 1 changed file: - compiler/GHC/Builtin/primops.txt.pp Changes: ===================================== 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 } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1b508a9e14c7c894ff4f080f099f3947813f41ec -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1b508a9e14c7c894ff4f080f099f3947813f41ec You're receiving 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:22:11 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 21 May 2020 12:22:11 -0400 Subject: [Git][ghc/ghc][master] Don't variable-length encode magic iface constant. Message-ID: <5ec6aab354e90_6e263f9eea2381ec6038f@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 4ca0c8a1 by Andreas Klebinger at 2020-05-21T12:21: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. - - - - - 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/4ca0c8a17b9d3a7e8ff8a93cc9e83be5173f8e14 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4ca0c8a17b9d3a7e8ff8a93cc9e83be5173f8e14 You're receiving 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:22:46 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 21 May 2020 12:22:46 -0400 Subject: [Git][ghc/ghc][master] Add a regression test for #11506 Message-ID: <5ec6aad6326c4_6e263f9ee41f92e06081b@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: a1275081 by Krzysztof Gogolewski at 2020-05-21T12:22:35-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 - - - - - 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/a127508137ba69d2fe1e563d2bbb9fdd9120ae85 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a127508137ba69d2fe1e563d2bbb9fdd9120ae85 You're receiving 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:24:05 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 21 May 2020 12:24:05 -0400 Subject: [Git][ghc/ghc][master] Sort deterministically metric output Message-ID: <5ec6ab25605e8_6e263f9f0bd8e174610986@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 8a816e5f by Krzysztof Gogolewski at 2020-05-21T12:23:55-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. - - - - - 1 changed file: - testsuite/driver/runtests.py Changes: ===================================== testsuite/driver/runtests.py ===================================== @@ -339,7 +339,7 @@ def cleanup_and_exit(exitcode): exit(exitcode) def tabulate_metrics(metrics: List[PerfMetric]) -> None: - for metric in sorted(metrics, key=lambda m: (m.stat.test, m.stat.way)): + for metric in sorted(metrics, key=lambda m: (m.stat.test, m.stat.way, m.stat.metric)): print("{test:24} {metric:40} {value:15.3f}".format( test = "{}({})".format(metric.stat.test, metric.stat.way), metric = metric.stat.metric, View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8a816e5fbe02c476f51ec92563cad8247ffc90ba -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8a816e5fbe02c476f51ec92563cad8247ffc90ba You're receiving 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:24:56 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 21 May 2020 12:24:56 -0400 Subject: [Git][ghc/ghc][master] Move isDynLinkName into GHC.Types.Name Message-ID: <5ec6ab589e8e2_6e263f9eea2381ec6138f5@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 566cc73f by Sylvain Henry at 2020-05-21T12:24:45-04:00 Move isDynLinkName into GHC.Types.Name It doesn't belong into GHC.Unit.State - - - - - 4 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Stg/Syntax.hs - compiler/GHC/Types/Name.hs - compiler/GHC/Unit/State.hs Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -119,7 +119,6 @@ import GHC.Prelude import GHC.Types.Id.Info import GHC.Types.Basic import {-# SOURCE #-} GHC.Cmm.BlockId (BlockId, mkBlockId) -import GHC.Unit.State import GHC.Unit import GHC.Types.Name import GHC.Types.Unique ===================================== compiler/GHC/Stg/Syntax.hs ===================================== @@ -72,11 +72,11 @@ import GHC.Core.DataCon import GHC.Driver.Session import GHC.Types.ForeignCall ( ForeignCall ) import GHC.Types.Id +import GHC.Types.Name ( isDynLinkName ) import GHC.Types.Var.Set import GHC.Types.Literal ( Literal, literalType ) import GHC.Unit.Module ( Module ) import GHC.Utils.Outputable -import GHC.Unit.State ( isDynLinkName ) import GHC.Platform import GHC.Core.Ppr( {- instances -} ) import GHC.Builtin.PrimOps ( PrimOp, PrimCall ) ===================================== compiler/GHC/Types/Name.hs ===================================== @@ -60,7 +60,7 @@ module GHC.Types.Name ( -- ** Predicates on 'Name's isSystemName, isInternalName, isExternalName, isTyVarName, isTyConName, isDataConName, - isValName, isVarName, + isValName, isVarName, isDynLinkName, isWiredInName, isWiredIn, isBuiltInSyntax, isHoleName, wiredInNameTyThing_maybe, @@ -83,6 +83,7 @@ import GHC.Prelude import {-# SOURCE #-} GHC.Core.TyCo.Rep( TyThing ) +import GHC.Platform import GHC.Types.Name.Occurrence import GHC.Unit.Module import GHC.Types.SrcLoc @@ -242,6 +243,39 @@ isInternalName name = not (isExternalName name) isHoleName :: Name -> Bool isHoleName = isHoleModule . nameModule +-- | Will the 'Name' come from a dynamically linked package? +isDynLinkName :: Platform -> Module -> Name -> Bool +isDynLinkName platform this_mod name + | Just mod <- nameModule_maybe name + -- Issue #8696 - when GHC is dynamically linked, it will attempt + -- to load the dynamic dependencies of object files at compile + -- time for things like QuasiQuotes or + -- TemplateHaskell. Unfortunately, this interacts badly with + -- intra-package linking, because we don't generate indirect + -- (dynamic) symbols for intra-package calls. This means that if a + -- module with an intra-package call is loaded without its + -- dependencies, then GHC fails to link. + -- + -- In the mean time, always force dynamic indirections to be + -- generated: when the module name isn't the module being + -- compiled, references are dynamic. + = case platformOS platform of + -- On Windows the hack for #8696 makes it unlinkable. + -- As the entire setup of the code from Cmm down to the RTS expects + -- the use of trampolines for the imported functions only when + -- doing intra-package linking, e.g. referring to a symbol defined in the same + -- package should not use a trampoline. + -- I much rather have dynamic TH not supported than the entire Dynamic linking + -- not due to a hack. + -- Also not sure this would break on Windows anyway. + OSMinGW32 -> moduleUnit mod /= moduleUnit this_mod + + -- For the other platforms, still perform the hack + _ -> mod /= this_mod + + | otherwise = False -- no, it is not even an external name + + nameModule name = nameModule_maybe name `orElse` pprPanic "nameModule" (ppr (n_sort name) <+> ppr name) ===================================== compiler/GHC/Unit/State.hs ===================================== @@ -60,7 +60,6 @@ module GHC.Unit.State ( pprPackagesSimple, pprModuleMap, isIndefinite, - isDynLinkName ) where @@ -75,13 +74,11 @@ import GHC.Unit.Module import GHC.Unit.Subst import GHC.Driver.Session import GHC.Driver.Ways -import GHC.Types.Name ( Name, nameModule_maybe ) import GHC.Types.Unique.FM import GHC.Types.Unique.DFM import GHC.Types.Unique.Set import GHC.Utils.Misc import GHC.Utils.Panic -import GHC.Platform import GHC.Utils.Outputable as Outputable import GHC.Data.Maybe @@ -2088,38 +2085,6 @@ displayUnitId :: PackageState -> UnitId -> Maybe String displayUnitId pkgstate uid = fmap unitPackageIdString (lookupInstalledPackage pkgstate uid) --- | Will the 'Name' come from a dynamically linked package? -isDynLinkName :: Platform -> Module -> Name -> Bool -isDynLinkName platform this_mod name - | Just mod <- nameModule_maybe name - -- Issue #8696 - when GHC is dynamically linked, it will attempt - -- to load the dynamic dependencies of object files at compile - -- time for things like QuasiQuotes or - -- TemplateHaskell. Unfortunately, this interacts badly with - -- intra-package linking, because we don't generate indirect - -- (dynamic) symbols for intra-package calls. This means that if a - -- module with an intra-package call is loaded without its - -- dependencies, then GHC fails to link. - -- - -- In the mean time, always force dynamic indirections to be - -- generated: when the module name isn't the module being - -- compiled, references are dynamic. - = case platformOS platform of - -- On Windows the hack for #8696 makes it unlinkable. - -- As the entire setup of the code from Cmm down to the RTS expects - -- the use of trampolines for the imported functions only when - -- doing intra-package linking, e.g. referring to a symbol defined in the same - -- package should not use a trampoline. - -- I much rather have dynamic TH not supported than the entire Dynamic linking - -- not due to a hack. - -- Also not sure this would break on Windows anyway. - OSMinGW32 -> moduleUnit mod /= moduleUnit this_mod - - -- For the other platforms, still perform the hack - _ -> mod /= this_mod - - | otherwise = False -- no, it is not even an external name - -- ----------------------------------------------------------------------------- -- Displaying packages View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/566cc73f46d67e2b36fda95d0253067bb0ecc12f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/566cc73f46d67e2b36fda95d0253067bb0ecc12f You're receiving 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:35:05 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Thu, 21 May 2020 12:35:05 -0400 Subject: [Git][ghc/ghc][wip/T18078] Implement cast worker/wrapper properly Message-ID: <5ec6adb97ba85_6e2612540ff861665b@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T18078 at Glasgow Haskell Compiler / GHC Commits: a98c4ef9 by Simon Peyton Jones at 2020-05-21T17:34:20+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 also discovered that unsafeCoerce wasn't being inlined if the context was boring. So (\x. f (unsafeCoerce x)) would create a thunk -- yikes! I fixed that by making inlineBoringOK a bit cleverer: see Note [Inline unsafeCoerce] in GHC.Core.Unfold. I also found that unsafeCoerceName was unused, so I removed it. 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% - - - - - 29 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Opt/Driver.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/SimpleOpt.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/Var.hs - libraries/base/Unsafe/Coerce.hs - testsuite/tests/codeGen/should_compile/debug.stdout - testsuite/tests/deSugar/should_compile/T2431.stderr - testsuite/tests/perf/compiler/T16473.stdout - testsuite/tests/simplCore/should_compile/T13143.stderr - testsuite/tests/simplCore/should_compile/T3772.stdout - testsuite/tests/simplCore/should_compile/T7360.stderr - testsuite/tests/simplCore/should_compile/T7865.stdout - testsuite/tests/stranal/should_compile/Makefile - testsuite/tests/stranal/should_compile/T16029.stdout - + testsuite/tests/stranal/should_compile/T17673.hs - + testsuite/tests/stranal/should_compile/T17673.stdout - + testsuite/tests/stranal/should_compile/T18078.hs - + testsuite/tests/stranal/should_compile/T18078.stdout - testsuite/tests/stranal/should_compile/all.T Changes: ===================================== compiler/GHC/Builtin/Names.hs ===================================== @@ -475,7 +475,6 @@ basicKnownKeyNames , unsafeEqualityTyConName , unsafeReflDataConName , unsafeCoercePrimName - , unsafeCoerceName ] genericTyConNames :: [Name] @@ -1333,12 +1332,11 @@ typeErrorShowTypeDataConName = -- Unsafe coercion proofs unsafeEqualityProofName, unsafeEqualityTyConName, unsafeCoercePrimName, - unsafeCoerceName, unsafeReflDataConName :: Name + unsafeReflDataConName :: Name unsafeEqualityProofName = varQual uNSAFE_COERCE (fsLit "unsafeEqualityProof") unsafeEqualityProofIdKey unsafeEqualityTyConName = tcQual uNSAFE_COERCE (fsLit "UnsafeEquality") unsafeEqualityTyConKey unsafeReflDataConName = dcQual uNSAFE_COERCE (fsLit "UnsafeRefl") unsafeReflDataConKey unsafeCoercePrimName = varQual uNSAFE_COERCE (fsLit "unsafeCoerce#") unsafeCoercePrimIdKey -unsafeCoerceName = varQual uNSAFE_COERCE (fsLit "unsafeCoerce") unsafeCoerceIdKey -- Dynamic toDynName :: Name @@ -2411,10 +2409,9 @@ naturalSDataConKey = mkPreludeMiscIdUnique 568 wordToNaturalIdKey = mkPreludeMiscIdUnique 569 -- Unsafe coercion proofs -unsafeEqualityProofIdKey, unsafeCoercePrimIdKey, unsafeCoerceIdKey :: Unique +unsafeEqualityProofIdKey, unsafeCoercePrimIdKey :: Unique unsafeEqualityProofIdKey = mkPreludeMiscIdUnique 570 unsafeCoercePrimIdKey = mkPreludeMiscIdUnique 571 -unsafeCoerceIdKey = mkPreludeMiscIdUnique 572 {- ************************************************************************ ===================================== compiler/GHC/Core/Coercion.hs ===================================== @@ -2187,7 +2187,7 @@ coercionLKind co go (TyConAppCo _ tc cos) = mkTyConApp tc (map go cos) go (AppCo co1 co2) = mkAppTy (go co1) (go co2) go (ForAllCo tv1 _ co1) = mkTyCoInvForAllTy tv1 (go co1) - go (FunCo _ co1 co2) = mkVisFunTy (go co1) (go co2) + go (FunCo _ co1 co2) = mkFunctionType (go co1) (go co2) go (CoVarCo cv) = coVarLType cv go (HoleCo h) = coVarLType (coHoleCoVar h) go (UnivCo _ _ ty1 _) = ty1 @@ -2244,7 +2244,7 @@ coercionRKind co go (AppCo co1 co2) = mkAppTy (go co1) (go co2) go (CoVarCo cv) = coVarRType cv go (HoleCo h) = coVarRType (coHoleCoVar h) - go (FunCo _ co1 co2) = mkVisFunTy (go co1) (go co2) + go (FunCo _ co1 co2) = mkFunctionType (go co1) (go co2) go (UnivCo _ _ _ ty2) = ty2 go (SymCo co) = coercionLKind co go (TransCo _ co2) = go co2 ===================================== compiler/GHC/Core/Opt/Driver.hs ===================================== @@ -37,7 +37,7 @@ import GHC.Core.Opt.FloatOut ( floatOutwards ) import GHC.Core.FamInstEnv import GHC.Types.Id import GHC.Utils.Error ( withTiming, withTimingD, DumpFormat (..) ) -import GHC.Types.Basic ( CompilerPhase(..), isDefaultInlinePragma, defaultInlinePragma ) +import GHC.Types.Basic import GHC.Types.Var.Set import GHC.Types.Var.Env import GHC.Core.Opt.LiberateCase ( liberateCase ) @@ -141,8 +141,10 @@ getCoreToDo dflags maybe_rule_check phase = runMaybe rule_check (CoreDoRuleCheck phase) - maybe_strictness_before phase - = runWhen (phase `elem` strictnessBefore dflags) CoreDoDemand + maybe_strictness_before (Phase phase) + | phase `elem` strictnessBefore dflags = CoreDoDemand + maybe_strictness_before _ + = CoreDoNothing base_mode = SimplMode { sm_phase = panic "base_mode" , sm_names = [] @@ -152,20 +154,20 @@ getCoreToDo dflags , sm_inline = True , sm_case_case = True } - simpl_phase phase names iter + simpl_phase phase name iter = CoreDoPasses $ [ maybe_strictness_before phase , CoreDoSimplify iter - (base_mode { sm_phase = Phase phase - , sm_names = names }) + (base_mode { sm_phase = phase + , sm_names = [name] }) - , maybe_rule_check (Phase phase) ] + , maybe_rule_check phase ] - simpl_phases = CoreDoPasses [ simpl_phase phase ["main"] max_iter - | phase <- [phases, phases-1 .. 1] ] + -- Run GHC's internal simplification phase, after all rules have run. + -- See Note [Compiler phases] in GHC.Types.Basic + simplify name = simpl_phase finalPhase name max_iter - - -- initial simplify: mk specialiser happy: minimum effort please + -- initial simplify: mk specialiser happy: minimum effort please simpl_gently = CoreDoSimplify max_iter (base_mode { sm_phase = InitialPhase , sm_names = ["Gentle"] @@ -182,7 +184,7 @@ getCoreToDo dflags demand_analyser = (CoreDoPasses ( dmd_cpr_ww ++ - [simpl_phase 0 ["post-worker-wrapper"] max_iter] + [simplify "post-worker-wrapper"] )) -- Static forms are moved to the top level with the FloatOut pass. @@ -203,7 +205,7 @@ getCoreToDo dflags if opt_level == 0 then [ static_ptrs_float_outwards, CoreDoSimplify max_iter - (base_mode { sm_phase = Phase 0 + (base_mode { sm_phase = finalPhase , sm_names = ["Non-opt simplification"] }) ] @@ -251,8 +253,10 @@ getCoreToDo dflags -- GHC.Iface.Tidy.StaticPtrTable. static_ptrs_float_outwards, - simpl_phases, - + -- Run the simplier phases 2,1,0 to allow rewrite rules to fire + CoreDoPasses [ simpl_phase (Phase phase) "main" max_iter + | phase <- [phases, phases-1 .. 1] ], + simpl_phase (Phase 0) "main" (max max_iter 3), -- Phase 0: allow all Ids to be inlined now -- This gets foldr inlined before strictness analysis @@ -263,7 +267,6 @@ getCoreToDo dflags -- ==> let k = BIG in letrec go = \xs -> ...(k x).... in go xs -- ==> let k = BIG in letrec go = \xs -> ...(BIG x).... in go xs -- Don't stop now! - simpl_phase 0 ["main"] (max max_iter 3), runWhen do_float_in CoreDoFloatInwards, -- Run float-inwards immediately before the strictness analyser @@ -274,9 +277,10 @@ getCoreToDo dflags runWhen call_arity $ CoreDoPasses [ CoreDoCallArity - , simpl_phase 0 ["post-call-arity"] max_iter + , simplify "post-call-arity" ], + -- Strictness analysis runWhen strictness demand_analyser, runWhen exitification CoreDoExitify, @@ -302,24 +306,24 @@ getCoreToDo dflags runWhen do_float_in CoreDoFloatInwards, - maybe_rule_check (Phase 0), + maybe_rule_check finalPhase, -- Case-liberation for -O2. This should be after -- strictness analysis and the simplification which follows it. runWhen liberate_case (CoreDoPasses [ CoreLiberateCase, - simpl_phase 0 ["post-liberate-case"] max_iter + simplify "post-liberate-case" ]), -- Run the simplifier after LiberateCase to vastly -- reduce the possibility of shadowing -- Reason: see Note [Shadowing] in GHC.Core.Opt.SpecConstr runWhen spec_constr CoreDoSpecConstr, - maybe_rule_check (Phase 0), + maybe_rule_check finalPhase, runWhen late_specialise (CoreDoPasses [ CoreDoSpecialising - , simpl_phase 0 ["post-late-spec"] max_iter]), + , simplify "post-late-spec"]), -- LiberateCase can yield new CSE opportunities because it peels -- off one layer of a recursive function (concretely, I saw this @@ -328,11 +332,10 @@ getCoreToDo dflags runWhen ((liberate_case || spec_constr) && cse) CoreCSE, -- Final clean-up simplification: - simpl_phase 0 ["final"] max_iter, + simplify "final", runWhen late_dmd_anal $ CoreDoPasses ( - dmd_cpr_ww ++ - [simpl_phase 0 ["post-late-ww"] max_iter] + dmd_cpr_ww ++ [simplify "post-late-ww"] ), -- Final run of the demand_analyser, ensures that one-shot thunks are @@ -342,7 +345,7 @@ getCoreToDo dflags -- can become /exponentially/ more expensive. See #11731, #12996. runWhen (strictness || late_dmd_anal) CoreDoDemand, - maybe_rule_check (Phase 0) + maybe_rule_check finalPhase ] -- Remove 'CoreDoNothing' and flatten 'CoreDoPasses' for clarity. ===================================== compiler/GHC/Core/Opt/Simplify.hs ===================================== @@ -43,12 +43,15 @@ import GHC.Types.Cpr ( mkCprSig, botCpr ) import GHC.Core.Ppr ( pprCoreExpr ) import GHC.Core.Unfold import GHC.Core.Utils +import GHC.Core.Arity ( etaExpand ) import GHC.Core.SimpleOpt ( pushCoTyArg, pushCoValArg , joinPointBinding_maybe, joinPointBindings_maybe ) import GHC.Core.FVs ( mkRuleInfo ) import GHC.Core.Rules ( lookupRule, getRules ) import GHC.Types.Basic ( TopLevelFlag(..), isNotTopLevel, isTopLevel, - RecFlag(..), Arity ) + RecFlag(..), InlinePragma(..), Activation(..), + SourceText(..), InlineSpec(..), activeDuringFinal, + Arity ) import GHC.Utils.Monad ( mapAccumLM, liftIO ) import GHC.Types.Var ( isTyCoVar ) import GHC.Data.Maybe ( orElse ) @@ -315,8 +318,8 @@ simplLazyBind env top_lvl is_rec bndr bndr1 rhs rhs_se -- ANF-ise a constructor or PAP rhs -- We get at most one float per argument here - ; (let_floats, body2) <- {-#SCC "prepareRhs" #-} prepareRhs (getMode env) top_lvl - (getOccFS bndr1) (idInfo bndr1) body1 + ; (let_floats, bndr2, body2) <- {-#SCC "prepareRhs" #-} + prepareBinding env top_lvl bndr bndr1 body1 ; let body_floats2 = body_floats1 `addLetFloats` let_floats ; (rhs_floats, rhs') @@ -341,7 +344,7 @@ simplLazyBind env top_lvl is_rec bndr bndr1 rhs rhs_se ; return (floats, rhs') } ; (bind_float, env2) <- completeBind (env `setInScopeFromF` rhs_floats) - top_lvl Nothing bndr bndr1 rhs' + top_lvl Nothing bndr bndr2 rhs' ; return (rhs_floats `addFloats` bind_float, env2) } -------------------------- @@ -393,16 +396,16 @@ completeNonRecX :: TopLevelFlag -> SimplEnv completeNonRecX top_lvl env is_strict old_bndr new_bndr new_rhs = ASSERT2( not (isJoinId new_bndr), ppr new_bndr ) - do { (prepd_floats, rhs1) <- prepareRhs (getMode env) top_lvl (getOccFS new_bndr) - (idInfo new_bndr) new_rhs + do { (prepd_floats, new_bndr, new_rhs) + <- prepareBinding env top_lvl old_bndr new_bndr new_rhs ; let floats = emptyFloats env `addLetFloats` prepd_floats ; (rhs_floats, rhs2) <- - if doFloatFromRhs NotTopLevel NonRecursive is_strict floats rhs1 + if doFloatFromRhs NotTopLevel NonRecursive is_strict floats new_rhs then -- Add the floats to the main env do { tick LetFloatFromLet - ; return (floats, rhs1) } + ; return (floats, new_rhs) } else -- Do not float; wrap the floats around the RHS - return (emptyFloats env, wrapFloats floats rhs1) + return (emptyFloats env, wrapFloats floats new_rhs) ; (bind_float, env2) <- completeBind (env `setInScopeFromF` rhs_floats) NotTopLevel Nothing @@ -412,12 +415,130 @@ completeNonRecX top_lvl env is_strict old_bndr new_bndr new_rhs {- ********************************************************************* * * - prepareRhs, makeTrivial + prepareBinding, prepareRhs, makeTrivial * * ************************************************************************ -Note [prepareRhs] -~~~~~~~~~~~~~~~~~ +Note [Cast worker/wrappers] +~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When we have a binding + x = e |> co +we want to do something very similar to worker/wrapper: + y = e + x = y |> co + +So now x can be inlined freely. There's a chance that e will be a +constructor application or function, or something like that, so moving +the coercion to the usage site may well cancel the coercions and lead +to further optimisation. Example: + + data family T a :: * + data instance T Int = T Int + + foo :: Int -> Int -> Int + foo m n = ... + where + x = T m + go 0 = 0 + go n = case x of { T m -> go (n-m) } + -- This case should optimise + +We call this making a cast worker/wrapper, and it'd done by prepareBinding. + +We need to be careful with the inline pragma on x. Suppose 'x' is +marked NOINLINE. Then we want to move that pragma to 'y', and remove +it from 'x'. If we fail to remove it from 'x' we get something like + + rec { $wy {-# NOINLINE #-} = ... x... + ; y = ... -- wrapper + ; x {-# NOINLINE #-} = y |> co } + +and now the recursive calls to x in $wy will not optimise properly. +In effect 'x' has become the wrapper, and must inline freely, while +'y' is the worker, and must carry x's INLINE pragma. See Note +[Worker-wrapper for NOINLINE functions] in GHC.Core.Opt.WorkWrap. +See #17673, #18093, #18078. + +Note [Preserve strictness in cast w/w] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In the Note [Float coercions] transformation, keep the strictness info. +Eg + f = e `cast` co -- f has strictness SSL +When we transform to + f' = e -- f' also has strictness SSL + f = f' `cast` co -- f still has strictness SSL + +Its not wrong to drop it on the floor, but better to keep it. + +Note [Cast w/w: unlifted] +~~~~~~~~~~~~~~~~~~~~~~~~~ +BUT don't do cast worker/wrapper if 'e' has an unlifted type. +This *can* happen: + + foo :: Int = (error (# Int,Int #) "urk") + `cast` CoUnsafe (# Int,Int #) Int + +If do the makeTrivial thing to the error call, we'll get + foo = case error (# Int,Int #) "urk" of v -> v `cast` ... +But 'v' isn't in scope! + +These strange casts can happen as a result of case-of-case + bar = case (case x of { T -> (# 2,3 #); F -> error "urk" }) of + (# p,q #) -> p+q + +NOTE: Nowadays we don't use casts for these error functions; +instead, we use (case erorr ... of {}). So I'm not sure +this Note makes much sense any more. +-} + +prepareBinding :: SimplEnv -> TopLevelFlag + -> InId -> OutId -> OutExpr + -> SimplM (LetFloats, OutId, OutExpr) + +prepareBinding env top_lvl old_bndr bndr rhs + | Cast rhs1 co <- rhs + -- Try for cast worker/wrapper + -- See Note [Cast worker/wrappers] + , not (isStableUnfolding (realIdUnfolding old_bndr)) + -- Don't make a cast w/w if the thing is going to be inlined anyway + , not (exprIsTrivial rhs1) + -- Nor if the RHS is trivial; then again it'll be inlined + , let ty1 = coercionLKind co + , not (isUnliftedType ty1) + -- Not if rhs has an unlifted type; see Note [Float coercions (unlifted)] + = do { (floats, new_id) <- makeTrivialBinding (getMode env) top_lvl + (getOccFS bndr) worker_info rhs1 ty1 + ; let bndr' = bndr `setInlinePragma` mkCastWrapperInlinePrag (idInlinePragma bndr) + ; return (floats, bndr', Cast (Var new_id) co) } + + | otherwise + = do { (floats, rhs') <- prepareRhs (getMode env) top_lvl (getOccFS bndr) rhs + ; return (floats, bndr, rhs') } + where + info = idInfo bndr + worker_info = vanillaIdInfo `setStrictnessInfo` strictnessInfo info + `setCprInfo` cprInfo info + `setDemandInfo` demandInfo info + `setInlinePragInfo` inlinePragInfo info + `setArityInfo` arityInfo info + -- We do /not/ want to transfer OccInfo, Rules, Unfolding + -- Note [Preserve strictness in cast w/w] + +mkCastWrapperInlinePrag :: InlinePragma -> InlinePragma +-- See Note [Cast wrappers] +mkCastWrapperInlinePrag (InlinePragma { inl_act = act, inl_rule = rule_info }) + = InlinePragma { inl_src = SourceText "{-# INLINE" + , inl_inline = NoUserInline -- See Note [Wrapper NoUserInline] + , inl_sat = Nothing + , inl_act = wrap_act -- See Note [Wrapper activation] + , inl_rule = rule_info } -- RuleMatchInfo is (and must be) unaffected + where + wrap_act = case act of -- See Note [Wrapper activation] + NeverActive -> activeDuringFinal -- Inline late because of rules + _ -> act + +{- Note [prepareRhs] +~~~~~~~~~~~~~~~~~~~~ prepareRhs takes a putative RHS, checks whether it's a PAP or constructor application and, if so, converts it to ANF, so that the resulting thing can be inlined more easily. Thus @@ -435,26 +556,16 @@ That's what the 'go' loop in prepareRhs does -} prepareRhs :: SimplMode -> TopLevelFlag - -> FastString -- Base for any new variables - -> IdInfo -- IdInfo for the LHS of this binding + -> FastString -- Base for any new variables -> OutExpr -> SimplM (LetFloats, OutExpr) --- Transforms a RHS into a better RHS by adding floats +-- Transforms a RHS into a better RHS by ANF'ing args +-- for expandable RHSs: constructors and PAPs -- e.g x = Just e -- becomes a = e -- x = Just a -- See Note [prepareRhs] -prepareRhs mode top_lvl occ info (Cast rhs co) -- Note [Float coercions] - | let ty1 = coercionLKind co -- Do *not* do this if rhs has an unlifted type - , not (isUnliftedType ty1) -- see Note [Float coercions (unlifted)] - = do { (floats, rhs') <- makeTrivialWithInfo mode top_lvl occ sanitised_info rhs - ; return (floats, Cast rhs' co) } - where - sanitised_info = vanillaIdInfo `setStrictnessInfo` strictnessInfo info - `setCprInfo` cprInfo info - `setDemandInfo` demandInfo info - -prepareRhs mode top_lvl occ _ rhs0 +prepareRhs mode top_lvl occ rhs0 = do { (_is_exp, floats, rhs1) <- go 0 rhs0 ; return (floats, rhs1) } where @@ -498,61 +609,10 @@ prepareRhs mode top_lvl occ _ rhs0 go _ other = return (False, emptyLetFloats, other) -{- -Note [Float coercions] -~~~~~~~~~~~~~~~~~~~~~~ -When we find the binding - x = e `cast` co -we'd like to transform it to - x' = e - x = x `cast` co -- A trivial binding -There's a chance that e will be a constructor application or function, or something -like that, so moving the coercion to the usage site may well cancel the coercions -and lead to further optimisation. Example: - - data family T a :: * - data instance T Int = T Int - - foo :: Int -> Int -> Int - foo m n = ... - where - x = T m - go 0 = 0 - go n = case x of { T m -> go (n-m) } - -- This case should optimise - -Note [Preserve strictness when floating coercions] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -In the Note [Float coercions] transformation, keep the strictness info. -Eg - f = e `cast` co -- f has strictness SSL -When we transform to - f' = e -- f' also has strictness SSL - f = f' `cast` co -- f still has strictness SSL - -Its not wrong to drop it on the floor, but better to keep it. - -Note [Float coercions (unlifted)] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -BUT don't do [Float coercions] if 'e' has an unlifted type. -This *can* happen: - - foo :: Int = (error (# Int,Int #) "urk") - `cast` CoUnsafe (# Int,Int #) Int - -If do the makeTrivial thing to the error call, we'll get - foo = case error (# Int,Int #) "urk" of v -> v `cast` ... -But 'v' isn't in scope! - -These strange casts can happen as a result of case-of-case - bar = case (case x of { T -> (# 2,3 #); F -> error "urk" }) of - (# p,q #) -> p+q --} - makeTrivialArg :: SimplMode -> ArgSpec -> SimplM (LetFloats, ArgSpec) -makeTrivialArg mode (ValArg e) +makeTrivialArg mode arg@(ValArg { as_arg = e }) = do { (floats, e') <- makeTrivial mode NotTopLevel (fsLit "arg") e - ; return (floats, ValArg e') } + ; return (floats, arg { as_arg = e' }) } makeTrivialArg _ arg = return (emptyLetFloats, arg) -- CastBy, TyArg @@ -561,29 +621,32 @@ makeTrivial :: SimplMode -> TopLevelFlag -> OutExpr -- ^ This expression satisfies the let/app invariant -> SimplM (LetFloats, OutExpr) -- Binds the expression to a variable, if it's not trivial, returning the variable -makeTrivial mode top_lvl context expr - = makeTrivialWithInfo mode top_lvl context vanillaIdInfo expr - -makeTrivialWithInfo :: SimplMode -> TopLevelFlag - -> FastString -- ^ a "friendly name" to build the new binder from - -> IdInfo - -> OutExpr -- ^ This expression satisfies the let/app invariant - -> SimplM (LetFloats, OutExpr) --- Propagate strictness and demand info to the new binder --- Note [Preserve strictness when floating coercions] --- Returned SimplEnv has same substitution as incoming one -makeTrivialWithInfo mode top_lvl occ_fs info expr +makeTrivial mode top_lvl occ_fs expr | exprIsTrivial expr -- Already trivial || not (bindingOk top_lvl expr expr_ty) -- Cannot trivialise -- See Note [Cannot trivialise] = return (emptyLetFloats, expr) + | Cast expr' co <- expr + = do { (floats, triv_expr) <- makeTrivial mode top_lvl occ_fs expr' + ; return (floats, Cast triv_expr co) } + | otherwise - = do { (floats, expr1) <- prepareRhs mode top_lvl occ_fs info expr - ; if exprIsTrivial expr1 -- See Note [Trivial after prepareRhs] - then return (floats, expr1) - else do - { uniq <- getUniqueM + = do { (floats, new_id) <- makeTrivialBinding mode top_lvl occ_fs + vanillaIdInfo expr expr_ty + ; return (floats, Var new_id) } + where + expr_ty = exprType expr + +makeTrivialBinding :: SimplMode -> TopLevelFlag + -> FastString -- ^ a "friendly name" to build the new binder from + -> IdInfo + -> OutExpr -- ^ This expression satisfies the let/app invariant + -> OutType -- Type of the expression + -> SimplM (LetFloats, OutId) +makeTrivialBinding mode top_lvl occ_fs info expr expr_ty + = do { (floats, expr1) <- prepareRhs mode top_lvl occ_fs expr + ; uniq <- getUniqueM ; let name = mkSystemVarName uniq occ_fs var = mkLocalIdWithInfo name expr_ty info @@ -595,9 +658,7 @@ makeTrivialWithInfo mode top_lvl occ_fs info expr ; let final_id = addLetBndrInfo var arity is_bot unf bind = NonRec final_id expr2 - ; return ( floats `addLetFlts` unitLetFloat bind, Var final_id ) }} - where - expr_ty = exprType expr + ; return ( floats `addLetFlts` unitLetFloat bind, final_id ) } bindingOk :: TopLevelFlag -> CoreExpr -> Type -> Bool -- True iff we can have a binding of this expression at this level @@ -606,15 +667,8 @@ bindingOk top_lvl expr expr_ty | isTopLevel top_lvl = exprIsTopLevelBindable expr expr_ty | otherwise = True -{- Note [Trivial after prepareRhs] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If we call makeTrival on (e |> co), the recursive use of prepareRhs -may leave us with - { a1 = e } and (a1 |> co) -Now the latter is trivial, so we don't want to let-bind it. - -Note [Cannot trivialise] -~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [Cannot trivialise] +~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider: f :: Int -> Addr# @@ -696,7 +750,7 @@ completeBind env top_lvl mb_cont old_bndr new_bndr new_rhs -- Simplify the unfolding ; new_unfolding <- simplLetUnfolding env top_lvl mb_cont old_bndr - final_rhs (idType new_bndr) old_unf + final_rhs (idType new_bndr) new_arity old_unf ; let final_bndr = addLetBndrInfo new_bndr new_arity is_bot new_unfolding -- See Note [In-scope set as a substitution] @@ -928,6 +982,7 @@ simplExprF1 env (App fun arg) cont , sc_cont = cont } } _ -> simplExprF env fun $ ApplyToVal { sc_arg = arg, sc_env = env + , sc_hole_ty = substTy env (exprType fun) , sc_dup = NoDup, sc_cont = cont } simplExprF1 env expr@(Lam {}) cont @@ -1232,8 +1287,8 @@ rebuild env expr cont Select { sc_bndr = bndr, sc_alts = alts, sc_env = se, sc_cont = cont } -> rebuildCase (se `setInScopeFromE` env) expr bndr alts cont - StrictArg { sc_fun = fun, sc_cont = cont } - -> rebuildCall env (fun `addValArgTo` expr) cont + StrictArg { sc_fun = fun, sc_cont = cont, sc_fun_ty = fun_ty } + -> rebuildCall env (addValArgTo fun expr fun_ty ) cont StrictBind { sc_bndr = b, sc_bndrs = bs, sc_body = body , sc_env = se, sc_cont = cont } -> do { (floats1, env') <- simplNonRecX (se `setInScopeFromE` env) b expr @@ -1271,7 +1326,7 @@ In particular, we want to behave well on * (f |> co) @t1 @t2 ... @tn x1 .. xm - Here we wil use pushCoTyArg and pushCoValArg successively, which + Here we will use pushCoTyArg and pushCoValArg successively, which build up NthCo stacks. Silly to do that if co is reflexive. However, we don't want to call isReflexiveCo too much, because it uses @@ -1310,20 +1365,20 @@ simplCast env body co0 cont0 where co' = mkTransCo co1 co2 - addCoerce co cont@(ApplyToTy { sc_arg_ty = arg_ty, sc_cont = tail }) + addCoerce co (ApplyToTy { sc_arg_ty = arg_ty, sc_cont = tail }) | Just (arg_ty', m_co') <- pushCoTyArg co arg_ty - -- N.B. As mentioned in Note [The hole type in ApplyToTy] this is - -- only needed by `sc_hole_ty` which is often not forced. - -- Consequently it is worthwhile using a lazy pattern match here to - -- avoid unnecessary coercionKind evaluations. - , let hole_ty = coercionLKind co = {-#SCC "addCoerce-pushCoTyArg" #-} do { tail' <- addCoerceM m_co' tail - ; return (cont { sc_arg_ty = arg_ty' - , sc_hole_ty = hole_ty -- NB! As the cast goes past, the - -- type of the hole changes (#16312) - , sc_cont = tail' }) } - + ; return (ApplyToTy { sc_arg_ty = arg_ty' + , sc_cont = tail' + , sc_hole_ty = coercionLKind co }) } + -- NB! As the cast goes past, the + -- type of the hole changes (#16312) + + -- (f |> co) e ===> (f (e |> co1)) |> co2 + -- where co :: (s1->s2) ~ (t1~t2) + -- co1 :: t1 ~ s1 + -- co2 :: s2 ~ t2 addCoerce co cont@(ApplyToVal { sc_arg = arg, sc_env = arg_se , sc_dup = dup, sc_cont = tail }) | Just (co1, m_co2) <- pushCoValArg co @@ -1347,7 +1402,8 @@ simplCast env body co0 cont0 ; return (ApplyToVal { sc_arg = mkCast arg' co1 , sc_env = arg_se' , sc_dup = dup' - , sc_cont = tail' }) } } + , sc_cont = tail' + , sc_hole_ty = coercionLKind co }) } } addCoerce co cont | isReflexiveCo co = return cont -- Having this at the end makes a huge @@ -1426,7 +1482,7 @@ simplLamBndr env bndr | isId bndr && hasCoreUnfolding old_unf -- Special case = do { (env1, bndr1) <- simplBinder env bndr ; unf' <- simplStableUnfolding env1 NotTopLevel Nothing bndr - old_unf (idType bndr1) + (idType bndr1) (idArity bndr1) old_unf ; let bndr2 = bndr1 `setIdUnfolding` unf' ; return (modifyInScope env1 bndr2, bndr2) } @@ -1874,22 +1930,24 @@ rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args rebuildCall env info (CastIt co cont) = rebuildCall env (addCastTo info co) cont -rebuildCall env info (ApplyToTy { sc_arg_ty = arg_ty, sc_cont = cont }) - = rebuildCall env (addTyArgTo info arg_ty) cont +rebuildCall env info (ApplyToTy { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_cont = cont }) + = rebuildCall env (addTyArgTo info arg_ty hole_ty) cont -rebuildCall env info@(ArgInfo { ai_encl = encl_rules, ai_type = fun_ty +rebuildCall env info@(ArgInfo { ai_encl = encl_rules , ai_strs = str:strs, ai_discs = disc:discs }) (ApplyToVal { sc_arg = arg, sc_env = arg_se - , sc_dup = dup_flag, sc_cont = cont }) + , sc_dup = dup_flag, sc_hole_ty = fun_ty + , sc_cont = cont }) | isSimplified dup_flag -- See Note [Avoid redundant simplification] - = rebuildCall env (addValArgTo info' arg) cont + = rebuildCall env (addValArgTo info' arg fun_ty) cont | str -- Strict argument , sm_case_case (getMode env) = -- pprTrace "Strict Arg" (ppr arg $$ ppr (seIdSubst env) $$ ppr (seInScope env)) $ simplExprF (arg_se `setInScopeFromE` env) arg (StrictArg { sc_fun = info', sc_cci = cci_strict - , sc_dup = Simplified, sc_cont = cont }) + , sc_dup = Simplified, sc_fun_ty = fun_ty + , sc_cont = cont }) -- Note [Shadowing] | otherwise -- Lazy argument @@ -1899,7 +1957,7 @@ rebuildCall env info@(ArgInfo { ai_encl = encl_rules, ai_type = fun_ty -- floating a demanded let. = do { arg' <- simplExprC (arg_se `setInScopeFromE` env) arg (mkLazyArgStop arg_ty cci_lazy) - ; rebuildCall env (addValArgTo info' arg') cont } + ; rebuildCall env (addValArgTo info' arg' fun_ty) cont } where info' = info { ai_strs = strs, ai_discs = discs } arg_ty = funArgTy fun_ty @@ -2107,9 +2165,11 @@ trySeqRules in_env scrut rhs cont where no_cast_scrut = drop_casts scrut scrut_ty = exprType no_cast_scrut - seq_id_ty = idType seqId - res1_ty = piResultTy seq_id_ty rhs_rep - res2_ty = piResultTy res1_ty scrut_ty + seq_id_ty = idType seqId -- forall r a (b::TYPE r). a -> b -> b + res1_ty = piResultTy seq_id_ty rhs_rep -- forall a (b::TYPE rhs_rep). a -> b -> b + res2_ty = piResultTy res1_ty scrut_ty -- forall (b::TYPE rhs_rep). scrut_ty -> b -> b + res3_ty = piResultTy res2_ty rhs_ty -- scrut_ty -> rhs_ty -> rhs_ty + res4_ty = funResultTy res3_ty -- rhs_ty -> rhs_ty rhs_ty = substTy in_env (exprType rhs) rhs_rep = getRuntimeRep rhs_ty out_args = [ TyArg { as_arg_ty = rhs_rep @@ -2118,9 +2178,11 @@ trySeqRules in_env scrut rhs cont , as_hole_ty = res1_ty } , TyArg { as_arg_ty = rhs_ty , as_hole_ty = res2_ty } - , ValArg no_cast_scrut] + , ValArg { as_arg = no_cast_scrut + , as_hole_ty = res3_ty } ] rule_cont = ApplyToVal { sc_dup = NoDup, sc_arg = rhs - , sc_env = in_env, sc_cont = cont } + , sc_env = in_env, sc_cont = cont + , sc_hole_ty = res4_ty } -- Lazily evaluated, so we don't do most of this drop_casts (Cast e _) = drop_casts e @@ -3110,7 +3172,8 @@ mkDupableCont env (StrictBind { sc_bndr = bndr, sc_bndrs = bndrs , sc_dup = OkToDup , sc_cont = mkBoringStop res_ty } ) } -mkDupableCont env (StrictArg { sc_fun = info, sc_cci = cci, sc_cont = cont }) +mkDupableCont env (StrictArg { sc_fun = info, sc_cci = cci + , sc_cont = cont, sc_fun_ty = fun_ty }) -- See Note [Duplicating StrictArg] -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable = do { (floats1, cont') <- mkDupableCont env cont @@ -3118,8 +3181,9 @@ mkDupableCont env (StrictArg { sc_fun = info, sc_cci = cci, sc_cont = cont }) (ai_args info) ; return ( foldl' addLetFloats floats1 floats_s , StrictArg { sc_fun = info { ai_args = args' } - , sc_cci = cci , sc_cont = cont' + , sc_cci = cci + , sc_fun_ty = fun_ty , sc_dup = OkToDup} ) } mkDupableCont env (ApplyToTy { sc_cont = cont @@ -3129,7 +3193,8 @@ mkDupableCont env (ApplyToTy { sc_cont = cont , sc_arg_ty = arg_ty, sc_hole_ty = hole_ty }) } mkDupableCont env (ApplyToVal { sc_arg = arg, sc_dup = dup - , sc_env = se, sc_cont = cont }) + , sc_env = se, sc_cont = cont + , sc_hole_ty = hole_ty }) = -- e.g. [...hole...] (...arg...) -- ==> -- let a = ...arg... @@ -3147,7 +3212,8 @@ mkDupableCont env (ApplyToVal { sc_arg = arg, sc_dup = dup -- arg'' in its in-scope set, even if makeTrivial -- has turned arg'' into a fresh variable -- See Note [StaticEnv invariant] in GHC.Core.Opt.Simplify.Utils - , sc_dup = OkToDup, sc_cont = cont' }) } + , sc_dup = OkToDup, sc_cont = cont' + , sc_hole_ty = hole_ty }) } mkDupableCont env (Select { sc_bndr = case_bndr, sc_alts = alts , sc_env = se, sc_cont = cont }) @@ -3491,11 +3557,11 @@ because we don't know its usage in each RHS separately simplLetUnfolding :: SimplEnv-> TopLevelFlag -> MaybeJoinCont -> InId - -> OutExpr -> OutType + -> OutExpr -> OutType -> Arity -> Unfolding -> SimplM Unfolding -simplLetUnfolding env top_lvl cont_mb id new_rhs rhs_ty unf +simplLetUnfolding env top_lvl cont_mb id new_rhs rhs_ty arity unf | isStableUnfolding unf - = simplStableUnfolding env top_lvl cont_mb id unf rhs_ty + = simplStableUnfolding env top_lvl cont_mb id rhs_ty arity unf | isExitJoinId id = return noUnfolding -- See Note [Do not inline exit join points] in GHC.Core.Opt.Exitify | otherwise @@ -3521,9 +3587,10 @@ mkLetUnfolding dflags top_lvl src id new_rhs simplStableUnfolding :: SimplEnv -> TopLevelFlag -> MaybeJoinCont -- Just k => a join point with continuation k -> InId - -> Unfolding -> OutType -> SimplM Unfolding + -> OutType -> Arity -> Unfolding + ->SimplM Unfolding -- Note [Setting the new unfolding] -simplStableUnfolding env top_lvl mb_cont id unf rhs_ty +simplStableUnfolding env top_lvl mb_cont id rhs_ty id_arity unf = case unf of NoUnfolding -> return unf BootUnfolding -> return unf @@ -3538,7 +3605,8 @@ simplStableUnfolding env top_lvl mb_cont id unf rhs_ty | isStableSource src -> do { expr' <- case mb_cont of -- See Note [Rules and unfolding for join points] Just cont -> simplJoinRhs unf_env id expr cont - Nothing -> simplExprC unf_env expr (mkBoringStop rhs_ty) + Nothing -> do { expr' <- simplExprC unf_env expr (mkBoringStop rhs_ty) + ; return (eta_expand expr') } ; case guide of UnfWhen { ug_arity = arity , ug_unsat_ok = sat_ok @@ -3575,7 +3643,40 @@ simplStableUnfolding env top_lvl mb_cont id unf rhs_ty unf_env = updMode (updModeForStableUnfoldings act) env -- See Note [Simplifying inside stable unfoldings] in GHC.Core.Opt.Simplify.Utils -{- + -- See Note [Eta-expand stable unfoldings] + eta_expand expr + | not eta_on = expr + | exprIsTrivial expr = expr + | otherwise = etaExpand id_arity expr + eta_on = sm_eta_expand (getMode env) + +{- Note [Eta-expand stable unfoldings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +For INLINE/INLINABLE things (which get stable unfoldings) there's a danger +of getting + f :: Int -> Int -> Int -> Blah + [ Arity = 3 -- Good arity + , Unf=Stable (\xy. blah) -- Less good arity, only 2 + f = \pqr. e + +This can happen because f's RHS is optimised more vigorously than +its stable unfolding. Now suppose we have a call + g = f x +Because f has arity=3, g will have arity=2. But if we inline f (using +its stable unfolding) g's arity will reduce to 1, because +hasn't been optimised yet. This happened in the 'parsec' library, +for Text.Pasec.Char.string. + +Generally, if we know that 'f' has arity N, it seems sensible to +eta-expand the stable unfolding to arity N too. Simple and consistent. + +Wrinkles +* Don't eta-expand a trivial expr, else each pass will eta-reduce it, + and then eta-expand again. See Note [Do not eta-expand trivial expressions] + in GHC.Core.Opt.Simplify.Utils. +* Don't eta-expand join points; see Note [Do not eta-expand join points] + in GHC.Core.Opt.Simplify.Utils. + Note [Force bottoming field] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We need to force bottoming, or the new unfolding holds ===================================== compiler/GHC/Core/Opt/Simplify/Utils.hs ===================================== @@ -118,7 +118,9 @@ data SimplCont SimplCont | ApplyToVal -- (ApplyToVal arg K)[e] = K[ e arg ] - { sc_dup :: DupFlag -- See Note [DupFlag invariants] + { sc_dup :: DupFlag -- See Note [DupFlag invariants] + , sc_hole_ty :: OutType -- Type of the function, presumably (forall a. blah) + -- See Note [The hole type in ApplyToTy/Val] , sc_arg :: InExpr -- The argument, , sc_env :: StaticEnv -- see Note [StaticEnv invariant] , sc_cont :: SimplCont } @@ -126,7 +128,7 @@ data SimplCont | ApplyToTy -- (ApplyToTy ty K)[e] = K[ e ty ] { sc_arg_ty :: OutType -- Argument type , sc_hole_ty :: OutType -- Type of the function, presumably (forall a. blah) - -- See Note [The hole type in ApplyToTy] + -- See Note [The hole type in ApplyToTy/Val] , sc_cont :: SimplCont } | Select -- (Select alts K)[e] = K[ case e of alts ] @@ -151,6 +153,9 @@ data SimplCont , sc_fun :: ArgInfo -- Specifies f, e1..en, Whether f has rules, etc -- plus strictness flags for *further* args , sc_cci :: CallCtxt -- Whether *this* argument position is interesting + , sc_fun_ty :: OutType -- Type of the function (f e1 .. en), + -- presumably (arg_ty -> res_ty) + -- where res_ty is expected by sc_cont , sc_cont :: SimplCont } | TickIt -- (TickIt t K)[e] = K[ tick t e ] @@ -254,8 +259,6 @@ data ArgInfo ai_fun :: OutId, -- The function ai_args :: [ArgSpec], -- ...applied to these args (which are in *reverse* order) - ai_type :: OutType, -- Type of (f a1 ... an) - ai_rules :: FunRules, -- Rules for this function ai_encl :: Bool, -- Flag saying whether this function @@ -271,37 +274,36 @@ data ArgInfo } data ArgSpec - = ValArg OutExpr -- Apply to this (coercion or value); c.f. ApplyToVal + = ValArg { as_arg :: OutExpr -- Apply to this (coercion or value); c.f. ApplyToVal + , as_hole_ty :: OutType } -- Type of the function (presumably t1 -> t2) | TyArg { as_arg_ty :: OutType -- Apply to this type; c.f. ApplyToTy , as_hole_ty :: OutType } -- Type of the function (presumably forall a. blah) | CastBy OutCoercion -- Cast by this; c.f. CastIt instance Outputable ArgSpec where - ppr (ValArg e) = text "ValArg" <+> ppr e + ppr (ValArg { as_arg = arg }) = text "ValArg" <+> ppr arg ppr (TyArg { as_arg_ty = ty }) = text "TyArg" <+> ppr ty ppr (CastBy c) = text "CastBy" <+> ppr c -addValArgTo :: ArgInfo -> OutExpr -> ArgInfo -addValArgTo ai arg = ai { ai_args = ValArg arg : ai_args ai - , ai_type = applyTypeToArg (ai_type ai) arg - , ai_rules = decRules (ai_rules ai) } +addValArgTo :: ArgInfo -> OutExpr -> OutType -> ArgInfo +addValArgTo ai arg hole_ty = ai { ai_args = arg_spec : ai_args ai + , ai_rules = decRules (ai_rules ai) } + where + arg_spec = ValArg { as_arg = arg, as_hole_ty = hole_ty } -addTyArgTo :: ArgInfo -> OutType -> ArgInfo -addTyArgTo ai arg_ty = ai { ai_args = arg_spec : ai_args ai - , ai_type = piResultTy poly_fun_ty arg_ty - , ai_rules = decRules (ai_rules ai) } +addTyArgTo :: ArgInfo -> OutType -> OutType -> ArgInfo +addTyArgTo ai arg_ty hole_ty = ai { ai_args = arg_spec : ai_args ai + , ai_rules = decRules (ai_rules ai) } where - poly_fun_ty = ai_type ai - arg_spec = TyArg { as_arg_ty = arg_ty, as_hole_ty = poly_fun_ty } + arg_spec = TyArg { as_arg_ty = arg_ty, as_hole_ty = hole_ty } addCastTo :: ArgInfo -> OutCoercion -> ArgInfo -addCastTo ai co = ai { ai_args = CastBy co : ai_args ai - , ai_type = coercionRKind co } +addCastTo ai co = ai { ai_args = CastBy co : ai_args ai } argInfoAppArgs :: [ArgSpec] -> [OutExpr] argInfoAppArgs [] = [] argInfoAppArgs (CastBy {} : _) = [] -- Stop at a cast -argInfoAppArgs (ValArg e : as) = e : argInfoAppArgs as +argInfoAppArgs (ValArg { as_arg = arg } : as) = arg : argInfoAppArgs as argInfoAppArgs (TyArg { as_arg_ty = ty } : as) = Type ty : argInfoAppArgs as pushSimplifiedArgs :: SimplEnv -> [ArgSpec] -> SimplCont -> SimplCont @@ -310,7 +312,9 @@ pushSimplifiedArgs env (arg : args) k = case arg of TyArg { as_arg_ty = arg_ty, as_hole_ty = hole_ty } -> ApplyToTy { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_cont = rest } - ValArg e -> ApplyToVal { sc_arg = e, sc_env = env, sc_dup = Simplified, sc_cont = rest } + ValArg { as_arg = arg, as_hole_ty = hole_ty } + -> ApplyToVal { sc_arg = arg, sc_env = env, sc_dup = Simplified + , sc_hole_ty = hole_ty, sc_cont = rest } CastBy c -> CastIt c rest where rest = pushSimplifiedArgs env args k @@ -323,7 +327,7 @@ argInfoExpr fun rev_args = go rev_args where go [] = Var fun - go (ValArg a : as) = go as `App` a + go (ValArg { as_arg = arg } : as) = go as `App` arg go (TyArg { as_arg_ty = ty } : as) = go as `App` Type ty go (CastBy co : as) = mkCast (go as) co @@ -409,11 +413,9 @@ contHoleType (TickIt _ k) = contHoleType k contHoleType (CastIt co _) = coercionLKind co contHoleType (StrictBind { sc_bndr = b, sc_dup = dup, sc_env = se }) = perhapsSubstTy dup se (idType b) -contHoleType (StrictArg { sc_fun = ai }) = funArgTy (ai_type ai) -contHoleType (ApplyToTy { sc_hole_ty = ty }) = ty -- See Note [The hole type in ApplyToTy] -contHoleType (ApplyToVal { sc_arg = e, sc_env = se, sc_dup = dup, sc_cont = k }) - = mkVisFunTy (perhapsSubstTy dup se (exprType e)) - (contHoleType k) +contHoleType (StrictArg { sc_fun_ty = ty }) = funArgTy ty +contHoleType (ApplyToTy { sc_hole_ty = ty }) = ty -- See Note [The hole type in ApplyToTy/Val] +contHoleType (ApplyToVal { sc_hole_ty = ty }) = ty -- See Note [The hole type in ApplyToTy/Val] contHoleType (Select { sc_dup = d, sc_bndr = b, sc_env = se }) = perhapsSubstTy d se (idType b) @@ -458,13 +460,13 @@ mkArgInfo :: SimplEnv mkArgInfo env fun rules n_val_args call_cont | n_val_args < idArity fun -- Note [Unsaturated functions] - = ArgInfo { ai_fun = fun, ai_args = [], ai_type = fun_ty + = ArgInfo { ai_fun = fun, ai_args = [] , ai_rules = fun_rules , ai_encl = False , ai_strs = vanilla_stricts , ai_discs = vanilla_discounts } | otherwise - = ArgInfo { ai_fun = fun, ai_args = [], ai_type = fun_ty + = ArgInfo { ai_fun = fun, ai_args = [] , ai_rules = fun_rules , ai_encl = interestingArgContext rules call_cont , ai_strs = arg_stricts @@ -1076,7 +1078,7 @@ seems to be to do a callSiteInline based on the fact that there is something interesting about the call site (it's strict). Hmm. That seems a bit fragile. -Conclusion: inline top level things gaily until Phase 0 (the last +Conclusion: inline top level things gaily until finalPhase (the last phase), at which point don't. Note [pre/postInlineUnconditionally in gentle mode] @@ -1199,23 +1201,21 @@ preInlineUnconditionally env top_lvl bndr rhs rhs_env -- not ticks. Counting ticks cannot be duplicated, and non-counting -- ticks around a Lam will disappear anyway. - early_phase = case sm_phase mode of - Phase 0 -> False - _ -> True --- If we don't have this early_phase test, consider --- x = length [1,2,3] --- The full laziness pass carefully floats all the cons cells to --- top level, and preInlineUnconditionally floats them all back in. --- Result is (a) static allocation replaced by dynamic allocation --- (b) many simplifier iterations because this tickles --- a related problem; only one inlining per pass --- --- On the other hand, I have seen cases where top-level fusion is --- lost if we don't inline top level thing (e.g. string constants) --- Hence the test for phase zero (which is the phase for all the final --- simplifications). Until phase zero we take no special notice of --- top level things, but then we become more leery about inlining --- them. + early_phase = not (isFinalPhase (sm_phase mode)) + -- If we don't have this early_phase test, consider + -- x = length [1,2,3] + -- The full laziness pass carefully floats all the cons cells to + -- top level, and preInlineUnconditionally floats them all back in. + -- Result is (a) static allocation replaced by dynamic allocation + -- (b) many simplifier iterations because this tickles + -- a related problem; only one inlining per pass + -- + -- On the other hand, I have seen cases where top-level fusion is + -- lost if we don't inline top level thing (e.g. string constants) + -- Hence the test for phase zero (which is the phase for all the final + -- simplifications). Until phase zero we take no special notice of + -- top level things, but then we become more leery about inlining + -- them. {- ************************************************************************ @@ -1530,7 +1530,7 @@ tryEtaExpandRhs mode bndr rhs return (new_arity, is_bot, new_rhs) } where try_expand - | exprIsTrivial rhs + | exprIsTrivial rhs -- See Note [Do not eta-expand trivial expressions] = return (exprArity rhs, False, rhs) | sm_eta_expand mode -- Provided eta-expansion is on @@ -1574,9 +1574,17 @@ because then 'genMap' will inline, and it really shouldn't: at least as far as the programmer is concerned, it's not applied to two arguments! +Note [Do not eta-expand trivial expressions] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Do not eta-expand a trivial RHS like + f = g +If we eta expand do + f = \x. g x +we'll just eta-reduce again, and so on; so the +simplifier never terminates. + Note [Do not eta-expand join points] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Similarly to CPR (see Note [Don't w/w join points for CPR] in GHC.Core.Opt.WorkWrap), a join point stands well to gain from its outer binding's eta-expansion, and eta-expanding a join point is fraught with issues like how to ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -1760,8 +1760,8 @@ Note [Transfer activation] In which phase should the specialise-constructor rules be active? Originally I made them always-active, but Manuel found that this defeated some clever user-written rules. Then I made them active only -in Phase 0; after all, currently, the specConstr transformation is -only run after the simplifier has reached Phase 0, but that meant +in finalPhase; after all, currently, the specConstr transformation is +only run after the simplifier has reached finalPhase, but that meant that specialisations didn't fire inside wrappers; see test simplCore/should_compile/spec-inline. ===================================== compiler/GHC/Core/Opt/WorkWrap.hs ===================================== @@ -245,8 +245,8 @@ NOINLINE pragma to the worker. (See #13143 for a real-world example.) It is crucial that we do this for *all* NOINLINE functions. #10069 -demonstrates what happens when we promise to w/w a (NOINLINE) leaf function, but -fail to deliver: +demonstrates what happens when we promise to w/w a (NOINLINE) leaf +function, but fail to deliver: data C = C Int# Int# @@ -426,8 +426,14 @@ Reminder: Note [Don't w/w INLINE things], so we don't need to worry Conclusion: - If the user said NOINLINE[n], respect that - - If the user said NOINLINE, inline the wrapper as late as - poss (phase 0). This is a compromise driven by (2) above + + - If the user said NOINLINE, inline the wrapper only after + phase 0, the last user-visible phase. That means that all + rules will have had a chance to fire. + + What phase is after phase 0? Answer: finalPhase, phase (-1). + That's the reason finalPhase exists. + - Otherwise inline wrapper in phase 2. That allows the 'gentle' simplification pass to apply specialisation rules @@ -575,8 +581,8 @@ splitFun dflags fam_envs fn_id fn_info wrap_dmds div cpr rhs 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 + NoInline -> inl_act fn_inl_prag + _ -> inl_act wrap_prag work_prag = InlinePragma { inl_src = SourceText "{-# INLINE" , inl_inline = fn_inline_spec @@ -626,19 +632,7 @@ splitFun dflags fam_envs fn_id fn_info wrap_dmds div cpr rhs | 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_prag = mkStrWrapperInlinePrag fn_inl_prag wrap_id = fn_id `setIdUnfolding` mkWwInlineRule dflags wrap_rhs arity `setInlinePragma` wrap_prag `setIdOccInfo` noOccInfo @@ -655,8 +649,6 @@ splitFun dflags fam_envs fn_id fn_info wrap_dmds div cpr rhs rhs_fvs = exprFreeVars rhs 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 @@ -674,6 +666,20 @@ splitFun dflags fam_envs fn_id fn_info wrap_dmds div cpr rhs | otherwise = topCpr +mkStrWrapperInlinePrag :: InlinePragma -> InlinePragma +mkStrWrapperInlinePrag (InlinePragma { inl_act = act, inl_rule = rule_info }) + = InlinePragma { inl_src = SourceText "{-# INLINE" + , inl_inline = NoUserInline -- See Note [Wrapper NoUserInline] + , inl_sat = Nothing + , inl_act = wrap_act -- See Note [Wrapper activation] + , inl_rule = rule_info } -- RuleMatchInfo is (and must be) unaffected + where + wrap_act = case act of -- See Note [Wrapper activation] + ActiveAfter {} -> act + NeverActive -> activeDuringFinal + _ -> activeAfterInitial + + {- Note [Demand on the worker] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Core/SimpleOpt.hs ===================================== @@ -1340,8 +1340,7 @@ pushCoTyArg co ty | otherwise = Nothing where - tyL = coercionLKind co - tyR = coercionRKind co + Pair tyL tyR = coercionKind co -- co :: tyL ~ tyR -- tyL = forall (a1 :: k1). ty1 -- tyR = forall (a2 :: k2). ty2 ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -50,7 +50,7 @@ module GHC.Core.Type ( splitPiTy_maybe, splitPiTy, splitPiTys, mkTyConBindersPreferAnon, mkPiTy, mkPiTys, - mkLamType, mkLamTypes, + mkLamType, mkLamTypes, mkFunctionType, piResultTy, piResultTys, applyTysX, dropForAlls, mkFamilyTyConApp, @@ -254,7 +254,7 @@ import {-# SOURCE #-} GHC.Core.Coercion , mkTyConAppCo, mkAppCo, mkCoVarCo, mkAxiomRuleCo , mkForAllCo, mkFunCo, mkAxiomInstCo, mkUnivCo , mkSymCo, mkTransCo, mkNthCo, mkLRCo, mkInstCo - , mkKindCo, mkSubCo, mkFunCo, mkAxiomInstCo + , mkKindCo, mkSubCo , decomposePiCos, coercionKind, coercionLKind , coercionRKind, coercionType , isReflexiveCo, seqCo ) @@ -1515,6 +1515,8 @@ mkLamType :: Var -> Type -> Type mkLamTypes :: [Var] -> Type -> Type -- ^ 'mkLamType' for multiple type or value arguments +mkLamTypes vs ty = foldr mkLamType ty vs + mkLamType v body_ty | isTyVar v = ForAllTy (Bndr v Inferred) body_ty @@ -1523,43 +1525,19 @@ mkLamType v body_ty , v `elemVarSet` tyCoVarsOfType body_ty = ForAllTy (Bndr v Required) body_ty - | isPredTy arg_ty -- See Note [mkLamType: dictionary arguments] - = mkInvisFunTy arg_ty body_ty - | otherwise - = mkVisFunTy arg_ty body_ty - where - arg_ty = varType v - -mkLamTypes vs ty = foldr mkLamType ty vs + = mkFunctionType (varType v) body_ty -{- Note [mkLamType: dictionary arguments] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If we have (\ (d :: Ord a). blah), we want to give it type - (Ord a => blah_ty) -with a fat arrow; that is, using mkInvisFunTy, not mkVisFunTy. -Why? After all, we are in Core, where (=>) and (->) behave the same. -Yes, but the /specialiser/ does treat dictionary arguments specially. -Suppose we do w/w on 'foo' in module A, thus (#11272, #6056) - foo :: Ord a => Int -> blah - foo a d x = case x of I# x' -> $wfoo @a d x' +mkFunctionType :: Type -> Type -> Type +-- This one works out the AnonArgFlag from the argument type +-- See GHC.Types.Var Note [AnonArgFlag] +mkFunctionType arg_ty res_ty + | isPredTy arg_ty -- See GHC.Types.Var Note [AnonArgFlag] + = mkInvisFunTy arg_ty res_ty - $wfoo :: Ord a => Int# -> blah - -Now in module B we see (foo @Int dOrdInt). The specialiser will -specialise this to $sfoo, where - $sfoo :: Int -> blah - $sfoo x = case x of I# x' -> $wfoo @Int dOrdInt x' - -Now we /must/ also specialise $wfoo! But it wasn't user-written, -and has a type built with mkLamTypes. - -Conclusion: the easiest thing is to make mkLamType build - (c => ty) -when the argument is a predicate type. See GHC.Core.TyCo.Rep -Note [Types for coercions, predicates, and evidence] --} + | otherwise + = mkVisFunTy arg_ty res_ty -- | Given a list of type-level vars and the free vars of a result kind, -- makes TyCoBinders, preferring anonymous binders ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -412,6 +412,8 @@ inlineBoringOk e , exprIsTrivial a = go (credit-1) f go credit (Tick _ e) = go credit e -- dubious go credit (Cast e _) = go credit e + go credit (Case scrut _ _ [(_,_,rhs)]) -- See Note [Inline unsafeCoerce] + | isUnsafeEqualityProof scrut = go credit rhs go _ (Var {}) = boringCxtOk go _ _ = boringCxtNotOk @@ -459,7 +461,21 @@ calcUnfoldingGuidance dflags is_top_bottoming expr | otherwise = (+) -- See Note [Function and non-function discounts] -{- +{- Note [Inline unsafeCoerce] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +We really want to inline unsafeCoerce, even when applied to boring +arguments. It doesn't look as if its RHS is smaller than the call + unsafeCoerce x = case unsafeEqualityProof @a @b of UnsafeRefl -> x +but that case is discarded -- see Note [Implementing unsafeCoerce] +in base:Unsafe.Coerce. + +Moreover, if we /don't/ inline it, we may be left with + f (unsafeCoerce x) +which will build a thunk -- bad, bad, bad. + +Conclusion: we really want inlineBoringOk to be True of the RHS of +unsafeCoerce. This is (U4a) in Note [Implementing unsafeCoerce]. + Note [Computing the size of an expression] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The basic idea of sizeExpr is obvious enough: count nodes. But getting the ===================================== compiler/GHC/Core/Utils.hs ===================================== @@ -56,6 +56,9 @@ module GHC.Core.Utils ( -- * Join points isJoinBind, + -- * unsafeEqualityProof + isUnsafeEqualityProof, + -- * Dumping stuff dumpIdInfoOfProgram ) where @@ -66,7 +69,7 @@ import GHC.Prelude import GHC.Platform import GHC.Core -import GHC.Builtin.Names ( makeStaticName ) +import GHC.Builtin.Names ( makeStaticName, unsafeEqualityProofName ) import GHC.Core.Ppr import GHC.Core.FVs( exprFreeVars ) import GHC.Types.Var @@ -2533,3 +2536,20 @@ dumpIdInfoOfProgram ppr_id_info binds = vcat (map printId ids) getIds (Rec bs) = map fst bs printId id | isExportedId id = ppr id <> colon <+> (ppr_id_info (idInfo id)) | otherwise = empty + + +{- ********************************************************************* +* * + unsafeEqualityProof +* * +********************************************************************* -} + +isUnsafeEqualityProof :: CoreExpr -> Bool +-- See (U3) and (U4) in +-- Note [Implementing unsafeCoerce] in base:Unsafe.Coerce +isUnsafeEqualityProof e + | Var v `App` Type _ `App` Type _ `App` Type _ <- e + = idName v == unsafeEqualityProofName + | otherwise + = False + ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -1011,15 +1011,6 @@ cpExprIsTrivial e | otherwise = exprIsTrivial e -isUnsafeEqualityProof :: CoreExpr -> Bool --- See (U3) and (U4) in --- Note [Implementing unsafeCoerce] in base:Unsafe.Coerce -isUnsafeEqualityProof e - | Var v `App` Type _ `App` Type _ `App` Type _ <- e - = idName v == unsafeEqualityProofName - | otherwise - = False - -- This is where we arrange that a non-trivial argument is let-bound cpeArg :: CorePrepEnv -> Demand -> CoreArg -> Type -> UniqSM (Floats, CpeArg) ===================================== compiler/GHC/Types/Basic.hs ===================================== @@ -83,6 +83,7 @@ module GHC.Types.Basic ( Activation(..), isActive, isActiveIn, competesWith, isNeverActive, isAlwaysActive, isEarlyActive, activeAfterInitial, activeDuringFinal, + finalPhase, isFinalPhase, RuleMatchInfo(..), isConLike, isFunLike, InlineSpec(..), noUserInlineSpec, @@ -1300,6 +1301,22 @@ pprWithSourceText (SourceText src) _ = text src ************************************************************************ When a rule or inlining is active + +Note [Compiler phases] +~~~~~~~~~~~~~~~~~~~~~~ +The CompilerPhase says which phase the simplifier is running in: + +* InitialPhase: before all user-visible phases + +* Phase 2,1,0: user-visible phases; the phase number + controls rule ordering an inlining. + +* Phase (-1) = finalPhase: used for all subsequent simplifier + runs. By delaying inlining of wrappers to phase (-1) we can + ensure that RULE have a good chance to fire. See + Note [Wrapper activation] in GHC.Core.Opt.WorkWrap + +The phase sequencing is done by GHC.Opt.Simplify.Driver -} -- | Phase Number @@ -1317,12 +1334,21 @@ instance Outputable CompilerPhase where activeAfterInitial :: Activation -- Active in the first phase after the initial phase --- Currently we have just phases [2,1,0] +-- Currently we have just phases [2,1,0,-1] +-- Where "-1" means GHC's internal simplification steps +-- after all rules have run activeAfterInitial = ActiveAfter NoSourceText 2 activeDuringFinal :: Activation -- Active in the final simplification phase (which is repeated) -activeDuringFinal = ActiveAfter NoSourceText 0 +activeDuringFinal = ActiveAfter NoSourceText (-1) + +finalPhase :: CompilerPhase +finalPhase = Phase (-1) + +isFinalPhase :: CompilerPhase -> Bool +isFinalPhase (Phase (-1)) = True +isFinalPhase _ = False -- See note [Pragma source text] data Activation = NeverActive ===================================== compiler/GHC/Types/Var.hs ===================================== @@ -436,10 +436,10 @@ instance Binary ArgFlag where _ -> return Inferred -- | The non-dependent version of 'ArgFlag'. - --- Appears here partly so that it's together with its friend ArgFlag, --- but also because it is used in IfaceType, rather early in the --- compilation chain +-- See Note [AnonArgFlag] +-- Appears here partly so that it's together with its friends ArgFlag +-- and ForallVisFlag, but also because it is used in IfaceType, rather +-- early in the compilation chain -- See Note [AnonArgFlag vs. ForallVisFlag] data AnonArgFlag = VisArg -- ^ Used for @(->)@: an ordinary non-dependent arrow. @@ -482,7 +482,61 @@ argToForallVisFlag Required = ForallVis argToForallVisFlag Specified = ForallInvis argToForallVisFlag Inferred = ForallInvis -{- +{- Note [AnonArgFlag] +~~~~~~~~~~~~~~~~~~~~~ +AnonArgFlag is used principally in the FunTy constructor of Type. + FunTy VisArg t1 t2 means t1 -> t2 + FunTy InvisArg t1 t2 means t1 => t2 + +However, the AnonArgFlag in a FunTy is just redundant, cached +information. In (FunTy { ft_af = af, ft_arg = t1, ft_res = t2 }) + * if (isPredTy t1 = True) then af = InvisArg + * if (isPredTy t1 = False) then af = VisArg +where isPredTy is defined in GHC.Core.Type, and sees if t1's +kind is Constraint. See GHC.Core.TyCo.Rep +Note [Types for coercions, predicates, and evidence] + +GHC.Core.Type.mkFunctionType :: Type -> Type -> Type +uses isPredTy to decide the AnonArgFlag for the FunTy. + +The term (Lam b e), and coercion (FunCo co1 co2) don't carry +AnonArgFlags; instead they use mkFunctionType when we want to +get their types; see mkLamType and coercionLKind/RKind resp. +This is just an engineering choice; we could cache here too +if we wanted. + +Why bother with all this? After all, we are in Core, where (=>) and +(->) behave the same. We maintain this distinction throughout Core so +that we can cheaply and conveniently determine +* How to print a type +* How to split up a type: tcSplitSigmaTy +* How to specialise it (over type classes; GHC.Core.Opt.Specialise) + +For the specialisation point, consider +(\ (d :: Ord a). blah). We want to give it type + (Ord a => blah_ty) +with a fat arrow; that is, using mkInvisFunTy, not mkVisFunTy. + +Yes, but the /specialiser/ does treat dictionary arguments specially. +Suppose we do w/w on 'foo' in module A, thus (#11272, #6056) + foo :: Ord a => Int -> blah + foo a d x = case x of I# x' -> $wfoo @a d x' + + $wfoo :: Ord a => Int# -> blah + +Now in module B we see (foo @Int dOrdInt). The specialiser will +specialise this to $sfoo, where + $sfoo :: Int -> blah + $sfoo x = case x of I# x' -> $wfoo @Int dOrdInt x' + +Now we /must/ also specialise $wfoo! But it wasn't user-written, +and has a type built with mkLamTypes. + +Conclusion: the easiest thing is to make mkLamType build + (c => ty) +when the argument is a predicate type. See GHC.Core.TyCo.Rep +Note [Types for coercions, predicates, and evidence] + Note [AnonArgFlag vs. ForallVisFlag] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The AnonArgFlag and ForallVisFlag data types are quite similar at a first @@ -493,15 +547,19 @@ glance: Both data types keep track of visibility of some sort. AnonArgFlag tracks whether a FunTy has a visible argument (->) or an invisible predicate argument -(=>). ForallVisFlag tracks whether a `forall` quantifier is visible -(forall a -> {...}) or invisible (forall a. {...}). - -Given their similarities, it's tempting to want to combine these two data types -into one, but they actually represent distinct concepts. AnonArgFlag reflects a -property of *Core* types, whereas ForallVisFlag reflects a property of the GHC -AST. In other words, AnonArgFlag is all about internals, whereas ForallVisFlag -is all about surface syntax. Therefore, they are kept as separate data types. --} +(=>). ForallVisFlag tracks whether a `forall` quantifier in a user-specified +HsType is + visible: forall a -> {...} + invisible: forall a. {...} +In fact the visible form can currently only appear in kinds. + +Given their similarities, it's tempting to want to combine these two +data types into one, but they actually represent distinct +concepts. AnonArgFlag reflects a property of *Core* types, whereas +ForallVisFlag reflects a property of the HsSyn source-code AST. In +other words, AnonArgFlag is all about internals, whereas ForallVisFlag +is all about surface syntax. Therefore, they are kept as separate data +types. -} {- ********************************************************************* * * ===================================== libraries/base/Unsafe/Coerce.hs ===================================== @@ -22,7 +22,6 @@ import GHC.Natural () -- See Note [Depend on GHC.Natural] in GHC.Base import GHC.Types {- Note [Implementing unsafeCoerce] - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The implementation of unsafeCoerce is surprisingly subtle. This Note describes the moving parts. You will find more @@ -126,9 +125,13 @@ several ways Flaoting the case is OK here, even though it broardens the scope, becuase we are done with simplification. -(U4) GHC.CoreToStg.Prep.cpeExprIsTrivial anticipated the +(U4) GHC.CoreToStg.Prep.cpeExprIsTrivial anticipates the upcoming discard of unsafeEqualityProof. +(U4a) Ditto GHC.Core.Unfold.inlineBoringOk we want to treat + the RHS of unsafeCoerce as very small; see + Note [Inline unsafeCoerce] in that module. + (U5) The definition of unsafeEqualityProof in Unsafe.Coerce looks very strange: unsafeEqualityProof = case unsafeEqualityProof @a @b of @@ -161,7 +164,7 @@ several ways to simplify the ase when the two tpyes are equal. (U8) The is a super-magic RULE in GHC.base - map cocerce = coerce + map coerce = coerce (see Note [Getting the map/coerce RULE to work] in CoreOpt) But it's all about turning coerce into a cast, and unsafeCoerce no longer does that. So we need a separate map/unsafeCoerce ===================================== testsuite/tests/codeGen/should_compile/debug.stdout ===================================== @@ -18,6 +18,7 @@ src src src src +src == CBE == src 89 ===================================== testsuite/tests/deSugar/should_compile/T2431.stderr ===================================== @@ -4,7 +4,7 @@ Result size of Tidy Core = {terms: 63, types: 43, coercions: 1, joins: 0/0} -- RHS size: {terms: 2, types: 4, coercions: 1, joins: 0/0} -T2431.$WRefl [InlPrag=INLINE[0] CONLIKE] :: forall a. a :~: a +T2431.$WRefl [InlPrag=INLINE[-1] CONLIKE] :: forall a. a :~: a [GblId[DataConWrapper], Caf=NoCafRefs, Cpr=m1, ===================================== testsuite/tests/perf/compiler/T16473.stdout ===================================== @@ -1,10 +1,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 $p1Applicative (BUILTIN) +Rule fired: Class op <$ (BUILTIN) Rule fired: Class op <*> (BUILTIN) +Rule fired: Class op $p1Applicative (BUILTIN) Rule fired: Class op fmap (BUILTIN) Rule fired: Class op pure (BUILTIN) Rule fired: Class op pure (BUILTIN) ===================================== testsuite/tests/simplCore/should_compile/T13143.stderr ===================================== @@ -12,7 +12,7 @@ T13143.$wf = \ (@a) _ [Occ=Dead] -> T13143.$wf @a GHC.Prim.void# end Rec } -- RHS size: {terms: 4, types: 4, coercions: 0, joins: 0/0} -f [InlPrag=NOUSERINLINE[0]] :: forall a. Int -> a +f [InlPrag=NOUSERINLINE[-1]] :: forall a. Int -> a [GblId, Arity=1, Str=b, ===================================== testsuite/tests/simplCore/should_compile/T3772.stdout ===================================== @@ -62,7 +62,7 @@ T3772.$wfoo } -- RHS size: {terms: 6, types: 3, coercions: 0, joins: 0/0} -foo [InlPrag=NOUSERINLINE[0]] :: Int -> () +foo [InlPrag=NOUSERINLINE[-1]] :: Int -> () [GblId, Arity=1, Str=, ===================================== testsuite/tests/simplCore/should_compile/T7360.stderr ===================================== @@ -4,7 +4,7 @@ Result size of Tidy Core = {terms: 106, types: 47, coercions: 0, joins: 0/0} -- RHS size: {terms: 6, types: 3, coercions: 0, joins: 0/0} -T7360.$WFoo3 [InlPrag=INLINE[0] CONLIKE] :: Int -> Foo +T7360.$WFoo3 [InlPrag=INLINE[-1] CONLIKE] :: Int -> Foo [GblId[DataConWrapper], Arity=1, Caf=NoCafRefs, ===================================== testsuite/tests/simplCore/should_compile/T7865.stdout ===================================== @@ -1,6 +1,6 @@ T7865.$wexpensive [InlPrag=NOINLINE] T7865.$wexpensive -expensive [InlPrag=NOUSERINLINE[0]] :: Int -> Int +expensive [InlPrag=NOUSERINLINE[-1]] :: Int -> Int case T7865.$wexpensive ww1 of ww2 [Occ=Once] { __DEFAULT -> expensive case T7865.$wexpensive ww1 of ww2 { __DEFAULT -> GHC.Types.I# ww2 } ===================================== testsuite/tests/stranal/should_compile/Makefile ===================================== @@ -10,3 +10,9 @@ T13031: # take only one Int# argument T16029: '$(TEST_HC)' $(TEST_HC_OPTS) -c -O -fforce-recomp T16029.hs -dsuppress-uniques -ddump-simpl | grep '::.*Int' + +T18078: + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O -fforce-recomp T18078.hs -dsuppress-uniques -ddump-simpl | grep 'wf' + +T17673: + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O -fforce-recomp T17673.hs -dsuppress-uniques -ddump-simpl | grep 'wf' ===================================== testsuite/tests/stranal/should_compile/T16029.stdout ===================================== @@ -1,4 +1,4 @@ -T16029.$WMkT [InlPrag=INLINE[0] CONLIKE] :: Int -> Int -> T +T16029.$WMkT [InlPrag=INLINE[-1] CONLIKE] :: Int -> Int -> T Tmpl= \ (dt [Occ=Once!] :: Int) (dt [Occ=Once!] :: Int) -> = \ (dt [Occ=Once!] :: Int) (dt [Occ=Once!] :: Int) -> :: GHC.Prim.Int# -> GHC.Prim.Int# ===================================== testsuite/tests/stranal/should_compile/T17673.hs ===================================== @@ -0,0 +1,6 @@ +module T17673 where + +facIO :: Int -> IO Int +facIO n | n < 2 = return 1 + | otherwise = do n' <- facIO (n-1); return (n*n') +{-# NOINLINE facIO #-} ===================================== testsuite/tests/stranal/should_compile/T17673.stdout ===================================== @@ -0,0 +1,5 @@ +T17673.$wfacIO [InlPrag=NOINLINE, Occ=LoopBreaker] +T17673.$wfacIO + case T17673.$wfacIO (GHC.Prim.-# ww 1#) w of { (# ipv, ipv1 #) -> + T17673.$wfacIO ww1 w1 + case w of { GHC.Types.I# ww1 -> T17673.$wfacIO ww1 w1 } ===================================== testsuite/tests/stranal/should_compile/T18078.hs ===================================== @@ -0,0 +1,13 @@ +module T18078 where + +newtype N = N { unN :: Int -> Int } + +-- This an example of a worker/wrapper thing +-- See Note [Cast worker/wrappers] in Simplify +-- We should get good code, with a $wf calling itself +-- but in 8.10 we do not +f :: N +{-# NOINLINE f #-} +f = N (\n -> if n==0 then 0 else unN f (n-1)) + +g x = unN f (x+1) ===================================== testsuite/tests/stranal/should_compile/T18078.stdout ===================================== @@ -0,0 +1,6 @@ +T18078.$wf [InlPrag=NOINLINE, Occ=LoopBreaker] +T18078.$wf + __DEFAULT -> T18078.$wf (GHC.Prim.-# wild 1#); + case T18078.$wf ww1 of ww2 [Occ=Once] { __DEFAULT -> + case T18078.$wf ww1 of ww2 { __DEFAULT -> GHC.Types.I# ww2 } + case T18078.$wf (GHC.Prim.+# x1 1#) of ww { __DEFAULT -> ===================================== testsuite/tests/stranal/should_compile/all.T ===================================== @@ -52,3 +52,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']) test('T13380b', [ grep_errmsg('bigDeadAction') ], compile, ['-dppr-cols=200 -ddump-simpl']) +test('T18078', normal, makefile_test, []) +test('T17673', normal, makefile_test, []) + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a98c4ef97e062d437897d064172bbe69dce1df57 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a98c4ef97e062d437897d064172bbe69dce1df57 You're receiving 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 17:09:31 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Thu, 21 May 2020 13:09:31 -0400 Subject: [Git][ghc/ghc][wip/T18185] 35 commits: IdInfo: Add reference to bitfield-packing ticket Message-ID: <5ec6b5cb2dc00_6e263f9eea2381ec6228f7@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T18185 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 - - - - - 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. - - - - - 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] - - - - - 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 - - - - - 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 - - - - - 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. - - - - - 78c6523c by Ben Gamari at 2020-05-21T12:13:01-04:00 nonmoving: Optimise the write barrier - - - - - 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). - - - - - 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 - - - - - b7a6b2f4 by Gleb Popov at 2020-05-21T12:15:26-04:00 gitlab-ci: Set locale to C.UTF-8. - - - - - 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. - - - - - 0004ccb8 by Tuan Le at 2020-05-21T12:16:46-04:00 llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 - - - - - 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 - - - - - 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 - - - - - 2b363ebb by Richard Eisenberg at 2020-05-21T12:18:45-04:00 MR template should ask for key part - - - - - a95bbd0b by Sebastian Graf at 2020-05-21T12:19:37-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. - - - - - d3d055b8 by Galen Huntington at 2020-05-21T12:20:18-04:00 Clarify pitfalls of NegativeLiterals; see #18022. - - - - - 1b508a9e by Alexey Kuleshevich at 2020-05-21T12:21:02-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" - - - - - 4ca0c8a1 by Andreas Klebinger at 2020-05-21T12:21: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. - - - - - a1275081 by Krzysztof Gogolewski at 2020-05-21T12:22:35-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 - - - - - 8a816e5f by Krzysztof Gogolewski at 2020-05-21T12:23:55-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. - - - - - 566cc73f by Sylvain Henry at 2020-05-21T12:24:45-04:00 Move isDynLinkName into GHC.Types.Name It doesn't belong into GHC.Unit.State - - - - - 6ca3d6a6 by Ryan Scott at 2020-05-21T13:08:40-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. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/merge_request_templates/merge-request.md - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - 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/Cmm/Opt.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/Arity.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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/28ee5a1f407257fdcd39ac0c9fec523488da4998...6ca3d6a6c19dcd885f3b0beeda192cd90e83e0bd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/28ee5a1f407257fdcd39ac0c9fec523488da4998...6ca3d6a6c19dcd885f3b0beeda192cd90e83e0bd You're receiving 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 23:00:10 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Thu, 21 May 2020 19:00:10 -0400 Subject: [Git][ghc/ghc][wip/T18078] 32 commits: Remove duplicate Note [When to print foralls] in GHC.Core.TyCo.Ppr Message-ID: <5ec707fa8164c_6e263f9f0becf12866276b@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T18078 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] - - - - - 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 - - - - - 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 - - - - - 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. - - - - - 78c6523c by Ben Gamari at 2020-05-21T12:13:01-04:00 nonmoving: Optimise the write barrier - - - - - 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). - - - - - 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 - - - - - b7a6b2f4 by Gleb Popov at 2020-05-21T12:15:26-04:00 gitlab-ci: Set locale to C.UTF-8. - - - - - 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. - - - - - 0004ccb8 by Tuan Le at 2020-05-21T12:16:46-04:00 llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 - - - - - 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 - - - - - 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 - - - - - 2b363ebb by Richard Eisenberg at 2020-05-21T12:18:45-04:00 MR template should ask for key part - - - - - a95bbd0b by Sebastian Graf at 2020-05-21T12:19:37-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. - - - - - d3d055b8 by Galen Huntington at 2020-05-21T12:20:18-04:00 Clarify pitfalls of NegativeLiterals; see #18022. - - - - - 1b508a9e by Alexey Kuleshevich at 2020-05-21T12:21:02-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" - - - - - 4ca0c8a1 by Andreas Klebinger at 2020-05-21T12:21: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. - - - - - a1275081 by Krzysztof Gogolewski at 2020-05-21T12:22:35-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 - - - - - 8a816e5f by Krzysztof Gogolewski at 2020-05-21T12:23:55-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. - - - - - 566cc73f by Sylvain Henry at 2020-05-21T12:24:45-04:00 Move isDynLinkName into GHC.Types.Name It doesn't belong into GHC.Unit.State - - - - - dc0f3dba by Simon Peyton Jones at 2020-05-21T23:59:38+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 also discovered that unsafeCoerce wasn't being inlined if the context was boring. So (\x. f (unsafeCoerce x)) would create a thunk -- yikes! I fixed that by making inlineBoringOK a bit cleverer: see Note [Inline unsafeCoerce] in GHC.Core.Unfold. I also found that unsafeCoerceName was unused, so I removed it. 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: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/merge_request_templates/merge-request.md - compiler/GHC/Builtin/Names.hs - 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/Driver.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a98c4ef97e062d437897d064172bbe69dce1df57...dc0f3dbadda447b1376169386f24bf29922cad55 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a98c4ef97e062d437897d064172bbe69dce1df57...dc0f3dbadda447b1376169386f24bf29922cad55 You're receiving 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 22 01:03:57 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 21 May 2020 21:03:57 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 32 commits: base: Add Generic instances to various datatypes under GHC.* Message-ID: <5ec724fd993ec_6e263f9f0ba41660667590@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job 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 - - - - - 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 - - - - - 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. - - - - - 78c6523c by Ben Gamari at 2020-05-21T12:13:01-04:00 nonmoving: Optimise the write barrier - - - - - 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). - - - - - 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 - - - - - b7a6b2f4 by Gleb Popov at 2020-05-21T12:15:26-04:00 gitlab-ci: Set locale to C.UTF-8. - - - - - 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. - - - - - 0004ccb8 by Tuan Le at 2020-05-21T12:16:46-04:00 llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 - - - - - 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 - - - - - 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 - - - - - 2b363ebb by Richard Eisenberg at 2020-05-21T12:18:45-04:00 MR template should ask for key part - - - - - a95bbd0b by Sebastian Graf at 2020-05-21T12:19:37-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. - - - - - d3d055b8 by Galen Huntington at 2020-05-21T12:20:18-04:00 Clarify pitfalls of NegativeLiterals; see #18022. - - - - - 1b508a9e by Alexey Kuleshevich at 2020-05-21T12:21:02-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" - - - - - 4ca0c8a1 by Andreas Klebinger at 2020-05-21T12:21: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. - - - - - a1275081 by Krzysztof Gogolewski at 2020-05-21T12:22:35-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 - - - - - 8a816e5f by Krzysztof Gogolewski at 2020-05-21T12:23:55-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. - - - - - 566cc73f by Sylvain Henry at 2020-05-21T12:24:45-04:00 Move isDynLinkName into GHC.Types.Name It doesn't belong into GHC.Unit.State - - - - - 00967b02 by Ben Gamari at 2020-05-21T21:03:48-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. - - - - - be3a978b by Ben Gamari at 2020-05-21T21:03:50-04:00 Bump process submodule Fixes #17926. - - - - - 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/Rules.hs - compiler/GHC/Core/TyCo/Ppr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6bc1278b88e6b82343348d4c0a217391eb33a447...be3a978b1677f0a70af033d9699bdffb106e3506 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6bc1278b88e6b82343348d4c0a217391eb33a447...be3a978b1677f0a70af033d9699bdffb106e3506 You're receiving 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 22 02:11:12 2020 From: gitlab at gitlab.haskell.org (Daneel S. Yaitskov) Date: Thu, 21 May 2020 22:11:12 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T17949 Message-ID: <5ec734c0b36d2_6e263f9eea2381ec67348f@gitlab.haskell.org.mail> Daneel S. Yaitskov pushed new branch wip/T17949 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T17949 You're receiving 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 22 09:31:38 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Fri, 22 May 2020 05:31:38 -0400 Subject: [Git][ghc/ghc][wip/T17775] 32 commits: Remove duplicate Note [When to print foralls] in GHC.Core.TyCo.Ppr Message-ID: <5ec79bfaace86_6e263f9eebd78574695858@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17775 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] - - - - - 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 - - - - - 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 - - - - - 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. - - - - - 78c6523c by Ben Gamari at 2020-05-21T12:13:01-04:00 nonmoving: Optimise the write barrier - - - - - 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). - - - - - 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 - - - - - b7a6b2f4 by Gleb Popov at 2020-05-21T12:15:26-04:00 gitlab-ci: Set locale to C.UTF-8. - - - - - 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. - - - - - 0004ccb8 by Tuan Le at 2020-05-21T12:16:46-04:00 llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 - - - - - 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 - - - - - 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 - - - - - 2b363ebb by Richard Eisenberg at 2020-05-21T12:18:45-04:00 MR template should ask for key part - - - - - a95bbd0b by Sebastian Graf at 2020-05-21T12:19:37-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. - - - - - d3d055b8 by Galen Huntington at 2020-05-21T12:20:18-04:00 Clarify pitfalls of NegativeLiterals; see #18022. - - - - - 1b508a9e by Alexey Kuleshevich at 2020-05-21T12:21:02-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" - - - - - 4ca0c8a1 by Andreas Klebinger at 2020-05-21T12:21: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. - - - - - a1275081 by Krzysztof Gogolewski at 2020-05-21T12:22:35-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 - - - - - 8a816e5f by Krzysztof Gogolewski at 2020-05-21T12:23:55-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. - - - - - 566cc73f by Sylvain Henry at 2020-05-21T12:24:45-04:00 Move isDynLinkName into GHC.Types.Name It doesn't belong into GHC.Unit.State - - - - - 3fff2812 by Simon Peyton Jones at 2020-05-22T10:30:28+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: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/merge_request_templates/merge-request.md - compiler/GHC/Builtin/Names.hs - 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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a2fda5e1e85fa237c8aa0b2a08510d47bf2c3d4b...3fff2812721d50134792e09ecbbf76377a0686ff -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a2fda5e1e85fa237c8aa0b2a08510d47bf2c3d4b...3fff2812721d50134792e09ecbbf76377a0686ff You're receiving 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 22 09:47:13 2020 From: gitlab at gitlab.haskell.org (Matthew Pickering) Date: Fri, 22 May 2020 05:47:13 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/unused-boot-file Message-ID: <5ec79fa19d6ab_6e263f9ed4defb547018df@gitlab.haskell.org.mail> Matthew Pickering pushed new branch wip/unused-boot-file at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/unused-boot-file You're receiving 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 22 10:04:47 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Fri, 22 May 2020 06:04:47 -0400 Subject: [Git][ghc/ghc][wip/T17775] Simple subsumption Message-ID: <5ec7a3bfd91a4_6e263f9eea2381ec704934@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: bcc9149f by Simon Peyton Jones at 2020-05-22T11:03:47+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 - - - - - 20 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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bcc9149f4b2f1fd320507f5dea5b8abd7d262d6c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bcc9149f4b2f1fd320507f5dea5b8abd7d262d6c You're receiving 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 22 10:47:33 2020 From: gitlab at gitlab.haskell.org (Matthew Pickering) Date: Fri, 22 May 2020 06:47:33 -0400 Subject: [Git][ghc/ghc][wip/compact-iface] 213 commits: fs.h: Add missing declarations on Windows Message-ID: <5ec7adc5e1b23_6e2679b9a407111c1@gitlab.haskell.org.mail> Matthew Pickering pushed to branch wip/compact-iface at Glasgow Haskell Compiler / GHC Commits: 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. - - - - - 41d9b1dc by Daniel Gröber at 2020-05-02T18:34:28+02:00 Remove length field from FastString - - - - - 485ebda9 by Daniel Gröber at 2020-05-02T19:03:19+02:00 Use ShortByteString for FastString There are multiple reasons we want this: - Fewer allocations: ByteString has 3 fields, ShortByteString just has one. - ByteString memory is pinned: - This can cause fragmentation issues (see for example #13110) but also - makes using FastStrings in compact regions impossible. Metric Decrease: T5837 T12150 T12234 T12425 - - - - - 5ecd1ab0 by Daniel Gröber at 2020-05-02T19:03:19+02:00 Pass specialised utf8DecodeChar# to utf8DecodeLazy# for performance Currently we're passing a indexWord8OffAddr# type function to utf8DecodeLazy# which then passes it on to utf8DecodeChar#. By passing one of utf8DecodeCharAddr# or utf8DecodeCharByteArray# instead we benefit from the inlining and specialization already done for those. - - - - - 66925050 by Daniel Gröber at 2020-05-02T19:03:19+02:00 Encoding: Add comment about tricky ForeignPtr lifetime - - - - - e7ab1c58 by Daniel Gröber at 2020-05-02T19:03:19+02:00 Use IO constructor instead of `stToIO . ST` - - - - - 6e8d780f by Daniel Gröber at 2020-05-02T19:03:19+02:00 Encoding: Remove redundant use of withForeignPtr - - - - - 64737574 by Daniel Gröber at 2020-05-02T19:03:19+02:00 Encoding: Reformat utf8EncodeShortByteString to be more consistent - - - - - 16e0e24d by Daniel Gröber at 2020-05-02T19:03:19+02:00 FastString: Reintroduce character count cache Metric Increase: ManyConstructors Metric Decrease: T4029 - - - - - 43f68b68 by Matthew Pickering at 2020-05-22T11:31:28+01:00 Remove TyThing from WiredIn names This change will allow `ModIface` to be compacted. Related to #17097 - - - - - 713e5cbc by Matthew Pickering at 2020-05-22T11:33:11+01:00 Parameterise Literal so that the Type can be removed The `Type` field contains references to things which can't be compacted. See #17097 - - - - - bea5d9a2 by Matthew Pickering at 2020-05-22T11:34:05+01:00 Use FastString instead of ByteString in LitString Not sure this is the best choice but manipulating ShortByteStrings is also awkward - - - - - d8e07325 by Matthew Pickering at 2020-05-22T11:36:41+01:00 Split off cache fields from ModIface This is necessary as functions can't be compacted. See #17097 - - - - - 0844b539 by Matthew Pickering at 2020-05-22T11:38:10+01:00 Refactor HsDocString to use ShortByteString This is towards being able to compact a ModIface (see #17097) - - - - - 822aa274 by Matthew Pickering at 2020-05-22T11:39:38+01:00 HIE Files: Remove use of ByteString for ShortByteString See #17097 - - - - - c9eaf757 by Matthew Pickering at 2020-05-22T11:39:40+01:00 Remove Binary instance for ByteString This is a defensive incase someone tries to add back something which mentions ByteString into a ModIface See #17097 - - - - - 5b89100d by Matthew Pickering at 2020-05-22T11:41:54+01:00 Proof of compacting ModIface - - - - - 9426ddf9 by Matthew Pickering at 2020-05-22T11:41:55+01:00 Use ShortByteString for FastZString We need something compactable here, as a FastString ends up getting compacted. - - - - - fcb0f334 by Matthew Pickering at 2020-05-22T11:41:55+01:00 Don't throw away extra info, for now - - - - - 49673a0b by Matthew Pickering at 2020-05-22T11:47:01+01:00 Update haddock - - - - - 3d8185f3 by Matthew Pickering at 2020-05-22T11:47:02+01:00 Remove redundant import - - - - - f213e81c by Matthew Pickering at 2020-05-22T11:47:03+01:00 8.6.5 hack, for now This instance is only used in rare code paths such as HieFiles - - - - - 76b530bd by Matthew Pickering at 2020-05-22T11:47:03+01:00 Turn off compacting - - - - - 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/BlockId.hs-boot - 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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b7ea9ba3fa75ad86b8220f92b51f60c24d737069...76b530bd1c720165be8dc6365c37ba74ad3e63f0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b7ea9ba3fa75ad86b8220f92b51f60c24d737069...76b530bd1c720165be8dc6365c37ba74ad3e63f0 You're receiving 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 22 10:50:01 2020 From: gitlab at gitlab.haskell.org (Sven Tennie) Date: Fri, 22 May 2020 06:50:01 -0400 Subject: [Git][ghc/ghc][wip/ghc-debug] Make StgTSO and StgStack decoding downwards compatible Message-ID: <5ec7ae5944ad_6e263f9ed809adc471756b@gitlab.haskell.org.mail> Sven Tennie pushed to branch wip/ghc-debug at Glasgow Haskell Compiler / GHC Commits: 76907eaa by Sven Tennie at 2020-05-22T12:49:33+02:00 Make StgTSO and StgStack decoding downwards compatible This is especially needed for hadrian/ghci. - - - - - 3 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 Changes: ===================================== libraries/ghc-heap/GHC/Exts/Heap.hs ===================================== @@ -345,7 +345,9 @@ getClosureX get_closure_raw x = do , stack_dirty = FFIClosures.stack_dirty fields , stackPointer = (pts !! 0) , stack = FFIClosures.stack fields +#if __GLASGOW_HASKELL__ >= 811 , stack_marking = FFIClosures.stack_marking fields +#endif } ) _ -> ===================================== libraries/ghc-heap/GHC/Exts/Heap/Closures.hs ===================================== @@ -287,7 +287,9 @@ data GenClosure b { info :: !StgInfoTable , size :: !Word32 -- ^ stack size in *words* , stack_dirty :: !Word8 -- ^ non-zero => dirty +#if __GLASGOW_HASKELL__ >= 811 , stack_marking :: Word8 +#endif , stackPointer :: !b -- ^ current stack pointer , stack :: [Word] } ===================================== libraries/ghc-heap/GHC/Exts/Heap/FFIClosures.hsc ===================================== @@ -1,3 +1,4 @@ +{-# LANGUAGE CPP #-} module GHC.Exts.Heap.FFIClosures where #include "Rts.h" @@ -47,7 +48,9 @@ peekTSOFields ptr = do data StackFields = StackFields { stack_size :: Word32, stack_dirty :: Word8, +#if __GLASGOW_HASKELL__ >= 811 stack_marking :: Word8, +#endif stack :: [Word] } @@ -56,7 +59,9 @@ peekStackFields :: Ptr a -> IO StackFields peekStackFields ptr = do stack_size' <- (#peek struct StgStack_, stack_size) ptr ::IO Word32 dirty' <- (#peek struct StgStack_, dirty) ptr +#if __GLASGOW_HASKELL__ >= 811 marking' <- (#peek struct StgStack_, marking) ptr +#endif let stackPtr = (#ptr struct StgStack_, stack) ptr stack' <- peekArray (fromIntegral stack_size') stackPtr @@ -64,6 +69,8 @@ peekStackFields ptr = do return StackFields { stack_size = stack_size', stack_dirty = dirty', +#if __GLASGOW_HASKELL__ >= 811 stack_marking = marking', +#endif stack = stack' } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/76907eaa4eb77c406e952ffb1680030e194e5003 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/76907eaa4eb77c406e952ffb1680030e194e5003 You're receiving 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 22 10:57:11 2020 From: gitlab at gitlab.haskell.org (Matthew Pickering) Date: Fri, 22 May 2020 06:57:11 -0400 Subject: [Git][ghc/ghc][wip/compact-iface] Don't use source import Message-ID: <5ec7b007bf3bb_6e263f9ed809adc47264e2@gitlab.haskell.org.mail> Matthew Pickering pushed to branch wip/compact-iface at Glasgow Haskell Compiler / GHC Commits: e7b032e6 by Matthew Pickering at 2020-05-22T11:56:58+01:00 Don't use source import - - - - - 1 changed file: - compiler/GHC/Builtin/Uniques.hs Changes: ===================================== compiler/GHC/Builtin/Uniques.hs ===================================== @@ -38,7 +38,7 @@ import GHC.Utils.Outputable import GHC.Types.Unique import GHC.Types.Name import GHC.Utils.Misc -import {-# SOURCE #-} GHC.Core.TyCo.Rep +import GHC.Core.TyCo.Rep import {-# SOURCE #-} GHC.Core.ConLike import Data.Bits View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e7b032e6437bede391c94ee58583d2b93619098e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e7b032e6437bede391c94ee58583d2b93619098e You're receiving 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 22 11:42:03 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Fri, 22 May 2020 07:42:03 -0400 Subject: [Git][ghc/ghc][wip/T17775] Simple subsumption Message-ID: <5ec7ba8bef6d4_6e263f9ed6ed0cc4738526@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: 9edcb502 by Simon Peyton Jones at 2020-05-22T12:41:16+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 - - - - - 20 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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9edcb502ab64400fb6b4e43f39ad139e77859e36 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9edcb502ab64400fb6b4e43f39ad139e77859e36 You're receiving 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 22 14:02:35 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Fri, 22 May 2020 10:02:35 -0400 Subject: [Git][ghc/ghc][wip/T17775] Simple subsumption Message-ID: <5ec7db7b2543_6e263f9eea2381ec7767f@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: 11dbe3f2 by Simon Peyton Jones at 2020-05-22T15:01:48+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 - - - - - 20 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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/11dbe3f2de77d674e389586e8e3b41465294fb5b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/11dbe3f2de77d674e389586e8e3b41465294fb5b You're receiving 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 22 15:26:17 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Fri, 22 May 2020 11:26:17 -0400 Subject: [Git][ghc/ghc][wip/T18078] Implement cast worker/wrapper properly Message-ID: <5ec7ef19d564b_6e263f9f016ab5dc81296b@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T18078 at Glasgow Haskell Compiler / GHC Commits: 10b0b9b1 by Simon Peyton Jones at 2020-05-22T16:24:52+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 also discovered that unsafeCoerce wasn't being inlined if the context was boring. So (\x. f (unsafeCoerce x)) would create a thunk -- yikes! I fixed that by making inlineBoringOK a bit cleverer: see Note [Inline unsafeCoerce] in GHC.Core.Unfold. I also found that unsafeCoerceName was unused, so I removed it. 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% - - - - - 29 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Opt/Driver.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/SimpleOpt.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/Var.hs - libraries/base/Unsafe/Coerce.hs - testsuite/tests/codeGen/should_compile/debug.stdout - testsuite/tests/deSugar/should_compile/T2431.stderr - testsuite/tests/perf/compiler/T16473.stdout - testsuite/tests/simplCore/should_compile/T13143.stderr - testsuite/tests/simplCore/should_compile/T3772.stdout - testsuite/tests/simplCore/should_compile/T7360.stderr - testsuite/tests/simplCore/should_compile/T7865.stdout - testsuite/tests/stranal/should_compile/Makefile - testsuite/tests/stranal/should_compile/T16029.stdout - + testsuite/tests/stranal/should_compile/T17673.hs - + testsuite/tests/stranal/should_compile/T17673.stdout - + testsuite/tests/stranal/should_compile/T18078.hs - + testsuite/tests/stranal/should_compile/T18078.stdout - testsuite/tests/stranal/should_compile/all.T Changes: ===================================== compiler/GHC/Builtin/Names.hs ===================================== @@ -475,7 +475,6 @@ basicKnownKeyNames , unsafeEqualityTyConName , unsafeReflDataConName , unsafeCoercePrimName - , unsafeCoerceName ] genericTyConNames :: [Name] @@ -1333,12 +1332,11 @@ typeErrorShowTypeDataConName = -- Unsafe coercion proofs unsafeEqualityProofName, unsafeEqualityTyConName, unsafeCoercePrimName, - unsafeCoerceName, unsafeReflDataConName :: Name + unsafeReflDataConName :: Name unsafeEqualityProofName = varQual uNSAFE_COERCE (fsLit "unsafeEqualityProof") unsafeEqualityProofIdKey unsafeEqualityTyConName = tcQual uNSAFE_COERCE (fsLit "UnsafeEquality") unsafeEqualityTyConKey unsafeReflDataConName = dcQual uNSAFE_COERCE (fsLit "UnsafeRefl") unsafeReflDataConKey unsafeCoercePrimName = varQual uNSAFE_COERCE (fsLit "unsafeCoerce#") unsafeCoercePrimIdKey -unsafeCoerceName = varQual uNSAFE_COERCE (fsLit "unsafeCoerce") unsafeCoerceIdKey -- Dynamic toDynName :: Name @@ -2411,10 +2409,9 @@ naturalSDataConKey = mkPreludeMiscIdUnique 568 wordToNaturalIdKey = mkPreludeMiscIdUnique 569 -- Unsafe coercion proofs -unsafeEqualityProofIdKey, unsafeCoercePrimIdKey, unsafeCoerceIdKey :: Unique +unsafeEqualityProofIdKey, unsafeCoercePrimIdKey :: Unique unsafeEqualityProofIdKey = mkPreludeMiscIdUnique 570 unsafeCoercePrimIdKey = mkPreludeMiscIdUnique 571 -unsafeCoerceIdKey = mkPreludeMiscIdUnique 572 {- ************************************************************************ ===================================== compiler/GHC/Core/Coercion.hs ===================================== @@ -2187,7 +2187,7 @@ coercionLKind co go (TyConAppCo _ tc cos) = mkTyConApp tc (map go cos) go (AppCo co1 co2) = mkAppTy (go co1) (go co2) go (ForAllCo tv1 _ co1) = mkTyCoInvForAllTy tv1 (go co1) - go (FunCo _ co1 co2) = mkVisFunTy (go co1) (go co2) + go (FunCo _ co1 co2) = mkFunctionType (go co1) (go co2) go (CoVarCo cv) = coVarLType cv go (HoleCo h) = coVarLType (coHoleCoVar h) go (UnivCo _ _ ty1 _) = ty1 @@ -2244,7 +2244,7 @@ coercionRKind co go (AppCo co1 co2) = mkAppTy (go co1) (go co2) go (CoVarCo cv) = coVarRType cv go (HoleCo h) = coVarRType (coHoleCoVar h) - go (FunCo _ co1 co2) = mkVisFunTy (go co1) (go co2) + go (FunCo _ co1 co2) = mkFunctionType (go co1) (go co2) go (UnivCo _ _ _ ty2) = ty2 go (SymCo co) = coercionLKind co go (TransCo _ co2) = go co2 ===================================== compiler/GHC/Core/Opt/Driver.hs ===================================== @@ -37,7 +37,7 @@ import GHC.Core.Opt.FloatOut ( floatOutwards ) import GHC.Core.FamInstEnv import GHC.Types.Id import GHC.Utils.Error ( withTiming, withTimingD, DumpFormat (..) ) -import GHC.Types.Basic ( CompilerPhase(..), isDefaultInlinePragma, defaultInlinePragma ) +import GHC.Types.Basic import GHC.Types.Var.Set import GHC.Types.Var.Env import GHC.Core.Opt.LiberateCase ( liberateCase ) @@ -141,8 +141,10 @@ getCoreToDo dflags maybe_rule_check phase = runMaybe rule_check (CoreDoRuleCheck phase) - maybe_strictness_before phase - = runWhen (phase `elem` strictnessBefore dflags) CoreDoDemand + maybe_strictness_before (Phase phase) + | phase `elem` strictnessBefore dflags = CoreDoDemand + maybe_strictness_before _ + = CoreDoNothing base_mode = SimplMode { sm_phase = panic "base_mode" , sm_names = [] @@ -152,20 +154,20 @@ getCoreToDo dflags , sm_inline = True , sm_case_case = True } - simpl_phase phase names iter + simpl_phase phase name iter = CoreDoPasses $ [ maybe_strictness_before phase , CoreDoSimplify iter - (base_mode { sm_phase = Phase phase - , sm_names = names }) + (base_mode { sm_phase = phase + , sm_names = [name] }) - , maybe_rule_check (Phase phase) ] + , maybe_rule_check phase ] - simpl_phases = CoreDoPasses [ simpl_phase phase ["main"] max_iter - | phase <- [phases, phases-1 .. 1] ] + -- Run GHC's internal simplification phase, after all rules have run. + -- See Note [Compiler phases] in GHC.Types.Basic + simplify name = simpl_phase finalPhase name max_iter - - -- initial simplify: mk specialiser happy: minimum effort please + -- initial simplify: mk specialiser happy: minimum effort please simpl_gently = CoreDoSimplify max_iter (base_mode { sm_phase = InitialPhase , sm_names = ["Gentle"] @@ -182,7 +184,7 @@ getCoreToDo dflags demand_analyser = (CoreDoPasses ( dmd_cpr_ww ++ - [simpl_phase 0 ["post-worker-wrapper"] max_iter] + [simplify "post-worker-wrapper"] )) -- Static forms are moved to the top level with the FloatOut pass. @@ -203,7 +205,7 @@ getCoreToDo dflags if opt_level == 0 then [ static_ptrs_float_outwards, CoreDoSimplify max_iter - (base_mode { sm_phase = Phase 0 + (base_mode { sm_phase = finalPhase , sm_names = ["Non-opt simplification"] }) ] @@ -251,8 +253,10 @@ getCoreToDo dflags -- GHC.Iface.Tidy.StaticPtrTable. static_ptrs_float_outwards, - simpl_phases, - + -- Run the simplier phases 2,1,0 to allow rewrite rules to fire + CoreDoPasses [ simpl_phase (Phase phase) "main" max_iter + | phase <- [phases, phases-1 .. 1] ], + simpl_phase (Phase 0) "main" (max max_iter 3), -- Phase 0: allow all Ids to be inlined now -- This gets foldr inlined before strictness analysis @@ -263,7 +267,6 @@ getCoreToDo dflags -- ==> let k = BIG in letrec go = \xs -> ...(k x).... in go xs -- ==> let k = BIG in letrec go = \xs -> ...(BIG x).... in go xs -- Don't stop now! - simpl_phase 0 ["main"] (max max_iter 3), runWhen do_float_in CoreDoFloatInwards, -- Run float-inwards immediately before the strictness analyser @@ -274,9 +277,10 @@ getCoreToDo dflags runWhen call_arity $ CoreDoPasses [ CoreDoCallArity - , simpl_phase 0 ["post-call-arity"] max_iter + , simplify "post-call-arity" ], + -- Strictness analysis runWhen strictness demand_analyser, runWhen exitification CoreDoExitify, @@ -302,24 +306,24 @@ getCoreToDo dflags runWhen do_float_in CoreDoFloatInwards, - maybe_rule_check (Phase 0), + maybe_rule_check finalPhase, -- Case-liberation for -O2. This should be after -- strictness analysis and the simplification which follows it. runWhen liberate_case (CoreDoPasses [ CoreLiberateCase, - simpl_phase 0 ["post-liberate-case"] max_iter + simplify "post-liberate-case" ]), -- Run the simplifier after LiberateCase to vastly -- reduce the possibility of shadowing -- Reason: see Note [Shadowing] in GHC.Core.Opt.SpecConstr runWhen spec_constr CoreDoSpecConstr, - maybe_rule_check (Phase 0), + maybe_rule_check finalPhase, runWhen late_specialise (CoreDoPasses [ CoreDoSpecialising - , simpl_phase 0 ["post-late-spec"] max_iter]), + , simplify "post-late-spec"]), -- LiberateCase can yield new CSE opportunities because it peels -- off one layer of a recursive function (concretely, I saw this @@ -328,11 +332,10 @@ getCoreToDo dflags runWhen ((liberate_case || spec_constr) && cse) CoreCSE, -- Final clean-up simplification: - simpl_phase 0 ["final"] max_iter, + simplify "final", runWhen late_dmd_anal $ CoreDoPasses ( - dmd_cpr_ww ++ - [simpl_phase 0 ["post-late-ww"] max_iter] + dmd_cpr_ww ++ [simplify "post-late-ww"] ), -- Final run of the demand_analyser, ensures that one-shot thunks are @@ -342,7 +345,7 @@ getCoreToDo dflags -- can become /exponentially/ more expensive. See #11731, #12996. runWhen (strictness || late_dmd_anal) CoreDoDemand, - maybe_rule_check (Phase 0) + maybe_rule_check finalPhase ] -- Remove 'CoreDoNothing' and flatten 'CoreDoPasses' for clarity. ===================================== compiler/GHC/Core/Opt/Simplify.hs ===================================== @@ -43,12 +43,15 @@ import GHC.Types.Cpr ( mkCprSig, botCpr ) import GHC.Core.Ppr ( pprCoreExpr ) import GHC.Core.Unfold import GHC.Core.Utils +import GHC.Core.Arity ( etaExpand ) import GHC.Core.SimpleOpt ( pushCoTyArg, pushCoValArg , joinPointBinding_maybe, joinPointBindings_maybe ) import GHC.Core.FVs ( mkRuleInfo ) import GHC.Core.Rules ( lookupRule, getRules ) import GHC.Types.Basic ( TopLevelFlag(..), isNotTopLevel, isTopLevel, - RecFlag(..), Arity ) + RecFlag(..), InlinePragma(..), Activation(..), + SourceText(..), InlineSpec(..), activeDuringFinal, + Arity ) import GHC.Utils.Monad ( mapAccumLM, liftIO ) import GHC.Types.Var ( isTyCoVar ) import GHC.Data.Maybe ( orElse ) @@ -315,8 +318,8 @@ simplLazyBind env top_lvl is_rec bndr bndr1 rhs rhs_se -- ANF-ise a constructor or PAP rhs -- We get at most one float per argument here - ; (let_floats, body2) <- {-#SCC "prepareRhs" #-} prepareRhs (getMode env) top_lvl - (getOccFS bndr1) (idInfo bndr1) body1 + ; (let_floats, bndr2, body2) <- {-#SCC "prepareBinding" #-} + prepareBinding env top_lvl bndr bndr1 body1 ; let body_floats2 = body_floats1 `addLetFloats` let_floats ; (rhs_floats, rhs') @@ -341,7 +344,7 @@ simplLazyBind env top_lvl is_rec bndr bndr1 rhs rhs_se ; return (floats, rhs') } ; (bind_float, env2) <- completeBind (env `setInScopeFromF` rhs_floats) - top_lvl Nothing bndr bndr1 rhs' + top_lvl Nothing bndr bndr2 rhs' ; return (rhs_floats `addFloats` bind_float, env2) } -------------------------- @@ -393,16 +396,16 @@ completeNonRecX :: TopLevelFlag -> SimplEnv completeNonRecX top_lvl env is_strict old_bndr new_bndr new_rhs = ASSERT2( not (isJoinId new_bndr), ppr new_bndr ) - do { (prepd_floats, rhs1) <- prepareRhs (getMode env) top_lvl (getOccFS new_bndr) - (idInfo new_bndr) new_rhs + do { (prepd_floats, new_bndr, new_rhs) + <- prepareBinding env top_lvl old_bndr new_bndr new_rhs ; let floats = emptyFloats env `addLetFloats` prepd_floats ; (rhs_floats, rhs2) <- - if doFloatFromRhs NotTopLevel NonRecursive is_strict floats rhs1 + if doFloatFromRhs NotTopLevel NonRecursive is_strict floats new_rhs then -- Add the floats to the main env do { tick LetFloatFromLet - ; return (floats, rhs1) } + ; return (floats, new_rhs) } else -- Do not float; wrap the floats around the RHS - return (emptyFloats env, wrapFloats floats rhs1) + return (emptyFloats env, wrapFloats floats new_rhs) ; (bind_float, env2) <- completeBind (env `setInScopeFromF` rhs_floats) NotTopLevel Nothing @@ -412,12 +415,146 @@ completeNonRecX top_lvl env is_strict old_bndr new_bndr new_rhs {- ********************************************************************* * * - prepareRhs, makeTrivial + prepareBinding, prepareRhs, makeTrivial * * ************************************************************************ -Note [prepareRhs] -~~~~~~~~~~~~~~~~~ +Note [Cast worker/wrappers] +~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When we have a binding + x = e |> co +we want to do something very similar to worker/wrapper: + $wx = e + x = $wx |> co + +So now x can be inlined freely. There's a chance that e will be a +constructor application or function, or something like that, so moving +the coercion to the usage site may well cancel the coercions and lead +to further optimisation. Example: + + data family T a :: * + data instance T Int = T Int + + foo :: Int -> Int -> Int + foo m n = ... + where + t = T m + go 0 = 0 + go n = case t of { T m -> go (n-m) } + -- This case should optimise + +We call this making a cast worker/wrapper, and it'd done by prepareBinding. + +We need to be careful with inline/noinline pragmas: + rec { {-# NOINLINE f #-} + f = (...g...) |> co + ; g = ...f... } +This is legitimate -- it tells GHC to use f as the loop breaker +rather than g. Now we do the cast thing, to get something like + rec { $wf = ...g... + ; f = $wf |> co + ; g = ...f... } +Where should the NOINLINE pragma go? If we leave it on f we'll get + rec { $wf = ...g... + ; {-# NOINLINE f #-} + f = $wf |> co + ; g = ...f... } +and that is bad bad: the whole point is that we want to inline that +cast! We want to transfer the pagma to $wf: + rec { {-# NOINLINE $wf #-} + $wf = ...g... + ; f = $wf |> co + ; g = ...f... } +It's exactly like worker/wrapper for strictness analysis: + f is the wrapper and must inline like crazy + $wf is the worker and must carry f's original pragma +See Note [Worker-wrapper for NOINLINE functions] in +GHC.Core.Opt.WorkWrap. + +See #17673, #18093, #18078. + +Note [Preserve strictness in cast w/w] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In the Note [Cast worker/wrappers] transformation, keep the strictness info. +Eg + f = e `cast` co -- f has strictness SSL +When we transform to + f' = e -- f' also has strictness SSL + f = f' `cast` co -- f still has strictness SSL + +Its not wrong to drop it on the floor, but better to keep it. + +Note [Cast w/w: unlifted] +~~~~~~~~~~~~~~~~~~~~~~~~~ +BUT don't do cast worker/wrapper if 'e' has an unlifted type. +This *can* happen: + + foo :: Int = (error (# Int,Int #) "urk") + `cast` CoUnsafe (# Int,Int #) Int + +If do the makeTrivial thing to the error call, we'll get + foo = case error (# Int,Int #) "urk" of v -> v `cast` ... +But 'v' isn't in scope! + +These strange casts can happen as a result of case-of-case + bar = case (case x of { T -> (# 2,3 #); F -> error "urk" }) of + (# p,q #) -> p+q + +NOTE: Nowadays we don't use casts for these error functions; +instead, we use (case erorr ... of {}). So I'm not sure +this Note makes much sense any more. +-} + +prepareBinding :: SimplEnv -> TopLevelFlag + -> InId -> OutId -> OutExpr + -> SimplM (LetFloats, OutId, OutExpr) + +prepareBinding env top_lvl old_bndr bndr rhs + | Cast rhs1 co <- rhs + -- Try for cast worker/wrapper + -- See Note [Cast worker/wrappers] + , not (isStableUnfolding (realIdUnfolding old_bndr)) + -- Don't make a cast w/w if the thing is going to be inlined anyway + , not (exprIsTrivial rhs1) + -- Nor if the RHS is trivial; then again it'll be inlined + , let ty1 = coercionLKind co + , not (isUnliftedType ty1) + -- Not if rhs has an unlifted type; see Note [Cast w/w: unlifted] + = do { (floats, new_id) <- makeTrivialBinding (getMode env) top_lvl + (getOccFS bndr) worker_info rhs1 ty1 + ; let bndr' = bndr `setInlinePragma` mkCastWrapperInlinePrag (idInlinePragma bndr) + ; return (floats, bndr', Cast (Var new_id) co) } + + | otherwise + = do { (floats, rhs') <- prepareRhs (getMode env) top_lvl (getOccFS bndr) rhs + ; return (floats, bndr, rhs') } + where + info = idInfo bndr + worker_info = vanillaIdInfo `setStrictnessInfo` strictnessInfo info + `setCprInfo` cprInfo info + `setDemandInfo` demandInfo info + `setInlinePragInfo` inlinePragInfo info + `setArityInfo` arityInfo info + -- We do /not/ want to transfer OccInfo, Rules, Unfolding + -- Note [Preserve strictness in cast w/w] + +mkCastWrapperInlinePrag :: InlinePragma -> InlinePragma +-- See Note [Cast wrappers] +mkCastWrapperInlinePrag (InlinePragma { inl_act = act, inl_rule = rule_info }) + = InlinePragma { inl_src = SourceText "{-# INLINE" + , inl_inline = NoUserInline -- See Note [Wrapper NoUserInline] + , inl_sat = Nothing -- in GHC.Core.Opt.WorkWrap + , inl_act = wrap_act -- See Note [Wrapper activation] + , inl_rule = rule_info } -- in GHC.Core.Opt.WorkWrap + -- RuleMatchInfo is (and must be) unaffected + where + -- See Note [Wrapper activation] in GHC.Core.Opt.WorkWrap + wrap_act = case act of + NeverActive -> activeDuringFinal -- Inline late because of rules + _ -> act + +{- Note [prepareRhs] +~~~~~~~~~~~~~~~~~~~~ prepareRhs takes a putative RHS, checks whether it's a PAP or constructor application and, if so, converts it to ANF, so that the resulting thing can be inlined more easily. Thus @@ -435,26 +572,16 @@ That's what the 'go' loop in prepareRhs does -} prepareRhs :: SimplMode -> TopLevelFlag - -> FastString -- Base for any new variables - -> IdInfo -- IdInfo for the LHS of this binding + -> FastString -- Base for any new variables -> OutExpr -> SimplM (LetFloats, OutExpr) --- Transforms a RHS into a better RHS by adding floats +-- Transforms a RHS into a better RHS by ANF'ing args +-- for expandable RHSs: constructors and PAPs -- e.g x = Just e -- becomes a = e -- x = Just a -- See Note [prepareRhs] -prepareRhs mode top_lvl occ info (Cast rhs co) -- Note [Float coercions] - | let ty1 = coercionLKind co -- Do *not* do this if rhs has an unlifted type - , not (isUnliftedType ty1) -- see Note [Float coercions (unlifted)] - = do { (floats, rhs') <- makeTrivialWithInfo mode top_lvl occ sanitised_info rhs - ; return (floats, Cast rhs' co) } - where - sanitised_info = vanillaIdInfo `setStrictnessInfo` strictnessInfo info - `setCprInfo` cprInfo info - `setDemandInfo` demandInfo info - -prepareRhs mode top_lvl occ _ rhs0 +prepareRhs mode top_lvl occ rhs0 = do { (_is_exp, floats, rhs1) <- go 0 rhs0 ; return (floats, rhs1) } where @@ -498,61 +625,10 @@ prepareRhs mode top_lvl occ _ rhs0 go _ other = return (False, emptyLetFloats, other) -{- -Note [Float coercions] -~~~~~~~~~~~~~~~~~~~~~~ -When we find the binding - x = e `cast` co -we'd like to transform it to - x' = e - x = x `cast` co -- A trivial binding -There's a chance that e will be a constructor application or function, or something -like that, so moving the coercion to the usage site may well cancel the coercions -and lead to further optimisation. Example: - - data family T a :: * - data instance T Int = T Int - - foo :: Int -> Int -> Int - foo m n = ... - where - x = T m - go 0 = 0 - go n = case x of { T m -> go (n-m) } - -- This case should optimise - -Note [Preserve strictness when floating coercions] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -In the Note [Float coercions] transformation, keep the strictness info. -Eg - f = e `cast` co -- f has strictness SSL -When we transform to - f' = e -- f' also has strictness SSL - f = f' `cast` co -- f still has strictness SSL - -Its not wrong to drop it on the floor, but better to keep it. - -Note [Float coercions (unlifted)] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -BUT don't do [Float coercions] if 'e' has an unlifted type. -This *can* happen: - - foo :: Int = (error (# Int,Int #) "urk") - `cast` CoUnsafe (# Int,Int #) Int - -If do the makeTrivial thing to the error call, we'll get - foo = case error (# Int,Int #) "urk" of v -> v `cast` ... -But 'v' isn't in scope! - -These strange casts can happen as a result of case-of-case - bar = case (case x of { T -> (# 2,3 #); F -> error "urk" }) of - (# p,q #) -> p+q --} - makeTrivialArg :: SimplMode -> ArgSpec -> SimplM (LetFloats, ArgSpec) -makeTrivialArg mode (ValArg e) +makeTrivialArg mode arg@(ValArg { as_arg = e }) = do { (floats, e') <- makeTrivial mode NotTopLevel (fsLit "arg") e - ; return (floats, ValArg e') } + ; return (floats, arg { as_arg = e' }) } makeTrivialArg _ arg = return (emptyLetFloats, arg) -- CastBy, TyArg @@ -561,29 +637,32 @@ makeTrivial :: SimplMode -> TopLevelFlag -> OutExpr -- ^ This expression satisfies the let/app invariant -> SimplM (LetFloats, OutExpr) -- Binds the expression to a variable, if it's not trivial, returning the variable -makeTrivial mode top_lvl context expr - = makeTrivialWithInfo mode top_lvl context vanillaIdInfo expr - -makeTrivialWithInfo :: SimplMode -> TopLevelFlag - -> FastString -- ^ a "friendly name" to build the new binder from - -> IdInfo - -> OutExpr -- ^ This expression satisfies the let/app invariant - -> SimplM (LetFloats, OutExpr) --- Propagate strictness and demand info to the new binder --- Note [Preserve strictness when floating coercions] --- Returned SimplEnv has same substitution as incoming one -makeTrivialWithInfo mode top_lvl occ_fs info expr +makeTrivial mode top_lvl occ_fs expr | exprIsTrivial expr -- Already trivial || not (bindingOk top_lvl expr expr_ty) -- Cannot trivialise -- See Note [Cannot trivialise] = return (emptyLetFloats, expr) + | Cast expr' co <- expr + = do { (floats, triv_expr) <- makeTrivial mode top_lvl occ_fs expr' + ; return (floats, Cast triv_expr co) } + | otherwise - = do { (floats, expr1) <- prepareRhs mode top_lvl occ_fs info expr - ; if exprIsTrivial expr1 -- See Note [Trivial after prepareRhs] - then return (floats, expr1) - else do - { uniq <- getUniqueM + = do { (floats, new_id) <- makeTrivialBinding mode top_lvl occ_fs + vanillaIdInfo expr expr_ty + ; return (floats, Var new_id) } + where + expr_ty = exprType expr + +makeTrivialBinding :: SimplMode -> TopLevelFlag + -> FastString -- ^ a "friendly name" to build the new binder from + -> IdInfo + -> OutExpr -- ^ This expression satisfies the let/app invariant + -> OutType -- Type of the expression + -> SimplM (LetFloats, OutId) +makeTrivialBinding mode top_lvl occ_fs info expr expr_ty + = do { (floats, expr1) <- prepareRhs mode top_lvl occ_fs expr + ; uniq <- getUniqueM ; let name = mkSystemVarName uniq occ_fs var = mkLocalIdWithInfo name expr_ty info @@ -595,9 +674,7 @@ makeTrivialWithInfo mode top_lvl occ_fs info expr ; let final_id = addLetBndrInfo var arity is_bot unf bind = NonRec final_id expr2 - ; return ( floats `addLetFlts` unitLetFloat bind, Var final_id ) }} - where - expr_ty = exprType expr + ; return ( floats `addLetFlts` unitLetFloat bind, final_id ) } bindingOk :: TopLevelFlag -> CoreExpr -> Type -> Bool -- True iff we can have a binding of this expression at this level @@ -606,15 +683,8 @@ bindingOk top_lvl expr expr_ty | isTopLevel top_lvl = exprIsTopLevelBindable expr expr_ty | otherwise = True -{- Note [Trivial after prepareRhs] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If we call makeTrival on (e |> co), the recursive use of prepareRhs -may leave us with - { a1 = e } and (a1 |> co) -Now the latter is trivial, so we don't want to let-bind it. - -Note [Cannot trivialise] -~~~~~~~~~~~~~~~~~~~~~~~~ +{- Note [Cannot trivialise] +~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider: f :: Int -> Addr# @@ -696,7 +766,7 @@ completeBind env top_lvl mb_cont old_bndr new_bndr new_rhs -- Simplify the unfolding ; new_unfolding <- simplLetUnfolding env top_lvl mb_cont old_bndr - final_rhs (idType new_bndr) old_unf + final_rhs (idType new_bndr) new_arity old_unf ; let final_bndr = addLetBndrInfo new_bndr new_arity is_bot new_unfolding -- See Note [In-scope set as a substitution] @@ -928,6 +998,7 @@ simplExprF1 env (App fun arg) cont , sc_cont = cont } } _ -> simplExprF env fun $ ApplyToVal { sc_arg = arg, sc_env = env + , sc_hole_ty = substTy env (exprType fun) , sc_dup = NoDup, sc_cont = cont } simplExprF1 env expr@(Lam {}) cont @@ -1232,8 +1303,8 @@ rebuild env expr cont Select { sc_bndr = bndr, sc_alts = alts, sc_env = se, sc_cont = cont } -> rebuildCase (se `setInScopeFromE` env) expr bndr alts cont - StrictArg { sc_fun = fun, sc_cont = cont } - -> rebuildCall env (fun `addValArgTo` expr) cont + StrictArg { sc_fun = fun, sc_cont = cont, sc_fun_ty = fun_ty } + -> rebuildCall env (addValArgTo fun expr fun_ty ) cont StrictBind { sc_bndr = b, sc_bndrs = bs, sc_body = body , sc_env = se, sc_cont = cont } -> do { (floats1, env') <- simplNonRecX (se `setInScopeFromE` env) b expr @@ -1271,7 +1342,7 @@ In particular, we want to behave well on * (f |> co) @t1 @t2 ... @tn x1 .. xm - Here we wil use pushCoTyArg and pushCoValArg successively, which + Here we will use pushCoTyArg and pushCoValArg successively, which build up NthCo stacks. Silly to do that if co is reflexive. However, we don't want to call isReflexiveCo too much, because it uses @@ -1310,20 +1381,20 @@ simplCast env body co0 cont0 where co' = mkTransCo co1 co2 - addCoerce co cont@(ApplyToTy { sc_arg_ty = arg_ty, sc_cont = tail }) + addCoerce co (ApplyToTy { sc_arg_ty = arg_ty, sc_cont = tail }) | Just (arg_ty', m_co') <- pushCoTyArg co arg_ty - -- N.B. As mentioned in Note [The hole type in ApplyToTy] this is - -- only needed by `sc_hole_ty` which is often not forced. - -- Consequently it is worthwhile using a lazy pattern match here to - -- avoid unnecessary coercionKind evaluations. - , let hole_ty = coercionLKind co = {-#SCC "addCoerce-pushCoTyArg" #-} do { tail' <- addCoerceM m_co' tail - ; return (cont { sc_arg_ty = arg_ty' - , sc_hole_ty = hole_ty -- NB! As the cast goes past, the - -- type of the hole changes (#16312) - , sc_cont = tail' }) } - + ; return (ApplyToTy { sc_arg_ty = arg_ty' + , sc_cont = tail' + , sc_hole_ty = coercionLKind co }) } + -- NB! As the cast goes past, the + -- type of the hole changes (#16312) + + -- (f |> co) e ===> (f (e |> co1)) |> co2 + -- where co :: (s1->s2) ~ (t1~t2) + -- co1 :: t1 ~ s1 + -- co2 :: s2 ~ t2 addCoerce co cont@(ApplyToVal { sc_arg = arg, sc_env = arg_se , sc_dup = dup, sc_cont = tail }) | Just (co1, m_co2) <- pushCoValArg co @@ -1347,7 +1418,8 @@ simplCast env body co0 cont0 ; return (ApplyToVal { sc_arg = mkCast arg' co1 , sc_env = arg_se' , sc_dup = dup' - , sc_cont = tail' }) } } + , sc_cont = tail' + , sc_hole_ty = coercionLKind co }) } } addCoerce co cont | isReflexiveCo co = return cont -- Having this at the end makes a huge @@ -1426,7 +1498,7 @@ simplLamBndr env bndr | isId bndr && hasCoreUnfolding old_unf -- Special case = do { (env1, bndr1) <- simplBinder env bndr ; unf' <- simplStableUnfolding env1 NotTopLevel Nothing bndr - old_unf (idType bndr1) + (idType bndr1) (idArity bndr1) old_unf ; let bndr2 = bndr1 `setIdUnfolding` unf' ; return (modifyInScope env1 bndr2, bndr2) } @@ -1874,22 +1946,24 @@ rebuildCall env info@(ArgInfo { ai_fun = fun, ai_args = rev_args rebuildCall env info (CastIt co cont) = rebuildCall env (addCastTo info co) cont -rebuildCall env info (ApplyToTy { sc_arg_ty = arg_ty, sc_cont = cont }) - = rebuildCall env (addTyArgTo info arg_ty) cont +rebuildCall env info (ApplyToTy { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_cont = cont }) + = rebuildCall env (addTyArgTo info arg_ty hole_ty) cont -rebuildCall env info@(ArgInfo { ai_encl = encl_rules, ai_type = fun_ty +rebuildCall env info@(ArgInfo { ai_encl = encl_rules , ai_strs = str:strs, ai_discs = disc:discs }) (ApplyToVal { sc_arg = arg, sc_env = arg_se - , sc_dup = dup_flag, sc_cont = cont }) + , sc_dup = dup_flag, sc_hole_ty = fun_ty + , sc_cont = cont }) | isSimplified dup_flag -- See Note [Avoid redundant simplification] - = rebuildCall env (addValArgTo info' arg) cont + = rebuildCall env (addValArgTo info' arg fun_ty) cont | str -- Strict argument , sm_case_case (getMode env) = -- pprTrace "Strict Arg" (ppr arg $$ ppr (seIdSubst env) $$ ppr (seInScope env)) $ simplExprF (arg_se `setInScopeFromE` env) arg (StrictArg { sc_fun = info', sc_cci = cci_strict - , sc_dup = Simplified, sc_cont = cont }) + , sc_dup = Simplified, sc_fun_ty = fun_ty + , sc_cont = cont }) -- Note [Shadowing] | otherwise -- Lazy argument @@ -1899,7 +1973,7 @@ rebuildCall env info@(ArgInfo { ai_encl = encl_rules, ai_type = fun_ty -- floating a demanded let. = do { arg' <- simplExprC (arg_se `setInScopeFromE` env) arg (mkLazyArgStop arg_ty cci_lazy) - ; rebuildCall env (addValArgTo info' arg') cont } + ; rebuildCall env (addValArgTo info' arg' fun_ty) cont } where info' = info { ai_strs = strs, ai_discs = discs } arg_ty = funArgTy fun_ty @@ -2107,9 +2181,11 @@ trySeqRules in_env scrut rhs cont where no_cast_scrut = drop_casts scrut scrut_ty = exprType no_cast_scrut - seq_id_ty = idType seqId - res1_ty = piResultTy seq_id_ty rhs_rep - res2_ty = piResultTy res1_ty scrut_ty + seq_id_ty = idType seqId -- forall r a (b::TYPE r). a -> b -> b + res1_ty = piResultTy seq_id_ty rhs_rep -- forall a (b::TYPE rhs_rep). a -> b -> b + res2_ty = piResultTy res1_ty scrut_ty -- forall (b::TYPE rhs_rep). scrut_ty -> b -> b + res3_ty = piResultTy res2_ty rhs_ty -- scrut_ty -> rhs_ty -> rhs_ty + res4_ty = funResultTy res3_ty -- rhs_ty -> rhs_ty rhs_ty = substTy in_env (exprType rhs) rhs_rep = getRuntimeRep rhs_ty out_args = [ TyArg { as_arg_ty = rhs_rep @@ -2118,9 +2194,11 @@ trySeqRules in_env scrut rhs cont , as_hole_ty = res1_ty } , TyArg { as_arg_ty = rhs_ty , as_hole_ty = res2_ty } - , ValArg no_cast_scrut] + , ValArg { as_arg = no_cast_scrut + , as_hole_ty = res3_ty } ] rule_cont = ApplyToVal { sc_dup = NoDup, sc_arg = rhs - , sc_env = in_env, sc_cont = cont } + , sc_env = in_env, sc_cont = cont + , sc_hole_ty = res4_ty } -- Lazily evaluated, so we don't do most of this drop_casts (Cast e _) = drop_casts e @@ -3110,7 +3188,8 @@ mkDupableCont env (StrictBind { sc_bndr = bndr, sc_bndrs = bndrs , sc_dup = OkToDup , sc_cont = mkBoringStop res_ty } ) } -mkDupableCont env (StrictArg { sc_fun = info, sc_cci = cci, sc_cont = cont }) +mkDupableCont env (StrictArg { sc_fun = info, sc_cci = cci + , sc_cont = cont, sc_fun_ty = fun_ty }) -- See Note [Duplicating StrictArg] -- NB: sc_dup /= OkToDup; that is caught earlier by contIsDupable = do { (floats1, cont') <- mkDupableCont env cont @@ -3118,8 +3197,9 @@ mkDupableCont env (StrictArg { sc_fun = info, sc_cci = cci, sc_cont = cont }) (ai_args info) ; return ( foldl' addLetFloats floats1 floats_s , StrictArg { sc_fun = info { ai_args = args' } - , sc_cci = cci , sc_cont = cont' + , sc_cci = cci + , sc_fun_ty = fun_ty , sc_dup = OkToDup} ) } mkDupableCont env (ApplyToTy { sc_cont = cont @@ -3129,7 +3209,8 @@ mkDupableCont env (ApplyToTy { sc_cont = cont , sc_arg_ty = arg_ty, sc_hole_ty = hole_ty }) } mkDupableCont env (ApplyToVal { sc_arg = arg, sc_dup = dup - , sc_env = se, sc_cont = cont }) + , sc_env = se, sc_cont = cont + , sc_hole_ty = hole_ty }) = -- e.g. [...hole...] (...arg...) -- ==> -- let a = ...arg... @@ -3147,7 +3228,8 @@ mkDupableCont env (ApplyToVal { sc_arg = arg, sc_dup = dup -- arg'' in its in-scope set, even if makeTrivial -- has turned arg'' into a fresh variable -- See Note [StaticEnv invariant] in GHC.Core.Opt.Simplify.Utils - , sc_dup = OkToDup, sc_cont = cont' }) } + , sc_dup = OkToDup, sc_cont = cont' + , sc_hole_ty = hole_ty }) } mkDupableCont env (Select { sc_bndr = case_bndr, sc_alts = alts , sc_env = se, sc_cont = cont }) @@ -3491,11 +3573,11 @@ because we don't know its usage in each RHS separately simplLetUnfolding :: SimplEnv-> TopLevelFlag -> MaybeJoinCont -> InId - -> OutExpr -> OutType + -> OutExpr -> OutType -> Arity -> Unfolding -> SimplM Unfolding -simplLetUnfolding env top_lvl cont_mb id new_rhs rhs_ty unf +simplLetUnfolding env top_lvl cont_mb id new_rhs rhs_ty arity unf | isStableUnfolding unf - = simplStableUnfolding env top_lvl cont_mb id unf rhs_ty + = simplStableUnfolding env top_lvl cont_mb id rhs_ty arity unf | isExitJoinId id = return noUnfolding -- See Note [Do not inline exit join points] in GHC.Core.Opt.Exitify | otherwise @@ -3521,9 +3603,10 @@ mkLetUnfolding dflags top_lvl src id new_rhs simplStableUnfolding :: SimplEnv -> TopLevelFlag -> MaybeJoinCont -- Just k => a join point with continuation k -> InId - -> Unfolding -> OutType -> SimplM Unfolding + -> OutType -> Arity -> Unfolding + ->SimplM Unfolding -- Note [Setting the new unfolding] -simplStableUnfolding env top_lvl mb_cont id unf rhs_ty +simplStableUnfolding env top_lvl mb_cont id rhs_ty id_arity unf = case unf of NoUnfolding -> return unf BootUnfolding -> return unf @@ -3536,9 +3619,13 @@ simplStableUnfolding env top_lvl mb_cont id unf rhs_ty CoreUnfolding { uf_tmpl = expr, uf_src = src, uf_guidance = guide } | isStableSource src - -> do { expr' <- case mb_cont of -- See Note [Rules and unfolding for join points] - Just cont -> simplJoinRhs unf_env id expr cont - Nothing -> simplExprC unf_env expr (mkBoringStop rhs_ty) + -> do { expr' <- case mb_cont of + Just cont -> -- Binder is a join point + -- See Note [Rules and unfolding for join points] + simplJoinRhs unf_env id expr cont + Nothing -> -- Binder is not a join point + do { expr' <- simplExprC unf_env expr (mkBoringStop rhs_ty) + ; return (eta_expand expr') } ; case guide of UnfWhen { ug_arity = arity , ug_unsat_ok = sat_ok @@ -3575,7 +3662,41 @@ simplStableUnfolding env top_lvl mb_cont id unf rhs_ty unf_env = updMode (updModeForStableUnfoldings act) env -- See Note [Simplifying inside stable unfoldings] in GHC.Core.Opt.Simplify.Utils -{- + -- See Note [Eta-expand stable unfoldings] + eta_expand expr + | not eta_on = expr + | exprIsTrivial expr = expr + | otherwise = etaExpand id_arity expr + eta_on = sm_eta_expand (getMode env) + +{- Note [Eta-expand stable unfoldings] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +For INLINE/INLINABLE things (which get stable unfoldings) there's a danger +of getting + f :: Int -> Int -> Int -> Blah + [ Arity = 3 -- Good arity + , Unf=Stable (\xy. blah) -- Less good arity, only 2 + f = \pqr. e + +This can happen because f's RHS is optimised more vigorously than +its stable unfolding. Now suppose we have a call + g = f x +Because f has arity=3, g will have arity=2. But if we inline f (using +its stable unfolding) g's arity will reduce to 1, because +hasn't been optimised yet. This happened in the 'parsec' library, +for Text.Pasec.Char.string. + +Generally, if we know that 'f' has arity N, it seems sensible to +eta-expand the stable unfolding to arity N too. Simple and consistent. + +Wrinkles +* Don't eta-expand a trivial expr, else each pass will eta-reduce it, + and then eta-expand again. See Note [Do not eta-expand trivial expressions] + in GHC.Core.Opt.Simplify.Utils. +* Don't eta-expand join points; see Note [Do not eta-expand join points] + in GHC.Core.Opt.Simplify.Utils. We uphold this because the join-point + case (mb_cont = Just _) doesn't use eta_expand. + Note [Force bottoming field] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ We need to force bottoming, or the new unfolding holds ===================================== compiler/GHC/Core/Opt/Simplify/Utils.hs ===================================== @@ -118,7 +118,9 @@ data SimplCont SimplCont | ApplyToVal -- (ApplyToVal arg K)[e] = K[ e arg ] - { sc_dup :: DupFlag -- See Note [DupFlag invariants] + { sc_dup :: DupFlag -- See Note [DupFlag invariants] + , sc_hole_ty :: OutType -- Type of the function, presumably (forall a. blah) + -- See Note [The hole type in ApplyToTy/Val] , sc_arg :: InExpr -- The argument, , sc_env :: StaticEnv -- see Note [StaticEnv invariant] , sc_cont :: SimplCont } @@ -126,7 +128,7 @@ data SimplCont | ApplyToTy -- (ApplyToTy ty K)[e] = K[ e ty ] { sc_arg_ty :: OutType -- Argument type , sc_hole_ty :: OutType -- Type of the function, presumably (forall a. blah) - -- See Note [The hole type in ApplyToTy] + -- See Note [The hole type in ApplyToTy/Val] , sc_cont :: SimplCont } | Select -- (Select alts K)[e] = K[ case e of alts ] @@ -151,6 +153,9 @@ data SimplCont , sc_fun :: ArgInfo -- Specifies f, e1..en, Whether f has rules, etc -- plus strictness flags for *further* args , sc_cci :: CallCtxt -- Whether *this* argument position is interesting + , sc_fun_ty :: OutType -- Type of the function (f e1 .. en), + -- presumably (arg_ty -> res_ty) + -- where res_ty is expected by sc_cont , sc_cont :: SimplCont } | TickIt -- (TickIt t K)[e] = K[ tick t e ] @@ -254,8 +259,6 @@ data ArgInfo ai_fun :: OutId, -- The function ai_args :: [ArgSpec], -- ...applied to these args (which are in *reverse* order) - ai_type :: OutType, -- Type of (f a1 ... an) - ai_rules :: FunRules, -- Rules for this function ai_encl :: Bool, -- Flag saying whether this function @@ -271,37 +274,36 @@ data ArgInfo } data ArgSpec - = ValArg OutExpr -- Apply to this (coercion or value); c.f. ApplyToVal + = ValArg { as_arg :: OutExpr -- Apply to this (coercion or value); c.f. ApplyToVal + , as_hole_ty :: OutType } -- Type of the function (presumably t1 -> t2) | TyArg { as_arg_ty :: OutType -- Apply to this type; c.f. ApplyToTy , as_hole_ty :: OutType } -- Type of the function (presumably forall a. blah) | CastBy OutCoercion -- Cast by this; c.f. CastIt instance Outputable ArgSpec where - ppr (ValArg e) = text "ValArg" <+> ppr e + ppr (ValArg { as_arg = arg }) = text "ValArg" <+> ppr arg ppr (TyArg { as_arg_ty = ty }) = text "TyArg" <+> ppr ty ppr (CastBy c) = text "CastBy" <+> ppr c -addValArgTo :: ArgInfo -> OutExpr -> ArgInfo -addValArgTo ai arg = ai { ai_args = ValArg arg : ai_args ai - , ai_type = applyTypeToArg (ai_type ai) arg - , ai_rules = decRules (ai_rules ai) } +addValArgTo :: ArgInfo -> OutExpr -> OutType -> ArgInfo +addValArgTo ai arg hole_ty = ai { ai_args = arg_spec : ai_args ai + , ai_rules = decRules (ai_rules ai) } + where + arg_spec = ValArg { as_arg = arg, as_hole_ty = hole_ty } -addTyArgTo :: ArgInfo -> OutType -> ArgInfo -addTyArgTo ai arg_ty = ai { ai_args = arg_spec : ai_args ai - , ai_type = piResultTy poly_fun_ty arg_ty - , ai_rules = decRules (ai_rules ai) } +addTyArgTo :: ArgInfo -> OutType -> OutType -> ArgInfo +addTyArgTo ai arg_ty hole_ty = ai { ai_args = arg_spec : ai_args ai + , ai_rules = decRules (ai_rules ai) } where - poly_fun_ty = ai_type ai - arg_spec = TyArg { as_arg_ty = arg_ty, as_hole_ty = poly_fun_ty } + arg_spec = TyArg { as_arg_ty = arg_ty, as_hole_ty = hole_ty } addCastTo :: ArgInfo -> OutCoercion -> ArgInfo -addCastTo ai co = ai { ai_args = CastBy co : ai_args ai - , ai_type = coercionRKind co } +addCastTo ai co = ai { ai_args = CastBy co : ai_args ai } argInfoAppArgs :: [ArgSpec] -> [OutExpr] argInfoAppArgs [] = [] argInfoAppArgs (CastBy {} : _) = [] -- Stop at a cast -argInfoAppArgs (ValArg e : as) = e : argInfoAppArgs as +argInfoAppArgs (ValArg { as_arg = arg } : as) = arg : argInfoAppArgs as argInfoAppArgs (TyArg { as_arg_ty = ty } : as) = Type ty : argInfoAppArgs as pushSimplifiedArgs :: SimplEnv -> [ArgSpec] -> SimplCont -> SimplCont @@ -310,7 +312,9 @@ pushSimplifiedArgs env (arg : args) k = case arg of TyArg { as_arg_ty = arg_ty, as_hole_ty = hole_ty } -> ApplyToTy { sc_arg_ty = arg_ty, sc_hole_ty = hole_ty, sc_cont = rest } - ValArg e -> ApplyToVal { sc_arg = e, sc_env = env, sc_dup = Simplified, sc_cont = rest } + ValArg { as_arg = arg, as_hole_ty = hole_ty } + -> ApplyToVal { sc_arg = arg, sc_env = env, sc_dup = Simplified + , sc_hole_ty = hole_ty, sc_cont = rest } CastBy c -> CastIt c rest where rest = pushSimplifiedArgs env args k @@ -323,7 +327,7 @@ argInfoExpr fun rev_args = go rev_args where go [] = Var fun - go (ValArg a : as) = go as `App` a + go (ValArg { as_arg = arg } : as) = go as `App` arg go (TyArg { as_arg_ty = ty } : as) = go as `App` Type ty go (CastBy co : as) = mkCast (go as) co @@ -409,11 +413,9 @@ contHoleType (TickIt _ k) = contHoleType k contHoleType (CastIt co _) = coercionLKind co contHoleType (StrictBind { sc_bndr = b, sc_dup = dup, sc_env = se }) = perhapsSubstTy dup se (idType b) -contHoleType (StrictArg { sc_fun = ai }) = funArgTy (ai_type ai) -contHoleType (ApplyToTy { sc_hole_ty = ty }) = ty -- See Note [The hole type in ApplyToTy] -contHoleType (ApplyToVal { sc_arg = e, sc_env = se, sc_dup = dup, sc_cont = k }) - = mkVisFunTy (perhapsSubstTy dup se (exprType e)) - (contHoleType k) +contHoleType (StrictArg { sc_fun_ty = ty }) = funArgTy ty +contHoleType (ApplyToTy { sc_hole_ty = ty }) = ty -- See Note [The hole type in ApplyToTy/Val] +contHoleType (ApplyToVal { sc_hole_ty = ty }) = ty -- See Note [The hole type in ApplyToTy/Val] contHoleType (Select { sc_dup = d, sc_bndr = b, sc_env = se }) = perhapsSubstTy d se (idType b) @@ -458,13 +460,13 @@ mkArgInfo :: SimplEnv mkArgInfo env fun rules n_val_args call_cont | n_val_args < idArity fun -- Note [Unsaturated functions] - = ArgInfo { ai_fun = fun, ai_args = [], ai_type = fun_ty + = ArgInfo { ai_fun = fun, ai_args = [] , ai_rules = fun_rules , ai_encl = False , ai_strs = vanilla_stricts , ai_discs = vanilla_discounts } | otherwise - = ArgInfo { ai_fun = fun, ai_args = [], ai_type = fun_ty + = ArgInfo { ai_fun = fun, ai_args = [] , ai_rules = fun_rules , ai_encl = interestingArgContext rules call_cont , ai_strs = arg_stricts @@ -1076,7 +1078,7 @@ seems to be to do a callSiteInline based on the fact that there is something interesting about the call site (it's strict). Hmm. That seems a bit fragile. -Conclusion: inline top level things gaily until Phase 0 (the last +Conclusion: inline top level things gaily until finalPhase (the last phase), at which point don't. Note [pre/postInlineUnconditionally in gentle mode] @@ -1199,23 +1201,21 @@ preInlineUnconditionally env top_lvl bndr rhs rhs_env -- not ticks. Counting ticks cannot be duplicated, and non-counting -- ticks around a Lam will disappear anyway. - early_phase = case sm_phase mode of - Phase 0 -> False - _ -> True --- If we don't have this early_phase test, consider --- x = length [1,2,3] --- The full laziness pass carefully floats all the cons cells to --- top level, and preInlineUnconditionally floats them all back in. --- Result is (a) static allocation replaced by dynamic allocation --- (b) many simplifier iterations because this tickles --- a related problem; only one inlining per pass --- --- On the other hand, I have seen cases where top-level fusion is --- lost if we don't inline top level thing (e.g. string constants) --- Hence the test for phase zero (which is the phase for all the final --- simplifications). Until phase zero we take no special notice of --- top level things, but then we become more leery about inlining --- them. + early_phase = not (isFinalPhase (sm_phase mode)) + -- If we don't have this early_phase test, consider + -- x = length [1,2,3] + -- The full laziness pass carefully floats all the cons cells to + -- top level, and preInlineUnconditionally floats them all back in. + -- Result is (a) static allocation replaced by dynamic allocation + -- (b) many simplifier iterations because this tickles + -- a related problem; only one inlining per pass + -- + -- On the other hand, I have seen cases where top-level fusion is + -- lost if we don't inline top level thing (e.g. string constants) + -- Hence the test for phase zero (which is the phase for all the final + -- simplifications). Until phase zero we take no special notice of + -- top level things, but then we become more leery about inlining + -- them. {- ************************************************************************ @@ -1530,7 +1530,7 @@ tryEtaExpandRhs mode bndr rhs return (new_arity, is_bot, new_rhs) } where try_expand - | exprIsTrivial rhs + | exprIsTrivial rhs -- See Note [Do not eta-expand trivial expressions] = return (exprArity rhs, False, rhs) | sm_eta_expand mode -- Provided eta-expansion is on @@ -1574,9 +1574,17 @@ because then 'genMap' will inline, and it really shouldn't: at least as far as the programmer is concerned, it's not applied to two arguments! +Note [Do not eta-expand trivial expressions] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Do not eta-expand a trivial RHS like + f = g +If we eta expand do + f = \x. g x +we'll just eta-reduce again, and so on; so the +simplifier never terminates. + Note [Do not eta-expand join points] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Similarly to CPR (see Note [Don't w/w join points for CPR] in GHC.Core.Opt.WorkWrap), a join point stands well to gain from its outer binding's eta-expansion, and eta-expanding a join point is fraught with issues like how to ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -1760,8 +1760,8 @@ Note [Transfer activation] In which phase should the specialise-constructor rules be active? Originally I made them always-active, but Manuel found that this defeated some clever user-written rules. Then I made them active only -in Phase 0; after all, currently, the specConstr transformation is -only run after the simplifier has reached Phase 0, but that meant +in finalPhase; after all, currently, the specConstr transformation is +only run after the simplifier has reached finalPhase, but that meant that specialisations didn't fire inside wrappers; see test simplCore/should_compile/spec-inline. ===================================== compiler/GHC/Core/Opt/WorkWrap.hs ===================================== @@ -245,8 +245,8 @@ NOINLINE pragma to the worker. (See #13143 for a real-world example.) It is crucial that we do this for *all* NOINLINE functions. #10069 -demonstrates what happens when we promise to w/w a (NOINLINE) leaf function, but -fail to deliver: +demonstrates what happens when we promise to w/w a (NOINLINE) leaf +function, but fail to deliver: data C = C Int# Int# @@ -426,8 +426,15 @@ Reminder: Note [Don't w/w INLINE things], so we don't need to worry Conclusion: - If the user said NOINLINE[n], respect that - - If the user said NOINLINE, inline the wrapper as late as - poss (phase 0). This is a compromise driven by (2) above + + - If the user said NOINLINE, inline the wrapper only after + phase 0, the last user-visible phase. That means that all + rules will have had a chance to fire. + + What phase is after phase 0? Answer: finalPhase, phase (-1). + That's the reason finalPhase exists. NB: user's can't write + INLINE[-1] f; it's syntactically illegal. + - Otherwise inline wrapper in phase 2. That allows the 'gentle' simplification pass to apply specialisation rules @@ -575,8 +582,8 @@ splitFun dflags fam_envs fn_id fn_info wrap_dmds div cpr rhs 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 + NoInline -> inl_act fn_inl_prag + _ -> inl_act wrap_prag work_prag = InlinePragma { inl_src = SourceText "{-# INLINE" , inl_inline = fn_inline_spec @@ -626,19 +633,7 @@ splitFun dflags fam_envs fn_id fn_info wrap_dmds div cpr rhs | 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_prag = mkStrWrapperInlinePrag fn_inl_prag wrap_id = fn_id `setIdUnfolding` mkWwInlineRule dflags wrap_rhs arity `setInlinePragma` wrap_prag `setIdOccInfo` noOccInfo @@ -655,8 +650,6 @@ splitFun dflags fam_envs fn_id fn_info wrap_dmds div cpr rhs rhs_fvs = exprFreeVars rhs 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 @@ -674,6 +667,20 @@ splitFun dflags fam_envs fn_id fn_info wrap_dmds div cpr rhs | otherwise = topCpr +mkStrWrapperInlinePrag :: InlinePragma -> InlinePragma +mkStrWrapperInlinePrag (InlinePragma { inl_act = act, inl_rule = rule_info }) + = InlinePragma { inl_src = SourceText "{-# INLINE" + , inl_inline = NoUserInline -- See Note [Wrapper NoUserInline] + , inl_sat = Nothing + , inl_act = wrap_act -- See Note [Wrapper activation] + , inl_rule = rule_info } -- RuleMatchInfo is (and must be) unaffected + where + wrap_act = case act of -- See Note [Wrapper activation] + ActiveAfter {} -> act + NeverActive -> activeDuringFinal + _ -> activeAfterInitial + + {- Note [Demand on the worker] ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Core/SimpleOpt.hs ===================================== @@ -1340,8 +1340,7 @@ pushCoTyArg co ty | otherwise = Nothing where - tyL = coercionLKind co - tyR = coercionRKind co + Pair tyL tyR = coercionKind co -- co :: tyL ~ tyR -- tyL = forall (a1 :: k1). ty1 -- tyR = forall (a2 :: k2). ty2 ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -51,7 +51,7 @@ module GHC.Core.Type ( splitPiTy_maybe, splitPiTy, splitPiTys, mkTyConBindersPreferAnon, mkPiTy, mkPiTys, - mkLamType, mkLamTypes, + mkLamType, mkLamTypes, mkFunctionType, piResultTy, piResultTys, applyTysX, dropForAlls, mkFamilyTyConApp, @@ -256,7 +256,7 @@ import {-# SOURCE #-} GHC.Core.Coercion , mkTyConAppCo, mkAppCo, mkCoVarCo, mkAxiomRuleCo , mkForAllCo, mkFunCo, mkAxiomInstCo, mkUnivCo , mkSymCo, mkTransCo, mkNthCo, mkLRCo, mkInstCo - , mkKindCo, mkSubCo, mkFunCo, mkAxiomInstCo + , mkKindCo, mkSubCo , decomposePiCos, coercionKind, coercionLKind , coercionRKind, coercionType , isReflexiveCo, seqCo ) @@ -1517,6 +1517,8 @@ mkLamType :: Var -> Type -> Type mkLamTypes :: [Var] -> Type -> Type -- ^ 'mkLamType' for multiple type or value arguments +mkLamTypes vs ty = foldr mkLamType ty vs + mkLamType v body_ty | isTyVar v = ForAllTy (Bndr v Inferred) body_ty @@ -1525,43 +1527,19 @@ mkLamType v body_ty , v `elemVarSet` tyCoVarsOfType body_ty = ForAllTy (Bndr v Required) body_ty - | isPredTy arg_ty -- See Note [mkLamType: dictionary arguments] - = mkInvisFunTy arg_ty body_ty - | otherwise - = mkVisFunTy arg_ty body_ty - where - arg_ty = varType v - -mkLamTypes vs ty = foldr mkLamType ty vs + = mkFunctionType (varType v) body_ty -{- Note [mkLamType: dictionary arguments] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If we have (\ (d :: Ord a). blah), we want to give it type - (Ord a => blah_ty) -with a fat arrow; that is, using mkInvisFunTy, not mkVisFunTy. -Why? After all, we are in Core, where (=>) and (->) behave the same. -Yes, but the /specialiser/ does treat dictionary arguments specially. -Suppose we do w/w on 'foo' in module A, thus (#11272, #6056) - foo :: Ord a => Int -> blah - foo a d x = case x of I# x' -> $wfoo @a d x' +mkFunctionType :: Type -> Type -> Type +-- This one works out the AnonArgFlag from the argument type +-- See GHC.Types.Var Note [AnonArgFlag] +mkFunctionType arg_ty res_ty + | isPredTy arg_ty -- See GHC.Types.Var Note [AnonArgFlag] + = mkInvisFunTy arg_ty res_ty - $wfoo :: Ord a => Int# -> blah - -Now in module B we see (foo @Int dOrdInt). The specialiser will -specialise this to $sfoo, where - $sfoo :: Int -> blah - $sfoo x = case x of I# x' -> $wfoo @Int dOrdInt x' - -Now we /must/ also specialise $wfoo! But it wasn't user-written, -and has a type built with mkLamTypes. - -Conclusion: the easiest thing is to make mkLamType build - (c => ty) -when the argument is a predicate type. See GHC.Core.TyCo.Rep -Note [Types for coercions, predicates, and evidence] --} + | otherwise + = mkVisFunTy arg_ty res_ty -- | Given a list of type-level vars and the free vars of a result kind, -- makes TyCoBinders, preferring anonymous binders ===================================== compiler/GHC/Core/Unfold.hs ===================================== @@ -412,6 +412,8 @@ inlineBoringOk e , exprIsTrivial a = go (credit-1) f go credit (Tick _ e) = go credit e -- dubious go credit (Cast e _) = go credit e + go credit (Case scrut _ _ [(_,_,rhs)]) -- See Note [Inline unsafeCoerce] + | isUnsafeEqualityProof scrut = go credit rhs go _ (Var {}) = boringCxtOk go _ _ = boringCxtNotOk @@ -459,7 +461,21 @@ calcUnfoldingGuidance dflags is_top_bottoming expr | otherwise = (+) -- See Note [Function and non-function discounts] -{- +{- Note [Inline unsafeCoerce] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +We really want to inline unsafeCoerce, even when applied to boring +arguments. It doesn't look as if its RHS is smaller than the call + unsafeCoerce x = case unsafeEqualityProof @a @b of UnsafeRefl -> x +but that case is discarded -- see Note [Implementing unsafeCoerce] +in base:Unsafe.Coerce. + +Moreover, if we /don't/ inline it, we may be left with + f (unsafeCoerce x) +which will build a thunk -- bad, bad, bad. + +Conclusion: we really want inlineBoringOk to be True of the RHS of +unsafeCoerce. This is (U4a) in Note [Implementing unsafeCoerce]. + Note [Computing the size of an expression] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The basic idea of sizeExpr is obvious enough: count nodes. But getting the ===================================== compiler/GHC/Core/Utils.hs ===================================== @@ -56,6 +56,9 @@ module GHC.Core.Utils ( -- * Join points isJoinBind, + -- * unsafeEqualityProof + isUnsafeEqualityProof, + -- * Dumping stuff dumpIdInfoOfProgram ) where @@ -66,7 +69,7 @@ import GHC.Prelude import GHC.Platform import GHC.Core -import GHC.Builtin.Names ( makeStaticName ) +import GHC.Builtin.Names ( makeStaticName, unsafeEqualityProofName ) import GHC.Core.Ppr import GHC.Core.FVs( exprFreeVars ) import GHC.Types.Var @@ -2533,3 +2536,20 @@ dumpIdInfoOfProgram ppr_id_info binds = vcat (map printId ids) getIds (Rec bs) = map fst bs printId id | isExportedId id = ppr id <> colon <+> (ppr_id_info (idInfo id)) | otherwise = empty + + +{- ********************************************************************* +* * + unsafeEqualityProof +* * +********************************************************************* -} + +isUnsafeEqualityProof :: CoreExpr -> Bool +-- See (U3) and (U4) in +-- Note [Implementing unsafeCoerce] in base:Unsafe.Coerce +isUnsafeEqualityProof e + | Var v `App` Type _ `App` Type _ `App` Type _ <- e + = idName v == unsafeEqualityProofName + | otherwise + = False + ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -1011,15 +1011,6 @@ cpExprIsTrivial e | otherwise = exprIsTrivial e -isUnsafeEqualityProof :: CoreExpr -> Bool --- See (U3) and (U4) in --- Note [Implementing unsafeCoerce] in base:Unsafe.Coerce -isUnsafeEqualityProof e - | Var v `App` Type _ `App` Type _ `App` Type _ <- e - = idName v == unsafeEqualityProofName - | otherwise - = False - -- This is where we arrange that a non-trivial argument is let-bound cpeArg :: CorePrepEnv -> Demand -> CoreArg -> Type -> UniqSM (Floats, CpeArg) ===================================== compiler/GHC/Types/Basic.hs ===================================== @@ -83,6 +83,7 @@ module GHC.Types.Basic ( Activation(..), isActive, isActiveIn, competesWith, isNeverActive, isAlwaysActive, isEarlyActive, activeAfterInitial, activeDuringFinal, + finalPhase, isFinalPhase, RuleMatchInfo(..), isConLike, isFunLike, InlineSpec(..), noUserInlineSpec, @@ -1300,6 +1301,25 @@ pprWithSourceText (SourceText src) _ = text src ************************************************************************ When a rule or inlining is active + +Note [Compiler phases] +~~~~~~~~~~~~~~~~~~~~~~ +The CompilerPhase says which phase the simplifier is running in: + +* InitialPhase: before all user-visible phases + +* Phase 2,1,0: user-visible phases; the phase number + controls rule ordering an inlining. + +* Phase (-1) = finalPhase: used for all subsequent simplifier + runs. By delaying inlining of wrappers to phase (-1) we can + ensure that RULE have a good chance to fire. See + Note [Wrapper activation] in GHC.Core.Opt.WorkWrap + + Note: users don't have access to phase (-1); it's syntactically + illegal to write {-# INLINE[-1] f #-} + +The phase sequencing is done by GHC.Opt.Simplify.Driver -} -- | Phase Number @@ -1317,12 +1337,21 @@ instance Outputable CompilerPhase where activeAfterInitial :: Activation -- Active in the first phase after the initial phase --- Currently we have just phases [2,1,0] +-- Currently we have just phases [2,1,0,-1] +-- Where "-1" means GHC's internal simplification steps +-- after all rules have run activeAfterInitial = ActiveAfter NoSourceText 2 activeDuringFinal :: Activation -- Active in the final simplification phase (which is repeated) -activeDuringFinal = ActiveAfter NoSourceText 0 +activeDuringFinal = ActiveAfter NoSourceText (-1) + +finalPhase :: CompilerPhase +finalPhase = Phase (-1) + +isFinalPhase :: CompilerPhase -> Bool +isFinalPhase (Phase (-1)) = True +isFinalPhase _ = False -- See note [Pragma source text] data Activation = NeverActive ===================================== compiler/GHC/Types/Var.hs ===================================== @@ -465,10 +465,10 @@ instance Binary ArgFlag where _ -> return Inferred -- | The non-dependent version of 'ArgFlag'. - --- Appears here partly so that it's together with its friend ArgFlag, --- but also because it is used in IfaceType, rather early in the --- compilation chain +-- See Note [AnonArgFlag] +-- Appears here partly so that it's together with its friends ArgFlag +-- and ForallVisFlag, but also because it is used in IfaceType, rather +-- early in the compilation chain -- See Note [AnonArgFlag vs. ForallVisFlag] data AnonArgFlag = VisArg -- ^ Used for @(->)@: an ordinary non-dependent arrow. @@ -511,7 +511,60 @@ argToForallVisFlag Required = ForallVis argToForallVisFlag Specified = ForallInvis argToForallVisFlag Inferred = ForallInvis -{- +{- Note [AnonArgFlag] +~~~~~~~~~~~~~~~~~~~~~ +AnonArgFlag is used principally in the FunTy constructor of Type. + FunTy VisArg t1 t2 means t1 -> t2 + FunTy InvisArg t1 t2 means t1 => t2 + +However, the AnonArgFlag in a FunTy is just redundant, cached +information. In (FunTy { ft_af = af, ft_arg = t1, ft_res = t2 }) + * if (isPredTy t1 = True) then af = InvisArg + * if (isPredTy t1 = False) then af = VisArg +where isPredTy is defined in GHC.Core.Type, and sees if t1's +kind is Constraint. See GHC.Core.TyCo.Rep +Note [Types for coercions, predicates, and evidence] + +GHC.Core.Type.mkFunctionType :: Type -> Type -> Type +uses isPredTy to decide the AnonArgFlag for the FunTy. + +The term (Lam b e), and coercion (FunCo co1 co2) don't carry +AnonArgFlags; instead they use mkFunctionType when we want to +get their types; see mkLamType and coercionLKind/RKind resp. +This is just an engineering choice; we could cache here too +if we wanted. + +Why bother with all this? After all, we are in Core, where (=>) and +(->) behave the same. We maintain this distinction throughout Core so +that we can cheaply and conveniently determine +* How to print a type +* How to split up a type: tcSplitSigmaTy +* How to specialise it (over type classes; GHC.Core.Opt.Specialise) + +For the specialisation point, consider +(\ (d :: Ord a). blah). We want to give it type + (Ord a => blah_ty) +with a fat arrow; that is, using mkInvisFunTy, not mkVisFunTy. +Why? Because the /specialiser/ treats dictionary arguments specially. +Suppose we do w/w on 'foo', thus (#11272, #6056) + foo :: Ord a => Int -> blah + foo a d x = case x of I# x' -> $wfoo @a d x' + + $wfoo :: Ord a => Int# -> blah + +Now, at a call we see (foo @Int dOrdInt). The specialiser will +specialise this to $sfoo, where + $sfoo :: Int -> blah + $sfoo x = case x of I# x' -> $wfoo @Int dOrdInt x' + +Now we /must/ also specialise $wfoo! But it wasn't user-written, +and has a type built with mkLamTypes. + +Conclusion: the easiest thing is to make mkLamType build + (c => ty) +when the argument is a predicate type. See GHC.Core.TyCo.Rep +Note [Types for coercions, predicates, and evidence] + Note [AnonArgFlag vs. ForallVisFlag] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The AnonArgFlag and ForallVisFlag data types are quite similar at a first @@ -522,15 +575,19 @@ glance: Both data types keep track of visibility of some sort. AnonArgFlag tracks whether a FunTy has a visible argument (->) or an invisible predicate argument -(=>). ForallVisFlag tracks whether a `forall` quantifier is visible -(forall a -> {...}) or invisible (forall a. {...}). - -Given their similarities, it's tempting to want to combine these two data types -into one, but they actually represent distinct concepts. AnonArgFlag reflects a -property of *Core* types, whereas ForallVisFlag reflects a property of the GHC -AST. In other words, AnonArgFlag is all about internals, whereas ForallVisFlag -is all about surface syntax. Therefore, they are kept as separate data types. --} +(=>). ForallVisFlag tracks whether a `forall` quantifier in a user-specified +HsType is + visible: forall a -> {...} + invisible: forall a. {...} +In fact the visible form can currently only appear in kinds. + +Given their similarities, it's tempting to want to combine these two +data types into one, but they actually represent distinct +concepts. AnonArgFlag reflects a property of *Core* types, whereas +ForallVisFlag reflects a property of the HsSyn source-code AST. In +other words, AnonArgFlag is all about internals, whereas ForallVisFlag +is all about surface syntax. Therefore, they are kept as separate data +types. -} {- ********************************************************************* * * ===================================== libraries/base/Unsafe/Coerce.hs ===================================== @@ -22,7 +22,6 @@ import GHC.Natural () -- See Note [Depend on GHC.Natural] in GHC.Base import GHC.Types {- Note [Implementing unsafeCoerce] - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The implementation of unsafeCoerce is surprisingly subtle. This Note describes the moving parts. You will find more @@ -126,9 +125,13 @@ several ways Flaoting the case is OK here, even though it broardens the scope, becuase we are done with simplification. -(U4) GHC.CoreToStg.Prep.cpeExprIsTrivial anticipated the +(U4) GHC.CoreToStg.Prep.cpeExprIsTrivial anticipates the upcoming discard of unsafeEqualityProof. +(U4a) Ditto GHC.Core.Unfold.inlineBoringOk we want to treat + the RHS of unsafeCoerce as very small; see + Note [Inline unsafeCoerce] in that module. + (U5) The definition of unsafeEqualityProof in Unsafe.Coerce looks very strange: unsafeEqualityProof = case unsafeEqualityProof @a @b of @@ -161,7 +164,7 @@ several ways to simplify the ase when the two tpyes are equal. (U8) The is a super-magic RULE in GHC.base - map cocerce = coerce + map coerce = coerce (see Note [Getting the map/coerce RULE to work] in CoreOpt) But it's all about turning coerce into a cast, and unsafeCoerce no longer does that. So we need a separate map/unsafeCoerce ===================================== testsuite/tests/codeGen/should_compile/debug.stdout ===================================== @@ -18,6 +18,7 @@ src src src src +src == CBE == src 89 ===================================== testsuite/tests/deSugar/should_compile/T2431.stderr ===================================== @@ -4,7 +4,7 @@ Result size of Tidy Core = {terms: 63, types: 43, coercions: 1, joins: 0/0} -- RHS size: {terms: 2, types: 4, coercions: 1, joins: 0/0} -T2431.$WRefl [InlPrag=INLINE[0] CONLIKE] :: forall a. a :~: a +T2431.$WRefl [InlPrag=INLINE[-1] CONLIKE] :: forall a. a :~: a [GblId[DataConWrapper], Caf=NoCafRefs, Cpr=m1, ===================================== testsuite/tests/perf/compiler/T16473.stdout ===================================== @@ -1,10 +1,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 $p1Applicative (BUILTIN) +Rule fired: Class op <$ (BUILTIN) Rule fired: Class op <*> (BUILTIN) +Rule fired: Class op $p1Applicative (BUILTIN) Rule fired: Class op fmap (BUILTIN) Rule fired: Class op pure (BUILTIN) Rule fired: Class op pure (BUILTIN) ===================================== testsuite/tests/simplCore/should_compile/T13143.stderr ===================================== @@ -12,7 +12,7 @@ T13143.$wf = \ (@a) _ [Occ=Dead] -> T13143.$wf @a GHC.Prim.void# end Rec } -- RHS size: {terms: 4, types: 4, coercions: 0, joins: 0/0} -f [InlPrag=NOUSERINLINE[0]] :: forall a. Int -> a +f [InlPrag=NOUSERINLINE[-1]] :: forall a. Int -> a [GblId, Arity=1, Str=b, ===================================== testsuite/tests/simplCore/should_compile/T3772.stdout ===================================== @@ -62,7 +62,7 @@ T3772.$wfoo } -- RHS size: {terms: 6, types: 3, coercions: 0, joins: 0/0} -foo [InlPrag=NOUSERINLINE[0]] :: Int -> () +foo [InlPrag=NOUSERINLINE[-1]] :: Int -> () [GblId, Arity=1, Str=, ===================================== testsuite/tests/simplCore/should_compile/T7360.stderr ===================================== @@ -4,7 +4,7 @@ Result size of Tidy Core = {terms: 106, types: 47, coercions: 0, joins: 0/0} -- RHS size: {terms: 6, types: 3, coercions: 0, joins: 0/0} -T7360.$WFoo3 [InlPrag=INLINE[0] CONLIKE] :: Int -> Foo +T7360.$WFoo3 [InlPrag=INLINE[-1] CONLIKE] :: Int -> Foo [GblId[DataConWrapper], Arity=1, Caf=NoCafRefs, ===================================== testsuite/tests/simplCore/should_compile/T7865.stdout ===================================== @@ -1,6 +1,6 @@ T7865.$wexpensive [InlPrag=NOINLINE] T7865.$wexpensive -expensive [InlPrag=NOUSERINLINE[0]] :: Int -> Int +expensive [InlPrag=NOUSERINLINE[-1]] :: Int -> Int case T7865.$wexpensive ww1 of ww2 [Occ=Once] { __DEFAULT -> expensive case T7865.$wexpensive ww1 of ww2 { __DEFAULT -> GHC.Types.I# ww2 } ===================================== testsuite/tests/stranal/should_compile/Makefile ===================================== @@ -10,3 +10,9 @@ T13031: # take only one Int# argument T16029: '$(TEST_HC)' $(TEST_HC_OPTS) -c -O -fforce-recomp T16029.hs -dsuppress-uniques -ddump-simpl | grep '::.*Int' + +T18078: + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O -fforce-recomp T18078.hs -dsuppress-uniques -ddump-simpl | grep 'wf' + +T17673: + '$(TEST_HC)' $(TEST_HC_OPTS) -c -O -fforce-recomp T17673.hs -dsuppress-uniques -ddump-simpl | grep 'wf' ===================================== testsuite/tests/stranal/should_compile/T16029.stdout ===================================== @@ -1,4 +1,4 @@ -T16029.$WMkT [InlPrag=INLINE[0] CONLIKE] :: Int -> Int -> T +T16029.$WMkT [InlPrag=INLINE[-1] CONLIKE] :: Int -> Int -> T Tmpl= \ (dt [Occ=Once!] :: Int) (dt [Occ=Once!] :: Int) -> = \ (dt [Occ=Once!] :: Int) (dt [Occ=Once!] :: Int) -> :: GHC.Prim.Int# -> GHC.Prim.Int# ===================================== testsuite/tests/stranal/should_compile/T17673.hs ===================================== @@ -0,0 +1,6 @@ +module T17673 where + +facIO :: Int -> IO Int +facIO n | n < 2 = return 1 + | otherwise = do n' <- facIO (n-1); return (n*n') +{-# NOINLINE facIO #-} ===================================== testsuite/tests/stranal/should_compile/T17673.stdout ===================================== @@ -0,0 +1,5 @@ +T17673.$wfacIO [InlPrag=NOINLINE, Occ=LoopBreaker] +T17673.$wfacIO + case T17673.$wfacIO (GHC.Prim.-# ww 1#) w of { (# ipv, ipv1 #) -> + T17673.$wfacIO ww1 w1 + case w of { GHC.Types.I# ww1 -> T17673.$wfacIO ww1 w1 } ===================================== testsuite/tests/stranal/should_compile/T18078.hs ===================================== @@ -0,0 +1,13 @@ +module T18078 where + +newtype N = N { unN :: Int -> Int } + +-- This an example of a worker/wrapper thing +-- See Note [Cast worker/wrappers] in Simplify +-- We should get good code, with a $wf calling itself +-- but in 8.10 we do not +f :: N +{-# NOINLINE f #-} +f = N (\n -> if n==0 then 0 else unN f (n-1)) + +g x = unN f (x+1) ===================================== testsuite/tests/stranal/should_compile/T18078.stdout ===================================== @@ -0,0 +1,6 @@ +T18078.$wf [InlPrag=NOINLINE, Occ=LoopBreaker] +T18078.$wf + __DEFAULT -> T18078.$wf (GHC.Prim.-# wild 1#); + case T18078.$wf ww1 of ww2 [Occ=Once] { __DEFAULT -> + case T18078.$wf ww1 of ww2 { __DEFAULT -> GHC.Types.I# ww2 } + case T18078.$wf (GHC.Prim.+# x1 1#) of ww { __DEFAULT -> ===================================== testsuite/tests/stranal/should_compile/all.T ===================================== @@ -52,3 +52,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']) test('T13380b', [ grep_errmsg('bigDeadAction') ], compile, ['-dppr-cols=200 -ddump-simpl']) +test('T18078', normal, makefile_test, []) +test('T17673', normal, makefile_test, []) + View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/10b0b9b1f2f06986d30c4fd511f4e4bbb7e62168 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/10b0b9b1f2f06986d30c4fd511f4e4bbb7e62168 You're receiving 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 22 16:17:44 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Fri, 22 May 2020 12:17:44 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18086 Message-ID: <5ec7fb28e94ea_6e263f9eea2381ec832444@gitlab.haskell.org.mail> Sebastian Graf pushed new branch wip/T18086 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18086 You're receiving 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 22 17:18:24 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Fri, 22 May 2020 13:18:24 -0400 Subject: [Git][ghc/ghc][wip/T18086] DmdAnal: Recognise precise exceptions from case alternatives (#18086) Message-ID: <5ec80960446c1_6e263f9ee27f806c850177@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/T18086 at Glasgow Haskell Compiler / GHC Commits: 5205b85a by Sebastian Graf at 2020-05-22T19:18:08+02:00 DmdAnal: Recognise precise exceptions from case alternatives (#18086) Consider ```hs m :: IO () m = do putStrLn "foo" error "bar" ``` `m` (from #18086) always throws a (precise or imprecise) exception or diverges. Yet demand analysis infers `<L,A>` as demand signature instead of `<L,A>x` for it. That's because the demand analyser sees `putStrLn` occuring in a case scrutinee and decides that it has to `deferAfterPreciseException`, because `putStrLn` throws a precise exception on some control flow paths. This will mask the `botDiv` `Divergence`of the single case alt containing `error` to `topDiv`. Since `putStrLn` has `topDiv` itself, the final `Divergence` is `topDiv`. This is easily fixed: `deferAfterPreciseException` works by `lub`ing with the demand type of a virtual case branch denoting the precise exceptional control flow. We used `nopDmdType` before, but we can be more precise and use `exnDmdType`, which is `nopDmdType` with `exnDiv`. Now the `Divergence` from the case alt will degrade `botDiv` to `exnDiv` instead of `topDiv`, which combines with the result from the scrutinee to `exnDiv`, and all is well. Fixes #18086. - - - - - 4 changed files: - compiler/GHC/Types/Demand.hs - + testsuite/tests/stranal/sigs/T18086.hs - + testsuite/tests/stranal/sigs/T18086.stderr - testsuite/tests/stranal/sigs/all.T Changes: ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -1055,11 +1055,19 @@ Is this strict in 'y'? Often not! If @foo x s@ might throw a precise exception (ultimately via raiseIO#), then we must not force 'y', which may fail to terminate or throw an imprecise exception, until we have performed @foo x s at . -So we have to 'Demand.deferAfterPreciseException' (which just 'lub's with -'nopDmdType' to model the exceptional control flow) when @foo x s@ -may throw a precise exception. Motivated by T13380{d,e,f}. +So we have to 'deferAfterPreciseException' (which 'lub's with 'exnDmdType' to +model the exceptional control flow) when @foo x s@ may throw a precise +exception. Motivated by T13380{d,e,f}. See Note [Which scrutinees may throw precise exceptions] in DmdAnal. +We have to be careful not to discard dead-end Divergence from case +alternatives, though (#18086): + + m = putStrLn "foo" >> error "bar" + +'m' should still have 'exnDiv', which is why it is not sufficient to lub with +'nopDmdType' (which has 'topDiv') in 'deferAfterPreciseException'. + Historical Note: This used to be called the "IO hack". But that term is rather a bad fit because 1. It's easily confused with the "State hack", which also affects IO. @@ -1261,6 +1269,11 @@ isTopDmdType :: DmdType -> Bool isTopDmdType (DmdType env args div) = div == topDiv && null args && isEmptyVarEnv env +-- | The demand type of an unspecified expression that is guaranteed to +-- throw a (precise or imprecise) exception or diverge. +exnDmdType :: DmdType +exnDmdType = DmdType emptyDmdEnv [] exnDiv + dmdTypeDepth :: DmdType -> Arity dmdTypeDepth (DmdType _ ds _) = length ds @@ -1303,13 +1316,17 @@ splitDmdTy (DmdType fv (dmd:dmds) res_ty) = (dmd, DmdType fv dmds res_ty) splitDmdTy ty@(DmdType _ [] res_ty) = (defaultArgDmd res_ty, ty) -- | When e is evaluated after executing an IO action that may throw a precise --- exception, and d is e's demand, then what of this demand should we consider? --- * We have to kill all strictness demands (i.e. lub with a lazy demand) --- * We can keep usage information (i.e. lub with an absent demand) --- * We have to kill definite divergence +-- exception, we act as if there is an additional control flow path that is +-- taken if e throws a precise exception. The demand type of this control flow +-- path +-- * is lazy and absent ('topDmd') in all free variables and arguments +-- * has 'exnDiv' 'Divergence' result +-- So we can simply take a variant of 'nopDmdType', 'exnDmdType'. +-- Why not 'nopDmdType'? Because then the result of 'e' can never be 'exnDiv'! +-- That means failure to drop dead-ends, see #18086. -- See Note [Precise exceptions and strictness analysis] deferAfterPreciseException :: DmdType -> DmdType -deferAfterPreciseException d = lubDmdType d nopDmdType +deferAfterPreciseException = lubDmdType exnDmdType strictenDmd :: Demand -> CleanDemand strictenDmd (JD { sd = s, ud = u}) ===================================== testsuite/tests/stranal/sigs/T18086.hs ===================================== @@ -0,0 +1,9 @@ +{-# OPTIONS_GHC -O2 -fforce-recomp #-} +module T18086 where + +-- Should have strictness signature x, emphasis on the exceptional +-- divergence result. +m :: IO () +m = do + putStrLn "foo" + error "bar" ===================================== testsuite/tests/stranal/sigs/T18086.stderr ===================================== @@ -0,0 +1,18 @@ + +==================== Strictness signatures ==================== +T18086.$trModule: +T18086.m: x + + + +==================== Cpr signatures ==================== +T18086.$trModule: +T18086.m: b + + + +==================== Strictness signatures ==================== +T18086.$trModule: +T18086.m: x + + ===================================== testsuite/tests/stranal/sigs/all.T ===================================== @@ -22,3 +22,4 @@ test('T5075', normal, compile, ['']) test('T17932', normal, compile, ['']) test('T13380c', expect_broken('!3014'), compile, ['']) test('T13380f', normal, compile, ['']) +test('T18086', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5205b85a058b0ae88a76cba9932b159da9296511 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5205b85a058b0ae88a76cba9932b159da9296511 You're receiving 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 22 17:25:04 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 22 May 2020 13:25:04 -0400 Subject: [Git][ghc/ghc][ghc-8.10] Note platform-specific Foreign.C.Types in context Message-ID: <5ec80af028276_6e263f9ee27f806c85664b@gitlab.haskell.org.mail> Ben Gamari pushed to branch ghc-8.10 at Glasgow Haskell Compiler / GHC Commits: 37956be4 by Viktor Dukhovni at 2020-05-21T17:42:48-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. - - - - - 1 changed file: - libraries/base/Foreign/C/Types.hs Changes: ===================================== libraries/base/Foreign/C/Types.hs ===================================== @@ -27,11 +27,11 @@ module Foreign.C.Types ( -- * Representations of C types -- $ctypes - -- ** Platform differences + -- ** #platform# Platform differences -- | This module contains platform specific information about types. - -- __/As such the types presented on this page reflect the platform - -- on which the documentation was generated and may not coincide with - -- the types on your platform./__ + -- __/As such, the types presented on this page reflect the/__ + -- __/platform on which the documentation was generated and may/__ + -- __/not coincide with the types on your platform./__ -- ** Integral types -- | These types are represented as @newtype at s of @@ -105,33 +105,45 @@ import GHC.Num #include "CTypes.h" -- | Haskell type representing the C @char@ type. +-- /(The concrete types of "Foreign.C.Types#platform" are platform-specific.)/ INTEGRAL_TYPE(CChar,HTYPE_CHAR) -- | Haskell type representing the C @signed char@ type. +-- /(The concrete types of "Foreign.C.Types#platform" are platform-specific.)/ INTEGRAL_TYPE(CSChar,HTYPE_SIGNED_CHAR) -- | Haskell type representing the C @unsigned char@ type. +-- /(The concrete types of "Foreign.C.Types#platform" are platform-specific.)/ INTEGRAL_TYPE(CUChar,HTYPE_UNSIGNED_CHAR) -- | Haskell type representing the C @short@ type. +-- /(The concrete types of "Foreign.C.Types#platform" are platform-specific.)/ INTEGRAL_TYPE(CShort,HTYPE_SHORT) -- | Haskell type representing the C @unsigned short@ type. +-- /(The concrete types of "Foreign.C.Types#platform" are platform-specific.)/ INTEGRAL_TYPE(CUShort,HTYPE_UNSIGNED_SHORT) -- | Haskell type representing the C @int@ type. +-- /(The concrete types of "Foreign.C.Types#platform" are platform-specific.)/ INTEGRAL_TYPE(CInt,HTYPE_INT) -- | Haskell type representing the C @unsigned int@ type. +-- /(The concrete types of "Foreign.C.Types#platform" are platform-specific.)/ INTEGRAL_TYPE(CUInt,HTYPE_UNSIGNED_INT) -- | Haskell type representing the C @long@ type. +-- /(The concrete types of "Foreign.C.Types#platform" are platform-specific.)/ INTEGRAL_TYPE(CLong,HTYPE_LONG) -- | Haskell type representing the C @unsigned long@ type. +-- /(The concrete types of "Foreign.C.Types#platform" are platform-specific.)/ INTEGRAL_TYPE(CULong,HTYPE_UNSIGNED_LONG) -- | Haskell type representing the C @long long@ type. +-- /(The concrete types of "Foreign.C.Types#platform" are platform-specific.)/ INTEGRAL_TYPE(CLLong,HTYPE_LONG_LONG) -- | Haskell type representing the C @unsigned long long@ type. +-- /(The concrete types of "Foreign.C.Types#platform" are platform-specific.)/ INTEGRAL_TYPE(CULLong,HTYPE_UNSIGNED_LONG_LONG) -- | Haskell type representing the C @bool@ type. +-- /(The concrete types of "Foreign.C.Types#platform" are platform-specific.)/ -- -- @since 4.10.0.0 INTEGRAL_TYPE_WITH_CTYPE(CBool,bool,HTYPE_BOOL) @@ -164,8 +176,10 @@ INTEGRAL_TYPE_WITH_CTYPE(CBool,bool,HTYPE_BOOL) #-} -- | Haskell type representing the C @float@ type. +-- /(The concrete types of "Foreign.C.Types#platform" are platform-specific.)/ FLOATING_TYPE(CFloat,HTYPE_FLOAT) -- | Haskell type representing the C @double@ type. +-- /(The concrete types of "Foreign.C.Types#platform" are platform-specific.)/ FLOATING_TYPE(CDouble,HTYPE_DOUBLE) -- XXX GHC doesn't support CLDouble yet @@ -182,12 +196,16 @@ FLOATING_TYPE(CDouble,HTYPE_DOUBLE) -- "realToFrac/CLDouble->a" realToFrac = \(CLDouble x) -> realToFrac x -- | Haskell type representing the C @ptrdiff_t@ type. +-- /(The concrete types of "Foreign.C.Types#platform" are platform-specific.)/ INTEGRAL_TYPE(CPtrdiff,HTYPE_PTRDIFF_T) -- | Haskell type representing the C @size_t@ type. +-- /(The concrete types of "Foreign.C.Types#platform" are platform-specific.)/ INTEGRAL_TYPE(CSize,HTYPE_SIZE_T) -- | Haskell type representing the C @wchar_t@ type. +-- /(The concrete types of "Foreign.C.Types#platform" are platform-specific.)/ INTEGRAL_TYPE(CWchar,HTYPE_WCHAR_T) -- | Haskell type representing the C @sig_atomic_t@ type. +-- /(The concrete types of "Foreign.C.Types#platform" are platform-specific.)/ INTEGRAL_TYPE(CSigAtomic,HTYPE_SIG_ATOMIC_T) {-# RULES @@ -203,25 +221,32 @@ INTEGRAL_TYPE(CSigAtomic,HTYPE_SIG_ATOMIC_T) #-} -- | Haskell type representing the C @clock_t@ type. +-- /(The concrete types of "Foreign.C.Types#platform" are platform-specific.)/ ARITHMETIC_TYPE(CClock,HTYPE_CLOCK_T) -- | Haskell type representing the C @time_t@ type. +-- /(The concrete types of "Foreign.C.Types#platform" are platform-specific.)/ ARITHMETIC_TYPE(CTime,HTYPE_TIME_T) -- | Haskell type representing the C @useconds_t@ type. +-- /(The concrete types of "Foreign.C.Types#platform" are platform-specific.)/ -- -- @since 4.4.0.0 ARITHMETIC_TYPE(CUSeconds,HTYPE_USECONDS_T) -- | Haskell type representing the C @suseconds_t@ type. +-- /(The concrete types of "Foreign.C.Types#platform" are platform-specific.)/ -- -- @since 4.4.0.0 ARITHMETIC_TYPE(CSUSeconds,HTYPE_SUSECONDS_T) -- FIXME: Implement and provide instances for Eq and Storable -- | Haskell type representing the C @FILE@ type. +-- /(The concrete types of "Foreign.C.Types#platform" are platform-specific.)/ data CFile = CFile -- | Haskell type representing the C @fpos_t@ type. +-- /(The concrete types of "Foreign.C.Types#platform" are platform-specific.)/ data CFpos = CFpos -- | Haskell type representing the C @jmp_buf@ type. +-- /(The concrete types of "Foreign.C.Types#platform" are platform-specific.)/ data CJmpBuf = CJmpBuf INTEGRAL_TYPE(CIntPtr,HTYPE_INTPTR_T) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/37956be4958a260c884a20e08ca3bf00a9622e6f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/37956be4958a260c884a20e08ca3bf00a9622e6f You're receiving 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 22 17:46:17 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 22 May 2020 13:46:17 -0400 Subject: [Git][ghc/ghc][wip/T18210] 32 commits: Remove duplicate Note [When to print foralls] in GHC.Core.TyCo.Ppr Message-ID: <5ec80fe940f70_6e263f9ed4e7a6a0860447@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18210 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] - - - - - 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 - - - - - 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 - - - - - 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. - - - - - 78c6523c by Ben Gamari at 2020-05-21T12:13:01-04:00 nonmoving: Optimise the write barrier - - - - - 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). - - - - - 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 - - - - - b7a6b2f4 by Gleb Popov at 2020-05-21T12:15:26-04:00 gitlab-ci: Set locale to C.UTF-8. - - - - - 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. - - - - - 0004ccb8 by Tuan Le at 2020-05-21T12:16:46-04:00 llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 - - - - - 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 - - - - - 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 - - - - - 2b363ebb by Richard Eisenberg at 2020-05-21T12:18:45-04:00 MR template should ask for key part - - - - - a95bbd0b by Sebastian Graf at 2020-05-21T12:19:37-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. - - - - - d3d055b8 by Galen Huntington at 2020-05-21T12:20:18-04:00 Clarify pitfalls of NegativeLiterals; see #18022. - - - - - 1b508a9e by Alexey Kuleshevich at 2020-05-21T12:21:02-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" - - - - - 4ca0c8a1 by Andreas Klebinger at 2020-05-21T12:21: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. - - - - - a1275081 by Krzysztof Gogolewski at 2020-05-21T12:22:35-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 - - - - - 8a816e5f by Krzysztof Gogolewski at 2020-05-21T12:23:55-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. - - - - - 566cc73f by Sylvain Henry at 2020-05-21T12:24:45-04:00 Move isDynLinkName into GHC.Types.Name It doesn't belong into GHC.Unit.State - - - - - 38767a1a by Ben Gamari at 2020-05-22T13:45:48-04:00 eventlog: Fix racy flushing Previously no attempt was made to avoid multiple threads writing their capability-local eventlog buffers to the eventlog writer simultaneously. This could result in multiple eventlog streams being interleaved. Fix this by documenting that the EventLogWriter's write() and flush() functions may be called reentrantly and fix the default writer to protect its FILE* by a mutex. Fixes #18210. - - - - - 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/59a3abc7ff06c6fa34cca6555f44d91e79a5d26e...38767a1af42202549cd1e30d0e71dc50ea9347ff -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/59a3abc7ff06c6fa34cca6555f44d91e79a5d26e...38767a1af42202549cd1e30d0e71dc50ea9347ff You're receiving 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 22 19:15:11 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 22 May 2020 15:15:11 -0400 Subject: [Git][ghc/ghc][wip/runRW] 63 commits: rts/CNF: Fix fixup comparison function Message-ID: <5ec824bf77515_6e263f9ed469e080871346@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/runRW 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. - - - - - 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] - - - - - 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 - - - - - 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 - - - - - 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. - - - - - 78c6523c by Ben Gamari at 2020-05-21T12:13:01-04:00 nonmoving: Optimise the write barrier - - - - - 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). - - - - - 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 - - - - - b7a6b2f4 by Gleb Popov at 2020-05-21T12:15:26-04:00 gitlab-ci: Set locale to C.UTF-8. - - - - - 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. - - - - - 0004ccb8 by Tuan Le at 2020-05-21T12:16:46-04:00 llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 - - - - - 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 - - - - - 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 - - - - - 2b363ebb by Richard Eisenberg at 2020-05-21T12:18:45-04:00 MR template should ask for key part - - - - - a95bbd0b by Sebastian Graf at 2020-05-21T12:19:37-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. - - - - - d3d055b8 by Galen Huntington at 2020-05-21T12:20:18-04:00 Clarify pitfalls of NegativeLiterals; see #18022. - - - - - 1b508a9e by Alexey Kuleshevich at 2020-05-21T12:21:02-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" - - - - - 4ca0c8a1 by Andreas Klebinger at 2020-05-21T12:21: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. - - - - - a1275081 by Krzysztof Gogolewski at 2020-05-21T12:22:35-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 - - - - - 8a816e5f by Krzysztof Gogolewski at 2020-05-21T12:23:55-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. - - - - - 566cc73f by Sylvain Henry at 2020-05-21T12:24:45-04:00 Move isDynLinkName into GHC.Types.Name It doesn't belong into GHC.Unit.State - - - - - e3777291 by Ben Gamari at 2020-05-22T15:14:46-04:00 CoreToStg: Add Outputable ArgInfo instance - - - - - df285125 by Simon Peyton Jones at 2020-05-22T15:14:46-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. - - - - - 31f1c568 by Simon Peyton Jones at 2020-05-22T15:14:46-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. - - - - - 5a2cdd5c by Ben Gamari at 2020-05-22T15:14:51-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 Metric Decrease: ManyConstructors Co-Authored-By: Simon Peyton-Jone <simonpj at microsoft.com> - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/merge_request_templates/merge-request.md - compiler/GHC.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.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/Arity.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/ConLike.hs - compiler/GHC/Core/DataCon.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0f2f1060a5d13b0fcfb1226ec8ca44643f1eb205...5a2cdd5c2f69992a59fa57b9dc46f6ed71864ef6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0f2f1060a5d13b0fcfb1226ec8ca44643f1eb205...5a2cdd5c2f69992a59fa57b9dc46f6ed71864ef6 You're receiving 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 22 20:39:47 2020 From: gitlab at gitlab.haskell.org (Daneel S. Yaitskov) Date: Fri, 22 May 2020 16:39:47 -0400 Subject: [Git][ghc/ghc][wip/T17949] 4 commits: T17949 rename withEventlog/whenEventlog Message-ID: <5ec8389362849_6e263f9ed6fef2048943ad@gitlab.haskell.org.mail> Daneel S. Yaitskov pushed to branch wip/T17949 at Glasgow Haskell Compiler / GHC Commits: ca7fa6b1 by Daneel Yaitskov at 2020-05-22T13:29:59-07:00 T17949 rename withEventlog/whenEventlog - - - - - 88c1d3cb by Daneel Yaitskov at 2020-05-22T13:30:58-07:00 T17949 inline whenEventlog - - - - - 3730961d by Daneel Yaitskov at 2020-05-22T13:35:12-07:00 T17949 remove whenEventlog from traceIO - - - - - fca165f0 by Daneel Yaitskov at 2020-05-22T13:35:48-07:00 T17949 remove double whenEventlog - - - - - 1 changed file: - libraries/base/Debug/Trace.hs Changes: ===================================== libraries/base/Debug/Trace.hs ===================================== @@ -77,12 +77,13 @@ import Data.List (null, partition) foreign import ccall "&eventlog_enabled" eventlog_enabled :: Ptr CBool --- | The 'withEventlog' function evals argument action +-- | The 'whenEventlog' function evals argument action -- if RTS eventlog (+RTS -l) is enabled. -- -- @since 4.14.0.0 -withEventlog :: IO () -> IO () -withEventlog logAction = do +{-# INLINE whenEventlog #-} +whenEventlog :: IO () -> IO () +whenEventlog logAction = do ee <- peek eventlog_enabled if toBool ee then logAction @@ -93,7 +94,7 @@ withEventlog logAction = do -- -- @since 4.5.0.0 traceIO :: String -> IO () -traceIO msg = withEventlog $ do +traceIO msg = withCString "%s\n" $ \cfmt -> do -- NB: debugBelch can't deal with null bytes, so filter them -- out so we don't accidentally truncate the message. See #9395 @@ -270,7 +271,7 @@ traceStack str expr = unsafePerformIO $ do -- @since 4.5.0.0 traceEvent :: String -> a -> a traceEvent msg expr = unsafeDupablePerformIO $ do - withEventlog $ traceEventIO msg + traceEventIO msg return expr -- | The 'traceEventIO' function emits a message to the eventlog, if eventlog @@ -282,7 +283,7 @@ traceEvent msg expr = unsafeDupablePerformIO $ do -- @since 4.5.0.0 traceEventIO :: String -> IO () traceEventIO msg = - withEventlog $ GHC.Foreign.withCString utf8 msg $ \(Ptr p) -> IO $ \s -> + whenEventlog $ GHC.Foreign.withCString utf8 msg $ \(Ptr p) -> IO $ \s -> case traceEvent# p s of s' -> (# s', () #) -- $markers @@ -320,7 +321,7 @@ traceEventIO msg = -- @since 4.7.0.0 traceMarker :: String -> a -> a traceMarker msg expr = unsafeDupablePerformIO $ do - withEventlog $ traceMarkerIO msg + traceMarkerIO msg return expr -- | The 'traceMarkerIO' function emits a marker to the eventlog, if eventlog @@ -332,5 +333,5 @@ traceMarker msg expr = unsafeDupablePerformIO $ do -- @since 4.7.0.0 traceMarkerIO :: String -> IO () traceMarkerIO msg = - withEventlog $ GHC.Foreign.withCString utf8 msg $ \(Ptr p) -> IO $ \s -> + whenEventlog $ GHC.Foreign.withCString utf8 msg $ \(Ptr p) -> IO $ \s -> case traceMarker# p s of s' -> (# s', () #) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d833b98b15d51d0ec67d283cd2749d03e70ca3c1...fca165f00d97179a91c2b95d86a8e5c2400c9c75 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d833b98b15d51d0ec67d283cd2749d03e70ca3c1...fca165f00d97179a91c2b95d86a8e5c2400c9c75 You're receiving 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 22 21:29:54 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 22 May 2020 17:29:54 -0400 Subject: [Git][ghc/ghc][ghc-8.8] Bump process to 1.6.9.0 Message-ID: <5ec84452d741a_6e263f9ee3522300907944@gitlab.haskell.org.mail> Ben Gamari pushed to branch ghc-8.8 at Glasgow Haskell Compiler / GHC Commits: dade73c7 by Ben Gamari at 2020-05-22T17:29:38-04:00 Bump process to 1.6.9.0 - - - - - 1 changed file: - libraries/process Changes: ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit 26ea79ceb2193a86f76a302a126be3319f22700d +Subproject commit 5a0cbd46eca6d30b78726688058b7fd258a2253d View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dade73c7849d05bc50d35e4c8411e2fdbba75f2a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dade73c7849d05bc50d35e4c8411e2fdbba75f2a You're receiving 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 22 22:04:53 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Fri, 22 May 2020 18:04:53 -0400 Subject: [Git][ghc/ghc][wip/T18191] WIP: T18191 Message-ID: <5ec84c853841b_6e261151364490813@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T18191 at Glasgow Haskell Compiler / GHC Commits: 50bab0e8 by Ryan Scott at 2020-05-22T18:01:17-04:00 WIP: T18191 TODO RGS: Write that commit message [ci skip] - - - - - 21 changed files: - compiler/GHC/Hs/Types.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/ThToHs.hs - docs/users_guide/8.12.1-notes.rst - docs/users_guide/exts/explicit_forall.rst - docs/users_guide/exts/gadt_syntax.rst - testsuite/tests/dependent/should_fail/T16326_Fail6.stderr - testsuite/tests/gadt/T12087.stderr - testsuite/tests/gadt/T14320.hs - + testsuite/tests/gadt/T14320.stderr - testsuite/tests/gadt/T16427.stderr - + testsuite/tests/gadt/T18191.hs - + testsuite/tests/gadt/T18191.stderr - testsuite/tests/gadt/all.T - testsuite/tests/ghc-api/annotations/T10399.stdout - testsuite/tests/ghc-api/annotations/Test10399.hs - testsuite/tests/parser/should_compile/T15323.hs - testsuite/tests/parser/should_compile/T15323.stderr Changes: ===================================== compiler/GHC/Hs/Types.hs ===================================== @@ -57,8 +57,9 @@ module GHC.Hs.Types ( hsLTyVarName, hsLTyVarNames, hsLTyVarLocName, hsExplicitLTyVarNames, splitLHsInstDeclTy, getLHsInstDeclHead, getLHsInstDeclClass_maybe, splitLHsPatSynTy, - splitLHsForAllTyInvis, splitLHsQualTy, splitLHsSigmaTyInvis, - splitHsFunType, hsTyGetAppHead_maybe, + splitLHsForAllTyInvis, splitLHsQualTy, + splitLHsSigmaTyInvis, splitNestedLHsSigmaTysInvis, + splitLHsFunTys, hsTyGetAppHead_maybe, mkHsOpTy, mkHsAppTy, mkHsAppTys, mkHsAppKindTy, ignoreParens, hsSigType, hsSigWcType, hsPatSigType, hsLTyVarBndrToType, hsLTyVarBndrsToTypes, @@ -1227,18 +1228,44 @@ mkHsAppKindTy ext ty k -} --------------------------------- --- splitHsFunType decomposes a type (t1 -> t2 ... -> tn) --- Breaks up any parens in the result type: --- splitHsFunType (a -> (b -> c)) = ([a,b], c) -splitHsFunType :: LHsType GhcRn -> ([LHsType GhcRn], LHsType GhcRn) -splitHsFunType (L _ (HsParTy _ ty)) - = splitHsFunType ty - -splitHsFunType (L _ (HsFunTy _ x y)) - | (args, res) <- splitHsFunType y +-- | 'splitLHsFunTys' decomposes a type @t1 -> t2 ... -> tn@ into the argument +-- and result types. For example: +-- +-- @ +-- 'splitLHsFunTys' (a -> b -> c) = ([a,b], c) +-- @ +-- +-- Note that this function looks through parentheses, so it will work on types +-- such as @(a -> (b -> c))@. The downside to this is that it is not +-- generally possible to take the returned types and reconstruct the original +-- type (parentheses and all) from them. +splitLHsFunTys :: LHsType GhcRn -> ([LHsType GhcRn], LHsType GhcRn) +splitLHsFunTys (L _ (HsParTy _ ty)) + = splitLHsFunTys ty + +splitLHsFunTys (L _ (HsFunTy _ x y)) + | (args, res) <- splitLHsFunTys y = (x:args, res) -splitHsFunType other = ([], other) +splitLHsFunTys other = ([], other) + +-- | Returns 'Just (arg_ty, res_ty)@ if the supplied type is an 'HsFunTy', +-- where @arg_ty@ and @res_ty@ are the decomposed argument and result types, +-- respectively. Returns 'Nothing' otherwise. For example: +-- +-- @ +-- 'splitLHsFunTy_maybe' (a -> b) = 'Just' (a, b) +-- 'splitLHsFunTy_maybe' [a] = 'Nothing' +-- @ +-- +-- Note that this function looks through parentheses, so it will work on types +-- such as @((a -> b))@. The downside to this is that it is not +-- generally possible to take the returned types and reconstruct the original +-- type (parentheses and all) from them. +splitLHsFunTy_maybe :: LHsType pass -> Maybe (LHsType pass, LHsType pass) +splitLHsFunTy_maybe (L _ (HsParTy _ ty)) = splitLHsFunTy_maybe ty +splitLHsFunTy_maybe (L _ (HsFunTy _ x y)) = Just (x, y) +splitLHsFunTy_maybe _ = Nothing -- retrieve the name of the "head" of a nested type application -- somewhat like splitHsAppTys, but a little more thorough @@ -1332,6 +1359,67 @@ splitLHsSigmaTyInvis ty , (ctxt, ty2) <- splitLHsQualTy ty1 = (tvs, ctxt, ty2) +-- | Decompose a type's @forall at s and contexts from its body, possibly looking +-- underneath 'HsFunTy's in the process. For example: +-- +-- @ +-- 'splitNestedLHsSigmaTysInvis' (forall a. a -> Show a => forall b. b -> a) +-- = ([a, b], [Show a], [a -> b -> a]) +-- @ +-- +-- Note that this function looks through parentheses, so it will work on types +-- such as @(forall a. <...>)@. The downside to this is that it is not +-- generally possible to take the returned types and reconstruct the original +-- type (parentheses and all) from them. +splitNestedLHsSigmaTysInvis :: + LHsType (GhcPass p) + -> ([LHsTyVarBndr (GhcPass p)], LHsContext (GhcPass p), LHsType (GhcPass p)) +splitNestedLHsSigmaTysInvis ty + -- If there's a forall, split it apart and try splitting the rho type + -- underneath it. + | Just (arg_tys, tvs1, theta1, rho1) <- deepSplitLHsSigmaTyInvis_maybe ty + = let (tvs2, theta2, rho2) = splitNestedLHsSigmaTysInvis rho1 + in ( tvs1 ++ tvs2 + , append_lhs_contexts theta1 theta2 + , foldr mk_lhs_fun_ty rho2 arg_tys ) + -- If there's no forall, we're done. + | otherwise = ([], noLHsContext, ty) + where + append_lhs_contexts :: LHsContext (GhcPass p) -> LHsContext (GhcPass p) + -> LHsContext (GhcPass p) + append_lhs_contexts (L _ ctxt1) (L _ ctxt2) = noLoc $ ctxt1 ++ ctxt2 + + mk_lhs_fun_ty :: LHsType (GhcPass p) -> LHsType (GhcPass p) + -> LHsType (GhcPass p) + mk_lhs_fun_ty arg_ty res_ty = noLoc $ HsFunTy noExtField arg_ty res_ty + +-- | Helper function for 'deepSplitLHsSigmaTyInvis_maybe' that decomposes a +-- function type's arguments, followed by any @forall at s and contexts that +-- appear after the last function arrow. For example: +-- +-- @ +-- 'deepSplitLHsSigmaTyInvis_maybe' (Int -> Char -> forall a. Show a => a -> b) +-- = ([Int, Char], [a], [Show a], [a -> b]) +-- @ +-- +-- Note that this function looks through parentheses, so it will work on types +-- such as @(forall a. <...>)@. The downside to this is that it is not +-- generally possible to take the returned types and reconstruct the original +-- type (parentheses and all) from them. +deepSplitLHsSigmaTyInvis_maybe :: + LHsType pass + -> Maybe ([LHsType pass], [LHsTyVarBndr pass], LHsContext pass, LHsType pass) +deepSplitLHsSigmaTyInvis_maybe ty + | Just (arg_ty, res_ty) <- splitLHsFunTy_maybe ty + , Just (arg_tys, tvs, theta, rho) <- deepSplitLHsSigmaTyInvis_maybe res_ty + = Just (arg_ty:arg_tys, tvs, theta, rho) + + | (tvs, theta, rho) <- splitLHsSigmaTyInvis ty + , not (null tvs && null (unLoc theta)) + = Just ([], tvs, theta, rho) + + | otherwise = Nothing + -- | Decompose a type of the form @forall . body@ into its constituent -- parts. Note that only /invisible/ @forall at s -- (i.e., @forall a.@, with a dot) are split apart; /visible/ @forall at s ===================================== compiler/GHC/Parser.y ===================================== @@ -2235,9 +2235,8 @@ gadt_constr :: { LConDecl GhcPs } -- see Note [Difference in parsing GADT and data constructors] -- Returns a list because of: C,D :: ty : con_list '::' sigtypedoc - {% let (gadt,anns) = mkGadtDecl (unLoc $1) $3 - in ams (sLL $1 $> gadt) - (mu AnnDcolon $2:anns) } + {% ams (sLL $1 $> (mkGadtDecl (unLoc $1) $3)) + [mu AnnDcolon $2] } {- Note [Difference in parsing GADT and data constructors] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -663,30 +663,41 @@ mkConDeclH98 name mb_forall mb_cxt args , con_args = args , con_doc = Nothing } +-- Construct a GADT-style data constructor from the constructor names and their +-- type. Does not perform any validity checking, as that it done later in +-- GHC.Rename.Module.rnConDecl. mkGadtDecl :: [Located RdrName] -> LHsType GhcPs -- Always a HsForAllTy - -> (ConDecl GhcPs, [AddAnn]) + -> ConDecl GhcPs mkGadtDecl names ty - = (ConDeclGADT { con_g_ext = noExtField - , con_names = names - , con_forall = L l $ isLHsForAllTy ty' - , con_qvars = mkHsQTvs tvs - , con_mb_cxt = mcxt - , con_args = args - , con_res_ty = res_ty - , con_doc = Nothing } - , anns1 ++ anns2) + = ConDeclGADT { con_g_ext = noExtField + , con_names = names + , con_forall = L (getLoc ty) $ isJust mtvs + , con_qvars = mkHsQTvs $ fromMaybe [] mtvs + , con_mb_cxt = mcxt + , con_args = args + , con_res_ty = res_ty + , con_doc = Nothing } where - (ty'@(L l _),anns1) = peel_parens ty [] - (tvs, rho) = splitLHsForAllTyInvis ty' - (mcxt, tau, anns2) = split_rho rho [] - - split_rho (L _ (HsQualTy { hst_ctxt = cxt, hst_body = tau })) ann - = (Just cxt, tau, ann) - split_rho (L l (HsParTy _ ty)) ann - = split_rho ty (ann++mkParensApiAnn l) - split_rho tau ann - = (Nothing, tau, ann) + (mtvs, rho) = split_sigma ty + (mcxt, tau) = split_rho rho + + -- NB: We do not use splitLHsForAllTyInvis below, since that looks through + -- parentheses... + split_sigma (L _ (HsForAllTy { hst_fvf = ForallInvis, hst_bndrs = bndrs + , hst_body = rho })) + = (Just bndrs, rho) + split_sigma sigma + = (Nothing, sigma) + + -- ...similarly, we do not use splitLHsQualTy below, since that also looks + -- through parentheses. + -- See Note [No nested foralls or contexts in GADT constructors] for why + -- this is important. + split_rho (L _ (HsQualTy { hst_ctxt = cxt, hst_body = tau })) + = (Just cxt, tau) + split_rho tau + = (Nothing, tau) (args, res_ty) = split_tau tau @@ -696,10 +707,43 @@ mkGadtDecl names ty split_tau tau = (PrefixCon [], tau) - peel_parens (L l (HsParTy _ ty)) ann = peel_parens ty - (ann++mkParensApiAnn l) - peel_parens ty ann = (ty, ann) - +{- +Note [No nested foralls or contexts in GADT constructors] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +GADT constructors provide some freedom to change the order of foralls in their +types (see Note [DataCon user type variable binders] in GHC.Core.DataCon), but +this freedom is still limited. GADTs still require that all quantification +occurs prenex. That is, any explicitly quantified type variables must occur at +the front of the GADT type, followed by any contexts, followed by the body of +the GADT type, in precisely that order. For instance: + + data T where + MkT1 :: forall a b. (Eq a, Eq b) => a -> b -> T + -- OK + MkT2 :: forall a. Eq a => forall b. a -> b -> T + -- Rejected, `forall b` is nested + MkT3 :: forall a b. Eq a => Eq b => a -> b -> T + -- Rejected, `Eq b` is nested + MkT4 :: Int -> forall a. a -> T + -- Rejected, `forall a` is nested + MkT5 :: forall a. Int -> Eq a => a -> T + -- Rejected, `Eq a` is nested + MkT6 :: (forall a. a -> T) + -- Rejected, `forall a` is nested due to the surrounding parentheses + MkT7 :: (Eq a => a -> t) + -- Rejected, `Eq a` is nested due to the surrounding parentheses + +For the full details, see the "Formal syntax for GADTs" section of the GHC +User's Guide. + +Because the presence of outermost parentheses can affect whether +`forall`s/contexts are nested, the parser is careful not to remove parentheses +when post-processing GADT constructors (in mkGadtDecl). Later, the renamer will +check for nested `forall`s/contexts (in GHC.Rename.Module.rnConDecl) after +it has determined what all of the argument types are. +(See Note [GADT abstract syntax] in GHC.Hs.Decls for why this check must wait +until the renamer.) +-} setRdrNameSpace :: RdrName -> NameSpace -> RdrName -- ^ This rather gruesome function is used mainly by the parser. ===================================== compiler/GHC/Rename/Module.hs ===================================== @@ -59,7 +59,8 @@ import GHC.Types.Basic ( pprRuleName, TypeOrKind(..) ) import GHC.Data.FastString import GHC.Types.SrcLoc as SrcLoc import GHC.Driver.Session -import GHC.Utils.Misc ( debugIsOn, filterOut, lengthExceeds, partitionWith ) +import GHC.Utils.Misc ( debugIsOn, filterOut, lengthExceeds, notNull + , partitionWith ) import GHC.Driver.Types ( HscEnv, hsc_dflags ) import GHC.Data.List.SetOps ( findDupsEq, removeDups, equivClasses ) import GHC.Data.Graph.Directed ( SCC, flattenSCC, flattenSCCs, Node(..) @@ -2102,17 +2103,22 @@ rnConDecl decl@(ConDeclGADT { con_names = names do { (new_cxt, fvs1) <- rnMbContext ctxt mcxt ; (new_args, fvs2) <- rnConDeclDetails (unLoc (head new_names)) ctxt args ; (new_res_ty, fvs3) <- rnLHsType ctxt res_ty + ; (args', res_ty') <- + case args of + InfixCon {} -> pprPanic "rnConDecl" (ppr names) + RecCon {} -> pure (new_args, new_res_ty) + PrefixCon as -> do + -- In the PrefixCon case, the parser puts the entire body of + -- the constructor type, including argument types, into res_ty. + -- We can properly determine what the argument types are after + -- renaming (see Note [GADT abstract syntax] in GHC.Hs.Decls), + -- so we do so by splitting new_res_ty below. + MASSERT( null as ) + (arg_tys, final_res_ty) <- + split_prefix_gadt_ty ctxt explicit_tkvs new_cxt new_res_ty + pure (PrefixCon arg_tys, final_res_ty) ; let all_fvs = fvs1 `plusFV` fvs2 `plusFV` fvs3 - (args', res_ty') - = case args of - InfixCon {} -> pprPanic "rnConDecl" (ppr names) - RecCon {} -> (new_args, new_res_ty) - PrefixCon as | (arg_tys, final_res_ty) <- splitHsFunType new_res_ty - -> ASSERT( null as ) - -- See Note [GADT abstract syntax] in GHC.Hs.Decls - (PrefixCon arg_tys, final_res_ty) - new_qtvs = HsQTvs { hsq_ext = implicit_tkvs , hsq_explicit = explicit_tkvs } @@ -2122,7 +2128,83 @@ rnConDecl decl@(ConDeclGADT { con_names = names , con_args = args', con_res_ty = res_ty' , con_doc = mb_doc' }, all_fvs) } } - + where + -- Split the body of a prefix GADT constructor type into its argument + -- and result types. Furthermore, ensure that there are no nested `forall`s + -- or contexts, per + -- Note [No nested foralls or contexts in GADT constructors] in + -- GHC.Parser.PostProcess. + split_prefix_gadt_ty :: HsDocContext + -> [LHsTyVarBndr GhcRn] + -> Maybe (LHsContext GhcRn) + -> LHsType GhcRn + -> RnM ([LHsType GhcRn], LHsType GhcRn) + split_prefix_gadt_ty ctxt gadt_tvbs mb_gadt_cxt gadt_rho = do + -- Check for nested `forall`s or contexts + case gadt_res_ty of + L _ (HsForAllTy { hst_fvf = fvf }) + | ForallVis <- fvf + -> addErr $ withHsDocContext ctxt $ vcat + [ hang (text "Illegal visible, dependent quantification" <+> + text "in the type of a term:") + 2 (ppr orig_gadt_ty) + , text "(GHC does not yet support this)" ] + | ForallInvis <- fvf + -> nested_foralls_contexts_err + L _ (HsQualTy {}) + -> nested_foralls_contexts_err + _ -> pure () + + pure (gadt_arg_tys, gadt_res_ty) + where + (gadt_arg_tys, gadt_res_ty) = splitLHsFunTys gadt_rho + + -- If we are going to reject a GADT constructor type for having nested + -- `forall`s or contexts, then we can at least suggest an alternative + -- way to write the type without nesting. (#12087) + nested_foralls_contexts_err :: RnM () + nested_foralls_contexts_err = + addErr $ withHsDocContext ctxt $ + text "GADT constructor type signature cannot contain nested" + <+> quotes forAllLit <> text "s or contexts" + $+$ hang (text "Suggestion: instead use this type signature:") + 2 (pprWithCommas ppr names <+> dcolon <+> ppr suggested_gadt_ty) + + -- To construct a type that GHC would accept (suggested_gadt_ty), we: + -- + -- 1) Split apart the return type (which is headed by a forall or a + -- context) using splitNestedLHsSigmaTysInvis, collecting the type + -- variables and predicates we find, as well as the rho type + -- lurking underneath the nested foralls and contexts. + -- 2) Reassemble the type variables, predicates, and rho type into + -- prenex form. + (suggested_tvbs, suggested_theta, suggested_rho) = + splitNestedLHsSigmaTysInvis orig_gadt_ty + mb_suggested_theta | null (unLoc suggested_theta) = Nothing + | otherwise = Just suggested_theta + + orig_gadt_ty = mk_forall_ty explicit_forall gadt_tvbs $ + mk_qual_ty mb_gadt_cxt gadt_rho + + suggested_gadt_ty = + mk_forall_ty (notNull suggested_tvbs) suggested_tvbs $ + mk_qual_ty mb_suggested_theta suggested_rho + + mk_forall_ty exp_forall tvbs tau + | exp_forall = noLoc $ + HsForAllTy { hst_xforall = noExtField + , hst_fvf = ForallInvis + , hst_bndrs = tvbs + , hst_body = tau } + | otherwise = tau + + mk_qual_ty mb_ctxt rho = + case mb_ctxt of + Nothing -> rho + Just ctxt -> noLoc $ + HsQualTy { hst_xqual = noExtField + , hst_ctxt = ctxt + , hst_body = rho } rnMbContext :: HsDocContext -> Maybe (LHsContext GhcPs) -> RnM (Maybe (LHsContext GhcRn), FreeVars) ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -4733,50 +4733,12 @@ noClassTyVarErr clas fam_tc badDataConTyCon :: DataCon -> Type -> SDoc badDataConTyCon data_con res_ty_tmpl - | ASSERT( all isTyVar tvs ) - tcIsForAllTy actual_res_ty - = nested_foralls_contexts_suggestion - | isJust (tcSplitPredFunTy_maybe actual_res_ty) - = nested_foralls_contexts_suggestion - | otherwise = hang (text "Data constructor" <+> quotes (ppr data_con) <+> text "returns type" <+> quotes (ppr actual_res_ty)) 2 (text "instead of an instance of its parent type" <+> quotes (ppr res_ty_tmpl)) where actual_res_ty = dataConOrigResTy data_con - -- This suggestion is useful for suggesting how to correct code like what - -- was reported in #12087: - -- - -- data F a where - -- MkF :: Ord a => Eq a => a -> F a - -- - -- Although nested foralls or contexts are allowed in function type - -- signatures, it is much more difficult to engineer GADT constructor type - -- signatures to allow something similar, so we error in the latter case. - -- Nevertheless, we can at least suggest how a user might reshuffle their - -- exotic GADT constructor type signature so that GHC will accept. - nested_foralls_contexts_suggestion = - text "GADT constructor type signature cannot contain nested" - <+> quotes forAllLit <> text "s or contexts" - $+$ hang (text "Suggestion: instead use this type signature:") - 2 (ppr (dataConName data_con) <+> dcolon <+> ppr suggested_ty) - - -- To construct a type that GHC would accept (suggested_ty), we: - -- - -- 1) Find the existentially quantified type variables and the class - -- predicates from the datacon. (NB: We don't need the universally - -- quantified type variables, since rejigConRes won't substitute them in - -- the result type if it fails, as in this scenario.) - -- 2) Split apart the return type (which is headed by a forall or a - -- context) using tcSplitNestedSigmaTys, collecting the type variables - -- and class predicates we find, as well as the rho type lurking - -- underneath the nested foralls and contexts. - -- 3) Smash together the type variables and class predicates from 1) and - -- 2), and prepend them to the rho type from 2). - (tvs, theta, rho) = tcSplitNestedSigmaTys (dataConUserType data_con) - suggested_ty = mkSpecSigmaTy tvs theta rho - badGadtDecl :: Name -> SDoc badGadtDecl tc_name = vcat [ text "Illegal generalised algebraic data declaration for" <+> quotes (ppr tc_name) ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -614,7 +614,7 @@ cvtConstr (GadtC c strtys ty) ; args <- mapM cvt_arg strtys ; L _ ty' <- cvtType ty ; c_ty <- mk_arr_apps args ty' - ; returnL $ fst $ mkGadtDecl c' c_ty} + ; returnL $ mkGadtDecl c' c_ty} cvtConstr (RecGadtC [] _varstrtys _ty) = failWith (text "RecGadtC must have at least one constructor name") @@ -625,7 +625,7 @@ cvtConstr (RecGadtC c varstrtys ty) ; rec_flds <- mapM cvt_id_arg varstrtys ; let rec_ty = noLoc (HsFunTy noExtField (noLoc $ HsRecTy noExtField rec_flds) ty') - ; returnL $ fst $ mkGadtDecl c' rec_ty } + ; returnL $ mkGadtDecl c' rec_ty } cvtSrcUnpackedness :: TH.SourceUnpackedness -> SrcUnpackedness cvtSrcUnpackedness NoSourceUnpackedness = NoSrcUnpack ===================================== docs/users_guide/8.12.1-notes.rst ===================================== @@ -79,6 +79,27 @@ Language This change prepares the way for Quick Look impredicativity. +* GADT constructor types now properly adhere to :ref:`forall-or-nothing`. As + a result, GHC will now reject some GADT constructors that previous versions + of GHC would accept, such as the following: :: + + data T where + MkT1 :: (forall a. a -> b -> T) + MkT2 :: (forall a. a -> T) + + ``MkT1`` and ``MkT2`` are rejected because the lack of an outermost + ``forall`` triggers implicit quantification, making the explicit ``forall``s + nested. Furthermore, GADT constructors do not permit the use of nested + ``forall``s, as explained in :ref:`formal-gadt-syntax`. + + In addition to rejecting nested ``forall``s, GHC is now more stringent about + rejecting uses of nested *contexts* in GADT constructors. For example, the + following example, which previous versions of GHC would accept, is now + rejected: + + data U a where + MkU :: (Show a => U a) + Compiler ~~~~~~~~ @@ -148,11 +169,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/exts/explicit_forall.rst ===================================== @@ -45,4 +45,81 @@ Notes: would warn about the unused type variable `a`. +.. _forall-or-nothing: + +The ``forall``-or-nothing rule +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In certain forms of types, type variables obey what is known as the +"``forall``-or-nothing" rule: if a type has an outermost, explicit +``forall``, then all of the type variables in the type must be explicitly +quantified. These two examples illustrate how the rule works: :: + + f :: forall a b. a -> b -> b -- OK, `a` and `b` are explicitly bound + g :: forall a. a -> forall b. b -> b -- OK, `a` and `b` are explicitly bound + h :: forall a. a -> b -> b -- Rejected, `b` is not in scope + +The type signatures for ``f``, ``g``, and ``h`` all begin with an outermost +``forall``, so every type variable in these signatures must be explicitly +bound by a ``forall``. Both ``f`` and ``g`` obey the ``forall``-or-nothing +rule, since they explicitly quantify ``a`` and ``b``. On the other hand, +``h`` does not explicitly quantify ``b``, so GHC will reject its type +signature for being improperly scoped. + +In places where the ``forall``-or-nothing rule takes effect, if a type does +*not* have an outermost ``forall``, then any type variables that are not +explicitly bound by a ``forall`` become implicitly quantified. For example: :: + + i :: a -> b -> b -- `a` and `b` are implicitly quantified + j :: a -> forall b. b -> b -- `a` is implicitly quantified + k :: (forall a. a -> b -> b) -- `b` is implicitly quantified + +GHC will accept ``i``, ``j``, and ``k``'s type signatures. Note that: + +- ``j``'s signature is accepted despite its mixture of implicit and explicit + quantification. As long as a ``forall`` is not an outermost one, it is fine + to use it among implicitly bound type variables. +- ``k``'s signature is accepted because the outermost parentheses imply that + the ``forall`` is not an outermost ``forall``. The ``forall``-or-nothing + rule is one of the few places in GHC where the presence or absence of + parentheses can be semantically significant! + +The ``forall``-or-nothing rule takes effect in the following places: + +- Type signature declarations for functions, values, and class methods +- Expression type annotations +- Instance declarations +- :ref:`class-default-signatures` +- Type signatures in a :ref:`specialize-pragma` or + :ref:`specialize-instance-pragma` +- :ref:`standalone-kind-signatures` +- Type signatures for :ref:`gadt` constructors +- Type signatures for :ref:`pattern-synonyms` +- :ref:`data-instance-declarations`, :ref:`type-instance-declarations`, + :ref:`closed-type-families`, and :ref:`assoc-inst` +- :ref:`rewrite-rules` in which the type variables are explicitly quantified +Notes: + +- :ref:`pattern-type-sigs` are a notable example of a place where + types do *not* obey the ``forall``-or-nothing rule. For example, GHC will + accept the following: :: + + f (g :: forall a. a -> b) x = g x :: b + + Furthermore, :ref:`rewrite-rules` do not obey the ``forall``-or-nothing rule + when their type variables are not explicitly quantified: :: + + {-# RULES "f" forall (g :: forall a. a -> b) x. f g x = g x :: b #-} + +- GADT constructors are extra particular about their ``forall``s. In addition + to adhering to the ``forall``-or-nothing rule, GADT constructors also forbid + nested ``forall``s. For example, GHC would reject the following GADT: :: + + data T where + MkT :: (forall a. a -> b -> T) + + Because of the lack of an outermost ``forall`` in the type of ``MkT``, the + ``b`` would be implicitly quantified. In effect, it would be as if one had + written ``MkT :: forall b. (forall a. a -> b -> T)``, which contains nested + ``forall``s. See :ref:`formal-gadt-syntax`. ===================================== docs/users_guide/exts/gadt_syntax.rst ===================================== @@ -103,6 +103,114 @@ implements this behaviour, odd though it is. But for GADT-style declarations, GHC's behaviour is much more useful, as well as much more intuitive. +.. _formal-gadt-syntax: + +Formal syntax for GADTs +~~~~~~~~~~~~~~~~~~~~~~~ + +To make more precise what is and what is not permitted inside of a GADT-style +constructor, we provide a BNF-style grammar for GADT below. Note that this +grammar is subject to change in the future. :: + + gadt_con ::= conids '::' opt_forall opt_ctxt gadt_body + + conids ::= conid + | conid ',' conids + + opt_forall ::= + | 'forall' tv_bndrs '.' + + tv_bndrs ::= + | tv_bndr tv_bndrs + + tv_bndr ::= tyvar + | '(' tyvar '::' ctype ')' + + opt_ctxt ::= + | btype '=>' + | '(' ctxt ')' '=>' + + ctxt ::= ctype + | ctype ',' ctxt + + gadt_body ::= prefix_gadt_body + | record_gadt_body + + prefix_gadt_body ::= '(' prefix_gadt_body ')' + | return_type + | opt_bang btype '->' prefix_gadt_body + + record_gadt_body ::= '{' fieldtypes '}' '->' return_type + + fieldtypes ::= + | fieldname '::' opt_bang ctype + | fieldname '::' opt_bang ctype ',' fieldtypes + + opt_bang ::= + | '!' + | '~' + | {-# UNPACK #-} + | {-# NOUNPACK #-} + +Where: + +- ``btype`` is a type that is not allowed to have an outermost + ``forall``/``=>`` unless it is surrounded by parentheses. For example, + ``forall a. a`` and ``Eq a => a`` are not legal ``btype``s, but + ``(forall a. a)`` and ``(Eq a => a)`` are legal. +- ``ctype`` is a ``btype`` that has no restrictions on an outermost + ``forall``/``=>``, so ``forall a. a`` and ``Eq a => a`` are legal ``ctype``s. +- ``return_type`` is a type that is not allowed to have ``forall``s, ``=>``s, + or ``->``s. + +This is a simplified grammar that does not fully delve into all of the +implementation details of GHC's parser (such as the placement of Haddock +comments), but it is sufficient to attain an understanding of what is +syntactically allowed. Some further various observations about this grammar: + +- GADT constructor types are currently not permitted to have nested ``forall``s + or ``=>``s. (e.g., something like ``MkT :: Int -> forall a. a -> T`` would be + rejected.) As a result, ``gadt_sig`` puts all of its quantification and + constraints up front with ``opt_forall`` and ``opt_context``. Note that + higher-rank ``forall``s and ``=>``s are only permitted if they do not appear + directly to the right of a function arrow in a `prefix_gadt_body`. (e.g., + something like ``MkS :: Int -> (forall a. a) -> S`` is allowed, since + parentheses separate the ``forall`` from the ``->``.) +- Furthermore, GADT constructors do not permit outermost parentheses that + surround the ``opt_forall`` or ``opt_ctxt``, if at least one of them are + used. For example, ``MkU :: (forall a. a -> U)`` would be rejected, since + it would treat the ``forall`` as being nested. + + Note that it is acceptable to use parentheses in a ``prefix_gadt_body``. + For instance, ``MkV1 :: forall a. (a) -> (V1)`` is acceptable, as is + ``MkV2 :: forall a. (a -> V2)``. +- The function arrows in a ``prefix_gadt_body``, as well as the function + arrow in a ``record_gadt_body``, are required to be used infix. For + example, ``MkA :: (->) Int A`` would be rejected. +- GHC uses the function arrows in a ``prefix_gadt_body`` and + ``prefix_gadt_body`` to syntactically demarcate the function and result + types. Note that GHC does not attempt to be clever about looking through + type synonyms here. If you attempt to do this, for instance: :: + + type C = Int -> B + + data B where + MkB :: C + + Then GHC will interpret the return type of ``MkB`` to be ``C``, and since + GHC requires that the return type must be headed by ``B``, this will be + rejected. On the other hand, it is acceptable to use type synonyms within + the argument and result types themselves, so the following is permitted: :: + + type B1 = Int + type B2 = B + + data B where + MkB :: B1 -> B2 + +GADT syntax odds at ends +~~~~~~~~~~~~~~~~~~~~~~~~ + The rest of this section gives further details about GADT-style data type declarations. ===================================== testsuite/tests/dependent/should_fail/T16326_Fail6.stderr ===================================== @@ -1,7 +1,6 @@ T16326_Fail6.hs:9:3: error: - • GADT constructor type signature cannot contain nested ‘forall’s or contexts - Suggestion: instead use this type signature: - MkFoo :: forall a. a -> Foo a - • In the definition of data constructor ‘MkFoo’ - In the data type declaration for ‘Foo’ + Illegal visible, dependent quantification in the type of a term: + forall a -> a -> Foo a + (GHC does not yet support this) + In the definition of data constructor ‘MkFoo’ ===================================== testsuite/tests/gadt/T12087.stderr ===================================== @@ -1,35 +1,30 @@ T12087.hs:6:3: error: - • GADT constructor type signature cannot contain nested ‘forall’s or contexts - Suggestion: instead use this type signature: - MkF1 :: forall a. (Ord a, Eq a) => a -> F1 a - • In the definition of data constructor ‘MkF1’ - In the data type declaration for ‘F1’ + GADT constructor type signature cannot contain nested ‘forall’s or contexts + Suggestion: instead use this type signature: + MkF1 :: (Ord a, Eq a) => a -> F1 a + In the definition of data constructor ‘MkF1’ T12087.hs:9:3: error: - • GADT constructor type signature cannot contain nested ‘forall’s or contexts - Suggestion: instead use this type signature: - MkF2 :: forall a. (Ord a, Eq a) => a -> F2 a - • In the definition of data constructor ‘MkF2’ - In the data type declaration for ‘F2’ + GADT constructor type signature cannot contain nested ‘forall’s or contexts + Suggestion: instead use this type signature: + MkF2 :: (Ord a, Eq a) => a -> F2 a + In the definition of data constructor ‘MkF2’ T12087.hs:12:3: error: - • GADT constructor type signature cannot contain nested ‘forall’s or contexts - Suggestion: instead use this type signature: - MkF3 :: forall a b. (Eq a, Eq b) => a -> b -> F3 a - • In the definition of data constructor ‘MkF3’ - In the data type declaration for ‘F3’ + GADT constructor type signature cannot contain nested ‘forall’s or contexts + Suggestion: instead use this type signature: + MkF3 :: forall a b. (Eq a, Eq b) => a -> b -> F3 a + In the definition of data constructor ‘MkF3’ T12087.hs:15:3: error: - • GADT constructor type signature cannot contain nested ‘forall’s or contexts - Suggestion: instead use this type signature: - MkF4 :: forall a b. (Eq a, Eq b) => a -> b -> F4 a - • In the definition of data constructor ‘MkF4’ - In the data type declaration for ‘F4’ + GADT constructor type signature cannot contain nested ‘forall’s or contexts + Suggestion: instead use this type signature: + MkF4 :: forall a b. (Eq a, Eq b) => a -> b -> F4 a + In the definition of data constructor ‘MkF4’ T12087.hs:18:3: error: - • GADT constructor type signature cannot contain nested ‘forall’s or contexts - Suggestion: instead use this type signature: - MkF5 :: forall a b. Int -> Int -> a -> Int -> Int -> b -> F5 a - • In the definition of data constructor ‘MkF5’ - In the data type declaration for ‘F5’ + GADT constructor type signature cannot contain nested ‘forall’s or contexts + Suggestion: instead use this type signature: + MkF5 :: forall a b. Int -> Int -> a -> Int -> Int -> b -> F5 a + In the definition of data constructor ‘MkF5’ ===================================== testsuite/tests/gadt/T14320.hs ===================================== @@ -10,8 +10,8 @@ data Exp :: Type where newtype TypedExp :: Type -> Type where TEGood :: forall a . (Exp -> (TypedExp a)) --- The only difference here is that the type is wrapped in parentheses, --- but GHC 8.0.1 rejects this program +-- The presence of outer parentheses makes the `forall` nested, and +-- GADTs do not permit nested `forall`s. -- newtype TypedExpToo :: Type -> Type where TEBad :: (forall a . (Exp -> (TypedExpToo a))) ===================================== testsuite/tests/gadt/T14320.stderr ===================================== @@ -0,0 +1,6 @@ + +T14320.hs:17:3: error: + GADT constructor type signature cannot contain nested ‘forall’s or contexts + Suggestion: instead use this type signature: + TEBad :: forall a. Exp -> (TypedExpToo a) + In the definition of data constructor ‘TEBad’ ===================================== testsuite/tests/gadt/T16427.stderr ===================================== @@ -1,7 +1,6 @@ T16427.hs:5:14: error: - • GADT constructor type signature cannot contain nested ‘forall’s or contexts - Suggestion: instead use this type signature: - C :: forall b. Int -> b -> D - • In the definition of data constructor ‘C’ - In the data type declaration for ‘D’ + GADT constructor type signature cannot contain nested ‘forall’s or contexts + Suggestion: instead use this type signature: + C :: forall b. Int -> b -> D + In the definition of data constructor ‘C’ ===================================== testsuite/tests/gadt/T18191.hs ===================================== @@ -0,0 +1,12 @@ +{-# LANGUAGE GADTs #-} +{-# LANGUAGE RankNTypes #-} +module T18191 where + +data T where + MkT :: (forall a. a -> b -> T) + +data S a where + MkS :: (forall a. S a) + +data U a where + MkU :: (Show a => U a) ===================================== testsuite/tests/gadt/T18191.stderr ===================================== @@ -0,0 +1,16 @@ + +T18191.hs:6:3: error: + GADT constructor type signature cannot contain nested ‘forall’s or contexts + Suggestion: instead use this type signature: + MkT :: forall a. a -> b -> T + In the definition of data constructor ‘MkT’ + +T18191.hs:9:3: error: + GADT constructor type signature cannot contain nested ‘forall’s or contexts + Suggestion: instead use this type signature: MkS :: forall a. S a + In the definition of data constructor ‘MkS’ + +T18191.hs:12:3: error: + GADT constructor type signature cannot contain nested ‘forall’s or contexts + Suggestion: instead use this type signature: MkU :: Show a => U a + In the definition of data constructor ‘MkU’ ===================================== testsuite/tests/gadt/all.T ===================================== @@ -113,10 +113,11 @@ test('T7558', normal, compile_fail, ['']) test('T9380', normal, compile_and_run, ['']) test('T12087', normal, compile_fail, ['']) test('T12468', normal, compile_fail, ['']) -test('T14320', normal, compile, ['']) +test('T14320', normal, compile_fail, ['']) test('T14719', normal, compile_fail, ['-fdiagnostics-show-caret']) test('T14808', normal, compile, ['']) test('T15009', normal, compile, ['']) test('T15558', normal, compile, ['']) test('T16427', normal, compile_fail, ['']) test('T17423', expect_broken(17423), compile_and_run, ['']) +test('T18191', normal, compile_fail, ['']) ===================================== testsuite/tests/ghc-api/annotations/T10399.stdout ===================================== @@ -34,9 +34,9 @@ ((Test10399.hs:12:30,AnnComma), [Test10399.hs:12:30]), ((Test10399.hs:12:31-32,AnnCloseP), [Test10399.hs:12:32]), ((Test10399.hs:12:31-32,AnnOpenP), [Test10399.hs:12:31]), -((Test10399.hs:(14,1)-(18,55),AnnData), [Test10399.hs:14:1-4]), -((Test10399.hs:(14,1)-(18,55),AnnSemi), [Test10399.hs:20:1]), -((Test10399.hs:(14,1)-(18,55),AnnWhere), [Test10399.hs:14:21-25]), +((Test10399.hs:(14,1)-(18,53),AnnData), [Test10399.hs:14:1-4]), +((Test10399.hs:(14,1)-(18,53),AnnSemi), [Test10399.hs:20:1]), +((Test10399.hs:(14,1)-(18,53),AnnWhere), [Test10399.hs:14:21-25]), ((Test10399.hs:15:5-64,AnnDcolon), [Test10399.hs:15:11-12]), ((Test10399.hs:15:5-64,AnnSemi), [Test10399.hs:16:5]), ((Test10399.hs:15:14-64,AnnDot), [Test10399.hs:15:23]), @@ -48,37 +48,29 @@ ((Test10399.hs:15:45-46,AnnBang), [Test10399.hs:15:45]), ((Test10399.hs:15:45-46,AnnRarrow), [Test10399.hs:15:48-49]), ((Test10399.hs:15:45-64,AnnRarrow), [Test10399.hs:15:48-49]), -((Test10399.hs:(16,5)-(17,69),AnnCloseP), [Test10399.hs:17:69]), -((Test10399.hs:(16,5)-(17,69),AnnDcolon), [Test10399.hs:16:12-13]), -((Test10399.hs:(16,5)-(17,69),AnnOpenP), [Test10399.hs:16:27]), -((Test10399.hs:(16,5)-(17,69),AnnSemi), [Test10399.hs:18:5]), -((Test10399.hs:(16,15)-(17,69),AnnDot), [Test10399.hs:16:25]), -((Test10399.hs:(16,15)-(17,69),AnnForall), [Test10399.hs:16:15-20]), -((Test10399.hs:(16,27)-(17,69),AnnCloseP), [Test10399.hs:17:69]), -((Test10399.hs:(16,27)-(17,69),AnnOpenP), [Test10399.hs:16:27]), -((Test10399.hs:16:28-43,AnnCloseP), [Test10399.hs:16:43, Test10399.hs:16:43]), -((Test10399.hs:16:28-43,AnnDarrow), [Test10399.hs:16:45-46]), -((Test10399.hs:16:28-43,AnnOpenP), [Test10399.hs:16:28, Test10399.hs:16:28]), -((Test10399.hs:16:30-33,AnnComma), [Test10399.hs:16:34]), -((Test10399.hs:16:48,AnnRarrow), [Test10399.hs:16:50-51]), -((Test10399.hs:(16,48)-(17,68),AnnRarrow), [Test10399.hs:16:50-51]), -((Test10399.hs:16:53-66,AnnRarrow), [Test10399.hs:17:45-46]), -((Test10399.hs:(16,53)-(17,68),AnnRarrow), [Test10399.hs:17:45-46]), -((Test10399.hs:17:48,AnnRarrow), [Test10399.hs:17:50-51]), -((Test10399.hs:17:48-68,AnnRarrow), [Test10399.hs:17:50-51]), -((Test10399.hs:17:66-68,AnnCloseS), [Test10399.hs:17:68]), -((Test10399.hs:17:66-68,AnnOpenS), [Test10399.hs:17:66]), -((Test10399.hs:18:5-55,AnnCloseP), [Test10399.hs:18:55]), -((Test10399.hs:18:5-55,AnnDcolon), [Test10399.hs:18:16-17]), -((Test10399.hs:18:5-55,AnnOpenP), [Test10399.hs:18:19]), -((Test10399.hs:18:19-55,AnnCloseP), [Test10399.hs:18:55]), -((Test10399.hs:18:19-55,AnnOpenP), [Test10399.hs:18:19]), -((Test10399.hs:18:20-54,AnnDot), [Test10399.hs:18:29]), -((Test10399.hs:18:20-54,AnnForall), [Test10399.hs:18:20-25]), -((Test10399.hs:18:31-36,AnnCloseP), [Test10399.hs:18:36]), -((Test10399.hs:18:31-36,AnnOpenP), [Test10399.hs:18:31]), -((Test10399.hs:18:31-36,AnnRarrow), [Test10399.hs:18:38-39]), -((Test10399.hs:18:31-54,AnnRarrow), [Test10399.hs:18:38-39]), +((Test10399.hs:(16,5)-(17,67),AnnDcolon), [Test10399.hs:16:12-13]), +((Test10399.hs:(16,5)-(17,67),AnnSemi), [Test10399.hs:18:5]), +((Test10399.hs:(16,15)-(17,67),AnnDot), [Test10399.hs:16:25]), +((Test10399.hs:(16,15)-(17,67),AnnForall), [Test10399.hs:16:15-20]), +((Test10399.hs:16:27-42,AnnCloseP), [Test10399.hs:16:42, Test10399.hs:16:42]), +((Test10399.hs:16:27-42,AnnDarrow), [Test10399.hs:16:44-45]), +((Test10399.hs:16:27-42,AnnOpenP), [Test10399.hs:16:27, Test10399.hs:16:27]), +((Test10399.hs:16:29-32,AnnComma), [Test10399.hs:16:33]), +((Test10399.hs:16:47,AnnRarrow), [Test10399.hs:16:49-50]), +((Test10399.hs:(16,47)-(17,67),AnnRarrow), [Test10399.hs:16:49-50]), +((Test10399.hs:16:52-65,AnnRarrow), [Test10399.hs:17:44-45]), +((Test10399.hs:(16,52)-(17,67),AnnRarrow), [Test10399.hs:17:44-45]), +((Test10399.hs:17:47,AnnRarrow), [Test10399.hs:17:49-50]), +((Test10399.hs:17:47-67,AnnRarrow), [Test10399.hs:17:49-50]), +((Test10399.hs:17:65-67,AnnCloseS), [Test10399.hs:17:67]), +((Test10399.hs:17:65-67,AnnOpenS), [Test10399.hs:17:65]), +((Test10399.hs:18:5-53,AnnDcolon), [Test10399.hs:18:16-17]), +((Test10399.hs:18:19-53,AnnDot), [Test10399.hs:18:28]), +((Test10399.hs:18:19-53,AnnForall), [Test10399.hs:18:19-24]), +((Test10399.hs:18:30-35,AnnCloseP), [Test10399.hs:18:35]), +((Test10399.hs:18:30-35,AnnOpenP), [Test10399.hs:18:30]), +((Test10399.hs:18:30-35,AnnRarrow), [Test10399.hs:18:37-38]), +((Test10399.hs:18:30-53,AnnRarrow), [Test10399.hs:18:37-38]), ((Test10399.hs:20:1-25,AnnCloseQ), [Test10399.hs:20:24-25]), ((Test10399.hs:20:1-25,AnnOpen), [Test10399.hs:20:1-3]), ((Test10399.hs:20:1-25,AnnSemi), [Test10399.hs:22:1]), ===================================== testsuite/tests/ghc-api/annotations/Test10399.hs ===================================== @@ -13,9 +13,9 @@ mkPoli = mkBila . map ((,,(),,()) <$> P.base <*> P.pos <*> P.form) data MaybeDefault v where SetTo :: forall v . ( Eq v, Show v ) => !v -> MaybeDefault v - SetTo4 :: forall v a. (( Eq v, Show v ) => v -> MaybeDefault v - -> a -> MaybeDefault [a]) - TestParens :: (forall v . (Eq v) -> MaybeDefault v) + SetTo4 :: forall v a. ( Eq v, Show v ) => v -> MaybeDefault v + -> a -> MaybeDefault [a] + TestParens :: forall v . (Eq v) -> MaybeDefault v [t| Map.Map T.Text $tc |] ===================================== testsuite/tests/parser/should_compile/T15323.hs ===================================== @@ -3,4 +3,4 @@ module T15323 where data MaybeDefault v where - TestParens :: (forall v . (Eq v) => MaybeDefault v) + TestParens :: forall v . (Eq v) => MaybeDefault v ===================================== testsuite/tests/parser/should_compile/T15323.stderr ===================================== @@ -8,7 +8,7 @@ {ModuleName: T15323})) (Nothing) [] - [({ T15323.hs:(5,1)-(6,56) } + [({ T15323.hs:(5,1)-(6,54) } (TyClD (NoExtField) (DataDecl @@ -32,61 +32,61 @@ []) (Nothing) (Nothing) - [({ T15323.hs:6:5-56 } + [({ T15323.hs:6:5-54 } (ConDeclGADT (NoExtField) [({ T15323.hs:6:5-14 } (Unqual {OccName: TestParens}))] - ({ T15323.hs:6:21-55 } + ({ T15323.hs:6:20-54 } (True)) (HsQTvs (NoExtField) - [({ T15323.hs:6:28 } + [({ T15323.hs:6:27 } (UserTyVar (NoExtField) - ({ T15323.hs:6:28 } + ({ T15323.hs:6:27 } (Unqual {OccName: v}))))]) (Just - ({ T15323.hs:6:32-37 } - [({ T15323.hs:6:32-37 } + ({ T15323.hs:6:31-36 } + [({ T15323.hs:6:31-36 } (HsParTy (NoExtField) - ({ T15323.hs:6:33-36 } + ({ T15323.hs:6:32-35 } (HsAppTy (NoExtField) - ({ T15323.hs:6:33-34 } + ({ T15323.hs:6:32-33 } (HsTyVar (NoExtField) (NotPromoted) - ({ T15323.hs:6:33-34 } + ({ T15323.hs:6:32-33 } (Unqual {OccName: Eq})))) - ({ T15323.hs:6:36 } + ({ T15323.hs:6:35 } (HsTyVar (NoExtField) (NotPromoted) - ({ T15323.hs:6:36 } + ({ T15323.hs:6:35 } (Unqual {OccName: v}))))))))])) (PrefixCon []) - ({ T15323.hs:6:42-55 } + ({ T15323.hs:6:41-54 } (HsAppTy (NoExtField) - ({ T15323.hs:6:42-53 } + ({ T15323.hs:6:41-52 } (HsTyVar (NoExtField) (NotPromoted) - ({ T15323.hs:6:42-53 } + ({ T15323.hs:6:41-52 } (Unqual {OccName: MaybeDefault})))) - ({ T15323.hs:6:55 } + ({ T15323.hs:6:54 } (HsTyVar (NoExtField) (NotPromoted) - ({ T15323.hs:6:55 } + ({ T15323.hs:6:54 } (Unqual {OccName: v})))))) (Nothing)))] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/50bab0e80c232d0cbdbe213a158d2abf5470aad0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/50bab0e80c232d0cbdbe213a158d2abf5470aad0 You're receiving 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 22 23:15:05 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Fri, 22 May 2020 19:15:05 -0400 Subject: [Git][ghc/ghc][wip/T18078] Optimisation in Unique.Supply Message-ID: <5ec85cf995850_6e26eb364ac9103f9@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T18078 at Glasgow Haskell Compiler / GHC Commits: 69c0e16e by Simon Peyton Jones at 2020-05-23T00:14:17+01:00 Optimisation in Unique.Supply Will need a proper Note; putting it up for CI for now - - - - - 1 changed file: - compiler/GHC/Types/Unique/Supply.hs Changes: ===================================== compiler/GHC/Types/Unique/Supply.hs ===================================== @@ -3,6 +3,7 @@ (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 -} +{-# OPTIONS_GHC -fno-state-hack #-} {-# LANGUAGE CPP #-} {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE PatternSynonyms #-} @@ -89,21 +90,18 @@ uniqFromMask mask ; return $! mkUnique mask uqNum } mkSplitUniqSupply c - = case ord c `shiftL` uNIQUE_BITS of - !mask -> let - -- here comes THE MAGIC: + = mk_supply + where + !mask = ord c `shiftL` uNIQUE_BITS + -- Here comes THE MAGIC: -- This is one of the most hammered bits in the whole compiler - mk_supply - -- NB: Use unsafeInterleaveIO for thread-safety. - = unsafeInterleaveIO ( - genSym >>= \ u -> - mk_supply >>= \ s1 -> - mk_supply >>= \ s2 -> - return (MkSplitUniqSupply (mask .|. u) s1 s2) - ) - in - mk_supply + -- NB: Use unsafeInterleaveIO for thread-safety. + mk_supply = unsafeInterleaveIO $ + genSym >>= \ u -> + mk_supply >>= \ s1 -> + mk_supply >>= \ s2 -> + return (MkSplitUniqSupply (mask .|. u) s1 s2) foreign import ccall unsafe "genSym" genSym :: IO Int foreign import ccall unsafe "initGenSym" initUniqSupply :: Int -> Int -> IO () View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/69c0e16e9ce9fe045851c09425956fa3407824ae -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/69c0e16e9ce9fe045851c09425956fa3407824ae You're receiving 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 22 23:55:23 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 22 May 2020 19:55:23 -0400 Subject: [Git][ghc/ghc][wip/T17775] Simple subsumption Message-ID: <5ec8666b27626_6e2611c732a4922488@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: 1d118923 by Simon Peyton Jones at 2020-05-22T19:54:47-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 Updates Cabal submodule. - - - - - 20 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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1d118923df3e58c1b6bd39855e32fd48188c2bc3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1d118923df3e58c1b6bd39855e32fd48188c2bc3 You're receiving 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 23 01:36:00 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 22 May 2020 21:36:00 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 7 commits: docs: fix formatting and add some links Message-ID: <5ec87e004f345_6e263f9f0b3daba094076@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: f31b1311 by Adam Sandberg Ericsson at 2020-05-22T21:35:29-04:00 docs: fix formatting and add some links [skip ci] - - - - - 7699a7ab by Andrew Martin at 2020-05-22T21:35:40-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. - - - - - f9d20958 by Ben Gamari at 2020-05-22T21:35:41-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. - - - - - f8f18a40 by John Ericson at 2020-05-22T21:35:46-04:00 Fix #18145 and also avoid needless work with implicit vars - `forAllOrNothing` now is monadic, so we can trace whether we bind an explicit `forall` or not. - #18145 arose because the free vars calculation was needlessly complex. It is now greatly simplified. - Replaced some other implicit var code with `filterFreeVarsToBind`. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - a7d31d89 by Ben Gamari at 2020-05-22T21:35:47-04:00 Bump process submodule Fixes #17926. - - - - - c7639bb8 by Ben Gamari at 2020-05-22T21:35:47-04:00 users-guide: Clarify meaning of -haddock flag Fixes #18206. - - - - - f5f3e709 by Ben Gamari at 2020-05-22T21:35:48-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 - - - - - 30 changed files: - + .git-ignore-revs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Hs/Lit.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Types/Literal.hs - docs/users_guide/8.12.1-notes.rst - docs/users_guide/exts/template_haskell.rst - docs/users_guide/using.rst - libraries/base/GHC/Exts.hs - libraries/base/GHC/ForeignPtr.hs - libraries/ghc-prim/GHC/CString.hs - libraries/ghc-prim/changelog.md - libraries/process - testsuite/.gitignore - testsuite/driver/testlib.py - + testsuite/tests/primops/should_gen_core/CStringLength_core.hs - + testsuite/tests/primops/should_gen_core/CStringLength_core.substr-simpl - + testsuite/tests/primops/should_gen_core/all.T - + testsuite/tests/primops/should_run/CStringLength.hs - + testsuite/tests/primops/should_run/CStringLength.stdout - testsuite/tests/primops/should_run/all.T - + testsuite/tests/rename/should_fail/T18145.hs - + testsuite/tests/rename/should_fail/T18145.stderr - testsuite/tests/rename/should_fail/all.T 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 ===================================== compiler/GHC/Builtin/Names.hs ===================================== @@ -349,6 +349,7 @@ basicKnownKeyNames -- Strings and lists unpackCStringName, unpackCStringFoldrName, unpackCStringUtf8Name, + cstringLengthName, -- Overloaded lists isListClassName, @@ -1014,10 +1015,11 @@ modIntName = varQual gHC_CLASSES (fsLit "modInt#") modIntIdKey -- Base strings Strings unpackCStringName, unpackCStringFoldrName, - unpackCStringUtf8Name, eqStringName :: Name + unpackCStringUtf8Name, eqStringName, cstringLengthName :: Name unpackCStringName = varQual gHC_CSTRING (fsLit "unpackCString#") unpackCStringIdKey unpackCStringFoldrName = varQual gHC_CSTRING (fsLit "unpackFoldrCString#") unpackCStringFoldrIdKey unpackCStringUtf8Name = varQual gHC_CSTRING (fsLit "unpackCStringUtf8#") unpackCStringUtf8IdKey +cstringLengthName = varQual gHC_CSTRING (fsLit "cstringLength#") cstringLengthIdKey eqStringName = varQual gHC_BASE (fsLit "eqString") eqStringIdKey -- The 'inline' function @@ -2097,7 +2099,7 @@ wildCardKey, absentErrorIdKey, augmentIdKey, appendIdKey, unpackCStringUtf8IdKey, unpackCStringAppendIdKey, unpackCStringFoldrIdKey, unpackCStringIdKey, typeErrorIdKey, divIntIdKey, modIntIdKey, - absentSumFieldErrorIdKey :: Unique + absentSumFieldErrorIdKey, cstringLengthIdKey :: Unique wildCardKey = mkPreludeMiscIdUnique 0 -- See Note [WildCard binders] absentErrorIdKey = mkPreludeMiscIdUnique 1 @@ -2124,6 +2126,7 @@ voidPrimIdKey = mkPreludeMiscIdUnique 21 typeErrorIdKey = mkPreludeMiscIdUnique 22 divIntIdKey = mkPreludeMiscIdUnique 23 modIntIdKey = mkPreludeMiscIdUnique 24 +cstringLengthIdKey = mkPreludeMiscIdUnique 25 concatIdKey, filterIdKey, zipIdKey, bindIOIdKey, returnIOIdKey, newStablePtrIdKey, ===================================== compiler/GHC/Core/Opt/ConstantFold.hs ===================================== @@ -66,6 +66,7 @@ import qualified Data.ByteString as BS import Data.Int import Data.Ratio import Data.Word +import Data.Maybe (fromMaybe) {- Note [Constant folding] @@ -1257,6 +1258,8 @@ builtinRules ru_nargs = 4, ru_try = match_append_lit }, BuiltinRule { ru_name = fsLit "EqString", ru_fn = eqStringName, ru_nargs = 2, ru_try = match_eq_string }, + BuiltinRule { ru_name = fsLit "CStringLength", ru_fn = cstringLengthName, + ru_nargs = 1, ru_try = match_cstring_length }, BuiltinRule { ru_name = fsLit "Inline", ru_fn = inlineIdName, ru_nargs = 2, ru_try = \_ _ _ -> match_inline }, BuiltinRule { ru_name = fsLit "MagicDict", ru_fn = idName magicDictId, @@ -1477,6 +1480,30 @@ match_eq_string _ id_unf _ match_eq_string _ _ _ _ = Nothing +----------------------------------------------------------------------- +-- Illustration of this rule: +-- +-- cstringLength# "foobar"# --> 6 +-- cstringLength# "fizz\NULzz"# --> 4 +-- +-- Nota bene: Addr# literals are suffixed by a NUL byte when they are +-- compiled to read-only data sections. That's why cstringLength# is +-- well defined on Addr# literals that do not explicitly have an embedded +-- NUL byte. +-- +-- See GHC issue #5218, MR 2165, and bytestring PR 191. This is particularly +-- helpful when using OverloadedStrings to create a ByteString since the +-- function computing the length of such ByteStrings can often be constant +-- folded. +match_cstring_length :: RuleFun +match_cstring_length env id_unf _ [lit1] + | Just (LitString str) <- exprIsLiteral_maybe id_unf lit1 + -- If elemIndex returns Just, it has the index of the first embedded NUL + -- in the string. If no NUL bytes are present (the common case) then use + -- full length of the byte string. + = let len = fromMaybe (BS.length str) (BS.elemIndex 0 str) + in Just (Lit (mkLitInt (roPlatform env) (fromIntegral len))) +match_cstring_length _ _ _ _ = Nothing --------------------------------------------------- -- The rule is this: ===================================== 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] ===================================== compiler/GHC/Data/FastString.hs ===================================== @@ -128,8 +128,9 @@ import Foreign import GHC.Conc.Sync (sharedCAF) #endif -import GHC.Base ( unpackCString#, unpackNBytes# ) - +#if __GLASGOW_HASKELL__ < 811 +import GHC.Base (unpackCString#,unpackNBytes#) +#endif -- | Gives the UTF-8 encoded bytes corresponding to a 'FastString' bytesFS :: FastString -> ByteString ===================================== compiler/GHC/Hs/Lit.hs ===================================== @@ -53,7 +53,7 @@ data HsLit x -- ^ Unboxed character | HsString (XHsString x) {- SourceText -} FastString -- ^ String - | HsStringPrim (XHsStringPrim x) {- SourceText -} ByteString + | HsStringPrim (XHsStringPrim x) {- SourceText -} !ByteString -- ^ Packed bytes | HsInt (XHsInt x) IntegralLit -- ^ Genuinely an Int; arises from ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -29,7 +29,7 @@ module GHC.Rename.HsType ( extractHsTysRdrTyVarsDups, extractRdrKindSigVars, extractDataDefnKindVars, extractHsTvBndrs, extractHsTyArgRdrKiTyVarsDup, - forAllOrNothing, nubL, elemRdr + forAllOrNothing, nubL ) where import GHC.Prelude @@ -65,7 +65,7 @@ import GHC.Data.FastString import GHC.Data.Maybe import qualified GHC.LanguageExtensions as LangExt -import Data.List ( nubBy, partition, (\\), find ) +import Data.List ( nubBy, partition, find ) import Control.Monad ( unless, when ) #include "HsVersions.h" @@ -164,13 +164,13 @@ rn_hs_sig_wc_type :: HsSigWcTypeScoping -> HsDocContext -> Maybe SDoc -> RnM (a, FreeVars) rn_hs_sig_wc_type scoping ctxt inf_err hs_ty thing_inside = do { check_inferred_vars ctxt inf_err hs_ty - ; free_vars <- extractFilteredRdrTyVarsDups hs_ty + ; free_vars <- filterInScopeM (extractHsTyRdrTyVarsDups hs_ty) ; (nwc_rdrs', tv_rdrs) <- partition_nwcs free_vars ; let nwc_rdrs = nubL nwc_rdrs' - implicit_bndrs = case scoping of - AlwaysBind -> tv_rdrs - BindUnlessForall -> forAllOrNothing (isLHsForAllTy hs_ty) tv_rdrs - NeverBind -> [] + ; implicit_bndrs <- case scoping of + AlwaysBind -> pure tv_rdrs + BindUnlessForall -> forAllOrNothing (isLHsForAllTy hs_ty) tv_rdrs + NeverBind -> pure [] ; rnImplicitBndrs implicit_bndrs $ \ vars -> do { (wcs, hs_ty', fvs1) <- rnWcBody ctxt nwc_rdrs hs_ty ; (res, fvs2) <- thing_inside wcs vars hs_ty' @@ -178,7 +178,7 @@ rn_hs_sig_wc_type scoping ctxt inf_err hs_ty thing_inside rnHsWcType :: HsDocContext -> LHsWcType GhcPs -> RnM (LHsWcType GhcRn, FreeVars) rnHsWcType ctxt (HsWC { hswc_body = hs_ty }) - = do { free_vars <- extractFilteredRdrTyVars hs_ty + = do { free_vars <- filterInScopeM (extractHsTyRdrTyVars hs_ty) ; (nwc_rdrs, _) <- partition_nwcs free_vars ; (wcs, hs_ty', fvs) <- rnWcBody ctxt nwc_rdrs hs_ty ; let sig_ty' = HsWC { hswc_ext = wcs, hswc_body = hs_ty' } @@ -278,22 +278,6 @@ extraConstraintWildCardsAllowed env StandaloneKindSigCtx {} -> False -- See Note [Wildcards in standalone kind signatures] in GHC/Hs/Decls _ -> False --- | Finds free type and kind variables in a type, --- without duplicates, and --- without variables that are already in scope in LocalRdrEnv --- NB: this includes named wildcards, which look like perfectly --- ordinary type variables at this point -extractFilteredRdrTyVars :: LHsType GhcPs -> RnM FreeKiTyVarsNoDups -extractFilteredRdrTyVars hs_ty = filterInScopeM (extractHsTyRdrTyVars hs_ty) - --- | Finds free type and kind variables in a type, --- with duplicates, but --- without variables that are already in scope in LocalRdrEnv --- NB: this includes named wildcards, which look like perfectly --- ordinary type variables at this point -extractFilteredRdrTyVarsDups :: LHsType GhcPs -> RnM FreeKiTyVarsWithDups -extractFilteredRdrTyVarsDups hs_ty = filterInScopeM (extractHsTyRdrTyVarsDups hs_ty) - -- | When the NamedWildCards extension is enabled, partition_nwcs -- removes type variables that start with an underscore from the -- FreeKiTyVars in the argument and returns them in a separate list. @@ -340,9 +324,12 @@ rnHsSigType :: HsDocContext -- that cannot have wildcards rnHsSigType ctx level inf_err (HsIB { hsib_body = hs_ty }) = do { traceRn "rnHsSigType" (ppr hs_ty) - ; vars <- extractFilteredRdrTyVarsDups hs_ty + ; rdr_env <- getLocalRdrEnv ; check_inferred_vars ctx inf_err hs_ty - ; rnImplicitBndrs (forAllOrNothing (isLHsForAllTy hs_ty) vars) $ \ vars -> + ; vars0 <- forAllOrNothing (isLHsForAllTy hs_ty) + $ filterInScope rdr_env + $ extractHsTyRdrTyVarsDups hs_ty + ; rnImplicitBndrs vars0 $ \ vars -> do { (body', fvs) <- rnLHsTyKi (mkTyKiEnv ctx level RnTypeBody) hs_ty ; return ( HsIB { hsib_ext = vars @@ -361,7 +348,7 @@ rnHsSigType ctx level inf_err (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 [forall-or-nothing rule]. This tiny little function is used +-- | 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 @@ -372,10 +359,14 @@ forAllOrNothing :: Bool -- we want to bring both 'a' and 'b' into scope, hence False -> FreeKiTyVarsWithDups -- ^ Free vars of the type - -> FreeKiTyVarsWithDups -forAllOrNothing True _ = [] -forAllOrNothing False fvs = fvs - + -> RnM FreeKiTyVarsWithDups +forAllOrNothing has_outer_forall fvs = case has_outer_forall of + True -> do + traceRn "forAllOrNothing" $ text "has explicit outer forall" + pure [] + False -> do + traceRn "forAllOrNothing" $ text "no explicit forall. implicit binders:" <+> ppr fvs + pure fvs rnImplicitBndrs :: FreeKiTyVarsWithDups -- ^ Surface-syntax free vars that we will implicitly bind. @@ -878,21 +869,20 @@ bindHsQTyVars doc mb_in_doc mb_assoc body_kv_occs hsq_bndrs thing_inside ; let -- See Note [bindHsQTyVars examples] for what -- all these various things are doing - bndrs, kv_occs, implicit_kvs :: [Located RdrName] + bndrs, implicit_kvs :: [Located RdrName] bndrs = map hsLTyVarLocName hs_tv_bndrs - kv_occs = nubL (bndr_kv_occs ++ body_kv_occs) - -- Make sure to list the binder kvs before the - -- body kvs, as mandated by - -- Note [Ordering of implicit variables] - implicit_kvs = filter_occs bndrs kv_occs + implicit_kvs = nubL $ filterFreeVarsToBind bndrs $ + bndr_kv_occs ++ body_kv_occs del = deleteBys eqLocated - all_bound_on_lhs = null ((body_kv_occs `del` bndrs) `del` bndr_kv_occs) + body_remaining = (body_kv_occs `del` bndrs) `del` bndr_kv_occs + all_bound_on_lhs = null body_remaining ; traceRn "checkMixedVars3" $ - vcat [ text "kv_occs" <+> ppr kv_occs - , text "bndrs" <+> ppr hs_tv_bndrs + vcat [ text "bndrs" <+> ppr hs_tv_bndrs , text "bndr_kv_occs" <+> ppr bndr_kv_occs - , text "wubble" <+> ppr ((kv_occs \\ bndrs) \\ bndr_kv_occs) + , text "body_kv_occs" <+> ppr body_kv_occs + , text "implicit_kvs" <+> ppr implicit_kvs + , text "body_remaining" <+> ppr body_remaining ] ; implicit_kv_nms <- mapM (newTyVarNameRn mb_assoc) implicit_kvs @@ -904,17 +894,6 @@ bindHsQTyVars doc mb_in_doc mb_assoc body_kv_occs hsq_bndrs thing_inside , hsq_explicit = rn_bndrs }) all_bound_on_lhs } } - where - filter_occs :: [Located RdrName] -- Bound here - -> [Located RdrName] -- Potential implicit binders - -> [Located RdrName] -- Final implicit binders - -- Filter out any potential implicit binders that are either - -- already in scope, or are explicitly bound in the same HsQTyVars - filter_occs bndrs occs - = filterOut is_in_scope occs - where - is_in_scope locc = locc `elemRdr` bndrs - {- Note [bindHsQTyVars examples] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Suppose we have @@ -943,7 +922,7 @@ Then: * Order is not important in these lists. All we are doing is bring Names into scope. -Finally, you may wonder why filter_occs removes in-scope variables +Finally, you may wonder why filterFreeVarsToBind removes in-scope variables from bndr/body_kv_occs. How can anything be in scope? Answer: HsQTyVars is /also/ used (slightly oddly) for Haskell-98 syntax ConDecls @@ -1654,9 +1633,15 @@ type FreeKiTyVarsWithDups = FreeKiTyVars -- | A 'FreeKiTyVars' list that contains no duplicate variables. type FreeKiTyVarsNoDups = FreeKiTyVars +-- | Filter out any type and kind variables that are already in scope in the +-- the supplied LocalRdrEnv. Note that this includes named wildcards, which +-- look like perfectly ordinary type variables at this point. filterInScope :: LocalRdrEnv -> FreeKiTyVars -> FreeKiTyVars filterInScope rdr_env = filterOut (inScope rdr_env . unLoc) +-- | Filter out any type and kind variables that are already in scope in the +-- the environment's LocalRdrEnv. Note that this includes named wildcards, +-- which look like perfectly ordinary type variables at this point. filterInScopeM :: FreeKiTyVars -> RnM FreeKiTyVars filterInScopeM vars = do { rdr_env <- getLocalRdrEnv @@ -1812,12 +1797,13 @@ extract_hs_tv_bndrs :: [LHsTyVarBndr flag GhcPs] -- 'a' is bound by the forall -- 'b' is a free type variable -- 'e' is a free kind variable -extract_hs_tv_bndrs tv_bndrs acc_vars body_vars - | null tv_bndrs = body_vars ++ acc_vars - | otherwise = filterOut (`elemRdr` tv_bndr_rdrs) (bndr_vars ++ body_vars) ++ acc_vars +extract_hs_tv_bndrs tv_bndrs acc_vars body_vars = new_vars ++ acc_vars + where + new_vars + | null tv_bndrs = body_vars + | otherwise = filterFreeVarsToBind tv_bndr_rdrs $ bndr_vars ++ body_vars -- NB: delete all tv_bndr_rdrs from bndr_vars as well as body_vars. -- See Note [Kind variable scoping] - where bndr_vars = extract_hs_tv_bndrs_kvs tv_bndrs tv_bndr_rdrs = map hsLTyVarLocName tv_bndrs @@ -1848,5 +1834,16 @@ extract_tv tv acc = nubL :: Eq a => [Located a] -> [Located a] nubL = nubBy eqLocated -elemRdr :: Located RdrName -> [Located RdrName] -> Bool -elemRdr x = any (eqLocated x) +-- | Filter out any potential implicit binders that are either +-- already in scope, or are explicitly bound in the binder. +filterFreeVarsToBind :: FreeKiTyVars + -- ^ Explicitly bound here + -> FreeKiTyVarsWithDups + -- ^ Potential implicit binders + -> FreeKiTyVarsWithDups + -- ^ Final implicit binders +filterFreeVarsToBind bndrs = filterOut is_in_scope + -- Make sure to list the binder kvs before the body kvs, as mandated by + -- Note [Ordering of implicit variables] + where + is_in_scope locc = any (eqLocated locc) bndrs ===================================== compiler/GHC/Rename/Module.hs ===================================== @@ -59,7 +59,7 @@ import GHC.Types.Basic ( pprRuleName, TypeOrKind(..) ) import GHC.Data.FastString import GHC.Types.SrcLoc as SrcLoc import GHC.Driver.Session -import GHC.Utils.Misc ( debugIsOn, filterOut, lengthExceeds, partitionWith ) +import GHC.Utils.Misc ( debugIsOn, lengthExceeds, partitionWith ) import GHC.Driver.Types ( HscEnv, hsc_dflags ) import GHC.Data.List.SetOps ( findDupsEq, removeDups, equivClasses ) import GHC.Data.Graph.Directed ( SCC, flattenSCC, flattenSCCs, Node(..) @@ -664,7 +664,9 @@ rnClsInstDecl (ClsInstDecl { cid_poly_ty = inst_ty, cid_binds = mbinds rnFamInstEqn :: HsDocContext -> AssocTyFamInfo - -> [Located RdrName] -- Kind variables from the equation's RHS + -> [Located RdrName] + -- ^ Kind variables from the equation's RHS to be implicitly bound + -- if no explicit forall. -> FamInstEqn GhcPs rhs -> (HsDocContext -> rhs -> RnM (rhs', FreeVars)) -> RnM (FamInstEqn GhcRn rhs', FreeVars) @@ -683,20 +685,36 @@ rnFamInstEqn doc atfi rhs_kvars -- Use the "...Dups" form because it's needed -- below to report unused binder on the LHS - -- Implicitly bound variables, empty if we have an explicit 'forall'. - -- See Note [forall-or-nothing rule] in GHC.Rename.HsType. - ; let imp_vars = nubL $ forAllOrNothing (isJust mb_bndrs) pat_kity_vars_with_dups - ; imp_var_names <- mapM (newTyVarNameRn mb_cls) imp_vars - ; let bndrs = fromMaybe [] mb_bndrs - bnd_vars = map hsLTyVarLocName bndrs - payload_kvars = filterOut (`elemRdr` (bnd_vars ++ imp_vars)) rhs_kvars - -- Make sure to filter out the kind variables that were explicitly - -- bound in the type patterns. - ; payload_kvar_names <- mapM (newTyVarNameRn mb_cls) payload_kvars - -- all names not bound in an explicit forall - ; let all_imp_var_names = imp_var_names ++ payload_kvar_names + -- all_imp_vars represent the implicitly bound type variables. This is + -- empty if we have an explicit `forall` (see + -- Note [forall-or-nothing rule] in GHC.Rename.HsType), which means + -- ignoring: + -- + -- - pat_kity_vars_with_dups, the variables mentioned in the LHS of + -- the equation, and + -- - rhs_kvars, the kind variables mentioned in an outermost kind + -- signature on the RHS of the equation. (See + -- Note [Implicit quantification in type synonyms] in + -- GHC.Rename.HsType for why these are implicitly quantified in the + -- absence of an explicit forall). + -- + -- For example: + -- + -- @ + -- type family F a b + -- type instance forall a b c. F [(a, b)] c = a -> b -> c + -- -- all_imp_vars = [] + -- type instance F [(a, b)] c = a -> b -> c + -- -- all_imp_vars = [a, b, c] + -- @ + ; all_imp_vars <- forAllOrNothing (isJust mb_bndrs) $ + -- No need to filter out explicit binders (the 'mb_bndrs = Just + -- explicit_bndrs' case) because there must be none if we're going + -- to implicitly bind anything, per the previous comment. + nubL $ pat_kity_vars_with_dups ++ rhs_kvars + ; all_imp_var_names <- mapM (newTyVarNameRn mb_cls) all_imp_vars -- All the free vars of the family patterns -- with a sensible binding location @@ -2096,14 +2114,14 @@ rnConDecl decl@(ConDeclGADT { con_names = names -- That order governs the order the implicitly-quantified type -- variable, and hence the order needed for visible type application -- See #14808. - free_tkvs = extractHsTvBndrs explicit_tkvs $ - extractHsTysRdrTyVarsDups (theta ++ arg_tys ++ [res_ty]) + ; implicit_bndrs <- forAllOrNothing explicit_forall + $ extractHsTvBndrs explicit_tkvs + $ extractHsTysRdrTyVarsDups (theta ++ arg_tys ++ [res_ty]) - ctxt = ConDeclCtx new_names + ; let ctxt = ConDeclCtx new_names mb_ctxt = Just (inHsDocContext ctxt) - ; traceRn "rnConDecl" (ppr names $$ ppr free_tkvs $$ ppr explicit_forall ) - ; rnImplicitBndrs (forAllOrNothing explicit_forall free_tkvs) $ \ implicit_tkvs -> + ; rnImplicitBndrs implicit_bndrs $ \ implicit_tkvs -> bindLHsTyVarBndrs ctxt mb_ctxt Nothing explicit_tkvs $ \ explicit_tkvs -> do { (new_cxt, fvs1) <- rnMbContext ctxt mcxt ; (new_args, fvs2) <- rnConDeclDetails (unLoc (head new_names)) ctxt args ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -6,6 +6,7 @@ This module converts Template Haskell syntax into Hs syntax -} +{-# LANGUAGE BangPatterns #-} {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ScopedTypeVariables #-} @@ -1232,8 +1233,7 @@ cvtLit (CharPrimL c) = do { force c; return $ HsCharPrim NoSourceText c } cvtLit (StringL s) = do { let { s' = mkFastString s } ; force s' ; return $ HsString (quotedSourceText s) s' } -cvtLit (StringPrimL s) = do { let { s' = BS.pack s } - ; force s' +cvtLit (StringPrimL s) = do { let { !s' = BS.pack s } ; return $ HsStringPrim NoSourceText s' } cvtLit (BytesPrimL (Bytes fptr off sz)) = do let bs = unsafePerformIO $ withForeignPtr fptr $ \ptr -> ===================================== compiler/GHC/Types/Literal.hs ===================================== @@ -114,7 +114,7 @@ data Literal -- See Note [Types of LitNumbers] below for the -- Type field. - | LitString ByteString -- ^ A string-literal: stored and emitted + | LitString !ByteString -- ^ A string-literal: stored and emitted -- UTF-8 encoded, we'll arrange to decode it -- at runtime. Also emitted with a @\'\\0\'@ -- terminator. Create with 'mkLitString' ===================================== docs/users_guide/8.12.1-notes.rst ===================================== @@ -79,12 +79,15 @@ Language * GHC now consistently does eager instantiation during type inference. As a consequence, visible type application (VTA) now only works when the head of the application is: + * A variable * An expression with a type signature - For example `(let x = blah in id) @Bool True` no longer typechecks. - You should write `let x = blah in id @Bool True` instead. - This change prepares the way for Quick Look impredicativity. + For example ``(let x = blah in id) @Bool True`` no longer typechecks. + You should write ``let x = blah in id @Bool True`` instead. + + This change prepares the way for `Quick Look impredicativity + `_. * GHC now allows users to manually define the specificity of type variable binders. By marking a variable with braces ``{tyvar}`` or ``{tyvar :: kind}``, @@ -110,60 +113,65 @@ Runtime system Template Haskell ~~~~~~~~~~~~~~~~ - - Implement the Overloaded Quotations proposal (#246). The type of all quotation - forms have now been generalised in terms of a minimal interface necessary for the - implementation rather than the overapproximation of the ``Q`` monad. +- Implement the `Overloaded Quotations proposal (#246) `_. + The type of all quotation forms have now been generalised in terms of a + minimal interface necessary (the ``Quote`` type class) for the + implementation rather than the overapproximation of the ``Q`` monad. - - Template Haskell quotes now handle fixity declarations in ``let`` and - ``where`` bindings properly. Previously, such fixity declarations would - be dropped when quoted due to a Template Haskell bug. +- Template Haskell quotes now handle fixity declarations in ``let`` and + ``where`` bindings properly. Previously, such fixity declarations would + be dropped when quoted due to a Template Haskell bug. - - The ``-XTemplateHaskellQuotes`` extension now allows nested splices as nested - splices do not lead directly to compile-time evaluation. (!2288) +- The ``-XTemplateHaskellQuotes`` extension now allows nested splices as nested + splices do not lead directly to compile-time evaluation. (Merge request + `!2288 `_) Arrow notation ~~~~~~~~~~~~~~ - - When combined with :extension:`Arrows`, the :extension:`LambdaCase` extension - now additionally allows ``\case`` syntax to be used as a command in ``proc`` - notation. +- When combined with :extension:`Arrows`, the :extension:`LambdaCase` extension + now additionally allows ``\case`` syntax to be used as a command in ``proc`` + notation. - - When combined with :extension:`Arrows`, the effects of the - :extension:`BlockArguments` extension now also apply to applications of - arrow control operators in ``(|`` banana brackets ``|)``: :: +- When combined with :extension:`Arrows`, the effects of the + :extension:`BlockArguments` extension now also apply to applications of + arrow control operators in ``(|`` banana brackets ``|)``: :: - (| untilA (increment -< x + y) do - within 0.5 -< x - ... |) + (| untilA (increment -< x + y) do + within 0.5 -< x + ... |) ``ghc-prim`` library ~~~~~~~~~~~~~~~~~~~~ +- Add a known-key ``cstringLength#`` to ``GHC.CString`` that is eligible + for constant folding by a built-in rule. + ``ghc`` library ~~~~~~~~~~~~~~~ - - The type of the ``getAnnotations`` function has changed to better reflect - the fact that it returns two different kinds of annotations, those on - names and those on modules: :: +- The type of the ``getAnnotations`` function has changed to better reflect + the fact that it returns two different kinds of annotations, those on + names and those on modules: :: - getAnnotations :: Typeable a - => ([Word8] -> a) -> ModGuts - -> CoreM (ModuleEnv [a], NameEnv [a]) + getAnnotations :: Typeable a + => ([Word8] -> a) -> ModGuts + -> CoreM (ModuleEnv [a], NameEnv [a]) - - The meaning of the ``hs_fixds`` field of ``HsGroup`` has changed slightly. - It now only contains fixity signatures defined for top-level declarations - and class methods defined *outside* of the class itself. Previously, - ``hs_fixds`` would also contain fixity signatures for class methods defined - *inside* the class, such as the fixity signature for ``m`` in the following - example: :: +- The meaning of the ``hs_fixds`` field of ``HsGroup`` has changed slightly. + It now only contains fixity signatures defined for top-level declarations + and class methods defined *outside* of the class itself. Previously, + ``hs_fixds`` would also contain fixity signatures for class methods defined + *inside* the class, such as the fixity signature for ``m`` in the following + example: :: - class C a where - infixl 4 `m` - m :: a -> a -> a + class C a where + infixl 4 `m` + m :: a -> a -> a - If you wish to attain the previous behavior of ``hs_fixds``, use the new - ``hsGroupTopLevelFixitySigs`` function, which collects all top-level fixity - signatures, including those for class methods defined inside classes. + If you wish to attain the previous behavior of ``hs_fixds``, use the new + ``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`` @@ -176,6 +184,15 @@ Arrow notation ``base`` library ~~~~~~~~~~~~~~~~ +- ``ForeignPtrContents`` has a new nullary data constructor ``FinalPtr``. + ``FinalPtr`` is intended for turning a primitive string literal into a + ``ForeignPtr``. Unlike ``PlainForeignPtr``, ``FinalPtr`` does not have + a finalizer. Replacing ``PlainForeignPtr`` that has ``NoFinalizers`` with + ``FinalPtr`` reduces allocations, reduces the size of compiled binaries, + and unlocks important Core-to-Core optimizations. ``FinalPtr`` will be used + in an upcoming ``bytestring`` release to improve the performance of + ``ByteString`` literals created with ``OverloadedStrings``. + Build system ~~~~~~~~~~~~ @@ -196,7 +213,7 @@ for further change information. libraries/containers/containers/containers.cabal: Dependency of ``ghc`` library libraries/deepseq/deepseq.cabal: Dependency of ``ghc`` library libraries/directory/directory.cabal: Dependency of ``ghc`` library - libraries/exceptions/exceptions.cabal: Dependency of ``haskeline`` library + libraries/exceptions/exceptions.cabal: Dependency of ``ghc`` and ``haskeline`` library libraries/filepath/filepath.cabal: Dependency of ``ghc`` library compiler/ghc.cabal: The compiler itself libraries/ghci/ghci.cabal: The REPL interface ===================================== docs/users_guide/exts/template_haskell.rst ===================================== @@ -74,7 +74,7 @@ The :extension:`TemplateHaskellQuotes` extension is considered safe under that declaration splices are not allowed anywhere except at top level (outside any other declarations). - The ``Q`` monad is a monad defined in ``Language.Haskell.TH.Syntax`` which + The ``Q`` monad is a monad defined in :th-ref:`Language.Haskell.TH.Syntax.` which supports several useful operations during code generation such as reporting errors or looking up identifiers in the environment. @@ -92,9 +92,10 @@ The :extension:`TemplateHaskellQuotes` extension is considered safe under - ``[p| ... |]``, where the "..." is a pattern; the quotation has type ``Quote m => m Pat``. - The ``Quote`` type class is the minimal interface necessary to implement - the desugaring of quotations. The ``Q`` monad is an instance of ``Quote`` but - contains many more operations which are not needed for defining quotations. + The ``Quote`` type class (:th-ref:`Language.Haskell.TH.Syntax.Quote`) is + the minimal interface necessary to implement the desugaring of quotations. + The ``Q`` monad is an instance of ``Quote`` but contains many more + operations which are not needed for defining quotations. See :ref:`pts-where` for using partial type signatures in quotations. @@ -402,7 +403,7 @@ Using Template Haskell ---------------------- - The data types and monadic constructor functions for Template Haskell - are in the library ``Language.Haskell.TH.Syntax``. + are in the library :th-ref:`Language.Haskell.TH.Syntax.`. - You can only run a function at compile time if it is imported from another module. That is, you can't define a function in a module, and @@ -645,7 +646,7 @@ Here are the salient features (Only the first two are described in the paper.) - A quoter is a value of type - ``Language.Haskell.TH.Quote.QuasiQuoter``, which is defined thus: :: + :th-ref:`Language.Haskell.TH.Quote.QuasiQuoter`, which is defined thus: :: data QuasiQuoter = QuasiQuoter { quoteExp :: String -> Q Exp, quotePat :: String -> Q Pat, ===================================== docs/users_guide/using.rst ===================================== @@ -1136,10 +1136,11 @@ Haddock single: haddock .. ghc-flag:: -haddock - :shortdesc: Make the parser more strict about Haddock comments. + :shortdesc: With this flag GHC will parse Haddock comments and include them + in the interface file it produces. :type: dynamic :reverse: -no-haddock - :category: misc + :category: haddock By default, GHC ignores Haddock comments (``-- | ...`` and ``-- ^ ...``) and does not check that they're associated with a valid term, such as a ===================================== libraries/base/GHC/Exts.hs ===================================== @@ -54,6 +54,14 @@ module GHC.Exts -- * Overloaded string literals IsString(..), + -- * CString + unpackCString#, + unpackAppendCString#, + unpackFoldrCString#, + unpackCStringUtf8#, + unpackNBytes#, + cstringLength#, + -- * Debugging breakpoint, breakpointCond, ===================================== libraries/base/GHC/ForeignPtr.hs ===================================== @@ -23,11 +23,13 @@ module GHC.ForeignPtr ( + -- * Types ForeignPtr(..), ForeignPtrContents(..), Finalizers(..), FinalizerPtr, FinalizerEnvPtr, + -- * Create newForeignPtr_, mallocForeignPtr, mallocPlainForeignPtr, @@ -35,15 +37,20 @@ module GHC.ForeignPtr mallocPlainForeignPtrBytes, mallocForeignPtrAlignedBytes, mallocPlainForeignPtrAlignedBytes, + newConcForeignPtr, + -- * Add Finalizers addForeignPtrFinalizer, addForeignPtrFinalizerEnv, - touchForeignPtr, + addForeignPtrConcFinalizer, + -- * Conversion unsafeForeignPtrToPtr, castForeignPtr, plusForeignPtr, - newConcForeignPtr, - addForeignPtrConcFinalizer, + -- * Finalization + touchForeignPtr, finalizeForeignPtr + -- * Commentary + -- $commentary ) where import Foreign.Storable @@ -86,15 +93,121 @@ data ForeignPtr a = ForeignPtr Addr# ForeignPtrContents -- object, because that ensures that whatever the finalizer is -- attached to is kept alive. +-- | Functions called when a 'ForeignPtr' is finalized. Note that +-- C finalizers and Haskell finalizers cannot be mixed. data Finalizers = NoFinalizers + -- ^ No finalizer. If there is no intent to add a finalizer at + -- any point in the future, consider 'FinalPtr' or 'PlainPtr' instead + -- since these perform fewer allocations. | CFinalizers (Weak# ()) + -- ^ Finalizers are all C functions. | HaskellFinalizers [IO ()] + -- ^ Finalizers are all Haskell functions. +-- | Controls finalization of a 'ForeignPtr', that is, what should happen +-- if the 'ForeignPtr' becomes unreachable. Visually, these data constructors +-- are appropriate in these scenarios: +-- +-- > Memory backing pointer is +-- > GC-Managed Unmanaged +-- > Finalizer functions are: +------------+-----------------+ +-- > Allowed | MallocPtr | PlainForeignPtr | +-- > +------------+-----------------+ +-- > Prohibited | PlainPtr | FinalPtr | +-- > +------------+-----------------+ data ForeignPtrContents = PlainForeignPtr !(IORef Finalizers) - | MallocPtr (MutableByteArray# RealWorld) !(IORef Finalizers) - | PlainPtr (MutableByteArray# RealWorld) + -- ^ The pointer refers to unmanaged memory that was allocated by + -- a foreign function (typically using @malloc@). The finalizer + -- frequently calls the C function @free@ or some variant of it. + | FinalPtr + -- ^ The pointer refers to unmanaged memory that should not be freed when + -- the 'ForeignPtr' becomes unreachable. Functions that add finalizers + -- to a 'ForeignPtr' throw exceptions when the 'ForeignPtr' is backed by + -- 'PlainPtr'Most commonly, this is used with @Addr#@ literals. + -- See Note [Why FinalPtr]. + -- + -- @since 4.15 + | MallocPtr (MutableByteArray# RealWorld) !(IORef Finalizers) + -- ^ The pointer refers to a byte array. + -- The 'MutableByteArray#' field means that the 'MutableByteArray#' is + -- reachable (by GC) whenever the 'ForeignPtr' is reachable. When the + -- 'ForeignPtr' becomes unreachable, the runtime\'s normal GC recovers + -- the memory backing it. Here, the finalizer function intended to be used + -- to @free()@ any ancilliary *unmanaged* memory pointed to by the + -- 'MutableByteArray#'. See the @zlib@ library for an example of this use. + -- + -- 1. Invariant: The 'Addr#' in the parent 'ForeignPtr' is an interior + -- pointer into this 'MutableByteArray#'. + -- 2. Invariant: The 'MutableByteArray#' is pinned, so the 'Addr#' does not + -- get invalidated by the GC moving the byte array. + -- 3. Invariant: A 'MutableByteArray#' must not be associated with more than + -- one set of finalizers. For example, this is sound: + -- + -- > incrGood :: ForeignPtr Word8 -> ForeignPtr Word8 + -- > incrGood (ForeignPtr p (MallocPtr m f)) = ForeignPtr (plusPtr p 1) (MallocPtr m f) + -- + -- But this is unsound: + -- + -- > incrBad :: ForeignPtr Word8 -> IO (ForeignPtr Word8) + -- > incrBad (ForeignPtr p (MallocPtr m _)) = do + -- > f <- newIORef NoFinalizers + -- > pure (ForeignPtr p (MallocPtr m f)) + | PlainPtr (MutableByteArray# RealWorld) + -- ^ The pointer refers to a byte array. Finalization is not + -- supported. This optimizes @MallocPtr@ by avoiding the allocation + -- of a @MutVar#@ when it is known that no one will add finalizers to + -- the @ForeignPtr at . Functions that add finalizers to a 'ForeignPtr' + -- throw exceptions when the 'ForeignPtr' is backed by 'PlainPtr'. + -- The invariants that apply to 'MallocPtr' apply to 'PlainPtr' as well. + +-- Note [Why FinalPtr] +-- +-- FinalPtr exists as an optimization for foreign pointers created +-- from Addr# literals. Most commonly, this happens in the bytestring +-- library, where the combination of OverloadedStrings and a rewrite +-- rule overloads String literals as ByteString literals. See the +-- rule "ByteString packChars/packAddress" in +-- bytestring:Data.ByteString.Internal. Prior to the +-- introduction of FinalPtr, bytestring used PlainForeignPtr (in +-- Data.ByteString.Internal.unsafePackAddress) to handle such literals. +-- With O2 optimization, the resulting Core from a GHC patched with a +-- known-key cstringLength# function but without FinalPtr looked like: +-- +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +-- stringOne1 = "hello beautiful world"# +-- RHS size: {terms: 11, types: 17, coercions: 0, joins: 0/0} +-- stringOne +-- = case newMutVar# NoFinalizers realWorld# of +-- { (# ipv_i7b6, ipv1_i7b7 #) -> +-- PS stringOne1 (PlainForeignPtr ipv1_i7b7) 0# 21# +-- } +-- +-- After the introduction of FinalPtr, the bytestring library was modified +-- so that the resulting Core was instead: +-- +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +-- stringOne1 = "hello beautiful world"# +-- RHS size: {terms: 5, types: 0, coercions: 0, joins: 0/0} +-- stringOne = PS stringOne1 FinalPtr 0# 21# +-- +-- This improves performance in three ways: +-- +-- 1. More optimization opportunities. GHC is willing to inline the FinalPtr +-- variant of stringOne into its use sites. This means the offset and length +-- are eligible for case-of-known-literal. Previously, this never happened. +-- 2. Smaller binaries. Setting up the thunk to call newMutVar# required +-- machine instruction in the generated code. On x86_64, FinalPtr reduces +-- the size of binaries by about 450 bytes per ByteString literal. +-- 3. Smaller memory footprint. Previously, every ByteString literal resulted +-- in the allocation of a MutVar# and a PlainForeignPtr data constructor. +-- These both hang around until the ByteString goes out of scope. FinalPtr +-- eliminates both of these sources of allocations. The MutVar# is not +-- allocated because FinalPtr does not allow it, and the data constructor +-- is not allocated because FinalPtr is a nullary data constructor. +-- +-- For more discussion of FinalPtr, see GHC MR #2165 and bytestring PR #191. -- | @since 2.01 instance Eq (ForeignPtr a) where @@ -259,7 +372,7 @@ addForeignPtrFinalizer :: FinalizerPtr a -> ForeignPtr a -> IO () addForeignPtrFinalizer (FunPtr fp) (ForeignPtr p c) = case c of PlainForeignPtr r -> insertCFinalizer r fp 0# nullAddr# p () MallocPtr _ r -> insertCFinalizer r fp 0# nullAddr# p c - _ -> errorWithoutStackTrace "GHC.ForeignPtr: attempt to add a finalizer to a plain pointer" + _ -> errorWithoutStackTrace "GHC.ForeignPtr: attempt to add a finalizer to a plain pointer or a final pointer" -- Note [MallocPtr finalizers] (#10904) -- @@ -277,7 +390,7 @@ addForeignPtrFinalizerEnv :: addForeignPtrFinalizerEnv (FunPtr fp) (Ptr ep) (ForeignPtr p c) = case c of PlainForeignPtr r -> insertCFinalizer r fp 1# ep p () MallocPtr _ r -> insertCFinalizer r fp 1# ep p c - _ -> errorWithoutStackTrace "GHC.ForeignPtr: attempt to add a finalizer to a plain pointer" + _ -> errorWithoutStackTrace "GHC.ForeignPtr: attempt to add a finalizer to a plain pointer or a final pointer" addForeignPtrConcFinalizer :: ForeignPtr a -> IO () -> IO () -- ^This function adds a finalizer to the given @ForeignPtr at . The @@ -319,7 +432,7 @@ addForeignPtrConcFinalizer_ f@(MallocPtr fo r) finalizer = do finalizer' = unIO (foreignPtrFinalizer r >> touch f) addForeignPtrConcFinalizer_ _ _ = - errorWithoutStackTrace "GHC.ForeignPtr: attempt to add a finalizer to plain pointer" + errorWithoutStackTrace "GHC.ForeignPtr: attempt to add a finalizer to plain pointer or a final pointer" insertHaskellFinalizer :: IORef Finalizers -> IO () -> IO Bool insertHaskellFinalizer r f = do @@ -345,6 +458,8 @@ insertCFinalizer r fp flag ep p val = do -- replaced the content of r before calling finalizeWeak#. (# s1, _ #) -> unIO (insertCFinalizer r fp flag ep p val) s1 +-- Read the weak reference from an IORef Finalizers, creating it if necessary. +-- Throws an exception if HaskellFinalizers is encountered. ensureCFinalizerWeak :: IORef Finalizers -> value -> IO MyWeak ensureCFinalizerWeak ref@(IORef (STRef r#)) value = do fin <- readIORef ref @@ -370,6 +485,7 @@ noMixingError = errorWithoutStackTrace $ "GHC.ForeignPtr: attempt to mix Haskell and C finalizers " ++ "in the same ForeignPtr" +-- Swap out the finalizers with NoFinalizers and then run them. foreignPtrFinalizer :: IORef Finalizers -> IO () foreignPtrFinalizer r = do fs <- atomicSwapIORef r NoFinalizers @@ -455,13 +571,53 @@ plusForeignPtr :: ForeignPtr a -> Int -> ForeignPtr b plusForeignPtr (ForeignPtr addr c) (I# d) = ForeignPtr (plusAddr# addr d) c -- | Causes the finalizers associated with a foreign pointer to be run --- immediately. +-- immediately. The foreign pointer must not be used again after this +-- function is called. finalizeForeignPtr :: ForeignPtr a -> IO () -finalizeForeignPtr (ForeignPtr _ (PlainPtr _)) = return () -- no effect -finalizeForeignPtr (ForeignPtr _ foreignPtr) = foreignPtrFinalizer refFinalizers - where - refFinalizers = case foreignPtr of - (PlainForeignPtr ref) -> ref - (MallocPtr _ ref) -> ref - PlainPtr _ -> - errorWithoutStackTrace "finalizeForeignPtr PlainPtr" +finalizeForeignPtr (ForeignPtr _ c) = case c of + PlainForeignPtr ref -> foreignPtrFinalizer ref + MallocPtr _ ref -> foreignPtrFinalizer ref + _ -> errorWithoutStackTrace "finalizeForeignPtr PlainPtr" + +{- $commentary + +This is a high-level overview of how 'ForeignPtr' works. +The implementation of 'ForeignPtr' must accomplish several goals: + +1. Invoke a finalizer once a foreign pointer becomes unreachable. +2. Support augmentation of finalizers, i.e. 'addForeignPtrFinalizer'. + As a motivating example, suppose that the payload of a foreign + pointer is C struct @bar@ that has an optionally NULL pointer field + @foo@ to an unmanaged heap object. Initially, @foo@ is NULL, and + later the program uses @malloc@, initializes the object, and assigns + @foo@ the address returned by @malloc at . When the foreign pointer + becomes unreachable, it is now necessary to first @free@ the object + pointed to by @foo@ and then invoke whatever finalizer was associated + with @bar at . That is, finalizers must be invoked in the opposite order + they are added. +3. Allow users to invoke a finalizer promptly if they know that the + foreign pointer is unreachable, i.e. 'finalizeForeignPtr'. + +How can these goals be accomplished? Goal 1 suggests that weak references +and finalizers (via 'Weak#' and 'mkWeak#') are necessary. But how should +they be used and what should their key be? Certainly not 'ForeignPtr' or +'ForeignPtrContents'. See the warning in "GHC.Weak" about weak pointers with +lifted (non-primitive) keys. The two finalizer-supporting data constructors of +'ForeignPtr' have an @'IORef' 'Finalizers'@ (backed by 'MutVar#') field. +This gets used in two different ways depending on the kind of finalizer: + +* 'HaskellFinalizers': The first @addForeignPtrConcFinalizer_@ call uses + 'mkWeak#' to attach the finalizer @foreignPtrFinalizer@ to the 'MutVar#'. + The resulting 'Weak#' is discarded (see @addForeignPtrConcFinalizer_@). + Subsequent calls to @addForeignPtrConcFinalizer_@ (goal 2) just add + finalizers onto the list in the 'HaskellFinalizers' data constructor. +* 'CFinalizers': The first 'addForeignPtrFinalizer' call uses + 'mkWeakNoFinalizer#' to create a 'Weak#'. The 'Weak#' is preserved in the + 'CFinalizers' data constructor. Both the first call and subsequent + calls (goal 2) use 'addCFinalizerToWeak#' to attach finalizers to the + 'Weak#' itself. Also, see Note [MallocPtr finalizers] for discussion of + the key and value of this 'Weak#'. + +In either case, the runtime invokes the appropriate finalizers when the +'ForeignPtr' becomes unreachable. +-} ===================================== libraries/ghc-prim/GHC/CString.hs ===================================== @@ -1,5 +1,4 @@ -{-# LANGUAGE MagicHash, NoImplicitPrelude, BangPatterns #-} - +{-# LANGUAGE MagicHash, NoImplicitPrelude, BangPatterns, UnliftedFFITypes #-} ----------------------------------------------------------------------------- -- | -- Module : GHC.CString @@ -18,7 +17,7 @@ module GHC.CString ( unpackCString#, unpackAppendCString#, unpackFoldrCString#, - unpackCStringUtf8#, unpackNBytes# + unpackCStringUtf8#, unpackNBytes#, cstringLength# ) where import GHC.Types @@ -174,3 +173,17 @@ unpackNBytes# addr len# = unpack [] (len# -# 1#) case indexCharOffAddr# addr i# of ch -> unpack (C# ch : acc) (i# -# 1#) +-- The return type is not correct here. We really want CSize, +-- but that type is defined in base. However, CSize should always +-- match the size of a machine word (I hope), so this is probably +-- alright on all platforms that GHC supports. +foreign import ccall unsafe "strlen" c_strlen :: Addr# -> Int# + +-- | Compute the length of a NUL-terminated string. This address +-- must refer to immutable memory. GHC includes a built-in rule for +-- constant folding when the argument is a statically-known literal. +-- That is, a core-to-core pass reduces the expression +-- @cstringLength# "hello"#@ to the constant @5#@. +cstringLength# :: Addr# -> Int# +{-# INLINE[0] cstringLength# #-} +cstringLength# = c_strlen ===================================== libraries/ghc-prim/changelog.md ===================================== @@ -1,3 +1,11 @@ +## 0.6.2 (edit as necessary) + +- Shipped with GHC 8.12.1 + +- Add known-key `cstringLength#` to `GHC.CString`. This is just the + C function `strlen`, but a built-in rewrite rule allows GHC to + compute the result at compile time when the argument is known. + ## 0.6.1 (edit as necessary) - Shipped with GHC 8.10.1 ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit 8fffea5ca319e85e1bc9e7cac39e5a2c8effefcc +Subproject commit 1afc36ecd38c069251a836e1c1c8b3a3043ddc01 ===================================== testsuite/.gitignore ===================================== @@ -43,6 +43,7 @@ Thumbs.db *.prof.sample.normalised *.run.stdout *.run.stderr +*.dump-simpl *.hp tests/**/*.ps ===================================== testsuite/driver/testlib.py ===================================== @@ -1344,6 +1344,26 @@ def compile_grep_asm(name: TestName, # no problems found, this test passed return passed() +def compile_grep_core(name: TestName, + way: WayName, + extra_hc_opts: str + ) -> PassFail: + print('Compile only, extra args = ', extra_hc_opts) + result = simple_build(name + '.hs', way, '-ddump-to-file -dsuppress-all -ddump-simpl -O ' + extra_hc_opts, False, None, False, False) + + if badResult(result): + return result + + expected_pat_file = find_expected_file(name, 'substr-simpl') + actual_core_file = add_suffix(name, 'dump-simpl') + + if not grep_output(join_normalisers(normalise_errmsg), + expected_pat_file, actual_core_file): + return failBecause('simplified core mismatch') + + # no problems found, this test passed + return passed() + # ----------------------------------------------------------------------------- # Compile-and-run tests ===================================== testsuite/tests/primops/should_gen_core/CStringLength_core.hs ===================================== @@ -0,0 +1,11 @@ +{-# language MagicHash #-} + +module CStringLengthCore + ( ozymandias + ) where + +import GHC.Exts + +ozymandias :: Int +ozymandias = + I# (cstringLength# "I met a traveller from an antique land"#) ===================================== testsuite/tests/primops/should_gen_core/CStringLength_core.substr-simpl ===================================== @@ -0,0 +1 @@ +I# 38# ===================================== testsuite/tests/primops/should_gen_core/all.T ===================================== @@ -0,0 +1 @@ +test('CStringLength_core', normal, compile_grep_core, ['']) ===================================== testsuite/tests/primops/should_run/CStringLength.hs ===================================== @@ -0,0 +1,33 @@ +{-# LANGUAGE BangPatterns #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} + +import GHC.Exts + +main :: IO () +main = do + putStr "A: " + print $ + I# (cstringLength# "hello_world"#) + == + naiveStrlen "hello_world"# 0 + putStr "B: " + print $ + I# (cstringLength# "aaaaaaaaaaaaa\x00b"#) + == + naiveStrlen "aaaaaaaaaaaaa\x00b"# 0 + putStr "C: " + print $ + I# (cstringLength# "cccccccccccccccccc\x00b"#) + == + naiveStrlen "cccccccccccccccccc\x00b"# 0 + putStr "D: " + print $ + I# (cstringLength# "araña\NULb"#) + == + naiveStrlen "araña\NULb"# 0 + +naiveStrlen :: Addr# -> Int -> Int +naiveStrlen addr !n = case indexWord8OffAddr# addr 0# of + 0## -> n + _ -> naiveStrlen (plusAddr# addr 1#) (n + 1) ===================================== testsuite/tests/primops/should_run/CStringLength.stdout ===================================== @@ -0,0 +1,4 @@ +A: True +B: True +C: True +D: True ===================================== testsuite/tests/primops/should_run/all.T ===================================== @@ -29,3 +29,4 @@ test('CmpWord16', normal, compile_and_run, ['']) test('ShrinkSmallMutableArrayA', normal, compile_and_run, ['']) test('ShrinkSmallMutableArrayB', normal, compile_and_run, ['']) test('T14664', normal, compile_and_run, ['']) +test('CStringLength', normal, compile_and_run, ['-O2']) ===================================== testsuite/tests/rename/should_fail/T18145.hs ===================================== @@ -0,0 +1,17 @@ +{-# LANGUAGE ExplicitForAll #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE DataKinds #-} + +module T18145 where + +type family A :: k +type instance forall. A = Nothing :: Maybe a -- 'a' should be out of scope + +class Foo x where + type B x :: Maybe a + type forall x. B x = Nothing :: Maybe a -- 'a' should be out of scope + +instance Foo [x] where + type forall. B [x] = Nothing :: Maybe a -- 'a' should be out of scope ===================================== testsuite/tests/rename/should_fail/T18145.stderr ===================================== @@ -0,0 +1,6 @@ + +T18145.hs:10:44: error: Not in scope: type variable ‘a’ + +T18145.hs:14:41: error: Not in scope: type variable ‘a’ + +T18145.hs:17:41: error: Not in scope: type variable ‘a’ ===================================== testsuite/tests/rename/should_fail/all.T ===================================== @@ -153,3 +153,4 @@ test('T16504', normal, compile_fail, ['']) test('T14548', normal, compile_fail, ['']) test('T16610', normal, compile_fail, ['']) test('T17593', normal, compile_fail, ['']) +test('T18145', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/be3a978b1677f0a70af033d9699bdffb106e3506...f5f3e7091dc281a48fd7c29862052d3f8475a793 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/be3a978b1677f0a70af033d9699bdffb106e3506...f5f3e7091dc281a48fd7c29862052d3f8475a793 You're receiving 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 23 01:39:30 2020 From: gitlab at gitlab.haskell.org (Daneel S. Yaitskov) Date: Fri, 22 May 2020 21:39:30 -0400 Subject: [Git][ghc/ghc][wip/T17949] 4 commits: T17949 TRACE_user instead of eventlog_enabled Message-ID: <5ec87ed257ac2_6e2690328d09519f2@gitlab.haskell.org.mail> Daneel S. Yaitskov pushed to branch wip/T17949 at Glasgow Haskell Compiler / GHC Commits: 0d4447ec by Daneel Yaitskov at 2020-05-22T14:09:58-07:00 T17949 TRACE_user instead of eventlog_enabled - - - - - 271d0ee1 by Daneel Yaitskov at 2020-05-22T18:33:03-07:00 T17949 RTS_DEFAULT macro - - - - - 93e5960d by Daneel Yaitskov at 2020-05-22T18:34:19-07:00 T17949 fix TRACE_user type - - - - - 46e71578 by Daneel Yaitskov at 2020-05-22T18:36:54-07:00 T17949 export TRACE_user - - - - - 6 changed files: - includes/Rts.h - libraries/base/Debug/Trace.hs - rts/Trace.c - rts/Trace.h - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h Changes: ===================================== includes/Rts.h ===================================== @@ -57,8 +57,10 @@ extern "C" { // library. #if defined(HAS_VISIBILITY_HIDDEN) #define RTS_PRIVATE GNUC3_ATTRIBUTE(visibility("hidden")) +#define RTS_DEFAULT GNUC3_ATTRIBUTE(visibility("default")) #else #define RTS_PRIVATE /* disabled: RTS_PRIVATE */ +#define RTS_DEFAULT #endif #if __GNUC__ >= 4 ===================================== libraries/base/Debug/Trace.hs ===================================== @@ -53,6 +53,7 @@ import GHC.Base import qualified GHC.Foreign import GHC.IO.Encoding import GHC.Ptr +import GHC.Real import GHC.Show import GHC.Stack import Data.List (null, partition) @@ -75,7 +76,7 @@ import Data.List (null, partition) -- Some implementations of these functions may decorate the string that\'s -- output to indicate that you\'re tracing. -foreign import ccall "&eventlog_enabled" eventlog_enabled :: Ptr CBool +foreign import ccall "&TRACE_user" traceUser :: Ptr CInt -- | The 'whenEventlog' function evals argument action -- if RTS eventlog (+RTS -l) is enabled. @@ -84,8 +85,8 @@ foreign import ccall "&eventlog_enabled" eventlog_enabled :: Ptr CBool {-# INLINE whenEventlog #-} whenEventlog :: IO () -> IO () whenEventlog logAction = do - ee <- peek eventlog_enabled - if toBool ee + ee <- peek traceUser + if 0 < (fromIntegral ee :: Int) then logAction else return () ===================================== rts/Trace.c ===================================== @@ -33,7 +33,9 @@ int TRACE_gc; int TRACE_nonmoving_gc; int TRACE_spark_sampled; int TRACE_spark_full; -int TRACE_user; +#endif /* TRACING */ +RTS_DEFAULT int TRACE_user; // used in Debug.Trace +#if defined(TRACING) int TRACE_cap; #if defined(THREADED_RTS) ===================================== rts/Trace.h ===================================== @@ -71,7 +71,7 @@ extern int TRACE_sched; extern int TRACE_gc; extern int TRACE_spark_sampled; extern int TRACE_spark_full; -/* extern int TRACE_user; */ // only used in Trace.c + extern int TRACE_cap; extern int TRACE_nonmoving_gc; ===================================== rts/eventlog/EventLog.c ===================================== @@ -26,13 +26,8 @@ #include #endif -#endif /* TRACING */ - -// for ghc-pkg is build without TRACING bool eventlog_enabled; -#if defined(TRACING) - static const EventLogWriter *event_log_writer = NULL; #define EVENT_LOG_SIZE 2 * (1024 * 1024) // 2MB ===================================== rts/eventlog/EventLog.h ===================================== @@ -15,8 +15,6 @@ #include "BeginPrivate.h" -extern bool eventlog_enabled; - #if defined(TRACING) /* @@ -24,6 +22,7 @@ extern bool eventlog_enabled; */ extern char *EventTagDesc[]; +extern bool eventlog_enabled; void initEventLogging(void); void restartEventLogging(void); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fca165f00d97179a91c2b95d86a8e5c2400c9c75...46e71578244d3a0433569b3a5a8d63238fb17c30 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fca165f00d97179a91c2b95d86a8e5c2400c9c75...46e71578244d3a0433569b3a5a8d63238fb17c30 You're receiving 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 23 01:47:14 2020 From: gitlab at gitlab.haskell.org (Daneel S. Yaitskov) Date: Fri, 22 May 2020 21:47:14 -0400 Subject: [Git][ghc/ghc][wip/T17949] T17949 reduce diff Message-ID: <5ec880a2c2107_6e26eb364ac9538b@gitlab.haskell.org.mail> Daneel S. Yaitskov pushed to branch wip/T17949 at Glasgow Haskell Compiler / GHC Commits: af482de7 by Daneel Yaitskov at 2020-05-22T18:47:02-07:00 T17949 reduce diff - - - - - 1 changed file: - libraries/base/Debug/Trace.hs Changes: ===================================== libraries/base/Debug/Trace.hs ===================================== @@ -95,7 +95,7 @@ whenEventlog logAction = do -- -- @since 4.5.0.0 traceIO :: String -> IO () -traceIO msg = +traceIO msg = do withCString "%s\n" $ \cfmt -> do -- NB: debugBelch can't deal with null bytes, so filter them -- out so we don't accidentally truncate the message. See #9395 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/af482de7842ede1300ad661da8e658d0ef1d4eec -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/af482de7842ede1300ad661da8e658d0ef1d4eec You're receiving 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 23 03:15:33 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 22 May 2020 23:15:33 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/bump-base Message-ID: <5ec8955525432_6e263f9ee298416095576@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/bump-base at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/bump-base You're receiving 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 23 03:28:12 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 22 May 2020 23:28:12 -0400 Subject: [Git][ghc/ghc][wip/T18079] 134 commits: Switch order on `GhcMake.IsBoot` Message-ID: <5ec8984ce63f0_6e263f9ee35223009573f0@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18079 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. - - - - - 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. - - - - - 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] - - - - - 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 - - - - - 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 - - - - - 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. - - - - - 78c6523c by Ben Gamari at 2020-05-21T12:13:01-04:00 nonmoving: Optimise the write barrier - - - - - 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). - - - - - 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 - - - - - b7a6b2f4 by Gleb Popov at 2020-05-21T12:15:26-04:00 gitlab-ci: Set locale to C.UTF-8. - - - - - 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. - - - - - 0004ccb8 by Tuan Le at 2020-05-21T12:16:46-04:00 llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 - - - - - 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 - - - - - 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 - - - - - 2b363ebb by Richard Eisenberg at 2020-05-21T12:18:45-04:00 MR template should ask for key part - - - - - a95bbd0b by Sebastian Graf at 2020-05-21T12:19:37-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. - - - - - d3d055b8 by Galen Huntington at 2020-05-21T12:20:18-04:00 Clarify pitfalls of NegativeLiterals; see #18022. - - - - - 1b508a9e by Alexey Kuleshevich at 2020-05-21T12:21:02-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" - - - - - 4ca0c8a1 by Andreas Klebinger at 2020-05-21T12:21: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. - - - - - a1275081 by Krzysztof Gogolewski at 2020-05-21T12:22:35-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 - - - - - 8a816e5f by Krzysztof Gogolewski at 2020-05-21T12:23:55-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. - - - - - 566cc73f by Sylvain Henry at 2020-05-21T12:24:45-04:00 Move isDynLinkName into GHC.Types.Name It doesn't belong into GHC.Unit.State - - - - - 3ddb9018 by Ben Gamari at 2020-05-22T23:28:03-04:00 Eta expand un-saturated primops Now since we no longer try to predict CAFfyness we have no need for the solution to #16846. Eta expanding unsaturated primop applications is conceptually simpler, especially in the presence of levity polymorphism. This essentially reverts cac8dc9f51e31e4c0a6cd9bc302f7e1bc7c03beb, as suggested in #18079. Closes #18079. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/merge_request_templates/merge-request.md - 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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b0494a52537ac18e07560b5cc6e230d0cb2a8351...3ddb90189212c5a5282cd9a0581cf288539206a4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b0494a52537ac18e07560b5cc6e230d0cb2a8351...3ddb90189212c5a5282cd9a0581cf288539206a4 You're receiving 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 23 11:14:08 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Sat, 23 May 2020 07:14:08 -0400 Subject: [Git][ghc/ghc][wip/T18191] 32 commits: Remove duplicate Note [When to print foralls] in GHC.Core.TyCo.Ppr Message-ID: <5ec905801b49b_6e26eb4a6c897791b@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T18191 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] - - - - - 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 - - - - - 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 - - - - - 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. - - - - - 78c6523c by Ben Gamari at 2020-05-21T12:13:01-04:00 nonmoving: Optimise the write barrier - - - - - 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). - - - - - 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 - - - - - b7a6b2f4 by Gleb Popov at 2020-05-21T12:15:26-04:00 gitlab-ci: Set locale to C.UTF-8. - - - - - 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. - - - - - 0004ccb8 by Tuan Le at 2020-05-21T12:16:46-04:00 llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 - - - - - 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 - - - - - 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 - - - - - 2b363ebb by Richard Eisenberg at 2020-05-21T12:18:45-04:00 MR template should ask for key part - - - - - a95bbd0b by Sebastian Graf at 2020-05-21T12:19:37-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. - - - - - d3d055b8 by Galen Huntington at 2020-05-21T12:20:18-04:00 Clarify pitfalls of NegativeLiterals; see #18022. - - - - - 1b508a9e by Alexey Kuleshevich at 2020-05-21T12:21:02-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" - - - - - 4ca0c8a1 by Andreas Klebinger at 2020-05-21T12:21: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. - - - - - a1275081 by Krzysztof Gogolewski at 2020-05-21T12:22:35-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 - - - - - 8a816e5f by Krzysztof Gogolewski at 2020-05-21T12:23:55-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. - - - - - 566cc73f by Sylvain Henry at 2020-05-21T12:24:45-04:00 Move isDynLinkName into GHC.Types.Name It doesn't belong into GHC.Unit.State - - - - - 069f2a8d by Ryan Scott at 2020-05-23T07:13:42-04:00 Make GADT constructors adhere to the forall-or-nothing rule properly Issue #18191 revealed that the types of GADT constructors don't quite adhere to the `forall`-or-nothing rule. This patch serves to clean up this sad state of affairs somewhat. The main change is not in the code itself, but in the documentation, as this patch introduces two sections to the GHC User's Guide: * A "Formal syntax for GADTs" section that presents a BNF-style grammar for what is and isn't allowed in GADT constructor types. This mostly exists to codify GHC's existing behavior, but it also imposes a new restriction that addresses #18191: the outermost `forall` and/or context in a GADT constructor is not allowed to be surrounded by parentheses. Doing so would make these `forall`s/contexts nested, and GADTs do not support nested `forall`s/contexts at present. * A "`forall`-or-nothing rule" section that describes exactly what the `forall`-or-nothing rule is all about. Surprisingly, there was no mention of this anywhere in the User's Guide up until now! To adhere the new specification in the "Formal syntax for GADTs" section of the User's Guide, the following code changes were made: * `GHC.Parser.PostProcess.mkGadtDecl` no longer strips away parentheses from the outermost `forall` and context. Instead, these parentheses are preserved so that the renamer can check for nested `forall`s/contexts later. See `Note [No nested foralls or contexts in GADT constructors]` in `GHC.Parser.PostProcess` for more details. One nice side effect of this change is that we can get rid of the explicit `AddAnn` tracking in `mkGadtDecl`, as we no longer need to remember the `AddAnn`s for stripped-away parentheses. * `GHC.Renamer.Module.rnConDecl` now checks for nested `forall`s/contexts, rather than checking for this in the typechcker (in `GHC.Tc.TyCl.badDataConTyCon`). For the most part, this code was ported directly from `badDataConTyCon`, but designed to work over `HsType`s instead of `Type`s. One nice side effect of this change is that we are able to give a more accurate error message for GADT constructors that use visible dependent quantification (e.g., `MkFoo :: forall a -> a -> Foo a`), which improves the stderr in the `T16326_Fail6` test case. Fixes #18191. - - - - - 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/50bab0e80c232d0cbdbe213a158d2abf5470aad0...069f2a8d7f9aa7f8a46a71a33586c47c94289334 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/50bab0e80c232d0cbdbe213a158d2abf5470aad0...069f2a8d7f9aa7f8a46a71a33586c47c94289334 You're receiving 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 23 17:36:26 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 23 May 2020 13:36:26 -0400 Subject: [Git][ghc/ghc][master] docs: fix formatting and add some links Message-ID: <5ec95f1a5e02_6e263f9f0c42726010099ed@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: d830bbc9 by Adam Sandberg Ericsson at 2020-05-23T13:36:20-04:00 docs: fix formatting and add some links [skip ci] - - - - - 2 changed files: - docs/users_guide/8.12.1-notes.rst - docs/users_guide/exts/template_haskell.rst Changes: ===================================== docs/users_guide/8.12.1-notes.rst ===================================== @@ -79,12 +79,15 @@ Language * GHC now consistently does eager instantiation during type inference. As a consequence, visible type application (VTA) now only works when the head of the application is: + * A variable * An expression with a type signature - For example `(let x = blah in id) @Bool True` no longer typechecks. - You should write `let x = blah in id @Bool True` instead. - This change prepares the way for Quick Look impredicativity. + For example ``(let x = blah in id) @Bool True`` no longer typechecks. + You should write ``let x = blah in id @Bool True`` instead. + + This change prepares the way for `Quick Look impredicativity + `_. * GHC now allows users to manually define the specificity of type variable binders. By marking a variable with braces ``{tyvar}`` or ``{tyvar :: kind}``, @@ -110,31 +113,33 @@ Runtime system Template Haskell ~~~~~~~~~~~~~~~~ - - Implement the Overloaded Quotations proposal (#246). The type of all quotation - forms have now been generalised in terms of a minimal interface necessary for the - implementation rather than the overapproximation of the ``Q`` monad. +- Implement the `Overloaded Quotations proposal (#246) `_. + The type of all quotation forms have now been generalised in terms of a + minimal interface necessary (the ``Quote`` type class) for the + implementation rather than the overapproximation of the ``Q`` monad. - - Template Haskell quotes now handle fixity declarations in ``let`` and - ``where`` bindings properly. Previously, such fixity declarations would - be dropped when quoted due to a Template Haskell bug. +- Template Haskell quotes now handle fixity declarations in ``let`` and + ``where`` bindings properly. Previously, such fixity declarations would + be dropped when quoted due to a Template Haskell bug. - - The ``-XTemplateHaskellQuotes`` extension now allows nested splices as nested - splices do not lead directly to compile-time evaluation. (!2288) +- The ``-XTemplateHaskellQuotes`` extension now allows nested splices as nested + splices do not lead directly to compile-time evaluation. (Merge request + `!2288 `_) Arrow notation ~~~~~~~~~~~~~~ - - When combined with :extension:`Arrows`, the :extension:`LambdaCase` extension - now additionally allows ``\case`` syntax to be used as a command in ``proc`` - notation. +- When combined with :extension:`Arrows`, the :extension:`LambdaCase` extension + now additionally allows ``\case`` syntax to be used as a command in ``proc`` + notation. - - When combined with :extension:`Arrows`, the effects of the - :extension:`BlockArguments` extension now also apply to applications of - arrow control operators in ``(|`` banana brackets ``|)``: :: +- When combined with :extension:`Arrows`, the effects of the + :extension:`BlockArguments` extension now also apply to applications of + arrow control operators in ``(|`` banana brackets ``|)``: :: - (| untilA (increment -< x + y) do - within 0.5 -< x - ... |) + (| untilA (increment -< x + y) do + within 0.5 -< x + ... |) ``ghc-prim`` library ~~~~~~~~~~~~~~~~~~~~ @@ -142,28 +147,28 @@ Arrow notation ``ghc`` library ~~~~~~~~~~~~~~~ - - The type of the ``getAnnotations`` function has changed to better reflect - the fact that it returns two different kinds of annotations, those on - names and those on modules: :: +- The type of the ``getAnnotations`` function has changed to better reflect + the fact that it returns two different kinds of annotations, those on + names and those on modules: :: - getAnnotations :: Typeable a - => ([Word8] -> a) -> ModGuts - -> CoreM (ModuleEnv [a], NameEnv [a]) + getAnnotations :: Typeable a + => ([Word8] -> a) -> ModGuts + -> CoreM (ModuleEnv [a], NameEnv [a]) - - The meaning of the ``hs_fixds`` field of ``HsGroup`` has changed slightly. - It now only contains fixity signatures defined for top-level declarations - and class methods defined *outside* of the class itself. Previously, - ``hs_fixds`` would also contain fixity signatures for class methods defined - *inside* the class, such as the fixity signature for ``m`` in the following - example: :: +- The meaning of the ``hs_fixds`` field of ``HsGroup`` has changed slightly. + It now only contains fixity signatures defined for top-level declarations + and class methods defined *outside* of the class itself. Previously, + ``hs_fixds`` would also contain fixity signatures for class methods defined + *inside* the class, such as the fixity signature for ``m`` in the following + example: :: - class C a where - infixl 4 `m` - m :: a -> a -> a + class C a where + infixl 4 `m` + m :: a -> a -> a - If you wish to attain the previous behavior of ``hs_fixds``, use the new - ``hsGroupTopLevelFixitySigs`` function, which collects all top-level fixity - signatures, including those for class methods defined inside classes. + If you wish to attain the previous behavior of ``hs_fixds``, use the new + ``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`` @@ -196,7 +201,7 @@ for further change information. libraries/containers/containers/containers.cabal: Dependency of ``ghc`` library libraries/deepseq/deepseq.cabal: Dependency of ``ghc`` library libraries/directory/directory.cabal: Dependency of ``ghc`` library - libraries/exceptions/exceptions.cabal: Dependency of ``haskeline`` library + libraries/exceptions/exceptions.cabal: Dependency of ``ghc`` and ``haskeline`` library libraries/filepath/filepath.cabal: Dependency of ``ghc`` library compiler/ghc.cabal: The compiler itself libraries/ghci/ghci.cabal: The REPL interface ===================================== docs/users_guide/exts/template_haskell.rst ===================================== @@ -74,7 +74,7 @@ The :extension:`TemplateHaskellQuotes` extension is considered safe under that declaration splices are not allowed anywhere except at top level (outside any other declarations). - The ``Q`` monad is a monad defined in ``Language.Haskell.TH.Syntax`` which + The ``Q`` monad is a monad defined in :th-ref:`Language.Haskell.TH.Syntax.` which supports several useful operations during code generation such as reporting errors or looking up identifiers in the environment. @@ -92,9 +92,10 @@ The :extension:`TemplateHaskellQuotes` extension is considered safe under - ``[p| ... |]``, where the "..." is a pattern; the quotation has type ``Quote m => m Pat``. - The ``Quote`` type class is the minimal interface necessary to implement - the desugaring of quotations. The ``Q`` monad is an instance of ``Quote`` but - contains many more operations which are not needed for defining quotations. + The ``Quote`` type class (:th-ref:`Language.Haskell.TH.Syntax.Quote`) is + the minimal interface necessary to implement the desugaring of quotations. + The ``Q`` monad is an instance of ``Quote`` but contains many more + operations which are not needed for defining quotations. See :ref:`pts-where` for using partial type signatures in quotations. @@ -402,7 +403,7 @@ Using Template Haskell ---------------------- - The data types and monadic constructor functions for Template Haskell - are in the library ``Language.Haskell.TH.Syntax``. + are in the library :th-ref:`Language.Haskell.TH.Syntax.`. - You can only run a function at compile time if it is imported from another module. That is, you can't define a function in a module, and @@ -645,7 +646,7 @@ Here are the salient features (Only the first two are described in the paper.) - A quoter is a value of type - ``Language.Haskell.TH.Quote.QuasiQuoter``, which is defined thus: :: + :th-ref:`Language.Haskell.TH.Quote.QuasiQuoter`, which is defined thus: :: data QuasiQuoter = QuasiQuoter { quoteExp :: String -> Q Exp, quotePat :: String -> Q Pat, View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d830bbc9921bcc59164a0a18f0e0874ae4ce226e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d830bbc9921bcc59164a0a18f0e0874ae4ce226e You're receiving 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 23 17:37:14 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 23 May 2020 13:37:14 -0400 Subject: [Git][ghc/ghc][master] Implement cstringLength# and FinalPtr Message-ID: <5ec95f4a9417e_6e263f9f0ba0f84010193c5@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 49301ad6 by Andrew Martin at 2020-05-23T13:37:01-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. - - - - - 19 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Hs/Lit.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Types/Literal.hs - docs/users_guide/8.12.1-notes.rst - libraries/base/GHC/Exts.hs - libraries/base/GHC/ForeignPtr.hs - libraries/ghc-prim/GHC/CString.hs - libraries/ghc-prim/changelog.md - testsuite/.gitignore - testsuite/driver/testlib.py - + testsuite/tests/primops/should_gen_core/CStringLength_core.hs - + testsuite/tests/primops/should_gen_core/CStringLength_core.substr-simpl - + testsuite/tests/primops/should_gen_core/all.T - + testsuite/tests/primops/should_run/CStringLength.hs - + testsuite/tests/primops/should_run/CStringLength.stdout - testsuite/tests/primops/should_run/all.T Changes: ===================================== compiler/GHC/Builtin/Names.hs ===================================== @@ -349,6 +349,7 @@ basicKnownKeyNames -- Strings and lists unpackCStringName, unpackCStringFoldrName, unpackCStringUtf8Name, + cstringLengthName, -- Overloaded lists isListClassName, @@ -1014,10 +1015,11 @@ modIntName = varQual gHC_CLASSES (fsLit "modInt#") modIntIdKey -- Base strings Strings unpackCStringName, unpackCStringFoldrName, - unpackCStringUtf8Name, eqStringName :: Name + unpackCStringUtf8Name, eqStringName, cstringLengthName :: Name unpackCStringName = varQual gHC_CSTRING (fsLit "unpackCString#") unpackCStringIdKey unpackCStringFoldrName = varQual gHC_CSTRING (fsLit "unpackFoldrCString#") unpackCStringFoldrIdKey unpackCStringUtf8Name = varQual gHC_CSTRING (fsLit "unpackCStringUtf8#") unpackCStringUtf8IdKey +cstringLengthName = varQual gHC_CSTRING (fsLit "cstringLength#") cstringLengthIdKey eqStringName = varQual gHC_BASE (fsLit "eqString") eqStringIdKey -- The 'inline' function @@ -2097,7 +2099,7 @@ wildCardKey, absentErrorIdKey, augmentIdKey, appendIdKey, unpackCStringUtf8IdKey, unpackCStringAppendIdKey, unpackCStringFoldrIdKey, unpackCStringIdKey, typeErrorIdKey, divIntIdKey, modIntIdKey, - absentSumFieldErrorIdKey :: Unique + absentSumFieldErrorIdKey, cstringLengthIdKey :: Unique wildCardKey = mkPreludeMiscIdUnique 0 -- See Note [WildCard binders] absentErrorIdKey = mkPreludeMiscIdUnique 1 @@ -2124,6 +2126,7 @@ voidPrimIdKey = mkPreludeMiscIdUnique 21 typeErrorIdKey = mkPreludeMiscIdUnique 22 divIntIdKey = mkPreludeMiscIdUnique 23 modIntIdKey = mkPreludeMiscIdUnique 24 +cstringLengthIdKey = mkPreludeMiscIdUnique 25 concatIdKey, filterIdKey, zipIdKey, bindIOIdKey, returnIOIdKey, newStablePtrIdKey, ===================================== compiler/GHC/Core/Opt/ConstantFold.hs ===================================== @@ -66,6 +66,7 @@ import qualified Data.ByteString as BS import Data.Int import Data.Ratio import Data.Word +import Data.Maybe (fromMaybe) {- Note [Constant folding] @@ -1257,6 +1258,8 @@ builtinRules ru_nargs = 4, ru_try = match_append_lit }, BuiltinRule { ru_name = fsLit "EqString", ru_fn = eqStringName, ru_nargs = 2, ru_try = match_eq_string }, + BuiltinRule { ru_name = fsLit "CStringLength", ru_fn = cstringLengthName, + ru_nargs = 1, ru_try = match_cstring_length }, BuiltinRule { ru_name = fsLit "Inline", ru_fn = inlineIdName, ru_nargs = 2, ru_try = \_ _ _ -> match_inline }, BuiltinRule { ru_name = fsLit "MagicDict", ru_fn = idName magicDictId, @@ -1477,6 +1480,30 @@ match_eq_string _ id_unf _ match_eq_string _ _ _ _ = Nothing +----------------------------------------------------------------------- +-- Illustration of this rule: +-- +-- cstringLength# "foobar"# --> 6 +-- cstringLength# "fizz\NULzz"# --> 4 +-- +-- Nota bene: Addr# literals are suffixed by a NUL byte when they are +-- compiled to read-only data sections. That's why cstringLength# is +-- well defined on Addr# literals that do not explicitly have an embedded +-- NUL byte. +-- +-- See GHC issue #5218, MR 2165, and bytestring PR 191. This is particularly +-- helpful when using OverloadedStrings to create a ByteString since the +-- function computing the length of such ByteStrings can often be constant +-- folded. +match_cstring_length :: RuleFun +match_cstring_length env id_unf _ [lit1] + | Just (LitString str) <- exprIsLiteral_maybe id_unf lit1 + -- If elemIndex returns Just, it has the index of the first embedded NUL + -- in the string. If no NUL bytes are present (the common case) then use + -- full length of the byte string. + = let len = fromMaybe (BS.length str) (BS.elemIndex 0 str) + in Just (Lit (mkLitInt (roPlatform env) (fromIntegral len))) +match_cstring_length _ _ _ _ = Nothing --------------------------------------------------- -- The rule is this: ===================================== compiler/GHC/Data/FastString.hs ===================================== @@ -128,8 +128,9 @@ import Foreign import GHC.Conc.Sync (sharedCAF) #endif -import GHC.Base ( unpackCString#, unpackNBytes# ) - +#if __GLASGOW_HASKELL__ < 811 +import GHC.Base (unpackCString#,unpackNBytes#) +#endif -- | Gives the UTF-8 encoded bytes corresponding to a 'FastString' bytesFS :: FastString -> ByteString ===================================== compiler/GHC/Hs/Lit.hs ===================================== @@ -53,7 +53,7 @@ data HsLit x -- ^ Unboxed character | HsString (XHsString x) {- SourceText -} FastString -- ^ String - | HsStringPrim (XHsStringPrim x) {- SourceText -} ByteString + | HsStringPrim (XHsStringPrim x) {- SourceText -} !ByteString -- ^ Packed bytes | HsInt (XHsInt x) IntegralLit -- ^ Genuinely an Int; arises from ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -6,6 +6,7 @@ This module converts Template Haskell syntax into Hs syntax -} +{-# LANGUAGE BangPatterns #-} {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ScopedTypeVariables #-} @@ -1232,8 +1233,7 @@ cvtLit (CharPrimL c) = do { force c; return $ HsCharPrim NoSourceText c } cvtLit (StringL s) = do { let { s' = mkFastString s } ; force s' ; return $ HsString (quotedSourceText s) s' } -cvtLit (StringPrimL s) = do { let { s' = BS.pack s } - ; force s' +cvtLit (StringPrimL s) = do { let { !s' = BS.pack s } ; return $ HsStringPrim NoSourceText s' } cvtLit (BytesPrimL (Bytes fptr off sz)) = do let bs = unsafePerformIO $ withForeignPtr fptr $ \ptr -> ===================================== compiler/GHC/Types/Literal.hs ===================================== @@ -114,7 +114,7 @@ data Literal -- See Note [Types of LitNumbers] below for the -- Type field. - | LitString ByteString -- ^ A string-literal: stored and emitted + | LitString !ByteString -- ^ A string-literal: stored and emitted -- UTF-8 encoded, we'll arrange to decode it -- at runtime. Also emitted with a @\'\\0\'@ -- terminator. Create with 'mkLitString' ===================================== docs/users_guide/8.12.1-notes.rst ===================================== @@ -144,6 +144,9 @@ Arrow notation ``ghc-prim`` library ~~~~~~~~~~~~~~~~~~~~ +- Add a known-key ``cstringLength#`` to ``GHC.CString`` that is eligible + for constant folding by a built-in rule. + ``ghc`` library ~~~~~~~~~~~~~~~ @@ -181,6 +184,15 @@ Arrow notation ``base`` library ~~~~~~~~~~~~~~~~ +- ``ForeignPtrContents`` has a new nullary data constructor ``FinalPtr``. + ``FinalPtr`` is intended for turning a primitive string literal into a + ``ForeignPtr``. Unlike ``PlainForeignPtr``, ``FinalPtr`` does not have + a finalizer. Replacing ``PlainForeignPtr`` that has ``NoFinalizers`` with + ``FinalPtr`` reduces allocations, reduces the size of compiled binaries, + and unlocks important Core-to-Core optimizations. ``FinalPtr`` will be used + in an upcoming ``bytestring`` release to improve the performance of + ``ByteString`` literals created with ``OverloadedStrings``. + Build system ~~~~~~~~~~~~ ===================================== libraries/base/GHC/Exts.hs ===================================== @@ -54,6 +54,14 @@ module GHC.Exts -- * Overloaded string literals IsString(..), + -- * CString + unpackCString#, + unpackAppendCString#, + unpackFoldrCString#, + unpackCStringUtf8#, + unpackNBytes#, + cstringLength#, + -- * Debugging breakpoint, breakpointCond, ===================================== libraries/base/GHC/ForeignPtr.hs ===================================== @@ -23,11 +23,13 @@ module GHC.ForeignPtr ( + -- * Types ForeignPtr(..), ForeignPtrContents(..), Finalizers(..), FinalizerPtr, FinalizerEnvPtr, + -- * Create newForeignPtr_, mallocForeignPtr, mallocPlainForeignPtr, @@ -35,15 +37,20 @@ module GHC.ForeignPtr mallocPlainForeignPtrBytes, mallocForeignPtrAlignedBytes, mallocPlainForeignPtrAlignedBytes, + newConcForeignPtr, + -- * Add Finalizers addForeignPtrFinalizer, addForeignPtrFinalizerEnv, - touchForeignPtr, + addForeignPtrConcFinalizer, + -- * Conversion unsafeForeignPtrToPtr, castForeignPtr, plusForeignPtr, - newConcForeignPtr, - addForeignPtrConcFinalizer, + -- * Finalization + touchForeignPtr, finalizeForeignPtr + -- * Commentary + -- $commentary ) where import Foreign.Storable @@ -86,15 +93,121 @@ data ForeignPtr a = ForeignPtr Addr# ForeignPtrContents -- object, because that ensures that whatever the finalizer is -- attached to is kept alive. +-- | Functions called when a 'ForeignPtr' is finalized. Note that +-- C finalizers and Haskell finalizers cannot be mixed. data Finalizers = NoFinalizers + -- ^ No finalizer. If there is no intent to add a finalizer at + -- any point in the future, consider 'FinalPtr' or 'PlainPtr' instead + -- since these perform fewer allocations. | CFinalizers (Weak# ()) + -- ^ Finalizers are all C functions. | HaskellFinalizers [IO ()] + -- ^ Finalizers are all Haskell functions. +-- | Controls finalization of a 'ForeignPtr', that is, what should happen +-- if the 'ForeignPtr' becomes unreachable. Visually, these data constructors +-- are appropriate in these scenarios: +-- +-- > Memory backing pointer is +-- > GC-Managed Unmanaged +-- > Finalizer functions are: +------------+-----------------+ +-- > Allowed | MallocPtr | PlainForeignPtr | +-- > +------------+-----------------+ +-- > Prohibited | PlainPtr | FinalPtr | +-- > +------------+-----------------+ data ForeignPtrContents = PlainForeignPtr !(IORef Finalizers) - | MallocPtr (MutableByteArray# RealWorld) !(IORef Finalizers) - | PlainPtr (MutableByteArray# RealWorld) + -- ^ The pointer refers to unmanaged memory that was allocated by + -- a foreign function (typically using @malloc@). The finalizer + -- frequently calls the C function @free@ or some variant of it. + | FinalPtr + -- ^ The pointer refers to unmanaged memory that should not be freed when + -- the 'ForeignPtr' becomes unreachable. Functions that add finalizers + -- to a 'ForeignPtr' throw exceptions when the 'ForeignPtr' is backed by + -- 'PlainPtr'Most commonly, this is used with @Addr#@ literals. + -- See Note [Why FinalPtr]. + -- + -- @since 4.15 + | MallocPtr (MutableByteArray# RealWorld) !(IORef Finalizers) + -- ^ The pointer refers to a byte array. + -- The 'MutableByteArray#' field means that the 'MutableByteArray#' is + -- reachable (by GC) whenever the 'ForeignPtr' is reachable. When the + -- 'ForeignPtr' becomes unreachable, the runtime\'s normal GC recovers + -- the memory backing it. Here, the finalizer function intended to be used + -- to @free()@ any ancilliary *unmanaged* memory pointed to by the + -- 'MutableByteArray#'. See the @zlib@ library for an example of this use. + -- + -- 1. Invariant: The 'Addr#' in the parent 'ForeignPtr' is an interior + -- pointer into this 'MutableByteArray#'. + -- 2. Invariant: The 'MutableByteArray#' is pinned, so the 'Addr#' does not + -- get invalidated by the GC moving the byte array. + -- 3. Invariant: A 'MutableByteArray#' must not be associated with more than + -- one set of finalizers. For example, this is sound: + -- + -- > incrGood :: ForeignPtr Word8 -> ForeignPtr Word8 + -- > incrGood (ForeignPtr p (MallocPtr m f)) = ForeignPtr (plusPtr p 1) (MallocPtr m f) + -- + -- But this is unsound: + -- + -- > incrBad :: ForeignPtr Word8 -> IO (ForeignPtr Word8) + -- > incrBad (ForeignPtr p (MallocPtr m _)) = do + -- > f <- newIORef NoFinalizers + -- > pure (ForeignPtr p (MallocPtr m f)) + | PlainPtr (MutableByteArray# RealWorld) + -- ^ The pointer refers to a byte array. Finalization is not + -- supported. This optimizes @MallocPtr@ by avoiding the allocation + -- of a @MutVar#@ when it is known that no one will add finalizers to + -- the @ForeignPtr at . Functions that add finalizers to a 'ForeignPtr' + -- throw exceptions when the 'ForeignPtr' is backed by 'PlainPtr'. + -- The invariants that apply to 'MallocPtr' apply to 'PlainPtr' as well. + +-- Note [Why FinalPtr] +-- +-- FinalPtr exists as an optimization for foreign pointers created +-- from Addr# literals. Most commonly, this happens in the bytestring +-- library, where the combination of OverloadedStrings and a rewrite +-- rule overloads String literals as ByteString literals. See the +-- rule "ByteString packChars/packAddress" in +-- bytestring:Data.ByteString.Internal. Prior to the +-- introduction of FinalPtr, bytestring used PlainForeignPtr (in +-- Data.ByteString.Internal.unsafePackAddress) to handle such literals. +-- With O2 optimization, the resulting Core from a GHC patched with a +-- known-key cstringLength# function but without FinalPtr looked like: +-- +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +-- stringOne1 = "hello beautiful world"# +-- RHS size: {terms: 11, types: 17, coercions: 0, joins: 0/0} +-- stringOne +-- = case newMutVar# NoFinalizers realWorld# of +-- { (# ipv_i7b6, ipv1_i7b7 #) -> +-- PS stringOne1 (PlainForeignPtr ipv1_i7b7) 0# 21# +-- } +-- +-- After the introduction of FinalPtr, the bytestring library was modified +-- so that the resulting Core was instead: +-- +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +-- stringOne1 = "hello beautiful world"# +-- RHS size: {terms: 5, types: 0, coercions: 0, joins: 0/0} +-- stringOne = PS stringOne1 FinalPtr 0# 21# +-- +-- This improves performance in three ways: +-- +-- 1. More optimization opportunities. GHC is willing to inline the FinalPtr +-- variant of stringOne into its use sites. This means the offset and length +-- are eligible for case-of-known-literal. Previously, this never happened. +-- 2. Smaller binaries. Setting up the thunk to call newMutVar# required +-- machine instruction in the generated code. On x86_64, FinalPtr reduces +-- the size of binaries by about 450 bytes per ByteString literal. +-- 3. Smaller memory footprint. Previously, every ByteString literal resulted +-- in the allocation of a MutVar# and a PlainForeignPtr data constructor. +-- These both hang around until the ByteString goes out of scope. FinalPtr +-- eliminates both of these sources of allocations. The MutVar# is not +-- allocated because FinalPtr does not allow it, and the data constructor +-- is not allocated because FinalPtr is a nullary data constructor. +-- +-- For more discussion of FinalPtr, see GHC MR #2165 and bytestring PR #191. -- | @since 2.01 instance Eq (ForeignPtr a) where @@ -259,7 +372,7 @@ addForeignPtrFinalizer :: FinalizerPtr a -> ForeignPtr a -> IO () addForeignPtrFinalizer (FunPtr fp) (ForeignPtr p c) = case c of PlainForeignPtr r -> insertCFinalizer r fp 0# nullAddr# p () MallocPtr _ r -> insertCFinalizer r fp 0# nullAddr# p c - _ -> errorWithoutStackTrace "GHC.ForeignPtr: attempt to add a finalizer to a plain pointer" + _ -> errorWithoutStackTrace "GHC.ForeignPtr: attempt to add a finalizer to a plain pointer or a final pointer" -- Note [MallocPtr finalizers] (#10904) -- @@ -277,7 +390,7 @@ addForeignPtrFinalizerEnv :: addForeignPtrFinalizerEnv (FunPtr fp) (Ptr ep) (ForeignPtr p c) = case c of PlainForeignPtr r -> insertCFinalizer r fp 1# ep p () MallocPtr _ r -> insertCFinalizer r fp 1# ep p c - _ -> errorWithoutStackTrace "GHC.ForeignPtr: attempt to add a finalizer to a plain pointer" + _ -> errorWithoutStackTrace "GHC.ForeignPtr: attempt to add a finalizer to a plain pointer or a final pointer" addForeignPtrConcFinalizer :: ForeignPtr a -> IO () -> IO () -- ^This function adds a finalizer to the given @ForeignPtr at . The @@ -319,7 +432,7 @@ addForeignPtrConcFinalizer_ f@(MallocPtr fo r) finalizer = do finalizer' = unIO (foreignPtrFinalizer r >> touch f) addForeignPtrConcFinalizer_ _ _ = - errorWithoutStackTrace "GHC.ForeignPtr: attempt to add a finalizer to plain pointer" + errorWithoutStackTrace "GHC.ForeignPtr: attempt to add a finalizer to plain pointer or a final pointer" insertHaskellFinalizer :: IORef Finalizers -> IO () -> IO Bool insertHaskellFinalizer r f = do @@ -345,6 +458,8 @@ insertCFinalizer r fp flag ep p val = do -- replaced the content of r before calling finalizeWeak#. (# s1, _ #) -> unIO (insertCFinalizer r fp flag ep p val) s1 +-- Read the weak reference from an IORef Finalizers, creating it if necessary. +-- Throws an exception if HaskellFinalizers is encountered. ensureCFinalizerWeak :: IORef Finalizers -> value -> IO MyWeak ensureCFinalizerWeak ref@(IORef (STRef r#)) value = do fin <- readIORef ref @@ -370,6 +485,7 @@ noMixingError = errorWithoutStackTrace $ "GHC.ForeignPtr: attempt to mix Haskell and C finalizers " ++ "in the same ForeignPtr" +-- Swap out the finalizers with NoFinalizers and then run them. foreignPtrFinalizer :: IORef Finalizers -> IO () foreignPtrFinalizer r = do fs <- atomicSwapIORef r NoFinalizers @@ -455,13 +571,53 @@ plusForeignPtr :: ForeignPtr a -> Int -> ForeignPtr b plusForeignPtr (ForeignPtr addr c) (I# d) = ForeignPtr (plusAddr# addr d) c -- | Causes the finalizers associated with a foreign pointer to be run --- immediately. +-- immediately. The foreign pointer must not be used again after this +-- function is called. finalizeForeignPtr :: ForeignPtr a -> IO () -finalizeForeignPtr (ForeignPtr _ (PlainPtr _)) = return () -- no effect -finalizeForeignPtr (ForeignPtr _ foreignPtr) = foreignPtrFinalizer refFinalizers - where - refFinalizers = case foreignPtr of - (PlainForeignPtr ref) -> ref - (MallocPtr _ ref) -> ref - PlainPtr _ -> - errorWithoutStackTrace "finalizeForeignPtr PlainPtr" +finalizeForeignPtr (ForeignPtr _ c) = case c of + PlainForeignPtr ref -> foreignPtrFinalizer ref + MallocPtr _ ref -> foreignPtrFinalizer ref + _ -> errorWithoutStackTrace "finalizeForeignPtr PlainPtr" + +{- $commentary + +This is a high-level overview of how 'ForeignPtr' works. +The implementation of 'ForeignPtr' must accomplish several goals: + +1. Invoke a finalizer once a foreign pointer becomes unreachable. +2. Support augmentation of finalizers, i.e. 'addForeignPtrFinalizer'. + As a motivating example, suppose that the payload of a foreign + pointer is C struct @bar@ that has an optionally NULL pointer field + @foo@ to an unmanaged heap object. Initially, @foo@ is NULL, and + later the program uses @malloc@, initializes the object, and assigns + @foo@ the address returned by @malloc at . When the foreign pointer + becomes unreachable, it is now necessary to first @free@ the object + pointed to by @foo@ and then invoke whatever finalizer was associated + with @bar at . That is, finalizers must be invoked in the opposite order + they are added. +3. Allow users to invoke a finalizer promptly if they know that the + foreign pointer is unreachable, i.e. 'finalizeForeignPtr'. + +How can these goals be accomplished? Goal 1 suggests that weak references +and finalizers (via 'Weak#' and 'mkWeak#') are necessary. But how should +they be used and what should their key be? Certainly not 'ForeignPtr' or +'ForeignPtrContents'. See the warning in "GHC.Weak" about weak pointers with +lifted (non-primitive) keys. The two finalizer-supporting data constructors of +'ForeignPtr' have an @'IORef' 'Finalizers'@ (backed by 'MutVar#') field. +This gets used in two different ways depending on the kind of finalizer: + +* 'HaskellFinalizers': The first @addForeignPtrConcFinalizer_@ call uses + 'mkWeak#' to attach the finalizer @foreignPtrFinalizer@ to the 'MutVar#'. + The resulting 'Weak#' is discarded (see @addForeignPtrConcFinalizer_@). + Subsequent calls to @addForeignPtrConcFinalizer_@ (goal 2) just add + finalizers onto the list in the 'HaskellFinalizers' data constructor. +* 'CFinalizers': The first 'addForeignPtrFinalizer' call uses + 'mkWeakNoFinalizer#' to create a 'Weak#'. The 'Weak#' is preserved in the + 'CFinalizers' data constructor. Both the first call and subsequent + calls (goal 2) use 'addCFinalizerToWeak#' to attach finalizers to the + 'Weak#' itself. Also, see Note [MallocPtr finalizers] for discussion of + the key and value of this 'Weak#'. + +In either case, the runtime invokes the appropriate finalizers when the +'ForeignPtr' becomes unreachable. +-} ===================================== libraries/ghc-prim/GHC/CString.hs ===================================== @@ -1,5 +1,4 @@ -{-# LANGUAGE MagicHash, NoImplicitPrelude, BangPatterns #-} - +{-# LANGUAGE MagicHash, NoImplicitPrelude, BangPatterns, UnliftedFFITypes #-} ----------------------------------------------------------------------------- -- | -- Module : GHC.CString @@ -18,7 +17,7 @@ module GHC.CString ( unpackCString#, unpackAppendCString#, unpackFoldrCString#, - unpackCStringUtf8#, unpackNBytes# + unpackCStringUtf8#, unpackNBytes#, cstringLength# ) where import GHC.Types @@ -174,3 +173,17 @@ unpackNBytes# addr len# = unpack [] (len# -# 1#) case indexCharOffAddr# addr i# of ch -> unpack (C# ch : acc) (i# -# 1#) +-- The return type is not correct here. We really want CSize, +-- but that type is defined in base. However, CSize should always +-- match the size of a machine word (I hope), so this is probably +-- alright on all platforms that GHC supports. +foreign import ccall unsafe "strlen" c_strlen :: Addr# -> Int# + +-- | Compute the length of a NUL-terminated string. This address +-- must refer to immutable memory. GHC includes a built-in rule for +-- constant folding when the argument is a statically-known literal. +-- That is, a core-to-core pass reduces the expression +-- @cstringLength# "hello"#@ to the constant @5#@. +cstringLength# :: Addr# -> Int# +{-# INLINE[0] cstringLength# #-} +cstringLength# = c_strlen ===================================== libraries/ghc-prim/changelog.md ===================================== @@ -1,3 +1,11 @@ +## 0.6.2 (edit as necessary) + +- Shipped with GHC 8.12.1 + +- Add known-key `cstringLength#` to `GHC.CString`. This is just the + C function `strlen`, but a built-in rewrite rule allows GHC to + compute the result at compile time when the argument is known. + ## 0.6.1 (edit as necessary) - Shipped with GHC 8.10.1 ===================================== testsuite/.gitignore ===================================== @@ -43,6 +43,7 @@ Thumbs.db *.prof.sample.normalised *.run.stdout *.run.stderr +*.dump-simpl *.hp tests/**/*.ps ===================================== testsuite/driver/testlib.py ===================================== @@ -1344,6 +1344,26 @@ def compile_grep_asm(name: TestName, # no problems found, this test passed return passed() +def compile_grep_core(name: TestName, + way: WayName, + extra_hc_opts: str + ) -> PassFail: + print('Compile only, extra args = ', extra_hc_opts) + result = simple_build(name + '.hs', way, '-ddump-to-file -dsuppress-all -ddump-simpl -O ' + extra_hc_opts, False, None, False, False) + + if badResult(result): + return result + + expected_pat_file = find_expected_file(name, 'substr-simpl') + actual_core_file = add_suffix(name, 'dump-simpl') + + if not grep_output(join_normalisers(normalise_errmsg), + expected_pat_file, actual_core_file): + return failBecause('simplified core mismatch') + + # no problems found, this test passed + return passed() + # ----------------------------------------------------------------------------- # Compile-and-run tests ===================================== testsuite/tests/primops/should_gen_core/CStringLength_core.hs ===================================== @@ -0,0 +1,11 @@ +{-# language MagicHash #-} + +module CStringLengthCore + ( ozymandias + ) where + +import GHC.Exts + +ozymandias :: Int +ozymandias = + I# (cstringLength# "I met a traveller from an antique land"#) ===================================== testsuite/tests/primops/should_gen_core/CStringLength_core.substr-simpl ===================================== @@ -0,0 +1 @@ +I# 38# ===================================== testsuite/tests/primops/should_gen_core/all.T ===================================== @@ -0,0 +1 @@ +test('CStringLength_core', normal, compile_grep_core, ['']) ===================================== testsuite/tests/primops/should_run/CStringLength.hs ===================================== @@ -0,0 +1,33 @@ +{-# LANGUAGE BangPatterns #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE UnboxedTuples #-} + +import GHC.Exts + +main :: IO () +main = do + putStr "A: " + print $ + I# (cstringLength# "hello_world"#) + == + naiveStrlen "hello_world"# 0 + putStr "B: " + print $ + I# (cstringLength# "aaaaaaaaaaaaa\x00b"#) + == + naiveStrlen "aaaaaaaaaaaaa\x00b"# 0 + putStr "C: " + print $ + I# (cstringLength# "cccccccccccccccccc\x00b"#) + == + naiveStrlen "cccccccccccccccccc\x00b"# 0 + putStr "D: " + print $ + I# (cstringLength# "araña\NULb"#) + == + naiveStrlen "araña\NULb"# 0 + +naiveStrlen :: Addr# -> Int -> Int +naiveStrlen addr !n = case indexWord8OffAddr# addr 0# of + 0## -> n + _ -> naiveStrlen (plusAddr# addr 1#) (n + 1) ===================================== testsuite/tests/primops/should_run/CStringLength.stdout ===================================== @@ -0,0 +1,4 @@ +A: True +B: True +C: True +D: True ===================================== testsuite/tests/primops/should_run/all.T ===================================== @@ -29,3 +29,4 @@ test('CmpWord16', normal, compile_and_run, ['']) test('ShrinkSmallMutableArrayA', normal, compile_and_run, ['']) test('ShrinkSmallMutableArrayB', normal, compile_and_run, ['']) test('T14664', normal, compile_and_run, ['']) +test('CStringLength', normal, compile_and_run, ['-O2']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/49301ad6226d9a83d110bee8c419615dd94f5ded -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/49301ad6226d9a83d110bee8c419615dd94f5ded You're receiving 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 23 17:38:00 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 23 May 2020 13:38:00 -0400 Subject: [Git][ghc/ghc][master] simplCore: Ignore ticks in rule templates Message-ID: <5ec95f78ec9d9_6e263f9ee35223001025056@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: dcd6bdcc by Ben Gamari at 2020-05-23T13:37:48-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/dcd6bdcce57430d08b335014625722c487ea08e4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dcd6bdcce57430d08b335014625722c487ea08e4 You're receiving 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 23 17:38:43 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 23 May 2020 13:38:43 -0400 Subject: [Git][ghc/ghc][master] Fix #18145 and also avoid needless work with implicit vars Message-ID: <5ec95fa3efc51_6e26eb4a6c8102991f@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 82cb8913 by John Ericson at 2020-05-23T13:38:32-04:00 Fix #18145 and also avoid needless work with implicit vars - `forAllOrNothing` now is monadic, so we can trace whether we bind an explicit `forall` or not. - #18145 arose because the free vars calculation was needlessly complex. It is now greatly simplified. - Replaced some other implicit var code with `filterFreeVarsToBind`. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - 5 changed files: - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - + testsuite/tests/rename/should_fail/T18145.hs - + testsuite/tests/rename/should_fail/T18145.stderr - testsuite/tests/rename/should_fail/all.T Changes: ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -29,7 +29,7 @@ module GHC.Rename.HsType ( extractHsTysRdrTyVarsDups, extractRdrKindSigVars, extractDataDefnKindVars, extractHsTvBndrs, extractHsTyArgRdrKiTyVarsDup, - forAllOrNothing, nubL, elemRdr + forAllOrNothing, nubL ) where import GHC.Prelude @@ -65,7 +65,7 @@ import GHC.Data.FastString import GHC.Data.Maybe import qualified GHC.LanguageExtensions as LangExt -import Data.List ( nubBy, partition, (\\), find ) +import Data.List ( nubBy, partition, find ) import Control.Monad ( unless, when ) #include "HsVersions.h" @@ -164,13 +164,13 @@ rn_hs_sig_wc_type :: HsSigWcTypeScoping -> HsDocContext -> Maybe SDoc -> RnM (a, FreeVars) rn_hs_sig_wc_type scoping ctxt inf_err hs_ty thing_inside = do { check_inferred_vars ctxt inf_err hs_ty - ; free_vars <- extractFilteredRdrTyVarsDups hs_ty + ; free_vars <- filterInScopeM (extractHsTyRdrTyVarsDups hs_ty) ; (nwc_rdrs', tv_rdrs) <- partition_nwcs free_vars ; let nwc_rdrs = nubL nwc_rdrs' - implicit_bndrs = case scoping of - AlwaysBind -> tv_rdrs - BindUnlessForall -> forAllOrNothing (isLHsForAllTy hs_ty) tv_rdrs - NeverBind -> [] + ; implicit_bndrs <- case scoping of + AlwaysBind -> pure tv_rdrs + BindUnlessForall -> forAllOrNothing (isLHsForAllTy hs_ty) tv_rdrs + NeverBind -> pure [] ; rnImplicitBndrs implicit_bndrs $ \ vars -> do { (wcs, hs_ty', fvs1) <- rnWcBody ctxt nwc_rdrs hs_ty ; (res, fvs2) <- thing_inside wcs vars hs_ty' @@ -178,7 +178,7 @@ rn_hs_sig_wc_type scoping ctxt inf_err hs_ty thing_inside rnHsWcType :: HsDocContext -> LHsWcType GhcPs -> RnM (LHsWcType GhcRn, FreeVars) rnHsWcType ctxt (HsWC { hswc_body = hs_ty }) - = do { free_vars <- extractFilteredRdrTyVars hs_ty + = do { free_vars <- filterInScopeM (extractHsTyRdrTyVars hs_ty) ; (nwc_rdrs, _) <- partition_nwcs free_vars ; (wcs, hs_ty', fvs) <- rnWcBody ctxt nwc_rdrs hs_ty ; let sig_ty' = HsWC { hswc_ext = wcs, hswc_body = hs_ty' } @@ -278,22 +278,6 @@ extraConstraintWildCardsAllowed env StandaloneKindSigCtx {} -> False -- See Note [Wildcards in standalone kind signatures] in GHC/Hs/Decls _ -> False --- | Finds free type and kind variables in a type, --- without duplicates, and --- without variables that are already in scope in LocalRdrEnv --- NB: this includes named wildcards, which look like perfectly --- ordinary type variables at this point -extractFilteredRdrTyVars :: LHsType GhcPs -> RnM FreeKiTyVarsNoDups -extractFilteredRdrTyVars hs_ty = filterInScopeM (extractHsTyRdrTyVars hs_ty) - --- | Finds free type and kind variables in a type, --- with duplicates, but --- without variables that are already in scope in LocalRdrEnv --- NB: this includes named wildcards, which look like perfectly --- ordinary type variables at this point -extractFilteredRdrTyVarsDups :: LHsType GhcPs -> RnM FreeKiTyVarsWithDups -extractFilteredRdrTyVarsDups hs_ty = filterInScopeM (extractHsTyRdrTyVarsDups hs_ty) - -- | When the NamedWildCards extension is enabled, partition_nwcs -- removes type variables that start with an underscore from the -- FreeKiTyVars in the argument and returns them in a separate list. @@ -340,9 +324,12 @@ rnHsSigType :: HsDocContext -- that cannot have wildcards rnHsSigType ctx level inf_err (HsIB { hsib_body = hs_ty }) = do { traceRn "rnHsSigType" (ppr hs_ty) - ; vars <- extractFilteredRdrTyVarsDups hs_ty + ; rdr_env <- getLocalRdrEnv ; check_inferred_vars ctx inf_err hs_ty - ; rnImplicitBndrs (forAllOrNothing (isLHsForAllTy hs_ty) vars) $ \ vars -> + ; vars0 <- forAllOrNothing (isLHsForAllTy hs_ty) + $ filterInScope rdr_env + $ extractHsTyRdrTyVarsDups hs_ty + ; rnImplicitBndrs vars0 $ \ vars -> do { (body', fvs) <- rnLHsTyKi (mkTyKiEnv ctx level RnTypeBody) hs_ty ; return ( HsIB { hsib_ext = vars @@ -361,7 +348,7 @@ rnHsSigType ctx level inf_err (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 [forall-or-nothing rule]. This tiny little function is used +-- | 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 @@ -372,10 +359,14 @@ forAllOrNothing :: Bool -- we want to bring both 'a' and 'b' into scope, hence False -> FreeKiTyVarsWithDups -- ^ Free vars of the type - -> FreeKiTyVarsWithDups -forAllOrNothing True _ = [] -forAllOrNothing False fvs = fvs - + -> RnM FreeKiTyVarsWithDups +forAllOrNothing has_outer_forall fvs = case has_outer_forall of + True -> do + traceRn "forAllOrNothing" $ text "has explicit outer forall" + pure [] + False -> do + traceRn "forAllOrNothing" $ text "no explicit forall. implicit binders:" <+> ppr fvs + pure fvs rnImplicitBndrs :: FreeKiTyVarsWithDups -- ^ Surface-syntax free vars that we will implicitly bind. @@ -878,21 +869,20 @@ bindHsQTyVars doc mb_in_doc mb_assoc body_kv_occs hsq_bndrs thing_inside ; let -- See Note [bindHsQTyVars examples] for what -- all these various things are doing - bndrs, kv_occs, implicit_kvs :: [Located RdrName] + bndrs, implicit_kvs :: [Located RdrName] bndrs = map hsLTyVarLocName hs_tv_bndrs - kv_occs = nubL (bndr_kv_occs ++ body_kv_occs) - -- Make sure to list the binder kvs before the - -- body kvs, as mandated by - -- Note [Ordering of implicit variables] - implicit_kvs = filter_occs bndrs kv_occs + implicit_kvs = nubL $ filterFreeVarsToBind bndrs $ + bndr_kv_occs ++ body_kv_occs del = deleteBys eqLocated - all_bound_on_lhs = null ((body_kv_occs `del` bndrs) `del` bndr_kv_occs) + body_remaining = (body_kv_occs `del` bndrs) `del` bndr_kv_occs + all_bound_on_lhs = null body_remaining ; traceRn "checkMixedVars3" $ - vcat [ text "kv_occs" <+> ppr kv_occs - , text "bndrs" <+> ppr hs_tv_bndrs + vcat [ text "bndrs" <+> ppr hs_tv_bndrs , text "bndr_kv_occs" <+> ppr bndr_kv_occs - , text "wubble" <+> ppr ((kv_occs \\ bndrs) \\ bndr_kv_occs) + , text "body_kv_occs" <+> ppr body_kv_occs + , text "implicit_kvs" <+> ppr implicit_kvs + , text "body_remaining" <+> ppr body_remaining ] ; implicit_kv_nms <- mapM (newTyVarNameRn mb_assoc) implicit_kvs @@ -904,17 +894,6 @@ bindHsQTyVars doc mb_in_doc mb_assoc body_kv_occs hsq_bndrs thing_inside , hsq_explicit = rn_bndrs }) all_bound_on_lhs } } - where - filter_occs :: [Located RdrName] -- Bound here - -> [Located RdrName] -- Potential implicit binders - -> [Located RdrName] -- Final implicit binders - -- Filter out any potential implicit binders that are either - -- already in scope, or are explicitly bound in the same HsQTyVars - filter_occs bndrs occs - = filterOut is_in_scope occs - where - is_in_scope locc = locc `elemRdr` bndrs - {- Note [bindHsQTyVars examples] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Suppose we have @@ -943,7 +922,7 @@ Then: * Order is not important in these lists. All we are doing is bring Names into scope. -Finally, you may wonder why filter_occs removes in-scope variables +Finally, you may wonder why filterFreeVarsToBind removes in-scope variables from bndr/body_kv_occs. How can anything be in scope? Answer: HsQTyVars is /also/ used (slightly oddly) for Haskell-98 syntax ConDecls @@ -1654,9 +1633,15 @@ type FreeKiTyVarsWithDups = FreeKiTyVars -- | A 'FreeKiTyVars' list that contains no duplicate variables. type FreeKiTyVarsNoDups = FreeKiTyVars +-- | Filter out any type and kind variables that are already in scope in the +-- the supplied LocalRdrEnv. Note that this includes named wildcards, which +-- look like perfectly ordinary type variables at this point. filterInScope :: LocalRdrEnv -> FreeKiTyVars -> FreeKiTyVars filterInScope rdr_env = filterOut (inScope rdr_env . unLoc) +-- | Filter out any type and kind variables that are already in scope in the +-- the environment's LocalRdrEnv. Note that this includes named wildcards, +-- which look like perfectly ordinary type variables at this point. filterInScopeM :: FreeKiTyVars -> RnM FreeKiTyVars filterInScopeM vars = do { rdr_env <- getLocalRdrEnv @@ -1812,12 +1797,13 @@ extract_hs_tv_bndrs :: [LHsTyVarBndr flag GhcPs] -- 'a' is bound by the forall -- 'b' is a free type variable -- 'e' is a free kind variable -extract_hs_tv_bndrs tv_bndrs acc_vars body_vars - | null tv_bndrs = body_vars ++ acc_vars - | otherwise = filterOut (`elemRdr` tv_bndr_rdrs) (bndr_vars ++ body_vars) ++ acc_vars +extract_hs_tv_bndrs tv_bndrs acc_vars body_vars = new_vars ++ acc_vars + where + new_vars + | null tv_bndrs = body_vars + | otherwise = filterFreeVarsToBind tv_bndr_rdrs $ bndr_vars ++ body_vars -- NB: delete all tv_bndr_rdrs from bndr_vars as well as body_vars. -- See Note [Kind variable scoping] - where bndr_vars = extract_hs_tv_bndrs_kvs tv_bndrs tv_bndr_rdrs = map hsLTyVarLocName tv_bndrs @@ -1848,5 +1834,16 @@ extract_tv tv acc = nubL :: Eq a => [Located a] -> [Located a] nubL = nubBy eqLocated -elemRdr :: Located RdrName -> [Located RdrName] -> Bool -elemRdr x = any (eqLocated x) +-- | Filter out any potential implicit binders that are either +-- already in scope, or are explicitly bound in the binder. +filterFreeVarsToBind :: FreeKiTyVars + -- ^ Explicitly bound here + -> FreeKiTyVarsWithDups + -- ^ Potential implicit binders + -> FreeKiTyVarsWithDups + -- ^ Final implicit binders +filterFreeVarsToBind bndrs = filterOut is_in_scope + -- Make sure to list the binder kvs before the body kvs, as mandated by + -- Note [Ordering of implicit variables] + where + is_in_scope locc = any (eqLocated locc) bndrs ===================================== compiler/GHC/Rename/Module.hs ===================================== @@ -59,7 +59,7 @@ import GHC.Types.Basic ( pprRuleName, TypeOrKind(..) ) import GHC.Data.FastString import GHC.Types.SrcLoc as SrcLoc import GHC.Driver.Session -import GHC.Utils.Misc ( debugIsOn, filterOut, lengthExceeds, partitionWith ) +import GHC.Utils.Misc ( debugIsOn, lengthExceeds, partitionWith ) import GHC.Driver.Types ( HscEnv, hsc_dflags ) import GHC.Data.List.SetOps ( findDupsEq, removeDups, equivClasses ) import GHC.Data.Graph.Directed ( SCC, flattenSCC, flattenSCCs, Node(..) @@ -664,7 +664,9 @@ rnClsInstDecl (ClsInstDecl { cid_poly_ty = inst_ty, cid_binds = mbinds rnFamInstEqn :: HsDocContext -> AssocTyFamInfo - -> [Located RdrName] -- Kind variables from the equation's RHS + -> [Located RdrName] + -- ^ Kind variables from the equation's RHS to be implicitly bound + -- if no explicit forall. -> FamInstEqn GhcPs rhs -> (HsDocContext -> rhs -> RnM (rhs', FreeVars)) -> RnM (FamInstEqn GhcRn rhs', FreeVars) @@ -683,20 +685,36 @@ rnFamInstEqn doc atfi rhs_kvars -- Use the "...Dups" form because it's needed -- below to report unused binder on the LHS - -- Implicitly bound variables, empty if we have an explicit 'forall'. - -- See Note [forall-or-nothing rule] in GHC.Rename.HsType. - ; let imp_vars = nubL $ forAllOrNothing (isJust mb_bndrs) pat_kity_vars_with_dups - ; imp_var_names <- mapM (newTyVarNameRn mb_cls) imp_vars - ; let bndrs = fromMaybe [] mb_bndrs - bnd_vars = map hsLTyVarLocName bndrs - payload_kvars = filterOut (`elemRdr` (bnd_vars ++ imp_vars)) rhs_kvars - -- Make sure to filter out the kind variables that were explicitly - -- bound in the type patterns. - ; payload_kvar_names <- mapM (newTyVarNameRn mb_cls) payload_kvars - -- all names not bound in an explicit forall - ; let all_imp_var_names = imp_var_names ++ payload_kvar_names + -- all_imp_vars represent the implicitly bound type variables. This is + -- empty if we have an explicit `forall` (see + -- Note [forall-or-nothing rule] in GHC.Rename.HsType), which means + -- ignoring: + -- + -- - pat_kity_vars_with_dups, the variables mentioned in the LHS of + -- the equation, and + -- - rhs_kvars, the kind variables mentioned in an outermost kind + -- signature on the RHS of the equation. (See + -- Note [Implicit quantification in type synonyms] in + -- GHC.Rename.HsType for why these are implicitly quantified in the + -- absence of an explicit forall). + -- + -- For example: + -- + -- @ + -- type family F a b + -- type instance forall a b c. F [(a, b)] c = a -> b -> c + -- -- all_imp_vars = [] + -- type instance F [(a, b)] c = a -> b -> c + -- -- all_imp_vars = [a, b, c] + -- @ + ; all_imp_vars <- forAllOrNothing (isJust mb_bndrs) $ + -- No need to filter out explicit binders (the 'mb_bndrs = Just + -- explicit_bndrs' case) because there must be none if we're going + -- to implicitly bind anything, per the previous comment. + nubL $ pat_kity_vars_with_dups ++ rhs_kvars + ; all_imp_var_names <- mapM (newTyVarNameRn mb_cls) all_imp_vars -- All the free vars of the family patterns -- with a sensible binding location @@ -2096,14 +2114,14 @@ rnConDecl decl@(ConDeclGADT { con_names = names -- That order governs the order the implicitly-quantified type -- variable, and hence the order needed for visible type application -- See #14808. - free_tkvs = extractHsTvBndrs explicit_tkvs $ - extractHsTysRdrTyVarsDups (theta ++ arg_tys ++ [res_ty]) + ; implicit_bndrs <- forAllOrNothing explicit_forall + $ extractHsTvBndrs explicit_tkvs + $ extractHsTysRdrTyVarsDups (theta ++ arg_tys ++ [res_ty]) - ctxt = ConDeclCtx new_names + ; let ctxt = ConDeclCtx new_names mb_ctxt = Just (inHsDocContext ctxt) - ; traceRn "rnConDecl" (ppr names $$ ppr free_tkvs $$ ppr explicit_forall ) - ; rnImplicitBndrs (forAllOrNothing explicit_forall free_tkvs) $ \ implicit_tkvs -> + ; rnImplicitBndrs implicit_bndrs $ \ implicit_tkvs -> bindLHsTyVarBndrs ctxt mb_ctxt Nothing explicit_tkvs $ \ explicit_tkvs -> do { (new_cxt, fvs1) <- rnMbContext ctxt mcxt ; (new_args, fvs2) <- rnConDeclDetails (unLoc (head new_names)) ctxt args ===================================== testsuite/tests/rename/should_fail/T18145.hs ===================================== @@ -0,0 +1,17 @@ +{-# LANGUAGE ExplicitForAll #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE DataKinds #-} + +module T18145 where + +type family A :: k +type instance forall. A = Nothing :: Maybe a -- 'a' should be out of scope + +class Foo x where + type B x :: Maybe a + type forall x. B x = Nothing :: Maybe a -- 'a' should be out of scope + +instance Foo [x] where + type forall. B [x] = Nothing :: Maybe a -- 'a' should be out of scope ===================================== testsuite/tests/rename/should_fail/T18145.stderr ===================================== @@ -0,0 +1,6 @@ + +T18145.hs:10:44: error: Not in scope: type variable ‘a’ + +T18145.hs:14:41: error: Not in scope: type variable ‘a’ + +T18145.hs:17:41: error: Not in scope: type variable ‘a’ ===================================== testsuite/tests/rename/should_fail/all.T ===================================== @@ -153,3 +153,4 @@ test('T16504', normal, compile_fail, ['']) test('T14548', normal, compile_fail, ['']) test('T16610', normal, compile_fail, ['']) test('T17593', normal, compile_fail, ['']) +test('T18145', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/82cb8913b38d44ef20e928ff8b08f3f0770ebf80 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/82cb8913b38d44ef20e928ff8b08f3f0770ebf80 You're receiving 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 23 17:39:23 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 23 May 2020 13:39:23 -0400 Subject: [Git][ghc/ghc][master] Bump process submodule Message-ID: <5ec95fcb5ef74_6e263f9ed7716be01033428@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: a60dc835 by Ben Gamari at 2020-05-23T13:39:12-04:00 Bump process submodule Fixes #17926. - - - - - 1 changed file: - libraries/process Changes: ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit 8fffea5ca319e85e1bc9e7cac39e5a2c8effefcc +Subproject commit 1afc36ecd38c069251a836e1c1c8b3a3043ddc01 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a60dc83552c38af9bbc159bd4e092531196db9c0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a60dc83552c38af9bbc159bd4e092531196db9c0 You're receiving 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 23 17:40:37 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 23 May 2020 13:40:37 -0400 Subject: [Git][ghc/ghc][master] users-guide: Clarify meaning of -haddock flag Message-ID: <5ec960157731_6e26eb364ac1040785@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 856adf54 by Ben Gamari at 2020-05-23T13:40:21-04:00 users-guide: Clarify meaning of -haddock flag Fixes #18206. - - - - - 1 changed file: - docs/users_guide/using.rst Changes: ===================================== docs/users_guide/using.rst ===================================== @@ -1136,10 +1136,11 @@ Haddock single: haddock .. ghc-flag:: -haddock - :shortdesc: Make the parser more strict about Haddock comments. + :shortdesc: With this flag GHC will parse Haddock comments and include them + in the interface file it produces. :type: dynamic :reverse: -no-haddock - :category: misc + :category: haddock By default, GHC ignores Haddock comments (``-- | ...`` and ``-- ^ ...``) and does not check that they're associated with a valid term, such as a View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/856adf54ab50fc3be66d17a0b94ba3074453b279 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/856adf54ab50fc3be66d17a0b94ba3074453b279 You're receiving 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 23 17:41:14 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 23 May 2020 13:41:14 -0400 Subject: [Git][ghc/ghc][master] git: Add ignored commits file Message-ID: <5ec9603a84135_6e263f9ee2984160104152f@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 7ae57afd by Ben Gamari at 2020-05-23T13:41:03-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/7ae57afd7abee9dec1050d9feace254ac04800bc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7ae57afd7abee9dec1050d9feace254ac04800bc You're receiving 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 23 17:54:24 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Sat, 23 May 2020 13:54:24 -0400 Subject: [Git][ghc/ghc][wip/T18191] 8 commits: docs: fix formatting and add some links Message-ID: <5ec9635089258_6e26eb364ac10437de@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T18191 at Glasgow Haskell Compiler / GHC Commits: d830bbc9 by Adam Sandberg Ericsson at 2020-05-23T13:36:20-04:00 docs: fix formatting and add some links [skip ci] - - - - - 49301ad6 by Andrew Martin at 2020-05-23T13:37:01-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. - - - - - dcd6bdcc by Ben Gamari at 2020-05-23T13:37:48-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. - - - - - 82cb8913 by John Ericson at 2020-05-23T13:38:32-04:00 Fix #18145 and also avoid needless work with implicit vars - `forAllOrNothing` now is monadic, so we can trace whether we bind an explicit `forall` or not. - #18145 arose because the free vars calculation was needlessly complex. It is now greatly simplified. - Replaced some other implicit var code with `filterFreeVarsToBind`. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - a60dc835 by Ben Gamari at 2020-05-23T13:39:12-04:00 Bump process submodule Fixes #17926. - - - - - 856adf54 by Ben Gamari at 2020-05-23T13:40:21-04:00 users-guide: Clarify meaning of -haddock flag Fixes #18206. - - - - - 7ae57afd by Ben Gamari at 2020-05-23T13:41:03-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 - - - - - 0d541790 by Ryan Scott at 2020-05-23T13:53:52-04:00 Make GADT constructors adhere to the forall-or-nothing rule properly Issue #18191 revealed that the types of GADT constructors don't quite adhere to the `forall`-or-nothing rule. This patch serves to clean up this sad state of affairs somewhat. The main change is not in the code itself, but in the documentation, as this patch introduces two sections to the GHC User's Guide: * A "Formal syntax for GADTs" section that presents a BNF-style grammar for what is and isn't allowed in GADT constructor types. This mostly exists to codify GHC's existing behavior, but it also imposes a new restriction that addresses #18191: the outermost `forall` and/or context in a GADT constructor is not allowed to be surrounded by parentheses. Doing so would make these `forall`s/contexts nested, and GADTs do not support nested `forall`s/contexts at present. * A "`forall`-or-nothing rule" section that describes exactly what the `forall`-or-nothing rule is all about. Surprisingly, there was no mention of this anywhere in the User's Guide up until now! To adhere the new specification in the "Formal syntax for GADTs" section of the User's Guide, the following code changes were made: * `GHC.Parser.PostProcess.mkGadtDecl` no longer strips away parentheses from the outermost `forall` and context. Instead, these parentheses are preserved so that the renamer can check for nested `forall`s/contexts later. See `Note [No nested foralls or contexts in GADT constructors]` in `GHC.Parser.PostProcess` for more details. One nice side effect of this change is that we can get rid of the explicit `AddAnn` tracking in `mkGadtDecl`, as we no longer need to remember the `AddAnn`s for stripped-away parentheses. * `GHC.Renamer.Module.rnConDecl` now checks for nested `forall`s/contexts, rather than checking for this in the typechcker (in `GHC.Tc.TyCl.badDataConTyCon`). For the most part, this code was ported directly from `badDataConTyCon`, but designed to work over `HsType`s instead of `Type`s. One nice side effect of this change is that we are able to give a more accurate error message for GADT constructors that use visible dependent quantification (e.g., `MkFoo :: forall a -> a -> Foo a`), which improves the stderr in the `T16326_Fail6` test case. Fixes #18191. - - - - - 30 changed files: - + .git-ignore-revs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Hs/Lit.hs - compiler/GHC/Hs/Types.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Types/Literal.hs - docs/users_guide/8.12.1-notes.rst - docs/users_guide/exts/explicit_forall.rst - docs/users_guide/exts/gadt_syntax.rst - docs/users_guide/exts/template_haskell.rst - docs/users_guide/using.rst - libraries/base/GHC/Exts.hs - libraries/base/GHC/ForeignPtr.hs - libraries/ghc-prim/GHC/CString.hs - libraries/ghc-prim/changelog.md - libraries/process - testsuite/.gitignore - testsuite/driver/testlib.py - testsuite/tests/dependent/should_fail/T16326_Fail6.stderr - testsuite/tests/gadt/T12087.stderr - testsuite/tests/gadt/T14320.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/069f2a8d7f9aa7f8a46a71a33586c47c94289334...0d54179051725461fa5a74cb80ed1e0880fb74b1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/069f2a8d7f9aa7f8a46a71a33586c47c94289334...0d54179051725461fa5a74cb80ed1e0880fb74b1 You're receiving 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 23 18:14:24 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 23 May 2020 14:14:24 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 17 commits: docs: fix formatting and add some links Message-ID: <5ec968003807e_6e26eb4a6c8104656@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: d830bbc9 by Adam Sandberg Ericsson at 2020-05-23T13:36:20-04:00 docs: fix formatting and add some links [skip ci] - - - - - 49301ad6 by Andrew Martin at 2020-05-23T13:37:01-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. - - - - - dcd6bdcc by Ben Gamari at 2020-05-23T13:37:48-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. - - - - - 82cb8913 by John Ericson at 2020-05-23T13:38:32-04:00 Fix #18145 and also avoid needless work with implicit vars - `forAllOrNothing` now is monadic, so we can trace whether we bind an explicit `forall` or not. - #18145 arose because the free vars calculation was needlessly complex. It is now greatly simplified. - Replaced some other implicit var code with `filterFreeVarsToBind`. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - a60dc835 by Ben Gamari at 2020-05-23T13:39:12-04:00 Bump process submodule Fixes #17926. - - - - - 856adf54 by Ben Gamari at 2020-05-23T13:40:21-04:00 users-guide: Clarify meaning of -haddock flag Fixes #18206. - - - - - 7ae57afd by Ben Gamari at 2020-05-23T13:41:03-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 - - - - - 360a700f by jneira at 2020-05-23T14:14:08-04:00 Add hie-bios script for windows systems It is a direct translation of the sh script - - - - - 91f83eee by jneira at 2020-05-23T14:14:08-04:00 Honour previous values for CABAL and CABFLAGS The immediate goal is let the hie-bios.bat script set CABFLAGS with `-v0` and remove all cabal output except the compiler arguments - - - - - fc7eadb3 by jneira at 2020-05-23T14:14:08-04:00 Add specific configuration for windows in hie.yaml - - - - - 590aff0c by jneira at 2020-05-23T14:14:08-04:00 Remove not needed hie-bios output - - - - - 4bdd30d5 by Sylvain Henry at 2020-05-23T14:14:18-04:00 Move Config module into GHC.Settings - - - - - b63d5865 by Sylvain Henry at 2020-05-23T14:14:18-04:00 Rename GHC.Core.Arity into GHC.Core.Opt.Arity - - - - - 1282657c by Sylvain Henry at 2020-05-23T14:14:18-04:00 Rename GHC.Hs.Types into GHC.Hs.Type See discussion in https://gitlab.haskell.org/ghc/ghc/issues/13009#note_268610 - - - - - 02600229 by Sylvain Henry at 2020-05-23T14:14:18-04:00 Bump haddock submodule - - - - - d8e136a8 by Ryan Scott at 2020-05-23T14:14:18-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. - - - - - 15b33ad3 by Matthew Pickering at 2020-05-23T14:14:19-04:00 Remove unused hs-boot file - - - - - 30 changed files: - + .git-ignore-revs - compiler/GHC/Builtin/Names.hs - − compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Types.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Arity.hs → compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatOut.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/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Expr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f5f3e7091dc281a48fd7c29862052d3f8475a793...15b33ad3d7bc150f0952ab7f2c592ca6fe37c0ee -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f5f3e7091dc281a48fd7c29862052d3f8475a793...15b33ad3d7bc150f0952ab7f2c592ca6fe37c0ee You're receiving 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 23 18:16:29 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Sat, 23 May 2020 14:16:29 -0400 Subject: [Git][ghc/ghc][wip/ww-max-worker-args-old-arity] 39 commits: Remove duplicate Note [When to print foralls] in GHC.Core.TyCo.Ppr Message-ID: <5ec9687de54da_6e26eb364ac1053843@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/ww-max-worker-args-old-arity 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] - - - - - 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 - - - - - 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 - - - - - 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. - - - - - 78c6523c by Ben Gamari at 2020-05-21T12:13:01-04:00 nonmoving: Optimise the write barrier - - - - - 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). - - - - - 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 - - - - - b7a6b2f4 by Gleb Popov at 2020-05-21T12:15:26-04:00 gitlab-ci: Set locale to C.UTF-8. - - - - - 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. - - - - - 0004ccb8 by Tuan Le at 2020-05-21T12:16:46-04:00 llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 - - - - - 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 - - - - - 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 - - - - - 2b363ebb by Richard Eisenberg at 2020-05-21T12:18:45-04:00 MR template should ask for key part - - - - - a95bbd0b by Sebastian Graf at 2020-05-21T12:19:37-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. - - - - - d3d055b8 by Galen Huntington at 2020-05-21T12:20:18-04:00 Clarify pitfalls of NegativeLiterals; see #18022. - - - - - 1b508a9e by Alexey Kuleshevich at 2020-05-21T12:21:02-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" - - - - - 4ca0c8a1 by Andreas Klebinger at 2020-05-21T12:21: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. - - - - - a1275081 by Krzysztof Gogolewski at 2020-05-21T12:22:35-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 - - - - - 8a816e5f by Krzysztof Gogolewski at 2020-05-21T12:23:55-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. - - - - - 566cc73f by Sylvain Henry at 2020-05-21T12:24:45-04:00 Move isDynLinkName into GHC.Types.Name It doesn't belong into GHC.Unit.State - - - - - d830bbc9 by Adam Sandberg Ericsson at 2020-05-23T13:36:20-04:00 docs: fix formatting and add some links [skip ci] - - - - - 49301ad6 by Andrew Martin at 2020-05-23T13:37:01-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. - - - - - dcd6bdcc by Ben Gamari at 2020-05-23T13:37:48-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. - - - - - 82cb8913 by John Ericson at 2020-05-23T13:38:32-04:00 Fix #18145 and also avoid needless work with implicit vars - `forAllOrNothing` now is monadic, so we can trace whether we bind an explicit `forall` or not. - #18145 arose because the free vars calculation was needlessly complex. It is now greatly simplified. - Replaced some other implicit var code with `filterFreeVarsToBind`. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - a60dc835 by Ben Gamari at 2020-05-23T13:39:12-04:00 Bump process submodule Fixes #17926. - - - - - 856adf54 by Ben Gamari at 2020-05-23T13:40:21-04:00 users-guide: Clarify meaning of -haddock flag Fixes #18206. - - - - - 7ae57afd by Ben Gamari at 2020-05-23T13:41:03-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 - - - - - 75a13c38 by Sebastian Graf at 2020-05-23T20:16:00+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: - + .git-ignore-revs - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/merge_request_templates/merge-request.md - compiler/GHC/Builtin/Names.hs - 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/ConstantFold.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/563bc167dc89032f99cd78fb5d6167f51ddccb5b...75a13c387da6a7249146c7160c8e6c4b324c2878 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/563bc167dc89032f99cd78fb5d6167f51ddccb5b...75a13c387da6a7249146c7160c8e6c4b324c2878 You're receiving 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 23 21:19:22 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 23 May 2020 17:19:22 -0400 Subject: [Git][ghc/ghc][wip/bump-base] base: Bump to 4.15.0.0 Message-ID: <5ec9935a23627_6e263f9f0ba0f8401069381@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/bump-base at Glasgow Haskell Compiler / GHC Commits: ee7dc121 by Ben Gamari at 2020-05-23T17:19:12-04:00 base: Bump to 4.15.0.0 - - - - - 13 changed files: - libraries/array - libraries/base/base.cabal - libraries/directory - libraries/filepath - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghc-compact/ghc-compact.cabal - libraries/ghci/ghci.cabal.in - libraries/haskeline - libraries/parsec - libraries/process - libraries/stm - libraries/template-haskell/template-haskell.cabal.in - libraries/unix Changes: ===================================== libraries/array ===================================== @@ -1 +1 @@ -Subproject commit f73f681e52546b1e35cb9e8a62fe49c33f259d98 +Subproject commit ab535173d7885ebfc2005d8da2765f0f52c923ce ===================================== 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 ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit 36bd1921258b759724a95ce56c5e880edf0972a2 +Subproject commit 0dcb228388a6e306c11f419c7c5575eaa6af40b3 ===================================== libraries/filepath ===================================== @@ -1 +1 @@ -Subproject commit 023eedaeb142d47b7b5a41fe4cc4150da0bd0042 +Subproject commit 7cb3dc285cd595a7b6cf0b74a58b6583fb67772e ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -55,7 +55,7 @@ Library -- GHC.Version -- GHC.Platform.Host - build-depends: base >= 4.7 && < 4.15, + build-depends: base >= 4.7 && < 4.16, binary == 0.8.*, bytestring == 0.10.*, containers >= 0.5 && < 0.7, ===================================== libraries/ghc-compact/ghc-compact.cabal ===================================== @@ -37,7 +37,7 @@ library CPP build-depends: ghc-prim >= 0.5.3 && < 0.7, - base >= 4.9.0 && < 4.15, + base >= 4.9.0 && < 4.16, bytestring >= 0.10.6.0 ghc-options: -Wall ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -72,7 +72,7 @@ library Build-Depends: array == 0.5.*, - base >= 4.8 && < 4.15, + base >= 4.8 && < 4.16, binary == 0.8.*, bytestring == 0.10.*, containers >= 0.5 && < 0.7, ===================================== libraries/haskeline ===================================== @@ -1 +1 @@ -Subproject commit 3d3e7c18a44fa904f004e5eac0e666e396f1b3f4 +Subproject commit 2373dbbb45898b5eac01ec32ded322baa4f9d535 ===================================== libraries/parsec ===================================== @@ -1 +1 @@ -Subproject commit ce416997e15438ca616667995660e123ef7e219d +Subproject commit 190492494fe92e8dd42165190b7ac112be1f7389 ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit 8fffea5ca319e85e1bc9e7cac39e5a2c8effefcc +Subproject commit a35b835ff0f11bdfca31fe9b072d808d828292c9 ===================================== libraries/stm ===================================== @@ -1 +1 @@ -Subproject commit faf9904137044e35a589c7c1579e1bfa03789c84 +Subproject commit 444f672416a354c3cfde9d94ec237a36be46ef59 ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -55,7 +55,7 @@ Library Language.Haskell.TH.Lib.Map build-depends: - base >= 4.11 && < 4.15, + base >= 4.11 && < 4.16, ghc-boot-th == @ProjectVersionMunged@, ghc-prim, pretty == 1.1.* ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 1a993b89c570e03ba74f196f5d065a0ebe624010 +Subproject commit ea13d990580273a883368793dfbb826cab5a22d4 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ee7dc121a778e237dae8317fb935d538a62f5fef -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ee7dc121a778e237dae8317fb935d538a62f5fef You're receiving 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 23 21:20:18 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 23 May 2020 17:20:18 -0400 Subject: [Git][ghc/ghc][wip/bump-base] base: Bump to 4.15.0.0 Message-ID: <5ec99392def98_6e2611c732a4106982b@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/bump-base at Glasgow Haskell Compiler / GHC Commits: cf3aaac2 by Ben Gamari at 2020-05-23T17:19:46-04:00 base: Bump to 4.15.0.0 - - - - - 12 changed files: - libraries/array - libraries/base/base.cabal - libraries/directory - libraries/filepath - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghc-compact/ghc-compact.cabal - libraries/ghci/ghci.cabal.in - libraries/parsec - libraries/process - libraries/stm - libraries/template-haskell/template-haskell.cabal.in - libraries/unix Changes: ===================================== libraries/array ===================================== @@ -1 +1 @@ -Subproject commit f73f681e52546b1e35cb9e8a62fe49c33f259d98 +Subproject commit ab535173d7885ebfc2005d8da2765f0f52c923ce ===================================== 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 ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit 36bd1921258b759724a95ce56c5e880edf0972a2 +Subproject commit 0dcb228388a6e306c11f419c7c5575eaa6af40b3 ===================================== libraries/filepath ===================================== @@ -1 +1 @@ -Subproject commit 023eedaeb142d47b7b5a41fe4cc4150da0bd0042 +Subproject commit 7cb3dc285cd595a7b6cf0b74a58b6583fb67772e ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -55,7 +55,7 @@ Library -- GHC.Version -- GHC.Platform.Host - build-depends: base >= 4.7 && < 4.15, + build-depends: base >= 4.7 && < 4.16, binary == 0.8.*, bytestring == 0.10.*, containers >= 0.5 && < 0.7, ===================================== libraries/ghc-compact/ghc-compact.cabal ===================================== @@ -37,7 +37,7 @@ library CPP build-depends: ghc-prim >= 0.5.3 && < 0.7, - base >= 4.9.0 && < 4.15, + base >= 4.9.0 && < 4.16, bytestring >= 0.10.6.0 ghc-options: -Wall ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -72,7 +72,7 @@ library Build-Depends: array == 0.5.*, - base >= 4.8 && < 4.15, + base >= 4.8 && < 4.16, binary == 0.8.*, bytestring == 0.10.*, containers >= 0.5 && < 0.7, ===================================== libraries/parsec ===================================== @@ -1 +1 @@ -Subproject commit ce416997e15438ca616667995660e123ef7e219d +Subproject commit 190492494fe92e8dd42165190b7ac112be1f7389 ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit 8fffea5ca319e85e1bc9e7cac39e5a2c8effefcc +Subproject commit a35b835ff0f11bdfca31fe9b072d808d828292c9 ===================================== libraries/stm ===================================== @@ -1 +1 @@ -Subproject commit faf9904137044e35a589c7c1579e1bfa03789c84 +Subproject commit 444f672416a354c3cfde9d94ec237a36be46ef59 ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -55,7 +55,7 @@ Library Language.Haskell.TH.Lib.Map build-depends: - base >= 4.11 && < 4.15, + base >= 4.11 && < 4.16, ghc-boot-th == @ProjectVersionMunged@, ghc-prim, pretty == 1.1.* ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 1a993b89c570e03ba74f196f5d065a0ebe624010 +Subproject commit ea13d990580273a883368793dfbb826cab5a22d4 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cf3aaac27e69b9bff996bc7653955755afb5bb2e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cf3aaac27e69b9bff996bc7653955755afb5bb2e You're receiving 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 24 04:17:19 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 24 May 2020 00:17:19 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/ticky-datacon-name Message-ID: <5ec9f54f5682e_6e263f9ee35223001100973@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/ticky-datacon-name at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/ticky-datacon-name You're receiving 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 24 04:23:35 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 24 May 2020 00:23:35 -0400 Subject: [Git][ghc/ghc][wip/ticky-datacon-name] Ticky-ticky: Record DataCon name in ticker name Message-ID: <5ec9f6c7e7ca3_6e26119d2f90110256d@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/ticky-datacon-name at Glasgow Haskell Compiler / GHC Commits: c2cbb6dd by Ben Gamari at 2020-05-24T00:23:29-04:00 Ticky-ticky: Record DataCon name in ticker name - - - - - 2 changed files: - compiler/GHC/StgToCmm/Bind.hs - compiler/GHC/StgToCmm/Ticky.hs Changes: ===================================== compiler/GHC/StgToCmm/Bind.hs ===================================== @@ -201,7 +201,7 @@ cgRhs :: Id ) cgRhs id (StgRhsCon cc con args) - = withNewTickyCounterCon (idName id) $ + = withNewTickyCounterCon (idName id) con $ buildDynCon id True cc con (assertNonVoidStgArgs args) -- con args are always non-void, -- see Note [Post-unarisation invariants] in GHC.Stg.Unarise ===================================== compiler/GHC/StgToCmm/Ticky.hs ===================================== @@ -128,6 +128,7 @@ import GHC.Driver.Session -- Turgid imports for showTypeCategory import GHC.Builtin.Names import GHC.Tc.Utils.TcType +import GHC.Core.DataCon import GHC.Core.TyCon import GHC.Core.Predicate @@ -145,6 +146,7 @@ data TickyClosureType = TickyFun Bool -- True <-> single entry | TickyCon + DataCon -- the allocated constructor | TickyThunk Bool -- True <-> updateable Bool -- True <-> standard thunk (AP or selector), has no entry counter @@ -188,13 +190,14 @@ withNewTickyCounterStdThunk isUpdatable name code = do withNewTickyCounterCon :: Name + -> DataCon -> FCode a -> FCode a -withNewTickyCounterCon name code = do +withNewTickyCounterCon name datacon code = do has_ctr <- thunkHasCounter False if not has_ctr then code - else withNewTickyCounter TickyCon name [] code + else withNewTickyCounter (TickyCon datacon) name [] code -- args does not include the void arguments withNewTickyCounter :: TickyClosureType -> Name -> [NonVoid Id] -> FCode a -> FCode a @@ -222,7 +225,7 @@ emitTickyCounter cloType name args ext = case cloType of TickyFun single_entry -> parens $ hcat $ punctuate comma $ [text "fun"] ++ [text "se"|single_entry] - TickyCon -> parens (text "con") + TickyCon datacon -> parens (text "con:" <+> ppr (dataConName datacon)) TickyThunk upd std -> parens $ hcat $ punctuate comma $ [text "thk"] ++ [text "se"|not upd] ++ [text "std"|std] TickyLNE | isInternalName name -> parens (text "LNE") View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c2cbb6ddc5f6082ad6779883aa9c21fbcb0e9a6c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c2cbb6ddc5f6082ad6779883aa9c21fbcb0e9a6c You're receiving 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 24 05:29:13 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 24 May 2020 01:29:13 -0400 Subject: [Git][ghc/ghc][wip/bump-base] base: Bump to 4.15.0.0 Message-ID: <5eca0629ac979_6e263f9f0ba0f840110522a@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/bump-base at Glasgow Haskell Compiler / GHC Commits: 26c284c9 by Ben Gamari at 2020-05-24T01:29:05-04:00 base: Bump to 4.15.0.0 - - - - - 13 changed files: - libraries/array - libraries/base/base.cabal - libraries/directory - libraries/filepath - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghc-compact/ghc-compact.cabal - libraries/ghci/ghci.cabal.in - libraries/parsec - libraries/process - libraries/stm - libraries/template-haskell/template-haskell.cabal.in - libraries/terminfo - libraries/unix Changes: ===================================== libraries/array ===================================== @@ -1 +1 @@ -Subproject commit f73f681e52546b1e35cb9e8a62fe49c33f259d98 +Subproject commit ab535173d7885ebfc2005d8da2765f0f52c923ce ===================================== 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 ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit 36bd1921258b759724a95ce56c5e880edf0972a2 +Subproject commit 0dcb228388a6e306c11f419c7c5575eaa6af40b3 ===================================== libraries/filepath ===================================== @@ -1 +1 @@ -Subproject commit 023eedaeb142d47b7b5a41fe4cc4150da0bd0042 +Subproject commit 7cb3dc285cd595a7b6cf0b74a58b6583fb67772e ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -55,7 +55,7 @@ Library -- GHC.Version -- GHC.Platform.Host - build-depends: base >= 4.7 && < 4.15, + build-depends: base >= 4.7 && < 4.16, binary == 0.8.*, bytestring == 0.10.*, containers >= 0.5 && < 0.7, ===================================== libraries/ghc-compact/ghc-compact.cabal ===================================== @@ -37,7 +37,7 @@ library CPP build-depends: ghc-prim >= 0.5.3 && < 0.7, - base >= 4.9.0 && < 4.15, + base >= 4.9.0 && < 4.16, bytestring >= 0.10.6.0 ghc-options: -Wall ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -72,7 +72,7 @@ library Build-Depends: array == 0.5.*, - base >= 4.8 && < 4.15, + base >= 4.8 && < 4.16, binary == 0.8.*, bytestring == 0.10.*, containers >= 0.5 && < 0.7, ===================================== libraries/parsec ===================================== @@ -1 +1 @@ -Subproject commit ce416997e15438ca616667995660e123ef7e219d +Subproject commit 190492494fe92e8dd42165190b7ac112be1f7389 ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit 8fffea5ca319e85e1bc9e7cac39e5a2c8effefcc +Subproject commit a35b835ff0f11bdfca31fe9b072d808d828292c9 ===================================== libraries/stm ===================================== @@ -1 +1 @@ -Subproject commit faf9904137044e35a589c7c1579e1bfa03789c84 +Subproject commit 444f672416a354c3cfde9d94ec237a36be46ef59 ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -55,7 +55,7 @@ Library Language.Haskell.TH.Lib.Map build-depends: - base >= 4.11 && < 4.15, + base >= 4.11 && < 4.16, ghc-boot-th == @ProjectVersionMunged@, ghc-prim, pretty == 1.1.* ===================================== libraries/terminfo ===================================== @@ -1 +1 @@ -Subproject commit 27e694688d2d6eee69959a8b6a128c584c84aa72 +Subproject commit 3ebb36f4a2c42b74ec4e35efccc2be34c198a830 ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 1a993b89c570e03ba74f196f5d065a0ebe624010 +Subproject commit ea13d990580273a883368793dfbb826cab5a22d4 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/26c284c9b40e5edcdb7385cfa6b2985b493b17d3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/26c284c9b40e5edcdb7385cfa6b2985b493b17d3 You're receiving 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 24 05:54:53 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 24 May 2020 01:54:53 -0400 Subject: [Git][ghc/ghc][master] 4 commits: Add hie-bios script for windows systems Message-ID: <5eca0c2db3166_6e2687ddb08110852b@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 63d30e60 by jneira at 2020-05-24T01:54:42-04:00 Add hie-bios script for windows systems It is a direct translation of the sh script - - - - - 59182b88 by jneira at 2020-05-24T01:54:42-04:00 Honour previous values for CABAL and CABFLAGS The immediate goal is let the hie-bios.bat script set CABFLAGS with `-v0` and remove all cabal output except the compiler arguments - - - - - 932dc54e by jneira at 2020-05-24T01:54:42-04:00 Add specific configuration for windows in hie.yaml - - - - - e0eda070 by jneira at 2020-05-24T01:54:42-04:00 Remove not needed hie-bios output - - - - - 3 changed files: - hadrian/build-cabal.bat - + hadrian/hie-bios.bat - hie.yaml Changes: ===================================== hadrian/build-cabal.bat ===================================== @@ -1,6 +1,12 @@ @echo off -set CABAL=cabal -set CABFLAGS=--disable-documentation --disable-profiling --disable-library-profiling + +if "%CABAL%"=="" ( + set CABAL=cabal +) + +if "%CABFLAGS%"=="" ( + set CABFLAGS=--disable-documentation --disable-profiling --disable-library-profiling +) rem It is currently more robust to pass Cabal an absolute path to the project file. set PROJ="%CD%/hadrian/cabal.project" ===================================== hadrian/hie-bios.bat ===================================== @@ -0,0 +1,3 @@ +set TERM=dumb +set CABFLAGS=-v0 +%CD%\hadrian\build-cabal.bat tool:%1 -q --build-root=_hie-bios --flavour=ghc-in-ghci > %HIE_BIOS_OUTPUT% ===================================== hie.yaml ===================================== @@ -1,5 +1,8 @@ # This is a IDE configuration file which tells IDEs such as `ghcide` how # to set up a GHC API session for this project. # +# To use it in windows systems replace the config with +# cradle: {bios: {program: "./hadrian/hie-bios.bat"}} +# # The format is documented here - https://github.com/mpickering/hie-bios cradle: {bios: {program: "./hadrian/hie-bios"}} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7ae57afd7abee9dec1050d9feace254ac04800bc...e0eda0707d6cc3d5a85cfb13543df61623e82070 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/7ae57afd7abee9dec1050d9feace254ac04800bc...e0eda0707d6cc3d5a85cfb13543df61623e82070 You're receiving 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 24 05:55:35 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 24 May 2020 01:55:35 -0400 Subject: [Git][ghc/ghc][master] 4 commits: Move Config module into GHC.Settings Message-ID: <5eca0c573c3c8_6e263f9ee35223001112026@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: a0ea59d6 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Move Config module into GHC.Settings - - - - - 37430251 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Core.Arity into GHC.Core.Opt.Arity - - - - - a426abb9 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Hs.Types into GHC.Hs.Type See discussion in https://gitlab.haskell.org/ghc/ghc/issues/13009#note_268610 - - - - - 1c91a7a0 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Bump haddock submodule - - - - - 30 changed files: - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Arity.hs → compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatOut.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/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Types.hs → compiler/GHC/Hs/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Quote.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e0eda0707d6cc3d5a85cfb13543df61623e82070...1c91a7a095331d8c776f6ecd74803026e0104502 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e0eda0707d6cc3d5a85cfb13543df61623e82070...1c91a7a095331d8c776f6ecd74803026e0104502 You're receiving 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 24 05:56:16 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 24 May 2020 01:56:16 -0400 Subject: [Git][ghc/ghc][master] Add orderingTyCon to wiredInTyCons (#18185) Message-ID: <5eca0c8019cfc_6e263f9f0ba0f84011163bb@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 66bd24d1 by Ryan Scott at 2020-05-24T01:56:03-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 ===================================== @@ -429,10 +429,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 ===================================== @@ -708,5 +708,6 @@ test('T18036', normal, compile, ['']) test('T18036a', normal, compile, ['']) test('T17873', normal, compile, ['']) test('T18129', expect_broken(18129), compile, ['']) +test('T18185', normal, compile, ['']) test('ExplicitSpecificityA1', normal, compile, ['']) test('ExplicitSpecificityA2', normal, compile, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/66bd24d197251b9907cbffba3d5d8a3f5e3c2e80 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/66bd24d197251b9907cbffba3d5d8a3f5e3c2e80 You're receiving 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 24 05:56:52 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 24 May 2020 01:56:52 -0400 Subject: [Git][ghc/ghc][master] Remove unused hs-boot file Message-ID: <5eca0ca44e30_6e263f9ee3c181641116856@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 01c43634 by Matthew Pickering at 2020-05-24T01:56:42-04:00 Remove unused hs-boot file - - - - - 2 changed files: - − compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Driver/Session.hs Changes: ===================================== compiler/GHC/Builtin/Names.hs-boot deleted ===================================== @@ -1,7 +0,0 @@ -module GHC.Builtin.Names where - -import GHC.Unit.Module -import GHC.Types.Unique - -mAIN :: Module -liftedTypeKindTyConKey :: Unique ===================================== compiler/GHC/Driver/Session.hs ===================================== @@ -246,7 +246,7 @@ import GHC.Unit.Parser import GHC.Unit.Module import {-# SOURCE #-} GHC.Driver.Plugins import {-# SOURCE #-} GHC.Driver.Hooks -import {-# SOURCE #-} GHC.Builtin.Names ( mAIN ) +import GHC.Builtin.Names ( mAIN ) import {-# SOURCE #-} GHC.Unit.State (PackageState, emptyPackageState, PackageDatabase, mkIndefUnitId, updateIndefUnitId) import GHC.Driver.Phases ( Phase(..), phaseInputExt ) import GHC.Driver.Flags View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/01c43634d443bd3cc0b95b43a7180e12230b845d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/01c43634d443bd3cc0b95b43a7180e12230b845d You're receiving 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 24 12:32:06 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 24 May 2020 08:32:06 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 14 commits: Add hie-bios script for windows systems Message-ID: <5eca69466ea97_6e26119d2f9011503a6@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 63d30e60 by jneira at 2020-05-24T01:54:42-04:00 Add hie-bios script for windows systems It is a direct translation of the sh script - - - - - 59182b88 by jneira at 2020-05-24T01:54:42-04:00 Honour previous values for CABAL and CABFLAGS The immediate goal is let the hie-bios.bat script set CABFLAGS with `-v0` and remove all cabal output except the compiler arguments - - - - - 932dc54e by jneira at 2020-05-24T01:54:42-04:00 Add specific configuration for windows in hie.yaml - - - - - e0eda070 by jneira at 2020-05-24T01:54:42-04:00 Remove not needed hie-bios output - - - - - a0ea59d6 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Move Config module into GHC.Settings - - - - - 37430251 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Core.Arity into GHC.Core.Opt.Arity - - - - - a426abb9 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Hs.Types into GHC.Hs.Type See discussion in https://gitlab.haskell.org/ghc/ghc/issues/13009#note_268610 - - - - - 1c91a7a0 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Bump haddock submodule - - - - - 66bd24d1 by Ryan Scott at 2020-05-24T01:56:03-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. - - - - - 01c43634 by Matthew Pickering at 2020-05-24T01:56:42-04:00 Remove unused hs-boot file - - - - - 0b8a93b3 by Sylvain Henry at 2020-05-24T08:32:00-04:00 Hadrian: fix cross-compiler build (#16051) - - - - - 8e240472 by Sylvain Henry at 2020-05-24T08:32:00-04:00 Hadrian: fix distDir per stage - - - - - 649659a8 by Sylvain Henry at 2020-05-24T08:32:00-04:00 Hadrian: fix hp2ps error during cross-compilation Fixed by @alp (see https://gitlab.haskell.org/ghc/ghc/issues/16051#note_274265) - - - - - d13138cd by Joshua Price at 2020-05-24T08:32:02-04:00 Make Unicode brackets opening/closing tokens (#18225) The tokens `[|`, `|]`, `(|`, and `|)` are opening/closing tokens as described in GHC Proposal #229. This commit makes the unicode variants (`⟦`, `⟧`, `⦇`, and `⦈`) act the same as their ASCII counterparts. - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - − compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Types.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Arity.hs → compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatOut.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/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Types.hs → compiler/GHC/Hs/Type.hs - compiler/GHC/Hs/Utils.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/15b33ad3d7bc150f0952ab7f2c592ca6fe37c0ee...d13138cdd1020f8476ea38e260d0773f406883d5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/15b33ad3d7bc150f0952ab7f2c592ca6fe37c0ee...d13138cdd1020f8476ea38e260d0773f406883d5 You're receiving 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 24 15:10:14 2020 From: gitlab at gitlab.haskell.org (Alan Zimmerman) Date: Sun, 24 May 2020 11:10:14 -0400 Subject: [Git][ghc/ghc][wip/az/exactprint] 130 commits: nonmoving: Clear bitmap after initializing block size Message-ID: <5eca8e56e61f1_6e263f9ee3c1816411734cd@gitlab.haskell.org.mail> Alan Zimmerman pushed to branch wip/az/exactprint 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. - - - - - 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. - - - - - 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] - - - - - 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 - - - - - 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 - - - - - 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. - - - - - 78c6523c by Ben Gamari at 2020-05-21T12:13:01-04:00 nonmoving: Optimise the write barrier - - - - - 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). - - - - - 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 - - - - - b7a6b2f4 by Gleb Popov at 2020-05-21T12:15:26-04:00 gitlab-ci: Set locale to C.UTF-8. - - - - - 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. - - - - - 0004ccb8 by Tuan Le at 2020-05-21T12:16:46-04:00 llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 - - - - - 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 - - - - - 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 - - - - - 2b363ebb by Richard Eisenberg at 2020-05-21T12:18:45-04:00 MR template should ask for key part - - - - - a95bbd0b by Sebastian Graf at 2020-05-21T12:19:37-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. - - - - - d3d055b8 by Galen Huntington at 2020-05-21T12:20:18-04:00 Clarify pitfalls of NegativeLiterals; see #18022. - - - - - 1b508a9e by Alexey Kuleshevich at 2020-05-21T12:21:02-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" - - - - - 4ca0c8a1 by Andreas Klebinger at 2020-05-21T12:21: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. - - - - - a1275081 by Krzysztof Gogolewski at 2020-05-21T12:22:35-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 - - - - - 8a816e5f by Krzysztof Gogolewski at 2020-05-21T12:23:55-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. - - - - - 566cc73f by Sylvain Henry at 2020-05-21T12:24:45-04:00 Move isDynLinkName into GHC.Types.Name It doesn't belong into GHC.Unit.State - - - - - d830bbc9 by Adam Sandberg Ericsson at 2020-05-23T13:36:20-04:00 docs: fix formatting and add some links [skip ci] - - - - - 49301ad6 by Andrew Martin at 2020-05-23T13:37:01-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. - - - - - dcd6bdcc by Ben Gamari at 2020-05-23T13:37:48-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. - - - - - 82cb8913 by John Ericson at 2020-05-23T13:38:32-04:00 Fix #18145 and also avoid needless work with implicit vars - `forAllOrNothing` now is monadic, so we can trace whether we bind an explicit `forall` or not. - #18145 arose because the free vars calculation was needlessly complex. It is now greatly simplified. - Replaced some other implicit var code with `filterFreeVarsToBind`. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - a60dc835 by Ben Gamari at 2020-05-23T13:39:12-04:00 Bump process submodule Fixes #17926. - - - - - 856adf54 by Ben Gamari at 2020-05-23T13:40:21-04:00 users-guide: Clarify meaning of -haddock flag Fixes #18206. - - - - - 7ae57afd by Ben Gamari at 2020-05-23T13:41:03-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 - - - - - 63d30e60 by jneira at 2020-05-24T01:54:42-04:00 Add hie-bios script for windows systems It is a direct translation of the sh script - - - - - 59182b88 by jneira at 2020-05-24T01:54:42-04:00 Honour previous values for CABAL and CABFLAGS The immediate goal is let the hie-bios.bat script set CABFLAGS with `-v0` and remove all cabal output except the compiler arguments - - - - - 932dc54e by jneira at 2020-05-24T01:54:42-04:00 Add specific configuration for windows in hie.yaml - - - - - e0eda070 by jneira at 2020-05-24T01:54:42-04:00 Remove not needed hie-bios output - - - - - a0ea59d6 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Move Config module into GHC.Settings - - - - - 37430251 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Core.Arity into GHC.Core.Opt.Arity - - - - - a426abb9 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Hs.Types into GHC.Hs.Type See discussion in https://gitlab.haskell.org/ghc/ghc/issues/13009#note_268610 - - - - - 1c91a7a0 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Bump haddock submodule - - - - - 66bd24d1 by Ryan Scott at 2020-05-24T01:56:03-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. - - - - - 01c43634 by Matthew Pickering at 2020-05-24T01:56:42-04:00 Remove unused hs-boot file - - - - - 095800f7 by Alan Zimmerman at 2020-05-24T14:12:36+01:00 Proof of Concept implementation of in-tree API Annotations This MR introduces a possible machinery to introduce API Annotations into the TTG extension points. It is intended to be a concrete example for discussion. It still needs to process comments. ---- Work in progress, adding more TTG extensions for annotations. And fixing ppr round-trip tests by being able to blank out in-tree annotations, as done with SrcSpans. This is needed for the case of class Foo a where for which current ppr does not print the "where". Rename AA to AddApiAnn and AA to AddAnn Add XConPatIn and XConPatOut Rebase ---- First pass at bringing in LocatedA for API anns in locations Treatment of ECP in parsing is provisional at this stage, leads to some horribly stuff in Parser.y and RdrHsSyn. It is an extensive but not invasive change. I think (AZ). Locally it reports some parsing tests using less memory. Add ApiAnns to the HsExpr data structure. rebase. Change HsMatchContext and HsStmtContext to use an id, not a GhcPass parameter. Add ApiAnns to Hs/Types Rebase Rebased 2020-03-25 WIP on in-tree annotations Includes updating HsModule Imports LocateA ImportDecl so we can hang AnnSemi off it A whole bunch of stuff more InjectivityAnn and FamEqn now have annotations in them Add annotations to context srcspan ---- In-tree annotations: LHsDecl and LHsBind LocatedA ---- WIP on in-tree annotations ---- in-tree annotations: LHsType is now LocatedA ---- FunDeps is now also a HS data type ---- WIP. Added LocatedA to Pat, Expr, Decl And worked some more through Parser.y ---- LStmt now Located ---- Finished working through Parser.y, tests seem ok failures relate to annotations. Adding test infrastructure for check-exact Like check-ppr, but checking for an exact reproduction of the parsed source file. Starting to work on actual exact printer - - - - - 30 changed files: - + .git-ignore-revs - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/merge_request_templates/merge-request.md - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - − compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/PPC/Cond.hs - compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/18f174bf73f046df5201f389c273fc4e0e5a7ec8...095800f7d9237d48dbcdaa90b92e8d07789b3d57 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/18f174bf73f046df5201f389c273fc4e0e5a7ec8...095800f7d9237d48dbcdaa90b92e8d07789b3d57 You're receiving 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 24 16:09:01 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 24 May 2020 12:09:01 -0400 Subject: [Git][ghc/ghc][wip/bump-base] base: Bump to 4.15.0.0 Message-ID: <5eca9c1d78f5b_6e263f9ed7716be011821d0@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/bump-base at Glasgow Haskell Compiler / GHC Commits: abc9efff by Ben Gamari at 2020-05-24T12:08:50-04:00 base: Bump to 4.15.0.0 - - - - - 13 changed files: - libraries/array - libraries/base/base.cabal - libraries/directory - libraries/filepath - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghc-compact/ghc-compact.cabal - libraries/ghci/ghci.cabal.in - libraries/parsec - libraries/process - libraries/stm - libraries/template-haskell/template-haskell.cabal.in - libraries/terminfo - libraries/unix Changes: ===================================== libraries/array ===================================== @@ -1 +1 @@ -Subproject commit f73f681e52546b1e35cb9e8a62fe49c33f259d98 +Subproject commit ab535173d7885ebfc2005d8da2765f0f52c923ce ===================================== 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 ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit 36bd1921258b759724a95ce56c5e880edf0972a2 +Subproject commit 0dcb228388a6e306c11f419c7c5575eaa6af40b3 ===================================== libraries/filepath ===================================== @@ -1 +1 @@ -Subproject commit 023eedaeb142d47b7b5a41fe4cc4150da0bd0042 +Subproject commit 7cb3dc285cd595a7b6cf0b74a58b6583fb67772e ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -55,7 +55,7 @@ Library -- GHC.Version -- GHC.Platform.Host - build-depends: base >= 4.7 && < 4.15, + build-depends: base >= 4.7 && < 4.16, binary == 0.8.*, bytestring == 0.10.*, containers >= 0.5 && < 0.7, ===================================== libraries/ghc-compact/ghc-compact.cabal ===================================== @@ -37,7 +37,7 @@ library CPP build-depends: ghc-prim >= 0.5.3 && < 0.7, - base >= 4.9.0 && < 4.15, + base >= 4.9.0 && < 4.16, bytestring >= 0.10.6.0 ghc-options: -Wall ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -72,7 +72,7 @@ library Build-Depends: array == 0.5.*, - base >= 4.8 && < 4.15, + base >= 4.8 && < 4.16, binary == 0.8.*, bytestring == 0.10.*, containers >= 0.5 && < 0.7, ===================================== libraries/parsec ===================================== @@ -1 +1 @@ -Subproject commit ce416997e15438ca616667995660e123ef7e219d +Subproject commit 190492494fe92e8dd42165190b7ac112be1f7389 ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit 8fffea5ca319e85e1bc9e7cac39e5a2c8effefcc +Subproject commit a35b835ff0f11bdfca31fe9b072d808d828292c9 ===================================== libraries/stm ===================================== @@ -1 +1 @@ -Subproject commit faf9904137044e35a589c7c1579e1bfa03789c84 +Subproject commit 444f672416a354c3cfde9d94ec237a36be46ef59 ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -55,7 +55,7 @@ Library Language.Haskell.TH.Lib.Map build-depends: - base >= 4.11 && < 4.15, + base >= 4.11 && < 4.16, ghc-boot-th == @ProjectVersionMunged@, ghc-prim, pretty == 1.1.* ===================================== libraries/terminfo ===================================== @@ -1 +1 @@ -Subproject commit 27e694688d2d6eee69959a8b6a128c584c84aa72 +Subproject commit 3ebb36f4a2c42b74ec4e35efccc2be34c198a830 ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 1a993b89c570e03ba74f196f5d065a0ebe624010 +Subproject commit ea13d990580273a883368793dfbb826cab5a22d4 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/abc9efff224ee09c7e3eff92ac48320136dcfa30 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/abc9efff224ee09c7e3eff92ac48320136dcfa30 You're receiving 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 24 16:11:32 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 24 May 2020 12:11:32 -0400 Subject: [Git][ghc/ghc][wip/tyconapp-opts] 286 commits: Use export list of Main module in function TcRnDriver.hs:check_main (Fix #16453) Message-ID: <5eca9cb4e9228_6e263f9f0ba0f8401182654@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/tyconapp-opts at Glasgow Haskell Compiler / GHC Commits: 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. - - - - - 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] - - - - - 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 - - - - - 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 - - - - - 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. - - - - - 78c6523c by Ben Gamari at 2020-05-21T12:13:01-04:00 nonmoving: Optimise the write barrier - - - - - 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). - - - - - 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 - - - - - b7a6b2f4 by Gleb Popov at 2020-05-21T12:15:26-04:00 gitlab-ci: Set locale to C.UTF-8. - - - - - 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. - - - - - 0004ccb8 by Tuan Le at 2020-05-21T12:16:46-04:00 llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 - - - - - 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 - - - - - 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 - - - - - 2b363ebb by Richard Eisenberg at 2020-05-21T12:18:45-04:00 MR template should ask for key part - - - - - a95bbd0b by Sebastian Graf at 2020-05-21T12:19:37-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. - - - - - d3d055b8 by Galen Huntington at 2020-05-21T12:20:18-04:00 Clarify pitfalls of NegativeLiterals; see #18022. - - - - - 1b508a9e by Alexey Kuleshevich at 2020-05-21T12:21:02-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" - - - - - 4ca0c8a1 by Andreas Klebinger at 2020-05-21T12:21: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. - - - - - a1275081 by Krzysztof Gogolewski at 2020-05-21T12:22:35-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 - - - - - 8a816e5f by Krzysztof Gogolewski at 2020-05-21T12:23:55-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. - - - - - 566cc73f by Sylvain Henry at 2020-05-21T12:24:45-04:00 Move isDynLinkName into GHC.Types.Name It doesn't belong into GHC.Unit.State - - - - - 8239a62a by Ben Gamari at 2020-05-24T12:10:23-04:00 Notes from call - - - - - cd343773 by Ben Gamari at 2020-05-24T12:10:23-04:00 Shortcut mkTvSubstPrs on empty list Surprisingly enough this reduces compilation time on Cabal by nearly 1%. - - - - - ef4fe8e5 by Ben Gamari at 2020-05-24T12:10:23-04:00 Shortcut coreView - - - - - e1ca137b by Ben Gamari at 2020-05-24T12:10:54-04:00 expandSynTyCon_maybe: Special-case nullary tycons This avoids both allocation and some instructions. - - - - - 8604f1e8 by Ben Gamari at 2020-05-24T12:11:18-04:00 Optimise tcView - - - - - e3777ebf by Ben Gamari at 2020-05-24T12:11:18-04:00 Inline expandSynTyCon_maybe This is necessary to avoid some needless allocation since we currently lack nested CPR on sums. Metric Decrease: T12227 T12545 T12707 T14683 T3064 T5631 T5642 T9020 T9872a - - - - - 9dd4e4f4 by Ben Gamari at 2020-05-24T12:11:19-04:00 Some cleanup - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/merge_request_templates/merge-request.md - 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/0038463cb7070090b9e62f0c5278a8f8f47ac7df...9dd4e4f4067cbd912981d1d4b4cec78b68918521 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0038463cb7070090b9e62f0c5278a8f8f47ac7df...9dd4e4f4067cbd912981d1d4b4cec78b68918521 You're receiving 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 24 19:22:26 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 24 May 2020 15:22:26 -0400 Subject: [Git][ghc/ghc][master] 3 commits: Hadrian: fix cross-compiler build (#16051) Message-ID: <5ecac9722bf56_6e263f9f0ba0f84012160b5@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 7a07aa71 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix cross-compiler build (#16051) - - - - - 15ccca16 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix distDir per stage - - - - - b420fb24 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix hp2ps error during cross-compilation Fixed by @alp (see https://gitlab.haskell.org/ghc/ghc/issues/16051#note_274265) - - - - - 3 changed files: - hadrian/src/Context.hs - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Packages.hs Changes: ===================================== hadrian/src/Context.hs ===================================== @@ -55,9 +55,12 @@ libPath Context {..} = buildRoot <&> (-/- (stageString stage -/- "lib")) -- conventions (see 'cabalOsString' and 'cabalArchString'). distDir :: Stage -> Action FilePath distDir st = do + let (os,arch) = case st of + Stage0 -> (HostOs , HostArch) + _ -> (TargetOs, TargetArch) version <- ghcVersionStage st - hostOs <- cabalOsString <$> setting BuildOs - hostArch <- cabalArchString <$> setting BuildArch + hostOs <- cabalOsString <$> setting os + hostArch <- cabalArchString <$> setting arch return $ hostArch ++ "-" ++ hostOs ++ "-ghc-" ++ version pkgFileName :: Package -> String -> String -> Action FilePath ===================================== hadrian/src/Settings/Default.hs ===================================== @@ -81,6 +81,7 @@ stage0Packages = do ++ [ terminfo | not windowsHost, not cross ] ++ [ timeout | windowsHost ] ++ [ touchy | windowsHost ] + ++ [ hp2ps | cross ] -- | Packages built in 'Stage1' by default. You can change this in "UserSettings". stage1Packages :: Action [Package] ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -20,6 +20,10 @@ packageArgs = do -- See: https://gitlab.haskell.org/ghc/ghc/issues/16809. cross = flag CrossCompiling + -- Check if the bootstrap compiler has the same version as the one we + -- are building. This is used to build cross-compilers + bootCross = (==) <$> ghcVersionStage Stage0 <*> ghcVersionStage Stage1 + mconcat --------------------------------- base --------------------------------- [ package base ? mconcat @@ -105,22 +109,37 @@ packageArgs = do input "**/cbits/atomic.c" ? arg "-Wno-sync-nand" ] --------------------------------- ghci --------------------------------- - -- TODO: This should not be @not <$> flag CrossCompiling at . Instead we - -- should ensure that the bootstrap compiler has the same version as the - -- one we are building. - - -- TODO: In that case we also do not need to build most of the Stage1 - -- libraries, as we already know that the compiler comes with the most - -- recent versions. - - -- TODO: The use case here is that we want to build @ghc-proxy@ for the - -- cross compiler. That one needs to be compiled by the bootstrap - -- compiler as it needs to run on the host. Hence @libiserv@ needs - -- @GHCi.TH@, @GHCi.Message@ and @GHCi.Run@ from @ghci at . And those are - -- behind the @-fghci@ flag. , package ghci ? mconcat [ notStage0 ? builder (Cabal Flags) ? arg "ghci" - , cross ? stage0 ? builder (Cabal Flags) ? arg "ghci" ] + + -- The use case here is that we want to build @ghc-proxy@ for the + -- cross compiler. That one needs to be compiled by the bootstrap + -- compiler as it needs to run on the host. Hence @libiserv@ needs + -- @GHCi.TH@, @GHCi.Message@ and @GHCi.Run@ from @ghci at . And those are + -- behind the @-fghci@ flag. + -- + -- But it may not build if we have made some changes to ghci's + -- dependencies (see #16051). + -- + -- To fix this properly Hadrian would need to: + -- * first build a compiler for the build platform (stage1 is enough) + -- * use it as a bootstrap compiler to build the stage1 cross-compiler + -- + -- The issue is that "configure" would have to be executed twice (for + -- the build platform and for the cross-platform) and Hadrian would + -- need to be fixed to support two different stage1 compilers. + -- + -- The workaround we use is to check if the bootstrap compiler has + -- the same version as the one we are building. In this case we can + -- avoid the first step above and directly build with `-fghci`. + -- + -- TODO: Note that in that case we also do not need to build most of + -- the Stage1 libraries, as we already know that the bootstrap + -- compiler comes with the same versions as the one we are building. + -- + , cross ? stage0 ? bootCross ? builder (Cabal Flags) ? arg "ghci" + + ] --------------------------------- iserv -------------------------------- -- Add -Wl,--export-dynamic enables GHCi to load dynamic objects that View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/01c43634d443bd3cc0b95b43a7180e12230b845d...b420fb2474650e6dfbd66afd199f28492f900f75 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/01c43634d443bd3cc0b95b43a7180e12230b845d...b420fb2474650e6dfbd66afd199f28492f900f75 You're receiving 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 24 19:23:07 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 24 May 2020 15:23:07 -0400 Subject: [Git][ghc/ghc][master] Make Unicode brackets opening/closing tokens (#18225) Message-ID: <5ecac99b4d900_6e263f9ee3522300121897a@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: cd339ef0 by Joshua Price at 2020-05-24T15:22:56-04:00 Make Unicode brackets opening/closing tokens (#18225) The tokens `[|`, `|]`, `(|`, and `|)` are opening/closing tokens as described in GHC Proposal #229. This commit makes the unicode variants (`⟦`, `⟧`, `⦇`, and `⦈`) act the same as their ASCII counterparts. - - - - - 5 changed files: - compiler/GHC/Parser/Lexer.x - + testsuite/tests/parser/unicode/T18225A.hs - + testsuite/tests/parser/unicode/T18225B.hs - + testsuite/tests/parser/unicode/T18225B.stderr - testsuite/tests/parser/unicode/all.T Changes: ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -564,11 +564,11 @@ $tab { warnTab } -- -- The precise rules are as follows: -- --- * Identifiers, literals, and opening brackets (, (#, [, [|, [||, [p|, [e|, --- [t|, {, are considered "opening tokens". The function followedByOpeningToken --- tests whether the next token is an opening token. +-- * Identifiers, literals, and opening brackets (, (#, (|, [, [|, [||, [p|, +-- [e|, [t|, {, ⟦, ⦇, are considered "opening tokens". The function +-- followedByOpeningToken tests whether the next token is an opening token. -- --- * Identifiers, literals, and closing brackets ), #), ], |], }, +-- * Identifiers, literals, and closing brackets ), #), |), ], |], }, ⟧, ⦈, -- are considered "closing tokens". The function precededByClosingToken tests -- whether the previous token is a closing token. -- @@ -1068,6 +1068,8 @@ followedByOpeningToken _ _ _ (AI _ buf) ('\"', _) -> True ('\'', _) -> True ('_', _) -> True + ('⟦', _) -> True + ('⦇', _) -> True (c, _) -> isAlphaNum c -- See Note [Whitespace-sensitive operator parsing] @@ -1080,6 +1082,8 @@ precededByClosingToken _ (AI _ buf) _ _ = '\"' -> True '\'' -> True '_' -> True + '⟧' -> True + '⦈' -> True c -> isAlphaNum c {-# INLINE nextCharIs #-} ===================================== testsuite/tests/parser/unicode/T18225A.hs ===================================== @@ -0,0 +1,13 @@ +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE UnicodeSyntax #-} + +module T18225A where + +(!) :: IO a -> b -> b +(!) _ = id + +test1 :: Int +test1 = $⟦1⟧ + +test2 :: Int +test2 = ⟦2⟧!2 ===================================== testsuite/tests/parser/unicode/T18225B.hs ===================================== @@ -0,0 +1,11 @@ +{-# LANGUAGE Arrows #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE UnicodeSyntax #-} + +module T18225B where + +f :: (a, (b, c)) -> b +f (_, (x, _)) = x + +test :: a -> a +test = proc x -> ⦇f⦈$([|x|]) ===================================== testsuite/tests/parser/unicode/T18225B.stderr ===================================== @@ -0,0 +1 @@ +T18225B.hs:11:23: Parse error in command: [| x |] ===================================== testsuite/tests/parser/unicode/all.T ===================================== @@ -28,3 +28,5 @@ test('T10907', normal, compile, ['']) test('T7650', normal, compile, ['']) test('brackets', normal, compile, ['']) +test('T18225A', normal, compile, ['']) +test('T18225B', normal, compile_fail, ['']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cd339ef0e8ce940902df79ed1d93b3af50ea6f77 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cd339ef0e8ce940902df79ed1d93b3af50ea6f77 You're receiving 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 24 22:02:57 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 24 May 2020 18:02:57 -0400 Subject: [Git][ghc/ghc][wip/bump-base] base: Bump to 4.15.0.0 Message-ID: <5ecaef11e5fb4_6e263f9ee352230012377c4@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/bump-base at Glasgow Haskell Compiler / GHC Commits: 379fe810 by Ben Gamari at 2020-05-24T18:02:52-04:00 base: Bump to 4.15.0.0 - - - - - 14 changed files: - libraries/array - libraries/base/base.cabal - libraries/directory - libraries/filepath - libraries/ghc-boot-th/ghc-boot-th.cabal.in - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghc-compact/ghc-compact.cabal - libraries/ghci/ghci.cabal.in - libraries/parsec - libraries/process - libraries/stm - libraries/template-haskell/template-haskell.cabal.in - libraries/terminfo - libraries/unix Changes: ===================================== libraries/array ===================================== @@ -1 +1 @@ -Subproject commit f73f681e52546b1e35cb9e8a62fe49c33f259d98 +Subproject commit ab535173d7885ebfc2005d8da2765f0f52c923ce ===================================== 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 ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit 36bd1921258b759724a95ce56c5e880edf0972a2 +Subproject commit 0dcb228388a6e306c11f419c7c5575eaa6af40b3 ===================================== libraries/filepath ===================================== @@ -1 +1 @@ -Subproject commit 023eedaeb142d47b7b5a41fe4cc4150da0bd0042 +Subproject commit 7cb3dc285cd595a7b6cf0b74a58b6583fb67772e ===================================== libraries/ghc-boot-th/ghc-boot-th.cabal.in ===================================== @@ -36,4 +36,4 @@ Library GHC.ForeignSrcLang.Type GHC.Lexeme - build-depends: base >= 4.7 && < 4.15 + build-depends: base >= 4.7 && < 4.16 ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -55,7 +55,7 @@ Library -- GHC.Version -- GHC.Platform.Host - build-depends: base >= 4.7 && < 4.15, + build-depends: base >= 4.7 && < 4.16, binary == 0.8.*, bytestring == 0.10.*, containers >= 0.5 && < 0.7, ===================================== libraries/ghc-compact/ghc-compact.cabal ===================================== @@ -37,7 +37,7 @@ library CPP build-depends: ghc-prim >= 0.5.3 && < 0.7, - base >= 4.9.0 && < 4.15, + base >= 4.9.0 && < 4.16, bytestring >= 0.10.6.0 ghc-options: -Wall ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -72,7 +72,7 @@ library Build-Depends: array == 0.5.*, - base >= 4.8 && < 4.15, + base >= 4.8 && < 4.16, binary == 0.8.*, bytestring == 0.10.*, containers >= 0.5 && < 0.7, ===================================== libraries/parsec ===================================== @@ -1 +1 @@ -Subproject commit ce416997e15438ca616667995660e123ef7e219d +Subproject commit 190492494fe92e8dd42165190b7ac112be1f7389 ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit 8fffea5ca319e85e1bc9e7cac39e5a2c8effefcc +Subproject commit a35b835ff0f11bdfca31fe9b072d808d828292c9 ===================================== libraries/stm ===================================== @@ -1 +1 @@ -Subproject commit faf9904137044e35a589c7c1579e1bfa03789c84 +Subproject commit 444f672416a354c3cfde9d94ec237a36be46ef59 ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -55,7 +55,7 @@ Library Language.Haskell.TH.Lib.Map build-depends: - base >= 4.11 && < 4.15, + base >= 4.11 && < 4.16, ghc-boot-th == @ProjectVersionMunged@, ghc-prim, pretty == 1.1.* ===================================== libraries/terminfo ===================================== @@ -1 +1 @@ -Subproject commit 27e694688d2d6eee69959a8b6a128c584c84aa72 +Subproject commit 3ebb36f4a2c42b74ec4e35efccc2be34c198a830 ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 1a993b89c570e03ba74f196f5d065a0ebe624010 +Subproject commit ea13d990580273a883368793dfbb826cab5a22d4 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/379fe81067ae097c656ebaadda75ea383fa8dede -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/379fe81067ae097c656ebaadda75ea383fa8dede You're receiving 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 24 23:51:06 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 24 May 2020 19:51:06 -0400 Subject: [Git][ghc/ghc][wip/keepAlive] And now for something completely different... Message-ID: <5ecb086a37a83_6e26119d2f9012557af@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/keepAlive at Glasgow Haskell Compiler / GHC Commits: 2590af96 by Ben Gamari at 2020-05-24T19:50:50-04:00 And now for something completely different... - - - - - 6 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Settings.hs - compiler/GHC/StgToCmm/Prim.hs - includes/rts/storage/Closures.h - rts/StgMiscClosures.cmm - utils/deriveConstants/Main.hs Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -43,6 +43,7 @@ module GHC.Cmm.CLabel ( mkDirty_MUT_VAR_Label, mkNonmovingWriteBarrierEnabledLabel, + mkKeepAliveInfoLabel, mkUpdInfoLabel, mkBHUpdInfoLabel, mkIndStaticInfoLabel, @@ -500,6 +501,7 @@ mkBlockInfoTableLabel name c = IdLabel name c BlockInfoTable -- Constructing Cmm Labels mkDirty_MUT_VAR_Label, mkNonmovingWriteBarrierEnabledLabel, + mkKeepAliveInfoLabel, mkUpdInfoLabel, mkBHUpdInfoLabel, mkIndStaticInfoLabel, mkMainCapabilityLabel, mkMAP_FROZEN_CLEAN_infoLabel, mkMAP_FROZEN_DIRTY_infoLabel, @@ -512,6 +514,7 @@ mkDirty_MUT_VAR_Label, mkDirty_MUT_VAR_Label = mkForeignLabel (fsLit "dirty_MUT_VAR") Nothing ForeignLabelInExternalPackage IsFunction mkNonmovingWriteBarrierEnabledLabel = CmmLabel rtsUnitId (fsLit "nonmoving_write_barrier_enabled") CmmData +mkKeepAliveInfoLabel = CmmLabel rtsUnitId (fsLit "stg_keepAlive_frame") CmmInfo mkUpdInfoLabel = CmmLabel rtsUnitId (fsLit "stg_upd_frame") CmmInfo mkBHUpdInfoLabel = CmmLabel rtsUnitId (fsLit "stg_bh_upd_frame" ) CmmInfo mkIndStaticInfoLabel = CmmLabel rtsUnitId (fsLit "stg_IND_STATIC") CmmInfo ===================================== compiler/GHC/Settings.hs ===================================== @@ -1,5 +1,6 @@ {-# LANGUAGE CPP #-} + -- | Run-time settings module GHC.Settings ( Settings (..) ===================================== compiler/GHC/StgToCmm/Prim.hs ===================================== @@ -39,7 +39,6 @@ import GHC.StgToCmm.Prof ( costCentreFrom ) import GHC.Driver.Session import GHC.Platform import GHC.Types.Basic -import GHC.Types.Id.Make ( realWorldPrimId ) import GHC.Cmm.BlockId import GHC.Cmm.Graph import GHC.Stg.Syntax @@ -86,12 +85,8 @@ cgOpApp (StgFCallOp fcall ty) stg_args res_ty cgOpApp (StgPrimOp KeepAliveOp) args _res_ty | [x, s, StgVarArg k] <- args = do - { emitComment $ fsLit "keepAlive#" - ; r <- cgExpr (StgApp k [s]) - ; cmm_args <- getNonVoidArgAmodes [x, StgVarArg realWorldPrimId] - ; emitPrimCall [] MO_Touch cmm_args - ; return r - } + x' <- getNonVoidArgAmodes [x] + emitKeepAliveFrame (case x' of [y] -> y) $ cgExpr (StgApp k [s]) | otherwise = pprPanic "ill-formed keepAlive#" (ppr args) cgOpApp (StgPrimOp primop) args res_ty = do @@ -131,6 +126,20 @@ cgOpApp (StgPrimCallOp primcall) args _res_ty ; let fun = CmmLit (CmmLabel (mkPrimCallLabel primcall)) ; emitCall (NativeNodeCall, NativeReturn) fun cmm_args } +emitKeepAliveFrame :: CmmExpr -> FCode a -> FCode a +emitKeepAliveFrame x body + = do + updfr <- getUpdFrameOff + dflags <- getDynFlags + let hdr = fixedHdrSize dflags + off_frame = updfr + hdr + sIZEOF_StgKeepAliveFrame_NoHdr dflags + frame = CmmStackSlot Old off_frame + off_closure = hdr + oFFSET_StgKeepAliveFrame_closure dflags + + emitStore frame (mkLblExpr mkKeepAliveInfoLabel) + emitStore (cmmOffset (targetPlatform dflags) frame off_closure) x + withUpdFrameOff off_frame body + -- | Interpret the argument as an unsigned value, assuming the value -- is given in two-complement form in the given width. -- ===================================== includes/rts/storage/Closures.h ===================================== @@ -194,6 +194,11 @@ typedef struct { StgClosure *handler; } StgCatchFrame; +typedef struct { + StgHeader header; + StgClosure *closure; +} StgKeepAliveFrame; + typedef struct { const StgInfoTable* info; struct StgStack_ *next_chunk; ===================================== rts/StgMiscClosures.cmm ===================================== @@ -68,6 +68,17 @@ INFO_TABLE_RET (stg_restore_cccs_eval, RET_SMALL, W_ info_ptr, W_ cccs) jump stg_ap_0_fast(ret); } +/* ---------------------------------------------------------------------------- + keepAlive# + ------------------------------------------------------------------------- */ + +INFO_TABLE_RET(stg_keepAlive_frame, RET_SMALL, W_ info_ptr) + /* explicit stack */ +{ + Sp_adj(1); + jump %ENTRY_CODE(Sp(0)) [*]; // N.B. all registers live +} + /* ---------------------------------------------------------------------------- Support for the bytecode interpreter. ------------------------------------------------------------------------- */ ===================================== utils/deriveConstants/Main.hs ===================================== @@ -466,6 +466,9 @@ wanteds os = concat ,closureField C "StgCatchFrame" "handler" ,closureField C "StgCatchFrame" "exceptions_blocked" + + ,closureSize Both "StgKeepAliveFrame" + ,closureField Both "StgKeepAliveFrame" "closure" ,closureSize C "StgPAP" ,closureField C "StgPAP" "n_args" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2590af96c9dd1bd12ed939bceefaf643b7cf1534 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2590af96c9dd1bd12ed939bceefaf643b7cf1534 You're receiving 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 24 23:56:39 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 24 May 2020 19:56:39 -0400 Subject: [Git][ghc/ghc][wip/tyconapp-opts] 29 commits: docs: fix formatting and add some links Message-ID: <5ecb09b719f49_6e26eb364ac125674d@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/tyconapp-opts at Glasgow Haskell Compiler / GHC Commits: d830bbc9 by Adam Sandberg Ericsson at 2020-05-23T13:36:20-04:00 docs: fix formatting and add some links [skip ci] - - - - - 49301ad6 by Andrew Martin at 2020-05-23T13:37:01-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. - - - - - dcd6bdcc by Ben Gamari at 2020-05-23T13:37:48-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. - - - - - 82cb8913 by John Ericson at 2020-05-23T13:38:32-04:00 Fix #18145 and also avoid needless work with implicit vars - `forAllOrNothing` now is monadic, so we can trace whether we bind an explicit `forall` or not. - #18145 arose because the free vars calculation was needlessly complex. It is now greatly simplified. - Replaced some other implicit var code with `filterFreeVarsToBind`. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - a60dc835 by Ben Gamari at 2020-05-23T13:39:12-04:00 Bump process submodule Fixes #17926. - - - - - 856adf54 by Ben Gamari at 2020-05-23T13:40:21-04:00 users-guide: Clarify meaning of -haddock flag Fixes #18206. - - - - - 7ae57afd by Ben Gamari at 2020-05-23T13:41:03-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 - - - - - 63d30e60 by jneira at 2020-05-24T01:54:42-04:00 Add hie-bios script for windows systems It is a direct translation of the sh script - - - - - 59182b88 by jneira at 2020-05-24T01:54:42-04:00 Honour previous values for CABAL and CABFLAGS The immediate goal is let the hie-bios.bat script set CABFLAGS with `-v0` and remove all cabal output except the compiler arguments - - - - - 932dc54e by jneira at 2020-05-24T01:54:42-04:00 Add specific configuration for windows in hie.yaml - - - - - e0eda070 by jneira at 2020-05-24T01:54:42-04:00 Remove not needed hie-bios output - - - - - a0ea59d6 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Move Config module into GHC.Settings - - - - - 37430251 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Core.Arity into GHC.Core.Opt.Arity - - - - - a426abb9 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Hs.Types into GHC.Hs.Type See discussion in https://gitlab.haskell.org/ghc/ghc/issues/13009#note_268610 - - - - - 1c91a7a0 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Bump haddock submodule - - - - - 66bd24d1 by Ryan Scott at 2020-05-24T01:56:03-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. - - - - - 01c43634 by Matthew Pickering at 2020-05-24T01:56:42-04:00 Remove unused hs-boot file - - - - - 7a07aa71 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix cross-compiler build (#16051) - - - - - 15ccca16 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix distDir per stage - - - - - b420fb24 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix hp2ps error during cross-compilation Fixed by @alp (see https://gitlab.haskell.org/ghc/ghc/issues/16051#note_274265) - - - - - cd339ef0 by Joshua Price at 2020-05-24T15:22:56-04:00 Make Unicode brackets opening/closing tokens (#18225) The tokens `[|`, `|]`, `(|`, and `|)` are opening/closing tokens as described in GHC Proposal #229. This commit makes the unicode variants (`⟦`, `⟧`, `⦇`, and `⦈`) act the same as their ASCII counterparts. - - - - - a175cccb by Ben Gamari at 2020-05-24T22:01:40+00:00 Notes from call - - - - - 954fbddf by Ben Gamari at 2020-05-24T22:01:40+00:00 Shortcut mkTvSubstPrs on empty list Surprisingly enough this reduces compilation time on Cabal by nearly 1%. - - - - - f4f773da by Ben Gamari at 2020-05-24T22:01:40+00:00 Shortcut coreView - - - - - f653a014 by Ben Gamari at 2020-05-24T22:01:40+00:00 expandSynTyCon_maybe: Special-case nullary tycons This avoids both allocation and some instructions. - - - - - 372ff2d4 by Ben Gamari at 2020-05-24T22:01:40+00:00 Optimise tcView - - - - - d1da02eb by Ben Gamari at 2020-05-24T22:01:40+00:00 Inline expandSynTyCon_maybe This is necessary to avoid some needless allocation since we currently lack nested CPR on sums. Metric Decrease: T12227 T12545 T12707 T14683 T3064 T5631 T5642 T9020 T9872a - - - - - 52668c74 by Ben Gamari at 2020-05-24T22:01:40+00:00 Some cleanup - - - - - ed54bad5 by Ben Gamari at 2020-05-24T22:01:40+00:00 hi - - - - - 30 changed files: - + .git-ignore-revs - compiler/GHC/Builtin/Names.hs - − compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Arity.hs → compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatOut.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/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/FastString.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9dd4e4f4067cbd912981d1d4b4cec78b68918521...ed54bad58245b5ccb0ad680515078685868377dd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9dd4e4f4067cbd912981d1d4b4cec78b68918521...ed54bad58245b5ccb0ad680515078685868377dd You're receiving 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 25 00:00:15 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 24 May 2020 20:00:15 -0400 Subject: [Git][ghc/ghc][wip/bump-base] base: Bump to 4.15.0.0 Message-ID: <5ecb0a8f5e2e2_6e263f9ee35223001257598@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/bump-base at Glasgow Haskell Compiler / GHC Commits: 3c47cf2c by Ben Gamari at 2020-05-24T19:59:38-04:00 base: Bump to 4.15.0.0 - - - - - 16 changed files: - libraries/array - libraries/base/base.cabal - libraries/deepseq - libraries/directory - libraries/filepath - libraries/ghc-boot-th/ghc-boot-th.cabal.in - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghc-compact/ghc-compact.cabal - libraries/ghci/ghci.cabal.in - libraries/hpc - libraries/parsec - libraries/process - libraries/stm - libraries/template-haskell/template-haskell.cabal.in - libraries/terminfo - libraries/unix Changes: ===================================== libraries/array ===================================== @@ -1 +1 @@ -Subproject commit f73f681e52546b1e35cb9e8a62fe49c33f259d98 +Subproject commit ab535173d7885ebfc2005d8da2765f0f52c923ce ===================================== 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 ===================================== libraries/deepseq ===================================== @@ -1 +1 @@ -Subproject commit da0eda33f540786b6823c6f542ab59cf9d1b71d9 +Subproject commit 13c1c84415da727ab56e9fa33aca5046b6683848 ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit 36bd1921258b759724a95ce56c5e880edf0972a2 +Subproject commit 0dcb228388a6e306c11f419c7c5575eaa6af40b3 ===================================== libraries/filepath ===================================== @@ -1 +1 @@ -Subproject commit 023eedaeb142d47b7b5a41fe4cc4150da0bd0042 +Subproject commit 7cb3dc285cd595a7b6cf0b74a58b6583fb67772e ===================================== libraries/ghc-boot-th/ghc-boot-th.cabal.in ===================================== @@ -36,4 +36,4 @@ Library GHC.ForeignSrcLang.Type GHC.Lexeme - build-depends: base >= 4.7 && < 4.15 + build-depends: base >= 4.7 && < 4.16 ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -55,7 +55,7 @@ Library -- GHC.Version -- GHC.Platform.Host - build-depends: base >= 4.7 && < 4.15, + build-depends: base >= 4.7 && < 4.16, binary == 0.8.*, bytestring == 0.10.*, containers >= 0.5 && < 0.7, ===================================== libraries/ghc-compact/ghc-compact.cabal ===================================== @@ -37,7 +37,7 @@ library CPP build-depends: ghc-prim >= 0.5.3 && < 0.7, - base >= 4.9.0 && < 4.15, + base >= 4.9.0 && < 4.16, bytestring >= 0.10.6.0 ghc-options: -Wall ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -72,7 +72,7 @@ library Build-Depends: array == 0.5.*, - base >= 4.8 && < 4.15, + base >= 4.8 && < 4.16, binary == 0.8.*, bytestring == 0.10.*, containers >= 0.5 && < 0.7, ===================================== libraries/hpc ===================================== @@ -1 +1 @@ -Subproject commit f73c482db30a40cfa12074de51335b70a0974931 +Subproject commit 43bb9061a748aee6a95a9f1db33a2b1e5f770634 ===================================== libraries/parsec ===================================== @@ -1 +1 @@ -Subproject commit ce416997e15438ca616667995660e123ef7e219d +Subproject commit 190492494fe92e8dd42165190b7ac112be1f7389 ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit 8fffea5ca319e85e1bc9e7cac39e5a2c8effefcc +Subproject commit a35b835ff0f11bdfca31fe9b072d808d828292c9 ===================================== libraries/stm ===================================== @@ -1 +1 @@ -Subproject commit faf9904137044e35a589c7c1579e1bfa03789c84 +Subproject commit 444f672416a354c3cfde9d94ec237a36be46ef59 ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -55,7 +55,7 @@ Library Language.Haskell.TH.Lib.Map build-depends: - base >= 4.11 && < 4.15, + base >= 4.11 && < 4.16, ghc-boot-th == @ProjectVersionMunged@, ghc-prim, pretty == 1.1.* ===================================== libraries/terminfo ===================================== @@ -1 +1 @@ -Subproject commit 27e694688d2d6eee69959a8b6a128c584c84aa72 +Subproject commit 3ebb36f4a2c42b74ec4e35efccc2be34c198a830 ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 1a993b89c570e03ba74f196f5d065a0ebe624010 +Subproject commit ea13d990580273a883368793dfbb826cab5a22d4 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3c47cf2c2eabce3faf1bb185487bbbbe35d49635 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3c47cf2c2eabce3faf1bb185487bbbbe35d49635 You're receiving 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 25 00:06:45 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 24 May 2020 20:06:45 -0400 Subject: [Git][ghc/ghc][wip/T18210] eventlog: Fix racy flushing Message-ID: <5ecb0c153a57d_6e2687ddb08125804e@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18210 at Glasgow Haskell Compiler / GHC Commits: 29acf083 by Ben Gamari at 2020-05-24T20:06:38-04:00 eventlog: Fix racy flushing Previously no attempt was made to avoid multiple threads writing their capability-local eventlog buffers to the eventlog writer simultaneously. This could result in multiple eventlog streams being interleaved. Fix this by documenting that the EventLogWriter's write() and flush() functions may be called reentrantly and fix the default writer to protect its FILE* by a mutex. Fixes #18210. - - - - - 3 changed files: - docs/users_guide/runtime_control.rst - includes/rts/EventLogWriter.h - rts/eventlog/EventLogWriter.c Changes: ===================================== docs/users_guide/runtime_control.rst ===================================== @@ -196,11 +196,17 @@ Furthermore GHC lets you specify the way event log data (see :rts-flag:`-l Hands buffered event log data to your event log writer. Return true on success. Required for a custom :c:type:`EventLogWriter`. + Note that this function may be called by multiple threads + simultaneously. + .. c:member:: void flushEventLog(void) Flush buffers (if any) of your custom :c:type:`EventLogWriter`. This can be ``NULL``. + Note that this function may be called by multiple threads + simultaneously. + .. c:member:: void stopEventLogWriter(void) Called when event logging is about to stop. This can be ``NULL``. ===================================== includes/rts/EventLogWriter.h ===================================== @@ -24,9 +24,13 @@ typedef struct { void (* initEventLogWriter) (void); // Write a series of events returning true on success. + // Note that this may be called by multiple threads simultaneously. + // The writer is responsible for concurrency control. bool (* writeEventLog) (void *eventlog, size_t eventlog_size); // Flush possibly existing buffers (may be NULL) + // Note that this may be called by multiple threads simultaneously. + // The writer is responsible for concurrency control. void (* flushEventLog) (void); // Close an initialized EventLogOutput (may be NULL) ===================================== rts/eventlog/EventLogWriter.c ===================================== @@ -28,11 +28,22 @@ static pid_t event_log_pid = -1; // File for logging events static FILE *event_log_file = NULL; +// Protects event log file +static Mutex event_log_mutex; + static void initEventLogFileWriter(void); static bool writeEventLogFile(void *eventlog, size_t eventlog_size); static void flushEventLogFile(void); static void stopEventLogFileWriter(void); +#if defined(THREADED_RTS) +static void acquire_event_log_mutex(void) { ACQUIRE_MUTEX(&event_log_mutex); } +static void release_event_log_mutex(void) { RELEASE_MUTEX(&event_log_mutex); } +#else +static void acquire_event_log_mutex(void) {} +static void release_event_log_mutex(void) {} +#endif + static char *outputFileName(void) { @@ -89,6 +100,9 @@ initEventLogFileWriter(void) } stgFree(event_log_filename); +#if defined(THREADED_RTS) + initMutex(&event_log_mutex); +#endif } static bool @@ -97,15 +111,17 @@ writeEventLogFile(void *eventlog, size_t eventlog_size) unsigned char *begin = eventlog; size_t remain = eventlog_size; + acquire_event_log_mutex(); while (remain > 0) { size_t written = fwrite(begin, 1, remain, event_log_file); if (written == 0) { + release_event_log_mutex(); return false; } remain -= written; begin += written; } - + release_event_log_mutex(); return true; } @@ -124,6 +140,9 @@ stopEventLogFileWriter(void) fclose(event_log_file); event_log_file = NULL; } +#if defined(THREADED_RTS) + closeMutex(&event_log_mutex); +#endif } const EventLogWriter FileEventLogWriter = { View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/29acf0835a102cdad2ecb08ba7d6a37b70eb99cc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/29acf0835a102cdad2ecb08ba7d6a37b70eb99cc You're receiving 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 25 00:42:37 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 24 May 2020 20:42:37 -0400 Subject: [Git][ghc/ghc][wip/backports] 24 commits: Note platform-specific Foreign.C.Types in context Message-ID: <5ecb147d4f6bc_6e263f9ed66cfd7c125967a@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/backports at Glasgow Haskell Compiler / GHC Commits: 37956be4 by Viktor Dukhovni at 2020-05-21T17:42:48-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. - - - - - a16c24b7 by Ben Gamari at 2020-05-24T20:42:31-04:00 rts: Add getCurrentThreadCPUTime helper (cherry picked from commit cedd6f3041de6abe64dfa3257bec7730a9dced9f) - - - - - d1f9d711 by Ben Gamari at 2020-05-24T20:42:31-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) - - - - - 39f3b172 by Ben Gamari at 2020-05-24T20:42:31-04:00 nonmoving-gc: Track time usage of nonmoving marking (cherry picked from commit ace618cd2294989e783bd453cee88e0e1c0dad77) - - - - - 35f50728 by Ben Gamari at 2020-05-24T20:42:31-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - dc26ba87 by Ben Gamari at 2020-05-24T20:42:31-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. - - - - - ce49860d by Ben Gamari at 2020-05-24T20:42:32-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. - - - - - 1101739a by Ben Gamari at 2020-05-24T20:42:32-04:00 hadrian: Allow libnuma library path to be specified - - - - - 6e8ede7e by Ben Gamari at 2020-05-24T20:42:32-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. - - - - - 185a870e by Ben Gamari at 2020-05-24T20:42:32-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. - - - - - 124a40cc by Ben Gamari at 2020-05-24T20:42:32-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. - - - - - b23f16d0 by Ben Gamari at 2020-05-24T20:42:32-04:00 nonmoving: Optimise the write barrier (cherry picked from commit a636eadac1f30bae37aeb6526f94893293f098b8) - - - - - d2581e98 by Ömer Sinan Ağacan at 2020-05-24T20:42:32-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) - - - - - 76059e3e by Simon Peyton Jones at 2020-05-24T20:42:32-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) - - - - - a7dd83db by Simon Peyton Jones at 2020-05-24T20:42:32-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) - - - - - e3fcf26d by Sylvain Henry at 2020-05-24T20:42:32-04:00 Rts: show errno on failure (#18033) (cherry picked from commit 4875d419ba066e479f7ac07f8b39ebe10c855859) - - - - - ba788d22 by Ryan Scott at 2020-05-24T20:42:32-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) - - - - - 25d84fa2 by Adam Gundry at 2020-05-24T20:42:32-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) - - - - - 646648a9 by Ben Gamari at 2020-05-24T20:42:32-04:00 Ensure that printMinimalImports closes handle Fixes #18166. (cherry picked from commit 5afc160dee7142c96a842037fb64bee1429ad9ec) - - - - - 123c386b by Ben Gamari at 2020-05-24T20:42:32-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) - - - - - 06f05573 by Ben Gamari at 2020-05-24T20:42:32-04:00 nonmoving: Optimise log2_ceil (cherry picked from commit 5f69016115414d0dd921e72f3edcd0b365966141) - - - - - dae01c10 by Ben Gamari at 2020-05-24T20:42:32-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) - - - - - 72218602 by Ben Gamari at 2020-05-24T20:42:32-04:00 users guide: Move eventlog documentation users guide (cherry picked from commit c560dd07f506810eaabae2f582491138aa224819) - - - - - 79da3ca2 by Ben Gamari at 2020-05-24T20:42:33-04:00 users guide: Add documentation for non-moving GC events (cherry picked from commit 02543d5ef9bd7a910fc9fece895780583ab9635a) - - - - - 30 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 - configure.ac - docs/users_guide/conf.py - docs/users_guide/eventlog-formats.rst - docs/users_guide/runtime_control.rst - 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/EventLogFormat.h - includes/rts/Time.h - libraries/base/Foreign/C/Types.hs - libraries/base/GHC/Stats.hsc - rts/GetTime.h - rts/ProfHeap.c - rts/RtsFlags.c - rts/Stats.c - rts/Stats.h - rts/Updates.h - rts/linker/PEi386.c - rts/posix/GetTime.c - rts/posix/itimer/Pthread.c - rts/sm/BlockAlloc.c - rts/sm/Evac.c The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/729922a5276f7a35b4090929acc1c9b07b618f75...79da3ca28d12306e5bc073d2f1b7ba130e12cd99 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/729922a5276f7a35b4090929acc1c9b07b618f75...79da3ca28d12306e5bc073d2f1b7ba130e12cd99 You're receiving 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 25 01:15:27 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 24 May 2020 21:15:27 -0400 Subject: [Git][ghc/ghc][wip/T18151] 36 commits: Add test for #16167 Message-ID: <5ecb1c2f99f22_6e263f9ee298416012614bb@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18151 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. - - - - - 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. - - - - - cdeadaaf by Ben Gamari at 2020-05-20T13:34:24-04:00 testsuite: Add test for #18151 - - - - - fcbf46ab by Ben Gamari at 2020-05-24T21:11:55-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. - - - - - 27b8e474 by Ben Gamari at 2020-05-24T21:15:11-04:00 testsuite: Add test for desugaring of PostfixOperators - - - - - 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/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/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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9ccb4dbafcf433e6bc2ec62ae08827309ee66582...27b8e4740e6c7b993ea88c323354ba7e596acad6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9ccb4dbafcf433e6bc2ec62ae08827309ee66582...27b8e4740e6c7b993ea88c323354ba7e596acad6 You're receiving 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 25 01:30:29 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 24 May 2020 21:30:29 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18131 Message-ID: <5ecb1fb5f04e_6e263f9ee2984160126377a@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/T18131 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18131 You're receiving 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 25 01:55:07 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 24 May 2020 21:55:07 -0400 Subject: [Git][ghc/ghc][wip/T18210] eventlog: Fix racy flushing Message-ID: <5ecb257b78a85_6e263f9f0ba0f84012679a3@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18210 at Glasgow Haskell Compiler / GHC Commits: eb253017 by Ben Gamari at 2020-05-24T21:54:58-04:00 eventlog: Fix racy flushing Previously no attempt was made to avoid multiple threads writing their capability-local eventlog buffers to the eventlog writer simultaneously. This could result in multiple eventlog streams being interleaved. Fix this by documenting that the EventLogWriter's write() and flush() functions may be called reentrantly and fix the default writer to protect its FILE* by a mutex. Fixes #18210. - - - - - 3 changed files: - docs/users_guide/runtime_control.rst - includes/rts/EventLogWriter.h - rts/eventlog/EventLogWriter.c Changes: ===================================== docs/users_guide/runtime_control.rst ===================================== @@ -196,11 +196,17 @@ Furthermore GHC lets you specify the way event log data (see :rts-flag:`-l Hands buffered event log data to your event log writer. Return true on success. Required for a custom :c:type:`EventLogWriter`. + Note that this function may be called by multiple threads + simultaneously. + .. c:member:: void flushEventLog(void) Flush buffers (if any) of your custom :c:type:`EventLogWriter`. This can be ``NULL``. + Note that this function may be called by multiple threads + simultaneously. + .. c:member:: void stopEventLogWriter(void) Called when event logging is about to stop. This can be ``NULL``. ===================================== includes/rts/EventLogWriter.h ===================================== @@ -24,9 +24,13 @@ typedef struct { void (* initEventLogWriter) (void); // Write a series of events returning true on success. + // Note that this may be called by multiple threads simultaneously. + // The writer is responsible for concurrency control. bool (* writeEventLog) (void *eventlog, size_t eventlog_size); // Flush possibly existing buffers (may be NULL) + // Note that this may be called by multiple threads simultaneously. + // The writer is responsible for concurrency control. void (* flushEventLog) (void); // Close an initialized EventLogOutput (may be NULL) ===================================== rts/eventlog/EventLogWriter.c ===================================== @@ -28,11 +28,22 @@ static pid_t event_log_pid = -1; // File for logging events static FILE *event_log_file = NULL; +// Protects event log file +static Mutex event_log_mutex; + static void initEventLogFileWriter(void); static bool writeEventLogFile(void *eventlog, size_t eventlog_size); static void flushEventLogFile(void); static void stopEventLogFileWriter(void); +#if defined(THREADED_RTS) +static void acquire_event_log_lock(void) { ACQUIRE_LOCK(&event_log_mutex); } +static void release_event_log_lock(void) { RELEASE_LOCK(&event_log_mutex); } +#else +static void acquire_event_log_lock(void) {} +static void release_event_log_lock(void) {} +#endif + static char *outputFileName(void) { @@ -89,6 +100,9 @@ initEventLogFileWriter(void) } stgFree(event_log_filename); +#if defined(THREADED_RTS) + initMutex(&event_log_mutex); +#endif } static bool @@ -97,15 +111,17 @@ writeEventLogFile(void *eventlog, size_t eventlog_size) unsigned char *begin = eventlog; size_t remain = eventlog_size; + acquire_event_log_lock(); while (remain > 0) { size_t written = fwrite(begin, 1, remain, event_log_file); if (written == 0) { + release_event_log_lock(); return false; } remain -= written; begin += written; } - + release_event_log_lock(); return true; } @@ -124,6 +140,9 @@ stopEventLogFileWriter(void) fclose(event_log_file); event_log_file = NULL; } +#if defined(THREADED_RTS) + closeMutex(&event_log_mutex); +#endif } const EventLogWriter FileEventLogWriter = { View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/eb25301757aa52dc6e574b3a2beedc43bcd2d286 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/eb25301757aa52dc6e574b3a2beedc43bcd2d286 You're receiving 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 25 02:17:15 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 24 May 2020 22:17:15 -0400 Subject: [Git][ghc/ghc][wip/T18151] HsToCore: Eta expand left sections Message-ID: <5ecb2aab11fde_6e2687ddb081279318@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18151 at Glasgow Haskell Compiler / GHC Commits: 453aa853 by Ben Gamari at 2020-05-24T22:17:02-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. -Operator sections. At first it looks as if we can convert -\begin{verbatim} - (expr op) -\end{verbatim} -to -\begin{verbatim} - \x -> op expr x -\end{verbatim} + +Note [Desugaring operator sections] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +At first it looks as if we can convert + (expr op) +naively to + \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} -If \tr{expr} is actually just a variable, say, then the simplifier + map (expr op) xs +for example. + +So we convert instead to + let y = expr in \x -> op y x +If `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,35 @@ 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') } - --- dsLExpr (SectionR op expr) -- \ x -> op x expr +-- dsExpr (SectionL op expr) === (expr `op`) ~> \y -> op expr y +-- +-- See Note [Desugaring operator sections]. +-- N.B. this also must handle postfix operator sections due to -XPostfixOperators. +dsExpr e@(SectionL _ expr op) = do + core_op <- dsLExpr op + x_core <- dsLExpr expr + case splitFunTys (exprType core_op) of + -- Binary operator section + (x_ty:y_ty:_, _) -> do + 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])) + + -- Postfix operator section + (x_ty:_, _) -> do + return $ mkCoreAppDs (text "sectionl" <+> ppr e) core_op x_core + + _ -> pprPanic "dsExpr(SectionL)" (ppr e) + +-- 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 ===================================== @@ -64,4 +64,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/453aa8531411380cc227a117f64f4d8a1a99aa24 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/453aa8531411380cc227a117f64f4d8a1a99aa24 You're receiving 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 25 02:27:45 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 24 May 2020 22:27:45 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 11 commits: Hadrian: fix cross-compiler build (#16051) Message-ID: <5ecb2d218c6ee_6e2687ddb081280148@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 7a07aa71 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix cross-compiler build (#16051) - - - - - 15ccca16 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix distDir per stage - - - - - b420fb24 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix hp2ps error during cross-compilation Fixed by @alp (see https://gitlab.haskell.org/ghc/ghc/issues/16051#note_274265) - - - - - cd339ef0 by Joshua Price at 2020-05-24T15:22:56-04:00 Make Unicode brackets opening/closing tokens (#18225) The tokens `[|`, `|]`, `(|`, and `|)` are opening/closing tokens as described in GHC Proposal #229. This commit makes the unicode variants (`⟦`, `⟧`, `⦇`, and `⦈`) act the same as their ASCII counterparts. - - - - - e7f26229 by Zubin Duggal at 2020-05-24T22:27:38-04:00 Add info about typeclass evidence to .hie files See `testsuite/tests/hiefile/should_run/HieQueries.hs` and `testsuite/tests/hiefile/should_run/HieQueries.stdout` for an example of this We add two new fields, `EvidenceVarBind` and `EvidenceVarUse` to the `ContextInfo` associated with an Identifier. These are associated with the appropriate identifiers for the evidence variables collected when we come across `HsWrappers`, `TcEvBinds` and `IPBinds` while traversing the AST. Instance dictionary and superclass selector dictionaries from `tcg_insts` and classes defined in `tcg_tcs` are also recorded in the AST as originating from their definition span This allows us to save a complete picture of the evidence constructed by the constraint solver, and will let us report this to the user, enabling features like going to the instance definition from the invocation of a class method(or any other method taking a constraint) and finding all usages of a particular instance. Additionally, - Mark NodeInfo with an origin so we can differentiate between bindings origininating in the source vs those in ghc - Along with typeclass evidence info, also include information on Implicit Parameters - Add a few utility functions to HieUtils in order to query the new info Updates haddock submodule - - - - - f4d24554 by Ben Gamari at 2020-05-24T22:27:40-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. - - - - - 9dd8d774 by Ben Gamari at 2020-05-24T22:27:41-04:00 Coverage: Drop redundant ad-hoc boot module check To determine whether the module is a boot module Coverage.addTicksToBinds was checking for a `boot` suffix in the module source filename. This is quite ad-hoc and shouldn't be necessary; the callsite in `deSugar` already checks that the module isn't a boot module. - - - - - 719ecf39 by Ben Gamari at 2020-05-24T22:27:41-04:00 Coverage: Make tickBoxCount strict This could otherwise easily cause a leak of (+) thunks. - - - - - 32007b31 by Ben Gamari at 2020-05-24T22:27:41-04:00 Coverage: Make ccIndices strict This just seems like a good idea. - - - - - f1b18726 by Ben Gamari at 2020-05-24T22:27:41-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. - - - - - 9d0c233e by Ben Gamari at 2020-05-24T22:27:41-04:00 Coverage: Factor out addMixEntry - - - - - 30 changed files: - compiler/GHC/HsToCore/Coverage.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Debug.hs - compiler/GHC/Iface/Ext/Types.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Parser/Lexer.x - hadrian/src/Context.hs - hadrian/src/Settings/Default.hs - hadrian/src/Settings/Packages.hs - 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/hiefile/should_compile/Scopes.hs - + testsuite/tests/hiefile/should_run/HieQueries.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d13138cdd1020f8476ea38e260d0773f406883d5...9d0c233ef9dc98783d537bd45fb40d37fb55b079 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d13138cdd1020f8476ea38e260d0773f406883d5...9d0c233ef9dc98783d537bd45fb40d37fb55b079 You're receiving 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 25 02:38:04 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 24 May 2020 22:38:04 -0400 Subject: [Git][ghc/ghc][wip/T18131] hadrian: Don't track GHC's verbosity argument Message-ID: <5ecb2f8c571f6_6e2687ddb08129057d@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18131 at Glasgow Haskell Compiler / GHC Commits: f1acf119 by Ben Gamari at 2020-05-24T22:37:53-04:00 hadrian: Don't track GHC's verbosity argument Teach hadrian to ignore GHC's -v argument in its recompilation check, thus fixing #18131. - - - - - 1 changed file: - hadrian/src/Target.hs Changes: ===================================== hadrian/src/Target.hs ===================================== @@ -20,7 +20,9 @@ type Target = H.Target Context Builder -- 'True' only if the argument needs to be tracked. trackArgument :: Target -> String -> Bool trackArgument target arg = case builder target of - (Make _) -> not $ threadArg arg - _ -> True + Make _ -> not $ threadArg arg + Ghc _ _ -> not $ verbosityArg arg + _ -> True where threadArg s = dropWhileEnd isDigit s `elem` ["-j", "MAKEFLAGS=-j", "THREADS="] + verbosityArg s = dropWhileEnd isDigit s == "-v" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f1acf1199e4094e16a3d2fbfb6b8129bf471b658 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f1acf1199e4094e16a3d2fbfb6b8129bf471b658 You're receiving 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 25 02:41:32 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 24 May 2020 22:41:32 -0400 Subject: [Git][ghc/ghc][wip/T18151] HsToCore: Eta expand left sections Message-ID: <5ecb305c6f22b_6e263f9ee35223001290933@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18151 at Glasgow Haskell Compiler / GHC Commits: cca6673d by Ben Gamari at 2020-05-24T22:41:14-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. -Operator sections. At first it looks as if we can convert -\begin{verbatim} - (expr op) -\end{verbatim} -to -\begin{verbatim} - \x -> op expr x -\end{verbatim} + +Note [Desugaring operator sections] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +At first it looks as if we can convert + (expr op) +naively to + \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} -If \tr{expr} is actually just a variable, say, then the simplifier + map (expr op) xs +for example. + +So we convert instead to + let y = expr in \x -> op y x +If `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,35 @@ 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') } - --- dsLExpr (SectionR op expr) -- \ x -> op x expr +-- dsExpr (SectionL op expr) === (expr `op`) ~> \y -> op expr y +-- +-- See Note [Desugaring operator sections]. +-- N.B. this also must handle postfix operator sections due to -XPostfixOperators. +dsExpr e@(SectionL _ expr op) = do + core_op <- dsLExpr op + x_core <- dsLExpr expr + case splitFunTys (exprType core_op) of + -- Binary operator section + (x_ty:y_ty:_, _) -> do + 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])) + + -- Postfix operator section + (_:_, _) -> do + return $ mkCoreAppDs (text "sectionl" <+> ppr e) core_op x_core + + _ -> pprPanic "dsExpr(SectionL)" (ppr e) + +-- 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 ===================================== @@ -64,4 +64,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/cca6673d4771eba253c8c0b15707059e098983d4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cca6673d4771eba253c8c0b15707059e098983d4 You're receiving 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 25 07:52:40 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 25 May 2020 03:52:40 -0400 Subject: [Git][ghc/ghc] Deleted branch wip/backports Message-ID: <5ecb79489a2e5_6e263f9ed66cfd7c1320716@gitlab.haskell.org.mail> Ben Gamari deleted branch wip/backports 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 25 07:52:41 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 25 May 2020 03:52:41 -0400 Subject: [Git][ghc/ghc][ghc-8.10] 23 commits: rts: Add getCurrentThreadCPUTime helper Message-ID: <5ecb794951b73_6e26eb364ac132098b@gitlab.haskell.org.mail> Ben Gamari pushed to branch ghc-8.10 at Glasgow Haskell Compiler / GHC Commits: a16c24b7 by Ben Gamari at 2020-05-24T20:42:31-04:00 rts: Add getCurrentThreadCPUTime helper (cherry picked from commit cedd6f3041de6abe64dfa3257bec7730a9dced9f) - - - - - d1f9d711 by Ben Gamari at 2020-05-24T20:42:31-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) - - - - - 39f3b172 by Ben Gamari at 2020-05-24T20:42:31-04:00 nonmoving-gc: Track time usage of nonmoving marking (cherry picked from commit ace618cd2294989e783bd453cee88e0e1c0dad77) - - - - - 35f50728 by Ben Gamari at 2020-05-24T20:42:31-04:00 nonmoving: Eagerly flush all capabilities' update remembered sets (cherry picked from commit 2fa79119570b358a4db61446396889b8260d7957) - - - - - dc26ba87 by Ben Gamari at 2020-05-24T20:42:31-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. - - - - - ce49860d by Ben Gamari at 2020-05-24T20:42:32-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. - - - - - 1101739a by Ben Gamari at 2020-05-24T20:42:32-04:00 hadrian: Allow libnuma library path to be specified - - - - - 6e8ede7e by Ben Gamari at 2020-05-24T20:42:32-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. - - - - - 185a870e by Ben Gamari at 2020-05-24T20:42:32-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. - - - - - 124a40cc by Ben Gamari at 2020-05-24T20:42:32-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. - - - - - b23f16d0 by Ben Gamari at 2020-05-24T20:42:32-04:00 nonmoving: Optimise the write barrier (cherry picked from commit a636eadac1f30bae37aeb6526f94893293f098b8) - - - - - d2581e98 by Ömer Sinan Ağacan at 2020-05-24T20:42:32-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) - - - - - 76059e3e by Simon Peyton Jones at 2020-05-24T20:42:32-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) - - - - - a7dd83db by Simon Peyton Jones at 2020-05-24T20:42:32-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) - - - - - e3fcf26d by Sylvain Henry at 2020-05-24T20:42:32-04:00 Rts: show errno on failure (#18033) (cherry picked from commit 4875d419ba066e479f7ac07f8b39ebe10c855859) - - - - - ba788d22 by Ryan Scott at 2020-05-24T20:42:32-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) - - - - - 25d84fa2 by Adam Gundry at 2020-05-24T20:42:32-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) - - - - - 646648a9 by Ben Gamari at 2020-05-24T20:42:32-04:00 Ensure that printMinimalImports closes handle Fixes #18166. (cherry picked from commit 5afc160dee7142c96a842037fb64bee1429ad9ec) - - - - - 123c386b by Ben Gamari at 2020-05-24T20:42:32-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) - - - - - 06f05573 by Ben Gamari at 2020-05-24T20:42:32-04:00 nonmoving: Optimise log2_ceil (cherry picked from commit 5f69016115414d0dd921e72f3edcd0b365966141) - - - - - dae01c10 by Ben Gamari at 2020-05-24T20:42:32-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) - - - - - 72218602 by Ben Gamari at 2020-05-24T20:42:32-04:00 users guide: Move eventlog documentation users guide (cherry picked from commit c560dd07f506810eaabae2f582491138aa224819) - - - - - 79da3ca2 by Ben Gamari at 2020-05-24T20:42:33-04:00 users guide: Add documentation for non-moving GC events (cherry picked from commit 02543d5ef9bd7a910fc9fece895780583ab9635a) - - - - - 30 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 - configure.ac - docs/users_guide/conf.py - docs/users_guide/eventlog-formats.rst - docs/users_guide/runtime_control.rst - 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/EventLogFormat.h - includes/rts/Time.h - libraries/base/GHC/Stats.hsc - rts/GetTime.h - rts/ProfHeap.c - rts/RtsFlags.c - rts/Stats.c - rts/Stats.h - rts/Updates.h - rts/linker/PEi386.c - rts/posix/GetTime.c - rts/posix/itimer/Pthread.c - rts/sm/BlockAlloc.c - rts/sm/Evac.c - rts/sm/GC.c The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/37956be4958a260c884a20e08ca3bf00a9622e6f...79da3ca28d12306e5bc073d2f1b7ba130e12cd99 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/37956be4958a260c884a20e08ca3bf00a9622e6f...79da3ca28d12306e5bc073d2f1b7ba130e12cd99 You're receiving 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 25 07:58:16 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Mon, 25 May 2020 03:58:16 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 6 commits: Revert "Specify kind variables for inferred kinds in base." Message-ID: <5ecb7a985ac07_6e2611c732a41326132@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 78ced966 by Ben Gamari at 2020-05-25T03:58:05-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. - - - - - ec3fbefa by Ben Gamari at 2020-05-25T03:58:05-04:00 Coverage: Drop redundant ad-hoc boot module check To determine whether the module is a boot module Coverage.addTicksToBinds was checking for a `boot` suffix in the module source filename. This is quite ad-hoc and shouldn't be necessary; the callsite in `deSugar` already checks that the module isn't a boot module. - - - - - 10b3b50e by Ben Gamari at 2020-05-25T03:58:05-04:00 Coverage: Make tickBoxCount strict This could otherwise easily cause a leak of (+) thunks. - - - - - 09434cdb by Ben Gamari at 2020-05-25T03:58:05-04:00 Coverage: Make ccIndices strict This just seems like a good idea. - - - - - e4ba9c58 by Ben Gamari at 2020-05-25T03:58:05-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. - - - - - 6819b29f by Ben Gamari at 2020-05-25T03:58:05-04:00 Coverage: Factor out addMixEntry - - - - - 22 changed files: - compiler/GHC/HsToCore/Coverage.hs - 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: ===================================== compiler/GHC/HsToCore/Coverage.hs ===================================== @@ -78,8 +78,7 @@ addTicksToBinds addTicksToBinds hsc_env mod mod_loc exports tyCons binds | let dflags = hsc_dflags hsc_env passes = coveragePasses dflags, not (null passes), - Just orig_file <- ml_hs_file mod_loc, - not ("boot" `isSuffixOf` orig_file) = do + Just orig_file <- ml_hs_file mod_loc = do let orig_file2 = guessSourceFile binds orig_file @@ -118,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) @@ -135,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_] @@ -1004,11 +1003,20 @@ addTickArithSeqInfo (FromThenTo e1 e2 e3) = (addTickLHsExpr e2) (addTickLHsExpr e3) -data TickTransState = TT { tickBoxCount:: Int +data TickTransState = TT { tickBoxCount:: !Int , mixEntries :: [MixEntry_] - , ccIndices :: CostCentreState + , 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 @@ -1028,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 $ @@ -1036,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. @@ -1202,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 @@ -1215,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 @@ -1240,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 _) ===================================== 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 #-} @@ -759,8 +757,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 @@ -775,8 +772,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 ) @@ -827,8 +823,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 @@ -856,8 +851,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 @@ -887,8 +881,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 @@ -929,9 +922,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 @@ -943,8 +935,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 @@ -956,8 +947,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 @@ -998,9 +988,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 @@ -1031,7 +1020,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#' @@ -1105,46 +1093,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 @@ -1155,27 +1134,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] @@ -1200,9 +1167,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] @@ -1342,9 +1306,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] @@ -1397,7 +1358,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 @@ -1530,16 +1490,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 @@ -1547,7 +1501,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/-/compare/9d0c233ef9dc98783d537bd45fb40d37fb55b079...6819b29f1a9255d5f62c57b85f1ab539330b3e3b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9d0c233ef9dc98783d537bd45fb40d37fb55b079...6819b29f1a9255d5f62c57b85f1ab539330b3e3b You're receiving 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 25 13:48:29 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Mon, 25 May 2020 09:48:29 -0400 Subject: [Git][ghc/ghc][master] Revert "Specify kind variables for inferred kinds in base." Message-ID: <5ecbccad8745e_6e263f9ed7508a7413883d4@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 013d7120 by Ben Gamari at 2020-05-25T09:48:17-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 #-} @@ -759,8 +757,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 @@ -775,8 +772,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 ) @@ -827,8 +823,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 @@ -856,8 +851,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 @@ -887,8 +881,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 @@ -929,9 +922,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 @@ -943,8 +935,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 @@ -956,8 +947,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 @@ -998,9 +988,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 @@ -1031,7 +1020,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#' @@ -1105,46 +1093,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 @@ -1155,27 +1134,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] @@ -1200,9 +1167,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] @@ -1342,9 +1306,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] @@ -1397,7 +1358,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 @@ -1530,16 +1490,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 @@ -1547,7 +1501,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/013d71204be44d660f01f8eb255db2d48b832421 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/013d71204be44d660f01f8eb255db2d48b832421 You're receiving 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 25 13:49:04 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Mon, 25 May 2020 09:49:04 -0400 Subject: [Git][ghc/ghc][master] 5 commits: Coverage: Drop redundant ad-hoc boot module check Message-ID: <5ecbccd05e8dd_6e263f9ee34e424413910b4@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 4c4312ed by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Drop redundant ad-hoc boot module check To determine whether the module is a boot module Coverage.addTicksToBinds was checking for a `boot` suffix in the module source filename. This is quite ad-hoc and shouldn't be necessary; the callsite in `deSugar` already checks that the module isn't a boot module. - - - - - 1abf3c84 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make tickBoxCount strict This could otherwise easily cause a leak of (+) thunks. - - - - - b2813750 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make ccIndices strict This just seems like a good idea. - - - - - 02e278eb by Ben Gamari at 2020-05-25T09:48:53-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. - - - - - b8c014ce by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Factor out addMixEntry - - - - - 1 changed file: - compiler/GHC/HsToCore/Coverage.hs Changes: ===================================== compiler/GHC/HsToCore/Coverage.hs ===================================== @@ -78,8 +78,7 @@ addTicksToBinds addTicksToBinds hsc_env mod mod_loc exports tyCons binds | let dflags = hsc_dflags hsc_env passes = coveragePasses dflags, not (null passes), - Just orig_file <- ml_hs_file mod_loc, - not ("boot" `isSuffixOf` orig_file) = do + Just orig_file <- ml_hs_file mod_loc = do let orig_file2 = guessSourceFile binds orig_file @@ -118,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) @@ -135,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_] @@ -1004,11 +1003,20 @@ addTickArithSeqInfo (FromThenTo e1 e2 e3) = (addTickLHsExpr e2) (addTickLHsExpr e3) -data TickTransState = TT { tickBoxCount:: Int +data TickTransState = TT { tickBoxCount:: !Int , mixEntries :: [MixEntry_] - , ccIndices :: CostCentreState + , 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 @@ -1028,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 $ @@ -1036,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. @@ -1202,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 @@ -1215,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 @@ -1240,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/013d71204be44d660f01f8eb255db2d48b832421...b8c014ce27c279e0d506d5391a4e9bfa7f1c31f2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/013d71204be44d660f01f8eb255db2d48b832421...b8c014ce27c279e0d506d5391a4e9bfa7f1c31f2 You're receiving 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 25 15:43:03 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Mon, 25 May 2020 11:43:03 -0400 Subject: [Git][ghc/ghc][wip/andreask/xchg_primop] winio: Add Atomic Exchange PrimOp and implement Atomic Ptr exchanges. Message-ID: <5ecbe787c8502_6e26c5c8abc14117e7@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/xchg_primop at Glasgow Haskell Compiler / GHC Commits: 317640b3 by Tamar Christina at 2020-05-25T17:42:50+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. - - - - - 27 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 - compiler/GHC/Utils/Panic/Plain.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_compile/all.T - + testsuite/tests/codeGen/should_compile/cg009.hs - testsuite/tests/codeGen/should_run/all.T - + testsuite/tests/codeGen/should_run/cgrun080.hs - + testsuite/tests/codeGen/should_run/cgrun080.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,16 @@ genCall (PrimTarget (MO_Cmpxchg _width)) retVar' <- doExprW targetTy $ ExtractV retVar 0 statement $ Store retVar' dstVar +genCall (PrimTarget (MO_Xchg _width)) [dst] [addr, val] = runStmtsDecls $ do + dstV <- getCmmRegW (CmmLocal dst) :: WriterT LlvmAccum LlvmM LlvmVar + addrVar <- exprToVarW addr + valVar <- exprToVarW val + let ptrTy = pLift $ getVarType valVar + ptrExpr = Cast LM_Inttoptr addrVar ptrTy + ptrVar <- doExprW ptrTy ptrExpr + resVar <- doExprW (getVarType valVar) (AtomicRMW LAO_Xchg ptrVar valVar SyncSeqCst) + statement $ Store resVar dstV + genCall (PrimTarget (MO_AtomicWrite _width)) [] [addr, val] = runStmtsDecls $ do addrVar <- exprToVarW addr valVar <- exprToVarW val @@ -856,6 +866,7 @@ cmmPrimOpFunctions mop = do MO_AtomicRMW _ _ -> unsupported MO_AtomicWrite _ -> unsupported MO_Cmpxchg _ -> unsupported + MO_Xchg _ -> unsupported -- | Tail function calls genJump :: CmmExpr -> [GlobalReg] -> LlvmM StmtData @@ -1943,10 +1954,10 @@ toIWord platform = mkIntLit (llvmWord platform) -- | Error functions -panic :: String -> a +panic :: HasDebugCallStack => String -> a panic s = Outputable.panic $ "GHC.CmmToLlvm.CodeGen." ++ s -pprPanic :: String -> SDoc -> a +pprPanic :: HasDebugCallStack => String -> SDoc -> a pprPanic s d = Outputable.pprPanic ("GHC.CmmToLlvm.CodeGen." ++ s) d ===================================== 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 ===================================== compiler/GHC/Utils/Panic/Plain.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE CPP, ScopedTypeVariables, LambdaCase #-} +{-# LANGUAGE ConstraintKinds, KindSignatures #-} -- | Defines a simple exception type and utilities to throw it. The -- 'PlainGhcException' type is a subset of the 'Panic.GhcException' @@ -33,6 +34,7 @@ import GHC.Stack import GHC.Prelude import System.Environment import System.IO.Unsafe +import Data.Kind (Constraint) -- | This type is very similar to 'Panic.GhcException', but it omits -- the constructors that involve pretty-printing via @@ -110,13 +112,22 @@ showPlainGhcException = throwPlainGhcException :: PlainGhcException -> a throwPlainGhcException = Exception.throw +-- | A call stack constraint, but only when 'isDebugOn'. +-- Redefined here to avoid import cycles. +#if defined(DEBUG) +type HasDebugCallStack = HasCallStack +#else +type HasDebugCallStack = (() :: Constraint) +#endif + -- | Panics and asserts. -panic, sorry, pgmError :: String -> a +panic, sorry, pgmError :: HasDebugCallStack => String -> a panic x = unsafeDupablePerformIO $ do stack <- ccsToStrings =<< getCurrentCCS x + let strCallStack = prettyCallStack callStack if null stack - then throwPlainGhcException (PlainPanic x) - else throwPlainGhcException (PlainPanic (x ++ '\n' : renderStack stack)) + then throwPlainGhcException (PlainPanic (x ++ "\n" ++ strCallStack)) + else throwPlainGhcException (PlainPanic (x ++ "\n" ++ strCallStack ++ "\n" ++ renderStack stack)) sorry x = throwPlainGhcException (PlainSorry x) pgmError x = throwPlainGhcException (PlainProgramError x) ===================================== 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_compile/all.T ===================================== @@ -6,6 +6,7 @@ test('cg005', only_ways(['optasm']), compile, ['']) test('cg006', normal, compile, ['']) test('cg007', normal, compile, ['']) test('cg008', normal, compile, ['']) +test('cg009', normal, compile, ['']) test('T1916', normal, compile, ['']) test('T2388', normal, compile, ['']) ===================================== testsuite/tests/codeGen/should_compile/cg009.hs ===================================== @@ -0,0 +1,11 @@ +{-# LANGUAGE CPP, MagicHash, BlockArguments, UnboxedTuples #-} + +-- Tests compilation for interlockedExchange primop. + +module M where + +import GHC.Exts (interlockedExchangeInt#, Int#, Addr#, State# ) + +swap :: Addr# -> Int# -> State# s -> (# #) +swap ptr val s = case (interlockedExchangeInt# ptr val s) of + (# s2, old_val #) -> (# #) ===================================== testsuite/tests/codeGen/should_run/all.T ===================================== @@ -90,6 +90,7 @@ test('cgrun076', normal, compile_and_run, ['']) test('cgrun077', [when(have_cpu_feature('bmi2'), extra_hc_opts('-mbmi2'))], compile_and_run, ['']) test('cgrun078', omit_ways(['ghci']), compile_and_run, ['']) test('cgrun079', normal, compile_and_run, ['']) +test('cgrun080', normal, compile_and_run, ['']) test('T1852', normal, compile_and_run, ['']) test('T1861', extra_run_opts('0'), compile_and_run, ['']) ===================================== testsuite/tests/codeGen/should_run/cgrun080.hs ===================================== @@ -0,0 +1,51 @@ +{-# LANGUAGE CPP, MagicHash, BlockArguments, UnboxedTuples #-} + +-- Test 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/cgrun080.stdout ===================================== @@ -0,0 +1 @@ +[1,2,3] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/317640b3477c3dc94dc513a733c763dbc4ea68ec -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/317640b3477c3dc94dc513a733c763dbc4ea68ec You're receiving 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 25 15:44:31 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Mon, 25 May 2020 11:44:31 -0400 Subject: [Git][ghc/ghc][wip/andreask/xchg_primop] winio: Add Atomic Exchange PrimOp and implement Atomic Ptr exchanges. Message-ID: <5ecbe7df26f8e_6e263f9f01f3c4801412331@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/xchg_primop at Glasgow Haskell Compiler / GHC Commits: 2c76f51f by Tamar Christina at 2020-05-25T17:43: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. Co-authored-by: Andreas Klebinger <klebinger.andreas at gmx.at> - - - - - 27 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 - compiler/GHC/Utils/Panic/Plain.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_compile/all.T - + testsuite/tests/codeGen/should_compile/cg009.hs - testsuite/tests/codeGen/should_run/all.T - + testsuite/tests/codeGen/should_run/cgrun080.hs - + testsuite/tests/codeGen/should_run/cgrun080.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,16 @@ genCall (PrimTarget (MO_Cmpxchg _width)) retVar' <- doExprW targetTy $ ExtractV retVar 0 statement $ Store retVar' dstVar +genCall (PrimTarget (MO_Xchg _width)) [dst] [addr, val] = runStmtsDecls $ do + dstV <- getCmmRegW (CmmLocal dst) :: WriterT LlvmAccum LlvmM LlvmVar + addrVar <- exprToVarW addr + valVar <- exprToVarW val + let ptrTy = pLift $ getVarType valVar + ptrExpr = Cast LM_Inttoptr addrVar ptrTy + ptrVar <- doExprW ptrTy ptrExpr + resVar <- doExprW (getVarType valVar) (AtomicRMW LAO_Xchg ptrVar valVar SyncSeqCst) + statement $ Store resVar dstV + genCall (PrimTarget (MO_AtomicWrite _width)) [] [addr, val] = runStmtsDecls $ do addrVar <- exprToVarW addr valVar <- exprToVarW val @@ -856,6 +866,7 @@ cmmPrimOpFunctions mop = do MO_AtomicRMW _ _ -> unsupported MO_AtomicWrite _ -> unsupported MO_Cmpxchg _ -> unsupported + MO_Xchg _ -> unsupported -- | Tail function calls genJump :: CmmExpr -> [GlobalReg] -> LlvmM StmtData @@ -1943,10 +1954,10 @@ toIWord platform = mkIntLit (llvmWord platform) -- | Error functions -panic :: String -> a +panic :: HasDebugCallStack => String -> a panic s = Outputable.panic $ "GHC.CmmToLlvm.CodeGen." ++ s -pprPanic :: String -> SDoc -> a +pprPanic :: HasDebugCallStack => String -> SDoc -> a pprPanic s d = Outputable.pprPanic ("GHC.CmmToLlvm.CodeGen." ++ s) d ===================================== 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 ===================================== compiler/GHC/Utils/Panic/Plain.hs ===================================== @@ -1,4 +1,5 @@ {-# LANGUAGE CPP, ScopedTypeVariables, LambdaCase #-} +{-# LANGUAGE ConstraintKinds, KindSignatures #-} -- | Defines a simple exception type and utilities to throw it. The -- 'PlainGhcException' type is a subset of the 'Panic.GhcException' @@ -33,6 +34,7 @@ import GHC.Stack import GHC.Prelude import System.Environment import System.IO.Unsafe +import Data.Kind (Constraint) -- | This type is very similar to 'Panic.GhcException', but it omits -- the constructors that involve pretty-printing via @@ -110,13 +112,22 @@ showPlainGhcException = throwPlainGhcException :: PlainGhcException -> a throwPlainGhcException = Exception.throw +-- | A call stack constraint, but only when 'isDebugOn'. +-- Redefined here to avoid import cycles. +#if defined(DEBUG) +type HasDebugCallStack = HasCallStack +#else +type HasDebugCallStack = (() :: Constraint) +#endif + -- | Panics and asserts. -panic, sorry, pgmError :: String -> a +panic, sorry, pgmError :: HasDebugCallStack => String -> a panic x = unsafeDupablePerformIO $ do stack <- ccsToStrings =<< getCurrentCCS x + let strCallStack = prettyCallStack callStack if null stack - then throwPlainGhcException (PlainPanic x) - else throwPlainGhcException (PlainPanic (x ++ '\n' : renderStack stack)) + then throwPlainGhcException (PlainPanic (x ++ "\n" ++ strCallStack)) + else throwPlainGhcException (PlainPanic (x ++ "\n" ++ strCallStack ++ "\n" ++ renderStack stack)) sorry x = throwPlainGhcException (PlainSorry x) pgmError x = throwPlainGhcException (PlainProgramError x) ===================================== 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_compile/all.T ===================================== @@ -6,6 +6,7 @@ test('cg005', only_ways(['optasm']), compile, ['']) test('cg006', normal, compile, ['']) test('cg007', normal, compile, ['']) test('cg008', normal, compile, ['']) +test('cg009', normal, compile, ['']) test('T1916', normal, compile, ['']) test('T2388', normal, compile, ['']) ===================================== testsuite/tests/codeGen/should_compile/cg009.hs ===================================== @@ -0,0 +1,11 @@ +{-# LANGUAGE CPP, MagicHash, BlockArguments, UnboxedTuples #-} + +-- Tests compilation for interlockedExchange primop. + +module M where + +import GHC.Exts (interlockedExchangeInt#, Int#, Addr#, State# ) + +swap :: Addr# -> Int# -> State# s -> (# #) +swap ptr val s = case (interlockedExchangeInt# ptr val s) of + (# s2, old_val #) -> (# #) ===================================== testsuite/tests/codeGen/should_run/all.T ===================================== @@ -90,6 +90,7 @@ test('cgrun076', normal, compile_and_run, ['']) test('cgrun077', [when(have_cpu_feature('bmi2'), extra_hc_opts('-mbmi2'))], compile_and_run, ['']) test('cgrun078', omit_ways(['ghci']), compile_and_run, ['']) test('cgrun079', normal, compile_and_run, ['']) +test('cgrun080', normal, compile_and_run, ['']) test('T1852', normal, compile_and_run, ['']) test('T1861', extra_run_opts('0'), compile_and_run, ['']) ===================================== testsuite/tests/codeGen/should_run/cgrun080.hs ===================================== @@ -0,0 +1,51 @@ +{-# LANGUAGE CPP, MagicHash, BlockArguments, UnboxedTuples #-} + +-- Test 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/cgrun080.stdout ===================================== @@ -0,0 +1 @@ +[1,2,3] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2c76f51fac5711fe1019e0944351cff063894fea -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2c76f51fac5711fe1019e0944351cff063894fea You're receiving 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 25 15:51:48 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Mon, 25 May 2020 11:51:48 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 9 commits: Revert "Specify kind variables for inferred kinds in base." Message-ID: <5ecbe994739fe_6e263f9f00579e08141632c@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 013d7120 by Ben Gamari at 2020-05-25T09:48:17-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. - - - - - 4c4312ed by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Drop redundant ad-hoc boot module check To determine whether the module is a boot module Coverage.addTicksToBinds was checking for a `boot` suffix in the module source filename. This is quite ad-hoc and shouldn't be necessary; the callsite in `deSugar` already checks that the module isn't a boot module. - - - - - 1abf3c84 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make tickBoxCount strict This could otherwise easily cause a leak of (+) thunks. - - - - - b2813750 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make ccIndices strict This just seems like a good idea. - - - - - 02e278eb by Ben Gamari at 2020-05-25T09:48:53-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. - - - - - b8c014ce by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Factor out addMixEntry - - - - - d3db2111 by Zubin Duggal at 2020-05-25T11:51:32-04:00 Add info about typeclass evidence to .hie files See `testsuite/tests/hiefile/should_run/HieQueries.hs` and `testsuite/tests/hiefile/should_run/HieQueries.stdout` for an example of this We add two new fields, `EvidenceVarBind` and `EvidenceVarUse` to the `ContextInfo` associated with an Identifier. These are associated with the appropriate identifiers for the evidence variables collected when we come across `HsWrappers`, `TcEvBinds` and `IPBinds` while traversing the AST. Instance dictionary and superclass selector dictionaries from `tcg_insts` and classes defined in `tcg_tcs` are also recorded in the AST as originating from their definition span This allows us to save a complete picture of the evidence constructed by the constraint solver, and will let us report this to the user, enabling features like going to the instance definition from the invocation of a class method(or any other method taking a constraint) and finding all usages of a particular instance. Additionally, - Mark NodeInfo with an origin so we can differentiate between bindings origininating in the source vs those in ghc - Along with typeclass evidence info, also include information on Implicit Parameters - Add a few utility functions to HieUtils in order to query the new info Updates haddock submodule - - - - - 1b76464b by Sebastian Graf at 2020-05-25T11:51:34-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. - - - - - c68ae868 by Sylvain Henry at 2020-05-25T11:51:41-04:00 Enhance Note [About units] for Backpack - - - - - 30 changed files: - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/HsToCore/Coverage.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Debug.hs - compiler/GHC/Iface/Ext/Types.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Unit.hs - docs/users_guide/using-optimisation.rst - 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/hiefile/should_compile/Scopes.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6819b29f1a9255d5f62c57b85f1ab539330b3e3b...c68ae868ac09e2904a4c724fdbd6bbcce7fcc725 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6819b29f1a9255d5f62c57b85f1ab539330b3e3b...c68ae868ac09e2904a4c724fdbd6bbcce7fcc725 You're receiving 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 25 16:55:41 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Mon, 25 May 2020 12:55:41 -0400 Subject: [Git][ghc/ghc][wip/T18086] 23 commits: docs: fix formatting and add some links Message-ID: <5ecbf88d6d1bb_6e2687ddb08144326f@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/T18086 at Glasgow Haskell Compiler / GHC Commits: d830bbc9 by Adam Sandberg Ericsson at 2020-05-23T13:36:20-04:00 docs: fix formatting and add some links [skip ci] - - - - - 49301ad6 by Andrew Martin at 2020-05-23T13:37:01-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. - - - - - dcd6bdcc by Ben Gamari at 2020-05-23T13:37:48-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. - - - - - 82cb8913 by John Ericson at 2020-05-23T13:38:32-04:00 Fix #18145 and also avoid needless work with implicit vars - `forAllOrNothing` now is monadic, so we can trace whether we bind an explicit `forall` or not. - #18145 arose because the free vars calculation was needlessly complex. It is now greatly simplified. - Replaced some other implicit var code with `filterFreeVarsToBind`. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - a60dc835 by Ben Gamari at 2020-05-23T13:39:12-04:00 Bump process submodule Fixes #17926. - - - - - 856adf54 by Ben Gamari at 2020-05-23T13:40:21-04:00 users-guide: Clarify meaning of -haddock flag Fixes #18206. - - - - - 7ae57afd by Ben Gamari at 2020-05-23T13:41:03-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 - - - - - 63d30e60 by jneira at 2020-05-24T01:54:42-04:00 Add hie-bios script for windows systems It is a direct translation of the sh script - - - - - 59182b88 by jneira at 2020-05-24T01:54:42-04:00 Honour previous values for CABAL and CABFLAGS The immediate goal is let the hie-bios.bat script set CABFLAGS with `-v0` and remove all cabal output except the compiler arguments - - - - - 932dc54e by jneira at 2020-05-24T01:54:42-04:00 Add specific configuration for windows in hie.yaml - - - - - e0eda070 by jneira at 2020-05-24T01:54:42-04:00 Remove not needed hie-bios output - - - - - a0ea59d6 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Move Config module into GHC.Settings - - - - - 37430251 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Core.Arity into GHC.Core.Opt.Arity - - - - - a426abb9 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Hs.Types into GHC.Hs.Type See discussion in https://gitlab.haskell.org/ghc/ghc/issues/13009#note_268610 - - - - - 1c91a7a0 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Bump haddock submodule - - - - - 66bd24d1 by Ryan Scott at 2020-05-24T01:56:03-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. - - - - - 01c43634 by Matthew Pickering at 2020-05-24T01:56:42-04:00 Remove unused hs-boot file - - - - - 7a07aa71 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix cross-compiler build (#16051) - - - - - 15ccca16 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix distDir per stage - - - - - b420fb24 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix hp2ps error during cross-compilation Fixed by @alp (see https://gitlab.haskell.org/ghc/ghc/issues/16051#note_274265) - - - - - cd339ef0 by Joshua Price at 2020-05-24T15:22:56-04:00 Make Unicode brackets opening/closing tokens (#18225) The tokens `[|`, `|]`, `(|`, and `|)` are opening/closing tokens as described in GHC Proposal #229. This commit makes the unicode variants (`⟦`, `⟧`, `⦇`, and `⦈`) act the same as their ASCII counterparts. - - - - - 53b5cb9a by Sebastian Graf at 2020-05-25T18:55:18+02:00 FloatOut: Only eta-expand dead-end RHS if arity will increase (#18231) Otherwise we risk turning trivial RHS into non-trivial RHS, introducing unnecessary bindings in the next Simplifier run, resulting in more churn. Fixes #18231. - - - - - 7ec8ea61 by Sebastian Graf at 2020-05-25T18:55:24+02:00 DmdAnal: Recognise precise exceptions from case alternatives (#18086) Consider ```hs m :: IO () m = do putStrLn "foo" error "bar" ``` `m` (from #18086) always throws a (precise or imprecise) exception or diverges. Yet demand analysis infers `<L,A>` as demand signature instead of `<L,A>x` for it. That's because the demand analyser sees `putStrLn` occuring in a case scrutinee and decides that it has to `deferAfterPreciseException`, because `putStrLn` throws a precise exception on some control flow paths. This will mask the `botDiv` `Divergence`of the single case alt containing `error` to `topDiv`. Since `putStrLn` has `topDiv` itself, the final `Divergence` is `topDiv`. This is easily fixed: `deferAfterPreciseException` works by `lub`ing with the demand type of a virtual case branch denoting the precise exceptional control flow. We used `nopDmdType` before, but we can be more precise and use `exnDmdType`, which is `nopDmdType` with `exnDiv`. Now the `Divergence` from the case alt will degrade `botDiv` to `exnDiv` instead of `topDiv`, which combines with the result from the scrutinee to `exnDiv`, and all is well. Fixes #18086. - - - - - 30 changed files: - + .git-ignore-revs - compiler/GHC/Builtin/Names.hs - − compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Types.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Arity.hs → compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatOut.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/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Expr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5205b85a058b0ae88a76cba9932b159da9296511...7ec8ea61215e66e5513a284b9395ad5e2c639d98 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5205b85a058b0ae88a76cba9932b159da9296511...7ec8ea61215e66e5513a284b9395ad5e2c639d98 You're receiving 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 25 17:29:16 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 25 May 2020 13:29:16 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18232 Message-ID: <5ecc006cab30c_6e263f9ed7508a74144847f@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/T18232 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18232 You're receiving 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 25 17:41:14 2020 From: gitlab at gitlab.haskell.org (Vladislav Zavialov) Date: Mon, 25 May 2020 13:41:14 -0400 Subject: [Git][ghc/ghc][wip/t18123] 123 commits: Remove custom ExceptionMonad class (#18075) (updating haddock submodule accordingly) Message-ID: <5ecc033aa5a6b_6e26c5c8abc1451897@gitlab.haskell.org.mail> Vladislav Zavialov pushed to branch wip/t18123 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. - - - - - 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. - - - - - 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] - - - - - 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 - - - - - 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 - - - - - 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. - - - - - 78c6523c by Ben Gamari at 2020-05-21T12:13:01-04:00 nonmoving: Optimise the write barrier - - - - - 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). - - - - - 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 - - - - - b7a6b2f4 by Gleb Popov at 2020-05-21T12:15:26-04:00 gitlab-ci: Set locale to C.UTF-8. - - - - - 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. - - - - - 0004ccb8 by Tuan Le at 2020-05-21T12:16:46-04:00 llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 - - - - - 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 - - - - - 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 - - - - - 2b363ebb by Richard Eisenberg at 2020-05-21T12:18:45-04:00 MR template should ask for key part - - - - - a95bbd0b by Sebastian Graf at 2020-05-21T12:19:37-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. - - - - - d3d055b8 by Galen Huntington at 2020-05-21T12:20:18-04:00 Clarify pitfalls of NegativeLiterals; see #18022. - - - - - 1b508a9e by Alexey Kuleshevich at 2020-05-21T12:21:02-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" - - - - - 4ca0c8a1 by Andreas Klebinger at 2020-05-21T12:21: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. - - - - - a1275081 by Krzysztof Gogolewski at 2020-05-21T12:22:35-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 - - - - - 8a816e5f by Krzysztof Gogolewski at 2020-05-21T12:23:55-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. - - - - - 566cc73f by Sylvain Henry at 2020-05-21T12:24:45-04:00 Move isDynLinkName into GHC.Types.Name It doesn't belong into GHC.Unit.State - - - - - d830bbc9 by Adam Sandberg Ericsson at 2020-05-23T13:36:20-04:00 docs: fix formatting and add some links [skip ci] - - - - - 49301ad6 by Andrew Martin at 2020-05-23T13:37:01-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. - - - - - dcd6bdcc by Ben Gamari at 2020-05-23T13:37:48-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. - - - - - 82cb8913 by John Ericson at 2020-05-23T13:38:32-04:00 Fix #18145 and also avoid needless work with implicit vars - `forAllOrNothing` now is monadic, so we can trace whether we bind an explicit `forall` or not. - #18145 arose because the free vars calculation was needlessly complex. It is now greatly simplified. - Replaced some other implicit var code with `filterFreeVarsToBind`. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - a60dc835 by Ben Gamari at 2020-05-23T13:39:12-04:00 Bump process submodule Fixes #17926. - - - - - 856adf54 by Ben Gamari at 2020-05-23T13:40:21-04:00 users-guide: Clarify meaning of -haddock flag Fixes #18206. - - - - - 7ae57afd by Ben Gamari at 2020-05-23T13:41:03-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 - - - - - 63d30e60 by jneira at 2020-05-24T01:54:42-04:00 Add hie-bios script for windows systems It is a direct translation of the sh script - - - - - 59182b88 by jneira at 2020-05-24T01:54:42-04:00 Honour previous values for CABAL and CABFLAGS The immediate goal is let the hie-bios.bat script set CABFLAGS with `-v0` and remove all cabal output except the compiler arguments - - - - - 932dc54e by jneira at 2020-05-24T01:54:42-04:00 Add specific configuration for windows in hie.yaml - - - - - e0eda070 by jneira at 2020-05-24T01:54:42-04:00 Remove not needed hie-bios output - - - - - a0ea59d6 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Move Config module into GHC.Settings - - - - - 37430251 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Core.Arity into GHC.Core.Opt.Arity - - - - - a426abb9 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Hs.Types into GHC.Hs.Type See discussion in https://gitlab.haskell.org/ghc/ghc/issues/13009#note_268610 - - - - - 1c91a7a0 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Bump haddock submodule - - - - - 66bd24d1 by Ryan Scott at 2020-05-24T01:56:03-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. - - - - - 01c43634 by Matthew Pickering at 2020-05-24T01:56:42-04:00 Remove unused hs-boot file - - - - - 7a07aa71 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix cross-compiler build (#16051) - - - - - 15ccca16 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix distDir per stage - - - - - b420fb24 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix hp2ps error during cross-compilation Fixed by @alp (see https://gitlab.haskell.org/ghc/ghc/issues/16051#note_274265) - - - - - cd339ef0 by Joshua Price at 2020-05-24T15:22:56-04:00 Make Unicode brackets opening/closing tokens (#18225) The tokens `[|`, `|]`, `(|`, and `|)` are opening/closing tokens as described in GHC Proposal #229. This commit makes the unicode variants (`⟦`, `⟧`, `⦇`, and `⦈`) act the same as their ASCII counterparts. - - - - - 013d7120 by Ben Gamari at 2020-05-25T09:48:17-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. - - - - - 4c4312ed by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Drop redundant ad-hoc boot module check To determine whether the module is a boot module Coverage.addTicksToBinds was checking for a `boot` suffix in the module source filename. This is quite ad-hoc and shouldn't be necessary; the callsite in `deSugar` already checks that the module isn't a boot module. - - - - - 1abf3c84 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make tickBoxCount strict This could otherwise easily cause a leak of (+) thunks. - - - - - b2813750 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make ccIndices strict This just seems like a good idea. - - - - - 02e278eb by Ben Gamari at 2020-05-25T09:48:53-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. - - - - - b8c014ce by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Factor out addMixEntry - - - - - ca4097c3 by Vladislav Zavialov at 2020-05-25T20:41:00+03:00 Add Semigroup/Monoid for Q (#18123) - - - - - 30 changed files: - + .git-ignore-revs - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/merge_request_templates/merge-request.md - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - − compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/PPC/Cond.hs - compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b4d771c3d750840fc7a7d20bda9119f20f65f39c...ca4097c39210676d1c42e81dae177b1bcfd8b5c4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b4d771c3d750840fc7a7d20bda9119f20f65f39c...ca4097c39210676d1c42e81dae177b1bcfd8b5c4 You're receiving 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 25 18:01:05 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 25 May 2020 14:01:05 -0400 Subject: [Git][ghc/ghc][wip/T18210] eventlog: Fix racy flushing Message-ID: <5ecc07e144fa9_6e263f9ee352230014532d4@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18210 at Glasgow Haskell Compiler / GHC Commits: ed97b68e by Ben Gamari at 2020-05-25T14:00:58-04:00 eventlog: Fix racy flushing Previously no attempt was made to avoid multiple threads writing their capability-local eventlog buffers to the eventlog writer simultaneously. This could result in multiple eventlog streams being interleaved. Fix this by documenting that the EventLogWriter's write() and flush() functions may be called reentrantly and fix the default writer to protect its FILE* by a mutex. Fixes #18210. - - - - - 3 changed files: - docs/users_guide/runtime_control.rst - includes/rts/EventLogWriter.h - rts/eventlog/EventLogWriter.c Changes: ===================================== docs/users_guide/runtime_control.rst ===================================== @@ -196,11 +196,17 @@ Furthermore GHC lets you specify the way event log data (see :rts-flag:`-l Hands buffered event log data to your event log writer. Return true on success. Required for a custom :c:type:`EventLogWriter`. + Note that this function may be called by multiple threads + simultaneously. + .. c:member:: void flushEventLog(void) Flush buffers (if any) of your custom :c:type:`EventLogWriter`. This can be ``NULL``. + Note that this function may be called by multiple threads + simultaneously. + .. c:member:: void stopEventLogWriter(void) Called when event logging is about to stop. This can be ``NULL``. ===================================== includes/rts/EventLogWriter.h ===================================== @@ -24,9 +24,13 @@ typedef struct { void (* initEventLogWriter) (void); // Write a series of events returning true on success. + // Note that this may be called by multiple threads simultaneously. + // The writer is responsible for concurrency control. bool (* writeEventLog) (void *eventlog, size_t eventlog_size); // Flush possibly existing buffers (may be NULL) + // Note that this may be called by multiple threads simultaneously. + // The writer is responsible for concurrency control. void (* flushEventLog) (void); // Close an initialized EventLogOutput (may be NULL) ===================================== rts/eventlog/EventLogWriter.c ===================================== @@ -28,6 +28,17 @@ static pid_t event_log_pid = -1; // File for logging events static FILE *event_log_file = NULL; +#if defined(THREADED_RTS) +// Protects event_log_file +static Mutex event_log_mutex; + +static void acquire_event_log_lock(void) { ACQUIRE_LOCK(&event_log_mutex); } +static void release_event_log_lock(void) { RELEASE_LOCK(&event_log_mutex); } +#else +static void acquire_event_log_lock(void) {} +static void release_event_log_lock(void) {} +#endif + static void initEventLogFileWriter(void); static bool writeEventLogFile(void *eventlog, size_t eventlog_size); static void flushEventLogFile(void); @@ -89,6 +100,9 @@ initEventLogFileWriter(void) } stgFree(event_log_filename); +#if defined(THREADED_RTS) + initMutex(&event_log_mutex); +#endif } static bool @@ -97,15 +111,17 @@ writeEventLogFile(void *eventlog, size_t eventlog_size) unsigned char *begin = eventlog; size_t remain = eventlog_size; + acquire_event_log_lock(); while (remain > 0) { size_t written = fwrite(begin, 1, remain, event_log_file); if (written == 0) { + release_event_log_lock(); return false; } remain -= written; begin += written; } - + release_event_log_lock(); return true; } @@ -124,6 +140,9 @@ stopEventLogFileWriter(void) fclose(event_log_file); event_log_file = NULL; } +#if defined(THREADED_RTS) + closeMutex(&event_log_mutex); +#endif } const EventLogWriter FileEventLogWriter = { View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ed97b68edf9396c1355d012dc510d340f3489383 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ed97b68edf9396c1355d012dc510d340f3489383 You're receiving 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 25 18:03:16 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 25 May 2020 14:03:16 -0400 Subject: [Git][ghc/ghc][wip/bump-base] 28 commits: docs: fix formatting and add some links Message-ID: <5ecc08644fc0_6e263f9ed71435d81453624@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/bump-base at Glasgow Haskell Compiler / GHC Commits: d830bbc9 by Adam Sandberg Ericsson at 2020-05-23T13:36:20-04:00 docs: fix formatting and add some links [skip ci] - - - - - 49301ad6 by Andrew Martin at 2020-05-23T13:37:01-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. - - - - - dcd6bdcc by Ben Gamari at 2020-05-23T13:37:48-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. - - - - - 82cb8913 by John Ericson at 2020-05-23T13:38:32-04:00 Fix #18145 and also avoid needless work with implicit vars - `forAllOrNothing` now is monadic, so we can trace whether we bind an explicit `forall` or not. - #18145 arose because the free vars calculation was needlessly complex. It is now greatly simplified. - Replaced some other implicit var code with `filterFreeVarsToBind`. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - a60dc835 by Ben Gamari at 2020-05-23T13:39:12-04:00 Bump process submodule Fixes #17926. - - - - - 856adf54 by Ben Gamari at 2020-05-23T13:40:21-04:00 users-guide: Clarify meaning of -haddock flag Fixes #18206. - - - - - 7ae57afd by Ben Gamari at 2020-05-23T13:41:03-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 - - - - - 63d30e60 by jneira at 2020-05-24T01:54:42-04:00 Add hie-bios script for windows systems It is a direct translation of the sh script - - - - - 59182b88 by jneira at 2020-05-24T01:54:42-04:00 Honour previous values for CABAL and CABFLAGS The immediate goal is let the hie-bios.bat script set CABFLAGS with `-v0` and remove all cabal output except the compiler arguments - - - - - 932dc54e by jneira at 2020-05-24T01:54:42-04:00 Add specific configuration for windows in hie.yaml - - - - - e0eda070 by jneira at 2020-05-24T01:54:42-04:00 Remove not needed hie-bios output - - - - - a0ea59d6 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Move Config module into GHC.Settings - - - - - 37430251 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Core.Arity into GHC.Core.Opt.Arity - - - - - a426abb9 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Hs.Types into GHC.Hs.Type See discussion in https://gitlab.haskell.org/ghc/ghc/issues/13009#note_268610 - - - - - 1c91a7a0 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Bump haddock submodule - - - - - 66bd24d1 by Ryan Scott at 2020-05-24T01:56:03-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. - - - - - 01c43634 by Matthew Pickering at 2020-05-24T01:56:42-04:00 Remove unused hs-boot file - - - - - 7a07aa71 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix cross-compiler build (#16051) - - - - - 15ccca16 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix distDir per stage - - - - - b420fb24 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix hp2ps error during cross-compilation Fixed by @alp (see https://gitlab.haskell.org/ghc/ghc/issues/16051#note_274265) - - - - - cd339ef0 by Joshua Price at 2020-05-24T15:22:56-04:00 Make Unicode brackets opening/closing tokens (#18225) The tokens `[|`, `|]`, `(|`, and `|)` are opening/closing tokens as described in GHC Proposal #229. This commit makes the unicode variants (`⟦`, `⟧`, `⦇`, and `⦈`) act the same as their ASCII counterparts. - - - - - 013d7120 by Ben Gamari at 2020-05-25T09:48:17-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. - - - - - 4c4312ed by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Drop redundant ad-hoc boot module check To determine whether the module is a boot module Coverage.addTicksToBinds was checking for a `boot` suffix in the module source filename. This is quite ad-hoc and shouldn't be necessary; the callsite in `deSugar` already checks that the module isn't a boot module. - - - - - 1abf3c84 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make tickBoxCount strict This could otherwise easily cause a leak of (+) thunks. - - - - - b2813750 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make ccIndices strict This just seems like a good idea. - - - - - 02e278eb by Ben Gamari at 2020-05-25T09:48:53-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. - - - - - b8c014ce by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Factor out addMixEntry - - - - - 4563e58c by Ben Gamari at 2020-05-25T14:03:05-04:00 base: Bump to 4.15.0.0 - - - - - 30 changed files: - + .git-ignore-revs - compiler/GHC/Builtin/Names.hs - − compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Types.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Arity.hs → compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatOut.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/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/FastString.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Expr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3c47cf2c2eabce3faf1bb185487bbbbe35d49635...4563e58c4fe8c352d0d7466dcd55d4636bb0653c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3c47cf2c2eabce3faf1bb185487bbbbe35d49635...4563e58c4fe8c352d0d7466dcd55d4636bb0653c You're receiving 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 25 18:04:30 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 25 May 2020 14:04:30 -0400 Subject: [Git][ghc/ghc][wip/bump-base] base: Bump to 4.15.0.0 Message-ID: <5ecc08ae18346_6e263f9ed71435d8145419d@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/bump-base at Glasgow Haskell Compiler / GHC Commits: 4c155fbe by Ben Gamari at 2020-05-25T14:04:24-04:00 base: Bump to 4.15.0.0 - - - - - 17 changed files: - libraries/array - libraries/base/base.cabal - libraries/deepseq - libraries/directory - libraries/filepath - libraries/ghc-boot-th/ghc-boot-th.cabal.in - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghc-compact/ghc-compact.cabal - libraries/ghci/ghci.cabal.in - libraries/haskeline - libraries/hpc - libraries/parsec - libraries/process - libraries/stm - libraries/template-haskell/template-haskell.cabal.in - libraries/terminfo - libraries/unix Changes: ===================================== libraries/array ===================================== @@ -1 +1 @@ -Subproject commit f73f681e52546b1e35cb9e8a62fe49c33f259d98 +Subproject commit ab535173d7885ebfc2005d8da2765f0f52c923ce ===================================== 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 ===================================== libraries/deepseq ===================================== @@ -1 +1 @@ -Subproject commit da0eda33f540786b6823c6f542ab59cf9d1b71d9 +Subproject commit 13c1c84415da727ab56e9fa33aca5046b6683848 ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit 36bd1921258b759724a95ce56c5e880edf0972a2 +Subproject commit 0dcb228388a6e306c11f419c7c5575eaa6af40b3 ===================================== libraries/filepath ===================================== @@ -1 +1 @@ -Subproject commit 023eedaeb142d47b7b5a41fe4cc4150da0bd0042 +Subproject commit 7cb3dc285cd595a7b6cf0b74a58b6583fb67772e ===================================== libraries/ghc-boot-th/ghc-boot-th.cabal.in ===================================== @@ -36,4 +36,4 @@ Library GHC.ForeignSrcLang.Type GHC.Lexeme - build-depends: base >= 4.7 && < 4.15 + build-depends: base >= 4.7 && < 4.16 ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -55,7 +55,7 @@ Library -- GHC.Version -- GHC.Platform.Host - build-depends: base >= 4.7 && < 4.15, + build-depends: base >= 4.7 && < 4.16, binary == 0.8.*, bytestring == 0.10.*, containers >= 0.5 && < 0.7, ===================================== libraries/ghc-compact/ghc-compact.cabal ===================================== @@ -37,7 +37,7 @@ library CPP build-depends: ghc-prim >= 0.5.3 && < 0.7, - base >= 4.9.0 && < 4.15, + base >= 4.9.0 && < 4.16, bytestring >= 0.10.6.0 ghc-options: -Wall ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -72,7 +72,7 @@ library Build-Depends: array == 0.5.*, - base >= 4.8 && < 4.15, + base >= 4.8 && < 4.16, binary == 0.8.*, bytestring == 0.10.*, containers >= 0.5 && < 0.7, ===================================== libraries/haskeline ===================================== @@ -1 +1 @@ -Subproject commit 463fc49d17bfab846cceba48bccc02ef285e6cba +Subproject commit 0382e3acdb8433e1d9c33ca5947784e78134f838 ===================================== libraries/hpc ===================================== @@ -1 +1 @@ -Subproject commit f73c482db30a40cfa12074de51335b70a0974931 +Subproject commit 43bb9061a748aee6a95a9f1db33a2b1e5f770634 ===================================== libraries/parsec ===================================== @@ -1 +1 @@ -Subproject commit ce416997e15438ca616667995660e123ef7e219d +Subproject commit 190492494fe92e8dd42165190b7ac112be1f7389 ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit 1afc36ecd38c069251a836e1c1c8b3a3043ddc01 +Subproject commit 8f4ecebb6578a179a6c04074cb06600683e2e50c ===================================== libraries/stm ===================================== @@ -1 +1 @@ -Subproject commit faf9904137044e35a589c7c1579e1bfa03789c84 +Subproject commit 444f672416a354c3cfde9d94ec237a36be46ef59 ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -55,7 +55,7 @@ Library Language.Haskell.TH.Lib.Map build-depends: - base >= 4.11 && < 4.15, + base >= 4.11 && < 4.16, ghc-boot-th == @ProjectVersionMunged@, ghc-prim, pretty == 1.1.* ===================================== libraries/terminfo ===================================== @@ -1 +1 @@ -Subproject commit 27e694688d2d6eee69959a8b6a128c584c84aa72 +Subproject commit 3ebb36f4a2c42b74ec4e35efccc2be34c198a830 ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 1a993b89c570e03ba74f196f5d065a0ebe624010 +Subproject commit ea13d990580273a883368793dfbb826cab5a22d4 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4c155fbe5c932383ce958352a514a63e5cac7564 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/4c155fbe5c932383ce958352a514a63e5cac7564 You're receiving 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 25 18:05:01 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Mon, 25 May 2020 14:05:01 -0400 Subject: [Git][ghc/ghc][wip/T18191] 21 commits: Add hie-bios script for windows systems Message-ID: <5ecc08cd3bacd_6e263f9ed71435d814546f4@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T18191 at Glasgow Haskell Compiler / GHC Commits: 63d30e60 by jneira at 2020-05-24T01:54:42-04:00 Add hie-bios script for windows systems It is a direct translation of the sh script - - - - - 59182b88 by jneira at 2020-05-24T01:54:42-04:00 Honour previous values for CABAL and CABFLAGS The immediate goal is let the hie-bios.bat script set CABFLAGS with `-v0` and remove all cabal output except the compiler arguments - - - - - 932dc54e by jneira at 2020-05-24T01:54:42-04:00 Add specific configuration for windows in hie.yaml - - - - - e0eda070 by jneira at 2020-05-24T01:54:42-04:00 Remove not needed hie-bios output - - - - - a0ea59d6 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Move Config module into GHC.Settings - - - - - 37430251 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Core.Arity into GHC.Core.Opt.Arity - - - - - a426abb9 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Hs.Types into GHC.Hs.Type See discussion in https://gitlab.haskell.org/ghc/ghc/issues/13009#note_268610 - - - - - 1c91a7a0 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Bump haddock submodule - - - - - 66bd24d1 by Ryan Scott at 2020-05-24T01:56:03-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. - - - - - 01c43634 by Matthew Pickering at 2020-05-24T01:56:42-04:00 Remove unused hs-boot file - - - - - 7a07aa71 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix cross-compiler build (#16051) - - - - - 15ccca16 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix distDir per stage - - - - - b420fb24 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix hp2ps error during cross-compilation Fixed by @alp (see https://gitlab.haskell.org/ghc/ghc/issues/16051#note_274265) - - - - - cd339ef0 by Joshua Price at 2020-05-24T15:22:56-04:00 Make Unicode brackets opening/closing tokens (#18225) The tokens `[|`, `|]`, `(|`, and `|)` are opening/closing tokens as described in GHC Proposal #229. This commit makes the unicode variants (`⟦`, `⟧`, `⦇`, and `⦈`) act the same as their ASCII counterparts. - - - - - 013d7120 by Ben Gamari at 2020-05-25T09:48:17-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. - - - - - 4c4312ed by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Drop redundant ad-hoc boot module check To determine whether the module is a boot module Coverage.addTicksToBinds was checking for a `boot` suffix in the module source filename. This is quite ad-hoc and shouldn't be necessary; the callsite in `deSugar` already checks that the module isn't a boot module. - - - - - 1abf3c84 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make tickBoxCount strict This could otherwise easily cause a leak of (+) thunks. - - - - - b2813750 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make ccIndices strict This just seems like a good idea. - - - - - 02e278eb by Ben Gamari at 2020-05-25T09:48:53-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. - - - - - b8c014ce by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Factor out addMixEntry - - - - - 5d753721 by Ryan Scott at 2020-05-25T14:04:31-04:00 Make GADT constructors adhere to the forall-or-nothing rule properly Issue #18191 revealed that the types of GADT constructors don't quite adhere to the `forall`-or-nothing rule. This patch serves to clean up this sad state of affairs somewhat. The main change is not in the code itself, but in the documentation, as this patch introduces two sections to the GHC User's Guide: * A "Formal syntax for GADTs" section that presents a BNF-style grammar for what is and isn't allowed in GADT constructor types. This mostly exists to codify GHC's existing behavior, but it also imposes a new restriction that addresses #18191: the outermost `forall` and/or context in a GADT constructor is not allowed to be surrounded by parentheses. Doing so would make these `forall`s/contexts nested, and GADTs do not support nested `forall`s/contexts at present. * A "`forall`-or-nothing rule" section that describes exactly what the `forall`-or-nothing rule is all about. Surprisingly, there was no mention of this anywhere in the User's Guide up until now! To adhere the new specification in the "Formal syntax for GADTs" section of the User's Guide, the following code changes were made: * `GHC.Parser.PostProcess.mkGadtDecl` no longer strips away parentheses from the outermost `forall` and context. Instead, these parentheses are preserved so that the renamer can check for nested `forall`s/contexts later. See `Note [No nested foralls or contexts in GADT constructors]` in `GHC.Parser.PostProcess` for more details. One nice side effect of this change is that we can get rid of the explicit `AddAnn` tracking in `mkGadtDecl`, as we no longer need to remember the `AddAnn`s for stripped-away parentheses. * `GHC.Renamer.Module.rnConDecl` now checks for nested `forall`s/contexts, rather than checking for this in the typechcker (in `GHC.Tc.TyCl.badDataConTyCon`). For the most part, this code was ported directly from `badDataConTyCon`, but designed to work over `HsType`s instead of `Type`s. One nice side effect of this change is that we are able to give a more accurate error message for GADT constructors that use visible dependent quantification (e.g., `MkFoo :: forall a -> a -> Foo a`), which improves the stderr in the `T16326_Fail6` test case. Fixes #18191. - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - − compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Types.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Arity.hs → compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatOut.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/Specialise.hs - compiler/GHC/Core/Opt/WorkWrap.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Hs.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Types.hs → compiler/GHC/Hs/Type.hs - compiler/GHC/Hs/Utils.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0d54179051725461fa5a74cb80ed1e0880fb74b1...5d753721f9642a67d90c0a5e273b788a14163054 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0d54179051725461fa5a74cb80ed1e0880fb74b1...5d753721f9642a67d90c0a5e273b788a14163054 You're receiving 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 25 21:52:38 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Mon, 25 May 2020 17:52:38 -0400 Subject: [Git][ghc/ghc][wip/sjakobi/undeprecate-first-last] 161 commits: Switch order on `GhcMake.IsBoot` Message-ID: <5ecc3e2664bcb_6e26eb9d3f014869ec@gitlab.haskell.org.mail> Simon Jakobi pushed to branch wip/sjakobi/undeprecate-first-last 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. - - - - - 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. - - - - - 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] - - - - - 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 - - - - - 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 - - - - - 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. - - - - - 78c6523c by Ben Gamari at 2020-05-21T12:13:01-04:00 nonmoving: Optimise the write barrier - - - - - 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). - - - - - 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 - - - - - b7a6b2f4 by Gleb Popov at 2020-05-21T12:15:26-04:00 gitlab-ci: Set locale to C.UTF-8. - - - - - 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. - - - - - 0004ccb8 by Tuan Le at 2020-05-21T12:16:46-04:00 llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 - - - - - 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 - - - - - 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 - - - - - 2b363ebb by Richard Eisenberg at 2020-05-21T12:18:45-04:00 MR template should ask for key part - - - - - a95bbd0b by Sebastian Graf at 2020-05-21T12:19:37-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. - - - - - d3d055b8 by Galen Huntington at 2020-05-21T12:20:18-04:00 Clarify pitfalls of NegativeLiterals; see #18022. - - - - - 1b508a9e by Alexey Kuleshevich at 2020-05-21T12:21:02-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" - - - - - 4ca0c8a1 by Andreas Klebinger at 2020-05-21T12:21: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. - - - - - a1275081 by Krzysztof Gogolewski at 2020-05-21T12:22:35-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 - - - - - 8a816e5f by Krzysztof Gogolewski at 2020-05-21T12:23:55-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. - - - - - 566cc73f by Sylvain Henry at 2020-05-21T12:24:45-04:00 Move isDynLinkName into GHC.Types.Name It doesn't belong into GHC.Unit.State - - - - - d830bbc9 by Adam Sandberg Ericsson at 2020-05-23T13:36:20-04:00 docs: fix formatting and add some links [skip ci] - - - - - 49301ad6 by Andrew Martin at 2020-05-23T13:37:01-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. - - - - - dcd6bdcc by Ben Gamari at 2020-05-23T13:37:48-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. - - - - - 82cb8913 by John Ericson at 2020-05-23T13:38:32-04:00 Fix #18145 and also avoid needless work with implicit vars - `forAllOrNothing` now is monadic, so we can trace whether we bind an explicit `forall` or not. - #18145 arose because the free vars calculation was needlessly complex. It is now greatly simplified. - Replaced some other implicit var code with `filterFreeVarsToBind`. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - a60dc835 by Ben Gamari at 2020-05-23T13:39:12-04:00 Bump process submodule Fixes #17926. - - - - - 856adf54 by Ben Gamari at 2020-05-23T13:40:21-04:00 users-guide: Clarify meaning of -haddock flag Fixes #18206. - - - - - 7ae57afd by Ben Gamari at 2020-05-23T13:41:03-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 - - - - - 63d30e60 by jneira at 2020-05-24T01:54:42-04:00 Add hie-bios script for windows systems It is a direct translation of the sh script - - - - - 59182b88 by jneira at 2020-05-24T01:54:42-04:00 Honour previous values for CABAL and CABFLAGS The immediate goal is let the hie-bios.bat script set CABFLAGS with `-v0` and remove all cabal output except the compiler arguments - - - - - 932dc54e by jneira at 2020-05-24T01:54:42-04:00 Add specific configuration for windows in hie.yaml - - - - - e0eda070 by jneira at 2020-05-24T01:54:42-04:00 Remove not needed hie-bios output - - - - - a0ea59d6 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Move Config module into GHC.Settings - - - - - 37430251 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Core.Arity into GHC.Core.Opt.Arity - - - - - a426abb9 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Hs.Types into GHC.Hs.Type See discussion in https://gitlab.haskell.org/ghc/ghc/issues/13009#note_268610 - - - - - 1c91a7a0 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Bump haddock submodule - - - - - 66bd24d1 by Ryan Scott at 2020-05-24T01:56:03-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. - - - - - 01c43634 by Matthew Pickering at 2020-05-24T01:56:42-04:00 Remove unused hs-boot file - - - - - 7a07aa71 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix cross-compiler build (#16051) - - - - - 15ccca16 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix distDir per stage - - - - - b420fb24 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix hp2ps error during cross-compilation Fixed by @alp (see https://gitlab.haskell.org/ghc/ghc/issues/16051#note_274265) - - - - - cd339ef0 by Joshua Price at 2020-05-24T15:22:56-04:00 Make Unicode brackets opening/closing tokens (#18225) The tokens `[|`, `|]`, `(|`, and `|)` are opening/closing tokens as described in GHC Proposal #229. This commit makes the unicode variants (`⟦`, `⟧`, `⦇`, and `⦈`) act the same as their ASCII counterparts. - - - - - 013d7120 by Ben Gamari at 2020-05-25T09:48:17-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. - - - - - 4c4312ed by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Drop redundant ad-hoc boot module check To determine whether the module is a boot module Coverage.addTicksToBinds was checking for a `boot` suffix in the module source filename. This is quite ad-hoc and shouldn't be necessary; the callsite in `deSugar` already checks that the module isn't a boot module. - - - - - 1abf3c84 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make tickBoxCount strict This could otherwise easily cause a leak of (+) thunks. - - - - - b2813750 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make ccIndices strict This just seems like a good idea. - - - - - 02e278eb by Ben Gamari at 2020-05-25T09:48:53-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. - - - - - b8c014ce by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Factor out addMixEntry - - - - - 7b5b6a5d by Simon Jakobi at 2020-05-25T23:50:05+02:00 base: Scrap deprecation plan for Data.Monoid.{First,Last} See the discussion on the libraries mailing list for context: https://mail.haskell.org/pipermail/libraries/2020-April/030357.html - - - - - 30 changed files: - + .git-ignore-revs - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/merge_request_templates/merge-request.md - 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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ade686a40f85322e29cd81ed4e0b4ee56b9df5de...7b5b6a5d1f52315d36719c69eba62146a81ee2b1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ade686a40f85322e29cd81ed4e0b4ee56b9df5de...7b5b6a5d1f52315d36719c69eba62146a81ee2b1 You're receiving 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 25 21:54:45 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Mon, 25 May 2020 17:54:45 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18235 Message-ID: <5ecc3ea579dd7_6e263f9ee3522300148753f@gitlab.haskell.org.mail> Ryan Scott pushed new branch wip/T18235 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18235 You're receiving 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 25 22:04:53 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 25 May 2020 18:04:53 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18234 Message-ID: <5ecc410595238_6e263f9ed7508a741491026@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/T18234 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18234 You're receiving 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 26 01:21:53 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 25 May 2020 21:21:53 -0400 Subject: [Git][ghc/ghc][wip/ticky-datacon-name] Ticky-ticky: Record DataCon name in ticker name Message-ID: <5ecc6f3142929_6e263f9f00579e0815279e1@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/ticky-datacon-name at Glasgow Haskell Compiler / GHC Commits: 5f46cee1 by Ben Gamari at 2020-05-25T21:20:05-04:00 Ticky-ticky: Record DataCon name in ticker name This makes it significantly easier to spot the nature of allocations regressions and comes at a reasonably low cost. - - - - - 2 changed files: - compiler/GHC/StgToCmm/Bind.hs - compiler/GHC/StgToCmm/Ticky.hs Changes: ===================================== compiler/GHC/StgToCmm/Bind.hs ===================================== @@ -201,7 +201,7 @@ cgRhs :: Id ) cgRhs id (StgRhsCon cc con args) - = withNewTickyCounterCon (idName id) $ + = withNewTickyCounterCon (idName id) con $ buildDynCon id True cc con (assertNonVoidStgArgs args) -- con args are always non-void, -- see Note [Post-unarisation invariants] in GHC.Stg.Unarise ===================================== compiler/GHC/StgToCmm/Ticky.hs ===================================== @@ -128,6 +128,7 @@ import GHC.Driver.Session -- Turgid imports for showTypeCategory import GHC.Builtin.Names import GHC.Tc.Utils.TcType +import GHC.Core.DataCon import GHC.Core.TyCon import GHC.Core.Predicate @@ -145,6 +146,7 @@ data TickyClosureType = TickyFun Bool -- True <-> single entry | TickyCon + DataCon -- the allocated constructor | TickyThunk Bool -- True <-> updateable Bool -- True <-> standard thunk (AP or selector), has no entry counter @@ -188,13 +190,14 @@ withNewTickyCounterStdThunk isUpdatable name code = do withNewTickyCounterCon :: Name + -> DataCon -> FCode a -> FCode a -withNewTickyCounterCon name code = do +withNewTickyCounterCon name datacon code = do has_ctr <- thunkHasCounter False if not has_ctr then code - else withNewTickyCounter TickyCon name [] code + else withNewTickyCounter (TickyCon datacon) name [] code -- args does not include the void arguments withNewTickyCounter :: TickyClosureType -> Name -> [NonVoid Id] -> FCode a -> FCode a @@ -222,7 +225,7 @@ emitTickyCounter cloType name args ext = case cloType of TickyFun single_entry -> parens $ hcat $ punctuate comma $ [text "fun"] ++ [text "se"|single_entry] - TickyCon -> parens (text "con") + TickyCon datacon -> parens (text "con:" <+> ppr (dataConName datacon)) TickyThunk upd std -> parens $ hcat $ punctuate comma $ [text "thk"] ++ [text "se"|not upd] ++ [text "std"|std] TickyLNE | isInternalName name -> parens (text "LNE") View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5f46cee1e9e5df73bb607ca91eb782661b1d2699 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5f46cee1e9e5df73bb607ca91eb782661b1d2699 You're receiving 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 26 01:24:51 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 25 May 2020 21:24:51 -0400 Subject: [Git][ghc/ghc][wip/lower-tc-tracing-cost] Avoid unnecessary allocations due to tracing utilities Message-ID: <5ecc6fe3ef4aa_6e263f9f00579e0815285ea@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/lower-tc-tracing-cost at Glasgow Haskell Compiler / GHC Commits: f4106973 by Ben Gamari at 2020-05-25T21:24:31-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 haddock.Cabal haddock.base haddock.compiler - - - - - 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/f410697319fbd2336af5fbf6ab8ca8334fd4b32b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f410697319fbd2336af5fbf6ab8ca8334fd4b32b You're receiving 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 26 01:33:24 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Mon, 25 May 2020 21:33:24 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: Add info about typeclass evidence to .hie files Message-ID: <5ecc71e44e44e_6e263f9f01f3c48015317ed@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 696879f9 by Zubin Duggal at 2020-05-25T21:32:33-04:00 Add info about typeclass evidence to .hie files See `testsuite/tests/hiefile/should_run/HieQueries.hs` and `testsuite/tests/hiefile/should_run/HieQueries.stdout` for an example of this We add two new fields, `EvidenceVarBind` and `EvidenceVarUse` to the `ContextInfo` associated with an Identifier. These are associated with the appropriate identifiers for the evidence variables collected when we come across `HsWrappers`, `TcEvBinds` and `IPBinds` while traversing the AST. Instance dictionary and superclass selector dictionaries from `tcg_insts` and classes defined in `tcg_tcs` are also recorded in the AST as originating from their definition span This allows us to save a complete picture of the evidence constructed by the constraint solver, and will let us report this to the user, enabling features like going to the instance definition from the invocation of a class method(or any other method taking a constraint) and finding all usages of a particular instance. Additionally, - Mark NodeInfo with an origin so we can differentiate between bindings origininating in the source vs those in ghc - Along with typeclass evidence info, also include information on Implicit Parameters - Add a few utility functions to HieUtils in order to query the new info Updates haddock submodule - - - - - 2e5fd786 by Sebastian Graf at 2020-05-25T21:32:35-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. - - - - - 38ad4a19 by Sylvain Henry at 2020-05-25T21:33:10-04:00 Enhance Note [About units] for Backpack - - - - - 19 changed files: - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Debug.hs - compiler/GHC/Iface/Ext/Types.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Unit.hs - docs/users_guide/using-optimisation.rst - testsuite/tests/hiefile/should_compile/Scopes.hs - + testsuite/tests/hiefile/should_run/HieQueries.hs - + testsuite/tests/hiefile/should_run/HieQueries.stdout - testsuite/tests/hiefile/should_run/PatTypes.hs - testsuite/tests/hiefile/should_run/all.T - + testsuite/tests/stranal/should_compile/T18122.hs - + testsuite/tests/stranal/should_compile/T18122.stderr - testsuite/tests/stranal/should_compile/all.T - utils/haddock 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 ===================================== @@ -1034,7 +1034,7 @@ 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 +cf Note [Tick annotations in call patterns] in GHC.Core.Opt.SpecConstr Note [Matching lets] ~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -13,36 +13,47 @@ Main functions for .hie file generation {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE DeriveDataTypeable #-} +{-# LANGUAGE TupleSections #-} {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} module GHC.Iface.Ext.Ast ( mkHieFile, mkHieFileWithSource, getCompressedAsts) where +import GHC.Utils.Outputable(ppr) + import GHC.Prelude import GHC.Types.Avail ( Avails ) import GHC.Data.Bag ( Bag, bagToList ) import GHC.Types.Basic import GHC.Data.BooleanFormula -import GHC.Core.Class ( FunDep ) +import GHC.Core.Class ( FunDep, className, classSCSelIds ) import GHC.Core.Utils ( exprType ) import GHC.Core.ConLike ( conLikeName ) +import GHC.Core.TyCon ( TyCon, tyConClass_maybe ) +import GHC.Core.FVs import GHC.HsToCore ( deSugarExpr ) import GHC.Types.FieldLabel import GHC.Hs import GHC.Driver.Types import GHC.Unit.Module ( ModuleName, ml_hs_file ) import GHC.Utils.Monad ( concatMapM, liftIO ) -import GHC.Types.Name ( Name, nameSrcSpan, setNameLoc ) +import GHC.Types.Name ( Name, nameSrcSpan, setNameLoc, nameUnique ) import GHC.Types.Name.Env ( NameEnv, emptyNameEnv, extendNameEnv, lookupNameEnv ) import GHC.Types.SrcLoc import GHC.Tc.Utils.Zonk ( hsLitType, hsPatType ) import GHC.Core.Type ( mkVisFunTys, Type ) +import GHC.Core.Predicate +import GHC.Core.InstEnv import GHC.Builtin.Types ( mkListTy, mkSumTy ) -import GHC.Types.Var ( Id, Var, setVarName, varName, varType ) import GHC.Tc.Types +import GHC.Tc.Types.Evidence +import GHC.Types.Var ( Id, Var, EvId, setVarName, varName, varType, varUnique ) +import GHC.Types.Var.Env +import GHC.Types.Unique import GHC.Iface.Make ( mkIfaceExports ) import GHC.Utils.Panic import GHC.Data.Maybe +import GHC.Data.FastString import GHC.Iface.Ext.Types import GHC.Iface.Ext.Utils @@ -53,6 +64,8 @@ import qualified Data.Map as M import qualified Data.Set as S import Data.Data ( Data, Typeable ) import Data.List ( foldl1' ) +import Control.Monad ( forM_ ) +import Control.Monad.Trans.State.Strict import Control.Monad.Trans.Reader import Control.Monad.Trans.Class ( lift ) @@ -196,12 +209,47 @@ The Typechecker introduces new names for mono names in AbsBinds. We don't care about the distinction between mono and poly bindings, so we replace all occurrences of the mono name with the poly name. -} -newtype HieState = HieState +type VarMap a = DVarEnv (Var,a) +data HieState = HieState { name_remapping :: NameEnv Id + , unlocated_ev_binds :: VarMap (S.Set ContextInfo) + -- These contain evidence bindings that we don't have a location for + -- These are placed at the top level Node in the HieAST after everything + -- else has been generated + -- This includes things like top level evidence bindings. } +addUnlocatedEvBind :: Var -> ContextInfo -> HieM () +addUnlocatedEvBind var ci = do + let go (a,b) (_,c) = (a,S.union b c) + lift $ modify' $ \s -> + s { unlocated_ev_binds = + extendDVarEnv_C go (unlocated_ev_binds s) + var (var,S.singleton ci) + } + +getUnlocatedEvBinds :: FastString -> HieM (NodeIdentifiers Type,[HieAST Type]) +getUnlocatedEvBinds file = do + binds <- lift $ gets unlocated_ev_binds + org <- ask + let elts = dVarEnvElts binds + + mkNodeInfo (n,ci) = (Right (varName n), IdentifierDetails (Just $ varType n) ci) + + go e@(v,_) (xs,ys) = case nameSrcSpan $ varName v of + RealSrcSpan spn _ + | srcSpanFile spn == file -> + let node = Node (mkSourcedNodeInfo org ni) spn [] + ni = NodeInfo mempty [] $ M.fromList [mkNodeInfo e] + in (xs,node:ys) + _ -> (mkNodeInfo e : xs,ys) + + (nis,asts) = foldr go ([],[]) elts + + pure $ (M.fromList nis, asts) + initState :: HieState -initState = HieState emptyNameEnv +initState = HieState emptyNameEnv emptyDVarEnv class ModifyState a where -- See Note [Name Remapping] addSubstitution :: a -> a -> HieState -> HieState @@ -216,10 +264,11 @@ instance ModifyState Id where modifyState :: ModifyState (IdP p) => [ABExport p] -> HieState -> HieState modifyState = foldr go id where - go ABE{abe_poly=poly,abe_mono=mono} f = addSubstitution mono poly . f + go ABE{abe_poly=poly,abe_mono=mono} f + = addSubstitution mono poly . f go _ f = f -type HieM = ReaderT HieState Hsc +type HieM = ReaderT NodeOrigin (StateT HieState Hsc) -- | Construct an 'HieFile' from the outputs of the typechecker. mkHieFile :: ModSummary @@ -239,7 +288,10 @@ mkHieFileWithSource :: FilePath -> RenamedSource -> Hsc HieFile mkHieFileWithSource src_file src ms ts rs = do let tc_binds = tcg_binds ts - (asts', arr) <- getCompressedAsts tc_binds rs + top_ev_binds = tcg_ev_binds ts + insts = tcg_insts ts + tcs = tcg_tcs ts + (asts', arr) <- getCompressedAsts tc_binds rs top_ev_binds insts tcs return $ HieFile { hie_hs_file = src_file , hie_module = ms_mod ms @@ -250,38 +302,70 @@ mkHieFileWithSource src_file src ms ts rs = do , hie_hs_src = src } -getCompressedAsts :: TypecheckedSource -> RenamedSource +getCompressedAsts :: TypecheckedSource -> RenamedSource -> Bag EvBind -> [ClsInst] -> [TyCon] -> Hsc (HieASTs TypeIndex, A.Array TypeIndex HieTypeFlat) -getCompressedAsts ts rs = do - asts <- enrichHie ts rs +getCompressedAsts ts rs top_ev_binds insts tcs = do + asts <- enrichHie ts rs top_ev_binds insts tcs return $ compressTypes asts -enrichHie :: TypecheckedSource -> RenamedSource -> Hsc (HieASTs Type) -enrichHie ts (hsGrp, imports, exports, _) = flip runReaderT initState $ do +enrichHie :: TypecheckedSource -> RenamedSource -> Bag EvBind -> [ClsInst] -> [TyCon] + -> Hsc (HieASTs Type) +enrichHie ts (hsGrp, imports, exports, _) ev_bs insts tcs = + flip evalStateT initState $ flip runReaderT SourceInfo $ do tasts <- toHie $ fmap (BC RegularBind ModuleScope) ts rasts <- processGrp hsGrp imps <- toHie $ filter (not . ideclImplicit . unLoc) imports exps <- toHie $ fmap (map $ IEC Export . fst) exports - let spanFile children = case children of - [] -> mkRealSrcSpan (mkRealSrcLoc "" 1 1) (mkRealSrcLoc "" 1 1) + -- Add Instance bindings + forM_ insts $ \i -> + addUnlocatedEvBind (is_dfun i) (EvidenceVarBind (EvInstBind False (is_cls_nm i)) ModuleScope Nothing) + -- Add class parent bindings + forM_ tcs $ \tc -> + case tyConClass_maybe tc of + Nothing -> pure () + Just c -> forM_ (classSCSelIds c) $ \v -> + addUnlocatedEvBind v (EvidenceVarBind (EvInstBind True (className c)) ModuleScope Nothing) + let spanFile file children = case children of + [] -> realSrcLocSpan (mkRealSrcLoc file 1 1) _ -> mkRealSrcSpan (realSrcSpanStart $ nodeSpan $ head children) (realSrcSpanEnd $ nodeSpan $ last children) - modulify xs = - Node (simpleNodeInfo "Module" "Module") (spanFile xs) xs - - asts = HieASTs - $ resolveTyVarScopes - $ M.map (modulify . mergeSortAsts) - $ M.fromListWith (++) - $ map (\x -> (srcSpanFile (nodeSpan x),[x])) flat_asts - flat_asts = concat [ tasts , rasts , imps , exps ] + + modulify file xs' = do + + top_ev_asts <- + toHie $ EvBindContext ModuleScope Nothing + $ L (RealSrcSpan (realSrcLocSpan $ mkRealSrcLoc file 1 1) Nothing) + $ EvBinds ev_bs + + (uloc_evs,more_ev_asts) <- getUnlocatedEvBinds file + + let xs = mergeSortAsts $ xs' ++ top_ev_asts ++ more_ev_asts + span = spanFile file xs + + moduleInfo = SourcedNodeInfo + $ M.singleton SourceInfo + $ (simpleNodeInfo "Module" "Module") + {nodeIdentifiers = uloc_evs} + + moduleNode = Node moduleInfo span [] + + case mergeSortAsts $ moduleNode : xs of + [x] -> return x + xs -> panicDoc "enrichHie: mergeSortAsts returned more than one result" (ppr $ map nodeSpan xs) + + asts' <- sequence + $ M.mapWithKey modulify + $ M.fromListWith (++) + $ map (\x -> (srcSpanFile (nodeSpan x),[x])) flat_asts + + let asts = HieASTs $ resolveTyVarScopes asts' return asts where processGrp grp = concatM @@ -305,13 +389,16 @@ grhss_span :: GRHSs p body -> SrcSpan grhss_span (GRHSs _ xs bs) = foldl' combineSrcSpans (getLoc bs) (map getLoc xs) grhss_span (XGRHSs _) = panic "XGRHS has no span" -bindingsOnly :: [Context Name] -> [HieAST a] -bindingsOnly [] = [] -bindingsOnly (C c n : xs) = case nameSrcSpan n of - RealSrcSpan span _ -> Node nodeinfo span [] : bindingsOnly xs - where nodeinfo = NodeInfo S.empty [] (M.singleton (Right n) info) - info = mempty{identInfo = S.singleton c} - _ -> bindingsOnly xs +bindingsOnly :: [Context Name] -> HieM [HieAST a] +bindingsOnly [] = pure [] +bindingsOnly (C c n : xs) = do + org <- ask + rest <- bindingsOnly xs + pure $ case nameSrcSpan n of + RealSrcSpan span _ -> Node (mkSourcedNodeInfo org nodeinfo) span [] : rest + where nodeinfo = NodeInfo S.empty [] (M.singleton (Right n) info) + info = mempty{identInfo = S.singleton c} + _ -> rest concatM :: Monad m => [m [a]] -> m [a] concatM xs = concat <$> sequence xs @@ -345,6 +432,8 @@ data SigInfo = SI SigType (Maybe Span) data SigType = BindSig | ClassSig | InstSig +data EvBindContext a = EvBindContext Scope (Maybe Span) a + data RScoped a = RS Scope a -- ^ Scope spans over everything to the right of a, (mostly) not -- including a itself @@ -502,8 +591,9 @@ instance ToHie (TScoped NoExtField) where toHie _ = pure [] instance ToHie (IEContext (Located ModuleName)) where - toHie (IEC c (L (RealSrcSpan span _) mname)) = - pure $ [Node (NodeInfo S.empty [] idents) span []] + toHie (IEC c (L (RealSrcSpan span _) mname)) = do + org <- ask + pure $ [Node (mkSourcedNodeInfo org $ NodeInfo S.empty [] idents) span []] where details = mempty{identInfo = S.singleton (IEThing c)} idents = M.singleton (Left mname) details toHie _ = pure [] @@ -511,38 +601,90 @@ instance ToHie (IEContext (Located ModuleName)) where instance ToHie (Context (Located Var)) where toHie c = case c of C context (L (RealSrcSpan span _) name') - -> do - m <- asks name_remapping - let name = case lookupNameEnv m (varName name') of - Just var -> var - Nothing-> name' - pure - [Node - (NodeInfo S.empty [] $ - M.singleton (Right $ varName name) - (IdentifierDetails (Just $ varType name') - (S.singleton context))) - span - []] + | varUnique name' == mkBuiltinUnique 1 -> pure [] + -- `mkOneRecordSelector` makes a field var using this unique, which we ignore + | otherwise -> do + m <- lift $ gets name_remapping + org <- ask + let name = case lookupNameEnv m (varName name') of + Just var -> var + Nothing-> name' + pure + [Node + (mkSourcedNodeInfo org $ NodeInfo S.empty [] $ + M.singleton (Right $ varName name) + (IdentifierDetails (Just $ varType name') + (S.singleton context))) + span + []] + C (EvidenceVarBind i _ sp) (L _ name) -> do + addUnlocatedEvBind name (EvidenceVarBind i ModuleScope sp) + pure [] _ -> pure [] instance ToHie (Context (Located Name)) where toHie c = case c of - C context (L (RealSrcSpan span _) name') -> do - m <- asks name_remapping - let name = case lookupNameEnv m name' of - Just var -> varName var - Nothing -> name' - pure - [Node - (NodeInfo S.empty [] $ - M.singleton (Right name) - (IdentifierDetails Nothing - (S.singleton context))) - span - []] + C context (L (RealSrcSpan span _) name') + | nameUnique name' == mkBuiltinUnique 1 -> pure [] + -- `mkOneRecordSelector` makes a field var using this unique, which we ignore + | otherwise -> do + m <- lift $ gets name_remapping + org <- ask + let name = case lookupNameEnv m name' of + Just var -> varName var + Nothing -> name' + pure + [Node + (mkSourcedNodeInfo org $ NodeInfo S.empty [] $ + M.singleton (Right name) + (IdentifierDetails Nothing + (S.singleton context))) + span + []] _ -> pure [] +evVarsOfTermList :: EvTerm -> [EvId] +evVarsOfTermList (EvExpr e) = exprSomeFreeVarsList isEvVar e +evVarsOfTermList (EvTypeable _ ev) = + case ev of + EvTypeableTyCon _ e -> concatMap evVarsOfTermList e + EvTypeableTyApp e1 e2 -> concatMap evVarsOfTermList [e1,e2] + EvTypeableTrFun e1 e2 -> concatMap evVarsOfTermList [e1,e2] + EvTypeableTyLit e -> evVarsOfTermList e +evVarsOfTermList (EvFun{}) = [] + +instance ToHie (EvBindContext (Located TcEvBinds)) where + toHie (EvBindContext sc sp (L span (EvBinds bs))) + = concatMapM go $ bagToList bs + where + go evbind = do + let evDeps = evVarsOfTermList $ eb_rhs evbind + depNames = EvBindDeps $ map varName evDeps + concatM $ + [ toHie (C (EvidenceVarBind (EvLetBind depNames) (combineScopes sc (mkScope span)) sp) + (L span $ eb_lhs evbind)) + , toHie $ map (C EvidenceVarUse . L span) $ evDeps + ] + toHie _ = pure [] + +instance ToHie (EvBindContext (Located NoExtField)) where + toHie _ = pure [] + +instance ToHie (Located HsWrapper) where + toHie (L osp wrap) + = case wrap of + (WpLet bs) -> toHie $ EvBindContext (mkScope osp) (getRealSpan osp) (L osp bs) + (WpCompose a b) -> concatM $ + [toHie (L osp a), toHie (L osp b)] + (WpFun a b _ _) -> concatM $ + [toHie (L osp a), toHie (L osp b)] + (WpEvLam a) -> + toHie $ C (EvidenceVarBind EvWrapperBind (mkScope osp) (getRealSpan osp)) + $ L osp a + (WpEvApp a) -> + concatMapM (toHie . C EvidenceVarUse . L osp) $ evVarsOfTermList a + _ -> pure [] + -- | Dummy instances - never called instance ToHie (TScoped (LHsSigWcType GhcTc)) where toHie _ = pure [] @@ -586,7 +728,7 @@ instance HasType (LHsExpr GhcRn) where -- -- See #16233 instance HasType (LHsExpr GhcTc) where - getTypeNode e@(L spn e') = lift $ + getTypeNode e@(L spn e') = -- Some expression forms have their type immediately available let tyOpt = case e' of HsLit _ l -> Just (hsLitType l) @@ -609,7 +751,7 @@ instance HasType (LHsExpr GhcTc) where Nothing | skipDesugaring e' -> fallback | otherwise -> do - hs_env <- Hsc $ \e w -> return (e,w) + hs_env <- lift $ lift $ Hsc $ \e w -> return (e,w) (_,mbe) <- liftIO $ deSugarExpr hs_env e maybe fallback (makeTypeNode e' spn . exprType) mbe where @@ -634,21 +776,25 @@ instance HasType (LHsExpr GhcTc) where XExpr (HsWrap{}) -> False _ -> True -instance ( ToHie (Context (Located (IdP a))) - , ToHie (MatchGroup a (LHsExpr a)) - , ToHie (PScoped (LPat a)) - , ToHie (GRHSs a (LHsExpr a)) - , ToHie (LHsExpr a) - , ToHie (Located (PatSynBind a a)) - , HasType (LHsBind a) - , ModifyState (IdP a) - , Data (HsBind a) - ) => ToHie (BindContext (LHsBind a)) where +instance ( ToHie (Context (Located (IdP (GhcPass a)))) + , ToHie (MatchGroup (GhcPass a) (LHsExpr (GhcPass a))) + , ToHie (PScoped (LPat (GhcPass a))) + , ToHie (GRHSs (GhcPass a) (LHsExpr (GhcPass a))) + , ToHie (LHsExpr (GhcPass a)) + , ToHie (Located (PatSynBind (GhcPass a) (GhcPass a))) + , HasType (LHsBind (GhcPass a)) + , ModifyState (IdP (GhcPass a)) + , Data (HsBind (GhcPass a)) + , IsPass a + ) => ToHie (BindContext (LHsBind (GhcPass a))) where toHie (BC context scope b@(L span bind)) = concatM $ getTypeNode b : case bind of - FunBind{fun_id = name, fun_matches = matches} -> + FunBind{fun_id = name, fun_matches = matches, fun_ext = wrap} -> [ toHie $ C (ValBind context scope $ getRealSpan span) name , toHie matches + , case ghcPass @a of + GhcTc -> toHie $ L span wrap + _ -> pure [] ] PatBind{pat_lhs = lhs, pat_rhs = rhs} -> [ toHie $ PS (getRealSpan span) scope NoScope lhs @@ -657,39 +803,55 @@ instance ( ToHie (Context (Located (IdP a))) VarBind{var_rhs = expr} -> [ toHie expr ] - AbsBinds{abs_exports = xs, abs_binds = binds} -> - [ local (modifyState xs) $ -- Note [Name Remapping] - toHie $ fmap (BC context scope) binds + AbsBinds{ abs_exports = xs, abs_binds = binds + , abs_ev_binds = ev_binds + , abs_ev_vars = ev_vars } -> + [ lift (modify (modifyState xs)) >> -- Note [Name Remapping] + (toHie $ fmap (BC context scope) binds) + , toHie $ map (L span . abe_wrap) xs + , toHie $ + map (EvBindContext (mkScope span) (getRealSpan span) + . L span) ev_binds + , toHie $ + map (C (EvidenceVarBind EvSigBind + (mkScope span) + (getRealSpan span)) + . L span) ev_vars ] PatSynBind _ psb -> [ toHie $ L span psb -- PatSynBinds only occur at the top level ] - XHsBindsLR _ -> [] instance ( ToHie (LMatch a body) ) => ToHie (MatchGroup a body) where - toHie mg = concatM $ case mg of - MG{ mg_alts = (L span alts) , mg_origin = FromSource } -> - [ pure $ locOnly span - , toHie alts - ] - MG{} -> [] - XMatchGroup _ -> [] + toHie mg = case mg of + MG{ mg_alts = (L span alts) , mg_origin = origin} -> + local (setOrigin origin) $ concatM + [ locOnly span + , toHie alts + ] + XMatchGroup _ -> pure [] + +setOrigin :: Origin -> NodeOrigin -> NodeOrigin +setOrigin FromSource _ = SourceInfo +setOrigin Generated _ = GeneratedInfo instance ( ToHie (Context (Located (IdP a))) , ToHie (PScoped (LPat a)) , ToHie (HsPatSynDir a) + , (a ~ GhcPass p) ) => ToHie (Located (PatSynBind a a)) where toHie (L sp psb) = concatM $ case psb of PSB{psb_id=var, psb_args=dets, psb_def=pat, psb_dir=dir} -> [ toHie $ C (Decl PatSynDec $ getRealSpan sp) var , toHie $ toBind dets - , toHie $ PS Nothing lhsScope NoScope pat + , toHie $ PS Nothing lhsScope patScope pat , toHie dir ] where lhsScope = combineScopes varScope detScope varScope = mkLScope var + patScope = mkScope $ getLoc pat detScope = case dets of (PrefixCon args) -> foldr combineScopes NoScope $ map mkLScope args (InfixCon a b) -> combineScopes (mkLScope a) (mkLScope b) @@ -702,7 +864,6 @@ instance ( ToHie (Context (Located (IdP a))) toBind (PrefixCon args) = PrefixCon $ map (C Use) args toBind (InfixCon a b) = InfixCon (C Use a) (C Use b) toBind (RecCon r) = RecCon $ map (PSC detSpan) r - XPatSynBind _ -> [] instance ( ToHie (MatchGroup a (LHsExpr a)) ) => ToHie (HsPatSynDir a) where @@ -780,12 +941,24 @@ instance ( a ~ GhcPass p SumPat _ pat _ _ -> [ toHie $ PS rsp scope pscope pat ] - ConPat {pat_con = con, pat_args = dets}-> + ConPat {pat_con = con, pat_args = dets, pat_con_ext = ext}-> [ case ghcPass @p of GhcPs -> toHie $ C Use $ con GhcRn -> toHie $ C Use $ con GhcTc -> toHie $ C Use $ fmap conLikeName con , toHie $ contextify dets + , case ghcPass @p of + GhcTc -> + let ev_binds = cpt_binds ext + ev_vars = cpt_dicts ext + wrap = cpt_wrap ext + evscope = mkScope ospan `combineScopes` scope `combineScopes` pscope + in concatM [ toHie $ EvBindContext scope rsp $ L ospan ev_binds + , toHie $ L ospan wrap + , toHie $ map (C (EvidenceVarBind EvPatternBind evscope rsp) + . L ospan) ev_vars + ] + _ -> pure [] ] ViewPat _ expr pat -> [ toHie expr @@ -816,10 +989,12 @@ instance ( a ~ GhcPass p GhcPs -> noExtCon e GhcRn -> noExtCon e #endif - GhcTc -> [] + GhcTc -> + [ toHie $ L ospan wrap + , toHie $ PS rsp scope pscope $ (L ospan pat :: LPat a) + ] where - -- Make sure we get an error if this changes - _noWarn@(CoPat _ _ _) = e + CoPat wrap pat _ = e where contextify (PrefixCon args) = PrefixCon $ patScopes rsp scope pscope args contextify (InfixCon a b) = InfixCon a' b' @@ -833,7 +1008,7 @@ instance ( a ~ GhcPass p 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) + [ bindingsOnly $ map (C $ TyVarBind (mkScope span) sc) (wcs++tvs) , toHie body ] -- See Note [Scoping Rules for SigPat] @@ -850,15 +1025,14 @@ instance ( ToHie body XGRHSs _ -> [] instance ( ToHie (Located body) - , ToHie (RScoped (GuardLStmt a)) - , Data (GRHS a (Located body)) - ) => ToHie (LGRHS a (Located body)) where + , ToHie (RScoped (GuardLStmt (GhcPass a))) + , Data (GRHS (GhcPass a) (Located body)) + ) => ToHie (LGRHS (GhcPass a) (Located body)) where toHie (L span g) = concatM $ makeNode g span : case g of GRHS _ guards body -> [ toHie $ listScopes (mkLScope body) guards , toHie body ] - XGRHS _ -> [] instance ( a ~ GhcPass p , ToHie (Context (Located (IdP a))) @@ -954,7 +1128,7 @@ instance ( a ~ GhcPass p , toHie expr ] HsDo _ _ (L ispan stmts) -> - [ pure $ locOnly ispan + [ locOnly ispan , toHie $ listScopes NoScope stmts ] ExplicitList _ _ exprs -> @@ -1008,9 +1182,10 @@ instance ( a ~ GhcPass p ] XExpr x | GhcTc <- ghcPass @p - , HsWrap _ a <- x - -> [ toHie $ L mspan a ] - + , HsWrap w a <- x + -> [ toHie $ L mspan a + , toHie (L mspan w) + ] | otherwise -> [] @@ -1070,17 +1245,37 @@ instance ( ToHie (LHsExpr a) , ToHie (BindContext (LHsBind a)) , ToHie (SigContext (LSig a)) , ToHie (RScoped (HsValBindsLR a a)) + , ToHie (EvBindContext (Located (XIPBinds a))) + , ToHie (RScoped (LIPBind a)) , Data (HsLocalBinds a) ) => ToHie (RScoped (LHsLocalBinds a)) where toHie (RS scope (L sp binds)) = concatM $ makeNode binds sp : case binds of EmptyLocalBinds _ -> [] - HsIPBinds _ _ -> [] + HsIPBinds _ ipbinds -> case ipbinds of + IPBinds evbinds xs -> let sc = combineScopes scope $ mkScope sp in + [ toHie $ EvBindContext sc (getRealSpan sp) $ L sp evbinds + , toHie $ map (RS sc) xs + ] + XHsIPBinds _ -> [] HsValBinds _ valBinds -> [ toHie $ RS (combineScopes scope $ mkScope sp) valBinds ] XHsLocalBindsLR _ -> [] +instance ( ToHie (LHsExpr a) + , ToHie (Context (Located (IdP a))) + , Data (IPBind a) + ) => ToHie (RScoped (LIPBind a)) where + toHie (RS scope (L sp bind)) = concatM $ makeNode bind sp : case bind of + IPBind _ (Left _) expr -> [toHie expr] + IPBind _ (Right v) expr -> + [ toHie $ C (EvidenceVarBind EvImplicitBind scope (getRealSpan sp)) + $ L sp v + , toHie expr + ] + XIPBind _ -> [] + instance ( ToHie (BindContext (LHsBind a)) , ToHie (SigContext (LSig a)) , ToHie (RScoped (XXValBindsLR a a)) @@ -1160,6 +1355,7 @@ instance ( a ~ GhcPass p , ToHie (LHsExpr a) , ToHie (SigContext (LSig a)) , ToHie (RScoped (HsValBindsLR a a)) + , ToHie (RScoped (ExprLStmt a)) , Data (StmtLR a a (Located (HsExpr a))) , Data (HsLocalBinds a) ) => ToHie (RScoped (ApplicativeArg (GhcPass p))) where @@ -1193,6 +1389,7 @@ instance ( a ~ GhcPass p , ToHie (MatchGroup a (LHsCmd a)) , ToHie (SigContext (LSig a)) , ToHie (RScoped (HsValBindsLR a a)) + , ToHie (RScoped (LHsLocalBinds a)) , Data (HsCmd a) , Data (HsCmdTop a) , Data (StmtLR a a (Located (HsCmd a))) @@ -1235,7 +1432,7 @@ instance ( a ~ GhcPass p , toHie cmd' ] HsCmdDo _ (L ispan stmts) -> - [ pure $ locOnly ispan + [ locOnly ispan , toHie $ listScopes NoScope stmts ] XCmd _ -> [] @@ -1289,7 +1486,7 @@ instance ToHie (LTyClDecl GhcRn) where , toHie $ map (SC $ SI ClassSig $ getRealSpan span) sigs , toHie $ fmap (BC InstanceBind ModuleScope) meths , toHie typs - , concatMapM (pure . locOnly . getLoc) deftyps + , concatMapM (locOnly . getLoc) deftyps , toHie deftyps ] where @@ -1313,7 +1510,7 @@ instance ToHie (LFamilyDecl GhcRn) where instance ToHie (FamilyInfo GhcRn) where toHie (ClosedTypeFamily (Just eqns)) = concatM $ - [ concatMapM (pure . locOnly . getLoc) eqns + [ concatMapM (locOnly . getLoc) eqns , toHie $ map go eqns ] where @@ -1371,7 +1568,7 @@ instance ToHie (HsDataDefn GhcRn) where instance ToHie (HsDeriving GhcRn) where toHie (L span clauses) = concatM - [ pure $ locOnly span + [ locOnly span , toHie clauses ] @@ -1379,7 +1576,7 @@ instance ToHie (LHsDerivingClause GhcRn) where toHie (L span cl) = concatM $ makeNode cl span : case cl of HsDerivingClause _ strat (L ispan tys) -> [ toHie strat - , pure $ locOnly ispan + , locOnly ispan , toHie $ map (TS (ResolvedScopes [])) tys ] @@ -1391,14 +1588,14 @@ instance ToHie (Located (DerivStrategy GhcRn)) where ViaStrategy s -> [ toHie $ TS (ResolvedScopes []) s ] instance ToHie (Located OverlapMode) where - toHie (L span _) = pure $ locOnly span + toHie (L span _) = locOnly span instance ToHie (LConDecl GhcRn) where toHie (L span decl) = concatM $ makeNode decl span : case decl of ConDeclGADT { con_names = names, con_qvars = exp_vars, con_g_ext = imp_vars , con_mb_cxt = ctx, con_args = args, con_res_ty = typ } -> [ toHie $ map (C (Decl ConDec $ getRealSpan span)) names - , concatM $ [ pure $ bindingsOnly bindings + , concatM $ [ bindingsOnly bindings , toHie $ tvScopes resScope NoScope exp_vars ] , toHie ctx , toHie args @@ -1429,7 +1626,7 @@ instance ToHie (LConDecl GhcRn) where instance ToHie (Located [LConDeclField GhcRn]) where toHie (L span decls) = concatM $ - [ pure $ locOnly span + [ locOnly span , toHie decls ] @@ -1437,7 +1634,7 @@ instance ( HasLoc thing , ToHie (TScoped thing) ) => ToHie (TScoped (HsImplicitBndrs GhcRn thing)) where toHie (TS sc (HsIB ibrn a)) = concatM $ - [ pure $ bindingsOnly $ map (C $ TyVarBind (mkScope span) sc) ibrn + [ bindingsOnly $ map (C $ TyVarBind (mkScope span) sc) ibrn , toHie $ TS sc a ] where span = loc a @@ -1446,7 +1643,7 @@ instance ( HasLoc thing , ToHie (TScoped thing) ) => ToHie (TScoped (HsWildCardBndrs GhcRn thing)) where toHie (TS sc (HsWC names a)) = concatM $ - [ pure $ bindingsOnly $ map (C $ TyVarBind (mkScope span) sc) names + [ bindingsOnly $ map (C $ TyVarBind (mkScope span) sc) names , toHie $ TS sc a ] where span = loc a @@ -1496,10 +1693,10 @@ instance ToHie (SigContext (LSig GhcRn)) where ] SCCFunSig _ _ name mtxt -> [ toHie $ (C Use) name - , pure $ maybe [] (locOnly . getLoc) mtxt + , maybe (pure []) (locOnly . getLoc) mtxt ] CompleteMatchSig _ _ (L ispan names) typ -> - [ pure $ locOnly ispan + [ locOnly ispan , toHie $ map (C Use) names , toHie $ fmap (C Use) typ ] @@ -1583,7 +1780,7 @@ instance ToHie (TScoped (LHsType GhcRn)) where instance (ToHie tm, ToHie ty) => ToHie (HsArg tm ty) where toHie (HsValArg tm) = toHie tm toHie (HsTypeArg _ ty) = toHie ty - toHie (HsArgPar sp) = pure $ locOnly sp + toHie (HsArgPar sp) = locOnly sp instance Data flag => ToHie (TVScoped (LHsTyVarBndr flag GhcRn)) where toHie (TVS tsc sc (L span bndr)) = concatM $ makeNode bndr span : case bndr of @@ -1597,7 +1794,7 @@ instance Data flag => ToHie (TVScoped (LHsTyVarBndr flag GhcRn)) where instance ToHie (TScoped (LHsQTyVars GhcRn)) where toHie (TS sc (HsQTvs implicits vars)) = concatM $ - [ pure $ bindingsOnly bindings + [ bindingsOnly bindings , toHie $ tvScopes sc NoScope vars ] where @@ -1606,7 +1803,7 @@ instance ToHie (TScoped (LHsQTyVars GhcRn)) where instance ToHie (LHsContext GhcRn) where toHie (L span tys) = concatM $ - [ pure $ locOnly span + [ locOnly span , toHie tys ] @@ -1679,7 +1876,7 @@ instance ( a ~ GhcPass p [ toHie expr ] HsQuasiQuote _ _ _ ispan _ -> - [ pure $ locOnly ispan + [ locOnly ispan ] HsSpliced _ _ _ -> [] @@ -1695,7 +1892,7 @@ instance ToHie (LRoleAnnotDecl GhcRn) where toHie (L span annot) = concatM $ makeNode annot span : case annot of RoleAnnotDecl _ var roles -> [ toHie $ C Use var - , concatMapM (pure . locOnly . getLoc) roles + , concatMapM (locOnly . getLoc) roles ] instance ToHie (LInstDecl GhcRn) where @@ -1715,9 +1912,9 @@ instance ToHie (LClsInstDecl GhcRn) where [ toHie $ TS (ResolvedScopes [mkScope span]) $ cid_poly_ty decl , toHie $ fmap (BC InstanceBind ModuleScope) $ cid_binds decl , toHie $ map (SC $ SI InstSig $ getRealSpan span) $ cid_sigs decl - , pure $ concatMap (locOnly . getLoc) $ cid_tyfam_insts decl + , concatMapM (locOnly . getLoc) $ cid_tyfam_insts decl , toHie $ cid_tyfam_insts decl - , pure $ concatMap (locOnly . getLoc) $ cid_datafam_insts decl + , concatMapM (locOnly . getLoc) $ cid_datafam_insts decl , toHie $ cid_datafam_insts decl , toHie $ cid_overlap_mode decl ] @@ -1769,14 +1966,14 @@ instance ToHie (LForeignDecl GhcRn) where ] instance ToHie ForeignImport where - toHie (CImport (L a _) (L b _) _ _ (L c _)) = pure $ concat $ + toHie (CImport (L a _) (L b _) _ _ (L c _)) = concatM $ [ locOnly a , locOnly b , locOnly c ] instance ToHie ForeignExport where - toHie (CExport (L a _) (L b _)) = pure $ concat $ + toHie (CExport (L a _) (L b _)) = concatM $ [ locOnly a , locOnly b ] @@ -1814,7 +2011,7 @@ instance ToHie (LRuleDecls GhcRn) where instance ToHie (LRuleDecl GhcRn) where toHie (L span r@(HsRule _ rname _ tybndrs bndrs exprA exprB)) = concatM [ makeNode r span - , pure $ locOnly $ getLoc rname + , locOnly $ getLoc rname , toHie $ fmap (tvScopes (ResolvedScopes []) scope) tybndrs , toHie $ map (RS $ mkScope span) bndrs , toHie exprA @@ -1844,7 +2041,7 @@ instance ToHie (LImportDecl GhcRn) where ] where goIE (hiding, (L sp liens)) = concatM $ - [ pure $ locOnly sp + [ locOnly sp , toHie $ map (IEC c) liens ] where ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -23,7 +23,6 @@ import GHC.Utils.Binary import GHC.Iface.Binary ( getDictFastString ) import GHC.Data.FastMutInt import GHC.Data.FastString ( FastString ) -import GHC.Unit.Module ( Module ) import GHC.Types.Name import GHC.Types.Name.Cache import GHC.Utils.Outputable @@ -32,7 +31,6 @@ import GHC.Types.SrcLoc as SrcLoc 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 @@ -48,42 +46,6 @@ import System.FilePath ( takeDirectory ) import GHC.Iface.Ext.Types --- | `Name`'s get converted into `HieName`'s before being written into @.hie@ --- files. See 'toHieName' and 'fromHieName' for logic on how to convert between --- these two types. -data HieName - = ExternalName !Module !OccName !SrcSpan - | LocalName !OccName !SrcSpan - | KnownKeyName !Unique - deriving (Eq) - -instance Ord HieName where - compare (ExternalName a b c) (ExternalName d e f) = compare (a,b) (d,e) `thenCmp` SrcLoc.leftmost_smallest c f - -- TODO (int-index): Perhaps use RealSrcSpan in HieName? - compare (LocalName a b) (LocalName c d) = compare a c `thenCmp` SrcLoc.leftmost_smallest b d - -- TODO (int-index): Perhaps use RealSrcSpan in HieName? - compare (KnownKeyName a) (KnownKeyName b) = nonDetCmpUnique a b - -- Not actually non deterministic as it is a KnownKey - compare ExternalName{} _ = LT - compare LocalName{} ExternalName{} = GT - compare LocalName{} _ = LT - compare KnownKeyName{} _ = GT - -instance Outputable HieName where - ppr (ExternalName m n sp) = text "ExternalName" <+> ppr m <+> ppr n <+> ppr sp - ppr (LocalName n sp) = text "LocalName" <+> ppr n <+> ppr sp - ppr (KnownKeyName u) = text "KnownKeyName" <+> ppr u - -hieNameOcc :: HieName -> OccName -hieNameOcc (ExternalName _ occ _) = occ -hieNameOcc (LocalName occ _) = occ -hieNameOcc (KnownKeyName u) = - case lookupKnownKeyName u of - Just n -> nameOccName n - Nothing -> pprPanic "hieNameOcc:unknown known-key unique" - (ppr (unpkUnique u)) - - data HieSymbolTable = HieSymbolTable { hie_symtab_next :: !FastMutInt , hie_symtab_map :: !(IORef (UniqFM (Int, HieName))) @@ -352,14 +314,6 @@ putName (HieSymbolTable next ref) bh name = do -- ** Converting to and from `HieName`'s -toHieName :: Name -> HieName -toHieName name - | isKnownKeyName name = KnownKeyName (nameUnique name) - | isExternalName name = ExternalName (nameModule name) - (nameOccName name) - (nameSrcSpan name) - | otherwise = LocalName (nameOccName name) (nameSrcSpan name) - fromHieName :: NameCache -> HieName -> (NameCache, Name) fromHieName nc (ExternalName mod occ span) = let cache = nsNames nc ===================================== compiler/GHC/Iface/Ext/Debug.hs ===================================== @@ -15,7 +15,6 @@ import GHC.Data.FastString import GHC.Utils.Outputable import GHC.Iface.Ext.Types -import GHC.Iface.Ext.Binary import GHC.Iface.Ext.Utils import GHC.Types.Name @@ -39,17 +38,18 @@ diffAst diffType (Node info1 span1 xs1) (Node info2 span2 xs2) = spanDiff | span1 /= span2 = [hsep ["Spans", ppr span1, "and", ppr span2, "differ"]] | otherwise = [] - infoDiff' - = (diffList eqDiff `on` (S.toAscList . nodeAnnotations)) info1 info2 - ++ (diffList diffType `on` nodeType) info1 info2 - ++ (diffIdents `on` nodeIdentifiers) info1 info2 - infoDiff = case infoDiff' of + infoDiff' i1 i2 + = (diffList eqDiff `on` (S.toAscList . nodeAnnotations)) i1 i2 + ++ (diffList diffType `on` nodeType) i1 i2 + ++ (diffIdents `on` nodeIdentifiers) i1 i2 + sinfoDiff = diffList (\(k1,a) (k2,b) -> eqDiff k1 k2 ++ infoDiff' a b) `on` (M.toList . getSourcedNodeInfo) + infoDiff = case sinfoDiff info1 info2 of [] -> [] - xs -> xs ++ [vcat ["In Node:",ppr (nodeIdentifiers info1,span1) - , "and", ppr (nodeIdentifiers info2,span2) + xs -> xs ++ [vcat ["In Node:",ppr (sourcedNodeIdents info1,span1) + , "and", ppr (sourcedNodeIdents info2,span2) , "While comparing" - , ppr (normalizeIdents $ nodeIdentifiers info1), "and" - , ppr (normalizeIdents $ nodeIdentifiers info2) + , ppr (normalizeIdents $ sourcedNodeIdents info1), "and" + , ppr (normalizeIdents $ sourcedNodeIdents info2) ] ] @@ -107,11 +107,24 @@ validAst (Node _ span children) = do -- | Look for any identifiers which occur outside of their supposed scopes. -- Returns a list of error messages. validateScopes :: Module -> M.Map FastString (HieAST a) -> [SDoc] -validateScopes mod asts = validScopes +validateScopes mod asts = validScopes ++ validEvs where refMap = generateReferencesMap asts -- We use a refmap for most of the computation + evs = M.keys + $ M.filter (any isEvidenceContext . concatMap (S.toList . identInfo . snd)) refMap + + validEvs = do + i@(Right ev) <- evs + case M.lookup i refMap of + Nothing -> ["Impossible, ev"<+> ppr ev <+> "not found in refmap" ] + Just refs + | nameIsLocalOrFrom mod ev + , not (any isEvidenceBind . concatMap (S.toList . identInfo . snd) $ refs) + -> ["Evidence var" <+> ppr ev <+> "not bound in refmap"] + | otherwise -> [] + -- Check if all the names occur in their calculated scopes validScopes = M.foldrWithKey (\k a b -> valid k a ++ b) [] refMap valid (Left _) _ = [] @@ -122,15 +135,18 @@ validateScopes mod asts = validScopes Just xs -> xs Nothing -> [] inScope (sp, dets) - | (definedInAsts asts n) + | (definedInAsts asts n || (any isEvidenceContext (identInfo dets))) && any isOccurrence (identInfo dets) -- We validate scopes for names which are defined locally, and occur - -- in this span + -- in this span, or are evidence variables = case scopes of - [] | (nameIsLocalOrFrom mod n - && not (isDerivedOccName $ nameOccName n)) - -- If we don't get any scopes for a local name then its an error. - -- We can ignore derived names. + [] | nameIsLocalOrFrom mod n + , ( not (isDerivedOccName $ nameOccName n) + || any isEvidenceContext (identInfo dets)) + -- If we don't get any scopes for a local name or + -- an evidence variable, then its an error. + -- We can ignore other kinds of derived names as + -- long as we take evidence vars into account -> return $ hsep $ [ "Locally defined Name", ppr n,pprDefinedAt n , "at position", ppr sp , "Doesn't have a calculated scope: ", ppr scopes] ===================================== compiler/GHC/Iface/Ext/Types.hs ===================================== @@ -17,13 +17,16 @@ import GHC.Prelude import GHC.Settings.Config import GHC.Utils.Binary import GHC.Data.FastString ( FastString ) +import GHC.Builtin.Utils import GHC.Iface.Type -import GHC.Unit.Module ( ModuleName, Module ) -import GHC.Types.Name ( Name ) +import GHC.Unit.Module ( ModuleName, Module ) +import GHC.Types.Name import GHC.Utils.Outputable hiding ( (<>) ) -import GHC.Types.SrcLoc ( RealSrcSpan ) +import GHC.Types.SrcLoc import GHC.Types.Avail +import GHC.Types.Unique import qualified GHC.Utils.Outputable as O ( (<>) ) +import GHC.Utils.Misc import qualified Data.Array as A import qualified Data.Map as M @@ -33,6 +36,8 @@ import Data.Data ( Typeable, Data ) import Data.Semigroup ( Semigroup(..) ) import Data.Word ( Word8 ) import Control.Applicative ( (<|>) ) +import Data.Coerce ( coerce ) +import Data.Function ( on ) type Span = RealSrcSpan @@ -222,17 +227,16 @@ instance Outputable a => Outputable (HieASTs a) where , rest ] - data HieAST a = Node - { nodeInfo :: NodeInfo a + { sourcedNodeInfo :: SourcedNodeInfo a , nodeSpan :: Span , nodeChildren :: [HieAST a] } deriving (Functor, Foldable, Traversable) instance Binary (HieAST TypeIndex) where put_ bh ast = do - put_ bh $ nodeInfo ast + put_ bh $ sourcedNodeInfo ast put_ bh $ nodeSpan ast put_ bh $ nodeChildren ast @@ -247,6 +251,38 @@ instance Outputable a => Outputable (HieAST a) where header = text "Node@" O.<> ppr sp O.<> ":" <+> ppr ni rest = vcat (map ppr ch) + +-- | NodeInfos grouped by source +newtype SourcedNodeInfo a = SourcedNodeInfo { getSourcedNodeInfo :: (M.Map NodeOrigin (NodeInfo a)) } + deriving (Functor, Foldable, Traversable) + +instance Binary (SourcedNodeInfo TypeIndex) where + put_ bh asts = put_ bh $ M.toAscList $ getSourcedNodeInfo asts + get bh = SourcedNodeInfo <$> fmap M.fromDistinctAscList (get bh) + +instance Outputable a => Outputable (SourcedNodeInfo a) where + ppr (SourcedNodeInfo asts) = M.foldrWithKey go "" asts + where + go k a rest = vcat $ + [ "Source: " O.<> ppr k + , ppr a + , rest + ] + +-- | Source of node info +data NodeOrigin + = SourceInfo + | GeneratedInfo + deriving (Eq, Enum, Ord) + +instance Outputable NodeOrigin where + ppr SourceInfo = text "From source" + ppr GeneratedInfo = text "generated by ghc" + +instance Binary NodeOrigin where + put_ bh b = putByte bh (fromIntegral (fromEnum b)) + get bh = do x <- getByte bh; pure $! (toEnum (fromIntegral x)) + -- | The information stored in one AST node. -- -- The type parameter exists to provide flexibility in representation of types @@ -314,7 +350,7 @@ instance Monoid (IdentifierDetails a) where instance Binary (IdentifierDetails TypeIndex) where put_ bh dets = do put_ bh $ identType dets - put_ bh $ S.toAscList $ identInfo dets + put_ bh $ S.toList $ identInfo dets get bh = IdentifierDetails <$> get bh <*> fmap S.fromDistinctAscList (get bh) @@ -363,6 +399,14 @@ data ContextInfo -- | Record field | RecField RecFieldContext (Maybe Span) + -- | Constraint/Dictionary evidence variable binding + | EvidenceVarBind + EvVarSource -- ^ how did this bind come into being + Scope -- ^ scope over which the value is bound + (Maybe Span) -- ^ span of the binding site + + -- | Usage of evidence variable + | EvidenceVarUse deriving (Eq, Ord) instance Outputable ContextInfo where @@ -385,10 +429,16 @@ instance Outputable ContextInfo where <+> ppr sc1 <+> "," <+> ppr sc2 ppr (RecField ctx sp) = text "record field" <+> ppr ctx <+> pprBindSpan sp + ppr (EvidenceVarBind ctx sc sp) = + text "evidence variable" <+> ppr ctx + $$ "with scope:" <+> ppr sc + $$ pprBindSpan sp + ppr (EvidenceVarUse) = + text "usage of evidence variable" pprBindSpan :: Maybe Span -> SDoc pprBindSpan Nothing = text "" -pprBindSpan (Just sp) = text "at:" <+> ppr sp +pprBindSpan (Just sp) = text "bound at:" <+> ppr sp instance Binary ContextInfo where put_ bh Use = putByte bh 0 @@ -422,6 +472,12 @@ instance Binary ContextInfo where put_ bh a put_ bh b put_ bh MatchBind = putByte bh 9 + put_ bh (EvidenceVarBind a b c) = do + putByte bh 10 + put_ bh a + put_ bh b + put_ bh c + put_ bh EvidenceVarUse = putByte bh 11 get bh = do (t :: Word8) <- get bh @@ -436,8 +492,69 @@ instance Binary ContextInfo where 7 -> TyVarBind <$> get bh <*> get bh 8 -> RecField <$> get bh <*> get bh 9 -> return MatchBind + 10 -> EvidenceVarBind <$> get bh <*> get bh <*> get bh + 11 -> return EvidenceVarUse _ -> panic "Binary ContextInfo: invalid tag" +data EvVarSource + = EvPatternBind -- ^ bound by a pattern match + | EvSigBind -- ^ bound by a type signature + | EvWrapperBind -- ^ bound by a hswrapper + | EvImplicitBind -- ^ bound by an implicit variable + | EvInstBind { isSuperInst :: Bool, cls :: Name } -- ^ Bound by some instance of given class + | EvLetBind EvBindDeps -- ^ A direct let binding + deriving (Eq,Ord) + +instance Binary EvVarSource where + put_ bh EvPatternBind = putByte bh 0 + put_ bh EvSigBind = putByte bh 1 + put_ bh EvWrapperBind = putByte bh 2 + put_ bh EvImplicitBind = putByte bh 3 + put_ bh (EvInstBind b cls) = do + putByte bh 4 + put_ bh b + put_ bh cls + put_ bh (EvLetBind deps) = do + putByte bh 5 + put_ bh deps + + get bh = do + (t :: Word8) <- get bh + case t of + 0 -> pure EvPatternBind + 1 -> pure EvSigBind + 2 -> pure EvWrapperBind + 3 -> pure EvImplicitBind + 4 -> EvInstBind <$> get bh <*> get bh + 5 -> EvLetBind <$> get bh + _ -> panic "Binary EvVarSource: invalid tag" + +instance Outputable EvVarSource where + ppr EvPatternBind = text "bound by a pattern" + ppr EvSigBind = text "bound by a type signature" + ppr EvWrapperBind = text "bound by a HsWrapper" + ppr EvImplicitBind = text "bound by an implicit variable binding" + ppr (EvInstBind False cls) = text "bound by an instance of class" <+> ppr cls + ppr (EvInstBind True cls) = text "bound due to a superclass of " <+> ppr cls + ppr (EvLetBind deps) = text "bound by a let, depending on:" <+> ppr deps + +-- | Eq/Ord instances compare on the converted HieName, +-- as non-exported names may have different uniques after +-- a roundtrip +newtype EvBindDeps = EvBindDeps { getEvBindDeps :: [Name] } + deriving Outputable + +instance Eq EvBindDeps where + (==) = coerce ((==) `on` map toHieName) + +instance Ord EvBindDeps where + compare = coerce (compare `on` map toHieName) + +instance Binary EvBindDeps where + put_ bh (EvBindDeps xs) = put_ bh xs + get bh = EvBindDeps <$> get bh + + -- | Types of imports and exports data IEType = Import @@ -587,3 +704,46 @@ instance Binary TyVarScope where 0 -> ResolvedScopes <$> get bh 1 -> UnresolvedScope <$> get bh <*> get bh _ -> panic "Binary TyVarScope: invalid tag" + +-- | `Name`'s get converted into `HieName`'s before being written into @.hie@ +-- files. See 'toHieName' and 'fromHieName' for logic on how to convert between +-- these two types. +data HieName + = ExternalName !Module !OccName !SrcSpan + | LocalName !OccName !SrcSpan + | KnownKeyName !Unique + deriving (Eq) + +instance Ord HieName where + compare (ExternalName a b c) (ExternalName d e f) = compare (a,b) (d,e) `thenCmp` leftmost_smallest c f + -- TODO (int-index): Perhaps use RealSrcSpan in HieName? + compare (LocalName a b) (LocalName c d) = compare a c `thenCmp` leftmost_smallest b d + -- TODO (int-index): Perhaps use RealSrcSpan in HieName? + compare (KnownKeyName a) (KnownKeyName b) = nonDetCmpUnique a b + -- Not actually non deterministic as it is a KnownKey + compare ExternalName{} _ = LT + compare LocalName{} ExternalName{} = GT + compare LocalName{} _ = LT + compare KnownKeyName{} _ = GT + +instance Outputable HieName where + ppr (ExternalName m n sp) = text "ExternalName" <+> ppr m <+> ppr n <+> ppr sp + ppr (LocalName n sp) = text "LocalName" <+> ppr n <+> ppr sp + ppr (KnownKeyName u) = text "KnownKeyName" <+> ppr u + +hieNameOcc :: HieName -> OccName +hieNameOcc (ExternalName _ occ _) = occ +hieNameOcc (LocalName occ _) = occ +hieNameOcc (KnownKeyName u) = + case lookupKnownKeyName u of + Just n -> nameOccName n + Nothing -> pprPanic "hieNameOcc:unknown known-key unique" + (ppr (unpkUnique u)) + +toHieName :: Name -> HieName +toHieName name + | isKnownKeyName name = KnownKeyName (nameUnique name) + | isExternalName name = ExternalName (nameModule name) + (nameOccName name) + (nameSrcSpan name) + | otherwise = LocalName (nameOccName name) (nameSrcSpan name) ===================================== compiler/GHC/Iface/Ext/Utils.hs ===================================== @@ -1,7 +1,9 @@ {-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE ViewPatterns #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE DeriveFunctor #-} module GHC.Iface.Ext.Utils where import GHC.Prelude @@ -11,7 +13,9 @@ import GHC.Driver.Session ( DynFlags ) import GHC.Data.FastString ( FastString, mkFastString ) import GHC.Iface.Type import GHC.Types.Name hiding (varName) -import GHC.Utils.Outputable ( renderWithStyle, ppr, defaultUserStyle, initSDocContext ) +import GHC.Types.Name.Set +import GHC.Utils.Outputable hiding ( (<>) ) +import qualified GHC.Utils.Outputable as O import GHC.Types.SrcLoc import GHC.CoreToIface import GHC.Core.TyCon @@ -27,21 +31,26 @@ import qualified Data.Set as S import qualified Data.IntMap.Strict as IM import qualified Data.Array as A import Data.Data ( typeOf, typeRepTyCon, Data(toConstr) ) -import Data.Maybe ( maybeToList ) +import Data.Maybe ( maybeToList, mapMaybe) import Data.Monoid +import Data.List (find) import Data.Traversable ( for ) +import Data.Coerce import Control.Monad.Trans.State.Strict hiding (get) +import Control.Monad.Trans.Reader +import qualified Data.Tree as Tree +type RefMap a = M.Map Identifier [(Span, IdentifierDetails a)] generateReferencesMap :: Foldable f => f (HieAST a) - -> M.Map Identifier [(Span, IdentifierDetails a)] + -> RefMap a generateReferencesMap = foldr (\ast m -> M.unionWith (++) (go ast) m) M.empty where go ast = M.unionsWith (++) (this : map go (nodeChildren ast)) where - this = fmap (pure . (nodeSpan ast,)) $ nodeIdentifiers $ nodeInfo ast + this = fmap (pure . (nodeSpan ast,)) $ sourcedNodeIdents $ sourcedNodeInfo ast renderHieType :: DynFlags -> HieTypeFix -> String renderHieType dflags ht = renderWithStyle (initSDocContext dflags defaultUserStyle) (ppr $ hieTypeToIface ht) @@ -72,6 +81,73 @@ resolveVisibility kind ty_args foldType :: (HieType a -> a) -> HieTypeFix -> a foldType f (Roll t) = f $ fmap (foldType f) t +selectPoint :: HieFile -> (Int,Int) -> Maybe (HieAST Int) +selectPoint hf (sl,sc) = getFirst $ + flip foldMap (M.toList (getAsts $ hie_asts hf)) $ \(fs,ast) -> First $ + case selectSmallestContaining (sp fs) ast of + Nothing -> Nothing + Just ast' -> Just ast' + where + sloc fs = mkRealSrcLoc fs sl sc + sp fs = mkRealSrcSpan (sloc fs) (sloc fs) + +findEvidenceUse :: NodeIdentifiers a -> [Name] +findEvidenceUse ni = [n | (Right n, dets) <- xs, any isEvidenceUse (identInfo dets)] + where + xs = M.toList ni + +data EvidenceInfo a + = EvidenceInfo + { evidenceVar :: Name + , evidenceSpan :: RealSrcSpan + , evidenceType :: a + , evidenceDetails :: Maybe (EvVarSource, Scope, Maybe Span) + } deriving (Eq,Ord,Functor) + +instance (Outputable a) => Outputable (EvidenceInfo a) where + ppr (EvidenceInfo name span typ dets) = + hang (ppr name <+> text "at" <+> ppr span O.<> text ", of type:" <+> ppr typ) 4 $ + pdets $$ (pprDefinedAt name) + where + pdets = case dets of + Nothing -> text "is a usage of an external evidence variable" + Just (src,scp,spn) -> text "is an" <+> ppr (EvidenceVarBind src scp spn) + +getEvidenceTreesAtPoint :: HieFile -> RefMap a -> (Int,Int) -> Tree.Forest (EvidenceInfo a) +getEvidenceTreesAtPoint hf refmap point = + [t | Just ast <- pure $ selectPoint hf point + , n <- findEvidenceUse (sourcedNodeIdents $ sourcedNodeInfo ast) + , Just t <- pure $ getEvidenceTree refmap n + ] + +getEvidenceTree :: RefMap a -> Name -> Maybe (Tree.Tree (EvidenceInfo a)) +getEvidenceTree refmap var = go emptyNameSet var + where + go seen var + | var `elemNameSet` seen = Nothing + | otherwise = do + xs <- M.lookup (Right var) refmap + case find (any isEvidenceBind . identInfo . snd) xs of + Just (sp,dets) -> do + typ <- identType dets + (evdet,children) <- getFirst $ foldMap First $ do + det <- S.toList $ identInfo dets + case det of + EvidenceVarBind src@(EvLetBind (getEvBindDeps -> xs)) scp spn -> + pure $ Just ((src,scp,spn),mapMaybe (go $ extendNameSet seen var) xs) + EvidenceVarBind src scp spn -> pure $ Just ((src,scp,spn),[]) + _ -> pure Nothing + pure $ Tree.Node (EvidenceInfo var sp typ (Just evdet)) children + -- It is externally bound + Nothing -> getFirst $ foldMap First $ do + (sp,dets) <- xs + if (any isEvidenceUse $ identInfo dets) + then do + case identType dets of + Nothing -> pure Nothing + Just typ -> pure $ Just $ Tree.Node (EvidenceInfo var sp typ Nothing) [] + else pure Nothing + hieTypeToIface :: HieTypeFix -> IfaceType hieTypeToIface = foldType go where @@ -194,8 +270,10 @@ resolveTyVarScopeLocal ast asts = go ast resolveScope scope = scope go (Node info span children) = Node info' span $ map go children where - info' = info { nodeIdentifiers = idents } - idents = M.map resolveNameScope $ nodeIdentifiers info + info' = SourcedNodeInfo (updateNodeInfo <$> getSourcedNodeInfo info) + updateNodeInfo i = i { nodeIdentifiers = idents } + where + idents = M.map resolveNameScope $ nodeIdentifiers i getNameBinding :: Name -> M.Map FastString (HieAST a) -> Maybe Span getNameBinding n asts = do @@ -217,7 +295,7 @@ getNameBindingInClass n sp asts = do getFirst $ foldMap First $ do child <- flattenAst ast dets <- maybeToList - $ M.lookup (Right n) $ nodeIdentifiers $ nodeInfo child + $ M.lookup (Right n) $ sourcedNodeIdents $ sourcedNodeInfo child let binding = foldMap (First . getBindSiteFromContext) (identInfo dets) return (getFirst binding) @@ -232,7 +310,7 @@ getNameScopeAndBinding n asts = case nameSrcSpan n of getFirst $ foldMap First $ do -- @[] node <- flattenAst defNode dets <- maybeToList - $ M.lookup (Right n) $ nodeIdentifiers $ nodeInfo node + $ M.lookup (Right n) $ sourcedNodeIdents $ sourcedNodeInfo node scopes <- maybeToList $ foldMap getScopeFromContext (identInfo dets) let binding = foldMap (First . getBindSiteFromContext) (identInfo dets) return $ Just (scopes, getFirst binding) @@ -245,6 +323,7 @@ getScopeFromContext (ClassTyDecl _) = Just [ModuleScope] getScopeFromContext (Decl _ _) = Just [ModuleScope] getScopeFromContext (TyVarBind a (ResolvedScopes xs)) = Just $ a:xs getScopeFromContext (TyVarBind a _) = Just [a] +getScopeFromContext (EvidenceVarBind _ a _) = Just [a] getScopeFromContext _ = Nothing getBindSiteFromContext :: ContextInfo -> Maybe Span @@ -292,8 +371,27 @@ definedInAsts asts n = case nameSrcSpan n of RealSrcSpan sp _ -> srcSpanFile sp `elem` M.keys asts _ -> False +getEvidenceBindDeps :: ContextInfo -> [Name] +getEvidenceBindDeps (EvidenceVarBind (EvLetBind xs) _ _) = + getEvBindDeps xs +getEvidenceBindDeps _ = [] + +isEvidenceBind :: ContextInfo -> Bool +isEvidenceBind EvidenceVarBind{} = True +isEvidenceBind _ = False + +isEvidenceContext :: ContextInfo -> Bool +isEvidenceContext EvidenceVarUse = True +isEvidenceContext EvidenceVarBind{} = True +isEvidenceContext _ = False + +isEvidenceUse :: ContextInfo -> Bool +isEvidenceUse EvidenceVarUse = True +isEvidenceUse _ = False + isOccurrence :: ContextInfo -> Bool isOccurrence Use = True +isOccurrence EvidenceVarUse = True isOccurrence _ = False scopeContainsSpan :: Scope -> Span -> Bool @@ -304,7 +402,7 @@ scopeContainsSpan (LocalScope a) b = a `containsSpan` b -- | One must contain the other. Leaf nodes cannot contain anything combineAst :: HieAST Type -> HieAST Type -> HieAST Type combineAst a@(Node aInf aSpn xs) b@(Node bInf bSpn ys) - | aSpn == bSpn = Node (aInf `combineNodeInfo` bInf) aSpn (mergeAsts xs ys) + | aSpn == bSpn = Node (aInf `combineSourcedNodeInfo` bInf) aSpn (mergeAsts xs ys) | aSpn `containsSpan` bSpn = combineAst b a combineAst a (Node xs span children) = Node xs span (insertAst a children) @@ -312,6 +410,18 @@ combineAst a (Node xs span children) = Node xs span (insertAst a children) insertAst :: HieAST Type -> [HieAST Type] -> [HieAST Type] insertAst x = mergeAsts [x] +nodeInfo :: HieAST Type -> NodeInfo Type +nodeInfo = foldl' combineNodeInfo emptyNodeInfo . getSourcedNodeInfo . sourcedNodeInfo + +emptyNodeInfo :: NodeInfo a +emptyNodeInfo = NodeInfo S.empty [] M.empty + +sourcedNodeIdents :: SourcedNodeInfo a -> NodeIdentifiers a +sourcedNodeIdents = M.unionsWith (<>) . fmap nodeIdentifiers . getSourcedNodeInfo + +combineSourcedNodeInfo :: SourcedNodeInfo Type -> SourcedNodeInfo Type -> SourcedNodeInfo Type +combineSourcedNodeInfo = coerce $ M.unionWith combineNodeInfo + -- | Merge two nodes together. -- -- Precondition and postcondition: elements in 'nodeType' are ordered. @@ -404,11 +514,12 @@ mergeSortAsts = go . map pure simpleNodeInfo :: FastString -> FastString -> NodeInfo a simpleNodeInfo cons typ = NodeInfo (S.singleton (cons, typ)) [] M.empty -locOnly :: SrcSpan -> [HieAST a] -locOnly (RealSrcSpan span _) = - [Node e span []] - where e = NodeInfo S.empty [] M.empty -locOnly _ = [] +locOnly :: Monad m => SrcSpan -> ReaderT NodeOrigin m [HieAST a] +locOnly (RealSrcSpan span _) = do + org <- ask + let e = mkSourcedNodeInfo org $ emptyNodeInfo + pure [Node e span []] +locOnly _ = pure [] mkScope :: SrcSpan -> Scope mkScope (RealSrcSpan sp _) = LocalScope sp @@ -425,30 +536,37 @@ combineScopes x NoScope = x combineScopes (LocalScope a) (LocalScope b) = mkScope $ combineSrcSpans (RealSrcSpan a Nothing) (RealSrcSpan b Nothing) +mkSourcedNodeInfo :: NodeOrigin -> NodeInfo a -> SourcedNodeInfo a +mkSourcedNodeInfo org ni = SourcedNodeInfo $ M.singleton org ni + {-# INLINEABLE makeNode #-} makeNode - :: (Applicative m, Data a) + :: (Monad m, Data a) => a -- ^ helps fill in 'nodeAnnotations' (with 'Data') -> SrcSpan -- ^ return an empty list if this is unhelpful - -> m [HieAST b] -makeNode x spn = pure $ case spn of - RealSrcSpan span _ -> [Node (simpleNodeInfo cons typ) span []] - _ -> [] + -> ReaderT NodeOrigin m [HieAST b] +makeNode x spn = do + org <- ask + pure $ case spn of + RealSrcSpan span _ -> [Node (mkSourcedNodeInfo org $ simpleNodeInfo cons typ) span []] + _ -> [] where cons = mkFastString . show . toConstr $ x typ = mkFastString . show . typeRepTyCon . typeOf $ x {-# INLINEABLE makeTypeNode #-} makeTypeNode - :: (Applicative m, Data a) + :: (Monad m, Data a) => a -- ^ helps fill in 'nodeAnnotations' (with 'Data') -> SrcSpan -- ^ return an empty list if this is unhelpful -> Type -- ^ type to associate with the node - -> m [HieAST Type] -makeTypeNode x spn etyp = pure $ case spn of - RealSrcSpan span _ -> - [Node (NodeInfo (S.singleton (cons,typ)) [etyp] M.empty) span []] - _ -> [] + -> ReaderT NodeOrigin m [HieAST Type] +makeTypeNode x spn etyp = do + org <- ask + pure $ case spn of + RealSrcSpan span _ -> + [Node (mkSourcedNodeInfo org $ NodeInfo (S.singleton (cons,typ)) [etyp] M.empty) span []] + _ -> [] where cons = mkFastString . show . toConstr $ x typ = mkFastString . show . typeRepTyCon . typeOf $ x ===================================== compiler/GHC/Unit.hs ===================================== @@ -21,237 +21,334 @@ import GHC.Unit.State import GHC.Unit.Subst import GHC.Unit.Module --- Note [About Units] --- ~~~~~~~~~~~~~~~~~~ --- --- Haskell users are used to manipulate Cabal packages. These packages are --- identified by: --- - a package name :: String --- - a package version :: Version --- - (a revision number, when they are registered on Hackage) --- --- Cabal packages may contain several components (libraries, programs, --- testsuites). In GHC we are mostly interested in libraries because those are --- the components that can be depended upon by other components. Components in a --- package are identified by their component name. Historically only one library --- component was allowed per package, hence it didn't need a name. For this --- reason, component name may be empty for one library component in each --- package: --- - a component name :: Maybe String --- --- UnitId --- ------ --- --- Cabal libraries can be compiled in various ways (different compiler options --- or Cabal flags, different dependencies, etc.), hence using package name, --- package version and component name isn't enough to identify a built library. --- We use another identifier called UnitId: --- --- package name \ --- package version | ________ --- component name | hash of all this ==> | UnitId | --- Cabal flags | -------- --- compiler options | --- dependencies' UnitId / --- --- Fortunately GHC doesn't have to generate these UnitId: they are provided by --- external build tools (e.g. Cabal) with `-this-unit-id` command-line parameter. --- --- UnitIds are important because they are used to generate internal names --- (symbols, etc.). --- --- Wired-in units --- -------------- --- --- Certain libraries are known to the compiler, in that we know about certain --- entities that reside in these libraries. The compiler needs to declare static --- Modules and Names that refer to units built from these libraries. --- --- Hence UnitIds of wired-in libraries are fixed. Instead of letting Cabal chose --- the UnitId for these libraries, their .cabal file uses the following stanza to --- force it to a specific value: --- --- ghc-options: -this-unit-id ghc-prim -- taken from ghc-prim.cabal --- --- The RTS also uses entities of wired-in units by directly referring to symbols --- such as "base_GHCziIOziException_heapOverflow_closure" where the prefix is --- the UnitId of "base" unit. --- --- Unit databases --- -------------- --- --- Units are stored in databases in order to be reused by other codes: --- --- UnitKey ---> UnitInfo { exposed modules, package name, package version --- component name, various file paths, --- dependencies :: [UnitKey], etc. } --- --- Because of the wired-in units described above, we can't exactly use UnitIds --- as UnitKeys in the database: if we did this, we could only have a single unit --- (compiled library) in the database for each wired-in library. As we want to --- support databases containing several different units for the same wired-in --- library, we do this: --- --- * for non wired-in units: --- * UnitId = UnitKey = Identifier (hash) computed by Cabal --- --- * for wired-in units: --- * UnitKey = Identifier computed by Cabal (just like for non wired-in units) --- * UnitId = unit-id specified with -this-unit-id command-line flag --- --- We can expose several units to GHC via the `package-id ` --- command-line parameter. We must use the UnitKeys of the units so that GHC can --- find them in the database. --- --- GHC then replaces the UnitKeys with UnitIds by taking into account wired-in --- units: these units are detected thanks to their UnitInfo (especially their --- package name). --- --- For example, knowing that "base", "ghc-prim" and "rts" are wired-in packages, --- the following dependency graph expressed with UnitKeys (as found in the --- database) will be transformed into a similar graph expressed with UnitIds --- (that are what matters for compilation): --- --- UnitKeys --- ~~~~~~~~ ---> rts-1.0-hashABC <-- --- | | --- | | --- foo-2.0-hash123 --> base-4.1-hashXYZ ---> ghc-prim-0.5.3-hashABC --- --- UnitIds --- ~~~~~~~ ---> rts <-- --- | | --- | | --- foo-2.0-hash123 --> base ---------------> ghc-prim --- --- --- Module signatures / indefinite units / instantiated units --- --------------------------------------------------------- --- --- GHC distinguishes two kinds of units: --- --- * definite: units for which every module has an associated code object --- (i.e. real compiled code in a .o/.a/.so/.dll/...) --- --- * indefinite: units for which some modules are replaced by module --- signatures. --- --- Module signatures are a kind of interface (similar to .hs-boot files). They --- are used in place of some real code. GHC allows real modules from other --- units to be used to fill these module holes. The process is called --- "unit/module instantiation". --- --- You can think of this as polymorphism at the module level: module signatures --- give constraints on the "type" of module that can be used to fill the hole --- (where "type" means types of the exported module entitites, etc.). --- --- Module signatures contain enough information (datatypes, abstract types, type --- synonyms, classes, etc.) to typecheck modules depending on them but not --- enough to compile them. As such, indefinite units found in databases only --- provide module interfaces (the .hi ones this time), not object code. --- --- To distinguish between indefinite and finite unit ids at the type level, we --- respectively use 'IndefUnitId' and 'DefUnitId' datatypes that are basically --- wrappers over 'UnitId'. --- --- Unit instantiation --- ------------------ --- --- Indefinite units can be instantiated with modules from other units. The --- instantiating units can also be instantiated themselves (if there are --- indefinite) and so on. The 'Unit' datatype represents a unit which may have --- been instantiated: --- --- data Unit = RealUnit DefUnitId --- | VirtUnit InstantiatedUnit --- --- 'InstantiatedUnit' has two interesting fields: --- --- * instUnitInstanceOf :: IndefUnitId --- -- ^ the indefinite unit that is instantiated --- --- * instUnitInsts :: [(ModuleName,(Unit,ModuleName)] --- -- ^ a list of instantiations, where an instantiation is: --- (module hole name, (instantiating unit, instantiating module name)) --- --- A 'Unit' may be indefinite or definite, it depends on whether some holes --- remain in the instantiated unit OR in the instantiating units (recursively). --- --- Pretty-printing UnitId --- ---------------------- --- --- GHC mostly deals with UnitIds which are some opaque strings. We could display --- them when we pretty-print a module origin, a name, etc. But it wouldn't be --- very friendly to the user because of the hash they usually contain. E.g. --- --- foo-4.18.1:thelib-XYZsomeUglyHashABC --- --- Instead when we want to pretty-print a 'UnitId' we query the database to --- get the 'UnitInfo' and print something nicer to the user: --- --- foo-4.18.1:thelib --- --- We do the same for wired-in units. --- --- Currently (2020-04-06), we don't thread the database into every function that --- pretty-prints a Name/Module/Unit. Instead querying the database is delayed --- until the `SDoc` is transformed into a `Doc` using the database that is --- active at this point in time. This is an issue because we want to be able to --- unload units from the database and we also want to support several --- independent databases loaded at the same time (see #14335). The alternatives --- we have are: --- --- * threading the database into every function that pretty-prints a UnitId --- for the user (directly or indirectly). --- --- * storing enough info to correctly display a UnitId into the UnitId --- datatype itself. This is done in the IndefUnitId wrapper (see --- 'UnitPprInfo' datatype) but not for every 'UnitId'. Statically defined --- 'UnitId' for wired-in units would have empty UnitPprInfo so we need to --- find some places to update them if we want to display wired-in UnitId --- correctly. This leads to a solution similar to the first one above. --- --- Note [VirtUnit to RealUnit improvement] --- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --- --- Over the course of instantiating VirtUnits on the fly while typechecking an --- indefinite library, we may end up with a fully instantiated VirtUnit. I.e. --- one that could be compiled and installed in the database. During --- type-checking we generate a virtual UnitId for it, say "abc". --- --- Now the question is: do we have a matching installed unit in the database? --- Suppose we have one with UnitId "xyz" (provided by Cabal so we don't know how --- to generate it). The trouble is that if both units end up being used in the --- same type-checking session, their names won't match (e.g. "abc:M.X" vs --- "xyz:M.X"). --- --- As we want them to match we just replace the virtual unit with the installed --- one: for some reason this is called "improvement". --- --- There is one last niggle: improvement based on the package database means --- that we might end up developing on a package that is not transitively --- depended upon by the packages the user specified directly via command line --- flags. This could lead to strange and difficult to understand bugs if those --- instantiations are out of date. The solution is to only improve a --- unit id if the new unit id is part of the 'preloadClosure'; i.e., the --- closure of all the packages which were explicitly specified. - --- Note [Representation of module/name variables] --- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --- In our ICFP'16, we use to represent module holes, and {A.T} to represent --- name holes. This could have been represented by adding some new cases --- to the core data types, but this would have made the existing 'moduleName' --- and 'moduleUnit' partial, which would have required a lot of modifications --- to existing code. --- --- Instead, we use a fake "hole" unit: --- --- ===> hole:A --- {A.T} ===> hole:A.T --- --- This encoding is quite convenient, but it is also a bit dangerous too, --- because if you have a 'hole:A' you need to know if it's actually a --- 'Module' or just a module stored in a 'Name'; these two cases must be --- treated differently when doing substitutions. 'renameHoleModule' --- and 'renameHoleUnit' assume they are NOT operating on a --- 'Name'; 'NameShape' handles name substitutions exclusively. +{- + +Note [About Units] +~~~~~~~~~~~~~~~~~~ + +Haskell users are used to manipulate Cabal packages. These packages are +identified by: + - a package name :: String + - a package version :: Version + - (a revision number, when they are registered on Hackage) + +Cabal packages may contain several components (libraries, programs, +testsuites). In GHC we are mostly interested in libraries because those are +the components that can be depended upon by other components. Components in a +package are identified by their component name. Historically only one library +component was allowed per package, hence it didn't need a name. For this +reason, component name may be empty for one library component in each +package: + - a component name :: Maybe String + +UnitId +------ + +Cabal libraries can be compiled in various ways (different compiler options +or Cabal flags, different dependencies, etc.), hence using package name, +package version and component name isn't enough to identify a built library. +We use another identifier called UnitId: + + package name \ + package version | ________ + component name | hash of all this ==> | UnitId | + Cabal flags | -------- + compiler options | + dependencies' UnitId / + +Fortunately GHC doesn't have to generate these UnitId: they are provided by +external build tools (e.g. Cabal) with `-this-unit-id` command-line parameter. + +UnitIds are important because they are used to generate internal names +(symbols, etc.). + +Wired-in units +-------------- + +Certain libraries (ghc-prim, base, etc.) are known to the compiler and to the +RTS as they provide some basic primitives. Hence UnitIds of wired-in libraries +are fixed. Instead of letting Cabal chose the UnitId for these libraries, their +.cabal file uses the following stanza to force it to a specific value: + + ghc-options: -this-unit-id ghc-prim -- taken from ghc-prim.cabal + +The RTS also uses entities of wired-in units by directly referring to symbols +such as "base_GHCziIOziException_heapOverflow_closure" where the prefix is +the UnitId of "base" unit. + +Unit databases +-------------- + +Units are stored in databases in order to be reused by other codes: + + UnitKey ---> UnitInfo { exposed modules, package name, package version + component name, various file paths, + dependencies :: [UnitKey], etc. } + +Because of the wired-in units described above, we can't exactly use UnitIds +as UnitKeys in the database: if we did this, we could only have a single unit +(compiled library) in the database for each wired-in library. As we want to +support databases containing several different units for the same wired-in +library, we do this: + + * for non wired-in units: + * UnitId = UnitKey = Identifier (hash) computed by Cabal + + * for wired-in units: + * UnitKey = Identifier computed by Cabal (just like for non wired-in units) + * UnitId = unit-id specified with -this-unit-id command-line flag + +We can expose several units to GHC via the `package-id ` command-line +parameter. We must use the UnitKeys of the units so that GHC can find them in +the database. + +During unit loading, GHC replaces UnitKeys with UnitIds. It identifies wired +units by their package name (stored in their UnitInfo) and uses wired-in UnitIds +for them. + +For example, knowing that "base", "ghc-prim" and "rts" are wired-in units, the +following dependency graph expressed with database UnitKeys will be transformed +into a similar graph expressed with UnitIds: + + UnitKeys + ~~~~~~~~ ----------> rts-1.0-hashABC <-- + | | + | | + foo-2.0-hash123 --> base-4.1-hashXYZ ---> ghc-prim-0.5.3-hashUVW + + UnitIds + ~~~~~~~ ---------------> rts <-- + | | + | | + foo-2.0-hash123 --> base ---------------> ghc-prim + + +Note that "foo-2.0-hash123" isn't wired-in so its UnitId is the same as its UnitKey. + + +Module signatures / indefinite units / instantiated units +--------------------------------------------------------- + +GHC distinguishes two kinds of units: + + * definite units: + * units without module holes and with definite dependencies + * can be compiled into machine code (.o/.a/.so/.dll/...) + + * indefinite units: + * units with some module holes or with some indefinite dependencies + * can only be type-checked + +Module holes are constrained by module signatures (.hsig files). Module +signatures are a kind of interface (similar to .hs-boot files). They are used in +place of some real code. GHC allows modules from other units to be used to fill +these module holes: the process is called "unit/module instantiation". The +instantiating module may either be a concrete module or a module signature. In +the latter case, the signatures are merged to form a new one. + +You can think of this as polymorphism at the module level: module signatures +give constraints on the "type" of module that can be used to fill the hole +(where "type" means types of the exported module entitites, etc.). + +Module signatures contain enough information (datatypes, abstract types, type +synonyms, classes, etc.) to typecheck modules depending on them but not +enough to compile them. As such, indefinite units found in databases only +provide module interfaces (the .hi ones this time), not object code. + +To distinguish between indefinite and definite unit ids at the type level, we +respectively use 'IndefUnitId' and 'DefUnitId' datatypes that are basically +wrappers over 'UnitId'. + +Unit instantiation / on-the-fly instantiation +--------------------------------------------- + +Indefinite units can be instantiated with modules from other units. The +instantiating units can also be instantiated themselves (if there are +indefinite) and so on. + +On-the-fly unit instantiation is a tricky optimization explained in +http://blog.ezyang.com/2016/08/optimizing-incremental-compilation +Here is a summary: + + 1. Indefinite units can only be type-checked, not compiled into real code. + Type-checking produces interface files (.hi) which are incomplete for code + generation (they lack unfoldings, etc.) but enough to perform type-checking + of units depending on them. + + 2. Type-checking an instantiated unit is cheap as we only have to merge + interface files (.hi) of the instantiated unit and of the instantiating + units, hence it can be done on-the-fly. Interface files of the dependencies + can be concrete or produced on-the-fly recursively. + + 3. When we compile a unit, we mustn't use interfaces produced by the + type-checker (on-the-fly or not) for the instantiated unit dependencies + because they lack some information. + + 4. When we type-check an indefinite unit, we must be consistent about the + interfaces we use for each dependency: only those produced by the + type-checker (on-the-fly or not) or only those produced after a full + compilation, but not both at the same time. + + It can be tricky if we have the following kind of dependency graph: + + X (indefinite) ------> D (definite, compiled) -----> I (instantiated, definite, compiled) + |----------------------------------------------------^ + + Suppose we want to type-check unit X which depends on unit I and D: + * I is definite and compiled: we have compiled .hi files for its modules on disk + * I is instantiated: it is cheap to produce type-checker .hi files for its modules on-the-fly + + But we must not do: + + X (indefinite) ------> D (definite, compiled) -----> I (instantiated, definite, compiled) + |--------------------------------------------------> I (instantiated on-the-fly) + + ==> inconsistent module interfaces for I + + Nor: + + X (indefinite) ------> D (definite, compiled) -------v + |--------------------------------------------------> I (instantiated on-the-fly) + + ==> D's interfaces may refer to things that only exist in I's *compiled* interfaces + + An alternative would be to store both type-checked and compiled interfaces + for every compiled non-instantiated unit (instantiated unit can be done + on-the-fly) so that we could use type-checked interfaces of D in the + example above. But it would increase compilation time and unit size. + + +The 'Unit' datatype represents a unit which may have been instantiated +on-the-fly: + + data Unit = RealUnit DefUnitId -- use compiled interfaces on disk + | VirtUnit InstantiatedUnit -- use on-the-fly instantiation + +'InstantiatedUnit' has two interesting fields: + + * instUnitInstanceOf :: IndefUnitId + -- ^ the indefinite unit that is instantiated + + * instUnitInsts :: [(ModuleName,(Unit,ModuleName)] + -- ^ a list of instantiations, where an instantiation is: + (module hole name, (instantiating unit, instantiating module name)) + +A 'VirtUnit' may be indefinite or definite, it depends on whether some holes +remain in the instantiated unit OR in the instantiating units (recursively). +Having a fully instantiated (i.e. definite) virtual unit can lead to some issues +if there is a matching compiled unit in the preload closure. See Note [VirtUnit +to RealUnit improvement] + +Unit database and indefinite units +---------------------------------- + +We don't store partially instantiated units in the unit database. Units in the +database are either: + + * definite (fully instantiated or without holes): in this case we have + *compiled* module interfaces (.hi) and object codes (.o/.a/.so/.dll/...). + + * fully indefinite (not instantiated at all): in this case we only have + *type-checked* module interfaces (.hi). + +Note that indefinite units are stored as an instantiation of themselves where +each instantiating module is a module variable (see Note [Representation of +module/name variables]). E.g. + + "xyz" (UnitKey) ---> UnitInfo { instanceOf = "xyz" + , instantiatedWith = [A=,B=...] + , ... + } + +Note that non-instantiated units are also stored as an instantiation of +themselves. It is a reminiscence of previous terminology (when "instanceOf" was +"componentId"). E.g. + + "xyz" (UnitKey) ---> UnitInfo { instanceOf = "xyz" + , instantiatedWith = [] + , ... + } + +TODO: We should probably have `instanceOf :: Maybe IndefUnitId` instead. + + +Pretty-printing UnitId +---------------------- + +GHC mostly deals with UnitIds which are some opaque strings. We could display +them when we pretty-print a module origin, a name, etc. But it wouldn't be +very friendly to the user because of the hash they usually contain. E.g. + + foo-4.18.1:thelib-XYZsomeUglyHashABC + +Instead when we want to pretty-print a 'UnitId' we query the database to +get the 'UnitInfo' and print something nicer to the user: + + foo-4.18.1:thelib + +We do the same for wired-in units. + +Currently (2020-04-06), we don't thread the database into every function that +pretty-prints a Name/Module/Unit. Instead querying the database is delayed +until the `SDoc` is transformed into a `Doc` using the database that is +active at this point in time. This is an issue because we want to be able to +unload units from the database and we also want to support several +independent databases loaded at the same time (see #14335). The alternatives +we have are: + + * threading the database into every function that pretty-prints a UnitId + for the user (directly or indirectly). + + * storing enough info to correctly display a UnitId into the UnitId + datatype itself. This is done in the IndefUnitId wrapper (see + 'UnitPprInfo' datatype) but not for every 'UnitId'. Statically defined + 'UnitId' for wired-in units would have empty UnitPprInfo so we need to + find some places to update them if we want to display wired-in UnitId + correctly. This leads to a solution similar to the first one above. + +Note [VirtUnit to RealUnit improvement] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Over the course of instantiating VirtUnits on the fly while typechecking an +indefinite library, we may end up with a fully instantiated VirtUnit. I.e. +one that could be compiled and installed in the database. During +type-checking we generate a virtual UnitId for it, say "abc". + +Now the question is: do we have a matching installed unit in the database? +Suppose we have one with UnitId "xyz" (provided by Cabal so we don't know how +to generate it). The trouble is that if both units end up being used in the +same type-checking session, their names won't match (e.g. "abc:M.X" vs +"xyz:M.X"). + +As we want them to match we just replace the virtual unit with the installed +one: for some reason this is called "improvement". + +There is one last niggle: improvement based on the unit database means +that we might end up developing on a unit that is not transitively +depended upon by the units the user specified directly via command line +flags. This could lead to strange and difficult to understand bugs if those +instantiations are out of date. The solution is to only improve a +unit id if the new unit id is part of the 'preloadClosure'; i.e., the +closure of all the units which were explicitly specified. + +Note [Representation of module/name variables] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In our ICFP'16, we use to represent module holes, and {A.T} to represent +name holes. This could have been represented by adding some new cases +to the core data types, but this would have made the existing 'moduleName' +and 'moduleUnit' partial, which would have required a lot of modifications +to existing code. + +Instead, we use a fake "hole" unit: + + ===> hole:A + {A.T} ===> hole:A.T + +This encoding is quite convenient, but it is also a bit dangerous too, +because if you have a 'hole:A' you need to know if it's actually a +'Module' or just a module stored in a 'Name'; these two cases must be +treated differently when doing substitutions. 'renameHoleModule' +and 'renameHoleUnit' assume they are NOT operating on a +'Name'; 'NameShape' handles name substitutions exclusively. + +-} ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -655,14 +655,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/hiefile/should_compile/Scopes.hs ===================================== @@ -1,10 +1,33 @@ +{-# LANGUAGE PatternSynonyms, ViewPatterns #-} +{-# LANGUAGE ImplicitParams #-} {-# LANGUAGE RecordWildCards #-} module Scopes where + +-- Verify that evidence bound by patern +-- synonyms has correct scope +pattern LL :: Num a => a -> a +pattern LL x <- (subtract 1 -> x) + where + LL x = x + 1 + data T = C { x :: Int, y :: Char } --- Verify that names generated from record construction are in scope +-- Verify that names generated from record construction +-- have correct scope foo = C { x = 1 , y = 'a' } +-- Verify that implicit paramters have correct scope +bar :: (?x :: Int) => Int +bar = ?x + 1 + +baz :: Int +baz = bar + ?x + where ?x = 2 + +-- Verify that variables bound in pattern +-- synonyms have the correct scope +pattern A a b = (a , b) + -- Verify that record wildcards are in scope sdaf :: T sdaf = C{..} ===================================== testsuite/tests/hiefile/should_run/HieQueries.hs ===================================== @@ -0,0 +1,82 @@ +{-# LANGUAGE ScopedTypeVariables #-} +module Main where + +import System.Environment + +import GHC.Types.Name.Cache +import GHC.Types.SrcLoc +import GHC.Types.Unique.Supply +import GHC.Types.Name +import Data.Tree +import GHC.Iface.Ext.Binary +import GHC.Iface.Ext.Types +import GHC.Iface.Ext.Utils +import Data.Maybe (fromJust) +import GHC.Driver.Session +import GHC.SysTools +import GHC.Utils.Outputable ( Outputable, renderWithStyle, ppr, defaultUserStyle, initSDocContext, text) +import qualified Data.Map as M +import Data.Foldable + +class C a where + f :: a -> Char + +instance C Char where + f x = x + +instance C a => C [a] where + f x = 'a' + +foo :: C a => a -> Char +foo x = f [x] +-- ^ this is the point +point :: (Int,Int) +point = (31,9) + +bar :: Show x => x -> String +bar x = show [(1,x,A)] +-- ^ this is the point' +point' :: (Int,Int) +point' = (37,9) + +data A = A deriving Show + +makeNc :: IO NameCache +makeNc = do + uniq_supply <- mkSplitUniqSupply 'z' + return $ initNameCache uniq_supply [] + +dynFlagsForPrinting :: String -> IO DynFlags +dynFlagsForPrinting libdir = do + systemSettings <- initSysTools libdir + return $ defaultDynFlags systemSettings (LlvmConfig [] []) + +main = do + libdir:_ <- getArgs + df <- dynFlagsForPrinting libdir + nc <- makeNc + hfr <- readHieFile (NCU (\f -> pure $ snd $ f nc)) "HieQueries.hie" + let hf = hie_file_result hfr + refmap = generateReferencesMap $ getAsts $ hie_asts hf + explainEv df hf refmap point + explainEv df hf refmap point' + return () + +explainEv :: DynFlags -> HieFile -> RefMap Int -> (Int,Int) -> IO () +explainEv df hf refmap point = do + putStrLn $ replicate 26 '=' + putStrLn $ "At point " ++ show point ++ ", we found:" + putStrLn $ replicate 26 '=' + putStr $ drawForest ptrees + where + trees = getEvidenceTreesAtPoint hf refmap point + + ptrees = fmap (pprint . fmap expandType) <$> trees + + expandType = text . renderHieType df . + flip recoverFullType (hie_types hf) + + pretty = unlines . (++["└"]) . ("┌":) . map ("│ "++) . lines + + pprint = pretty . renderWithStyle (initSDocContext df sty) . ppr + sty = defaultUserStyle ===================================== testsuite/tests/hiefile/should_run/HieQueries.stdout ===================================== @@ -0,0 +1,98 @@ +========================== +At point (31,9), we found: +========================== +┌ +│ $dC at HieQueries.hs:31:1-13, of type: C [a] +│ is an evidence variable bound by a let, depending on: [$fC[], $dC] +│ with scope: LocalScope HieQueries.hs:31:1-13 +│ bound at: HieQueries.hs:31:1-13 +│ Defined at +└ +| ++- ┌ +| │ $fC[] at HieQueries.hs:27:10-21, of type: forall a. C a => C [a] +| │ is an evidence variable bound by an instance of class C +| │ with scope: ModuleScope +| │ +| │ Defined at HieQueries.hs:27:10 +| └ +| +`- ┌ + │ $dC at HieQueries.hs:31:1-13, of type: C a + │ is an evidence variable bound by a type signature + │ with scope: LocalScope HieQueries.hs:31:1-13 + │ bound at: HieQueries.hs:31:1-13 + │ Defined at + └ + +========================== +At point (37,9), we found: +========================== +┌ +│ $dShow at HieQueries.hs:37:1-22, of type: Show [(Integer, x, A)] +│ is an evidence variable bound by a let, depending on: [$fShow[], +│ $dShow] +│ with scope: LocalScope HieQueries.hs:37:1-22 +│ bound at: HieQueries.hs:37:1-22 +│ Defined at +└ +| ++- ┌ +| │ $fShow[] at HieQueries.hs:37:1-22, of type: forall a. Show a => Show [a] +| │ is a usage of an external evidence variable +| │ Defined in `GHC.Show' +| └ +| +`- ┌ + │ $dShow at HieQueries.hs:37:1-22, of type: Show (Integer, x, A) + │ is an evidence variable bound by a let, depending on: [$fShow(,,), + │ $dShow, $dShow, $dShow] + │ with scope: LocalScope HieQueries.hs:37:1-22 + │ bound at: HieQueries.hs:37:1-22 + │ Defined at + └ + | + +- ┌ + | │ $fShow(,,) at HieQueries.hs:37:1-22, of type: forall a b c. (Show a, Show b, Show c) => Show (a, b, c) + | │ is a usage of an external evidence variable + | │ Defined in `GHC.Show' + | └ + | + +- ┌ + | │ $dShow at HieQueries.hs:37:1-22, of type: Show Integer + | │ is an evidence variable bound by a let, depending on: [$fShowInteger] + | │ with scope: LocalScope HieQueries.hs:37:1-22 + | │ bound at: HieQueries.hs:37:1-22 + | │ Defined at + | └ + | | + | `- ┌ + | │ $fShowInteger at HieQueries.hs:37:1-22, of type: Show Integer + | │ is a usage of an external evidence variable + | │ Defined in `GHC.Show' + | └ + | + +- ┌ + | │ $dShow at HieQueries.hs:37:1-22, of type: Show x + | │ is an evidence variable bound by a type signature + | │ with scope: LocalScope HieQueries.hs:37:1-22 + | │ bound at: HieQueries.hs:37:1-22 + | │ Defined at + | └ + | + `- ┌ + │ $dShow at HieQueries.hs:37:1-22, of type: Show A + │ is an evidence variable bound by a let, depending on: [$fShowA] + │ with scope: LocalScope HieQueries.hs:37:1-22 + │ bound at: HieQueries.hs:37:1-22 + │ Defined at + └ + | + `- ┌ + │ $fShowA at HieQueries.hs:42:21-24, of type: Show A + │ is an evidence variable bound by an instance of class Show + │ with scope: ModuleScope + │ + │ Defined at HieQueries.hs:42:21 + └ + ===================================== testsuite/tests/hiefile/should_run/PatTypes.hs ===================================== @@ -42,16 +42,9 @@ dynFlagsForPrinting libdir = do systemSettings <- initSysTools libdir return $ defaultDynFlags systemSettings (LlvmConfig [] []) -selectPoint :: HieFile -> (Int,Int) -> HieAST Int -selectPoint hf (sl,sc) = case M.toList (getAsts $ hie_asts hf) of - [(fs,ast)] -> - case selectSmallestContaining (sp fs) ast of - Nothing -> error "point not found" - Just ast' -> ast' - _ -> error "map should only contain a single AST" - where - sloc fs = mkRealSrcLoc fs sl sc - sp fs = mkRealSrcSpan (sloc fs) (sloc fs) +selectPoint' :: HieFile -> (Int,Int) -> HieAST Int +selectPoint' hf loc = + maybe (error "point not found") id $ selectPoint hf loc main = do libdir:_ <- getArgs @@ -61,6 +54,6 @@ main = do let hf = hie_file_result hfr forM_ [p1,p2,p3,p4] $ \point -> do putStr $ "At " ++ show point ++ ", got type: " - let types = nodeType $ nodeInfo $ selectPoint hf point + let types = concatMap nodeType $ getSourcedNodeInfo $ sourcedNodeInfo $ selectPoint' hf point forM_ types $ \typ -> do putStrLn (renderHieType df $ recoverFullType typ (hie_types hf)) ===================================== testsuite/tests/hiefile/should_run/all.T ===================================== @@ -1 +1,2 @@ test('PatTypes', [extra_run_opts('"' + config.libdir + '"')], compile_and_run, ['-package ghc -fwrite-ide-info']) +test('HieQueries', [extra_run_opts('"' + config.libdir + '"')], compile_and_run, ['-package ghc -fwrite-ide-info']) ===================================== 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 ===================================== @@ -52,3 +52,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']) test('T13380b', [ grep_errmsg('bigDeadAction') ], 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']) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 8f340aef12df5f5df02d49ab5c6c5d7cccfa398b +Subproject commit 8134a3be2c01ab5f1b88fed86c4ad7cc2f417f0a View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c68ae868ac09e2904a4c724fdbd6bbcce7fcc725...38ad4a1965699128fb4858fc2b1fd8022cc9df49 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c68ae868ac09e2904a4c724fdbd6bbcce7fcc725...38ad4a1965699128fb4858fc2b1fd8022cc9df49 You're receiving 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 26 03:49:23 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Mon, 25 May 2020 23:49:23 -0400 Subject: [Git][ghc/ghc][wip/ticky-eventlog] 227 commits: Change zipWith to zipWithEqual in a few places Message-ID: <5ecc91c3419ed_6e2687ddb0815370c7@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/ticky-eventlog 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. - - - - - 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] - - - - - 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 - - - - - 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 - - - - - 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. - - - - - 78c6523c by Ben Gamari at 2020-05-21T12:13:01-04:00 nonmoving: Optimise the write barrier - - - - - 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). - - - - - 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 - - - - - b7a6b2f4 by Gleb Popov at 2020-05-21T12:15:26-04:00 gitlab-ci: Set locale to C.UTF-8. - - - - - 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. - - - - - 0004ccb8 by Tuan Le at 2020-05-21T12:16:46-04:00 llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 - - - - - 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 - - - - - 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 - - - - - 2b363ebb by Richard Eisenberg at 2020-05-21T12:18:45-04:00 MR template should ask for key part - - - - - a95bbd0b by Sebastian Graf at 2020-05-21T12:19:37-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. - - - - - d3d055b8 by Galen Huntington at 2020-05-21T12:20:18-04:00 Clarify pitfalls of NegativeLiterals; see #18022. - - - - - 1b508a9e by Alexey Kuleshevich at 2020-05-21T12:21:02-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" - - - - - 4ca0c8a1 by Andreas Klebinger at 2020-05-21T12:21: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. - - - - - a1275081 by Krzysztof Gogolewski at 2020-05-21T12:22:35-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 - - - - - 8a816e5f by Krzysztof Gogolewski at 2020-05-21T12:23:55-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. - - - - - 566cc73f by Sylvain Henry at 2020-05-21T12:24:45-04:00 Move isDynLinkName into GHC.Types.Name It doesn't belong into GHC.Unit.State - - - - - d830bbc9 by Adam Sandberg Ericsson at 2020-05-23T13:36:20-04:00 docs: fix formatting and add some links [skip ci] - - - - - 49301ad6 by Andrew Martin at 2020-05-23T13:37:01-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. - - - - - dcd6bdcc by Ben Gamari at 2020-05-23T13:37:48-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. - - - - - 82cb8913 by John Ericson at 2020-05-23T13:38:32-04:00 Fix #18145 and also avoid needless work with implicit vars - `forAllOrNothing` now is monadic, so we can trace whether we bind an explicit `forall` or not. - #18145 arose because the free vars calculation was needlessly complex. It is now greatly simplified. - Replaced some other implicit var code with `filterFreeVarsToBind`. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - a60dc835 by Ben Gamari at 2020-05-23T13:39:12-04:00 Bump process submodule Fixes #17926. - - - - - 856adf54 by Ben Gamari at 2020-05-23T13:40:21-04:00 users-guide: Clarify meaning of -haddock flag Fixes #18206. - - - - - 7ae57afd by Ben Gamari at 2020-05-23T13:41:03-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 - - - - - 63d30e60 by jneira at 2020-05-24T01:54:42-04:00 Add hie-bios script for windows systems It is a direct translation of the sh script - - - - - 59182b88 by jneira at 2020-05-24T01:54:42-04:00 Honour previous values for CABAL and CABFLAGS The immediate goal is let the hie-bios.bat script set CABFLAGS with `-v0` and remove all cabal output except the compiler arguments - - - - - 932dc54e by jneira at 2020-05-24T01:54:42-04:00 Add specific configuration for windows in hie.yaml - - - - - e0eda070 by jneira at 2020-05-24T01:54:42-04:00 Remove not needed hie-bios output - - - - - a0ea59d6 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Move Config module into GHC.Settings - - - - - 37430251 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Core.Arity into GHC.Core.Opt.Arity - - - - - a426abb9 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Hs.Types into GHC.Hs.Type See discussion in https://gitlab.haskell.org/ghc/ghc/issues/13009#note_268610 - - - - - 1c91a7a0 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Bump haddock submodule - - - - - 66bd24d1 by Ryan Scott at 2020-05-24T01:56:03-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. - - - - - 01c43634 by Matthew Pickering at 2020-05-24T01:56:42-04:00 Remove unused hs-boot file - - - - - 7a07aa71 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix cross-compiler build (#16051) - - - - - 15ccca16 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix distDir per stage - - - - - b420fb24 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix hp2ps error during cross-compilation Fixed by @alp (see https://gitlab.haskell.org/ghc/ghc/issues/16051#note_274265) - - - - - cd339ef0 by Joshua Price at 2020-05-24T15:22:56-04:00 Make Unicode brackets opening/closing tokens (#18225) The tokens `[|`, `|]`, `(|`, and `|)` are opening/closing tokens as described in GHC Proposal #229. This commit makes the unicode variants (`⟦`, `⟧`, `⦇`, and `⦈`) act the same as their ASCII counterparts. - - - - - 013d7120 by Ben Gamari at 2020-05-25T09:48:17-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. - - - - - 4c4312ed by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Drop redundant ad-hoc boot module check To determine whether the module is a boot module Coverage.addTicksToBinds was checking for a `boot` suffix in the module source filename. This is quite ad-hoc and shouldn't be necessary; the callsite in `deSugar` already checks that the module isn't a boot module. - - - - - 1abf3c84 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make tickBoxCount strict This could otherwise easily cause a leak of (+) thunks. - - - - - b2813750 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make ccIndices strict This just seems like a good idea. - - - - - 02e278eb by Ben Gamari at 2020-05-25T09:48:53-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. - - - - - b8c014ce by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Factor out addMixEntry - - - - - 733e82c0 by Ben Gamari at 2020-05-26T03:49:04+00:00 rts: Post ticky entry counts to the eventlog We currently only post the entry counters, not the other global counters as in my experience the former are more useful. We use the heap profiler's census period to decide when to dump. - - - - - 30 changed files: - + .git-ignore-revs - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/merge_request_templates/merge-request.md - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - 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/8280f0d885d68bfc4468e4e127e978c96d1bfad1...733e82c0528fe2a60a10369a80ad5fc5e5cdc1ae -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8280f0d885d68bfc4468e4e127e978c96d1bfad1...733e82c0528fe2a60a10369a80ad5fc5e5cdc1ae You're receiving 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 26 04:03:39 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Tue, 26 May 2020 00:03:39 -0400 Subject: [Git][ghc/ghc][wip/ticky-eventlog] rts: Post ticky entry counts to the eventlog Message-ID: <5ecc951b5e278_6e26c5c8abc15377b0@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/ticky-eventlog at Glasgow Haskell Compiler / GHC Commits: b4460b8f by Ben Gamari at 2020-05-26T04:03:31+00:00 rts: Post ticky entry counts to the eventlog We currently only post the entry counters, not the other global counters as in my experience the former are more useful. We use the heap profiler's census period to decide when to dump. - - - - - 11 changed files: - includes/rts/EventLogFormat.h - includes/rts/Flags.h - rts/Proftimer.c - rts/Proftimer.h - rts/RtsFlags.c - rts/RtsStartup.c - rts/Ticky.c - rts/Ticky.h - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h - rts/sm/GC.c Changes: ===================================== includes/rts/EventLogFormat.h ===================================== @@ -154,12 +154,15 @@ #define EVENT_CONC_UPD_REM_SET_FLUSH 206 #define EVENT_NONMOVING_HEAP_CENSUS 207 +#define EVENT_TICKY_COUNTER_DEF 210 +#define EVENT_TICKY_COUNTER_SAMPLE 211 + /* * The highest event code +1 that ghc itself emits. Note that some event * ranges higher than this are reserved but not currently emitted by ghc. * This must match the size of the EventDesc[] array in EventLog.c */ -#define NUM_GHC_EVENT_TAGS 208 +#define NUM_GHC_EVENT_TAGS 212 #if 0 /* DEPRECATED EVENTS: */ /* we don't actually need to record the thread, it's implicit */ ===================================== includes/rts/Flags.h ===================================== @@ -176,6 +176,7 @@ typedef struct _TRACE_FLAGS { bool nonmoving_gc; /* trace nonmoving GC events */ bool sparks_sampled; /* trace spark events by a sampled method */ bool sparks_full; /* trace spark events 100% accurately */ + bool ticky; /* trace ticky-ticky samples */ bool user; /* trace user events (emitted from Haskell code) */ char *trace_output; /* output filename for eventlog */ } TRACE_FLAGS; ===================================== rts/Proftimer.c ===================================== @@ -20,6 +20,12 @@ static bool do_prof_ticks = false; // enable profiling ticks static bool do_heap_prof_ticks = false; // enable heap profiling ticks +// Sampling of Ticky-Ticky profiler to eventlog +#if defined(TICKY_TICKY) && defined(TRACING) +static int ticks_to_ticky_sample = 0; +bool performTickySample = false; +#endif + // Number of ticks until next heap census static int ticks_to_heap_profile; @@ -83,6 +89,16 @@ handleProfTick(void) } #endif +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + ticks_to_ticky_sample--; + if (ticks_to_ticky_sample <= 0) { + ticks_to_ticky_sample = RtsFlags.ProfFlags.heapProfileIntervalTicks; + performTickySample = true; + } + } +#endif + if (do_heap_prof_ticks) { ticks_to_heap_profile--; if (ticks_to_heap_profile <= 0) { ===================================== rts/Proftimer.h ===================================== @@ -17,5 +17,6 @@ void stopHeapProfTimer ( void ); void startHeapProfTimer ( void ); extern bool performHeapProfile; +extern bool performTickySample; #include "EndPrivate.h" ===================================== rts/RtsFlags.c ===================================== @@ -234,6 +234,7 @@ void initRtsFlagsDefaults(void) RtsFlags.TraceFlags.sparks_sampled= false; RtsFlags.TraceFlags.sparks_full = false; RtsFlags.TraceFlags.user = false; + RtsFlags.TraceFlags.ticky = false; RtsFlags.TraceFlags.trace_output = NULL; #endif @@ -386,6 +387,9 @@ usage_text[] = { " p par spark events (sampled)", " f par spark events (full detail)", " u user events (emitted from Haskell code)", +#if defined(TICKY_TICKY) +" T ticky-ticky counter samples", +#endif " a all event classes above", # if defined(DEBUG) " t add time stamps (only useful with -v)", @@ -1791,6 +1795,11 @@ static void normaliseRtsOpts (void) "the compacting collector."); errorUsage(); } + + if (RtsFlags.TraceFlags.ticky && RtsFlags.TickyFlags.showTickyStats) { + barf("The ticky-ticky eventlog output cannot be used in conjunction with\n" + "+RTS -r."); + } } static void errorUsage (void) @@ -2233,6 +2242,15 @@ static void read_trace_flags(const char *arg) RtsFlags.TraceFlags.user = enabled; enabled = true; break; + case 'T': +#if defined(TICKY_TICKY) + RtsFlags.TraceFlags.ticky = enabled; + enabled = true; + break; +#else + errorBelch("Program not compiled with ticky-ticky support"); + break; +#endif default: errorBelch("unknown trace option: %c",*c); break; ===================================== rts/RtsStartup.c ===================================== @@ -415,6 +415,17 @@ hs_exit_(bool wait_foreign) */ exitTimer(true); + /* + * Dump the ticky counter definitions + * We do this at the end of execution since tickers are registered in the + * course of program execution. + */ +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + emitTickyCounterDefs(); + } +#endif + // set the terminal settings back to what they were #if !defined(mingw32_HOST_OS) resetTerminalSettings(); ===================================== rts/Ticky.c ===================================== @@ -10,6 +10,8 @@ #include "PosixSource.h" #include "Rts.h" +#include "eventlog/EventLog.h" + /* Catch-all top-level counter struct. Allocations from CAFs will go * here. */ @@ -46,6 +48,10 @@ static void printRegisteredCounterInfo (FILE *); /* fwd decl */ void PrintTickyInfo(void) { + if (RtsFlags.TraceFlags.ticky) { + barf("Ticky eventlog output can't be used with +RTS -r"); + } + unsigned long i; unsigned long tot_thk_enters = ENT_STATIC_THK_MANY_ctr + ENT_DYN_THK_MANY_ctr @@ -374,4 +380,19 @@ printRegisteredCounterInfo (FILE *tf) } } + +void emitTickyCounterDefs() +{ +#if defined(TRACING) + postTickyCounterDefs(ticky_entry_ctrs); +#endif +} + +void emitTickyCounterSamples() +{ +#if defined(TRACING) + postTickyCounterSamples(ticky_entry_ctrs); +#endif +} + #endif /* TICKY_TICKY */ ===================================== rts/Ticky.h ===================================== @@ -8,4 +8,11 @@ #pragma once -RTS_PRIVATE void PrintTickyInfo(void); +#include "BeginPrivate.h" + +void PrintTickyInfo(void); + +void emitTickyCounterSamples(void); +void emitTickyCounterDefs(void); + +#include "EndPrivate.h" ===================================== rts/eventlog/EventLog.c ===================================== @@ -119,7 +119,9 @@ char *EventDesc[] = { [EVENT_CONC_SWEEP_BEGIN] = "Begin concurrent sweep", [EVENT_CONC_SWEEP_END] = "End concurrent sweep", [EVENT_CONC_UPD_REM_SET_FLUSH] = "Update remembered set flushed", - [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census" + [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census", + [EVENT_TICKY_COUNTER_DEF] = "Ticky-ticky entry counter definition", + [EVENT_TICKY_COUNTER_SAMPLE] = "Ticky-ticky entry counter sample", }; // Event type. @@ -487,6 +489,14 @@ init_event_types(void) eventTypes[t].size = 13; break; + case EVENT_TICKY_COUNTER_DEF: // (counter_id, arity, arg_kinds, name) + eventTypes[t].size = EVENT_SIZE_DYNAMIC; + break; + + case EVENT_TICKY_COUNTER_SAMPLE: // (counter_id, entry_count, allocs, allocd) + eventTypes[t].size = 8*4; + break; + default: continue; /* ignore deprecated events */ } @@ -1472,6 +1482,56 @@ void postProfBegin(void) } #endif /* PROFILING */ +#if defined(TICKY_TICKY) +static void postTickyCounterDef(EventsBuf *eb, StgEntCounter *p) +{ + StgWord len = 8 + 2 + strlen(p->arg_kinds)+1 + strlen(p->str)+1; + ensureRoomForVariableEvent(eb, len); + postEventHeader(eb, EVENT_TICKY_COUNTER_DEF); + postPayloadSize(eb, len); + postWord64(eb, (uint64_t) p); + postWord16(eb, (uint16_t) p->arity); + postString(eb, p->arg_kinds); + postString(eb, p->str); +} + +void postTickyCounterDefs(StgEntCounter *counters) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = counters; p != NULL; p = p->link) { + postTickyCounterDef(&eventBuf, p); + } + RELEASE_LOCK(&eventBufMutex); +} + +static void postTickyCounterSample(EventsBuf *eb, StgEntCounter *p) +{ + if ( p->entry_count == 0 + && p->allocs == 0 + && p->allocd == 0) + return; + + ensureRoomForEvent(eb, EVENT_TICKY_COUNTER_SAMPLE); + postEventHeader(eb, EVENT_TICKY_COUNTER_SAMPLE); + postWord64(eb, (uint64_t) p); + postWord64(eb, p->entry_count); + postWord64(eb, p->allocs); + postWord64(eb, p->allocd); + p->entry_count = 0; + p->allocs = 0; + p->allocd = 0; +} + +void postTickyCounterSamples(StgEntCounter *counters) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = counters; p != NULL; p = p->link) { + postTickyCounterSample(&eventBuf, p); + } + RELEASE_LOCK(&eventBufMutex); +} +#endif /* TICKY_TICKY */ + void printAndClearEventBuf (EventsBuf *ebuf) { closeBlockMarker(ebuf); ===================================== rts/eventlog/EventLog.h ===================================== @@ -173,6 +173,11 @@ void postConcMarkEnd(StgWord32 marked_obj_count); void postNonmovingHeapCensus(int log_blk_size, const struct NonmovingAllocCensus *census); +#if defined(TICKY_TICKY) +void postTickyCounterDefs(StgEntCounter *p); +void postTickyCounterSamples(StgEntCounter *p); +#endif /* TICKY_TICKY */ + #else /* !TRACING */ INLINE_HEADER void postSchedEvent (Capability *cap STG_UNUSED, ===================================== rts/sm/GC.c ===================================== @@ -38,6 +38,7 @@ #include "Sanity.h" #include "BlockAlloc.h" #include "ProfHeap.h" +#include "Proftimer.h" #include "Weak.h" #include "Prelude.h" #include "RtsSignals.h" @@ -52,6 +53,7 @@ #include "CNF.h" #include "RtsFlags.h" #include "NonMoving.h" +#include "Ticky.h" #include // for memset() #include @@ -860,6 +862,16 @@ GarbageCollect (uint32_t collect_gen, ACQUIRE_SM_LOCK; } +#if defined(TICKY_TICKY) + // Post ticky counter sample. + // We do this at the end of execution since tickers are registered in the + // course of program execution. + if (performTickySample) { + emitTickyCounterSamples(); + performTickySample = false; + } +#endif + // send exceptions to any threads which were about to die RELEASE_SM_LOCK; resurrectThreads(resurrected_threads); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b4460b8f879a8232811f1e289181db9b94887cbd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b4460b8f879a8232811f1e289181db9b94887cbd You're receiving 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 26 04:12:13 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Tue, 26 May 2020 00:12:13 -0400 Subject: [Git][ghc/ghc][wip/ticky-eventlog] rts: Post ticky entry counts to the eventlog Message-ID: <5ecc971ddafa3_6e263f9ed71435d81538241@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/ticky-eventlog at Glasgow Haskell Compiler / GHC Commits: 6dc64b7c by Ben Gamari at 2020-05-26T04:12:06+00:00 rts: Post ticky entry counts to the eventlog We currently only post the entry counters, not the other global counters as in my experience the former are more useful. We use the heap profiler's census period to decide when to dump. - - - - - 12 changed files: - docs/users_guide/eventlog-formats.rst - includes/rts/EventLogFormat.h - includes/rts/Flags.h - rts/Proftimer.c - rts/Proftimer.h - rts/RtsFlags.c - rts/RtsStartup.c - rts/Ticky.c - rts/Ticky.h - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h - rts/sm/GC.c Changes: ===================================== docs/users_guide/eventlog-formats.rst ===================================== @@ -755,3 +755,34 @@ intended to provide insight into fragmentation of the non-moving heap. :field Word32: number of live blocks. Describes the occupancy of the *blk_sz* sub-heap. + +Ticky counters +~~~~~~~~~~~~~~ + +Programs compiled with :ghc-flag:`-ticky` and :ghc-flag:`-eventlog` and invoked +with ``+RTS -lT`` will emit periodic samples of the ticky entry counters to the +eventlog. + +.. event-type:: TICKY_COUNTER_DEF + + :tag: 210 + :length: variable + :field Word64: counter ID + :field Word16: arity/field count + :field String: argument kinds. This is the same as the synonymous field in the + textual ticky summary. + :field String: counter name + + Defines a ticky counter. + +.. event-type:: TICKY_COUNTER_SAMPLE + + :tag: 211 + :length: fixed + :field Word64: counter ID + :field Word64: number of times closures of this type has been entered. + :field Word64: number of allocations (words) + :field Word64: number of times this has been allocated (words). Only + produced for modules compiled with :ghc-flag:`-ticky-allocd`. + + Records the counter statistics at a moment in time. ===================================== includes/rts/EventLogFormat.h ===================================== @@ -154,12 +154,15 @@ #define EVENT_CONC_UPD_REM_SET_FLUSH 206 #define EVENT_NONMOVING_HEAP_CENSUS 207 +#define EVENT_TICKY_COUNTER_DEF 210 +#define EVENT_TICKY_COUNTER_SAMPLE 211 + /* * The highest event code +1 that ghc itself emits. Note that some event * ranges higher than this are reserved but not currently emitted by ghc. * This must match the size of the EventDesc[] array in EventLog.c */ -#define NUM_GHC_EVENT_TAGS 208 +#define NUM_GHC_EVENT_TAGS 212 #if 0 /* DEPRECATED EVENTS: */ /* we don't actually need to record the thread, it's implicit */ ===================================== includes/rts/Flags.h ===================================== @@ -176,6 +176,7 @@ typedef struct _TRACE_FLAGS { bool nonmoving_gc; /* trace nonmoving GC events */ bool sparks_sampled; /* trace spark events by a sampled method */ bool sparks_full; /* trace spark events 100% accurately */ + bool ticky; /* trace ticky-ticky samples */ bool user; /* trace user events (emitted from Haskell code) */ char *trace_output; /* output filename for eventlog */ } TRACE_FLAGS; ===================================== rts/Proftimer.c ===================================== @@ -20,6 +20,12 @@ static bool do_prof_ticks = false; // enable profiling ticks static bool do_heap_prof_ticks = false; // enable heap profiling ticks +// Sampling of Ticky-Ticky profiler to eventlog +#if defined(TICKY_TICKY) && defined(TRACING) +static int ticks_to_ticky_sample = 0; +bool performTickySample = false; +#endif + // Number of ticks until next heap census static int ticks_to_heap_profile; @@ -83,6 +89,16 @@ handleProfTick(void) } #endif +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + ticks_to_ticky_sample--; + if (ticks_to_ticky_sample <= 0) { + ticks_to_ticky_sample = RtsFlags.ProfFlags.heapProfileIntervalTicks; + performTickySample = true; + } + } +#endif + if (do_heap_prof_ticks) { ticks_to_heap_profile--; if (ticks_to_heap_profile <= 0) { ===================================== rts/Proftimer.h ===================================== @@ -17,5 +17,6 @@ void stopHeapProfTimer ( void ); void startHeapProfTimer ( void ); extern bool performHeapProfile; +extern bool performTickySample; #include "EndPrivate.h" ===================================== rts/RtsFlags.c ===================================== @@ -234,6 +234,7 @@ void initRtsFlagsDefaults(void) RtsFlags.TraceFlags.sparks_sampled= false; RtsFlags.TraceFlags.sparks_full = false; RtsFlags.TraceFlags.user = false; + RtsFlags.TraceFlags.ticky = false; RtsFlags.TraceFlags.trace_output = NULL; #endif @@ -386,6 +387,9 @@ usage_text[] = { " p par spark events (sampled)", " f par spark events (full detail)", " u user events (emitted from Haskell code)", +#if defined(TICKY_TICKY) +" T ticky-ticky counter samples", +#endif " a all event classes above", # if defined(DEBUG) " t add time stamps (only useful with -v)", @@ -1791,6 +1795,11 @@ static void normaliseRtsOpts (void) "the compacting collector."); errorUsage(); } + + if (RtsFlags.TraceFlags.ticky && RtsFlags.TickyFlags.showTickyStats) { + barf("The ticky-ticky eventlog output cannot be used in conjunction with\n" + "+RTS -r."); + } } static void errorUsage (void) @@ -2233,6 +2242,15 @@ static void read_trace_flags(const char *arg) RtsFlags.TraceFlags.user = enabled; enabled = true; break; + case 'T': +#if defined(TICKY_TICKY) + RtsFlags.TraceFlags.ticky = enabled; + enabled = true; + break; +#else + errorBelch("Program not compiled with ticky-ticky support"); + break; +#endif default: errorBelch("unknown trace option: %c",*c); break; ===================================== rts/RtsStartup.c ===================================== @@ -415,6 +415,17 @@ hs_exit_(bool wait_foreign) */ exitTimer(true); + /* + * Dump the ticky counter definitions + * We do this at the end of execution since tickers are registered in the + * course of program execution. + */ +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + emitTickyCounterDefs(); + } +#endif + // set the terminal settings back to what they were #if !defined(mingw32_HOST_OS) resetTerminalSettings(); ===================================== rts/Ticky.c ===================================== @@ -10,6 +10,8 @@ #include "PosixSource.h" #include "Rts.h" +#include "eventlog/EventLog.h" + /* Catch-all top-level counter struct. Allocations from CAFs will go * here. */ @@ -46,6 +48,10 @@ static void printRegisteredCounterInfo (FILE *); /* fwd decl */ void PrintTickyInfo(void) { + if (RtsFlags.TraceFlags.ticky) { + barf("Ticky eventlog output can't be used with +RTS -r"); + } + unsigned long i; unsigned long tot_thk_enters = ENT_STATIC_THK_MANY_ctr + ENT_DYN_THK_MANY_ctr @@ -374,4 +380,19 @@ printRegisteredCounterInfo (FILE *tf) } } + +void emitTickyCounterDefs() +{ +#if defined(TRACING) + postTickyCounterDefs(ticky_entry_ctrs); +#endif +} + +void emitTickyCounterSamples() +{ +#if defined(TRACING) + postTickyCounterSamples(ticky_entry_ctrs); +#endif +} + #endif /* TICKY_TICKY */ ===================================== rts/Ticky.h ===================================== @@ -8,4 +8,11 @@ #pragma once -RTS_PRIVATE void PrintTickyInfo(void); +#include "BeginPrivate.h" + +void PrintTickyInfo(void); + +void emitTickyCounterSamples(void); +void emitTickyCounterDefs(void); + +#include "EndPrivate.h" ===================================== rts/eventlog/EventLog.c ===================================== @@ -119,7 +119,9 @@ char *EventDesc[] = { [EVENT_CONC_SWEEP_BEGIN] = "Begin concurrent sweep", [EVENT_CONC_SWEEP_END] = "End concurrent sweep", [EVENT_CONC_UPD_REM_SET_FLUSH] = "Update remembered set flushed", - [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census" + [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census", + [EVENT_TICKY_COUNTER_DEF] = "Ticky-ticky entry counter definition", + [EVENT_TICKY_COUNTER_SAMPLE] = "Ticky-ticky entry counter sample", }; // Event type. @@ -487,6 +489,14 @@ init_event_types(void) eventTypes[t].size = 13; break; + case EVENT_TICKY_COUNTER_DEF: // (counter_id, arity, arg_kinds, name) + eventTypes[t].size = EVENT_SIZE_DYNAMIC; + break; + + case EVENT_TICKY_COUNTER_SAMPLE: // (counter_id, entry_count, allocs, allocd) + eventTypes[t].size = 8*4; + break; + default: continue; /* ignore deprecated events */ } @@ -1472,6 +1482,53 @@ void postProfBegin(void) } #endif /* PROFILING */ +#if defined(TICKY_TICKY) +static void postTickyCounterDef(EventsBuf *eb, StgEntCounter *p) +{ + StgWord len = 8 + 2 + strlen(p->arg_kinds)+1 + strlen(p->str)+1; + ensureRoomForVariableEvent(eb, len); + postEventHeader(eb, EVENT_TICKY_COUNTER_DEF); + postPayloadSize(eb, len); + postWord64(eb, (uint64_t) p); + postWord16(eb, (uint16_t) p->arity); + postString(eb, p->arg_kinds); + postString(eb, p->str); +} + +void postTickyCounterDefs(StgEntCounter *counters) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = counters; p != NULL; p = p->link) { + postTickyCounterDef(&eventBuf, p); + } + RELEASE_LOCK(&eventBufMutex); +} + +static void postTickyCounterSample(EventsBuf *eb, StgEntCounter *p) +{ + if ( p->entry_count == 0 + && p->allocs == 0 + && p->allocd == 0) + return; + + ensureRoomForEvent(eb, EVENT_TICKY_COUNTER_SAMPLE); + postEventHeader(eb, EVENT_TICKY_COUNTER_SAMPLE); + postWord64(eb, (uint64_t) p); + postWord64(eb, p->entry_count); + postWord64(eb, p->allocs); + postWord64(eb, p->allocd); +} + +void postTickyCounterSamples(StgEntCounter *counters) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = counters; p != NULL; p = p->link) { + postTickyCounterSample(&eventBuf, p); + } + RELEASE_LOCK(&eventBufMutex); +} +#endif /* TICKY_TICKY */ + void printAndClearEventBuf (EventsBuf *ebuf) { closeBlockMarker(ebuf); ===================================== rts/eventlog/EventLog.h ===================================== @@ -173,6 +173,11 @@ void postConcMarkEnd(StgWord32 marked_obj_count); void postNonmovingHeapCensus(int log_blk_size, const struct NonmovingAllocCensus *census); +#if defined(TICKY_TICKY) +void postTickyCounterDefs(StgEntCounter *p); +void postTickyCounterSamples(StgEntCounter *p); +#endif /* TICKY_TICKY */ + #else /* !TRACING */ INLINE_HEADER void postSchedEvent (Capability *cap STG_UNUSED, ===================================== rts/sm/GC.c ===================================== @@ -38,6 +38,7 @@ #include "Sanity.h" #include "BlockAlloc.h" #include "ProfHeap.h" +#include "Proftimer.h" #include "Weak.h" #include "Prelude.h" #include "RtsSignals.h" @@ -52,6 +53,7 @@ #include "CNF.h" #include "RtsFlags.h" #include "NonMoving.h" +#include "Ticky.h" #include // for memset() #include @@ -860,6 +862,16 @@ GarbageCollect (uint32_t collect_gen, ACQUIRE_SM_LOCK; } +#if defined(TICKY_TICKY) + // Post ticky counter sample. + // We do this at the end of execution since tickers are registered in the + // course of program execution. + if (performTickySample) { + emitTickyCounterSamples(); + performTickySample = false; + } +#endif + // send exceptions to any threads which were about to die RELEASE_SM_LOCK; resurrectThreads(resurrected_threads); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6dc64b7ca21a0efbdeb805833198768f7ec081f6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6dc64b7ca21a0efbdeb805833198768f7ec081f6 You're receiving 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 26 05:01:00 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Tue, 26 May 2020 01:01:00 -0400 Subject: [Git][ghc/ghc][wip/bump-base] base: Bump to 4.15.0.0 Message-ID: <5ecca28cb99f6_6e263f9f01f3c4801539335@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/bump-base at Glasgow Haskell Compiler / GHC Commits: bb811cac by Ben Gamari at 2020-05-26T01:00:51-04:00 base: Bump to 4.15.0.0 - - - - - 18 changed files: - libraries/array - libraries/base/base.cabal - libraries/deepseq - libraries/directory - libraries/filepath - libraries/ghc-boot-th/ghc-boot-th.cabal.in - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghc-compact/ghc-compact.cabal - libraries/ghci/ghci.cabal.in - libraries/haskeline - libraries/hpc - libraries/parsec - libraries/process - libraries/stm - libraries/template-haskell/template-haskell.cabal.in - libraries/terminfo - libraries/unix - utils/hsc2hs Changes: ===================================== libraries/array ===================================== @@ -1 +1 @@ -Subproject commit f73f681e52546b1e35cb9e8a62fe49c33f259d98 +Subproject commit ab535173d7885ebfc2005d8da2765f0f52c923ce ===================================== 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 ===================================== libraries/deepseq ===================================== @@ -1 +1 @@ -Subproject commit da0eda33f540786b6823c6f542ab59cf9d1b71d9 +Subproject commit 13c1c84415da727ab56e9fa33aca5046b6683848 ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit 36bd1921258b759724a95ce56c5e880edf0972a2 +Subproject commit 0dcb228388a6e306c11f419c7c5575eaa6af40b3 ===================================== libraries/filepath ===================================== @@ -1 +1 @@ -Subproject commit 023eedaeb142d47b7b5a41fe4cc4150da0bd0042 +Subproject commit 7cb3dc285cd595a7b6cf0b74a58b6583fb67772e ===================================== libraries/ghc-boot-th/ghc-boot-th.cabal.in ===================================== @@ -36,4 +36,4 @@ Library GHC.ForeignSrcLang.Type GHC.Lexeme - build-depends: base >= 4.7 && < 4.15 + build-depends: base >= 4.7 && < 4.16 ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -55,7 +55,7 @@ Library -- GHC.Version -- GHC.Platform.Host - build-depends: base >= 4.7 && < 4.15, + build-depends: base >= 4.7 && < 4.16, binary == 0.8.*, bytestring == 0.10.*, containers >= 0.5 && < 0.7, ===================================== libraries/ghc-compact/ghc-compact.cabal ===================================== @@ -37,7 +37,7 @@ library CPP build-depends: ghc-prim >= 0.5.3 && < 0.7, - base >= 4.9.0 && < 4.15, + base >= 4.9.0 && < 4.16, bytestring >= 0.10.6.0 ghc-options: -Wall ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -72,7 +72,7 @@ library Build-Depends: array == 0.5.*, - base >= 4.8 && < 4.15, + base >= 4.8 && < 4.16, binary == 0.8.*, bytestring == 0.10.*, containers >= 0.5 && < 0.7, ===================================== libraries/haskeline ===================================== @@ -1 +1 @@ -Subproject commit 463fc49d17bfab846cceba48bccc02ef285e6cba +Subproject commit 0382e3acdb8433e1d9c33ca5947784e78134f838 ===================================== libraries/hpc ===================================== @@ -1 +1 @@ -Subproject commit f73c482db30a40cfa12074de51335b70a0974931 +Subproject commit 43bb9061a748aee6a95a9f1db33a2b1e5f770634 ===================================== libraries/parsec ===================================== @@ -1 +1 @@ -Subproject commit ce416997e15438ca616667995660e123ef7e219d +Subproject commit 190492494fe92e8dd42165190b7ac112be1f7389 ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit 1afc36ecd38c069251a836e1c1c8b3a3043ddc01 +Subproject commit 8f4ecebb6578a179a6c04074cb06600683e2e50c ===================================== libraries/stm ===================================== @@ -1 +1 @@ -Subproject commit faf9904137044e35a589c7c1579e1bfa03789c84 +Subproject commit 444f672416a354c3cfde9d94ec237a36be46ef59 ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -55,7 +55,7 @@ Library Language.Haskell.TH.Lib.Map build-depends: - base >= 4.11 && < 4.15, + base >= 4.11 && < 4.16, ghc-boot-th == @ProjectVersionMunged@, ghc-prim, pretty == 1.1.* ===================================== libraries/terminfo ===================================== @@ -1 +1 @@ -Subproject commit 27e694688d2d6eee69959a8b6a128c584c84aa72 +Subproject commit 3ebb36f4a2c42b74ec4e35efccc2be34c198a830 ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 1a993b89c570e03ba74f196f5d065a0ebe624010 +Subproject commit ea13d990580273a883368793dfbb826cab5a22d4 ===================================== utils/hsc2hs ===================================== @@ -1 +1 @@ -Subproject commit 24100ea521596922d3edc8370b3d9f7b845ae4cf +Subproject commit e792dd8e5589d42a4d416f78df8efb70995f95e3 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bb811cac5504d1c820533aa1c5a6c9b9749524de -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bb811cac5504d1c820533aa1c5a6c9b9749524de You're receiving 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 26 07:03:39 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 26 May 2020 03:03:39 -0400 Subject: [Git][ghc/ghc][master] Add info about typeclass evidence to .hie files Message-ID: <5eccbf4bd6559_6e263f9ed71435d815519e2@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 53814a64 by Zubin Duggal at 2020-05-26T03:03:24-04:00 Add info about typeclass evidence to .hie files See `testsuite/tests/hiefile/should_run/HieQueries.hs` and `testsuite/tests/hiefile/should_run/HieQueries.stdout` for an example of this We add two new fields, `EvidenceVarBind` and `EvidenceVarUse` to the `ContextInfo` associated with an Identifier. These are associated with the appropriate identifiers for the evidence variables collected when we come across `HsWrappers`, `TcEvBinds` and `IPBinds` while traversing the AST. Instance dictionary and superclass selector dictionaries from `tcg_insts` and classes defined in `tcg_tcs` are also recorded in the AST as originating from their definition span This allows us to save a complete picture of the evidence constructed by the constraint solver, and will let us report this to the user, enabling features like going to the instance definition from the invocation of a class method(or any other method taking a constraint) and finding all usages of a particular instance. Additionally, - Mark NodeInfo with an origin so we can differentiate between bindings origininating in the source vs those in ghc - Along with typeclass evidence info, also include information on Implicit Parameters - Add a few utility functions to HieUtils in order to query the new info Updates haddock submodule - - - - - 11 changed files: - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Debug.hs - compiler/GHC/Iface/Ext/Types.hs - compiler/GHC/Iface/Ext/Utils.hs - testsuite/tests/hiefile/should_compile/Scopes.hs - + testsuite/tests/hiefile/should_run/HieQueries.hs - + testsuite/tests/hiefile/should_run/HieQueries.stdout - testsuite/tests/hiefile/should_run/PatTypes.hs - testsuite/tests/hiefile/should_run/all.T - utils/haddock Changes: ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -13,36 +13,47 @@ Main functions for .hie file generation {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE DeriveDataTypeable #-} +{-# LANGUAGE TupleSections #-} {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} module GHC.Iface.Ext.Ast ( mkHieFile, mkHieFileWithSource, getCompressedAsts) where +import GHC.Utils.Outputable(ppr) + import GHC.Prelude import GHC.Types.Avail ( Avails ) import GHC.Data.Bag ( Bag, bagToList ) import GHC.Types.Basic import GHC.Data.BooleanFormula -import GHC.Core.Class ( FunDep ) +import GHC.Core.Class ( FunDep, className, classSCSelIds ) import GHC.Core.Utils ( exprType ) import GHC.Core.ConLike ( conLikeName ) +import GHC.Core.TyCon ( TyCon, tyConClass_maybe ) +import GHC.Core.FVs import GHC.HsToCore ( deSugarExpr ) import GHC.Types.FieldLabel import GHC.Hs import GHC.Driver.Types import GHC.Unit.Module ( ModuleName, ml_hs_file ) import GHC.Utils.Monad ( concatMapM, liftIO ) -import GHC.Types.Name ( Name, nameSrcSpan, setNameLoc ) +import GHC.Types.Name ( Name, nameSrcSpan, setNameLoc, nameUnique ) import GHC.Types.Name.Env ( NameEnv, emptyNameEnv, extendNameEnv, lookupNameEnv ) import GHC.Types.SrcLoc import GHC.Tc.Utils.Zonk ( hsLitType, hsPatType ) import GHC.Core.Type ( mkVisFunTys, Type ) +import GHC.Core.Predicate +import GHC.Core.InstEnv import GHC.Builtin.Types ( mkListTy, mkSumTy ) -import GHC.Types.Var ( Id, Var, setVarName, varName, varType ) import GHC.Tc.Types +import GHC.Tc.Types.Evidence +import GHC.Types.Var ( Id, Var, EvId, setVarName, varName, varType, varUnique ) +import GHC.Types.Var.Env +import GHC.Types.Unique import GHC.Iface.Make ( mkIfaceExports ) import GHC.Utils.Panic import GHC.Data.Maybe +import GHC.Data.FastString import GHC.Iface.Ext.Types import GHC.Iface.Ext.Utils @@ -53,6 +64,8 @@ import qualified Data.Map as M import qualified Data.Set as S import Data.Data ( Data, Typeable ) import Data.List ( foldl1' ) +import Control.Monad ( forM_ ) +import Control.Monad.Trans.State.Strict import Control.Monad.Trans.Reader import Control.Monad.Trans.Class ( lift ) @@ -196,12 +209,47 @@ The Typechecker introduces new names for mono names in AbsBinds. We don't care about the distinction between mono and poly bindings, so we replace all occurrences of the mono name with the poly name. -} -newtype HieState = HieState +type VarMap a = DVarEnv (Var,a) +data HieState = HieState { name_remapping :: NameEnv Id + , unlocated_ev_binds :: VarMap (S.Set ContextInfo) + -- These contain evidence bindings that we don't have a location for + -- These are placed at the top level Node in the HieAST after everything + -- else has been generated + -- This includes things like top level evidence bindings. } +addUnlocatedEvBind :: Var -> ContextInfo -> HieM () +addUnlocatedEvBind var ci = do + let go (a,b) (_,c) = (a,S.union b c) + lift $ modify' $ \s -> + s { unlocated_ev_binds = + extendDVarEnv_C go (unlocated_ev_binds s) + var (var,S.singleton ci) + } + +getUnlocatedEvBinds :: FastString -> HieM (NodeIdentifiers Type,[HieAST Type]) +getUnlocatedEvBinds file = do + binds <- lift $ gets unlocated_ev_binds + org <- ask + let elts = dVarEnvElts binds + + mkNodeInfo (n,ci) = (Right (varName n), IdentifierDetails (Just $ varType n) ci) + + go e@(v,_) (xs,ys) = case nameSrcSpan $ varName v of + RealSrcSpan spn _ + | srcSpanFile spn == file -> + let node = Node (mkSourcedNodeInfo org ni) spn [] + ni = NodeInfo mempty [] $ M.fromList [mkNodeInfo e] + in (xs,node:ys) + _ -> (mkNodeInfo e : xs,ys) + + (nis,asts) = foldr go ([],[]) elts + + pure $ (M.fromList nis, asts) + initState :: HieState -initState = HieState emptyNameEnv +initState = HieState emptyNameEnv emptyDVarEnv class ModifyState a where -- See Note [Name Remapping] addSubstitution :: a -> a -> HieState -> HieState @@ -216,10 +264,11 @@ instance ModifyState Id where modifyState :: ModifyState (IdP p) => [ABExport p] -> HieState -> HieState modifyState = foldr go id where - go ABE{abe_poly=poly,abe_mono=mono} f = addSubstitution mono poly . f + go ABE{abe_poly=poly,abe_mono=mono} f + = addSubstitution mono poly . f go _ f = f -type HieM = ReaderT HieState Hsc +type HieM = ReaderT NodeOrigin (StateT HieState Hsc) -- | Construct an 'HieFile' from the outputs of the typechecker. mkHieFile :: ModSummary @@ -239,7 +288,10 @@ mkHieFileWithSource :: FilePath -> RenamedSource -> Hsc HieFile mkHieFileWithSource src_file src ms ts rs = do let tc_binds = tcg_binds ts - (asts', arr) <- getCompressedAsts tc_binds rs + top_ev_binds = tcg_ev_binds ts + insts = tcg_insts ts + tcs = tcg_tcs ts + (asts', arr) <- getCompressedAsts tc_binds rs top_ev_binds insts tcs return $ HieFile { hie_hs_file = src_file , hie_module = ms_mod ms @@ -250,38 +302,70 @@ mkHieFileWithSource src_file src ms ts rs = do , hie_hs_src = src } -getCompressedAsts :: TypecheckedSource -> RenamedSource +getCompressedAsts :: TypecheckedSource -> RenamedSource -> Bag EvBind -> [ClsInst] -> [TyCon] -> Hsc (HieASTs TypeIndex, A.Array TypeIndex HieTypeFlat) -getCompressedAsts ts rs = do - asts <- enrichHie ts rs +getCompressedAsts ts rs top_ev_binds insts tcs = do + asts <- enrichHie ts rs top_ev_binds insts tcs return $ compressTypes asts -enrichHie :: TypecheckedSource -> RenamedSource -> Hsc (HieASTs Type) -enrichHie ts (hsGrp, imports, exports, _) = flip runReaderT initState $ do +enrichHie :: TypecheckedSource -> RenamedSource -> Bag EvBind -> [ClsInst] -> [TyCon] + -> Hsc (HieASTs Type) +enrichHie ts (hsGrp, imports, exports, _) ev_bs insts tcs = + flip evalStateT initState $ flip runReaderT SourceInfo $ do tasts <- toHie $ fmap (BC RegularBind ModuleScope) ts rasts <- processGrp hsGrp imps <- toHie $ filter (not . ideclImplicit . unLoc) imports exps <- toHie $ fmap (map $ IEC Export . fst) exports - let spanFile children = case children of - [] -> mkRealSrcSpan (mkRealSrcLoc "" 1 1) (mkRealSrcLoc "" 1 1) + -- Add Instance bindings + forM_ insts $ \i -> + addUnlocatedEvBind (is_dfun i) (EvidenceVarBind (EvInstBind False (is_cls_nm i)) ModuleScope Nothing) + -- Add class parent bindings + forM_ tcs $ \tc -> + case tyConClass_maybe tc of + Nothing -> pure () + Just c -> forM_ (classSCSelIds c) $ \v -> + addUnlocatedEvBind v (EvidenceVarBind (EvInstBind True (className c)) ModuleScope Nothing) + let spanFile file children = case children of + [] -> realSrcLocSpan (mkRealSrcLoc file 1 1) _ -> mkRealSrcSpan (realSrcSpanStart $ nodeSpan $ head children) (realSrcSpanEnd $ nodeSpan $ last children) - modulify xs = - Node (simpleNodeInfo "Module" "Module") (spanFile xs) xs - - asts = HieASTs - $ resolveTyVarScopes - $ M.map (modulify . mergeSortAsts) - $ M.fromListWith (++) - $ map (\x -> (srcSpanFile (nodeSpan x),[x])) flat_asts - flat_asts = concat [ tasts , rasts , imps , exps ] + + modulify file xs' = do + + top_ev_asts <- + toHie $ EvBindContext ModuleScope Nothing + $ L (RealSrcSpan (realSrcLocSpan $ mkRealSrcLoc file 1 1) Nothing) + $ EvBinds ev_bs + + (uloc_evs,more_ev_asts) <- getUnlocatedEvBinds file + + let xs = mergeSortAsts $ xs' ++ top_ev_asts ++ more_ev_asts + span = spanFile file xs + + moduleInfo = SourcedNodeInfo + $ M.singleton SourceInfo + $ (simpleNodeInfo "Module" "Module") + {nodeIdentifiers = uloc_evs} + + moduleNode = Node moduleInfo span [] + + case mergeSortAsts $ moduleNode : xs of + [x] -> return x + xs -> panicDoc "enrichHie: mergeSortAsts returned more than one result" (ppr $ map nodeSpan xs) + + asts' <- sequence + $ M.mapWithKey modulify + $ M.fromListWith (++) + $ map (\x -> (srcSpanFile (nodeSpan x),[x])) flat_asts + + let asts = HieASTs $ resolveTyVarScopes asts' return asts where processGrp grp = concatM @@ -305,13 +389,16 @@ grhss_span :: GRHSs p body -> SrcSpan grhss_span (GRHSs _ xs bs) = foldl' combineSrcSpans (getLoc bs) (map getLoc xs) grhss_span (XGRHSs _) = panic "XGRHS has no span" -bindingsOnly :: [Context Name] -> [HieAST a] -bindingsOnly [] = [] -bindingsOnly (C c n : xs) = case nameSrcSpan n of - RealSrcSpan span _ -> Node nodeinfo span [] : bindingsOnly xs - where nodeinfo = NodeInfo S.empty [] (M.singleton (Right n) info) - info = mempty{identInfo = S.singleton c} - _ -> bindingsOnly xs +bindingsOnly :: [Context Name] -> HieM [HieAST a] +bindingsOnly [] = pure [] +bindingsOnly (C c n : xs) = do + org <- ask + rest <- bindingsOnly xs + pure $ case nameSrcSpan n of + RealSrcSpan span _ -> Node (mkSourcedNodeInfo org nodeinfo) span [] : rest + where nodeinfo = NodeInfo S.empty [] (M.singleton (Right n) info) + info = mempty{identInfo = S.singleton c} + _ -> rest concatM :: Monad m => [m [a]] -> m [a] concatM xs = concat <$> sequence xs @@ -345,6 +432,8 @@ data SigInfo = SI SigType (Maybe Span) data SigType = BindSig | ClassSig | InstSig +data EvBindContext a = EvBindContext Scope (Maybe Span) a + data RScoped a = RS Scope a -- ^ Scope spans over everything to the right of a, (mostly) not -- including a itself @@ -502,8 +591,9 @@ instance ToHie (TScoped NoExtField) where toHie _ = pure [] instance ToHie (IEContext (Located ModuleName)) where - toHie (IEC c (L (RealSrcSpan span _) mname)) = - pure $ [Node (NodeInfo S.empty [] idents) span []] + toHie (IEC c (L (RealSrcSpan span _) mname)) = do + org <- ask + pure $ [Node (mkSourcedNodeInfo org $ NodeInfo S.empty [] idents) span []] where details = mempty{identInfo = S.singleton (IEThing c)} idents = M.singleton (Left mname) details toHie _ = pure [] @@ -511,38 +601,90 @@ instance ToHie (IEContext (Located ModuleName)) where instance ToHie (Context (Located Var)) where toHie c = case c of C context (L (RealSrcSpan span _) name') - -> do - m <- asks name_remapping - let name = case lookupNameEnv m (varName name') of - Just var -> var - Nothing-> name' - pure - [Node - (NodeInfo S.empty [] $ - M.singleton (Right $ varName name) - (IdentifierDetails (Just $ varType name') - (S.singleton context))) - span - []] + | varUnique name' == mkBuiltinUnique 1 -> pure [] + -- `mkOneRecordSelector` makes a field var using this unique, which we ignore + | otherwise -> do + m <- lift $ gets name_remapping + org <- ask + let name = case lookupNameEnv m (varName name') of + Just var -> var + Nothing-> name' + pure + [Node + (mkSourcedNodeInfo org $ NodeInfo S.empty [] $ + M.singleton (Right $ varName name) + (IdentifierDetails (Just $ varType name') + (S.singleton context))) + span + []] + C (EvidenceVarBind i _ sp) (L _ name) -> do + addUnlocatedEvBind name (EvidenceVarBind i ModuleScope sp) + pure [] _ -> pure [] instance ToHie (Context (Located Name)) where toHie c = case c of - C context (L (RealSrcSpan span _) name') -> do - m <- asks name_remapping - let name = case lookupNameEnv m name' of - Just var -> varName var - Nothing -> name' - pure - [Node - (NodeInfo S.empty [] $ - M.singleton (Right name) - (IdentifierDetails Nothing - (S.singleton context))) - span - []] + C context (L (RealSrcSpan span _) name') + | nameUnique name' == mkBuiltinUnique 1 -> pure [] + -- `mkOneRecordSelector` makes a field var using this unique, which we ignore + | otherwise -> do + m <- lift $ gets name_remapping + org <- ask + let name = case lookupNameEnv m name' of + Just var -> varName var + Nothing -> name' + pure + [Node + (mkSourcedNodeInfo org $ NodeInfo S.empty [] $ + M.singleton (Right name) + (IdentifierDetails Nothing + (S.singleton context))) + span + []] _ -> pure [] +evVarsOfTermList :: EvTerm -> [EvId] +evVarsOfTermList (EvExpr e) = exprSomeFreeVarsList isEvVar e +evVarsOfTermList (EvTypeable _ ev) = + case ev of + EvTypeableTyCon _ e -> concatMap evVarsOfTermList e + EvTypeableTyApp e1 e2 -> concatMap evVarsOfTermList [e1,e2] + EvTypeableTrFun e1 e2 -> concatMap evVarsOfTermList [e1,e2] + EvTypeableTyLit e -> evVarsOfTermList e +evVarsOfTermList (EvFun{}) = [] + +instance ToHie (EvBindContext (Located TcEvBinds)) where + toHie (EvBindContext sc sp (L span (EvBinds bs))) + = concatMapM go $ bagToList bs + where + go evbind = do + let evDeps = evVarsOfTermList $ eb_rhs evbind + depNames = EvBindDeps $ map varName evDeps + concatM $ + [ toHie (C (EvidenceVarBind (EvLetBind depNames) (combineScopes sc (mkScope span)) sp) + (L span $ eb_lhs evbind)) + , toHie $ map (C EvidenceVarUse . L span) $ evDeps + ] + toHie _ = pure [] + +instance ToHie (EvBindContext (Located NoExtField)) where + toHie _ = pure [] + +instance ToHie (Located HsWrapper) where + toHie (L osp wrap) + = case wrap of + (WpLet bs) -> toHie $ EvBindContext (mkScope osp) (getRealSpan osp) (L osp bs) + (WpCompose a b) -> concatM $ + [toHie (L osp a), toHie (L osp b)] + (WpFun a b _ _) -> concatM $ + [toHie (L osp a), toHie (L osp b)] + (WpEvLam a) -> + toHie $ C (EvidenceVarBind EvWrapperBind (mkScope osp) (getRealSpan osp)) + $ L osp a + (WpEvApp a) -> + concatMapM (toHie . C EvidenceVarUse . L osp) $ evVarsOfTermList a + _ -> pure [] + -- | Dummy instances - never called instance ToHie (TScoped (LHsSigWcType GhcTc)) where toHie _ = pure [] @@ -586,7 +728,7 @@ instance HasType (LHsExpr GhcRn) where -- -- See #16233 instance HasType (LHsExpr GhcTc) where - getTypeNode e@(L spn e') = lift $ + getTypeNode e@(L spn e') = -- Some expression forms have their type immediately available let tyOpt = case e' of HsLit _ l -> Just (hsLitType l) @@ -609,7 +751,7 @@ instance HasType (LHsExpr GhcTc) where Nothing | skipDesugaring e' -> fallback | otherwise -> do - hs_env <- Hsc $ \e w -> return (e,w) + hs_env <- lift $ lift $ Hsc $ \e w -> return (e,w) (_,mbe) <- liftIO $ deSugarExpr hs_env e maybe fallback (makeTypeNode e' spn . exprType) mbe where @@ -634,21 +776,25 @@ instance HasType (LHsExpr GhcTc) where XExpr (HsWrap{}) -> False _ -> True -instance ( ToHie (Context (Located (IdP a))) - , ToHie (MatchGroup a (LHsExpr a)) - , ToHie (PScoped (LPat a)) - , ToHie (GRHSs a (LHsExpr a)) - , ToHie (LHsExpr a) - , ToHie (Located (PatSynBind a a)) - , HasType (LHsBind a) - , ModifyState (IdP a) - , Data (HsBind a) - ) => ToHie (BindContext (LHsBind a)) where +instance ( ToHie (Context (Located (IdP (GhcPass a)))) + , ToHie (MatchGroup (GhcPass a) (LHsExpr (GhcPass a))) + , ToHie (PScoped (LPat (GhcPass a))) + , ToHie (GRHSs (GhcPass a) (LHsExpr (GhcPass a))) + , ToHie (LHsExpr (GhcPass a)) + , ToHie (Located (PatSynBind (GhcPass a) (GhcPass a))) + , HasType (LHsBind (GhcPass a)) + , ModifyState (IdP (GhcPass a)) + , Data (HsBind (GhcPass a)) + , IsPass a + ) => ToHie (BindContext (LHsBind (GhcPass a))) where toHie (BC context scope b@(L span bind)) = concatM $ getTypeNode b : case bind of - FunBind{fun_id = name, fun_matches = matches} -> + FunBind{fun_id = name, fun_matches = matches, fun_ext = wrap} -> [ toHie $ C (ValBind context scope $ getRealSpan span) name , toHie matches + , case ghcPass @a of + GhcTc -> toHie $ L span wrap + _ -> pure [] ] PatBind{pat_lhs = lhs, pat_rhs = rhs} -> [ toHie $ PS (getRealSpan span) scope NoScope lhs @@ -657,39 +803,55 @@ instance ( ToHie (Context (Located (IdP a))) VarBind{var_rhs = expr} -> [ toHie expr ] - AbsBinds{abs_exports = xs, abs_binds = binds} -> - [ local (modifyState xs) $ -- Note [Name Remapping] - toHie $ fmap (BC context scope) binds + AbsBinds{ abs_exports = xs, abs_binds = binds + , abs_ev_binds = ev_binds + , abs_ev_vars = ev_vars } -> + [ lift (modify (modifyState xs)) >> -- Note [Name Remapping] + (toHie $ fmap (BC context scope) binds) + , toHie $ map (L span . abe_wrap) xs + , toHie $ + map (EvBindContext (mkScope span) (getRealSpan span) + . L span) ev_binds + , toHie $ + map (C (EvidenceVarBind EvSigBind + (mkScope span) + (getRealSpan span)) + . L span) ev_vars ] PatSynBind _ psb -> [ toHie $ L span psb -- PatSynBinds only occur at the top level ] - XHsBindsLR _ -> [] instance ( ToHie (LMatch a body) ) => ToHie (MatchGroup a body) where - toHie mg = concatM $ case mg of - MG{ mg_alts = (L span alts) , mg_origin = FromSource } -> - [ pure $ locOnly span - , toHie alts - ] - MG{} -> [] - XMatchGroup _ -> [] + toHie mg = case mg of + MG{ mg_alts = (L span alts) , mg_origin = origin} -> + local (setOrigin origin) $ concatM + [ locOnly span + , toHie alts + ] + XMatchGroup _ -> pure [] + +setOrigin :: Origin -> NodeOrigin -> NodeOrigin +setOrigin FromSource _ = SourceInfo +setOrigin Generated _ = GeneratedInfo instance ( ToHie (Context (Located (IdP a))) , ToHie (PScoped (LPat a)) , ToHie (HsPatSynDir a) + , (a ~ GhcPass p) ) => ToHie (Located (PatSynBind a a)) where toHie (L sp psb) = concatM $ case psb of PSB{psb_id=var, psb_args=dets, psb_def=pat, psb_dir=dir} -> [ toHie $ C (Decl PatSynDec $ getRealSpan sp) var , toHie $ toBind dets - , toHie $ PS Nothing lhsScope NoScope pat + , toHie $ PS Nothing lhsScope patScope pat , toHie dir ] where lhsScope = combineScopes varScope detScope varScope = mkLScope var + patScope = mkScope $ getLoc pat detScope = case dets of (PrefixCon args) -> foldr combineScopes NoScope $ map mkLScope args (InfixCon a b) -> combineScopes (mkLScope a) (mkLScope b) @@ -702,7 +864,6 @@ instance ( ToHie (Context (Located (IdP a))) toBind (PrefixCon args) = PrefixCon $ map (C Use) args toBind (InfixCon a b) = InfixCon (C Use a) (C Use b) toBind (RecCon r) = RecCon $ map (PSC detSpan) r - XPatSynBind _ -> [] instance ( ToHie (MatchGroup a (LHsExpr a)) ) => ToHie (HsPatSynDir a) where @@ -780,12 +941,24 @@ instance ( a ~ GhcPass p SumPat _ pat _ _ -> [ toHie $ PS rsp scope pscope pat ] - ConPat {pat_con = con, pat_args = dets}-> + ConPat {pat_con = con, pat_args = dets, pat_con_ext = ext}-> [ case ghcPass @p of GhcPs -> toHie $ C Use $ con GhcRn -> toHie $ C Use $ con GhcTc -> toHie $ C Use $ fmap conLikeName con , toHie $ contextify dets + , case ghcPass @p of + GhcTc -> + let ev_binds = cpt_binds ext + ev_vars = cpt_dicts ext + wrap = cpt_wrap ext + evscope = mkScope ospan `combineScopes` scope `combineScopes` pscope + in concatM [ toHie $ EvBindContext scope rsp $ L ospan ev_binds + , toHie $ L ospan wrap + , toHie $ map (C (EvidenceVarBind EvPatternBind evscope rsp) + . L ospan) ev_vars + ] + _ -> pure [] ] ViewPat _ expr pat -> [ toHie expr @@ -816,10 +989,12 @@ instance ( a ~ GhcPass p GhcPs -> noExtCon e GhcRn -> noExtCon e #endif - GhcTc -> [] + GhcTc -> + [ toHie $ L ospan wrap + , toHie $ PS rsp scope pscope $ (L ospan pat :: LPat a) + ] where - -- Make sure we get an error if this changes - _noWarn@(CoPat _ _ _) = e + CoPat wrap pat _ = e where contextify (PrefixCon args) = PrefixCon $ patScopes rsp scope pscope args contextify (InfixCon a b) = InfixCon a' b' @@ -833,7 +1008,7 @@ instance ( a ~ GhcPass p 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) + [ bindingsOnly $ map (C $ TyVarBind (mkScope span) sc) (wcs++tvs) , toHie body ] -- See Note [Scoping Rules for SigPat] @@ -850,15 +1025,14 @@ instance ( ToHie body XGRHSs _ -> [] instance ( ToHie (Located body) - , ToHie (RScoped (GuardLStmt a)) - , Data (GRHS a (Located body)) - ) => ToHie (LGRHS a (Located body)) where + , ToHie (RScoped (GuardLStmt (GhcPass a))) + , Data (GRHS (GhcPass a) (Located body)) + ) => ToHie (LGRHS (GhcPass a) (Located body)) where toHie (L span g) = concatM $ makeNode g span : case g of GRHS _ guards body -> [ toHie $ listScopes (mkLScope body) guards , toHie body ] - XGRHS _ -> [] instance ( a ~ GhcPass p , ToHie (Context (Located (IdP a))) @@ -954,7 +1128,7 @@ instance ( a ~ GhcPass p , toHie expr ] HsDo _ _ (L ispan stmts) -> - [ pure $ locOnly ispan + [ locOnly ispan , toHie $ listScopes NoScope stmts ] ExplicitList _ _ exprs -> @@ -1008,9 +1182,10 @@ instance ( a ~ GhcPass p ] XExpr x | GhcTc <- ghcPass @p - , HsWrap _ a <- x - -> [ toHie $ L mspan a ] - + , HsWrap w a <- x + -> [ toHie $ L mspan a + , toHie (L mspan w) + ] | otherwise -> [] @@ -1070,17 +1245,37 @@ instance ( ToHie (LHsExpr a) , ToHie (BindContext (LHsBind a)) , ToHie (SigContext (LSig a)) , ToHie (RScoped (HsValBindsLR a a)) + , ToHie (EvBindContext (Located (XIPBinds a))) + , ToHie (RScoped (LIPBind a)) , Data (HsLocalBinds a) ) => ToHie (RScoped (LHsLocalBinds a)) where toHie (RS scope (L sp binds)) = concatM $ makeNode binds sp : case binds of EmptyLocalBinds _ -> [] - HsIPBinds _ _ -> [] + HsIPBinds _ ipbinds -> case ipbinds of + IPBinds evbinds xs -> let sc = combineScopes scope $ mkScope sp in + [ toHie $ EvBindContext sc (getRealSpan sp) $ L sp evbinds + , toHie $ map (RS sc) xs + ] + XHsIPBinds _ -> [] HsValBinds _ valBinds -> [ toHie $ RS (combineScopes scope $ mkScope sp) valBinds ] XHsLocalBindsLR _ -> [] +instance ( ToHie (LHsExpr a) + , ToHie (Context (Located (IdP a))) + , Data (IPBind a) + ) => ToHie (RScoped (LIPBind a)) where + toHie (RS scope (L sp bind)) = concatM $ makeNode bind sp : case bind of + IPBind _ (Left _) expr -> [toHie expr] + IPBind _ (Right v) expr -> + [ toHie $ C (EvidenceVarBind EvImplicitBind scope (getRealSpan sp)) + $ L sp v + , toHie expr + ] + XIPBind _ -> [] + instance ( ToHie (BindContext (LHsBind a)) , ToHie (SigContext (LSig a)) , ToHie (RScoped (XXValBindsLR a a)) @@ -1160,6 +1355,7 @@ instance ( a ~ GhcPass p , ToHie (LHsExpr a) , ToHie (SigContext (LSig a)) , ToHie (RScoped (HsValBindsLR a a)) + , ToHie (RScoped (ExprLStmt a)) , Data (StmtLR a a (Located (HsExpr a))) , Data (HsLocalBinds a) ) => ToHie (RScoped (ApplicativeArg (GhcPass p))) where @@ -1193,6 +1389,7 @@ instance ( a ~ GhcPass p , ToHie (MatchGroup a (LHsCmd a)) , ToHie (SigContext (LSig a)) , ToHie (RScoped (HsValBindsLR a a)) + , ToHie (RScoped (LHsLocalBinds a)) , Data (HsCmd a) , Data (HsCmdTop a) , Data (StmtLR a a (Located (HsCmd a))) @@ -1235,7 +1432,7 @@ instance ( a ~ GhcPass p , toHie cmd' ] HsCmdDo _ (L ispan stmts) -> - [ pure $ locOnly ispan + [ locOnly ispan , toHie $ listScopes NoScope stmts ] XCmd _ -> [] @@ -1289,7 +1486,7 @@ instance ToHie (LTyClDecl GhcRn) where , toHie $ map (SC $ SI ClassSig $ getRealSpan span) sigs , toHie $ fmap (BC InstanceBind ModuleScope) meths , toHie typs - , concatMapM (pure . locOnly . getLoc) deftyps + , concatMapM (locOnly . getLoc) deftyps , toHie deftyps ] where @@ -1313,7 +1510,7 @@ instance ToHie (LFamilyDecl GhcRn) where instance ToHie (FamilyInfo GhcRn) where toHie (ClosedTypeFamily (Just eqns)) = concatM $ - [ concatMapM (pure . locOnly . getLoc) eqns + [ concatMapM (locOnly . getLoc) eqns , toHie $ map go eqns ] where @@ -1371,7 +1568,7 @@ instance ToHie (HsDataDefn GhcRn) where instance ToHie (HsDeriving GhcRn) where toHie (L span clauses) = concatM - [ pure $ locOnly span + [ locOnly span , toHie clauses ] @@ -1379,7 +1576,7 @@ instance ToHie (LHsDerivingClause GhcRn) where toHie (L span cl) = concatM $ makeNode cl span : case cl of HsDerivingClause _ strat (L ispan tys) -> [ toHie strat - , pure $ locOnly ispan + , locOnly ispan , toHie $ map (TS (ResolvedScopes [])) tys ] @@ -1391,14 +1588,14 @@ instance ToHie (Located (DerivStrategy GhcRn)) where ViaStrategy s -> [ toHie $ TS (ResolvedScopes []) s ] instance ToHie (Located OverlapMode) where - toHie (L span _) = pure $ locOnly span + toHie (L span _) = locOnly span instance ToHie (LConDecl GhcRn) where toHie (L span decl) = concatM $ makeNode decl span : case decl of ConDeclGADT { con_names = names, con_qvars = exp_vars, con_g_ext = imp_vars , con_mb_cxt = ctx, con_args = args, con_res_ty = typ } -> [ toHie $ map (C (Decl ConDec $ getRealSpan span)) names - , concatM $ [ pure $ bindingsOnly bindings + , concatM $ [ bindingsOnly bindings , toHie $ tvScopes resScope NoScope exp_vars ] , toHie ctx , toHie args @@ -1429,7 +1626,7 @@ instance ToHie (LConDecl GhcRn) where instance ToHie (Located [LConDeclField GhcRn]) where toHie (L span decls) = concatM $ - [ pure $ locOnly span + [ locOnly span , toHie decls ] @@ -1437,7 +1634,7 @@ instance ( HasLoc thing , ToHie (TScoped thing) ) => ToHie (TScoped (HsImplicitBndrs GhcRn thing)) where toHie (TS sc (HsIB ibrn a)) = concatM $ - [ pure $ bindingsOnly $ map (C $ TyVarBind (mkScope span) sc) ibrn + [ bindingsOnly $ map (C $ TyVarBind (mkScope span) sc) ibrn , toHie $ TS sc a ] where span = loc a @@ -1446,7 +1643,7 @@ instance ( HasLoc thing , ToHie (TScoped thing) ) => ToHie (TScoped (HsWildCardBndrs GhcRn thing)) where toHie (TS sc (HsWC names a)) = concatM $ - [ pure $ bindingsOnly $ map (C $ TyVarBind (mkScope span) sc) names + [ bindingsOnly $ map (C $ TyVarBind (mkScope span) sc) names , toHie $ TS sc a ] where span = loc a @@ -1496,10 +1693,10 @@ instance ToHie (SigContext (LSig GhcRn)) where ] SCCFunSig _ _ name mtxt -> [ toHie $ (C Use) name - , pure $ maybe [] (locOnly . getLoc) mtxt + , maybe (pure []) (locOnly . getLoc) mtxt ] CompleteMatchSig _ _ (L ispan names) typ -> - [ pure $ locOnly ispan + [ locOnly ispan , toHie $ map (C Use) names , toHie $ fmap (C Use) typ ] @@ -1583,7 +1780,7 @@ instance ToHie (TScoped (LHsType GhcRn)) where instance (ToHie tm, ToHie ty) => ToHie (HsArg tm ty) where toHie (HsValArg tm) = toHie tm toHie (HsTypeArg _ ty) = toHie ty - toHie (HsArgPar sp) = pure $ locOnly sp + toHie (HsArgPar sp) = locOnly sp instance Data flag => ToHie (TVScoped (LHsTyVarBndr flag GhcRn)) where toHie (TVS tsc sc (L span bndr)) = concatM $ makeNode bndr span : case bndr of @@ -1597,7 +1794,7 @@ instance Data flag => ToHie (TVScoped (LHsTyVarBndr flag GhcRn)) where instance ToHie (TScoped (LHsQTyVars GhcRn)) where toHie (TS sc (HsQTvs implicits vars)) = concatM $ - [ pure $ bindingsOnly bindings + [ bindingsOnly bindings , toHie $ tvScopes sc NoScope vars ] where @@ -1606,7 +1803,7 @@ instance ToHie (TScoped (LHsQTyVars GhcRn)) where instance ToHie (LHsContext GhcRn) where toHie (L span tys) = concatM $ - [ pure $ locOnly span + [ locOnly span , toHie tys ] @@ -1679,7 +1876,7 @@ instance ( a ~ GhcPass p [ toHie expr ] HsQuasiQuote _ _ _ ispan _ -> - [ pure $ locOnly ispan + [ locOnly ispan ] HsSpliced _ _ _ -> [] @@ -1695,7 +1892,7 @@ instance ToHie (LRoleAnnotDecl GhcRn) where toHie (L span annot) = concatM $ makeNode annot span : case annot of RoleAnnotDecl _ var roles -> [ toHie $ C Use var - , concatMapM (pure . locOnly . getLoc) roles + , concatMapM (locOnly . getLoc) roles ] instance ToHie (LInstDecl GhcRn) where @@ -1715,9 +1912,9 @@ instance ToHie (LClsInstDecl GhcRn) where [ toHie $ TS (ResolvedScopes [mkScope span]) $ cid_poly_ty decl , toHie $ fmap (BC InstanceBind ModuleScope) $ cid_binds decl , toHie $ map (SC $ SI InstSig $ getRealSpan span) $ cid_sigs decl - , pure $ concatMap (locOnly . getLoc) $ cid_tyfam_insts decl + , concatMapM (locOnly . getLoc) $ cid_tyfam_insts decl , toHie $ cid_tyfam_insts decl - , pure $ concatMap (locOnly . getLoc) $ cid_datafam_insts decl + , concatMapM (locOnly . getLoc) $ cid_datafam_insts decl , toHie $ cid_datafam_insts decl , toHie $ cid_overlap_mode decl ] @@ -1769,14 +1966,14 @@ instance ToHie (LForeignDecl GhcRn) where ] instance ToHie ForeignImport where - toHie (CImport (L a _) (L b _) _ _ (L c _)) = pure $ concat $ + toHie (CImport (L a _) (L b _) _ _ (L c _)) = concatM $ [ locOnly a , locOnly b , locOnly c ] instance ToHie ForeignExport where - toHie (CExport (L a _) (L b _)) = pure $ concat $ + toHie (CExport (L a _) (L b _)) = concatM $ [ locOnly a , locOnly b ] @@ -1814,7 +2011,7 @@ instance ToHie (LRuleDecls GhcRn) where instance ToHie (LRuleDecl GhcRn) where toHie (L span r@(HsRule _ rname _ tybndrs bndrs exprA exprB)) = concatM [ makeNode r span - , pure $ locOnly $ getLoc rname + , locOnly $ getLoc rname , toHie $ fmap (tvScopes (ResolvedScopes []) scope) tybndrs , toHie $ map (RS $ mkScope span) bndrs , toHie exprA @@ -1844,7 +2041,7 @@ instance ToHie (LImportDecl GhcRn) where ] where goIE (hiding, (L sp liens)) = concatM $ - [ pure $ locOnly sp + [ locOnly sp , toHie $ map (IEC c) liens ] where ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -23,7 +23,6 @@ import GHC.Utils.Binary import GHC.Iface.Binary ( getDictFastString ) import GHC.Data.FastMutInt import GHC.Data.FastString ( FastString ) -import GHC.Unit.Module ( Module ) import GHC.Types.Name import GHC.Types.Name.Cache import GHC.Utils.Outputable @@ -32,7 +31,6 @@ import GHC.Types.SrcLoc as SrcLoc 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 @@ -48,42 +46,6 @@ import System.FilePath ( takeDirectory ) import GHC.Iface.Ext.Types --- | `Name`'s get converted into `HieName`'s before being written into @.hie@ --- files. See 'toHieName' and 'fromHieName' for logic on how to convert between --- these two types. -data HieName - = ExternalName !Module !OccName !SrcSpan - | LocalName !OccName !SrcSpan - | KnownKeyName !Unique - deriving (Eq) - -instance Ord HieName where - compare (ExternalName a b c) (ExternalName d e f) = compare (a,b) (d,e) `thenCmp` SrcLoc.leftmost_smallest c f - -- TODO (int-index): Perhaps use RealSrcSpan in HieName? - compare (LocalName a b) (LocalName c d) = compare a c `thenCmp` SrcLoc.leftmost_smallest b d - -- TODO (int-index): Perhaps use RealSrcSpan in HieName? - compare (KnownKeyName a) (KnownKeyName b) = nonDetCmpUnique a b - -- Not actually non deterministic as it is a KnownKey - compare ExternalName{} _ = LT - compare LocalName{} ExternalName{} = GT - compare LocalName{} _ = LT - compare KnownKeyName{} _ = GT - -instance Outputable HieName where - ppr (ExternalName m n sp) = text "ExternalName" <+> ppr m <+> ppr n <+> ppr sp - ppr (LocalName n sp) = text "LocalName" <+> ppr n <+> ppr sp - ppr (KnownKeyName u) = text "KnownKeyName" <+> ppr u - -hieNameOcc :: HieName -> OccName -hieNameOcc (ExternalName _ occ _) = occ -hieNameOcc (LocalName occ _) = occ -hieNameOcc (KnownKeyName u) = - case lookupKnownKeyName u of - Just n -> nameOccName n - Nothing -> pprPanic "hieNameOcc:unknown known-key unique" - (ppr (unpkUnique u)) - - data HieSymbolTable = HieSymbolTable { hie_symtab_next :: !FastMutInt , hie_symtab_map :: !(IORef (UniqFM (Int, HieName))) @@ -352,14 +314,6 @@ putName (HieSymbolTable next ref) bh name = do -- ** Converting to and from `HieName`'s -toHieName :: Name -> HieName -toHieName name - | isKnownKeyName name = KnownKeyName (nameUnique name) - | isExternalName name = ExternalName (nameModule name) - (nameOccName name) - (nameSrcSpan name) - | otherwise = LocalName (nameOccName name) (nameSrcSpan name) - fromHieName :: NameCache -> HieName -> (NameCache, Name) fromHieName nc (ExternalName mod occ span) = let cache = nsNames nc ===================================== compiler/GHC/Iface/Ext/Debug.hs ===================================== @@ -15,7 +15,6 @@ import GHC.Data.FastString import GHC.Utils.Outputable import GHC.Iface.Ext.Types -import GHC.Iface.Ext.Binary import GHC.Iface.Ext.Utils import GHC.Types.Name @@ -39,17 +38,18 @@ diffAst diffType (Node info1 span1 xs1) (Node info2 span2 xs2) = spanDiff | span1 /= span2 = [hsep ["Spans", ppr span1, "and", ppr span2, "differ"]] | otherwise = [] - infoDiff' - = (diffList eqDiff `on` (S.toAscList . nodeAnnotations)) info1 info2 - ++ (diffList diffType `on` nodeType) info1 info2 - ++ (diffIdents `on` nodeIdentifiers) info1 info2 - infoDiff = case infoDiff' of + infoDiff' i1 i2 + = (diffList eqDiff `on` (S.toAscList . nodeAnnotations)) i1 i2 + ++ (diffList diffType `on` nodeType) i1 i2 + ++ (diffIdents `on` nodeIdentifiers) i1 i2 + sinfoDiff = diffList (\(k1,a) (k2,b) -> eqDiff k1 k2 ++ infoDiff' a b) `on` (M.toList . getSourcedNodeInfo) + infoDiff = case sinfoDiff info1 info2 of [] -> [] - xs -> xs ++ [vcat ["In Node:",ppr (nodeIdentifiers info1,span1) - , "and", ppr (nodeIdentifiers info2,span2) + xs -> xs ++ [vcat ["In Node:",ppr (sourcedNodeIdents info1,span1) + , "and", ppr (sourcedNodeIdents info2,span2) , "While comparing" - , ppr (normalizeIdents $ nodeIdentifiers info1), "and" - , ppr (normalizeIdents $ nodeIdentifiers info2) + , ppr (normalizeIdents $ sourcedNodeIdents info1), "and" + , ppr (normalizeIdents $ sourcedNodeIdents info2) ] ] @@ -107,11 +107,24 @@ validAst (Node _ span children) = do -- | Look for any identifiers which occur outside of their supposed scopes. -- Returns a list of error messages. validateScopes :: Module -> M.Map FastString (HieAST a) -> [SDoc] -validateScopes mod asts = validScopes +validateScopes mod asts = validScopes ++ validEvs where refMap = generateReferencesMap asts -- We use a refmap for most of the computation + evs = M.keys + $ M.filter (any isEvidenceContext . concatMap (S.toList . identInfo . snd)) refMap + + validEvs = do + i@(Right ev) <- evs + case M.lookup i refMap of + Nothing -> ["Impossible, ev"<+> ppr ev <+> "not found in refmap" ] + Just refs + | nameIsLocalOrFrom mod ev + , not (any isEvidenceBind . concatMap (S.toList . identInfo . snd) $ refs) + -> ["Evidence var" <+> ppr ev <+> "not bound in refmap"] + | otherwise -> [] + -- Check if all the names occur in their calculated scopes validScopes = M.foldrWithKey (\k a b -> valid k a ++ b) [] refMap valid (Left _) _ = [] @@ -122,15 +135,18 @@ validateScopes mod asts = validScopes Just xs -> xs Nothing -> [] inScope (sp, dets) - | (definedInAsts asts n) + | (definedInAsts asts n || (any isEvidenceContext (identInfo dets))) && any isOccurrence (identInfo dets) -- We validate scopes for names which are defined locally, and occur - -- in this span + -- in this span, or are evidence variables = case scopes of - [] | (nameIsLocalOrFrom mod n - && not (isDerivedOccName $ nameOccName n)) - -- If we don't get any scopes for a local name then its an error. - -- We can ignore derived names. + [] | nameIsLocalOrFrom mod n + , ( not (isDerivedOccName $ nameOccName n) + || any isEvidenceContext (identInfo dets)) + -- If we don't get any scopes for a local name or + -- an evidence variable, then its an error. + -- We can ignore other kinds of derived names as + -- long as we take evidence vars into account -> return $ hsep $ [ "Locally defined Name", ppr n,pprDefinedAt n , "at position", ppr sp , "Doesn't have a calculated scope: ", ppr scopes] ===================================== compiler/GHC/Iface/Ext/Types.hs ===================================== @@ -17,13 +17,16 @@ import GHC.Prelude import GHC.Settings.Config import GHC.Utils.Binary import GHC.Data.FastString ( FastString ) +import GHC.Builtin.Utils import GHC.Iface.Type -import GHC.Unit.Module ( ModuleName, Module ) -import GHC.Types.Name ( Name ) +import GHC.Unit.Module ( ModuleName, Module ) +import GHC.Types.Name import GHC.Utils.Outputable hiding ( (<>) ) -import GHC.Types.SrcLoc ( RealSrcSpan ) +import GHC.Types.SrcLoc import GHC.Types.Avail +import GHC.Types.Unique import qualified GHC.Utils.Outputable as O ( (<>) ) +import GHC.Utils.Misc import qualified Data.Array as A import qualified Data.Map as M @@ -33,6 +36,8 @@ import Data.Data ( Typeable, Data ) import Data.Semigroup ( Semigroup(..) ) import Data.Word ( Word8 ) import Control.Applicative ( (<|>) ) +import Data.Coerce ( coerce ) +import Data.Function ( on ) type Span = RealSrcSpan @@ -222,17 +227,16 @@ instance Outputable a => Outputable (HieASTs a) where , rest ] - data HieAST a = Node - { nodeInfo :: NodeInfo a + { sourcedNodeInfo :: SourcedNodeInfo a , nodeSpan :: Span , nodeChildren :: [HieAST a] } deriving (Functor, Foldable, Traversable) instance Binary (HieAST TypeIndex) where put_ bh ast = do - put_ bh $ nodeInfo ast + put_ bh $ sourcedNodeInfo ast put_ bh $ nodeSpan ast put_ bh $ nodeChildren ast @@ -247,6 +251,38 @@ instance Outputable a => Outputable (HieAST a) where header = text "Node@" O.<> ppr sp O.<> ":" <+> ppr ni rest = vcat (map ppr ch) + +-- | NodeInfos grouped by source +newtype SourcedNodeInfo a = SourcedNodeInfo { getSourcedNodeInfo :: (M.Map NodeOrigin (NodeInfo a)) } + deriving (Functor, Foldable, Traversable) + +instance Binary (SourcedNodeInfo TypeIndex) where + put_ bh asts = put_ bh $ M.toAscList $ getSourcedNodeInfo asts + get bh = SourcedNodeInfo <$> fmap M.fromDistinctAscList (get bh) + +instance Outputable a => Outputable (SourcedNodeInfo a) where + ppr (SourcedNodeInfo asts) = M.foldrWithKey go "" asts + where + go k a rest = vcat $ + [ "Source: " O.<> ppr k + , ppr a + , rest + ] + +-- | Source of node info +data NodeOrigin + = SourceInfo + | GeneratedInfo + deriving (Eq, Enum, Ord) + +instance Outputable NodeOrigin where + ppr SourceInfo = text "From source" + ppr GeneratedInfo = text "generated by ghc" + +instance Binary NodeOrigin where + put_ bh b = putByte bh (fromIntegral (fromEnum b)) + get bh = do x <- getByte bh; pure $! (toEnum (fromIntegral x)) + -- | The information stored in one AST node. -- -- The type parameter exists to provide flexibility in representation of types @@ -314,7 +350,7 @@ instance Monoid (IdentifierDetails a) where instance Binary (IdentifierDetails TypeIndex) where put_ bh dets = do put_ bh $ identType dets - put_ bh $ S.toAscList $ identInfo dets + put_ bh $ S.toList $ identInfo dets get bh = IdentifierDetails <$> get bh <*> fmap S.fromDistinctAscList (get bh) @@ -363,6 +399,14 @@ data ContextInfo -- | Record field | RecField RecFieldContext (Maybe Span) + -- | Constraint/Dictionary evidence variable binding + | EvidenceVarBind + EvVarSource -- ^ how did this bind come into being + Scope -- ^ scope over which the value is bound + (Maybe Span) -- ^ span of the binding site + + -- | Usage of evidence variable + | EvidenceVarUse deriving (Eq, Ord) instance Outputable ContextInfo where @@ -385,10 +429,16 @@ instance Outputable ContextInfo where <+> ppr sc1 <+> "," <+> ppr sc2 ppr (RecField ctx sp) = text "record field" <+> ppr ctx <+> pprBindSpan sp + ppr (EvidenceVarBind ctx sc sp) = + text "evidence variable" <+> ppr ctx + $$ "with scope:" <+> ppr sc + $$ pprBindSpan sp + ppr (EvidenceVarUse) = + text "usage of evidence variable" pprBindSpan :: Maybe Span -> SDoc pprBindSpan Nothing = text "" -pprBindSpan (Just sp) = text "at:" <+> ppr sp +pprBindSpan (Just sp) = text "bound at:" <+> ppr sp instance Binary ContextInfo where put_ bh Use = putByte bh 0 @@ -422,6 +472,12 @@ instance Binary ContextInfo where put_ bh a put_ bh b put_ bh MatchBind = putByte bh 9 + put_ bh (EvidenceVarBind a b c) = do + putByte bh 10 + put_ bh a + put_ bh b + put_ bh c + put_ bh EvidenceVarUse = putByte bh 11 get bh = do (t :: Word8) <- get bh @@ -436,8 +492,69 @@ instance Binary ContextInfo where 7 -> TyVarBind <$> get bh <*> get bh 8 -> RecField <$> get bh <*> get bh 9 -> return MatchBind + 10 -> EvidenceVarBind <$> get bh <*> get bh <*> get bh + 11 -> return EvidenceVarUse _ -> panic "Binary ContextInfo: invalid tag" +data EvVarSource + = EvPatternBind -- ^ bound by a pattern match + | EvSigBind -- ^ bound by a type signature + | EvWrapperBind -- ^ bound by a hswrapper + | EvImplicitBind -- ^ bound by an implicit variable + | EvInstBind { isSuperInst :: Bool, cls :: Name } -- ^ Bound by some instance of given class + | EvLetBind EvBindDeps -- ^ A direct let binding + deriving (Eq,Ord) + +instance Binary EvVarSource where + put_ bh EvPatternBind = putByte bh 0 + put_ bh EvSigBind = putByte bh 1 + put_ bh EvWrapperBind = putByte bh 2 + put_ bh EvImplicitBind = putByte bh 3 + put_ bh (EvInstBind b cls) = do + putByte bh 4 + put_ bh b + put_ bh cls + put_ bh (EvLetBind deps) = do + putByte bh 5 + put_ bh deps + + get bh = do + (t :: Word8) <- get bh + case t of + 0 -> pure EvPatternBind + 1 -> pure EvSigBind + 2 -> pure EvWrapperBind + 3 -> pure EvImplicitBind + 4 -> EvInstBind <$> get bh <*> get bh + 5 -> EvLetBind <$> get bh + _ -> panic "Binary EvVarSource: invalid tag" + +instance Outputable EvVarSource where + ppr EvPatternBind = text "bound by a pattern" + ppr EvSigBind = text "bound by a type signature" + ppr EvWrapperBind = text "bound by a HsWrapper" + ppr EvImplicitBind = text "bound by an implicit variable binding" + ppr (EvInstBind False cls) = text "bound by an instance of class" <+> ppr cls + ppr (EvInstBind True cls) = text "bound due to a superclass of " <+> ppr cls + ppr (EvLetBind deps) = text "bound by a let, depending on:" <+> ppr deps + +-- | Eq/Ord instances compare on the converted HieName, +-- as non-exported names may have different uniques after +-- a roundtrip +newtype EvBindDeps = EvBindDeps { getEvBindDeps :: [Name] } + deriving Outputable + +instance Eq EvBindDeps where + (==) = coerce ((==) `on` map toHieName) + +instance Ord EvBindDeps where + compare = coerce (compare `on` map toHieName) + +instance Binary EvBindDeps where + put_ bh (EvBindDeps xs) = put_ bh xs + get bh = EvBindDeps <$> get bh + + -- | Types of imports and exports data IEType = Import @@ -587,3 +704,46 @@ instance Binary TyVarScope where 0 -> ResolvedScopes <$> get bh 1 -> UnresolvedScope <$> get bh <*> get bh _ -> panic "Binary TyVarScope: invalid tag" + +-- | `Name`'s get converted into `HieName`'s before being written into @.hie@ +-- files. See 'toHieName' and 'fromHieName' for logic on how to convert between +-- these two types. +data HieName + = ExternalName !Module !OccName !SrcSpan + | LocalName !OccName !SrcSpan + | KnownKeyName !Unique + deriving (Eq) + +instance Ord HieName where + compare (ExternalName a b c) (ExternalName d e f) = compare (a,b) (d,e) `thenCmp` leftmost_smallest c f + -- TODO (int-index): Perhaps use RealSrcSpan in HieName? + compare (LocalName a b) (LocalName c d) = compare a c `thenCmp` leftmost_smallest b d + -- TODO (int-index): Perhaps use RealSrcSpan in HieName? + compare (KnownKeyName a) (KnownKeyName b) = nonDetCmpUnique a b + -- Not actually non deterministic as it is a KnownKey + compare ExternalName{} _ = LT + compare LocalName{} ExternalName{} = GT + compare LocalName{} _ = LT + compare KnownKeyName{} _ = GT + +instance Outputable HieName where + ppr (ExternalName m n sp) = text "ExternalName" <+> ppr m <+> ppr n <+> ppr sp + ppr (LocalName n sp) = text "LocalName" <+> ppr n <+> ppr sp + ppr (KnownKeyName u) = text "KnownKeyName" <+> ppr u + +hieNameOcc :: HieName -> OccName +hieNameOcc (ExternalName _ occ _) = occ +hieNameOcc (LocalName occ _) = occ +hieNameOcc (KnownKeyName u) = + case lookupKnownKeyName u of + Just n -> nameOccName n + Nothing -> pprPanic "hieNameOcc:unknown known-key unique" + (ppr (unpkUnique u)) + +toHieName :: Name -> HieName +toHieName name + | isKnownKeyName name = KnownKeyName (nameUnique name) + | isExternalName name = ExternalName (nameModule name) + (nameOccName name) + (nameSrcSpan name) + | otherwise = LocalName (nameOccName name) (nameSrcSpan name) ===================================== compiler/GHC/Iface/Ext/Utils.hs ===================================== @@ -1,7 +1,9 @@ {-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE ViewPatterns #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE DeriveFunctor #-} module GHC.Iface.Ext.Utils where import GHC.Prelude @@ -11,7 +13,9 @@ import GHC.Driver.Session ( DynFlags ) import GHC.Data.FastString ( FastString, mkFastString ) import GHC.Iface.Type import GHC.Types.Name hiding (varName) -import GHC.Utils.Outputable ( renderWithStyle, ppr, defaultUserStyle, initSDocContext ) +import GHC.Types.Name.Set +import GHC.Utils.Outputable hiding ( (<>) ) +import qualified GHC.Utils.Outputable as O import GHC.Types.SrcLoc import GHC.CoreToIface import GHC.Core.TyCon @@ -27,21 +31,26 @@ import qualified Data.Set as S import qualified Data.IntMap.Strict as IM import qualified Data.Array as A import Data.Data ( typeOf, typeRepTyCon, Data(toConstr) ) -import Data.Maybe ( maybeToList ) +import Data.Maybe ( maybeToList, mapMaybe) import Data.Monoid +import Data.List (find) import Data.Traversable ( for ) +import Data.Coerce import Control.Monad.Trans.State.Strict hiding (get) +import Control.Monad.Trans.Reader +import qualified Data.Tree as Tree +type RefMap a = M.Map Identifier [(Span, IdentifierDetails a)] generateReferencesMap :: Foldable f => f (HieAST a) - -> M.Map Identifier [(Span, IdentifierDetails a)] + -> RefMap a generateReferencesMap = foldr (\ast m -> M.unionWith (++) (go ast) m) M.empty where go ast = M.unionsWith (++) (this : map go (nodeChildren ast)) where - this = fmap (pure . (nodeSpan ast,)) $ nodeIdentifiers $ nodeInfo ast + this = fmap (pure . (nodeSpan ast,)) $ sourcedNodeIdents $ sourcedNodeInfo ast renderHieType :: DynFlags -> HieTypeFix -> String renderHieType dflags ht = renderWithStyle (initSDocContext dflags defaultUserStyle) (ppr $ hieTypeToIface ht) @@ -72,6 +81,73 @@ resolveVisibility kind ty_args foldType :: (HieType a -> a) -> HieTypeFix -> a foldType f (Roll t) = f $ fmap (foldType f) t +selectPoint :: HieFile -> (Int,Int) -> Maybe (HieAST Int) +selectPoint hf (sl,sc) = getFirst $ + flip foldMap (M.toList (getAsts $ hie_asts hf)) $ \(fs,ast) -> First $ + case selectSmallestContaining (sp fs) ast of + Nothing -> Nothing + Just ast' -> Just ast' + where + sloc fs = mkRealSrcLoc fs sl sc + sp fs = mkRealSrcSpan (sloc fs) (sloc fs) + +findEvidenceUse :: NodeIdentifiers a -> [Name] +findEvidenceUse ni = [n | (Right n, dets) <- xs, any isEvidenceUse (identInfo dets)] + where + xs = M.toList ni + +data EvidenceInfo a + = EvidenceInfo + { evidenceVar :: Name + , evidenceSpan :: RealSrcSpan + , evidenceType :: a + , evidenceDetails :: Maybe (EvVarSource, Scope, Maybe Span) + } deriving (Eq,Ord,Functor) + +instance (Outputable a) => Outputable (EvidenceInfo a) where + ppr (EvidenceInfo name span typ dets) = + hang (ppr name <+> text "at" <+> ppr span O.<> text ", of type:" <+> ppr typ) 4 $ + pdets $$ (pprDefinedAt name) + where + pdets = case dets of + Nothing -> text "is a usage of an external evidence variable" + Just (src,scp,spn) -> text "is an" <+> ppr (EvidenceVarBind src scp spn) + +getEvidenceTreesAtPoint :: HieFile -> RefMap a -> (Int,Int) -> Tree.Forest (EvidenceInfo a) +getEvidenceTreesAtPoint hf refmap point = + [t | Just ast <- pure $ selectPoint hf point + , n <- findEvidenceUse (sourcedNodeIdents $ sourcedNodeInfo ast) + , Just t <- pure $ getEvidenceTree refmap n + ] + +getEvidenceTree :: RefMap a -> Name -> Maybe (Tree.Tree (EvidenceInfo a)) +getEvidenceTree refmap var = go emptyNameSet var + where + go seen var + | var `elemNameSet` seen = Nothing + | otherwise = do + xs <- M.lookup (Right var) refmap + case find (any isEvidenceBind . identInfo . snd) xs of + Just (sp,dets) -> do + typ <- identType dets + (evdet,children) <- getFirst $ foldMap First $ do + det <- S.toList $ identInfo dets + case det of + EvidenceVarBind src@(EvLetBind (getEvBindDeps -> xs)) scp spn -> + pure $ Just ((src,scp,spn),mapMaybe (go $ extendNameSet seen var) xs) + EvidenceVarBind src scp spn -> pure $ Just ((src,scp,spn),[]) + _ -> pure Nothing + pure $ Tree.Node (EvidenceInfo var sp typ (Just evdet)) children + -- It is externally bound + Nothing -> getFirst $ foldMap First $ do + (sp,dets) <- xs + if (any isEvidenceUse $ identInfo dets) + then do + case identType dets of + Nothing -> pure Nothing + Just typ -> pure $ Just $ Tree.Node (EvidenceInfo var sp typ Nothing) [] + else pure Nothing + hieTypeToIface :: HieTypeFix -> IfaceType hieTypeToIface = foldType go where @@ -194,8 +270,10 @@ resolveTyVarScopeLocal ast asts = go ast resolveScope scope = scope go (Node info span children) = Node info' span $ map go children where - info' = info { nodeIdentifiers = idents } - idents = M.map resolveNameScope $ nodeIdentifiers info + info' = SourcedNodeInfo (updateNodeInfo <$> getSourcedNodeInfo info) + updateNodeInfo i = i { nodeIdentifiers = idents } + where + idents = M.map resolveNameScope $ nodeIdentifiers i getNameBinding :: Name -> M.Map FastString (HieAST a) -> Maybe Span getNameBinding n asts = do @@ -217,7 +295,7 @@ getNameBindingInClass n sp asts = do getFirst $ foldMap First $ do child <- flattenAst ast dets <- maybeToList - $ M.lookup (Right n) $ nodeIdentifiers $ nodeInfo child + $ M.lookup (Right n) $ sourcedNodeIdents $ sourcedNodeInfo child let binding = foldMap (First . getBindSiteFromContext) (identInfo dets) return (getFirst binding) @@ -232,7 +310,7 @@ getNameScopeAndBinding n asts = case nameSrcSpan n of getFirst $ foldMap First $ do -- @[] node <- flattenAst defNode dets <- maybeToList - $ M.lookup (Right n) $ nodeIdentifiers $ nodeInfo node + $ M.lookup (Right n) $ sourcedNodeIdents $ sourcedNodeInfo node scopes <- maybeToList $ foldMap getScopeFromContext (identInfo dets) let binding = foldMap (First . getBindSiteFromContext) (identInfo dets) return $ Just (scopes, getFirst binding) @@ -245,6 +323,7 @@ getScopeFromContext (ClassTyDecl _) = Just [ModuleScope] getScopeFromContext (Decl _ _) = Just [ModuleScope] getScopeFromContext (TyVarBind a (ResolvedScopes xs)) = Just $ a:xs getScopeFromContext (TyVarBind a _) = Just [a] +getScopeFromContext (EvidenceVarBind _ a _) = Just [a] getScopeFromContext _ = Nothing getBindSiteFromContext :: ContextInfo -> Maybe Span @@ -292,8 +371,27 @@ definedInAsts asts n = case nameSrcSpan n of RealSrcSpan sp _ -> srcSpanFile sp `elem` M.keys asts _ -> False +getEvidenceBindDeps :: ContextInfo -> [Name] +getEvidenceBindDeps (EvidenceVarBind (EvLetBind xs) _ _) = + getEvBindDeps xs +getEvidenceBindDeps _ = [] + +isEvidenceBind :: ContextInfo -> Bool +isEvidenceBind EvidenceVarBind{} = True +isEvidenceBind _ = False + +isEvidenceContext :: ContextInfo -> Bool +isEvidenceContext EvidenceVarUse = True +isEvidenceContext EvidenceVarBind{} = True +isEvidenceContext _ = False + +isEvidenceUse :: ContextInfo -> Bool +isEvidenceUse EvidenceVarUse = True +isEvidenceUse _ = False + isOccurrence :: ContextInfo -> Bool isOccurrence Use = True +isOccurrence EvidenceVarUse = True isOccurrence _ = False scopeContainsSpan :: Scope -> Span -> Bool @@ -304,7 +402,7 @@ scopeContainsSpan (LocalScope a) b = a `containsSpan` b -- | One must contain the other. Leaf nodes cannot contain anything combineAst :: HieAST Type -> HieAST Type -> HieAST Type combineAst a@(Node aInf aSpn xs) b@(Node bInf bSpn ys) - | aSpn == bSpn = Node (aInf `combineNodeInfo` bInf) aSpn (mergeAsts xs ys) + | aSpn == bSpn = Node (aInf `combineSourcedNodeInfo` bInf) aSpn (mergeAsts xs ys) | aSpn `containsSpan` bSpn = combineAst b a combineAst a (Node xs span children) = Node xs span (insertAst a children) @@ -312,6 +410,18 @@ combineAst a (Node xs span children) = Node xs span (insertAst a children) insertAst :: HieAST Type -> [HieAST Type] -> [HieAST Type] insertAst x = mergeAsts [x] +nodeInfo :: HieAST Type -> NodeInfo Type +nodeInfo = foldl' combineNodeInfo emptyNodeInfo . getSourcedNodeInfo . sourcedNodeInfo + +emptyNodeInfo :: NodeInfo a +emptyNodeInfo = NodeInfo S.empty [] M.empty + +sourcedNodeIdents :: SourcedNodeInfo a -> NodeIdentifiers a +sourcedNodeIdents = M.unionsWith (<>) . fmap nodeIdentifiers . getSourcedNodeInfo + +combineSourcedNodeInfo :: SourcedNodeInfo Type -> SourcedNodeInfo Type -> SourcedNodeInfo Type +combineSourcedNodeInfo = coerce $ M.unionWith combineNodeInfo + -- | Merge two nodes together. -- -- Precondition and postcondition: elements in 'nodeType' are ordered. @@ -404,11 +514,12 @@ mergeSortAsts = go . map pure simpleNodeInfo :: FastString -> FastString -> NodeInfo a simpleNodeInfo cons typ = NodeInfo (S.singleton (cons, typ)) [] M.empty -locOnly :: SrcSpan -> [HieAST a] -locOnly (RealSrcSpan span _) = - [Node e span []] - where e = NodeInfo S.empty [] M.empty -locOnly _ = [] +locOnly :: Monad m => SrcSpan -> ReaderT NodeOrigin m [HieAST a] +locOnly (RealSrcSpan span _) = do + org <- ask + let e = mkSourcedNodeInfo org $ emptyNodeInfo + pure [Node e span []] +locOnly _ = pure [] mkScope :: SrcSpan -> Scope mkScope (RealSrcSpan sp _) = LocalScope sp @@ -425,30 +536,37 @@ combineScopes x NoScope = x combineScopes (LocalScope a) (LocalScope b) = mkScope $ combineSrcSpans (RealSrcSpan a Nothing) (RealSrcSpan b Nothing) +mkSourcedNodeInfo :: NodeOrigin -> NodeInfo a -> SourcedNodeInfo a +mkSourcedNodeInfo org ni = SourcedNodeInfo $ M.singleton org ni + {-# INLINEABLE makeNode #-} makeNode - :: (Applicative m, Data a) + :: (Monad m, Data a) => a -- ^ helps fill in 'nodeAnnotations' (with 'Data') -> SrcSpan -- ^ return an empty list if this is unhelpful - -> m [HieAST b] -makeNode x spn = pure $ case spn of - RealSrcSpan span _ -> [Node (simpleNodeInfo cons typ) span []] - _ -> [] + -> ReaderT NodeOrigin m [HieAST b] +makeNode x spn = do + org <- ask + pure $ case spn of + RealSrcSpan span _ -> [Node (mkSourcedNodeInfo org $ simpleNodeInfo cons typ) span []] + _ -> [] where cons = mkFastString . show . toConstr $ x typ = mkFastString . show . typeRepTyCon . typeOf $ x {-# INLINEABLE makeTypeNode #-} makeTypeNode - :: (Applicative m, Data a) + :: (Monad m, Data a) => a -- ^ helps fill in 'nodeAnnotations' (with 'Data') -> SrcSpan -- ^ return an empty list if this is unhelpful -> Type -- ^ type to associate with the node - -> m [HieAST Type] -makeTypeNode x spn etyp = pure $ case spn of - RealSrcSpan span _ -> - [Node (NodeInfo (S.singleton (cons,typ)) [etyp] M.empty) span []] - _ -> [] + -> ReaderT NodeOrigin m [HieAST Type] +makeTypeNode x spn etyp = do + org <- ask + pure $ case spn of + RealSrcSpan span _ -> + [Node (mkSourcedNodeInfo org $ NodeInfo (S.singleton (cons,typ)) [etyp] M.empty) span []] + _ -> [] where cons = mkFastString . show . toConstr $ x typ = mkFastString . show . typeRepTyCon . typeOf $ x ===================================== testsuite/tests/hiefile/should_compile/Scopes.hs ===================================== @@ -1,10 +1,33 @@ +{-# LANGUAGE PatternSynonyms, ViewPatterns #-} +{-# LANGUAGE ImplicitParams #-} {-# LANGUAGE RecordWildCards #-} module Scopes where + +-- Verify that evidence bound by patern +-- synonyms has correct scope +pattern LL :: Num a => a -> a +pattern LL x <- (subtract 1 -> x) + where + LL x = x + 1 + data T = C { x :: Int, y :: Char } --- Verify that names generated from record construction are in scope +-- Verify that names generated from record construction +-- have correct scope foo = C { x = 1 , y = 'a' } +-- Verify that implicit paramters have correct scope +bar :: (?x :: Int) => Int +bar = ?x + 1 + +baz :: Int +baz = bar + ?x + where ?x = 2 + +-- Verify that variables bound in pattern +-- synonyms have the correct scope +pattern A a b = (a , b) + -- Verify that record wildcards are in scope sdaf :: T sdaf = C{..} ===================================== testsuite/tests/hiefile/should_run/HieQueries.hs ===================================== @@ -0,0 +1,82 @@ +{-# LANGUAGE ScopedTypeVariables #-} +module Main where + +import System.Environment + +import GHC.Types.Name.Cache +import GHC.Types.SrcLoc +import GHC.Types.Unique.Supply +import GHC.Types.Name +import Data.Tree +import GHC.Iface.Ext.Binary +import GHC.Iface.Ext.Types +import GHC.Iface.Ext.Utils +import Data.Maybe (fromJust) +import GHC.Driver.Session +import GHC.SysTools +import GHC.Utils.Outputable ( Outputable, renderWithStyle, ppr, defaultUserStyle, initSDocContext, text) +import qualified Data.Map as M +import Data.Foldable + +class C a where + f :: a -> Char + +instance C Char where + f x = x + +instance C a => C [a] where + f x = 'a' + +foo :: C a => a -> Char +foo x = f [x] +-- ^ this is the point +point :: (Int,Int) +point = (31,9) + +bar :: Show x => x -> String +bar x = show [(1,x,A)] +-- ^ this is the point' +point' :: (Int,Int) +point' = (37,9) + +data A = A deriving Show + +makeNc :: IO NameCache +makeNc = do + uniq_supply <- mkSplitUniqSupply 'z' + return $ initNameCache uniq_supply [] + +dynFlagsForPrinting :: String -> IO DynFlags +dynFlagsForPrinting libdir = do + systemSettings <- initSysTools libdir + return $ defaultDynFlags systemSettings (LlvmConfig [] []) + +main = do + libdir:_ <- getArgs + df <- dynFlagsForPrinting libdir + nc <- makeNc + hfr <- readHieFile (NCU (\f -> pure $ snd $ f nc)) "HieQueries.hie" + let hf = hie_file_result hfr + refmap = generateReferencesMap $ getAsts $ hie_asts hf + explainEv df hf refmap point + explainEv df hf refmap point' + return () + +explainEv :: DynFlags -> HieFile -> RefMap Int -> (Int,Int) -> IO () +explainEv df hf refmap point = do + putStrLn $ replicate 26 '=' + putStrLn $ "At point " ++ show point ++ ", we found:" + putStrLn $ replicate 26 '=' + putStr $ drawForest ptrees + where + trees = getEvidenceTreesAtPoint hf refmap point + + ptrees = fmap (pprint . fmap expandType) <$> trees + + expandType = text . renderHieType df . + flip recoverFullType (hie_types hf) + + pretty = unlines . (++["└"]) . ("┌":) . map ("│ "++) . lines + + pprint = pretty . renderWithStyle (initSDocContext df sty) . ppr + sty = defaultUserStyle ===================================== testsuite/tests/hiefile/should_run/HieQueries.stdout ===================================== @@ -0,0 +1,98 @@ +========================== +At point (31,9), we found: +========================== +┌ +│ $dC at HieQueries.hs:31:1-13, of type: C [a] +│ is an evidence variable bound by a let, depending on: [$fC[], $dC] +│ with scope: LocalScope HieQueries.hs:31:1-13 +│ bound at: HieQueries.hs:31:1-13 +│ Defined at +└ +| ++- ┌ +| │ $fC[] at HieQueries.hs:27:10-21, of type: forall a. C a => C [a] +| │ is an evidence variable bound by an instance of class C +| │ with scope: ModuleScope +| │ +| │ Defined at HieQueries.hs:27:10 +| └ +| +`- ┌ + │ $dC at HieQueries.hs:31:1-13, of type: C a + │ is an evidence variable bound by a type signature + │ with scope: LocalScope HieQueries.hs:31:1-13 + │ bound at: HieQueries.hs:31:1-13 + │ Defined at + └ + +========================== +At point (37,9), we found: +========================== +┌ +│ $dShow at HieQueries.hs:37:1-22, of type: Show [(Integer, x, A)] +│ is an evidence variable bound by a let, depending on: [$fShow[], +│ $dShow] +│ with scope: LocalScope HieQueries.hs:37:1-22 +│ bound at: HieQueries.hs:37:1-22 +│ Defined at +└ +| ++- ┌ +| │ $fShow[] at HieQueries.hs:37:1-22, of type: forall a. Show a => Show [a] +| │ is a usage of an external evidence variable +| │ Defined in `GHC.Show' +| └ +| +`- ┌ + │ $dShow at HieQueries.hs:37:1-22, of type: Show (Integer, x, A) + │ is an evidence variable bound by a let, depending on: [$fShow(,,), + │ $dShow, $dShow, $dShow] + │ with scope: LocalScope HieQueries.hs:37:1-22 + │ bound at: HieQueries.hs:37:1-22 + │ Defined at + └ + | + +- ┌ + | │ $fShow(,,) at HieQueries.hs:37:1-22, of type: forall a b c. (Show a, Show b, Show c) => Show (a, b, c) + | │ is a usage of an external evidence variable + | │ Defined in `GHC.Show' + | └ + | + +- ┌ + | │ $dShow at HieQueries.hs:37:1-22, of type: Show Integer + | │ is an evidence variable bound by a let, depending on: [$fShowInteger] + | │ with scope: LocalScope HieQueries.hs:37:1-22 + | │ bound at: HieQueries.hs:37:1-22 + | │ Defined at + | └ + | | + | `- ┌ + | │ $fShowInteger at HieQueries.hs:37:1-22, of type: Show Integer + | │ is a usage of an external evidence variable + | │ Defined in `GHC.Show' + | └ + | + +- ┌ + | │ $dShow at HieQueries.hs:37:1-22, of type: Show x + | │ is an evidence variable bound by a type signature + | │ with scope: LocalScope HieQueries.hs:37:1-22 + | │ bound at: HieQueries.hs:37:1-22 + | │ Defined at + | └ + | + `- ┌ + │ $dShow at HieQueries.hs:37:1-22, of type: Show A + │ is an evidence variable bound by a let, depending on: [$fShowA] + │ with scope: LocalScope HieQueries.hs:37:1-22 + │ bound at: HieQueries.hs:37:1-22 + │ Defined at + └ + | + `- ┌ + │ $fShowA at HieQueries.hs:42:21-24, of type: Show A + │ is an evidence variable bound by an instance of class Show + │ with scope: ModuleScope + │ + │ Defined at HieQueries.hs:42:21 + └ + ===================================== testsuite/tests/hiefile/should_run/PatTypes.hs ===================================== @@ -42,16 +42,9 @@ dynFlagsForPrinting libdir = do systemSettings <- initSysTools libdir return $ defaultDynFlags systemSettings (LlvmConfig [] []) -selectPoint :: HieFile -> (Int,Int) -> HieAST Int -selectPoint hf (sl,sc) = case M.toList (getAsts $ hie_asts hf) of - [(fs,ast)] -> - case selectSmallestContaining (sp fs) ast of - Nothing -> error "point not found" - Just ast' -> ast' - _ -> error "map should only contain a single AST" - where - sloc fs = mkRealSrcLoc fs sl sc - sp fs = mkRealSrcSpan (sloc fs) (sloc fs) +selectPoint' :: HieFile -> (Int,Int) -> HieAST Int +selectPoint' hf loc = + maybe (error "point not found") id $ selectPoint hf loc main = do libdir:_ <- getArgs @@ -61,6 +54,6 @@ main = do let hf = hie_file_result hfr forM_ [p1,p2,p3,p4] $ \point -> do putStr $ "At " ++ show point ++ ", got type: " - let types = nodeType $ nodeInfo $ selectPoint hf point + let types = concatMap nodeType $ getSourcedNodeInfo $ sourcedNodeInfo $ selectPoint' hf point forM_ types $ \typ -> do putStrLn (renderHieType df $ recoverFullType typ (hie_types hf)) ===================================== testsuite/tests/hiefile/should_run/all.T ===================================== @@ -1 +1,2 @@ test('PatTypes', [extra_run_opts('"' + config.libdir + '"')], compile_and_run, ['-package ghc -fwrite-ide-info']) +test('HieQueries', [extra_run_opts('"' + config.libdir + '"')], compile_and_run, ['-package ghc -fwrite-ide-info']) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 8f340aef12df5f5df02d49ab5c6c5d7cccfa398b +Subproject commit 8134a3be2c01ab5f1b88fed86c4ad7cc2f417f0a View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/53814a6424240ab50201fdde81a6e7832c1aad3d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/53814a6424240ab50201fdde81a6e7832c1aad3d You're receiving 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 26 07:04:15 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 26 May 2020 03:04:15 -0400 Subject: [Git][ghc/ghc][master] Make WorkWrap.Lib.isWorkerSmallEnough aware of the old arity Message-ID: <5eccbf6f572c1_6e263f9ed7508a741555928@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 6604906c by Sebastian Graf at 2020-05-26T03:04:04-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. - - - - - 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 ===================================== @@ -1034,7 +1034,7 @@ 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 +cf Note [Tick annotations in call patterns] in GHC.Core.Opt.SpecConstr Note [Matching lets] ~~~~~~~~~~~~~~~~~~~~ ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -655,14 +655,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 ===================================== @@ -52,3 +52,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']) test('T13380b', [ grep_errmsg('bigDeadAction') ], 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/6604906c8cfa37f5780a6d5c40506b751b1740db -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6604906c8cfa37f5780a6d5c40506b751b1740db You're receiving 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 26 07:04:55 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 26 May 2020 03:04:55 -0400 Subject: [Git][ghc/ghc][master] Enhance Note [About units] for Backpack Message-ID: <5eccbf97baa40_6e26115afe7c15584d4@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: cf772f19 by Sylvain Henry at 2020-05-26T03:04:45-04:00 Enhance Note [About units] for Backpack - - - - - 1 changed file: - compiler/GHC/Unit.hs Changes: ===================================== compiler/GHC/Unit.hs ===================================== @@ -21,237 +21,334 @@ import GHC.Unit.State import GHC.Unit.Subst import GHC.Unit.Module --- Note [About Units] --- ~~~~~~~~~~~~~~~~~~ --- --- Haskell users are used to manipulate Cabal packages. These packages are --- identified by: --- - a package name :: String --- - a package version :: Version --- - (a revision number, when they are registered on Hackage) --- --- Cabal packages may contain several components (libraries, programs, --- testsuites). In GHC we are mostly interested in libraries because those are --- the components that can be depended upon by other components. Components in a --- package are identified by their component name. Historically only one library --- component was allowed per package, hence it didn't need a name. For this --- reason, component name may be empty for one library component in each --- package: --- - a component name :: Maybe String --- --- UnitId --- ------ --- --- Cabal libraries can be compiled in various ways (different compiler options --- or Cabal flags, different dependencies, etc.), hence using package name, --- package version and component name isn't enough to identify a built library. --- We use another identifier called UnitId: --- --- package name \ --- package version | ________ --- component name | hash of all this ==> | UnitId | --- Cabal flags | -------- --- compiler options | --- dependencies' UnitId / --- --- Fortunately GHC doesn't have to generate these UnitId: they are provided by --- external build tools (e.g. Cabal) with `-this-unit-id` command-line parameter. --- --- UnitIds are important because they are used to generate internal names --- (symbols, etc.). --- --- Wired-in units --- -------------- --- --- Certain libraries are known to the compiler, in that we know about certain --- entities that reside in these libraries. The compiler needs to declare static --- Modules and Names that refer to units built from these libraries. --- --- Hence UnitIds of wired-in libraries are fixed. Instead of letting Cabal chose --- the UnitId for these libraries, their .cabal file uses the following stanza to --- force it to a specific value: --- --- ghc-options: -this-unit-id ghc-prim -- taken from ghc-prim.cabal --- --- The RTS also uses entities of wired-in units by directly referring to symbols --- such as "base_GHCziIOziException_heapOverflow_closure" where the prefix is --- the UnitId of "base" unit. --- --- Unit databases --- -------------- --- --- Units are stored in databases in order to be reused by other codes: --- --- UnitKey ---> UnitInfo { exposed modules, package name, package version --- component name, various file paths, --- dependencies :: [UnitKey], etc. } --- --- Because of the wired-in units described above, we can't exactly use UnitIds --- as UnitKeys in the database: if we did this, we could only have a single unit --- (compiled library) in the database for each wired-in library. As we want to --- support databases containing several different units for the same wired-in --- library, we do this: --- --- * for non wired-in units: --- * UnitId = UnitKey = Identifier (hash) computed by Cabal --- --- * for wired-in units: --- * UnitKey = Identifier computed by Cabal (just like for non wired-in units) --- * UnitId = unit-id specified with -this-unit-id command-line flag --- --- We can expose several units to GHC via the `package-id ` --- command-line parameter. We must use the UnitKeys of the units so that GHC can --- find them in the database. --- --- GHC then replaces the UnitKeys with UnitIds by taking into account wired-in --- units: these units are detected thanks to their UnitInfo (especially their --- package name). --- --- For example, knowing that "base", "ghc-prim" and "rts" are wired-in packages, --- the following dependency graph expressed with UnitKeys (as found in the --- database) will be transformed into a similar graph expressed with UnitIds --- (that are what matters for compilation): --- --- UnitKeys --- ~~~~~~~~ ---> rts-1.0-hashABC <-- --- | | --- | | --- foo-2.0-hash123 --> base-4.1-hashXYZ ---> ghc-prim-0.5.3-hashABC --- --- UnitIds --- ~~~~~~~ ---> rts <-- --- | | --- | | --- foo-2.0-hash123 --> base ---------------> ghc-prim --- --- --- Module signatures / indefinite units / instantiated units --- --------------------------------------------------------- --- --- GHC distinguishes two kinds of units: --- --- * definite: units for which every module has an associated code object --- (i.e. real compiled code in a .o/.a/.so/.dll/...) --- --- * indefinite: units for which some modules are replaced by module --- signatures. --- --- Module signatures are a kind of interface (similar to .hs-boot files). They --- are used in place of some real code. GHC allows real modules from other --- units to be used to fill these module holes. The process is called --- "unit/module instantiation". --- --- You can think of this as polymorphism at the module level: module signatures --- give constraints on the "type" of module that can be used to fill the hole --- (where "type" means types of the exported module entitites, etc.). --- --- Module signatures contain enough information (datatypes, abstract types, type --- synonyms, classes, etc.) to typecheck modules depending on them but not --- enough to compile them. As such, indefinite units found in databases only --- provide module interfaces (the .hi ones this time), not object code. --- --- To distinguish between indefinite and finite unit ids at the type level, we --- respectively use 'IndefUnitId' and 'DefUnitId' datatypes that are basically --- wrappers over 'UnitId'. --- --- Unit instantiation --- ------------------ --- --- Indefinite units can be instantiated with modules from other units. The --- instantiating units can also be instantiated themselves (if there are --- indefinite) and so on. The 'Unit' datatype represents a unit which may have --- been instantiated: --- --- data Unit = RealUnit DefUnitId --- | VirtUnit InstantiatedUnit --- --- 'InstantiatedUnit' has two interesting fields: --- --- * instUnitInstanceOf :: IndefUnitId --- -- ^ the indefinite unit that is instantiated --- --- * instUnitInsts :: [(ModuleName,(Unit,ModuleName)] --- -- ^ a list of instantiations, where an instantiation is: --- (module hole name, (instantiating unit, instantiating module name)) --- --- A 'Unit' may be indefinite or definite, it depends on whether some holes --- remain in the instantiated unit OR in the instantiating units (recursively). --- --- Pretty-printing UnitId --- ---------------------- --- --- GHC mostly deals with UnitIds which are some opaque strings. We could display --- them when we pretty-print a module origin, a name, etc. But it wouldn't be --- very friendly to the user because of the hash they usually contain. E.g. --- --- foo-4.18.1:thelib-XYZsomeUglyHashABC --- --- Instead when we want to pretty-print a 'UnitId' we query the database to --- get the 'UnitInfo' and print something nicer to the user: --- --- foo-4.18.1:thelib --- --- We do the same for wired-in units. --- --- Currently (2020-04-06), we don't thread the database into every function that --- pretty-prints a Name/Module/Unit. Instead querying the database is delayed --- until the `SDoc` is transformed into a `Doc` using the database that is --- active at this point in time. This is an issue because we want to be able to --- unload units from the database and we also want to support several --- independent databases loaded at the same time (see #14335). The alternatives --- we have are: --- --- * threading the database into every function that pretty-prints a UnitId --- for the user (directly or indirectly). --- --- * storing enough info to correctly display a UnitId into the UnitId --- datatype itself. This is done in the IndefUnitId wrapper (see --- 'UnitPprInfo' datatype) but not for every 'UnitId'. Statically defined --- 'UnitId' for wired-in units would have empty UnitPprInfo so we need to --- find some places to update them if we want to display wired-in UnitId --- correctly. This leads to a solution similar to the first one above. --- --- Note [VirtUnit to RealUnit improvement] --- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --- --- Over the course of instantiating VirtUnits on the fly while typechecking an --- indefinite library, we may end up with a fully instantiated VirtUnit. I.e. --- one that could be compiled and installed in the database. During --- type-checking we generate a virtual UnitId for it, say "abc". --- --- Now the question is: do we have a matching installed unit in the database? --- Suppose we have one with UnitId "xyz" (provided by Cabal so we don't know how --- to generate it). The trouble is that if both units end up being used in the --- same type-checking session, their names won't match (e.g. "abc:M.X" vs --- "xyz:M.X"). --- --- As we want them to match we just replace the virtual unit with the installed --- one: for some reason this is called "improvement". --- --- There is one last niggle: improvement based on the package database means --- that we might end up developing on a package that is not transitively --- depended upon by the packages the user specified directly via command line --- flags. This could lead to strange and difficult to understand bugs if those --- instantiations are out of date. The solution is to only improve a --- unit id if the new unit id is part of the 'preloadClosure'; i.e., the --- closure of all the packages which were explicitly specified. - --- Note [Representation of module/name variables] --- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --- In our ICFP'16, we use to represent module holes, and {A.T} to represent --- name holes. This could have been represented by adding some new cases --- to the core data types, but this would have made the existing 'moduleName' --- and 'moduleUnit' partial, which would have required a lot of modifications --- to existing code. --- --- Instead, we use a fake "hole" unit: --- --- ===> hole:A --- {A.T} ===> hole:A.T --- --- This encoding is quite convenient, but it is also a bit dangerous too, --- because if you have a 'hole:A' you need to know if it's actually a --- 'Module' or just a module stored in a 'Name'; these two cases must be --- treated differently when doing substitutions. 'renameHoleModule' --- and 'renameHoleUnit' assume they are NOT operating on a --- 'Name'; 'NameShape' handles name substitutions exclusively. +{- + +Note [About Units] +~~~~~~~~~~~~~~~~~~ + +Haskell users are used to manipulate Cabal packages. These packages are +identified by: + - a package name :: String + - a package version :: Version + - (a revision number, when they are registered on Hackage) + +Cabal packages may contain several components (libraries, programs, +testsuites). In GHC we are mostly interested in libraries because those are +the components that can be depended upon by other components. Components in a +package are identified by their component name. Historically only one library +component was allowed per package, hence it didn't need a name. For this +reason, component name may be empty for one library component in each +package: + - a component name :: Maybe String + +UnitId +------ + +Cabal libraries can be compiled in various ways (different compiler options +or Cabal flags, different dependencies, etc.), hence using package name, +package version and component name isn't enough to identify a built library. +We use another identifier called UnitId: + + package name \ + package version | ________ + component name | hash of all this ==> | UnitId | + Cabal flags | -------- + compiler options | + dependencies' UnitId / + +Fortunately GHC doesn't have to generate these UnitId: they are provided by +external build tools (e.g. Cabal) with `-this-unit-id` command-line parameter. + +UnitIds are important because they are used to generate internal names +(symbols, etc.). + +Wired-in units +-------------- + +Certain libraries (ghc-prim, base, etc.) are known to the compiler and to the +RTS as they provide some basic primitives. Hence UnitIds of wired-in libraries +are fixed. Instead of letting Cabal chose the UnitId for these libraries, their +.cabal file uses the following stanza to force it to a specific value: + + ghc-options: -this-unit-id ghc-prim -- taken from ghc-prim.cabal + +The RTS also uses entities of wired-in units by directly referring to symbols +such as "base_GHCziIOziException_heapOverflow_closure" where the prefix is +the UnitId of "base" unit. + +Unit databases +-------------- + +Units are stored in databases in order to be reused by other codes: + + UnitKey ---> UnitInfo { exposed modules, package name, package version + component name, various file paths, + dependencies :: [UnitKey], etc. } + +Because of the wired-in units described above, we can't exactly use UnitIds +as UnitKeys in the database: if we did this, we could only have a single unit +(compiled library) in the database for each wired-in library. As we want to +support databases containing several different units for the same wired-in +library, we do this: + + * for non wired-in units: + * UnitId = UnitKey = Identifier (hash) computed by Cabal + + * for wired-in units: + * UnitKey = Identifier computed by Cabal (just like for non wired-in units) + * UnitId = unit-id specified with -this-unit-id command-line flag + +We can expose several units to GHC via the `package-id ` command-line +parameter. We must use the UnitKeys of the units so that GHC can find them in +the database. + +During unit loading, GHC replaces UnitKeys with UnitIds. It identifies wired +units by their package name (stored in their UnitInfo) and uses wired-in UnitIds +for them. + +For example, knowing that "base", "ghc-prim" and "rts" are wired-in units, the +following dependency graph expressed with database UnitKeys will be transformed +into a similar graph expressed with UnitIds: + + UnitKeys + ~~~~~~~~ ----------> rts-1.0-hashABC <-- + | | + | | + foo-2.0-hash123 --> base-4.1-hashXYZ ---> ghc-prim-0.5.3-hashUVW + + UnitIds + ~~~~~~~ ---------------> rts <-- + | | + | | + foo-2.0-hash123 --> base ---------------> ghc-prim + + +Note that "foo-2.0-hash123" isn't wired-in so its UnitId is the same as its UnitKey. + + +Module signatures / indefinite units / instantiated units +--------------------------------------------------------- + +GHC distinguishes two kinds of units: + + * definite units: + * units without module holes and with definite dependencies + * can be compiled into machine code (.o/.a/.so/.dll/...) + + * indefinite units: + * units with some module holes or with some indefinite dependencies + * can only be type-checked + +Module holes are constrained by module signatures (.hsig files). Module +signatures are a kind of interface (similar to .hs-boot files). They are used in +place of some real code. GHC allows modules from other units to be used to fill +these module holes: the process is called "unit/module instantiation". The +instantiating module may either be a concrete module or a module signature. In +the latter case, the signatures are merged to form a new one. + +You can think of this as polymorphism at the module level: module signatures +give constraints on the "type" of module that can be used to fill the hole +(where "type" means types of the exported module entitites, etc.). + +Module signatures contain enough information (datatypes, abstract types, type +synonyms, classes, etc.) to typecheck modules depending on them but not +enough to compile them. As such, indefinite units found in databases only +provide module interfaces (the .hi ones this time), not object code. + +To distinguish between indefinite and definite unit ids at the type level, we +respectively use 'IndefUnitId' and 'DefUnitId' datatypes that are basically +wrappers over 'UnitId'. + +Unit instantiation / on-the-fly instantiation +--------------------------------------------- + +Indefinite units can be instantiated with modules from other units. The +instantiating units can also be instantiated themselves (if there are +indefinite) and so on. + +On-the-fly unit instantiation is a tricky optimization explained in +http://blog.ezyang.com/2016/08/optimizing-incremental-compilation +Here is a summary: + + 1. Indefinite units can only be type-checked, not compiled into real code. + Type-checking produces interface files (.hi) which are incomplete for code + generation (they lack unfoldings, etc.) but enough to perform type-checking + of units depending on them. + + 2. Type-checking an instantiated unit is cheap as we only have to merge + interface files (.hi) of the instantiated unit and of the instantiating + units, hence it can be done on-the-fly. Interface files of the dependencies + can be concrete or produced on-the-fly recursively. + + 3. When we compile a unit, we mustn't use interfaces produced by the + type-checker (on-the-fly or not) for the instantiated unit dependencies + because they lack some information. + + 4. When we type-check an indefinite unit, we must be consistent about the + interfaces we use for each dependency: only those produced by the + type-checker (on-the-fly or not) or only those produced after a full + compilation, but not both at the same time. + + It can be tricky if we have the following kind of dependency graph: + + X (indefinite) ------> D (definite, compiled) -----> I (instantiated, definite, compiled) + |----------------------------------------------------^ + + Suppose we want to type-check unit X which depends on unit I and D: + * I is definite and compiled: we have compiled .hi files for its modules on disk + * I is instantiated: it is cheap to produce type-checker .hi files for its modules on-the-fly + + But we must not do: + + X (indefinite) ------> D (definite, compiled) -----> I (instantiated, definite, compiled) + |--------------------------------------------------> I (instantiated on-the-fly) + + ==> inconsistent module interfaces for I + + Nor: + + X (indefinite) ------> D (definite, compiled) -------v + |--------------------------------------------------> I (instantiated on-the-fly) + + ==> D's interfaces may refer to things that only exist in I's *compiled* interfaces + + An alternative would be to store both type-checked and compiled interfaces + for every compiled non-instantiated unit (instantiated unit can be done + on-the-fly) so that we could use type-checked interfaces of D in the + example above. But it would increase compilation time and unit size. + + +The 'Unit' datatype represents a unit which may have been instantiated +on-the-fly: + + data Unit = RealUnit DefUnitId -- use compiled interfaces on disk + | VirtUnit InstantiatedUnit -- use on-the-fly instantiation + +'InstantiatedUnit' has two interesting fields: + + * instUnitInstanceOf :: IndefUnitId + -- ^ the indefinite unit that is instantiated + + * instUnitInsts :: [(ModuleName,(Unit,ModuleName)] + -- ^ a list of instantiations, where an instantiation is: + (module hole name, (instantiating unit, instantiating module name)) + +A 'VirtUnit' may be indefinite or definite, it depends on whether some holes +remain in the instantiated unit OR in the instantiating units (recursively). +Having a fully instantiated (i.e. definite) virtual unit can lead to some issues +if there is a matching compiled unit in the preload closure. See Note [VirtUnit +to RealUnit improvement] + +Unit database and indefinite units +---------------------------------- + +We don't store partially instantiated units in the unit database. Units in the +database are either: + + * definite (fully instantiated or without holes): in this case we have + *compiled* module interfaces (.hi) and object codes (.o/.a/.so/.dll/...). + + * fully indefinite (not instantiated at all): in this case we only have + *type-checked* module interfaces (.hi). + +Note that indefinite units are stored as an instantiation of themselves where +each instantiating module is a module variable (see Note [Representation of +module/name variables]). E.g. + + "xyz" (UnitKey) ---> UnitInfo { instanceOf = "xyz" + , instantiatedWith = [A=,B=...] + , ... + } + +Note that non-instantiated units are also stored as an instantiation of +themselves. It is a reminiscence of previous terminology (when "instanceOf" was +"componentId"). E.g. + + "xyz" (UnitKey) ---> UnitInfo { instanceOf = "xyz" + , instantiatedWith = [] + , ... + } + +TODO: We should probably have `instanceOf :: Maybe IndefUnitId` instead. + + +Pretty-printing UnitId +---------------------- + +GHC mostly deals with UnitIds which are some opaque strings. We could display +them when we pretty-print a module origin, a name, etc. But it wouldn't be +very friendly to the user because of the hash they usually contain. E.g. + + foo-4.18.1:thelib-XYZsomeUglyHashABC + +Instead when we want to pretty-print a 'UnitId' we query the database to +get the 'UnitInfo' and print something nicer to the user: + + foo-4.18.1:thelib + +We do the same for wired-in units. + +Currently (2020-04-06), we don't thread the database into every function that +pretty-prints a Name/Module/Unit. Instead querying the database is delayed +until the `SDoc` is transformed into a `Doc` using the database that is +active at this point in time. This is an issue because we want to be able to +unload units from the database and we also want to support several +independent databases loaded at the same time (see #14335). The alternatives +we have are: + + * threading the database into every function that pretty-prints a UnitId + for the user (directly or indirectly). + + * storing enough info to correctly display a UnitId into the UnitId + datatype itself. This is done in the IndefUnitId wrapper (see + 'UnitPprInfo' datatype) but not for every 'UnitId'. Statically defined + 'UnitId' for wired-in units would have empty UnitPprInfo so we need to + find some places to update them if we want to display wired-in UnitId + correctly. This leads to a solution similar to the first one above. + +Note [VirtUnit to RealUnit improvement] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Over the course of instantiating VirtUnits on the fly while typechecking an +indefinite library, we may end up with a fully instantiated VirtUnit. I.e. +one that could be compiled and installed in the database. During +type-checking we generate a virtual UnitId for it, say "abc". + +Now the question is: do we have a matching installed unit in the database? +Suppose we have one with UnitId "xyz" (provided by Cabal so we don't know how +to generate it). The trouble is that if both units end up being used in the +same type-checking session, their names won't match (e.g. "abc:M.X" vs +"xyz:M.X"). + +As we want them to match we just replace the virtual unit with the installed +one: for some reason this is called "improvement". + +There is one last niggle: improvement based on the unit database means +that we might end up developing on a unit that is not transitively +depended upon by the units the user specified directly via command line +flags. This could lead to strange and difficult to understand bugs if those +instantiations are out of date. The solution is to only improve a +unit id if the new unit id is part of the 'preloadClosure'; i.e., the +closure of all the units which were explicitly specified. + +Note [Representation of module/name variables] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In our ICFP'16, we use to represent module holes, and {A.T} to represent +name holes. This could have been represented by adding some new cases +to the core data types, but this would have made the existing 'moduleName' +and 'moduleUnit' partial, which would have required a lot of modifications +to existing code. + +Instead, we use a fake "hole" unit: + + ===> hole:A + {A.T} ===> hole:A.T + +This encoding is quite convenient, but it is also a bit dangerous too, +because if you have a 'hole:A' you need to know if it's actually a +'Module' or just a module stored in a 'Name'; these two cases must be +treated differently when doing substitutions. 'renameHoleModule' +and 'renameHoleUnit' assume they are NOT operating on a +'Name'; 'NameShape' handles name substitutions exclusively. + +-} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cf772f19c06944f0fd03b4bdcd4a49e437084ba5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cf772f19c06944f0fd03b4bdcd4a49e437084ba5 You're receiving 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 26 09:26:58 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Tue, 26 May 2020 05:26:58 -0400 Subject: [Git][ghc/ghc][wip/nested-cpr-2019] 81 commits: Remove duplicate Note [When to print foralls] in GHC.Core.TyCo.Ppr Message-ID: <5ecce0e2fda2_6e263f9ee35223001577265@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/nested-cpr-2019 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] - - - - - 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 - - - - - 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 - - - - - 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. - - - - - 78c6523c by Ben Gamari at 2020-05-21T12:13:01-04:00 nonmoving: Optimise the write barrier - - - - - 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). - - - - - 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 - - - - - b7a6b2f4 by Gleb Popov at 2020-05-21T12:15:26-04:00 gitlab-ci: Set locale to C.UTF-8. - - - - - 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. - - - - - 0004ccb8 by Tuan Le at 2020-05-21T12:16:46-04:00 llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 - - - - - 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 - - - - - 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 - - - - - 2b363ebb by Richard Eisenberg at 2020-05-21T12:18:45-04:00 MR template should ask for key part - - - - - a95bbd0b by Sebastian Graf at 2020-05-21T12:19:37-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. - - - - - d3d055b8 by Galen Huntington at 2020-05-21T12:20:18-04:00 Clarify pitfalls of NegativeLiterals; see #18022. - - - - - 1b508a9e by Alexey Kuleshevich at 2020-05-21T12:21:02-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" - - - - - 4ca0c8a1 by Andreas Klebinger at 2020-05-21T12:21: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. - - - - - a1275081 by Krzysztof Gogolewski at 2020-05-21T12:22:35-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 - - - - - 8a816e5f by Krzysztof Gogolewski at 2020-05-21T12:23:55-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. - - - - - 566cc73f by Sylvain Henry at 2020-05-21T12:24:45-04:00 Move isDynLinkName into GHC.Types.Name It doesn't belong into GHC.Unit.State - - - - - d830bbc9 by Adam Sandberg Ericsson at 2020-05-23T13:36:20-04:00 docs: fix formatting and add some links [skip ci] - - - - - 49301ad6 by Andrew Martin at 2020-05-23T13:37:01-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. - - - - - dcd6bdcc by Ben Gamari at 2020-05-23T13:37:48-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. - - - - - 82cb8913 by John Ericson at 2020-05-23T13:38:32-04:00 Fix #18145 and also avoid needless work with implicit vars - `forAllOrNothing` now is monadic, so we can trace whether we bind an explicit `forall` or not. - #18145 arose because the free vars calculation was needlessly complex. It is now greatly simplified. - Replaced some other implicit var code with `filterFreeVarsToBind`. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - a60dc835 by Ben Gamari at 2020-05-23T13:39:12-04:00 Bump process submodule Fixes #17926. - - - - - 856adf54 by Ben Gamari at 2020-05-23T13:40:21-04:00 users-guide: Clarify meaning of -haddock flag Fixes #18206. - - - - - 7ae57afd by Ben Gamari at 2020-05-23T13:41:03-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 - - - - - 63d30e60 by jneira at 2020-05-24T01:54:42-04:00 Add hie-bios script for windows systems It is a direct translation of the sh script - - - - - 59182b88 by jneira at 2020-05-24T01:54:42-04:00 Honour previous values for CABAL and CABFLAGS The immediate goal is let the hie-bios.bat script set CABFLAGS with `-v0` and remove all cabal output except the compiler arguments - - - - - 932dc54e by jneira at 2020-05-24T01:54:42-04:00 Add specific configuration for windows in hie.yaml - - - - - e0eda070 by jneira at 2020-05-24T01:54:42-04:00 Remove not needed hie-bios output - - - - - a0ea59d6 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Move Config module into GHC.Settings - - - - - 37430251 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Core.Arity into GHC.Core.Opt.Arity - - - - - a426abb9 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Hs.Types into GHC.Hs.Type See discussion in https://gitlab.haskell.org/ghc/ghc/issues/13009#note_268610 - - - - - 1c91a7a0 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Bump haddock submodule - - - - - 66bd24d1 by Ryan Scott at 2020-05-24T01:56:03-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. - - - - - 01c43634 by Matthew Pickering at 2020-05-24T01:56:42-04:00 Remove unused hs-boot file - - - - - 7a07aa71 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix cross-compiler build (#16051) - - - - - 15ccca16 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix distDir per stage - - - - - b420fb24 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix hp2ps error during cross-compilation Fixed by @alp (see https://gitlab.haskell.org/ghc/ghc/issues/16051#note_274265) - - - - - cd339ef0 by Joshua Price at 2020-05-24T15:22:56-04:00 Make Unicode brackets opening/closing tokens (#18225) The tokens `[|`, `|]`, `(|`, and `|)` are opening/closing tokens as described in GHC Proposal #229. This commit makes the unicode variants (`⟦`, `⟧`, `⦇`, and `⦈`) act the same as their ASCII counterparts. - - - - - 61a46464 by Sebastian Graf at 2020-05-26T11:26:06+02:00 Nested CPR - - - - - 56014585 by Sebastian Graf at 2020-05-26T11:26:06+02:00 Move tests from stranal to cpranal - - - - - 32bab299 by Sebastian Graf at 2020-05-26T11:26:06+02:00 Accept FacState - - - - - 5b452873 by Sebastian Graf at 2020-05-26T11:26:06+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. - - - - - 051e28e1 by Sebastian Graf at 2020-05-26T11:26:42+02:00 Consider unboxing effects of WW better and get rid of hack - - - - - 4d0c1f9d by Sebastian Graf at 2020-05-26T11:26:44+02:00 stuff - - - - - 0487b064 by Sebastian Graf at 2020-05-26T11:26:44+02:00 Debug output - - - - - 630ce44d by Sebastian Graf at 2020-05-26T11:26:44+02:00 A slew of testsuite changes - - - - - f1234f76 by Sebastian Graf at 2020-05-26T11:26:44+02:00 Fix T1600 - - - - - 3f3d7881 by Sebastian Graf at 2020-05-26T11:26:44+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. - - - - - 2e4bb983 by Sebastian Graf at 2020-05-26T11:26:44+02:00 Fix primop termination - - - - - 8dbfd893 by Sebastian Graf at 2020-05-26T11:26:44+02:00 Test for DataCon wrapper CPR - - - - - f9386552 by Sebastian Graf at 2020-05-26T11:26:45+02:00 Fix CPR of bottoming functions/primops - - - - - 2472d714 by Sebastian Graf at 2020-05-26T11:26:45+02:00 Fix DataConWrapperCpr and accept other test outputs - - - - - e8aabb57 by Sebastian Graf at 2020-05-26T11:26:45+02:00 Accept two more changed test outputs - - - - - d0a9c046 by Sebastian Graf at 2020-05-26T11:26:45+02:00 Update CaseBinderCPR with a new function - - - - - 8143ce54 by Sebastian Graf at 2020-05-26T11:26:45+02:00 Don't give the case binder the CPR property - - - - - 0dfaf57e by Sebastian Graf at 2020-05-26T11:26:45+02:00 Prune CPR sigs to constant depth on all bindings - - - - - 05642eb3 by Sebastian Graf at 2020-05-26T11:26:45+02:00 Use variable length coding for ConTags - - - - - 159777d4 by Sebastian Graf at 2020-05-26T11:26:45+02:00 Accept testuite output - - - - - 9b391fd5 by Sebastian Graf at 2020-05-26T11:26:45+02:00 Don't attach CPR sigs to expandable bindings; transform their unfoldings instead - - - - - 32f29281 by Sebastian Graf at 2020-05-26T11:26:45+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`. - - - - - 13545e2d by Sebastian Graf at 2020-05-26T11:26:45+02:00 A more modular and configurable approach to optimistic case binder CPR - - - - - 545ba9d1 by Sebastian Graf at 2020-05-26T11:26:45+02:00 Fix T9291 - - - - - b58def22 by Sebastian Graf at 2020-05-26T11:26:45+02:00 Document -fcase-binder-cpr-depth in the user's guide - - - - - bb965505 by Sebastian Graf at 2020-05-26T11:26:45+02:00 Rebase woes - - - - - 69fe0bd6 by Sebastian Graf at 2020-05-26T11:26:45+02:00 Testsuite changes - - - - - d33b8ba7 by Sebastian Graf at 2020-05-26T11:26:45+02:00 Refactoring around cprAnalBind - - - - - 2594ade0 by Sebastian Graf at 2020-05-26T11:26:45+02:00 Fix case binder CPR by not looking into unfoldings of case binders - - - - - 30 changed files: - + .git-ignore-revs - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/merge_request_templates/merge-request.md - compiler/GHC/Builtin/Names.hs - − compiler/GHC/Builtin/Names.hs-boot - 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/Dwarf.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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3ae7eb1f530eba8e30fb85a0f5d018e15666b882...2594ade04814abc16db74367265be92acc82c94a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3ae7eb1f530eba8e30fb85a0f5d018e15666b882...2594ade04814abc16db74367265be92acc82c94a You're receiving 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 26 09:58:47 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Tue, 26 May 2020 05:58:47 -0400 Subject: [Git][ghc/ghc][wip/T18086] DmdAnal: Recognise precise exceptions from case alternatives (#18086) Message-ID: <5ecce85780e8d_6e26eb9d3f015841df@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/T18086 at Glasgow Haskell Compiler / GHC Commits: 52721c43 by Sebastian Graf at 2020-05-26T11:58:37+02:00 DmdAnal: Recognise precise exceptions from case alternatives (#18086) Consider ```hs m :: IO () m = do putStrLn "foo" error "bar" ``` `m` (from #18086) always throws a (precise or imprecise) exception or diverges. Yet demand analysis infers `<L,A>` as demand signature instead of `<L,A>x` for it. That's because the demand analyser sees `putStrLn` occuring in a case scrutinee and decides that it has to `deferAfterPreciseException`, because `putStrLn` throws a precise exception on some control flow paths. This will mask the `botDiv` `Divergence`of the single case alt containing `error` to `topDiv`. Since `putStrLn` has `topDiv` itself, the final `Divergence` is `topDiv`. This is easily fixed: `deferAfterPreciseException` works by `lub`ing with the demand type of a virtual case branch denoting the precise exceptional control flow. We used `nopDmdType` before, but we can be more precise and use `exnDmdType`, which is `nopDmdType` with `exnDiv`. Now the `Divergence` from the case alt will degrade `botDiv` to `exnDiv` instead of `topDiv`, which combines with the result from the scrutinee to `exnDiv`, and all is well. Fixes #18086. - - - - - 4 changed files: - compiler/GHC/Types/Demand.hs - + testsuite/tests/stranal/sigs/T18086.hs - + testsuite/tests/stranal/sigs/T18086.stderr - testsuite/tests/stranal/sigs/all.T Changes: ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -1055,11 +1055,19 @@ Is this strict in 'y'? Often not! If @foo x s@ might throw a precise exception (ultimately via raiseIO#), then we must not force 'y', which may fail to terminate or throw an imprecise exception, until we have performed @foo x s at . -So we have to 'Demand.deferAfterPreciseException' (which just 'lub's with -'nopDmdType' to model the exceptional control flow) when @foo x s@ -may throw a precise exception. Motivated by T13380{d,e,f}. +So we have to 'deferAfterPreciseException' (which 'lub's with 'exnDmdType' to +model the exceptional control flow) when @foo x s@ may throw a precise +exception. Motivated by T13380{d,e,f}. See Note [Which scrutinees may throw precise exceptions] in DmdAnal. +We have to be careful not to discard dead-end Divergence from case +alternatives, though (#18086): + + m = putStrLn "foo" >> error "bar" + +'m' should still have 'exnDiv', which is why it is not sufficient to lub with +'nopDmdType' (which has 'topDiv') in 'deferAfterPreciseException'. + Historical Note: This used to be called the "IO hack". But that term is rather a bad fit because 1. It's easily confused with the "State hack", which also affects IO. @@ -1261,6 +1269,11 @@ isTopDmdType :: DmdType -> Bool isTopDmdType (DmdType env args div) = div == topDiv && null args && isEmptyVarEnv env +-- | The demand type of an unspecified expression that is guaranteed to +-- throw a (precise or imprecise) exception or diverge. +exnDmdType :: DmdType +exnDmdType = DmdType emptyDmdEnv [] exnDiv + dmdTypeDepth :: DmdType -> Arity dmdTypeDepth (DmdType _ ds _) = length ds @@ -1303,13 +1316,17 @@ splitDmdTy (DmdType fv (dmd:dmds) res_ty) = (dmd, DmdType fv dmds res_ty) splitDmdTy ty@(DmdType _ [] res_ty) = (defaultArgDmd res_ty, ty) -- | When e is evaluated after executing an IO action that may throw a precise --- exception, and d is e's demand, then what of this demand should we consider? --- * We have to kill all strictness demands (i.e. lub with a lazy demand) --- * We can keep usage information (i.e. lub with an absent demand) --- * We have to kill definite divergence +-- exception, we act as if there is an additional control flow path that is +-- taken if e throws a precise exception. The demand type of this control flow +-- path +-- * is lazy and absent ('topDmd') in all free variables and arguments +-- * has 'exnDiv' 'Divergence' result +-- So we can simply take a variant of 'nopDmdType', 'exnDmdType'. +-- Why not 'nopDmdType'? Because then the result of 'e' can never be 'exnDiv'! +-- That means failure to drop dead-ends, see #18086. -- See Note [Precise exceptions and strictness analysis] deferAfterPreciseException :: DmdType -> DmdType -deferAfterPreciseException d = lubDmdType d nopDmdType +deferAfterPreciseException = lubDmdType exnDmdType strictenDmd :: Demand -> CleanDemand strictenDmd (JD { sd = s, ud = u}) ===================================== testsuite/tests/stranal/sigs/T18086.hs ===================================== @@ -0,0 +1,23 @@ +{-# OPTIONS_GHC -O2 -fforce-recomp #-} +module T18086 where + +import GHC.Stack +import GHC.Utils.Panic.Plain +import Control.Exception +import System.IO.Unsafe + +-- Should have strictness signature x, emphasis on the exceptional +-- divergence result. +m :: IO () +m = do + putStrLn "foo" + error "bar" + +-- Dito, just in a more complex scenario (the original reproducer of #18086) +panic :: String -> a +panic x = unsafeDupablePerformIO $ do + stack <- ccsToStrings =<< getCurrentCCS x + if null stack + then throw (PlainPanic x) + else throw (PlainPanic (x ++ '\n' : renderStack stack)) + ===================================== testsuite/tests/stranal/sigs/T18086.stderr ===================================== @@ -0,0 +1,21 @@ + +==================== Strictness signatures ==================== +T18086.$trModule: +T18086.m: x +T18086.panic: x + + + +==================== Cpr signatures ==================== +T18086.$trModule: +T18086.m: b +T18086.panic: + + + +==================== Strictness signatures ==================== +T18086.$trModule: +T18086.m: x +T18086.panic: x + + ===================================== testsuite/tests/stranal/sigs/all.T ===================================== @@ -22,3 +22,4 @@ test('T5075', normal, compile, ['']) test('T17932', normal, compile, ['']) test('T13380c', expect_broken('!3014'), compile, ['']) test('T13380f', normal, compile, ['']) +test('T18086', normal, compile, ['-package ghc']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/52721c43adb8d7eb5a8bba09bea81ef64216d3d4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/52721c43adb8d7eb5a8bba09bea81ef64216d3d4 You're receiving 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 26 10:02:42 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Tue, 26 May 2020 06:02:42 -0400 Subject: [Git][ghc/ghc][wip/T18126] 83 commits: Remove further dead code found by a simple Python script. Message-ID: <5ecce94242559_6e26c5c8abc1589215@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T18126 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. - - - - - 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] - - - - - 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 - - - - - 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 - - - - - 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. - - - - - 78c6523c by Ben Gamari at 2020-05-21T12:13:01-04:00 nonmoving: Optimise the write barrier - - - - - 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). - - - - - 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 - - - - - b7a6b2f4 by Gleb Popov at 2020-05-21T12:15:26-04:00 gitlab-ci: Set locale to C.UTF-8. - - - - - 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. - - - - - 0004ccb8 by Tuan Le at 2020-05-21T12:16:46-04:00 llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 - - - - - 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 - - - - - 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 - - - - - 2b363ebb by Richard Eisenberg at 2020-05-21T12:18:45-04:00 MR template should ask for key part - - - - - a95bbd0b by Sebastian Graf at 2020-05-21T12:19:37-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. - - - - - d3d055b8 by Galen Huntington at 2020-05-21T12:20:18-04:00 Clarify pitfalls of NegativeLiterals; see #18022. - - - - - 1b508a9e by Alexey Kuleshevich at 2020-05-21T12:21:02-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" - - - - - 4ca0c8a1 by Andreas Klebinger at 2020-05-21T12:21: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. - - - - - a1275081 by Krzysztof Gogolewski at 2020-05-21T12:22:35-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 - - - - - 8a816e5f by Krzysztof Gogolewski at 2020-05-21T12:23:55-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. - - - - - 566cc73f by Sylvain Henry at 2020-05-21T12:24:45-04:00 Move isDynLinkName into GHC.Types.Name It doesn't belong into GHC.Unit.State - - - - - 1d118923 by Simon Peyton Jones at 2020-05-22T19:54:47-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 Updates Cabal submodule. - - - - - fcb157d7 by Simon Peyton Jones at 2020-05-23T22:33:20+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 - - - - - 343bff5c by Simon Peyton Jones at 2020-05-23T22:39:20+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. - - - - - 7683714b by Simon Peyton Jones at 2020-05-23T22:39:21+01:00 Wibbles - - - - - 61a30705 by Simon Peyton Jones at 2020-05-26T10:58:07+01:00 More wibbles - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/merge_request_templates/merge-request.md - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/PPC/Cond.hs - compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.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/CmmToAsm/SPARC/Cond.hs - compiler/GHC/CmmToAsm/X86/Cond.hs - compiler/GHC/CmmToC.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/81ef202e7467b9ebdd52adde7af7c3dd390b77c5...61a30705fab7f1c013f1b3b28aa1a94b36c9366b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/81ef202e7467b9ebdd52adde7af7c3dd390b77c5...61a30705fab7f1c013f1b3b28aa1a94b36c9366b You're receiving 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 26 10:11:56 2020 From: gitlab at gitlab.haskell.org (Peter Trommler) Date: Tue, 26 May 2020 06:11:56 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18237 Message-ID: <5ecceb6c85884_6e263f9f01f3c48015939bb@gitlab.haskell.org.mail> Peter Trommler pushed new branch wip/T18237 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18237 You're receiving 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 26 10:49:15 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Tue, 26 May 2020 06:49:15 -0400 Subject: [Git][ghc/ghc][wip/T18235] 10 commits: Revert "Specify kind variables for inferred kinds in base." Message-ID: <5eccf42b81f2_6e26eb9d3f01608758@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T18235 at Glasgow Haskell Compiler / GHC Commits: 013d7120 by Ben Gamari at 2020-05-25T09:48:17-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. - - - - - 4c4312ed by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Drop redundant ad-hoc boot module check To determine whether the module is a boot module Coverage.addTicksToBinds was checking for a `boot` suffix in the module source filename. This is quite ad-hoc and shouldn't be necessary; the callsite in `deSugar` already checks that the module isn't a boot module. - - - - - 1abf3c84 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make tickBoxCount strict This could otherwise easily cause a leak of (+) thunks. - - - - - b2813750 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make ccIndices strict This just seems like a good idea. - - - - - 02e278eb by Ben Gamari at 2020-05-25T09:48:53-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. - - - - - b8c014ce by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Factor out addMixEntry - - - - - 53814a64 by Zubin Duggal at 2020-05-26T03:03:24-04:00 Add info about typeclass evidence to .hie files See `testsuite/tests/hiefile/should_run/HieQueries.hs` and `testsuite/tests/hiefile/should_run/HieQueries.stdout` for an example of this We add two new fields, `EvidenceVarBind` and `EvidenceVarUse` to the `ContextInfo` associated with an Identifier. These are associated with the appropriate identifiers for the evidence variables collected when we come across `HsWrappers`, `TcEvBinds` and `IPBinds` while traversing the AST. Instance dictionary and superclass selector dictionaries from `tcg_insts` and classes defined in `tcg_tcs` are also recorded in the AST as originating from their definition span This allows us to save a complete picture of the evidence constructed by the constraint solver, and will let us report this to the user, enabling features like going to the instance definition from the invocation of a class method(or any other method taking a constraint) and finding all usages of a particular instance. Additionally, - Mark NodeInfo with an origin so we can differentiate between bindings origininating in the source vs those in ghc - Along with typeclass evidence info, also include information on Implicit Parameters - Add a few utility functions to HieUtils in order to query the new info Updates haddock submodule - - - - - 6604906c by Sebastian Graf at 2020-05-26T03:04:04-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. - - - - - cf772f19 by Sylvain Henry at 2020-05-26T03:04:45-04:00 Enhance Note [About units] for Backpack - - - - - 262b6558 by Ryan Scott at 2020-05-26T06:47:39-04:00 Use HsForAllTelescope to avoid inferred, visible foralls Currently, `HsForAllTy` permits the combination of `ForallVis` and `Inferred`, but you can't actually typecheck code that uses it (e.g., `forall {a} ->`). This patch refactors `HsForAllTy` to use a new `HsForAllTelescope` data type that makes a type-level distinction between visible and invisible `forall`s such that visible `forall`s do not track `Specificity`. That part of the patch is actually quite small; the rest is simply changing consumers of `HsType` to accommodate this new type. Fixes #18235. - - - - - 30 changed files: - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Extension.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Coverage.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Debug.hs - compiler/GHC/Iface/Ext/Types.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Tc/Deriv.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Tc/Utils/TcType.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c941725dab4fb5146ceb81dd898ee5f8baee4b9b...262b6558c0f7f7769ba0db2e6f81a21749edb54c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c941725dab4fb5146ceb81dd898ee5f8baee4b9b...262b6558c0f7f7769ba0db2e6f81a21749edb54c You're receiving 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 26 10:53:08 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Tue, 26 May 2020 06:53:08 -0400 Subject: [Git][ghc/ghc][wip/T18191] 4 commits: Add info about typeclass evidence to .hie files Message-ID: <5eccf514aa1e1_6e26c5c8abc1611022@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T18191 at Glasgow Haskell Compiler / GHC Commits: 53814a64 by Zubin Duggal at 2020-05-26T03:03:24-04:00 Add info about typeclass evidence to .hie files See `testsuite/tests/hiefile/should_run/HieQueries.hs` and `testsuite/tests/hiefile/should_run/HieQueries.stdout` for an example of this We add two new fields, `EvidenceVarBind` and `EvidenceVarUse` to the `ContextInfo` associated with an Identifier. These are associated with the appropriate identifiers for the evidence variables collected when we come across `HsWrappers`, `TcEvBinds` and `IPBinds` while traversing the AST. Instance dictionary and superclass selector dictionaries from `tcg_insts` and classes defined in `tcg_tcs` are also recorded in the AST as originating from their definition span This allows us to save a complete picture of the evidence constructed by the constraint solver, and will let us report this to the user, enabling features like going to the instance definition from the invocation of a class method(or any other method taking a constraint) and finding all usages of a particular instance. Additionally, - Mark NodeInfo with an origin so we can differentiate between bindings origininating in the source vs those in ghc - Along with typeclass evidence info, also include information on Implicit Parameters - Add a few utility functions to HieUtils in order to query the new info Updates haddock submodule - - - - - 6604906c by Sebastian Graf at 2020-05-26T03:04:04-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. - - - - - cf772f19 by Sylvain Henry at 2020-05-26T03:04:45-04:00 Enhance Note [About units] for Backpack - - - - - ec02f82f by Ryan Scott at 2020-05-26T06:50:27-04:00 Make GADT constructors adhere to the forall-or-nothing rule properly Issue #18191 revealed that the types of GADT constructors don't quite adhere to the `forall`-or-nothing rule. This patch serves to clean up this sad state of affairs somewhat. The main change is not in the code itself, but in the documentation, as this patch introduces two sections to the GHC User's Guide: * A "Formal syntax for GADTs" section that presents a BNF-style grammar for what is and isn't allowed in GADT constructor types. This mostly exists to codify GHC's existing behavior, but it also imposes a new restriction that addresses #18191: the outermost `forall` and/or context in a GADT constructor is not allowed to be surrounded by parentheses. Doing so would make these `forall`s/contexts nested, and GADTs do not support nested `forall`s/contexts at present. * A "`forall`-or-nothing rule" section that describes exactly what the `forall`-or-nothing rule is all about. Surprisingly, there was no mention of this anywhere in the User's Guide up until now! To adhere the new specification in the "Formal syntax for GADTs" section of the User's Guide, the following code changes were made: * `GHC.Parser.PostProcess.mkGadtDecl` no longer strips away parentheses from the outermost `forall` and context. Instead, these parentheses are preserved so that the renamer can check for nested `forall`s/contexts later. See `Note [No nested foralls or contexts in GADT constructors]` in `GHC.Parser.PostProcess` for more details. One nice side effect of this change is that we can get rid of the explicit `AddAnn` tracking in `mkGadtDecl`, as we no longer need to remember the `AddAnn`s for stripped-away parentheses. * `GHC.Renamer.Module.rnConDecl` now checks for nested `forall`s/contexts, rather than checking for this in the typechcker (in `GHC.Tc.TyCl.badDataConTyCon`). For the most part, this code was ported directly from `badDataConTyCon`, but designed to work over `HsType`s instead of `Type`s. One nice side effect of this change is that we are able to give a more accurate error message for GADT constructors that use visible dependent quantification (e.g., `MkFoo :: forall a -> a -> Foo a`), which improves the stderr in the `T16326_Fail6` test case. Fixes #18191. - - - - - 30 changed files: - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Debug.hs - compiler/GHC/Iface/Ext/Types.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Unit.hs - docs/users_guide/8.12.1-notes.rst - docs/users_guide/exts/explicit_forall.rst - docs/users_guide/exts/gadt_syntax.rst - docs/users_guide/using-optimisation.rst - testsuite/tests/dependent/should_fail/T16326_Fail6.stderr - testsuite/tests/gadt/T12087.stderr - testsuite/tests/gadt/T14320.hs - + testsuite/tests/gadt/T14320.stderr - testsuite/tests/gadt/T16427.stderr - + testsuite/tests/gadt/T18191.hs - + testsuite/tests/gadt/T18191.stderr - testsuite/tests/gadt/all.T - testsuite/tests/ghc-api/annotations/T10399.stdout - testsuite/tests/ghc-api/annotations/Test10399.hs - testsuite/tests/hiefile/should_compile/Scopes.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5d753721f9642a67d90c0a5e273b788a14163054...ec02f82f1ec46f57bbb5887cbec62c4fc8671f9f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5d753721f9642a67d90c0a5e273b788a14163054...ec02f82f1ec46f57bbb5887cbec62c4fc8671f9f You're receiving 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 26 10:56:06 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Tue, 26 May 2020 06:56:06 -0400 Subject: [Git][ghc/ghc][wip/T18235] Use HsForAllTelescope to avoid inferred, visible foralls Message-ID: <5eccf5c67f8e4_6e263f9f00579e08161209b@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T18235 at Glasgow Haskell Compiler / GHC Commits: 805c62e0 by Ryan Scott at 2020-05-26T06:55:43-04:00 Use HsForAllTelescope to avoid inferred, visible foralls Currently, `HsForAllTy` permits the combination of `ForallVis` and `Inferred`, but you can't actually typecheck code that uses it (e.g., `forall {a} ->`). This patch refactors `HsForAllTy` to use a new `HsForAllTelescope` data type that makes a type-level distinction between visible and invisible `forall`s such that visible `forall`s do not track `Specificity`. That part of the patch is actually quite small; the rest is simply changing consumers of `HsType` to accommodate this new type. Fixes #18235. Bumps the `haddock` submodule. - - - - - 30 changed files: - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Extension.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Tc/Deriv.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Types/Var.hs - testsuite/tests/ghc-api/annotations/T10278.stdout - testsuite/tests/ghc-api/annotations/T10399.stdout - testsuite/tests/ghc-api/annotations/T11018.stdout - testsuite/tests/ghc-api/annotations/T16230.stdout - testsuite/tests/ghc-api/annotations/T17519.stdout - testsuite/tests/parser/should_compile/DumpRenamedAst.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/805c62e04613f51924deb979bce565b85e0d1665 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/805c62e04613f51924deb979bce565b85e0d1665 You're receiving 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 26 11:14:20 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Tue, 26 May 2020 07:14:20 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/andreask/callstack-prelude Message-ID: <5eccfa0cd7a52_6e26115afe7c16142c2@gitlab.haskell.org.mail> Andreas Klebinger pushed new branch wip/andreask/callstack-prelude at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/andreask/callstack-prelude You're receiving 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 26 11:16:56 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Tue, 26 May 2020 07:16:56 -0400 Subject: [Git][ghc/ghc][wip/andreask/callstack-prelude] Make use of DebugCallStack for plain panic. Message-ID: <5eccfaa85ce92_6e26eb9d3f0161441a@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/callstack-prelude at Glasgow Haskell Compiler / GHC Commits: f9ceab26 by Andreas Klebinger at 2020-05-26T13:16:01+02:00 Make use of DebugCallStack for plain panic. Also move HasDebugCallStack into GHC.Prelude. This allows it to be used without indirectly depending on the Outputable module. - - - - - 3 changed files: - compiler/GHC/Prelude.hs - compiler/GHC/Utils/Misc.hs - compiler/GHC/Utils/Panic/Plain.hs Changes: ===================================== compiler/GHC/Prelude.hs ===================================== @@ -1,5 +1,6 @@ {-# LANGUAGE CPP #-} - +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE ConstraintKinds #-} -- | Custom GHC "Prelude" -- -- This module serves as a replacement for the "Prelude" module @@ -10,7 +11,7 @@ -- * Is compiled with -XNoImplicitPrelude -- * Explicitly imports GHC.Prelude -module GHC.Prelude (module X) where +module GHC.Prelude (module X, HasDebugCallStack) where -- We export the 'Semigroup' class but w/o the (<>) operator to avoid -- clashing with the (Outputable.<>) operator which is heavily used @@ -19,6 +20,19 @@ module GHC.Prelude (module X) where import Prelude as X hiding ((<>)) import Data.Foldable as X (foldl') +import GHC.Exts (Constraint) +#if defined(DEBUG) +import GHC.Stack (HasCallStack) +#endif +-- We define + +-- | A call stack constraint, but only when 'isDebugOn'. +#if defined(DEBUG) +type HasDebugCallStack = HasCallStack +#else +type HasDebugCallStack = (() :: Constraint) +#endif + {- Note [Why do we import Prelude here?] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Utils/Misc.hs ===================================== @@ -1440,13 +1440,6 @@ mulHi a b = fromIntegral (r `shiftR` 32) where r :: Int64 r = fromIntegral a * fromIntegral b --- | A call stack constraint, but only when 'isDebugOn'. -#if defined(DEBUG) -type HasDebugCallStack = HasCallStack -#else -type HasDebugCallStack = (() :: Constraint) -#endif - data OverridingBool = Auto | Always ===================================== compiler/GHC/Utils/Panic/Plain.hs ===================================== @@ -111,15 +111,15 @@ throwPlainGhcException :: PlainGhcException -> a throwPlainGhcException = Exception.throw -- | Panics and asserts. -panic, sorry, pgmError :: String -> a +panic, sorry, pgmError :: CallStack => String -> a panic x = unsafeDupablePerformIO $ do stack <- ccsToStrings =<< getCurrentCCS x if null stack - then throwPlainGhcException (PlainPanic x) - else throwPlainGhcException (PlainPanic (x ++ '\n' : renderStack stack)) + then throwPlainGhcException (PlainPanic ((prettyCallStack callStack) ++ "\n" ++ x)) + else throwPlainGhcException (PlainPanic ((prettyCallStack callStack) ++ "\n" ++ x ++ '\n' : renderStack stack)) -sorry x = throwPlainGhcException (PlainSorry x) -pgmError x = throwPlainGhcException (PlainProgramError x) +sorry x = throwPlainGhcException (PlainSorry $ (prettyCallStack callStack) ++ "\n" ++ x) +pgmError x = throwPlainGhcException (PlainProgramError $ (prettyCallStack callStack) ++ "\n" ++x) cmdLineError :: String -> a cmdLineError = unsafeDupablePerformIO . cmdLineErrorIO @@ -132,7 +132,7 @@ cmdLineErrorIO x = do else throwPlainGhcException (PlainCmdLineError (x ++ '\n' : renderStack stack)) -- | Throw a failed assertion exception for a given filename and line number. -assertPanic :: String -> Int -> a +assertPanic :: CallStack => String -> Int -> a assertPanic file line = Exception.throw (Exception.AssertionFailed - ("ASSERT failed! file " ++ file ++ ", line " ++ show line)) + ((prettyCallStack callStack) ++ "\nASSERT failed! file " ++ file ++ ", line " ++ show line)) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f9ceab26b4c3fc754ed7ea3209de31a050eeaf3c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f9ceab26b4c3fc754ed7ea3209de31a050eeaf3c You're receiving 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 26 11:39:31 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Tue, 26 May 2020 07:39:31 -0400 Subject: [Git][ghc/ghc][wip/andreask/callstack-prelude] Make use of DebugCallStack for plain panic. Message-ID: <5eccfff3a5347_6e263f9ee352230016192e0@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/callstack-prelude at Glasgow Haskell Compiler / GHC Commits: b374b650 by Andreas Klebinger at 2020-05-26T13:39:22+02:00 Make use of DebugCallStack for plain panic. Also move HasDebugCallStack into GHC.Prelude. This allows it to be used without indirectly depending on the Outputable module. - - - - - 3 changed files: - compiler/GHC/Prelude.hs - compiler/GHC/Utils/Misc.hs - compiler/GHC/Utils/Panic/Plain.hs Changes: ===================================== compiler/GHC/Prelude.hs ===================================== @@ -1,5 +1,6 @@ {-# LANGUAGE CPP #-} - +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE ConstraintKinds #-} -- | Custom GHC "Prelude" -- -- This module serves as a replacement for the "Prelude" module @@ -10,7 +11,7 @@ -- * Is compiled with -XNoImplicitPrelude -- * Explicitly imports GHC.Prelude -module GHC.Prelude (module X) where +module GHC.Prelude (module X, HasDebugCallStack) where -- We export the 'Semigroup' class but w/o the (<>) operator to avoid -- clashing with the (Outputable.<>) operator which is heavily used @@ -19,6 +20,19 @@ module GHC.Prelude (module X) where import Prelude as X hiding ((<>)) import Data.Foldable as X (foldl') +import GHC.Exts (Constraint) +#if defined(DEBUG) +import GHC.Stack (HasCallStack) +#endif +-- We define + +-- | A call stack constraint, but only when 'isDebugOn'. +#if defined(DEBUG) +type HasDebugCallStack = HasCallStack +#else +type HasDebugCallStack = (() :: Constraint) +#endif + {- Note [Why do we import Prelude here?] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Utils/Misc.hs ===================================== @@ -1440,13 +1440,6 @@ mulHi a b = fromIntegral (r `shiftR` 32) where r :: Int64 r = fromIntegral a * fromIntegral b --- | A call stack constraint, but only when 'isDebugOn'. -#if defined(DEBUG) -type HasDebugCallStack = HasCallStack -#else -type HasDebugCallStack = (() :: Constraint) -#endif - data OverridingBool = Auto | Always ===================================== compiler/GHC/Utils/Panic/Plain.hs ===================================== @@ -111,15 +111,15 @@ throwPlainGhcException :: PlainGhcException -> a throwPlainGhcException = Exception.throw -- | Panics and asserts. -panic, sorry, pgmError :: String -> a +panic, sorry, pgmError :: HasCallStack => String -> a panic x = unsafeDupablePerformIO $ do stack <- ccsToStrings =<< getCurrentCCS x if null stack - then throwPlainGhcException (PlainPanic x) - else throwPlainGhcException (PlainPanic (x ++ '\n' : renderStack stack)) + then throwPlainGhcException (PlainPanic ((prettyCallStack callStack) ++ "\n" ++ x)) + else throwPlainGhcException (PlainPanic ((prettyCallStack callStack) ++ "\n" ++ x ++ '\n' : renderStack stack)) -sorry x = throwPlainGhcException (PlainSorry x) -pgmError x = throwPlainGhcException (PlainProgramError x) +sorry x = throwPlainGhcException (PlainSorry $ (prettyCallStack callStack) ++ "\n" ++ x) +pgmError x = throwPlainGhcException (PlainProgramError $ (prettyCallStack callStack) ++ "\n" ++x) cmdLineError :: String -> a cmdLineError = unsafeDupablePerformIO . cmdLineErrorIO @@ -132,7 +132,7 @@ cmdLineErrorIO x = do else throwPlainGhcException (PlainCmdLineError (x ++ '\n' : renderStack stack)) -- | Throw a failed assertion exception for a given filename and line number. -assertPanic :: String -> Int -> a +assertPanic :: HasCallStack => String -> Int -> a assertPanic file line = Exception.throw (Exception.AssertionFailed - ("ASSERT failed! file " ++ file ++ ", line " ++ show line)) + ((prettyCallStack callStack) ++ "\nASSERT failed! file " ++ file ++ ", line " ++ show line)) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b374b6500570f82cfe345451c2d2630d8917bed9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b374b6500570f82cfe345451c2d2630d8917bed9 You're receiving 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 26 11:41:50 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Tue, 26 May 2020 07:41:50 -0400 Subject: [Git][ghc/ghc][wip/nested-cpr-2019] 38 commits: Revert "Specify kind variables for inferred kinds in base." Message-ID: <5ecd007e14f3b_6e263f9ed71435d81620711@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/nested-cpr-2019 at Glasgow Haskell Compiler / GHC Commits: 013d7120 by Ben Gamari at 2020-05-25T09:48:17-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. - - - - - 4c4312ed by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Drop redundant ad-hoc boot module check To determine whether the module is a boot module Coverage.addTicksToBinds was checking for a `boot` suffix in the module source filename. This is quite ad-hoc and shouldn't be necessary; the callsite in `deSugar` already checks that the module isn't a boot module. - - - - - 1abf3c84 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make tickBoxCount strict This could otherwise easily cause a leak of (+) thunks. - - - - - b2813750 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make ccIndices strict This just seems like a good idea. - - - - - 02e278eb by Ben Gamari at 2020-05-25T09:48:53-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. - - - - - b8c014ce by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Factor out addMixEntry - - - - - 53814a64 by Zubin Duggal at 2020-05-26T03:03:24-04:00 Add info about typeclass evidence to .hie files See `testsuite/tests/hiefile/should_run/HieQueries.hs` and `testsuite/tests/hiefile/should_run/HieQueries.stdout` for an example of this We add two new fields, `EvidenceVarBind` and `EvidenceVarUse` to the `ContextInfo` associated with an Identifier. These are associated with the appropriate identifiers for the evidence variables collected when we come across `HsWrappers`, `TcEvBinds` and `IPBinds` while traversing the AST. Instance dictionary and superclass selector dictionaries from `tcg_insts` and classes defined in `tcg_tcs` are also recorded in the AST as originating from their definition span This allows us to save a complete picture of the evidence constructed by the constraint solver, and will let us report this to the user, enabling features like going to the instance definition from the invocation of a class method(or any other method taking a constraint) and finding all usages of a particular instance. Additionally, - Mark NodeInfo with an origin so we can differentiate between bindings origininating in the source vs those in ghc - Along with typeclass evidence info, also include information on Implicit Parameters - Add a few utility functions to HieUtils in order to query the new info Updates haddock submodule - - - - - 6604906c by Sebastian Graf at 2020-05-26T03:04:04-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. - - - - - cf772f19 by Sylvain Henry at 2020-05-26T03:04:45-04:00 Enhance Note [About units] for Backpack - - - - - 0baa1b68 by Sebastian Graf at 2020-05-26T13:41:42+02:00 Nested CPR - - - - - b1d3e5bf by Sebastian Graf at 2020-05-26T13:41:42+02:00 Move tests from stranal to cpranal - - - - - 00a5eaff by Sebastian Graf at 2020-05-26T13:41:42+02:00 Accept FacState - - - - - 8999468c by Sebastian Graf at 2020-05-26T13:41:42+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. - - - - - b796c131 by Sebastian Graf at 2020-05-26T13:41:42+02:00 Consider unboxing effects of WW better and get rid of hack - - - - - 3dad9697 by Sebastian Graf at 2020-05-26T13:41:42+02:00 stuff - - - - - 5fedeafa by Sebastian Graf at 2020-05-26T13:41:42+02:00 Debug output - - - - - ed8a958a by Sebastian Graf at 2020-05-26T13:41:42+02:00 A slew of testsuite changes - - - - - f4cbdbb4 by Sebastian Graf at 2020-05-26T13:41:42+02:00 Fix T1600 - - - - - cc7a7d00 by Sebastian Graf at 2020-05-26T13:41:42+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. - - - - - 2ed3162b by Sebastian Graf at 2020-05-26T13:41:42+02:00 Fix primop termination - - - - - ff024fbd by Sebastian Graf at 2020-05-26T13:41:42+02:00 Test for DataCon wrapper CPR - - - - - ee6d3cf8 by Sebastian Graf at 2020-05-26T13:41:42+02:00 Fix CPR of bottoming functions/primops - - - - - c7048a24 by Sebastian Graf at 2020-05-26T13:41:42+02:00 Fix DataConWrapperCpr and accept other test outputs - - - - - 0372f4ce by Sebastian Graf at 2020-05-26T13:41:42+02:00 Accept two more changed test outputs - - - - - beaf2d7e by Sebastian Graf at 2020-05-26T13:41:42+02:00 Update CaseBinderCPR with a new function - - - - - c6e512af by Sebastian Graf at 2020-05-26T13:41:42+02:00 Don't give the case binder the CPR property - - - - - fcf53cc6 by Sebastian Graf at 2020-05-26T13:41:42+02:00 Prune CPR sigs to constant depth on all bindings - - - - - 943183a6 by Sebastian Graf at 2020-05-26T13:41:42+02:00 Use variable length coding for ConTags - - - - - 2df33d63 by Sebastian Graf at 2020-05-26T13:41:42+02:00 Accept testuite output - - - - - 1dd01bfe by Sebastian Graf at 2020-05-26T13:41:42+02:00 Don't attach CPR sigs to expandable bindings; transform their unfoldings instead - - - - - 47bb131d by Sebastian Graf at 2020-05-26T13:41:42+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`. - - - - - 6f6ed3bc by Sebastian Graf at 2020-05-26T13:41:42+02:00 A more modular and configurable approach to optimistic case binder CPR - - - - - fe7bf0f3 by Sebastian Graf at 2020-05-26T13:41:42+02:00 Fix T9291 - - - - - 70675708 by Sebastian Graf at 2020-05-26T13:41:42+02:00 Document -fcase-binder-cpr-depth in the user's guide - - - - - 9a320289 by Sebastian Graf at 2020-05-26T13:41:42+02:00 Rebase woes - - - - - acb6be14 by Sebastian Graf at 2020-05-26T13:41:42+02:00 Testsuite changes - - - - - b045dd05 by Sebastian Graf at 2020-05-26T13:41:42+02:00 Refactoring around cprAnalBind - - - - - a324360b by Sebastian Graf at 2020-05-26T13:41:42+02:00 Fix case binder CPR by not looking into unfoldings of case binders - - - - - 25 changed files: - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Opt/Arity.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/WorkWrap.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/Maybe.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/HsToCore/Coverage.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Debug.hs - compiler/GHC/Iface/Ext/Types.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Types/Cpr.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id/Info.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2594ade04814abc16db74367265be92acc82c94a...a324360bdcc55e8825f04425969fd2d4b1c501df -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2594ade04814abc16db74367265be92acc82c94a...a324360bdcc55e8825f04425969fd2d4b1c501df You're receiving 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 26 12:28:56 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Tue, 26 May 2020 08:28:56 -0400 Subject: [Git][ghc/ghc][wip/andreask/xchg_primop] winio: Add Atomic Exchange PrimOp and implement Atomic Ptr exchanges. Message-ID: <5ecd0b885a332_6e263f9f01f3c48016275ae@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/xchg_primop at Glasgow Haskell Compiler / GHC Commits: b81c4a06 by Tamar Christina at 2020-05-26T14:28:44+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. Co-authored-by: Andreas Klebinger <klebinger.andreas at gmx.at> - - - - - 26 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_compile/all.T - + testsuite/tests/codeGen/should_compile/cg009.hs - testsuite/tests/codeGen/should_run/all.T - + testsuite/tests/codeGen/should_run/cgrun080.hs - + testsuite/tests/codeGen/should_run/cgrun080.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,16 @@ genCall (PrimTarget (MO_Cmpxchg _width)) retVar' <- doExprW targetTy $ ExtractV retVar 0 statement $ Store retVar' dstVar +genCall (PrimTarget (MO_Xchg _width)) [dst] [addr, val] = runStmtsDecls $ do + dstV <- getCmmRegW (CmmLocal dst) :: WriterT LlvmAccum LlvmM LlvmVar + addrVar <- exprToVarW addr + valVar <- exprToVarW val + let ptrTy = pLift $ getVarType valVar + ptrExpr = Cast LM_Inttoptr addrVar ptrTy + ptrVar <- doExprW ptrTy ptrExpr + resVar <- doExprW (getVarType valVar) (AtomicRMW LAO_Xchg ptrVar valVar SyncSeqCst) + statement $ Store resVar dstV + genCall (PrimTarget (MO_AtomicWrite _width)) [] [addr, val] = runStmtsDecls $ do addrVar <- exprToVarW addr valVar <- exprToVarW val @@ -856,6 +866,7 @@ cmmPrimOpFunctions mop = do MO_AtomicRMW _ _ -> unsupported MO_AtomicWrite _ -> unsupported MO_Cmpxchg _ -> unsupported + MO_Xchg _ -> unsupported -- | Tail function calls genJump :: CmmExpr -> [GlobalReg] -> LlvmM StmtData @@ -1943,10 +1954,10 @@ toIWord platform = mkIntLit (llvmWord platform) -- | Error functions -panic :: String -> a +panic :: HasCallStack => String -> a panic s = Outputable.panic $ "GHC.CmmToLlvm.CodeGen." ++ s -pprPanic :: String -> SDoc -> a +pprPanic :: HasCallStack => String -> SDoc -> a pprPanic s d = Outputable.pprPanic ("GHC.CmmToLlvm.CodeGen." ++ s) d ===================================== 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(StgWord x, StgWord val); +StgWord hs_xchg16(StgWord x, StgWord val); +StgWord hs_xchg32(StgWord x, StgWord val); +StgWord hs_xchg64(StgWord 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(StgWord x, StgWord val); +StgWord +hs_xchg8(StgWord x, StgWord val) +{ + return (StgWord) __atomic_exchange_n((StgWord8 *) x, (StgWord8) val, __ATOMIC_SEQ_CST); +} + +extern StgWord hs_xchg16(StgWord x, StgWord val); +StgWord +hs_xchg16(StgWord x, StgWord val) +{ + return (StgWord) __atomic_exchange_n((StgWord16 *)x, (StgWord16) val, __ATOMIC_SEQ_CST); +} + +extern StgWord hs_xchg32(StgWord x, StgWord val); +StgWord +hs_xchg32(StgWord 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(StgWord x, StgWord val); +StgWord +hs_xchg64(StgWord 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_compile/all.T ===================================== @@ -6,6 +6,7 @@ test('cg005', only_ways(['optasm']), compile, ['']) test('cg006', normal, compile, ['']) test('cg007', normal, compile, ['']) test('cg008', normal, compile, ['']) +test('cg009', normal, compile, ['']) test('T1916', normal, compile, ['']) test('T2388', normal, compile, ['']) ===================================== testsuite/tests/codeGen/should_compile/cg009.hs ===================================== @@ -0,0 +1,11 @@ +{-# LANGUAGE CPP, MagicHash, BlockArguments, UnboxedTuples #-} + +-- Tests compilation for interlockedExchange primop. + +module M where + +import GHC.Exts (interlockedExchangeInt#, Int#, Addr#, State# ) + +swap :: Addr# -> Int# -> State# s -> (# #) +swap ptr val s = case (interlockedExchangeInt# ptr val s) of + (# s2, old_val #) -> (# #) ===================================== testsuite/tests/codeGen/should_run/all.T ===================================== @@ -90,6 +90,7 @@ test('cgrun076', normal, compile_and_run, ['']) test('cgrun077', [when(have_cpu_feature('bmi2'), extra_hc_opts('-mbmi2'))], compile_and_run, ['']) test('cgrun078', omit_ways(['ghci']), compile_and_run, ['']) test('cgrun079', normal, compile_and_run, ['']) +test('cgrun080', normal, compile_and_run, ['']) test('T1852', normal, compile_and_run, ['']) test('T1861', extra_run_opts('0'), compile_and_run, ['']) ===================================== testsuite/tests/codeGen/should_run/cgrun080.hs ===================================== @@ -0,0 +1,51 @@ +{-# LANGUAGE CPP, MagicHash, BlockArguments, UnboxedTuples #-} + +-- Test 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/cgrun080.stdout ===================================== @@ -0,0 +1 @@ +[1,2,3] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b81c4a06d5773fb206f74f662390f06c4ad5e12e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b81c4a06d5773fb206f74f662390f06c4ad5e12e You're receiving 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 26 12:31:06 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Tue, 26 May 2020 08:31:06 -0400 Subject: [Git][ghc/ghc][wip/andreask/callstack-prelude] Make use of DebugCallStack for plain panic. Message-ID: <5ecd0c0a9a3fd_6e263f9f00579e081629662@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/callstack-prelude at Glasgow Haskell Compiler / GHC Commits: 85f6487f by Andreas Klebinger at 2020-05-26T14:30:57+02:00 Make use of DebugCallStack for plain panic. Also move HasDebugCallStack into GHC.Prelude. This allows it to be used without indirectly depending on the Outputable module. - - - - - 4 changed files: - compiler/GHC/Prelude.hs - compiler/GHC/Tc/Utils/Env.hs - compiler/GHC/Utils/Misc.hs - compiler/GHC/Utils/Panic/Plain.hs Changes: ===================================== compiler/GHC/Prelude.hs ===================================== @@ -1,5 +1,6 @@ {-# LANGUAGE CPP #-} - +{-# LANGUAGE KindSignatures #-} +{-# LANGUAGE ConstraintKinds #-} -- | Custom GHC "Prelude" -- -- This module serves as a replacement for the "Prelude" module @@ -10,7 +11,7 @@ -- * Is compiled with -XNoImplicitPrelude -- * Explicitly imports GHC.Prelude -module GHC.Prelude (module X) where +module GHC.Prelude (module X, HasDebugCallStack) where -- We export the 'Semigroup' class but w/o the (<>) operator to avoid -- clashing with the (Outputable.<>) operator which is heavily used @@ -19,6 +20,19 @@ module GHC.Prelude (module X) where import Prelude as X hiding ((<>)) import Data.Foldable as X (foldl') +import GHC.Exts (Constraint) +#if defined(DEBUG) +import GHC.Stack (HasCallStack) +#endif +-- We define + +-- | A call stack constraint, but only when 'isDebugOn'. +#if defined(DEBUG) +type HasDebugCallStack = HasCallStack +#else +type HasDebugCallStack = (() :: Constraint) +#endif + {- Note [Why do we import Prelude here?] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Tc/Utils/Env.hs ===================================== @@ -109,7 +109,6 @@ import GHC.Data.List.SetOps import GHC.Utils.Error import GHC.Data.Maybe( MaybeErr(..), orElse ) import qualified GHC.LanguageExtensions as LangExt -import GHC.Utils.Misc ( HasDebugCallStack ) import Data.IORef import Data.List (intercalate) ===================================== compiler/GHC/Utils/Misc.hs ===================================== @@ -1440,13 +1440,6 @@ mulHi a b = fromIntegral (r `shiftR` 32) where r :: Int64 r = fromIntegral a * fromIntegral b --- | A call stack constraint, but only when 'isDebugOn'. -#if defined(DEBUG) -type HasDebugCallStack = HasCallStack -#else -type HasDebugCallStack = (() :: Constraint) -#endif - data OverridingBool = Auto | Always ===================================== compiler/GHC/Utils/Panic/Plain.hs ===================================== @@ -111,15 +111,15 @@ throwPlainGhcException :: PlainGhcException -> a throwPlainGhcException = Exception.throw -- | Panics and asserts. -panic, sorry, pgmError :: String -> a +panic, sorry, pgmError :: HasCallStack => String -> a panic x = unsafeDupablePerformIO $ do stack <- ccsToStrings =<< getCurrentCCS x if null stack - then throwPlainGhcException (PlainPanic x) - else throwPlainGhcException (PlainPanic (x ++ '\n' : renderStack stack)) + then throwPlainGhcException (PlainPanic ((prettyCallStack callStack) ++ "\n" ++ x)) + else throwPlainGhcException (PlainPanic ((prettyCallStack callStack) ++ "\n" ++ x ++ '\n' : renderStack stack)) -sorry x = throwPlainGhcException (PlainSorry x) -pgmError x = throwPlainGhcException (PlainProgramError x) +sorry x = throwPlainGhcException (PlainSorry $ (prettyCallStack callStack) ++ "\n" ++ x) +pgmError x = throwPlainGhcException (PlainProgramError $ (prettyCallStack callStack) ++ "\n" ++x) cmdLineError :: String -> a cmdLineError = unsafeDupablePerformIO . cmdLineErrorIO @@ -132,7 +132,7 @@ cmdLineErrorIO x = do else throwPlainGhcException (PlainCmdLineError (x ++ '\n' : renderStack stack)) -- | Throw a failed assertion exception for a given filename and line number. -assertPanic :: String -> Int -> a +assertPanic :: HasCallStack => String -> Int -> a assertPanic file line = Exception.throw (Exception.AssertionFailed - ("ASSERT failed! file " ++ file ++ ", line " ++ show line)) + ((prettyCallStack callStack) ++ "\nASSERT failed! file " ++ file ++ ", line " ++ show line)) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/85f6487ff04e857acd333d176f33e9c26e0256cd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/85f6487ff04e857acd333d176f33e9c26e0256cd You're receiving 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 26 12:48:29 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Tue, 26 May 2020 08:48:29 -0400 Subject: [Git][ghc/ghc][wip/andreask/elem_rule_fix] 90 commits: rts/CNF: Fix fixup comparison function Message-ID: <5ecd101d7354f_6e26115afe7c16344bb@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/elem_rule_fix 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. - - - - - 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] - - - - - 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 - - - - - 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 - - - - - 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. - - - - - 78c6523c by Ben Gamari at 2020-05-21T12:13:01-04:00 nonmoving: Optimise the write barrier - - - - - 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). - - - - - 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 - - - - - b7a6b2f4 by Gleb Popov at 2020-05-21T12:15:26-04:00 gitlab-ci: Set locale to C.UTF-8. - - - - - 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. - - - - - 0004ccb8 by Tuan Le at 2020-05-21T12:16:46-04:00 llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 - - - - - 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 - - - - - 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 - - - - - 2b363ebb by Richard Eisenberg at 2020-05-21T12:18:45-04:00 MR template should ask for key part - - - - - a95bbd0b by Sebastian Graf at 2020-05-21T12:19:37-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. - - - - - d3d055b8 by Galen Huntington at 2020-05-21T12:20:18-04:00 Clarify pitfalls of NegativeLiterals; see #18022. - - - - - 1b508a9e by Alexey Kuleshevich at 2020-05-21T12:21:02-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" - - - - - 4ca0c8a1 by Andreas Klebinger at 2020-05-21T12:21: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. - - - - - a1275081 by Krzysztof Gogolewski at 2020-05-21T12:22:35-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 - - - - - 8a816e5f by Krzysztof Gogolewski at 2020-05-21T12:23:55-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. - - - - - 566cc73f by Sylvain Henry at 2020-05-21T12:24:45-04:00 Move isDynLinkName into GHC.Types.Name It doesn't belong into GHC.Unit.State - - - - - d830bbc9 by Adam Sandberg Ericsson at 2020-05-23T13:36:20-04:00 docs: fix formatting and add some links [skip ci] - - - - - 49301ad6 by Andrew Martin at 2020-05-23T13:37:01-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. - - - - - dcd6bdcc by Ben Gamari at 2020-05-23T13:37:48-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. - - - - - 82cb8913 by John Ericson at 2020-05-23T13:38:32-04:00 Fix #18145 and also avoid needless work with implicit vars - `forAllOrNothing` now is monadic, so we can trace whether we bind an explicit `forall` or not. - #18145 arose because the free vars calculation was needlessly complex. It is now greatly simplified. - Replaced some other implicit var code with `filterFreeVarsToBind`. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - a60dc835 by Ben Gamari at 2020-05-23T13:39:12-04:00 Bump process submodule Fixes #17926. - - - - - 856adf54 by Ben Gamari at 2020-05-23T13:40:21-04:00 users-guide: Clarify meaning of -haddock flag Fixes #18206. - - - - - 7ae57afd by Ben Gamari at 2020-05-23T13:41:03-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 - - - - - 63d30e60 by jneira at 2020-05-24T01:54:42-04:00 Add hie-bios script for windows systems It is a direct translation of the sh script - - - - - 59182b88 by jneira at 2020-05-24T01:54:42-04:00 Honour previous values for CABAL and CABFLAGS The immediate goal is let the hie-bios.bat script set CABFLAGS with `-v0` and remove all cabal output except the compiler arguments - - - - - 932dc54e by jneira at 2020-05-24T01:54:42-04:00 Add specific configuration for windows in hie.yaml - - - - - e0eda070 by jneira at 2020-05-24T01:54:42-04:00 Remove not needed hie-bios output - - - - - a0ea59d6 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Move Config module into GHC.Settings - - - - - 37430251 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Core.Arity into GHC.Core.Opt.Arity - - - - - a426abb9 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Hs.Types into GHC.Hs.Type See discussion in https://gitlab.haskell.org/ghc/ghc/issues/13009#note_268610 - - - - - 1c91a7a0 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Bump haddock submodule - - - - - 66bd24d1 by Ryan Scott at 2020-05-24T01:56:03-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. - - - - - 01c43634 by Matthew Pickering at 2020-05-24T01:56:42-04:00 Remove unused hs-boot file - - - - - 7a07aa71 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix cross-compiler build (#16051) - - - - - 15ccca16 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix distDir per stage - - - - - b420fb24 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix hp2ps error during cross-compilation Fixed by @alp (see https://gitlab.haskell.org/ghc/ghc/issues/16051#note_274265) - - - - - cd339ef0 by Joshua Price at 2020-05-24T15:22:56-04:00 Make Unicode brackets opening/closing tokens (#18225) The tokens `[|`, `|]`, `(|`, and `|)` are opening/closing tokens as described in GHC Proposal #229. This commit makes the unicode variants (`⟦`, `⟧`, `⦇`, and `⦈`) act the same as their ASCII counterparts. - - - - - 013d7120 by Ben Gamari at 2020-05-25T09:48:17-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. - - - - - 4c4312ed by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Drop redundant ad-hoc boot module check To determine whether the module is a boot module Coverage.addTicksToBinds was checking for a `boot` suffix in the module source filename. This is quite ad-hoc and shouldn't be necessary; the callsite in `deSugar` already checks that the module isn't a boot module. - - - - - 1abf3c84 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make tickBoxCount strict This could otherwise easily cause a leak of (+) thunks. - - - - - b2813750 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make ccIndices strict This just seems like a good idea. - - - - - 02e278eb by Ben Gamari at 2020-05-25T09:48:53-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. - - - - - b8c014ce by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Factor out addMixEntry - - - - - 53814a64 by Zubin Duggal at 2020-05-26T03:03:24-04:00 Add info about typeclass evidence to .hie files See `testsuite/tests/hiefile/should_run/HieQueries.hs` and `testsuite/tests/hiefile/should_run/HieQueries.stdout` for an example of this We add two new fields, `EvidenceVarBind` and `EvidenceVarUse` to the `ContextInfo` associated with an Identifier. These are associated with the appropriate identifiers for the evidence variables collected when we come across `HsWrappers`, `TcEvBinds` and `IPBinds` while traversing the AST. Instance dictionary and superclass selector dictionaries from `tcg_insts` and classes defined in `tcg_tcs` are also recorded in the AST as originating from their definition span This allows us to save a complete picture of the evidence constructed by the constraint solver, and will let us report this to the user, enabling features like going to the instance definition from the invocation of a class method(or any other method taking a constraint) and finding all usages of a particular instance. Additionally, - Mark NodeInfo with an origin so we can differentiate between bindings origininating in the source vs those in ghc - Along with typeclass evidence info, also include information on Implicit Parameters - Add a few utility functions to HieUtils in order to query the new info Updates haddock submodule - - - - - 6604906c by Sebastian Graf at 2020-05-26T03:04:04-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. - - - - - cf772f19 by Sylvain Henry at 2020-05-26T03:04:45-04:00 Enhance Note [About units] for Backpack - - - - - 887c78b4 by Andreas Klebinger at 2020-05-26T14:46:23+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: - + .git-ignore-revs - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/merge_request_templates/merge-request.md - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - − compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4a98f14feed2c29c76f019675247255aa0c6f5fc...887c78b4073e934d19ed6256598599f896a03851 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4a98f14feed2c29c76f019675247255aa0c6f5fc...887c78b4073e934d19ed6256598599f896a03851 You're receiving 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 26 12:50:25 2020 From: gitlab at gitlab.haskell.org (Matthew Pickering) Date: Tue, 26 May 2020 08:50:25 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/proposal-195 Message-ID: <5ecd1091452b3_6e263f9ee352230016387a6@gitlab.haskell.org.mail> Matthew Pickering pushed new branch wip/proposal-195 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/proposal-195 You're receiving 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 26 13:35:23 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Tue, 26 May 2020 09:35:23 -0400 Subject: [Git][ghc/ghc][wip/osa1/lfinfo] 132 commits: rts: Enable tracing of nonmoving heap census with -ln Message-ID: <5ecd1b1b1e7aa_6e26115afe7c16630d6@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/lfinfo 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". - - - - - 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. - - - - - 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] - - - - - 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 - - - - - 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 - - - - - 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. - - - - - 78c6523c by Ben Gamari at 2020-05-21T12:13:01-04:00 nonmoving: Optimise the write barrier - - - - - 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). - - - - - 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 - - - - - b7a6b2f4 by Gleb Popov at 2020-05-21T12:15:26-04:00 gitlab-ci: Set locale to C.UTF-8. - - - - - 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. - - - - - 0004ccb8 by Tuan Le at 2020-05-21T12:16:46-04:00 llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 - - - - - 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 - - - - - 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 - - - - - 2b363ebb by Richard Eisenberg at 2020-05-21T12:18:45-04:00 MR template should ask for key part - - - - - a95bbd0b by Sebastian Graf at 2020-05-21T12:19:37-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. - - - - - d3d055b8 by Galen Huntington at 2020-05-21T12:20:18-04:00 Clarify pitfalls of NegativeLiterals; see #18022. - - - - - 1b508a9e by Alexey Kuleshevich at 2020-05-21T12:21:02-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" - - - - - 4ca0c8a1 by Andreas Klebinger at 2020-05-21T12:21: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. - - - - - a1275081 by Krzysztof Gogolewski at 2020-05-21T12:22:35-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 - - - - - 8a816e5f by Krzysztof Gogolewski at 2020-05-21T12:23:55-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. - - - - - 566cc73f by Sylvain Henry at 2020-05-21T12:24:45-04:00 Move isDynLinkName into GHC.Types.Name It doesn't belong into GHC.Unit.State - - - - - d830bbc9 by Adam Sandberg Ericsson at 2020-05-23T13:36:20-04:00 docs: fix formatting and add some links [skip ci] - - - - - 49301ad6 by Andrew Martin at 2020-05-23T13:37:01-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. - - - - - dcd6bdcc by Ben Gamari at 2020-05-23T13:37:48-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. - - - - - 82cb8913 by John Ericson at 2020-05-23T13:38:32-04:00 Fix #18145 and also avoid needless work with implicit vars - `forAllOrNothing` now is monadic, so we can trace whether we bind an explicit `forall` or not. - #18145 arose because the free vars calculation was needlessly complex. It is now greatly simplified. - Replaced some other implicit var code with `filterFreeVarsToBind`. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - a60dc835 by Ben Gamari at 2020-05-23T13:39:12-04:00 Bump process submodule Fixes #17926. - - - - - 856adf54 by Ben Gamari at 2020-05-23T13:40:21-04:00 users-guide: Clarify meaning of -haddock flag Fixes #18206. - - - - - 7ae57afd by Ben Gamari at 2020-05-23T13:41:03-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 - - - - - 63d30e60 by jneira at 2020-05-24T01:54:42-04:00 Add hie-bios script for windows systems It is a direct translation of the sh script - - - - - 59182b88 by jneira at 2020-05-24T01:54:42-04:00 Honour previous values for CABAL and CABFLAGS The immediate goal is let the hie-bios.bat script set CABFLAGS with `-v0` and remove all cabal output except the compiler arguments - - - - - 932dc54e by jneira at 2020-05-24T01:54:42-04:00 Add specific configuration for windows in hie.yaml - - - - - e0eda070 by jneira at 2020-05-24T01:54:42-04:00 Remove not needed hie-bios output - - - - - a0ea59d6 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Move Config module into GHC.Settings - - - - - 37430251 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Core.Arity into GHC.Core.Opt.Arity - - - - - a426abb9 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Hs.Types into GHC.Hs.Type See discussion in https://gitlab.haskell.org/ghc/ghc/issues/13009#note_268610 - - - - - 1c91a7a0 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Bump haddock submodule - - - - - 66bd24d1 by Ryan Scott at 2020-05-24T01:56:03-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. - - - - - 01c43634 by Matthew Pickering at 2020-05-24T01:56:42-04:00 Remove unused hs-boot file - - - - - 7a07aa71 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix cross-compiler build (#16051) - - - - - 15ccca16 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix distDir per stage - - - - - b420fb24 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix hp2ps error during cross-compilation Fixed by @alp (see https://gitlab.haskell.org/ghc/ghc/issues/16051#note_274265) - - - - - cd339ef0 by Joshua Price at 2020-05-24T15:22:56-04:00 Make Unicode brackets opening/closing tokens (#18225) The tokens `[|`, `|]`, `(|`, and `|)` are opening/closing tokens as described in GHC Proposal #229. This commit makes the unicode variants (`⟦`, `⟧`, `⦇`, and `⦈`) act the same as their ASCII counterparts. - - - - - 013d7120 by Ben Gamari at 2020-05-25T09:48:17-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. - - - - - 4c4312ed by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Drop redundant ad-hoc boot module check To determine whether the module is a boot module Coverage.addTicksToBinds was checking for a `boot` suffix in the module source filename. This is quite ad-hoc and shouldn't be necessary; the callsite in `deSugar` already checks that the module isn't a boot module. - - - - - 1abf3c84 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make tickBoxCount strict This could otherwise easily cause a leak of (+) thunks. - - - - - b2813750 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make ccIndices strict This just seems like a good idea. - - - - - 02e278eb by Ben Gamari at 2020-05-25T09:48:53-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. - - - - - b8c014ce by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Factor out addMixEntry - - - - - 53814a64 by Zubin Duggal at 2020-05-26T03:03:24-04:00 Add info about typeclass evidence to .hie files See `testsuite/tests/hiefile/should_run/HieQueries.hs` and `testsuite/tests/hiefile/should_run/HieQueries.stdout` for an example of this We add two new fields, `EvidenceVarBind` and `EvidenceVarUse` to the `ContextInfo` associated with an Identifier. These are associated with the appropriate identifiers for the evidence variables collected when we come across `HsWrappers`, `TcEvBinds` and `IPBinds` while traversing the AST. Instance dictionary and superclass selector dictionaries from `tcg_insts` and classes defined in `tcg_tcs` are also recorded in the AST as originating from their definition span This allows us to save a complete picture of the evidence constructed by the constraint solver, and will let us report this to the user, enabling features like going to the instance definition from the invocation of a class method(or any other method taking a constraint) and finding all usages of a particular instance. Additionally, - Mark NodeInfo with an origin so we can differentiate between bindings origininating in the source vs those in ghc - Along with typeclass evidence info, also include information on Implicit Parameters - Add a few utility functions to HieUtils in order to query the new info Updates haddock submodule - - - - - 6604906c by Sebastian Graf at 2020-05-26T03:04:04-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. - - - - - cf772f19 by Sylvain Henry at 2020-05-26T03:04:45-04:00 Enhance Note [About units] for Backpack - - - - - 2276d4d7 by Ömer Sinan Ağacan at 2020-05-26T16:34:20+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.89 | 0:34.10 | -1.78s, -4.98% | | -O1 | 2:24.01 | 2:23.62 | -0.39s, -0.27% | | -O2 | 2:52.23 | 2:51.35 | -0.88s, -0.51% | ## Allocations | | GHC HEAD | This patch | Diff | |-----|-----------------|-----------------|----------------------------| | -O0 | 54,843,608,416 | 54,878,769,544 | +35,161,128 bytes, +0.06% | | -O1 | 227,136,076,400 | 227,569,045,168 | +432,968,768 bytes, +0.19% | | -O2 | 266,147,063,296 | 266,749,643,440 | +602,580,144 bytes, +0.22% | ## 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 | 410,284,000 (910 samples) | 411,745,008 (906 samples) | +1,461,008 bytes, +0.35% | | -O1 | 928,580,856 (2109 samples) | 943,506,552 (2103 samples) | +14,925,696 bytes, +1.60% | | -O2 | 993,951,352 (2549 samples) | 1,010,156,328 (2545 samples) | +16,204,9760 bytes, +1.63% | 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: - + .git-ignore-revs - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/merge_request_templates/merge-request.md - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - − compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/PPC/Cond.hs - compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0340b080e58e9119050d8b3b6ae344406b1a0cdc...2276d4d7c1c589b6f1ac49a72c37e5c58e4d72c9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0340b080e58e9119050d8b3b6ae344406b1a0cdc...2276d4d7c1c589b6f1ac49a72c37e5c58e4d72c9 You're receiving 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 26 13:54:53 2020 From: gitlab at gitlab.haskell.org (Matthew Pickering) Date: Tue, 26 May 2020 09:54:53 -0400 Subject: [Git][ghc/ghc][wip/proposal-195] Use a newtype `Code` for the return type of typed quotations (Proposal #195) Message-ID: <5ecd1fada8d75_6e263f9f01f3c480167771c@gitlab.haskell.org.mail> Matthew Pickering pushed to branch wip/proposal-195 at Glasgow Haskell Compiler / GHC Commits: 9eb9370d by Matthew Pickering at 2020-05-26T14:54:32+01:00 Use a newtype `Code` for the return type of typed quotations (Proposal #195) There are three problems with the current API: 1. It is hard to properly write instances for ``Quote m => m (TExp a)`` as the type is the composition of two type constructors. Doing so in your program involves making your own newtype and doing a lot of wrapping/unwrapping. For example, if I want to create a language which I can either run immediately or generate code from I could write the following with the new API. :: class Lang r where _int :: Int -> r Int _if :: r Bool -> r a -> r a -> r a instance Lang Identity where _int = Identity _if (Identity b) (Identity t) (Identity f) = Identity (if b then t else f) instance Quote m => Lang (Code m) where _int = liftTyped _if cb ct cf = [|| if $$cb then $$ct else $$cf ||] 2. When doing code generation it is common to want to store code fragments in a map. When doing typed code generation, these code fragments contain a type index so it is desirable to store them in one of the parameterised map data types such as ``DMap`` from ``dependent-map`` or ``MapF`` from ``parameterized-utils``. :: compiler :: Env -> AST a -> Code Q a data AST a where ... data Ident a = ... type Env = MapF Ident (Code Q) newtype Code m a = Code (m (TExp a)) In this example, the ``MapF`` maps an ``Ident String`` directly to a ``Code Q String``. Using one of these map types currently requires creating your own newtype and constantly wrapping every quotation and unwrapping it when using a splice. Achievable, but it creates even more syntactic noise than normal metaprogramming. 3. ``m (TExp a)`` is ugly to read and write, understanding ``Code m a`` is easier. This is a weak reason but one everyone can surely agree with. - - - - - 26 changed files: - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Gen/Splice.hs - docs/users_guide/exts/deriving_extra.rst - docs/users_guide/exts/template_haskell.rst - libraries/template-haskell/Language/Haskell/TH.hs - libraries/template-haskell/Language/Haskell/TH/Lib.hs - libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/changelog.md - libraries/template-haskell/template-haskell.cabal.in - libraries/text - testsuite/tests/quotes/T17857.hs - testsuite/tests/th/T10945.stderr - testsuite/tests/th/T15471A.hs - testsuite/tests/th/T15843.hs - testsuite/tests/th/T16195A.hs - testsuite/tests/th/T18121.hs - testsuite/tests/th/T8577.stderr - testsuite/tests/th/T8577a.hs - testsuite/tests/th/TH_StringLift.hs - testsuite/tests/th/TH_reifyLocalDefs.hs - testsuite/tests/th/overloaded/T17839.hs - testsuite/tests/th/overloaded/TH_overloaded_constraints.hs - testsuite/tests/th/overloaded/TH_overloaded_csp.hs - testsuite/tests/th/overloaded/TH_overloaded_extract.hs Changes: ===================================== compiler/GHC/Builtin/Names/TH.hs ===================================== @@ -31,9 +31,8 @@ templateHaskellNames = [ mkNameName, mkNameG_vName, mkNameG_dName, mkNameG_tcName, mkNameLName, mkNameSName, liftStringName, - unTypeName, - unTypeQName, - unsafeTExpCoerceName, + unTypeName, unTypeCodeName, + unsafeCodeCoerceName, -- Lit charLName, stringLName, integerLName, intPrimLName, wordPrimLName, @@ -134,8 +133,6 @@ templateHaskellNames = [ -- DerivStrategy stockStrategyName, anyclassStrategyName, newtypeStrategyName, viaStrategyName, - -- TExp - tExpDataConName, -- RuleBndr ruleVarName, typedRuleVarName, -- FunDep @@ -158,7 +155,7 @@ templateHaskellNames = [ typeTyConName, tyVarBndrUnitTyConName, tyVarBndrSpecTyConName, clauseTyConName, patQTyConName, funDepTyConName, decsQTyConName, ruleBndrTyConName, tySynEqnTyConName, - roleTyConName, tExpTyConName, injAnnTyConName, kindTyConName, + roleTyConName, codeTyConName, injAnnTyConName, kindTyConName, overlapTyConName, derivClauseTyConName, derivStrategyTyConName, -- Quasiquoting @@ -191,7 +188,7 @@ quoteClassName = thCls (fsLit "Quote") quoteClassKey qTyConName, nameTyConName, fieldExpTyConName, patTyConName, fieldPatTyConName, expTyConName, decTyConName, typeTyConName, matchTyConName, clauseTyConName, funDepTyConName, predTyConName, - tExpTyConName, injAnnTyConName, overlapTyConName, decsTyConName :: Name + codeTyConName, injAnnTyConName, overlapTyConName, decsTyConName :: Name qTyConName = thTc (fsLit "Q") qTyConKey nameTyConName = thTc (fsLit "Name") nameTyConKey fieldExpTyConName = thTc (fsLit "FieldExp") fieldExpTyConKey @@ -205,14 +202,14 @@ matchTyConName = thTc (fsLit "Match") matchTyConKey clauseTyConName = thTc (fsLit "Clause") clauseTyConKey funDepTyConName = thTc (fsLit "FunDep") funDepTyConKey predTyConName = thTc (fsLit "Pred") predTyConKey -tExpTyConName = thTc (fsLit "TExp") tExpTyConKey +codeTyConName = thTc (fsLit "Code") codeTyConKey injAnnTyConName = thTc (fsLit "InjectivityAnn") injAnnTyConKey overlapTyConName = thTc (fsLit "Overlap") overlapTyConKey returnQName, bindQName, sequenceQName, newNameName, liftName, mkNameName, mkNameG_vName, mkNameG_dName, mkNameG_tcName, - mkNameLName, mkNameSName, liftStringName, unTypeName, unTypeQName, - unsafeTExpCoerceName, liftTypedName :: Name + mkNameLName, mkNameSName, liftStringName, unTypeName, unTypeCodeName, + unsafeCodeCoerceName, liftTypedName :: Name returnQName = thFun (fsLit "returnQ") returnQIdKey bindQName = thFun (fsLit "bindQ") bindQIdKey sequenceQName = thFun (fsLit "sequenceQ") sequenceQIdKey @@ -226,8 +223,8 @@ mkNameG_tcName = thFun (fsLit "mkNameG_tc") mkNameG_tcIdKey mkNameLName = thFun (fsLit "mkNameL") mkNameLIdKey mkNameSName = thFun (fsLit "mkNameS") mkNameSIdKey unTypeName = thFun (fsLit "unType") unTypeIdKey -unTypeQName = thFun (fsLit "unTypeQ") unTypeQIdKey -unsafeTExpCoerceName = thFun (fsLit "unsafeTExpCoerce") unsafeTExpCoerceIdKey +unTypeCodeName = thFun (fsLit "unTypeCode") unTypeCodeIdKey +unsafeCodeCoerceName = thFun (fsLit "unsafeCodeCoerce") unsafeCodeCoerceIdKey liftTypedName = thFun (fsLit "liftTyped") liftTypedIdKey @@ -519,10 +516,6 @@ unsafeName = libFun (fsLit "unsafe") unsafeIdKey safeName = libFun (fsLit "safe") safeIdKey interruptibleName = libFun (fsLit "interruptible") interruptibleIdKey --- newtype TExp a = ... -tExpDataConName :: Name -tExpDataConName = thCon (fsLit "TExp") tExpDataConKey - -- data RuleBndr = ... ruleVarName, typedRuleVarName :: Name ruleVarName = libFun (fsLit ("ruleVar")) ruleVarIdKey @@ -647,7 +640,7 @@ expTyConKey, matchTyConKey, clauseTyConKey, qTyConKey, expQTyConKey, fieldExpTyConKey, fieldPatTyConKey, nameTyConKey, patQTyConKey, funDepTyConKey, predTyConKey, predQTyConKey, decsQTyConKey, ruleBndrTyConKey, tySynEqnTyConKey, - roleTyConKey, tExpTyConKey, injAnnTyConKey, kindTyConKey, + roleTyConKey, tExpTyConKey, codeTyConKey, injAnnTyConKey, kindTyConKey, overlapTyConKey, derivClauseTyConKey, derivStrategyTyConKey, decsTyConKey :: Unique expTyConKey = mkPreludeTyConUnique 200 @@ -671,7 +664,6 @@ funDepTyConKey = mkPreludeTyConUnique 222 predTyConKey = mkPreludeTyConUnique 223 predQTyConKey = mkPreludeTyConUnique 224 tyVarBndrUnitTyConKey = mkPreludeTyConUnique 225 -tyVarBndrSpecTyConKey = mkPreludeTyConUnique 237 decsQTyConKey = mkPreludeTyConUnique 226 ruleBndrTyConKey = mkPreludeTyConUnique 227 tySynEqnTyConKey = mkPreludeTyConUnique 228 @@ -683,6 +675,8 @@ overlapTyConKey = mkPreludeTyConUnique 233 derivClauseTyConKey = mkPreludeTyConUnique 234 derivStrategyTyConKey = mkPreludeTyConUnique 235 decsTyConKey = mkPreludeTyConUnique 236 +tyVarBndrSpecTyConKey = mkPreludeTyConUnique 237 +codeTyConKey = mkPreludeTyConUnique 238 {- ********************************************************************* * * @@ -710,10 +704,6 @@ allPhasesDataConKey = mkPreludeDataConUnique 205 fromPhaseDataConKey = mkPreludeDataConUnique 206 beforePhaseDataConKey = mkPreludeDataConUnique 207 --- newtype TExp a = ... -tExpDataConKey :: Unique -tExpDataConKey = mkPreludeDataConUnique 208 - -- data Overlap = .. overlappableDataConKey, overlappingDataConKey, @@ -735,8 +725,8 @@ incoherentDataConKey = mkPreludeDataConUnique 212 returnQIdKey, bindQIdKey, sequenceQIdKey, liftIdKey, newNameIdKey, mkNameIdKey, mkNameG_vIdKey, mkNameG_dIdKey, mkNameG_tcIdKey, - mkNameLIdKey, mkNameSIdKey, unTypeIdKey, unTypeQIdKey, - unsafeTExpCoerceIdKey, liftTypedIdKey :: Unique + mkNameLIdKey, mkNameSIdKey, unTypeIdKey, unTypeCodeIdKey, + liftTypedIdKey, unsafeCodeCoerceIdKey :: Unique returnQIdKey = mkPreludeMiscIdUnique 200 bindQIdKey = mkPreludeMiscIdUnique 201 sequenceQIdKey = mkPreludeMiscIdUnique 202 @@ -749,9 +739,9 @@ mkNameG_tcIdKey = mkPreludeMiscIdUnique 208 mkNameLIdKey = mkPreludeMiscIdUnique 209 mkNameSIdKey = mkPreludeMiscIdUnique 210 unTypeIdKey = mkPreludeMiscIdUnique 211 -unTypeQIdKey = mkPreludeMiscIdUnique 212 -unsafeTExpCoerceIdKey = mkPreludeMiscIdUnique 213 +unTypeCodeIdKey = mkPreludeMiscIdUnique 212 liftTypedIdKey = mkPreludeMiscIdUnique 214 +unsafeCodeCoerceIdKey = mkPreludeMiscIdUnique 215 -- data Lit = ... @@ -1093,9 +1083,10 @@ inferredSpecKey = mkPreludeMiscIdUnique 499 ************************************************************************ -} -lift_RDR, liftTyped_RDR, mkNameG_dRDR, mkNameG_vRDR :: RdrName +lift_RDR, liftTyped_RDR, mkNameG_dRDR, mkNameG_vRDR, unsafeCodeCoerce_RDR :: RdrName lift_RDR = nameRdrName liftName liftTyped_RDR = nameRdrName liftTypedName +unsafeCodeCoerce_RDR = nameRdrName unsafeCodeCoerceName mkNameG_dRDR = nameRdrName mkNameG_dName mkNameG_vRDR = nameRdrName mkNameG_vName ===================================== compiler/GHC/Tc/Deriv/Generate.hs ===================================== @@ -1576,7 +1576,7 @@ gen_Lift_binds loc tycon = (listToBag [lift_bind, liftTyped_bind], emptyBag) where lift_bind = mkFunBindEC 1 loc lift_RDR (nlHsApp pure_Expr) (map (pats_etc mk_exp) data_cons) - liftTyped_bind = mkFunBindEC 1 loc liftTyped_RDR (nlHsApp pure_Expr) + liftTyped_bind = mkFunBindEC 1 loc liftTyped_RDR (nlHsApp unsafeCodeCoerce_Expr . nlHsApp pure_Expr) (map (pats_etc mk_texp) data_cons) mk_exp = ExpBr noExtField @@ -2352,17 +2352,18 @@ bs_RDRs = [ mkVarUnqual (mkFastString ("b"++show i)) | i <- [(1::Int) .. cs_RDRs = [ mkVarUnqual (mkFastString ("c"++show i)) | i <- [(1::Int) .. ] ] a_Expr, b_Expr, c_Expr, z_Expr, ltTag_Expr, eqTag_Expr, gtTag_Expr, false_Expr, - true_Expr, pure_Expr :: LHsExpr GhcPs -a_Expr = nlHsVar a_RDR -b_Expr = nlHsVar b_RDR -c_Expr = nlHsVar c_RDR -z_Expr = nlHsVar z_RDR -ltTag_Expr = nlHsVar ltTag_RDR -eqTag_Expr = nlHsVar eqTag_RDR -gtTag_Expr = nlHsVar gtTag_RDR -false_Expr = nlHsVar false_RDR -true_Expr = nlHsVar true_RDR -pure_Expr = nlHsVar pure_RDR + true_Expr, pure_Expr, unsafeCodeCoerce_Expr :: LHsExpr GhcPs +a_Expr = nlHsVar a_RDR +b_Expr = nlHsVar b_RDR +c_Expr = nlHsVar c_RDR +z_Expr = nlHsVar z_RDR +ltTag_Expr = nlHsVar ltTag_RDR +eqTag_Expr = nlHsVar eqTag_RDR +gtTag_Expr = nlHsVar gtTag_RDR +false_Expr = nlHsVar false_RDR +true_Expr = nlHsVar true_RDR +pure_Expr = nlHsVar pure_RDR +unsafeCodeCoerce_Expr = nlHsVar unsafeCodeCoerce_RDR a_Pat, b_Pat, c_Pat, d_Pat, k_Pat, z_Pat :: LPat GhcPs a_Pat = nlVarPat a_RDR ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -196,7 +196,7 @@ tcTypedBracket rn_expr brack@(TExpBr _ expr) res_ty ; let rep = getRuntimeRep expr_ty ; meta_ty <- tcTExpTy m_var expr_ty ; ps' <- readMutVar ps_ref - ; texpco <- tcLookupId unsafeTExpCoerceName + ; texpco <- tcLookupId unsafeCodeCoerceName ; tcWrapResultO (Shouldn'tHappenOrigin "TExpBr") rn_expr (unLoc (mkHsApp (mkLHsWrap (applyQuoteWrapper wrapper) @@ -302,9 +302,9 @@ tcPendingSplice m_var (PendingRnSplice flavour splice_name expr) tcTExpTy :: TcType -> TcType -> TcM TcType tcTExpTy m_ty exp_ty = do { unless (isTauTy exp_ty) $ addErr (err_msg exp_ty) - ; texp <- tcLookupTyCon tExpTyConName + ; codeCon <- tcLookupTyCon codeTyConName ; let rep = getRuntimeRep exp_ty - ; return (mkAppTy m_ty (mkTyConApp texp [rep, exp_ty])) } + ; return (mkTyConApp codeCon [rep, m_ty, exp_ty]) } where err_msg ty = vcat [ text "Illegal polytype:" <+> ppr ty @@ -619,10 +619,10 @@ tcNestedSplice pop_stage (TcPending ps_var lie_var q@(QuoteWrapper _ m_var)) spl ; expr' <- setStage pop_stage $ setConstraintVar lie_var $ tcLExpr expr (mkCheckExpType meta_exp_ty) - ; untypeq <- tcLookupId unTypeQName + ; untypeCode <- tcLookupId unTypeCodeName ; let expr'' = mkHsApp (mkLHsWrap (applyQuoteWrapper q) - (nlHsTyApp untypeq [rep, res_ty])) expr' + (nlHsTyApp untypeCode [rep, res_ty])) expr' ; ps <- readMutVar ps_var ; writeMutVar ps_var (PendingTcSplice splice_name expr'' : ps) ===================================== docs/users_guide/exts/deriving_extra.rst ===================================== @@ -528,7 +528,7 @@ Deriving ``Lift`` instances The class ``Lift``, unlike other derivable classes, lives in ``template-haskell`` instead of ``base``. Having a data type be an instance of ``Lift`` permits its values to be promoted to Template Haskell expressions (of -type ``ExpQ`` and ``TExpQ a``), which can then be spliced into Haskell source +type ``ExpQ`` and ``Code Q a``), which can then be spliced into Haskell source code. Here is an example of how one can derive ``Lift``: ===================================== docs/users_guide/exts/template_haskell.rst ===================================== @@ -133,15 +133,15 @@ The :extension:`TemplateHaskellQuotes` extension is considered safe under is an arbitrary expression. A top-level typed expression splice can occur in place of an expression; the - spliced expression must have type ``Q (TExp a)`` + spliced expression must have type ``Code Q a`` - A *typed* expression quotation is written as ``[|| ... ||]``, or ``[e|| ... ||]``, where the "..." is an expression; if the "..." expression has type ``a``, then the quotation has type - ``Quote m => m (TExp a)``. + ``Quote m => Code m a``. - Values of type ``TExp a`` may be converted to values of type ``Exp`` - using the function ``unType :: TExp a -> Exp``. + It is possible to extract a value of type ``m Exp`` from ``Code m a`` + using the ``unTypeCode :: Code m a -> m Exp`` function. - A quasi-quotation can appear in a pattern, type, expression, or declaration context and is also written in Oxford brackets: @@ -202,7 +202,7 @@ The :extension:`TemplateHaskellQuotes` extension is considered safe under class Lift t where lift :: Quote m => t -> m Exp - liftTyped :: Quote m => t -> m (TExp t) + liftTyped :: Quote m => t -> Code m t In general, if GHC sees an expression within Oxford brackets (e.g., ``[| foo bar |]``, then GHC looks up each name within the brackets. If a name ===================================== libraries/template-haskell/Language/Haskell/TH.hs ===================================== @@ -50,6 +50,7 @@ module Language.Haskell.TH( -- * Typed expressions TExp, unType, + Code(..), unTypeCode, unsafeCodeCoerce, hoistCode, -- * Names Name, NameSpace, -- Abstract ===================================== libraries/template-haskell/Language/Haskell/TH/Lib.hs ===================================== @@ -18,7 +18,7 @@ module Language.Haskell.TH.Lib ( -- * Library functions -- ** Abbreviations - InfoQ, ExpQ, TExpQ, DecQ, DecsQ, ConQ, TypeQ, KindQ, + InfoQ, ExpQ, TExpQ, CodeQ, DecQ, DecsQ, ConQ, TypeQ, KindQ, TyLitQ, CxtQ, PredQ, DerivClauseQ, MatchQ, ClauseQ, BodyQ, GuardQ, StmtQ, RangeQ, SourceStrictnessQ, SourceUnpackednessQ, BangQ, BangTypeQ, VarBangTypeQ, StrictTypeQ, VarStrictTypeQ, FieldExpQ, PatQ, ===================================== libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs ===================================== @@ -31,6 +31,7 @@ type PatQ = Q Pat type FieldPatQ = Q FieldPat type ExpQ = Q Exp type TExpQ a = Q (TExp a) +type CodeQ a = Code Q a type DecQ = Q Dec type DecsQ = Q [Dec] type Decs = [Dec] -- Defined as it is more convenient to wire-in ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -343,6 +343,63 @@ be inferred (#8459). Consider The splice will evaluate to (MkAge 3) and you can't add that to 4::Int. So you can't coerce a (TExp Age) to a (TExp Int). -} +-- Code constructor + +type role Code representational nominal -- See Note [Role of TExp] +newtype Code m (a :: TYPE (r :: RuntimeRep)) = Code + { examineCode :: m (TExp a) -- ^ Underlying monadic value + } + +-- | Unsafely convert an untyped code representation into a typed code +-- representation. +unsafeCodeCoerce :: forall (r :: RuntimeRep) (a :: TYPE r) m . + Quote m => m Exp -> Code m a +unsafeCodeCoerce m = Code (unsafeTExpCoerce m) + +-- | Lift a monadic action producing code into the typed 'Code' +-- representation +liftCode :: forall (r :: RuntimeRep) (a :: TYPE r) m . m (TExp a) -> Code m a +liftCode = Code + +-- | Extract the untyped representation from the typed representation +unTypeCode :: forall (r :: RuntimeRep) (a :: TYPE r) m . Quote m + => Code m a -> m Exp +unTypeCode = unTypeQ . examineCode + +-- | Modify the ambient monad used during code generation. For example, you +-- can use `hoistCode` to handle a state effect: +-- @ +-- handleState :: Code (StateT Int Q) a -> Code Q a +-- handleState = hoistCode (flip runState 0) +-- @ +hoistCode :: forall m n (r :: RuntimeRep) (a :: TYPE r) . Monad m + => (forall x . m x -> n x) -> Code m a -> Code n a +hoistCode f (Code a) = Code (f a) + + +-- | Variant of (>>=) which allows effectful computations to be injected +-- into code generation. +bindCode :: forall m a (r :: RuntimeRep) (b :: TYPE r) . Monad m + => m a -> (a -> Code m b) -> Code m b +bindCode q k = liftCode (q >>= examineCode . k) + +-- | Variant of (>>) which allows effectful computations to be injected +-- into code generation. +bindCode_ :: forall m a (r :: RuntimeRep) (b :: TYPE r) . Monad m + => m a -> Code m b -> Code m b +bindCode_ q c = liftCode ( q >> examineCode c) + +-- | A useful combinator for embedding monadic actions into 'Code' +-- @ +-- myCode :: ... => Code m a +-- myCode = joinCode $ do +-- x <- someSideEffect +-- return (makeCodeWith x) +-- @ +joinCode :: forall m (r :: RuntimeRep) (a :: TYPE r) . Monad m + => m (Code m a) -> Code m a +joinCode = flip bindCode id + ---------------------------------------------------- -- Packaged versions for the programmer, hiding the Quasi-ness @@ -727,107 +784,107 @@ class Lift (t :: TYPE r) where -- a splice. lift :: Quote m => t -> m Exp default lift :: (r ~ 'LiftedRep, Quote m) => t -> m Exp - lift = unTypeQ . liftTyped + lift = unTypeCode . liftTyped -- | Turn a value into a Template Haskell typed expression, suitable for use -- in a typed splice. -- -- @since 2.16.0.0 - liftTyped :: Quote m => t -> m (TExp t) + liftTyped :: Quote m => t -> Code m t -- If you add any instances here, consider updating test th/TH_Lift instance Lift Integer where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL x)) instance Lift Int where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) -- | @since 2.16.0.0 instance Lift Int# where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntPrimL (fromIntegral (I# x)))) instance Lift Int8 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Int16 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Int32 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Int64 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) -- | @since 2.16.0.0 instance Lift Word# where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (WordPrimL (fromIntegral (W# x)))) instance Lift Word where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Word8 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Word16 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Word32 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Word64 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Natural where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Integral a => Lift (Ratio a) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (RationalL (toRational x))) instance Lift Float where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (RationalL (toRational x))) -- | @since 2.16.0.0 instance Lift Float# where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (FloatPrimL (toRational (F# x)))) instance Lift Double where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (RationalL (toRational x))) -- | @since 2.16.0.0 instance Lift Double# where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (DoublePrimL (toRational (D# x)))) instance Lift Char where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (CharL x)) -- | @since 2.16.0.0 instance Lift Char# where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (CharPrimL (C# x))) instance Lift Bool where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift True = return (ConE trueName) lift False = return (ConE falseName) @@ -837,24 +894,24 @@ instance Lift Bool where -- -- @since 2.16.0.0 instance Lift Addr# where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (StringPrimL (map (fromIntegral . ord) (unpackCString# x)))) instance Lift a => Lift (Maybe a) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift Nothing = return (ConE nothingName) lift (Just x) = liftM (ConE justName `AppE`) (lift x) instance (Lift a, Lift b) => Lift (Either a b) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (Left x) = liftM (ConE leftName `AppE`) (lift x) lift (Right y) = liftM (ConE rightName `AppE`) (lift y) instance Lift a => Lift [a] where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift xs = do { xs' <- mapM lift xs; return (ListE xs') } liftString :: Quote m => String -> m Exp @@ -863,7 +920,7 @@ liftString s = return (LitE (StringL s)) -- | @since 2.15.0.0 instance Lift a => Lift (NonEmpty a) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (x :| xs) = do x' <- lift x @@ -872,77 +929,77 @@ instance Lift a => Lift (NonEmpty a) where -- | @since 2.15.0.0 instance Lift Void where - liftTyped = pure . absurd + liftTyped = liftCode . absurd lift = pure . absurd instance Lift () where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift () = return (ConE (tupleDataName 0)) instance (Lift a, Lift b) => Lift (a, b) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (a, b) = liftM TupE $ sequence $ map (fmap Just) [lift a, lift b] instance (Lift a, Lift b, Lift c) => Lift (a, b, c) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (a, b, c) = liftM TupE $ sequence $ map (fmap Just) [lift a, lift b, lift c] instance (Lift a, Lift b, Lift c, Lift d) => Lift (a, b, c, d) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (a, b, c, d) = liftM TupE $ sequence $ map (fmap Just) [lift a, lift b, lift c, lift d] instance (Lift a, Lift b, Lift c, Lift d, Lift e) => Lift (a, b, c, d, e) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (a, b, c, d, e) = liftM TupE $ sequence $ map (fmap Just) [ lift a, lift b , lift c, lift d, lift e ] instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f) => Lift (a, b, c, d, e, f) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (a, b, c, d, e, f) = liftM TupE $ sequence $ map (fmap Just) [ lift a, lift b, lift c , lift d, lift e, lift f ] instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f, Lift g) => Lift (a, b, c, d, e, f, g) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (a, b, c, d, e, f, g) = liftM TupE $ sequence $ map (fmap Just) [ lift a, lift b, lift c , lift d, lift e, lift f, lift g ] -- | @since 2.16.0.0 instance Lift (# #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# #) = return (ConE (unboxedTupleTypeName 0)) -- | @since 2.16.0.0 instance (Lift a) => Lift (# a #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# a #) = liftM UnboxedTupE $ sequence $ map (fmap Just) [lift a] -- | @since 2.16.0.0 instance (Lift a, Lift b) => Lift (# a, b #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# a, b #) = liftM UnboxedTupE $ sequence $ map (fmap Just) [lift a, lift b] -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c) => Lift (# a, b, c #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# a, b, c #) = liftM UnboxedTupE $ sequence $ map (fmap Just) [lift a, lift b, lift c] -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d) => Lift (# a, b, c, d #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# a, b, c, d #) = liftM UnboxedTupE $ sequence $ map (fmap Just) [ lift a, lift b , lift c, lift d ] @@ -950,7 +1007,7 @@ instance (Lift a, Lift b, Lift c, Lift d) -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d, Lift e) => Lift (# a, b, c, d, e #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# a, b, c, d, e #) = liftM UnboxedTupE $ sequence $ map (fmap Just) [ lift a, lift b , lift c, lift d, lift e ] @@ -958,7 +1015,7 @@ instance (Lift a, Lift b, Lift c, Lift d, Lift e) -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f) => Lift (# a, b, c, d, e, f #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# a, b, c, d, e, f #) = liftM UnboxedTupE $ sequence $ map (fmap Just) [ lift a, lift b, lift c , lift d, lift e, lift f ] @@ -966,7 +1023,7 @@ instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f) -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f, Lift g) => Lift (# a, b, c, d, e, f, g #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# a, b, c, d, e, f, g #) = liftM UnboxedTupE $ sequence $ map (fmap Just) [ lift a, lift b, lift c , lift d, lift e, lift f @@ -974,7 +1031,7 @@ instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f, Lift g) -- | @since 2.16.0.0 instance (Lift a, Lift b) => Lift (# a | b #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = case x of (# y | #) -> UnboxedSumE <$> lift y <*> pure 1 <*> pure 2 @@ -983,7 +1040,7 @@ instance (Lift a, Lift b) => Lift (# a | b #) where -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c) => Lift (# a | b | c #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = case x of (# y | | #) -> UnboxedSumE <$> lift y <*> pure 1 <*> pure 3 @@ -993,7 +1050,7 @@ instance (Lift a, Lift b, Lift c) -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d) => Lift (# a | b | c | d #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = case x of (# y | | | #) -> UnboxedSumE <$> lift y <*> pure 1 <*> pure 4 @@ -1004,7 +1061,7 @@ instance (Lift a, Lift b, Lift c, Lift d) -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d, Lift e) => Lift (# a | b | c | d | e #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = case x of (# y | | | | #) -> UnboxedSumE <$> lift y <*> pure 1 <*> pure 5 @@ -1016,7 +1073,7 @@ instance (Lift a, Lift b, Lift c, Lift d, Lift e) -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f) => Lift (# a | b | c | d | e | f #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = case x of (# y | | | | | #) -> UnboxedSumE <$> lift y <*> pure 1 <*> pure 6 @@ -1029,7 +1086,7 @@ instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f) -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f, Lift g) => Lift (# a | b | c | d | e | f | g #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = case x of (# y | | | | | | #) -> UnboxedSumE <$> lift y <*> pure 1 <*> pure 7 ===================================== libraries/template-haskell/changelog.md ===================================== @@ -1,6 +1,9 @@ # Changelog for [`template-haskell` package](http://hackage.haskell.org/package/template-haskell) ## 2.17.0.0 + * Typed Quotations now return a value of type `Code m a` (GHC Proposal #195). + The main motiviation is to make writing instances easier and make it easier to + store `Code` values in type-indexed maps. * Implement Overloaded Quotations (GHC Proposal #246). This patch modifies a few fundamental things in the API. All the library combinators are generalised @@ -9,7 +12,7 @@ written in terms of `Q` are now disallowed. The types of `unsafeTExpCoerce` and `unTypeQ` are also generalised in terms of `Quote` rather than specific to `Q`. - + * Implement Explicit specificity in type variable binders (GHC Proposal #99). In `Language.Haskell.TH.Syntax`, `TyVarBndr` is now annotated with a `flag`, denoting the additional argument to its constructors `PlainTV` and `KindedTV`. ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -48,7 +48,7 @@ Library Language.Haskell.TH.Quote Language.Haskell.TH.Syntax Language.Haskell.TH.LanguageExtensions - + Language.Haskell.TH.CodeDo Language.Haskell.TH.Lib.Internal other-modules: ===================================== libraries/text ===================================== @@ -1 +1 @@ -Subproject commit a01843250166b5559936ba5eb81f7873e709587a +Subproject commit 74f835751b60b312d01dd600d516756d5325d514 ===================================== testsuite/tests/quotes/T17857.hs ===================================== @@ -7,4 +7,4 @@ import Language.Haskell.TH.Syntax data T = MkT deriving Data instance Lift T where lift = liftData - liftTyped = unsafeTExpCoerce . lift + liftTyped = unsafeCodeCoerce . lift ===================================== testsuite/tests/th/T10945.stderr ===================================== @@ -1,8 +1,8 @@ T10945.hs:7:4: error: - • Couldn't match type ‘[Dec]’ with ‘TExp DecsQ’ - Expected type: Q (TExp DecsQ) - Actual type: Q [Dec] + • Couldn't match type ‘[Dec]’ with ‘Q [Dec]’ + Expected type: Code Q DecsQ + Actual type: Code Q [Dec] • In the expression: return [SigD ===================================== testsuite/tests/th/T15471A.hs ===================================== @@ -6,9 +6,9 @@ import Language.Haskell.TH foo1 x = x -test_foo :: Q (TExp (a -> a)) +test_foo :: Code Q (a -> a) test_foo = [|| foo1 ||] -list_foo :: Q (TExp a) -> Q (TExp [a]) +list_foo :: Code Q a -> Code Q [a] list_foo x = [|| [ $$x, $$x ] ||] ===================================== testsuite/tests/th/T15843.hs ===================================== @@ -13,12 +13,12 @@ main = do mapM_ (\q -> runQ q >>= ppr_and_show) [first_of_2, second_of_2, empty_2, full_2, third_of_3] - mapM_ (\q -> runQ (fmap unType q) >>= ppr_and_show) + mapM_ (\q -> (runQ (unTypeCode q)) >>= ppr_and_show) [first_of_2_T, second_of_2_T] - runQ (fmap unType empty_2_T) >>= ppr_and_show - runQ (fmap unType full_2_T) >>= ppr_and_show - runQ (fmap unType third_of_3_T) >>= ppr_and_show + runQ (unTypeCode empty_2_T) >>= ppr_and_show + runQ (unTypeCode full_2_T) >>= ppr_and_show + runQ (unTypeCode third_of_3_T) >>= ppr_and_show print $ "(909,) applied to 'c' should be (909, 'c') ===> " ++ (show $ (909, 'c') == ($first_of_2 'c')) ===================================== testsuite/tests/th/T16195A.hs ===================================== @@ -3,11 +3,11 @@ module T16195A where import Language.Haskell.TH -foo :: Q (TExp (IO ())) +foo :: Code Q (IO ()) foo = [|| return () ||] -showC :: Q (TExp (() -> String)) +showC :: Code Q (() -> String) showC = [|| show ||] -unitC :: Q (TExp ()) +unitC :: Code Q () unitC = [|| () ||] ===================================== testsuite/tests/th/T18121.hs ===================================== @@ -3,5 +3,5 @@ module Bug where import Language.Haskell.TH -sapply :: Q (TExp (a -> b)) -> Q (TExp a) -> Q (TExp b) +sapply :: Quote m => Code m (a -> b) -> Code m a -> Code m b sapply cf cx = [|| $$cf $$cx ||] ===================================== testsuite/tests/th/T8577.stderr ===================================== @@ -1,8 +1,8 @@ T8577.hs:9:11: error: • Couldn't match type ‘Int’ with ‘Bool’ - Expected type: Q (TExp (A Bool)) - Actual type: Q (TExp (A Int)) + Expected type: Code Q (A Bool) + Actual type: Code Q (A Int) • In the expression: y In the Template Haskell splice $$(y) In the expression: $$(y) ===================================== testsuite/tests/th/T8577a.hs ===================================== @@ -4,8 +4,8 @@ import Language.Haskell.TH data A a = A -x :: Q (TExp (A a)) +x :: Code Q (A a) x = [|| A ||] -y :: Q (TExp (A Int)) +y :: Code Q (A Int) y = x ===================================== testsuite/tests/th/TH_StringLift.hs ===================================== @@ -3,7 +3,7 @@ module TH_StringLift where import Language.Haskell.TH.Syntax -foo :: Quote m => String -> m (TExp String) +foo :: Quote m => String -> Code m String foo x = [|| x ||] foo2 :: Quote m => String -> m Exp ===================================== testsuite/tests/th/TH_reifyLocalDefs.hs ===================================== @@ -29,8 +29,8 @@ main = print (f 1 "", g 'a' 2, h True 3) ) , xg :: Char ) - h xh y = ( $$(do printTypeOf("xh") - [|| y :: Int ||] + h xh y = ( $$(liftCode $ do printTypeOf("xh") + examineCode [|| y :: Int ||] ) , xh :: Bool ) ===================================== testsuite/tests/th/overloaded/T17839.hs ===================================== @@ -16,7 +16,7 @@ import Data.Functor.Identity type LetT m a = WriterT [Locus] m a -type Code m a = m (TExp a) +type MCode m a = m (TExp a) type LetCode m a = LetT m (TExp a) @@ -29,7 +29,7 @@ instance (Monoid w, Quote m) => Quote (StateT w m) where newName x = W.lift (newName x) -locus :: (Locus -> LetCode m a) -> Code m a +locus :: (Locus -> LetCode m a) -> MCode m a locus = undefined newTypedName :: Quote m => m (TExp a) @@ -38,15 +38,15 @@ newTypedName = do return (TExp (VarE n)) -gen :: Quote m => Locus -> (Code Identity (a -> b) -> LetCode m a -> LetCode m b) -> LetCode m (a -> b) +gen :: Quote m => Locus -> (MCode Identity (a -> b) -> LetCode m a -> LetCode m b) -> LetCode m (a -> b) gen l f = do n <- newTypedName - [|| \a -> $$(f (Identity n) [|| a ||]) ||] + examineCode [|| \a -> $$(liftCode $ f (Identity n) (examineCode [|| a ||])) ||] mrfix :: forall a b m r . (Monad m, Ord a, Quote m) - => (forall m . (a -> Code m (b -> r)) -> (a -> Code m b -> Code m r)) - -> (a -> Code m (b -> r)) + => (forall m . (a -> MCode m (b -> r)) -> (a -> MCode m b -> MCode m r)) + -> (a -> MCode m (b -> r)) mrfix f x = flip evalStateT Map.empty $ locus $ \locus -> do ===================================== testsuite/tests/th/overloaded/TH_overloaded_constraints.hs ===================================== @@ -22,11 +22,11 @@ dq = [| 5 |] top_level :: (C m, D m, Quote m) => m Exp top_level = [| $cq + $dq |] -cqt :: (C m, Quote m) => m (TExp Int) +cqt :: (C m, Quote m) => Code m Int cqt = [|| 5 ||] -dqt :: (D m, Quote m) => m (TExp Int) +dqt :: (D m, Quote m) => Code m Int dqt = [|| 5 ||] -top_level_t :: (C m, D m, Quote m) => m (TExp Int) +top_level_t :: (C m, D m, Quote m) => Code m Int top_level_t = [|| $$cqt + $$dqt ||] ===================================== testsuite/tests/th/overloaded/TH_overloaded_csp.hs ===================================== @@ -14,5 +14,5 @@ instance Quote Identity where main = do print $ runIdentity ((\x -> [| x |]) ()) - print $ unType $ runIdentity ((\x -> [|| x ||]) ()) + print $ runIdentity $ unTypeCode ((\x -> [|| x ||]) ()) ===================================== testsuite/tests/th/overloaded/TH_overloaded_extract.hs ===================================== @@ -19,5 +19,5 @@ main = do print $ runIdentity [d| data Foo = Foo |] print $ runIdentity [p| () |] print $ runIdentity [t| [Int] |] - print $ unType $ runIdentity [|| (+1) ||] + print $ runIdentity $ unTypeCode [|| (+1) ||] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9eb9370db9ce001ab4f4ea661e148f4dc4d43151 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/9eb9370db9ce001ab4f4ea661e148f4dc4d43151 You're receiving 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 26 14:02:59 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Tue, 26 May 2020 10:02:59 -0400 Subject: [Git][ghc/ghc][wip/T18191] Make GADT constructors adhere to the forall-or-nothing rule properly Message-ID: <5ecd21932fc41_6e263f9f0ba0f8401688528@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T18191 at Glasgow Haskell Compiler / GHC Commits: 448cfdfb by Ryan Scott at 2020-05-26T09:46:55-04:00 Make GADT constructors adhere to the forall-or-nothing rule properly Issue #18191 revealed that the types of GADT constructors don't quite adhere to the `forall`-or-nothing rule. This patch serves to clean up this sad state of affairs somewhat. The main change is not in the code itself, but in the documentation, as this patch introduces two sections to the GHC User's Guide: * A "Formal syntax for GADTs" section that presents a BNF-style grammar for what is and isn't allowed in GADT constructor types. This mostly exists to codify GHC's existing behavior, but it also imposes a new restriction that addresses #18191: the outermost `forall` and/or context in a GADT constructor is not allowed to be surrounded by parentheses. Doing so would make these `forall`s/contexts nested, and GADTs do not support nested `forall`s/contexts at present. * A "`forall`-or-nothing rule" section that describes exactly what the `forall`-or-nothing rule is all about. Surprisingly, there was no mention of this anywhere in the User's Guide up until now! To adhere the new specification in the "Formal syntax for GADTs" section of the User's Guide, the following code changes were made: * `GHC.Parser.PostProcess.mkGadtDecl` no longer strips away parentheses from the outermost `forall` and context. Instead, these parentheses are preserved so that the renamer can check for nested `forall`s/contexts later. See `Note [No nested foralls or contexts in GADT constructors]` in `GHC.Parser.PostProcess` for more details. One nice side effect of this change is that we can get rid of the explicit `AddAnn` tracking in `mkGadtDecl`, as we no longer need to remember the `AddAnn`s for stripped-away parentheses. * `GHC.Renamer.Module.rnConDecl` now checks for nested `forall`s/contexts, rather than checking for this in the typechcker (in `GHC.Tc.TyCl.badDataConTyCon`). For the most part, this code was ported directly from `badDataConTyCon`, but designed to work over `HsType`s instead of `Type`s. One nice side effect of this change is that we are able to give a more accurate error message for GADT constructors that use visible dependent quantification (e.g., `MkFoo :: forall a -> a -> Foo a`), which improves the stderr in the `T16326_Fail6` test case. Fixes #18191. - - - - - 20 changed files: - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/ThToHs.hs - docs/users_guide/8.12.1-notes.rst - docs/users_guide/exts/explicit_forall.rst - docs/users_guide/exts/gadt_syntax.rst - testsuite/tests/dependent/should_fail/T16326_Fail6.stderr - testsuite/tests/gadt/T12087.stderr - testsuite/tests/gadt/T14320.hs - + testsuite/tests/gadt/T14320.stderr - testsuite/tests/gadt/T16427.stderr - + testsuite/tests/gadt/T18191.hs - + testsuite/tests/gadt/T18191.stderr - testsuite/tests/gadt/all.T - testsuite/tests/ghc-api/annotations/T10399.stdout - testsuite/tests/ghc-api/annotations/Test10399.hs - testsuite/tests/parser/should_compile/T15323.hs - testsuite/tests/parser/should_compile/T15323.stderr Changes: ===================================== compiler/GHC/Parser.y ===================================== @@ -2248,9 +2248,8 @@ gadt_constr :: { LConDecl GhcPs } -- see Note [Difference in parsing GADT and data constructors] -- Returns a list because of: C,D :: ty : con_list '::' sigtypedoc - {% let (gadt,anns) = mkGadtDecl (unLoc $1) $3 - in ams (sLL $1 $> gadt) - (mu AnnDcolon $2:anns) } + {% ams (sLL $1 $> (mkGadtDecl (unLoc $1) $3)) + [mu AnnDcolon $2] } {- Note [Difference in parsing GADT and data constructors] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -685,30 +685,41 @@ mkConDeclH98 name mb_forall mb_cxt args , con_args = args , con_doc = Nothing } +-- Construct a GADT-style data constructor from the constructor names and their +-- type. Does not perform any validity checking, as that it done later in +-- GHC.Rename.Module.rnConDecl. mkGadtDecl :: [Located RdrName] -> LHsType GhcPs -- Always a HsForAllTy - -> (ConDecl GhcPs, [AddAnn]) + -> ConDecl GhcPs mkGadtDecl names ty - = (ConDeclGADT { con_g_ext = noExtField - , con_names = names - , con_forall = L l $ isLHsForAllTy ty' - , con_qvars = tvs - , con_mb_cxt = mcxt - , con_args = args - , con_res_ty = res_ty - , con_doc = Nothing } - , anns1 ++ anns2) + = ConDeclGADT { con_g_ext = noExtField + , con_names = names + , con_forall = L (getLoc ty) $ isJust mtvs + , con_qvars = fromMaybe [] mtvs + , con_mb_cxt = mcxt + , con_args = args + , con_res_ty = res_ty + , con_doc = Nothing } where - (ty'@(L l _),anns1) = peel_parens ty [] - (tvs, rho) = splitLHsForAllTyInvis ty' - (mcxt, tau, anns2) = split_rho rho [] - - split_rho (L _ (HsQualTy { hst_ctxt = cxt, hst_body = tau })) ann - = (Just cxt, tau, ann) - split_rho (L l (HsParTy _ ty)) ann - = split_rho ty (ann++mkParensApiAnn l) - split_rho tau ann - = (Nothing, tau, ann) + (mtvs, rho) = split_sigma ty + (mcxt, tau) = split_rho rho + + -- NB: We do not use splitLHsForAllTyInvis below, since that looks through + -- parentheses... + split_sigma (L _ (HsForAllTy { hst_fvf = ForallInvis, hst_bndrs = bndrs + , hst_body = rho })) + = (Just bndrs, rho) + split_sigma sigma + = (Nothing, sigma) + + -- ...similarly, we do not use splitLHsQualTy below, since that also looks + -- through parentheses. + -- See Note [No nested foralls or contexts in GADT constructors] for why + -- this is important. + split_rho (L _ (HsQualTy { hst_ctxt = cxt, hst_body = tau })) + = (Just cxt, tau) + split_rho tau + = (Nothing, tau) (args, res_ty) = split_tau tau @@ -718,10 +729,43 @@ mkGadtDecl names ty split_tau tau = (PrefixCon [], tau) - peel_parens (L l (HsParTy _ ty)) ann = peel_parens ty - (ann++mkParensApiAnn l) - peel_parens ty ann = (ty, ann) - +{- +Note [No nested foralls or contexts in GADT constructors] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +GADT constructors provide some freedom to change the order of foralls in their +types (see Note [DataCon user type variable binders] in GHC.Core.DataCon), but +this freedom is still limited. GADTs still require that all quantification +occurs prenex. That is, any explicitly quantified type variables must occur at +the front of the GADT type, followed by any contexts, followed by the body of +the GADT type, in precisely that order. For instance: + + data T where + MkT1 :: forall a b. (Eq a, Eq b) => a -> b -> T + -- OK + MkT2 :: forall a. Eq a => forall b. a -> b -> T + -- Rejected, `forall b` is nested + MkT3 :: forall a b. Eq a => Eq b => a -> b -> T + -- Rejected, `Eq b` is nested + MkT4 :: Int -> forall a. a -> T + -- Rejected, `forall a` is nested + MkT5 :: forall a. Int -> Eq a => a -> T + -- Rejected, `Eq a` is nested + MkT6 :: (forall a. a -> T) + -- Rejected, `forall a` is nested due to the surrounding parentheses + MkT7 :: (Eq a => a -> t) + -- Rejected, `Eq a` is nested due to the surrounding parentheses + +For the full details, see the "Formal syntax for GADTs" section of the GHC +User's Guide. + +Because the presence of outermost parentheses can affect whether +`forall`s/contexts are nested, the parser is careful not to remove parentheses +when post-processing GADT constructors (in mkGadtDecl). Later, the renamer will +check for nested `forall`s/contexts (in GHC.Rename.Module.rnConDecl) after +it has determined what all of the argument types are. +(See Note [GADT abstract syntax] in GHC.Hs.Decls for why this check must wait +until the renamer.) +-} setRdrNameSpace :: RdrName -> NameSpace -> RdrName -- ^ This rather gruesome function is used mainly by the parser. ===================================== compiler/GHC/Rename/Module.hs ===================================== @@ -2126,16 +2126,21 @@ rnConDecl decl@(ConDeclGADT { con_names = names do { (new_cxt, fvs1) <- rnMbContext ctxt mcxt ; (new_args, fvs2) <- rnConDeclDetails (unLoc (head new_names)) ctxt args ; (new_res_ty, fvs3) <- rnLHsType ctxt res_ty + ; (args', res_ty') <- + case args of + InfixCon {} -> pprPanic "rnConDecl" (ppr names) + RecCon {} -> pure (new_args, new_res_ty) + PrefixCon as -> do + -- In the PrefixCon case, the parser puts the entire body of + -- the constructor type, including argument types, into res_ty. + -- We can properly determine what the argument types are after + -- renaming (see Note [GADT abstract syntax] in GHC.Hs.Decls), + -- so we do so by splitting new_res_ty below. + MASSERT( null as ) + (arg_tys, final_res_ty) <- split_prefix_gadt_ty ctxt new_res_ty + pure (PrefixCon arg_tys, final_res_ty) ; let all_fvs = fvs1 `plusFV` fvs2 `plusFV` fvs3 - (args', res_ty') - = case args of - InfixCon {} -> pprPanic "rnConDecl" (ppr names) - RecCon {} -> (new_args, new_res_ty) - PrefixCon as | (arg_tys, final_res_ty) <- splitHsFunType new_res_ty - -> ASSERT( null as ) - -- See Note [GADT abstract syntax] in GHC.Hs.Decls - (PrefixCon arg_tys, final_res_ty) ; traceRn "rnConDecl2" (ppr names $$ ppr implicit_tkvs $$ ppr explicit_tkvs) ; return (decl { con_g_ext = implicit_tkvs, con_names = new_names @@ -2143,7 +2148,42 @@ rnConDecl decl@(ConDeclGADT { con_names = names , con_args = args', con_res_ty = res_ty' , con_doc = mb_doc' }, all_fvs) } } - + where + -- Split the body of a prefix GADT constructor type into its argument + -- and result types. Furthermore, ensure that there are no nested `forall`s + -- or contexts, per + -- Note [No nested foralls or contexts in GADT constructors] in + -- GHC.Parser.PostProcess. + split_prefix_gadt_ty :: HsDocContext + -> LHsType GhcRn + -> RnM ([LHsType GhcRn], LHsType GhcRn) + split_prefix_gadt_ty ctxt gadt_rho = do + let split_gadt_rho@(_, gadt_res_ty) = splitHsFunType gadt_rho + + -- Check for nested `forall`s or contexts + case gadt_res_ty of + L l (HsForAllTy { hst_fvf = fvf }) + | ForallVis <- fvf + -> setSrcSpan l $ addErr $ withHsDocContext ctxt $ vcat + [ text "Illegal visible, dependent quantification" <+> + text "in the type of a term" + , text "(GHC does not yet support this)" ] + | ForallInvis <- fvf + -> nested_foralls_contexts_err l ctxt + L l (HsQualTy {}) + -> nested_foralls_contexts_err l ctxt + _ -> pure () + + pure split_gadt_rho + + -- If we are going to reject a GADT constructor type for having nested + -- `forall`s or contexts, then we can at least suggest an alternative + -- way to write the type without nesting. (#12087) + nested_foralls_contexts_err :: SrcSpan -> HsDocContext -> RnM () + nested_foralls_contexts_err l ctxt = + setSrcSpan l $ addErr $ withHsDocContext ctxt $ + text "GADT constructor type signature cannot contain nested" + <+> quotes forAllLit <> text "s or contexts" rnMbContext :: HsDocContext -> Maybe (LHsContext GhcPs) -> RnM (Maybe (LHsContext GhcRn), FreeVars) ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -4720,50 +4720,12 @@ noClassTyVarErr clas fam_tc badDataConTyCon :: DataCon -> Type -> SDoc badDataConTyCon data_con res_ty_tmpl - | ASSERT( all isTyVar tvs ) - tcIsForAllTy actual_res_ty - = nested_foralls_contexts_suggestion - | isJust (tcSplitPredFunTy_maybe actual_res_ty) - = nested_foralls_contexts_suggestion - | otherwise = hang (text "Data constructor" <+> quotes (ppr data_con) <+> text "returns type" <+> quotes (ppr actual_res_ty)) 2 (text "instead of an instance of its parent type" <+> quotes (ppr res_ty_tmpl)) where actual_res_ty = dataConOrigResTy data_con - -- This suggestion is useful for suggesting how to correct code like what - -- was reported in #12087: - -- - -- data F a where - -- MkF :: Ord a => Eq a => a -> F a - -- - -- Although nested foralls or contexts are allowed in function type - -- signatures, it is much more difficult to engineer GADT constructor type - -- signatures to allow something similar, so we error in the latter case. - -- Nevertheless, we can at least suggest how a user might reshuffle their - -- exotic GADT constructor type signature so that GHC will accept. - nested_foralls_contexts_suggestion = - text "GADT constructor type signature cannot contain nested" - <+> quotes forAllLit <> text "s or contexts" - $+$ hang (text "Suggestion: instead use this type signature:") - 2 (ppr (dataConName data_con) <+> dcolon <+> ppr suggested_ty) - - -- To construct a type that GHC would accept (suggested_ty), we: - -- - -- 1) Find the existentially quantified type variables and the class - -- predicates from the datacon. (NB: We don't need the universally - -- quantified type variables, since rejigConRes won't substitute them in - -- the result type if it fails, as in this scenario.) - -- 2) Split apart the return type (which is headed by a forall or a - -- context) using tcSplitNestedSigmaTys, collecting the type variables - -- and class predicates we find, as well as the rho type lurking - -- underneath the nested foralls and contexts. - -- 3) Smash together the type variables and class predicates from 1) and - -- 2), and prepend them to the rho type from 2). - (tvs, theta, rho) = tcSplitNestedSigmaTys (dataConUserType data_con) - suggested_ty = mkSpecSigmaTy tvs theta rho - badGadtDecl :: Name -> SDoc badGadtDecl tc_name = vcat [ text "Illegal generalised algebraic data declaration for" <+> quotes (ppr tc_name) ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -619,7 +619,7 @@ cvtConstr (GadtC c strtys ty) ; args <- mapM cvt_arg strtys ; L _ ty' <- cvtType ty ; c_ty <- mk_arr_apps args ty' - ; returnL $ fst $ mkGadtDecl c' c_ty} + ; returnL $ mkGadtDecl c' c_ty} cvtConstr (RecGadtC [] _varstrtys _ty) = failWith (text "RecGadtC must have at least one constructor name") @@ -630,7 +630,7 @@ cvtConstr (RecGadtC c varstrtys ty) ; rec_flds <- mapM cvt_id_arg varstrtys ; let rec_ty = noLoc (HsFunTy noExtField (noLoc $ HsRecTy noExtField rec_flds) ty') - ; returnL $ fst $ mkGadtDecl c' rec_ty } + ; returnL $ mkGadtDecl c' rec_ty } cvtSrcUnpackedness :: TH.SourceUnpackedness -> SrcUnpackedness cvtSrcUnpackedness NoSourceUnpackedness = NoSrcUnpack ===================================== docs/users_guide/8.12.1-notes.rst ===================================== @@ -95,7 +95,28 @@ Language effectively allows users to choose which variables can or can't be instantiated through visible type application. More information can be found here: :ref:`Manually-defining-inferred-variables`. - + +* GADT constructor types now properly adhere to :ref:`forall-or-nothing`. As + a result, GHC will now reject some GADT constructors that previous versions + of GHC would accept, such as the following: :: + + data T where + MkT1 :: (forall a. a -> b -> T) + MkT2 :: (forall a. a -> T) + + ``MkT1`` and ``MkT2`` are rejected because the lack of an outermost + ``forall`` triggers implicit quantification, making the explicit ``forall``s + nested. Furthermore, GADT constructors do not permit the use of nested + ``forall``s, as explained in :ref:`formal-gadt-syntax`. + + In addition to rejecting nested ``forall``s, GHC is now more stringent about + rejecting uses of nested *contexts* in GADT constructors. For example, the + following example, which previous versions of GHC would accept, is now + rejected: + + data U a where + MkU :: (Show a => U a) + Compiler ~~~~~~~~ ===================================== docs/users_guide/exts/explicit_forall.rst ===================================== @@ -45,4 +45,81 @@ Notes: would warn about the unused type variable `a`. +.. _forall-or-nothing: + +The ``forall``-or-nothing rule +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In certain forms of types, type variables obey what is known as the +"``forall``-or-nothing" rule: if a type has an outermost, explicit +``forall``, then all of the type variables in the type must be explicitly +quantified. These two examples illustrate how the rule works: :: + + f :: forall a b. a -> b -> b -- OK, `a` and `b` are explicitly bound + g :: forall a. a -> forall b. b -> b -- OK, `a` and `b` are explicitly bound + h :: forall a. a -> b -> b -- Rejected, `b` is not in scope + +The type signatures for ``f``, ``g``, and ``h`` all begin with an outermost +``forall``, so every type variable in these signatures must be explicitly +bound by a ``forall``. Both ``f`` and ``g`` obey the ``forall``-or-nothing +rule, since they explicitly quantify ``a`` and ``b``. On the other hand, +``h`` does not explicitly quantify ``b``, so GHC will reject its type +signature for being improperly scoped. + +In places where the ``forall``-or-nothing rule takes effect, if a type does +*not* have an outermost ``forall``, then any type variables that are not +explicitly bound by a ``forall`` become implicitly quantified. For example: :: + + i :: a -> b -> b -- `a` and `b` are implicitly quantified + j :: a -> forall b. b -> b -- `a` is implicitly quantified + k :: (forall a. a -> b -> b) -- `b` is implicitly quantified + +GHC will accept ``i``, ``j``, and ``k``'s type signatures. Note that: + +- ``j``'s signature is accepted despite its mixture of implicit and explicit + quantification. As long as a ``forall`` is not an outermost one, it is fine + to use it among implicitly bound type variables. +- ``k``'s signature is accepted because the outermost parentheses imply that + the ``forall`` is not an outermost ``forall``. The ``forall``-or-nothing + rule is one of the few places in GHC where the presence or absence of + parentheses can be semantically significant! + +The ``forall``-or-nothing rule takes effect in the following places: + +- Type signature declarations for functions, values, and class methods +- Expression type annotations +- Instance declarations +- :ref:`class-default-signatures` +- Type signatures in a :ref:`specialize-pragma` or + :ref:`specialize-instance-pragma` +- :ref:`standalone-kind-signatures` +- Type signatures for :ref:`gadt` constructors +- Type signatures for :ref:`pattern-synonyms` +- :ref:`data-instance-declarations`, :ref:`type-instance-declarations`, + :ref:`closed-type-families`, and :ref:`assoc-inst` +- :ref:`rewrite-rules` in which the type variables are explicitly quantified +Notes: + +- :ref:`pattern-type-sigs` are a notable example of a place where + types do *not* obey the ``forall``-or-nothing rule. For example, GHC will + accept the following: :: + + f (g :: forall a. a -> b) x = g x :: b + + Furthermore, :ref:`rewrite-rules` do not obey the ``forall``-or-nothing rule + when their type variables are not explicitly quantified: :: + + {-# RULES "f" forall (g :: forall a. a -> b) x. f g x = g x :: b #-} + +- GADT constructors are extra particular about their ``forall``s. In addition + to adhering to the ``forall``-or-nothing rule, GADT constructors also forbid + nested ``forall``s. For example, GHC would reject the following GADT: :: + + data T where + MkT :: (forall a. a -> b -> T) + + Because of the lack of an outermost ``forall`` in the type of ``MkT``, the + ``b`` would be implicitly quantified. In effect, it would be as if one had + written ``MkT :: forall b. (forall a. a -> b -> T)``, which contains nested + ``forall``s. See :ref:`formal-gadt-syntax`. ===================================== docs/users_guide/exts/gadt_syntax.rst ===================================== @@ -103,6 +103,123 @@ implements this behaviour, odd though it is. But for GADT-style declarations, GHC's behaviour is much more useful, as well as much more intuitive. +.. _formal-gadt-syntax: + +Formal syntax for GADTs +~~~~~~~~~~~~~~~~~~~~~~~ + +To make more precise what is and what is not permitted inside of a GADT-style +constructor, we provide a BNF-style grammar for GADT below. Note that this +grammar is subject to change in the future. :: + + gadt_con ::= conids '::' opt_forall opt_ctxt gadt_body + + conids ::= conid + | conid ',' conids + + opt_forall ::= + | 'forall' tv_bndrs '.' + + tv_bndrs ::= + | tv_bndr tv_bndrs + + tv_bndr ::= tyvar + | '(' tyvar '::' ctype ')' + + opt_ctxt ::= + | btype '=>' + | '(' ctxt ')' '=>' + + ctxt ::= ctype + | ctype ',' ctxt + + gadt_body ::= prefix_gadt_body + | record_gadt_body + + prefix_gadt_body ::= '(' prefix_gadt_body ')' + | return_type + | opt_unpack btype '->' prefix_gadt_body + + record_gadt_body ::= '{' fieldtypes '}' '->' return_type + + fieldtypes ::= + | fieldnames '::' opt_unpack ctype + | fieldnames '::' opt_unpack ctype ',' fieldtypes + + fieldnames ::= fieldname + | fieldname ',' fieldnames + + opt_unpack ::= opt_bang + : {-# UNPACK #-} opt_bang + | {-# NOUNPACK #-} opt_bang + + opt_bang ::= + | '!' + | '~' + +Where: + +- ``btype`` is a type that is not allowed to have an outermost + ``forall``/``=>`` unless it is surrounded by parentheses. For example, + ``forall a. a`` and ``Eq a => a`` are not legal ``btype``s, but + ``(forall a. a)`` and ``(Eq a => a)`` are legal. +- ``ctype`` is a ``btype`` that has no restrictions on an outermost + ``forall``/``=>``, so ``forall a. a`` and ``Eq a => a`` are legal ``ctype``s. +- ``return_type`` is a type that is not allowed to have ``forall``s, ``=>``s, + or ``->``s. + +This is a simplified grammar that does not fully delve into all of the +implementation details of GHC's parser (such as the placement of Haddock +comments), but it is sufficient to attain an understanding of what is +syntactically allowed. Some further various observations about this grammar: + +- GADT constructor types are currently not permitted to have nested ``forall``s + or ``=>``s. (e.g., something like ``MkT :: Int -> forall a. a -> T`` would be + rejected.) As a result, ``gadt_sig`` puts all of its quantification and + constraints up front with ``opt_forall`` and ``opt_context``. Note that + higher-rank ``forall``s and ``=>``s are only permitted if they do not appear + directly to the right of a function arrow in a `prefix_gadt_body`. (e.g., + something like ``MkS :: Int -> (forall a. a) -> S`` is allowed, since + parentheses separate the ``forall`` from the ``->``.) +- Furthermore, GADT constructors do not permit outermost parentheses that + surround the ``opt_forall`` or ``opt_ctxt``, if at least one of them are + used. For example, ``MkU :: (forall a. a -> U)`` would be rejected, since + it would treat the ``forall`` as being nested. + + Note that it is acceptable to use parentheses in a ``prefix_gadt_body``. + For instance, ``MkV1 :: forall a. (a) -> (V1)`` is acceptable, as is + ``MkV2 :: forall a. (a -> V2)``. +- The function arrows in a ``prefix_gadt_body``, as well as the function + arrow in a ``record_gadt_body``, are required to be used infix. For + example, ``MkA :: (->) Int A`` would be rejected. +- GHC uses the function arrows in a ``prefix_gadt_body`` and + ``prefix_gadt_body`` to syntactically demarcate the function and result + types. Note that GHC does not attempt to be clever about looking through + type synonyms here. If you attempt to do this, for instance: :: + + type C = Int -> B + + data B where + MkB :: C + + Then GHC will interpret the return type of ``MkB`` to be ``C``, and since + GHC requires that the return type must be headed by ``B``, this will be + rejected. On the other hand, it is acceptable to use type synonyms within + the argument and result types themselves, so the following is permitted: :: + + type B1 = Int + type B2 = B + + data B where + MkB :: B1 -> B2 +- GHC will accept any combination of ``!``/``~`` and + ``{-# UNPACK #-}``/``{-# NOUNPACK #-}``, although GHC will ignore some + combinations. For example, GHC will produce a warning if you write + ``{-# UNPACK #-} ~Int`` and proceed as if you had written ``Int``. + +GADT syntax odds and ends +~~~~~~~~~~~~~~~~~~~~~~~~~ + The rest of this section gives further details about GADT-style data type declarations. ===================================== testsuite/tests/dependent/should_fail/T16326_Fail6.stderr ===================================== @@ -1,7 +1,5 @@ -T16326_Fail6.hs:9:3: error: - • GADT constructor type signature cannot contain nested ‘forall’s or contexts - Suggestion: instead use this type signature: - MkFoo :: forall a. a -> Foo a - • In the definition of data constructor ‘MkFoo’ - In the data type declaration for ‘Foo’ +T16326_Fail6.hs:9:12: error: + Illegal visible, dependent quantification in the type of a term + (GHC does not yet support this) + In the definition of data constructor ‘MkFoo’ ===================================== testsuite/tests/gadt/T12087.stderr ===================================== @@ -1,35 +1,20 @@ -T12087.hs:6:3: error: - • GADT constructor type signature cannot contain nested ‘forall’s or contexts - Suggestion: instead use this type signature: - MkF1 :: forall a. (Ord a, Eq a) => a -> F1 a - • In the definition of data constructor ‘MkF1’ - In the data type declaration for ‘F1’ +T12087.hs:6:20: error: + GADT constructor type signature cannot contain nested ‘forall’s or contexts + In the definition of data constructor ‘MkF1’ -T12087.hs:9:3: error: - • GADT constructor type signature cannot contain nested ‘forall’s or contexts - Suggestion: instead use this type signature: - MkF2 :: forall a. (Ord a, Eq a) => a -> F2 a - • In the definition of data constructor ‘MkF2’ - In the data type declaration for ‘F2’ +T12087.hs:9:25: error: + GADT constructor type signature cannot contain nested ‘forall’s or contexts + In the definition of data constructor ‘MkF2’ -T12087.hs:12:3: error: - • GADT constructor type signature cannot contain nested ‘forall’s or contexts - Suggestion: instead use this type signature: - MkF3 :: forall a b. (Eq a, Eq b) => a -> b -> F3 a - • In the definition of data constructor ‘MkF3’ - In the data type declaration for ‘F3’ +T12087.hs:12:34: error: + GADT constructor type signature cannot contain nested ‘forall’s or contexts + In the definition of data constructor ‘MkF3’ -T12087.hs:15:3: error: - • GADT constructor type signature cannot contain nested ‘forall’s or contexts - Suggestion: instead use this type signature: - MkF4 :: forall a b. (Eq a, Eq b) => a -> b -> F4 a - • In the definition of data constructor ‘MkF4’ - In the data type declaration for ‘F4’ +T12087.hs:15:36: error: + GADT constructor type signature cannot contain nested ‘forall’s or contexts + In the definition of data constructor ‘MkF4’ -T12087.hs:18:3: error: - • GADT constructor type signature cannot contain nested ‘forall’s or contexts - Suggestion: instead use this type signature: - MkF5 :: forall a b. Int -> Int -> a -> Int -> Int -> b -> F5 a - • In the definition of data constructor ‘MkF5’ - In the data type declaration for ‘F5’ +T12087.hs:18:25: error: + GADT constructor type signature cannot contain nested ‘forall’s or contexts + In the definition of data constructor ‘MkF5’ ===================================== testsuite/tests/gadt/T14320.hs ===================================== @@ -10,8 +10,8 @@ data Exp :: Type where newtype TypedExp :: Type -> Type where TEGood :: forall a . (Exp -> (TypedExp a)) --- The only difference here is that the type is wrapped in parentheses, --- but GHC 8.0.1 rejects this program +-- The presence of outer parentheses makes the `forall` nested, and +-- GADTs do not permit nested `forall`s. -- newtype TypedExpToo :: Type -> Type where TEBad :: (forall a . (Exp -> (TypedExpToo a))) ===================================== testsuite/tests/gadt/T14320.stderr ===================================== @@ -0,0 +1,4 @@ + +T14320.hs:17:14: error: + GADT constructor type signature cannot contain nested ‘forall’s or contexts + In the definition of data constructor ‘TEBad’ ===================================== testsuite/tests/gadt/T16427.stderr ===================================== @@ -1,7 +1,4 @@ -T16427.hs:5:14: error: - • GADT constructor type signature cannot contain nested ‘forall’s or contexts - Suggestion: instead use this type signature: - C :: forall b. Int -> b -> D - • In the definition of data constructor ‘C’ - In the data type declaration for ‘D’ +T16427.hs:5:26: error: + GADT constructor type signature cannot contain nested ‘forall’s or contexts + In the definition of data constructor ‘C’ ===================================== testsuite/tests/gadt/T18191.hs ===================================== @@ -0,0 +1,12 @@ +{-# LANGUAGE GADTs #-} +{-# LANGUAGE RankNTypes #-} +module T18191 where + +data T where + MkT :: (forall a. a -> b -> T) + +data S a where + MkS :: (forall a. S a) + +data U a where + MkU :: (Show a => U a) ===================================== testsuite/tests/gadt/T18191.stderr ===================================== @@ -0,0 +1,12 @@ + +T18191.hs:6:11: error: + GADT constructor type signature cannot contain nested ‘forall’s or contexts + In the definition of data constructor ‘MkT’ + +T18191.hs:9:11: error: + GADT constructor type signature cannot contain nested ‘forall’s or contexts + In the definition of data constructor ‘MkS’ + +T18191.hs:12:11: error: + GADT constructor type signature cannot contain nested ‘forall’s or contexts + In the definition of data constructor ‘MkU’ ===================================== testsuite/tests/gadt/all.T ===================================== @@ -113,10 +113,11 @@ test('T7558', normal, compile_fail, ['']) test('T9380', normal, compile_and_run, ['']) test('T12087', normal, compile_fail, ['']) test('T12468', normal, compile_fail, ['']) -test('T14320', normal, compile, ['']) +test('T14320', normal, compile_fail, ['']) test('T14719', normal, compile_fail, ['-fdiagnostics-show-caret']) test('T14808', normal, compile, ['']) test('T15009', normal, compile, ['']) test('T15558', normal, compile, ['']) test('T16427', normal, compile_fail, ['']) test('T17423', expect_broken(17423), compile_and_run, ['']) +test('T18191', normal, compile_fail, ['']) ===================================== testsuite/tests/ghc-api/annotations/T10399.stdout ===================================== @@ -34,9 +34,9 @@ ((Test10399.hs:12:30,AnnComma), [Test10399.hs:12:30]), ((Test10399.hs:12:31-32,AnnCloseP), [Test10399.hs:12:32]), ((Test10399.hs:12:31-32,AnnOpenP), [Test10399.hs:12:31]), -((Test10399.hs:(14,1)-(18,55),AnnData), [Test10399.hs:14:1-4]), -((Test10399.hs:(14,1)-(18,55),AnnSemi), [Test10399.hs:20:1]), -((Test10399.hs:(14,1)-(18,55),AnnWhere), [Test10399.hs:14:21-25]), +((Test10399.hs:(14,1)-(18,53),AnnData), [Test10399.hs:14:1-4]), +((Test10399.hs:(14,1)-(18,53),AnnSemi), [Test10399.hs:20:1]), +((Test10399.hs:(14,1)-(18,53),AnnWhere), [Test10399.hs:14:21-25]), ((Test10399.hs:15:5-64,AnnDcolon), [Test10399.hs:15:11-12]), ((Test10399.hs:15:5-64,AnnSemi), [Test10399.hs:16:5]), ((Test10399.hs:15:14-64,AnnDot), [Test10399.hs:15:23]), @@ -48,37 +48,29 @@ ((Test10399.hs:15:45-46,AnnBang), [Test10399.hs:15:45]), ((Test10399.hs:15:45-46,AnnRarrow), [Test10399.hs:15:48-49]), ((Test10399.hs:15:45-64,AnnRarrow), [Test10399.hs:15:48-49]), -((Test10399.hs:(16,5)-(17,69),AnnCloseP), [Test10399.hs:17:69]), -((Test10399.hs:(16,5)-(17,69),AnnDcolon), [Test10399.hs:16:12-13]), -((Test10399.hs:(16,5)-(17,69),AnnOpenP), [Test10399.hs:16:27]), -((Test10399.hs:(16,5)-(17,69),AnnSemi), [Test10399.hs:18:5]), -((Test10399.hs:(16,15)-(17,69),AnnDot), [Test10399.hs:16:25]), -((Test10399.hs:(16,15)-(17,69),AnnForall), [Test10399.hs:16:15-20]), -((Test10399.hs:(16,27)-(17,69),AnnCloseP), [Test10399.hs:17:69]), -((Test10399.hs:(16,27)-(17,69),AnnOpenP), [Test10399.hs:16:27]), -((Test10399.hs:16:28-43,AnnCloseP), [Test10399.hs:16:43, Test10399.hs:16:43]), -((Test10399.hs:16:28-43,AnnDarrow), [Test10399.hs:16:45-46]), -((Test10399.hs:16:28-43,AnnOpenP), [Test10399.hs:16:28, Test10399.hs:16:28]), -((Test10399.hs:16:30-33,AnnComma), [Test10399.hs:16:34]), -((Test10399.hs:16:48,AnnRarrow), [Test10399.hs:16:50-51]), -((Test10399.hs:(16,48)-(17,68),AnnRarrow), [Test10399.hs:16:50-51]), -((Test10399.hs:16:53-66,AnnRarrow), [Test10399.hs:17:45-46]), -((Test10399.hs:(16,53)-(17,68),AnnRarrow), [Test10399.hs:17:45-46]), -((Test10399.hs:17:48,AnnRarrow), [Test10399.hs:17:50-51]), -((Test10399.hs:17:48-68,AnnRarrow), [Test10399.hs:17:50-51]), -((Test10399.hs:17:66-68,AnnCloseS), [Test10399.hs:17:68]), -((Test10399.hs:17:66-68,AnnOpenS), [Test10399.hs:17:66]), -((Test10399.hs:18:5-55,AnnCloseP), [Test10399.hs:18:55]), -((Test10399.hs:18:5-55,AnnDcolon), [Test10399.hs:18:16-17]), -((Test10399.hs:18:5-55,AnnOpenP), [Test10399.hs:18:19]), -((Test10399.hs:18:19-55,AnnCloseP), [Test10399.hs:18:55]), -((Test10399.hs:18:19-55,AnnOpenP), [Test10399.hs:18:19]), -((Test10399.hs:18:20-54,AnnDot), [Test10399.hs:18:29]), -((Test10399.hs:18:20-54,AnnForall), [Test10399.hs:18:20-25]), -((Test10399.hs:18:31-36,AnnCloseP), [Test10399.hs:18:36]), -((Test10399.hs:18:31-36,AnnOpenP), [Test10399.hs:18:31]), -((Test10399.hs:18:31-36,AnnRarrow), [Test10399.hs:18:38-39]), -((Test10399.hs:18:31-54,AnnRarrow), [Test10399.hs:18:38-39]), +((Test10399.hs:(16,5)-(17,67),AnnDcolon), [Test10399.hs:16:12-13]), +((Test10399.hs:(16,5)-(17,67),AnnSemi), [Test10399.hs:18:5]), +((Test10399.hs:(16,15)-(17,67),AnnDot), [Test10399.hs:16:25]), +((Test10399.hs:(16,15)-(17,67),AnnForall), [Test10399.hs:16:15-20]), +((Test10399.hs:16:27-42,AnnCloseP), [Test10399.hs:16:42, Test10399.hs:16:42]), +((Test10399.hs:16:27-42,AnnDarrow), [Test10399.hs:16:44-45]), +((Test10399.hs:16:27-42,AnnOpenP), [Test10399.hs:16:27, Test10399.hs:16:27]), +((Test10399.hs:16:29-32,AnnComma), [Test10399.hs:16:33]), +((Test10399.hs:16:47,AnnRarrow), [Test10399.hs:16:49-50]), +((Test10399.hs:(16,47)-(17,67),AnnRarrow), [Test10399.hs:16:49-50]), +((Test10399.hs:16:52-65,AnnRarrow), [Test10399.hs:17:44-45]), +((Test10399.hs:(16,52)-(17,67),AnnRarrow), [Test10399.hs:17:44-45]), +((Test10399.hs:17:47,AnnRarrow), [Test10399.hs:17:49-50]), +((Test10399.hs:17:47-67,AnnRarrow), [Test10399.hs:17:49-50]), +((Test10399.hs:17:65-67,AnnCloseS), [Test10399.hs:17:67]), +((Test10399.hs:17:65-67,AnnOpenS), [Test10399.hs:17:65]), +((Test10399.hs:18:5-53,AnnDcolon), [Test10399.hs:18:16-17]), +((Test10399.hs:18:19-53,AnnDot), [Test10399.hs:18:28]), +((Test10399.hs:18:19-53,AnnForall), [Test10399.hs:18:19-24]), +((Test10399.hs:18:30-35,AnnCloseP), [Test10399.hs:18:35]), +((Test10399.hs:18:30-35,AnnOpenP), [Test10399.hs:18:30]), +((Test10399.hs:18:30-35,AnnRarrow), [Test10399.hs:18:37-38]), +((Test10399.hs:18:30-53,AnnRarrow), [Test10399.hs:18:37-38]), ((Test10399.hs:20:1-25,AnnCloseQ), [Test10399.hs:20:24-25]), ((Test10399.hs:20:1-25,AnnOpen), [Test10399.hs:20:1-3]), ((Test10399.hs:20:1-25,AnnSemi), [Test10399.hs:22:1]), ===================================== testsuite/tests/ghc-api/annotations/Test10399.hs ===================================== @@ -13,9 +13,9 @@ mkPoli = mkBila . map ((,,(),,()) <$> P.base <*> P.pos <*> P.form) data MaybeDefault v where SetTo :: forall v . ( Eq v, Show v ) => !v -> MaybeDefault v - SetTo4 :: forall v a. (( Eq v, Show v ) => v -> MaybeDefault v - -> a -> MaybeDefault [a]) - TestParens :: (forall v . (Eq v) -> MaybeDefault v) + SetTo4 :: forall v a. ( Eq v, Show v ) => v -> MaybeDefault v + -> a -> MaybeDefault [a] + TestParens :: forall v . (Eq v) -> MaybeDefault v [t| Map.Map T.Text $tc |] ===================================== testsuite/tests/parser/should_compile/T15323.hs ===================================== @@ -3,4 +3,4 @@ module T15323 where data MaybeDefault v where - TestParens :: (forall v . (Eq v) => MaybeDefault v) + TestParens :: forall v . (Eq v) => MaybeDefault v ===================================== testsuite/tests/parser/should_compile/T15323.stderr ===================================== @@ -8,7 +8,7 @@ {ModuleName: T15323})) (Nothing) [] - [({ T15323.hs:(5,1)-(6,56) } + [({ T15323.hs:(5,1)-(6,54) } (TyClD (NoExtField) (DataDecl @@ -33,60 +33,60 @@ []) (Nothing) (Nothing) - [({ T15323.hs:6:5-56 } + [({ T15323.hs:6:5-54 } (ConDeclGADT (NoExtField) [({ T15323.hs:6:5-14 } (Unqual {OccName: TestParens}))] - ({ T15323.hs:6:21-55 } + ({ T15323.hs:6:20-54 } (True)) - [({ T15323.hs:6:28 } + [({ T15323.hs:6:27 } (UserTyVar (NoExtField) (SpecifiedSpec) - ({ T15323.hs:6:28 } + ({ T15323.hs:6:27 } (Unqual {OccName: v}))))] (Just - ({ T15323.hs:6:32-37 } - [({ T15323.hs:6:32-37 } + ({ T15323.hs:6:31-36 } + [({ T15323.hs:6:31-36 } (HsParTy (NoExtField) - ({ T15323.hs:6:33-36 } + ({ T15323.hs:6:32-35 } (HsAppTy (NoExtField) - ({ T15323.hs:6:33-34 } + ({ T15323.hs:6:32-33 } (HsTyVar (NoExtField) (NotPromoted) - ({ T15323.hs:6:33-34 } + ({ T15323.hs:6:32-33 } (Unqual {OccName: Eq})))) - ({ T15323.hs:6:36 } + ({ T15323.hs:6:35 } (HsTyVar (NoExtField) (NotPromoted) - ({ T15323.hs:6:36 } + ({ T15323.hs:6:35 } (Unqual {OccName: v}))))))))])) (PrefixCon []) - ({ T15323.hs:6:42-55 } + ({ T15323.hs:6:41-54 } (HsAppTy (NoExtField) - ({ T15323.hs:6:42-53 } + ({ T15323.hs:6:41-52 } (HsTyVar (NoExtField) (NotPromoted) - ({ T15323.hs:6:42-53 } + ({ T15323.hs:6:41-52 } (Unqual {OccName: MaybeDefault})))) - ({ T15323.hs:6:55 } + ({ T15323.hs:6:54 } (HsTyVar (NoExtField) (NotPromoted) - ({ T15323.hs:6:55 } + ({ T15323.hs:6:54 } (Unqual {OccName: v})))))) (Nothing)))] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/448cfdfb7c50463a092d35ea48c5b1a33eee3ba0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/448cfdfb7c50463a092d35ea48c5b1a33eee3ba0 You're receiving 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 26 14:03:08 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Tue, 26 May 2020 10:03:08 -0400 Subject: [Git][ghc/ghc][wip/bump-base] base: Bump to 4.15.0.0 Message-ID: <5ecd219c2dcd7_6e26c5c8abc16895de@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/bump-base at Glasgow Haskell Compiler / GHC Commits: 71d28d88 by Ben Gamari at 2020-05-26T10:03:00-04:00 base: Bump to 4.15.0.0 - - - - - 19 changed files: - compiler/ghc.cabal.in - libraries/array - libraries/base/base.cabal - libraries/deepseq - libraries/directory - libraries/filepath - libraries/ghc-boot-th/ghc-boot-th.cabal.in - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghc-compact/ghc-compact.cabal - libraries/ghci/ghci.cabal.in - libraries/haskeline - libraries/hpc - libraries/parsec - libraries/process - libraries/stm - libraries/template-haskell/template-haskell.cabal.in - libraries/terminfo - libraries/unix - utils/hsc2hs Changes: ===================================== compiler/ghc.cabal.in ===================================== @@ -59,7 +59,7 @@ Library Default-Language: Haskell2010 Exposed: False - Build-Depends: base >= 4.11 && < 4.15, + Build-Depends: base >= 4.11 && < 4.16, deepseq >= 1.4 && < 1.5, directory >= 1 && < 1.4, process >= 1 && < 1.7, ===================================== libraries/array ===================================== @@ -1 +1 @@ -Subproject commit f73f681e52546b1e35cb9e8a62fe49c33f259d98 +Subproject commit ab535173d7885ebfc2005d8da2765f0f52c923ce ===================================== 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 ===================================== libraries/deepseq ===================================== @@ -1 +1 @@ -Subproject commit da0eda33f540786b6823c6f542ab59cf9d1b71d9 +Subproject commit 13c1c84415da727ab56e9fa33aca5046b6683848 ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit 36bd1921258b759724a95ce56c5e880edf0972a2 +Subproject commit 0dcb228388a6e306c11f419c7c5575eaa6af40b3 ===================================== libraries/filepath ===================================== @@ -1 +1 @@ -Subproject commit 023eedaeb142d47b7b5a41fe4cc4150da0bd0042 +Subproject commit 7cb3dc285cd595a7b6cf0b74a58b6583fb67772e ===================================== libraries/ghc-boot-th/ghc-boot-th.cabal.in ===================================== @@ -36,4 +36,4 @@ Library GHC.ForeignSrcLang.Type GHC.Lexeme - build-depends: base >= 4.7 && < 4.15 + build-depends: base >= 4.7 && < 4.16 ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -55,7 +55,7 @@ Library -- GHC.Version -- GHC.Platform.Host - build-depends: base >= 4.7 && < 4.15, + build-depends: base >= 4.7 && < 4.16, binary == 0.8.*, bytestring == 0.10.*, containers >= 0.5 && < 0.7, ===================================== libraries/ghc-compact/ghc-compact.cabal ===================================== @@ -37,7 +37,7 @@ library CPP build-depends: ghc-prim >= 0.5.3 && < 0.7, - base >= 4.9.0 && < 4.15, + base >= 4.9.0 && < 4.16, bytestring >= 0.10.6.0 ghc-options: -Wall ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -72,7 +72,7 @@ library Build-Depends: array == 0.5.*, - base >= 4.8 && < 4.15, + base >= 4.8 && < 4.16, binary == 0.8.*, bytestring == 0.10.*, containers >= 0.5 && < 0.7, ===================================== libraries/haskeline ===================================== @@ -1 +1 @@ -Subproject commit 463fc49d17bfab846cceba48bccc02ef285e6cba +Subproject commit 0382e3acdb8433e1d9c33ca5947784e78134f838 ===================================== libraries/hpc ===================================== @@ -1 +1 @@ -Subproject commit f73c482db30a40cfa12074de51335b70a0974931 +Subproject commit 43bb9061a748aee6a95a9f1db33a2b1e5f770634 ===================================== libraries/parsec ===================================== @@ -1 +1 @@ -Subproject commit ce416997e15438ca616667995660e123ef7e219d +Subproject commit 190492494fe92e8dd42165190b7ac112be1f7389 ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit 1afc36ecd38c069251a836e1c1c8b3a3043ddc01 +Subproject commit 8f4ecebb6578a179a6c04074cb06600683e2e50c ===================================== libraries/stm ===================================== @@ -1 +1 @@ -Subproject commit faf9904137044e35a589c7c1579e1bfa03789c84 +Subproject commit 444f672416a354c3cfde9d94ec237a36be46ef59 ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -55,7 +55,7 @@ Library Language.Haskell.TH.Lib.Map build-depends: - base >= 4.11 && < 4.15, + base >= 4.11 && < 4.16, ghc-boot-th == @ProjectVersionMunged@, ghc-prim, pretty == 1.1.* ===================================== libraries/terminfo ===================================== @@ -1 +1 @@ -Subproject commit 27e694688d2d6eee69959a8b6a128c584c84aa72 +Subproject commit 3ebb36f4a2c42b74ec4e35efccc2be34c198a830 ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 1a993b89c570e03ba74f196f5d065a0ebe624010 +Subproject commit ea13d990580273a883368793dfbb826cab5a22d4 ===================================== utils/hsc2hs ===================================== @@ -1 +1 @@ -Subproject commit 24100ea521596922d3edc8370b3d9f7b845ae4cf +Subproject commit e792dd8e5589d42a4d416f78df8efb70995f95e3 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/71d28d88d03b9f86713c3007d6eeffb2d89a489c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/71d28d88d03b9f86713c3007d6eeffb2d89a489c You're receiving 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 26 15:44:26 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Tue, 26 May 2020 11:44:26 -0400 Subject: [Git][ghc/ghc][wip/T18232] 7 commits: Revert "Specify kind variables for inferred kinds in base." Message-ID: <5ecd395ad5b6_6e263f9f01f3c48017213d@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18232 at Glasgow Haskell Compiler / GHC Commits: 013d7120 by Ben Gamari at 2020-05-25T09:48:17-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. - - - - - 4c4312ed by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Drop redundant ad-hoc boot module check To determine whether the module is a boot module Coverage.addTicksToBinds was checking for a `boot` suffix in the module source filename. This is quite ad-hoc and shouldn't be necessary; the callsite in `deSugar` already checks that the module isn't a boot module. - - - - - 1abf3c84 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make tickBoxCount strict This could otherwise easily cause a leak of (+) thunks. - - - - - b2813750 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make ccIndices strict This just seems like a good idea. - - - - - 02e278eb by Ben Gamari at 2020-05-25T09:48:53-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. - - - - - b8c014ce by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Factor out addMixEntry - - - - - 2c27baff by Ben Gamari at 2020-05-26T11:44:14-04:00 Rip out CmmStackInfo(updfr_space) As noted in #18232, this field is currently completely unused and moreover doesn't have a clear meaning. - - - - - 27 changed files: - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/LayoutStack.hs - compiler/GHC/Cmm/Ppr.hs - compiler/GHC/Cmm/ProcPoint.hs - compiler/GHC/HsToCore/Coverage.hs - compiler/GHC/StgToCmm/Monad.hs - 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: ===================================== compiler/GHC/Cmm.hs ===================================== @@ -132,9 +132,6 @@ data CmmStackInfo -- number of bytes of arguments on the stack on entry to the -- the proc. This is filled in by GHC.StgToCmm.codeGen, and -- used by the stack allocator later. - updfr_space :: Maybe ByteOff, - -- XXX: this never contains anything useful, but it should. - -- See comment in GHC.Cmm.LayoutStack. do_layout :: Bool -- Do automatic stack layout for this proc. This is -- True for all code generated by the code generator, ===================================== compiler/GHC/Cmm/LayoutStack.hs ===================================== @@ -357,10 +357,9 @@ isGcJump _something_else = False -- This doesn't seem right somehow. We need to find out whether this -- proc will push some update frame material at some point, so that we --- can avoid using that area of the stack for spilling. The --- updfr_space field of the CmmProc *should* tell us, but it doesn't --- (I think maybe it gets filled in later when we do proc-point --- splitting). +-- can avoid using that area of the stack for spilling. Ideally we would +-- capture this information in the CmmProc (e.g. in CmmStackInfo; see #18232 +-- for details on one ill-fated attempt at this). -- -- So we'll just take the max of all the cml_ret_offs. This could be -- unnecessarily pessimistic, but probably not in the code we ===================================== compiler/GHC/Cmm/Ppr.hs ===================================== @@ -103,9 +103,8 @@ instance Outputable CmmGraph where -- Outputting types Cmm contains pprStackInfo :: CmmStackInfo -> SDoc -pprStackInfo (StackInfo {arg_space=arg_space, updfr_space=updfr_space}) = - text "arg_space: " <> ppr arg_space <+> - text "updfr_space: " <> ppr updfr_space +pprStackInfo (StackInfo {arg_space=arg_space}) = + text "arg_space: " <> ppr arg_space pprTopInfo :: CmmTopInfo -> SDoc pprTopInfo (TopInfo {info_tbls=info_tbl, stack_info=stack_info}) = ===================================== compiler/GHC/Cmm/ProcPoint.hs ===================================== @@ -356,7 +356,6 @@ splitAtProcPoints dflags entry_label callPPs procPoints procMap g' = replacePPIds g live = ppLiveness (g_entry g') stack_info = StackInfo { arg_space = 0 - , updfr_space = Nothing , do_layout = True } -- cannot use panic, this is printed by -ddump-cmm ===================================== compiler/GHC/HsToCore/Coverage.hs ===================================== @@ -78,8 +78,7 @@ addTicksToBinds addTicksToBinds hsc_env mod mod_loc exports tyCons binds | let dflags = hsc_dflags hsc_env passes = coveragePasses dflags, not (null passes), - Just orig_file <- ml_hs_file mod_loc, - not ("boot" `isSuffixOf` orig_file) = do + Just orig_file <- ml_hs_file mod_loc = do let orig_file2 = guessSourceFile binds orig_file @@ -118,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) @@ -135,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_] @@ -1004,11 +1003,20 @@ addTickArithSeqInfo (FromThenTo e1 e2 e3) = (addTickLHsExpr e2) (addTickLHsExpr e3) -data TickTransState = TT { tickBoxCount:: Int +data TickTransState = TT { tickBoxCount:: !Int , mixEntries :: [MixEntry_] - , ccIndices :: CostCentreState + , 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 @@ -1028,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 $ @@ -1036,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. @@ -1202,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 @@ -1215,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 @@ -1240,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 _) ===================================== compiler/GHC/StgToCmm/Monad.hs ===================================== @@ -772,7 +772,6 @@ emitProc mb_info lbl live blocks offset do_layout | otherwise = mapEmpty sinfo = StackInfo { arg_space = offset - , updfr_space = Just (initUpdFrameOff platform) , do_layout = do_layout } tinfo = TopInfo { info_tbls = infos ===================================== 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 #-} @@ -759,8 +757,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 @@ -775,8 +772,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 ) @@ -827,8 +823,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 @@ -856,8 +851,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 @@ -887,8 +881,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 @@ -929,9 +922,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 @@ -943,8 +935,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 @@ -956,8 +947,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 @@ -998,9 +988,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 @@ -1031,7 +1020,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#' @@ -1105,46 +1093,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 @@ -1155,27 +1134,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] @@ -1200,9 +1167,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] @@ -1342,9 +1306,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] @@ -1397,7 +1358,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 @@ -1530,16 +1490,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 @@ -1547,7 +1501,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/-/compare/45223d7b1e312b61bfe3a3f885bcc334d2622529...2c27baff0fad102fd2bbbac40e170ccc89cd5153 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/45223d7b1e312b61bfe3a3f885bcc334d2622529...2c27baff0fad102fd2bbbac40e170ccc89cd5153 You're receiving 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 26 16:43:19 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 26 May 2020 12:43:19 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: Add info about typeclass evidence to .hie files Message-ID: <5ecd472724ddf_6e26c5c8abc1743118@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 53814a64 by Zubin Duggal at 2020-05-26T03:03:24-04:00 Add info about typeclass evidence to .hie files See `testsuite/tests/hiefile/should_run/HieQueries.hs` and `testsuite/tests/hiefile/should_run/HieQueries.stdout` for an example of this We add two new fields, `EvidenceVarBind` and `EvidenceVarUse` to the `ContextInfo` associated with an Identifier. These are associated with the appropriate identifiers for the evidence variables collected when we come across `HsWrappers`, `TcEvBinds` and `IPBinds` while traversing the AST. Instance dictionary and superclass selector dictionaries from `tcg_insts` and classes defined in `tcg_tcs` are also recorded in the AST as originating from their definition span This allows us to save a complete picture of the evidence constructed by the constraint solver, and will let us report this to the user, enabling features like going to the instance definition from the invocation of a class method(or any other method taking a constraint) and finding all usages of a particular instance. Additionally, - Mark NodeInfo with an origin so we can differentiate between bindings origininating in the source vs those in ghc - Along with typeclass evidence info, also include information on Implicit Parameters - Add a few utility functions to HieUtils in order to query the new info Updates haddock submodule - - - - - 6604906c by Sebastian Graf at 2020-05-26T03:04:04-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. - - - - - cf772f19 by Sylvain Henry at 2020-05-26T03:04:45-04:00 Enhance Note [About units] for Backpack - - - - - 089f58b5 by Takenobu Tani at 2020-05-26T12:43:02-04:00 core-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Core.hs <= coreSyn/CoreSyn.hs * GHC/Core/Coercion.hs <= types/Coercion.hs * GHC/Core/Coercion/Axiom.hs <= types/CoAxiom.hs * GHC/Core/Coercion/Opt.hs <= types/OptCoercion.hs * GHC/Core/DataCon.hs <= basicTypes/DataCon.hs * GHC/Core/FamInstEnv.hs <= types/FamInstEnv.hs * GHC/Core/Lint.hs <= coreSyn/CoreLint.hs * GHC/Core/Subst.hs <= coreSyn/CoreSubst.hs * GHC/Core/TyCo/Rep.hs <= types/TyCoRep.hs * GHC/Core/TyCon.hs <= types/TyCon.hs * GHC/Core/Type.hs <= types/Type.hs * GHC/Core/Unify.hs <= types/Unify.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/Var.hs <= basicTypes/Var.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [skip ci] - - - - - d293975d by Joshua Price at 2020-05-26T12:43:04-04:00 Make `identifier` parse unparenthesized `->` (#18060) - - - - - 28 changed files: - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Debug.hs - compiler/GHC/Iface/Ext/Types.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Parser.y - compiler/GHC/Unit.hs - docs/core-spec/CoreLint.ott - docs/core-spec/CoreSyn.ott - docs/core-spec/README - docs/core-spec/core-spec.mng - docs/core-spec/core-spec.pdf - docs/users_guide/using-optimisation.rst - + testsuite/tests/ghci/T18060/T18060.script - + testsuite/tests/ghci/T18060/T18060.stdout - + testsuite/tests/ghci/T18060/all.T - testsuite/tests/hiefile/should_compile/Scopes.hs - + testsuite/tests/hiefile/should_run/HieQueries.hs - + testsuite/tests/hiefile/should_run/HieQueries.stdout - testsuite/tests/hiefile/should_run/PatTypes.hs - testsuite/tests/hiefile/should_run/all.T - + testsuite/tests/stranal/should_compile/T18122.hs - + testsuite/tests/stranal/should_compile/T18122.stderr - testsuite/tests/stranal/should_compile/all.T - utils/haddock 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 ===================================== @@ -1034,7 +1034,7 @@ 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 +cf Note [Tick annotations in call patterns] in GHC.Core.Opt.SpecConstr Note [Matching lets] ~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -13,36 +13,47 @@ Main functions for .hie file generation {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE DeriveDataTypeable #-} +{-# LANGUAGE TupleSections #-} {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} module GHC.Iface.Ext.Ast ( mkHieFile, mkHieFileWithSource, getCompressedAsts) where +import GHC.Utils.Outputable(ppr) + import GHC.Prelude import GHC.Types.Avail ( Avails ) import GHC.Data.Bag ( Bag, bagToList ) import GHC.Types.Basic import GHC.Data.BooleanFormula -import GHC.Core.Class ( FunDep ) +import GHC.Core.Class ( FunDep, className, classSCSelIds ) import GHC.Core.Utils ( exprType ) import GHC.Core.ConLike ( conLikeName ) +import GHC.Core.TyCon ( TyCon, tyConClass_maybe ) +import GHC.Core.FVs import GHC.HsToCore ( deSugarExpr ) import GHC.Types.FieldLabel import GHC.Hs import GHC.Driver.Types import GHC.Unit.Module ( ModuleName, ml_hs_file ) import GHC.Utils.Monad ( concatMapM, liftIO ) -import GHC.Types.Name ( Name, nameSrcSpan, setNameLoc ) +import GHC.Types.Name ( Name, nameSrcSpan, setNameLoc, nameUnique ) import GHC.Types.Name.Env ( NameEnv, emptyNameEnv, extendNameEnv, lookupNameEnv ) import GHC.Types.SrcLoc import GHC.Tc.Utils.Zonk ( hsLitType, hsPatType ) import GHC.Core.Type ( mkVisFunTys, Type ) +import GHC.Core.Predicate +import GHC.Core.InstEnv import GHC.Builtin.Types ( mkListTy, mkSumTy ) -import GHC.Types.Var ( Id, Var, setVarName, varName, varType ) import GHC.Tc.Types +import GHC.Tc.Types.Evidence +import GHC.Types.Var ( Id, Var, EvId, setVarName, varName, varType, varUnique ) +import GHC.Types.Var.Env +import GHC.Types.Unique import GHC.Iface.Make ( mkIfaceExports ) import GHC.Utils.Panic import GHC.Data.Maybe +import GHC.Data.FastString import GHC.Iface.Ext.Types import GHC.Iface.Ext.Utils @@ -53,6 +64,8 @@ import qualified Data.Map as M import qualified Data.Set as S import Data.Data ( Data, Typeable ) import Data.List ( foldl1' ) +import Control.Monad ( forM_ ) +import Control.Monad.Trans.State.Strict import Control.Monad.Trans.Reader import Control.Monad.Trans.Class ( lift ) @@ -196,12 +209,47 @@ The Typechecker introduces new names for mono names in AbsBinds. We don't care about the distinction between mono and poly bindings, so we replace all occurrences of the mono name with the poly name. -} -newtype HieState = HieState +type VarMap a = DVarEnv (Var,a) +data HieState = HieState { name_remapping :: NameEnv Id + , unlocated_ev_binds :: VarMap (S.Set ContextInfo) + -- These contain evidence bindings that we don't have a location for + -- These are placed at the top level Node in the HieAST after everything + -- else has been generated + -- This includes things like top level evidence bindings. } +addUnlocatedEvBind :: Var -> ContextInfo -> HieM () +addUnlocatedEvBind var ci = do + let go (a,b) (_,c) = (a,S.union b c) + lift $ modify' $ \s -> + s { unlocated_ev_binds = + extendDVarEnv_C go (unlocated_ev_binds s) + var (var,S.singleton ci) + } + +getUnlocatedEvBinds :: FastString -> HieM (NodeIdentifiers Type,[HieAST Type]) +getUnlocatedEvBinds file = do + binds <- lift $ gets unlocated_ev_binds + org <- ask + let elts = dVarEnvElts binds + + mkNodeInfo (n,ci) = (Right (varName n), IdentifierDetails (Just $ varType n) ci) + + go e@(v,_) (xs,ys) = case nameSrcSpan $ varName v of + RealSrcSpan spn _ + | srcSpanFile spn == file -> + let node = Node (mkSourcedNodeInfo org ni) spn [] + ni = NodeInfo mempty [] $ M.fromList [mkNodeInfo e] + in (xs,node:ys) + _ -> (mkNodeInfo e : xs,ys) + + (nis,asts) = foldr go ([],[]) elts + + pure $ (M.fromList nis, asts) + initState :: HieState -initState = HieState emptyNameEnv +initState = HieState emptyNameEnv emptyDVarEnv class ModifyState a where -- See Note [Name Remapping] addSubstitution :: a -> a -> HieState -> HieState @@ -216,10 +264,11 @@ instance ModifyState Id where modifyState :: ModifyState (IdP p) => [ABExport p] -> HieState -> HieState modifyState = foldr go id where - go ABE{abe_poly=poly,abe_mono=mono} f = addSubstitution mono poly . f + go ABE{abe_poly=poly,abe_mono=mono} f + = addSubstitution mono poly . f go _ f = f -type HieM = ReaderT HieState Hsc +type HieM = ReaderT NodeOrigin (StateT HieState Hsc) -- | Construct an 'HieFile' from the outputs of the typechecker. mkHieFile :: ModSummary @@ -239,7 +288,10 @@ mkHieFileWithSource :: FilePath -> RenamedSource -> Hsc HieFile mkHieFileWithSource src_file src ms ts rs = do let tc_binds = tcg_binds ts - (asts', arr) <- getCompressedAsts tc_binds rs + top_ev_binds = tcg_ev_binds ts + insts = tcg_insts ts + tcs = tcg_tcs ts + (asts', arr) <- getCompressedAsts tc_binds rs top_ev_binds insts tcs return $ HieFile { hie_hs_file = src_file , hie_module = ms_mod ms @@ -250,38 +302,70 @@ mkHieFileWithSource src_file src ms ts rs = do , hie_hs_src = src } -getCompressedAsts :: TypecheckedSource -> RenamedSource +getCompressedAsts :: TypecheckedSource -> RenamedSource -> Bag EvBind -> [ClsInst] -> [TyCon] -> Hsc (HieASTs TypeIndex, A.Array TypeIndex HieTypeFlat) -getCompressedAsts ts rs = do - asts <- enrichHie ts rs +getCompressedAsts ts rs top_ev_binds insts tcs = do + asts <- enrichHie ts rs top_ev_binds insts tcs return $ compressTypes asts -enrichHie :: TypecheckedSource -> RenamedSource -> Hsc (HieASTs Type) -enrichHie ts (hsGrp, imports, exports, _) = flip runReaderT initState $ do +enrichHie :: TypecheckedSource -> RenamedSource -> Bag EvBind -> [ClsInst] -> [TyCon] + -> Hsc (HieASTs Type) +enrichHie ts (hsGrp, imports, exports, _) ev_bs insts tcs = + flip evalStateT initState $ flip runReaderT SourceInfo $ do tasts <- toHie $ fmap (BC RegularBind ModuleScope) ts rasts <- processGrp hsGrp imps <- toHie $ filter (not . ideclImplicit . unLoc) imports exps <- toHie $ fmap (map $ IEC Export . fst) exports - let spanFile children = case children of - [] -> mkRealSrcSpan (mkRealSrcLoc "" 1 1) (mkRealSrcLoc "" 1 1) + -- Add Instance bindings + forM_ insts $ \i -> + addUnlocatedEvBind (is_dfun i) (EvidenceVarBind (EvInstBind False (is_cls_nm i)) ModuleScope Nothing) + -- Add class parent bindings + forM_ tcs $ \tc -> + case tyConClass_maybe tc of + Nothing -> pure () + Just c -> forM_ (classSCSelIds c) $ \v -> + addUnlocatedEvBind v (EvidenceVarBind (EvInstBind True (className c)) ModuleScope Nothing) + let spanFile file children = case children of + [] -> realSrcLocSpan (mkRealSrcLoc file 1 1) _ -> mkRealSrcSpan (realSrcSpanStart $ nodeSpan $ head children) (realSrcSpanEnd $ nodeSpan $ last children) - modulify xs = - Node (simpleNodeInfo "Module" "Module") (spanFile xs) xs - - asts = HieASTs - $ resolveTyVarScopes - $ M.map (modulify . mergeSortAsts) - $ M.fromListWith (++) - $ map (\x -> (srcSpanFile (nodeSpan x),[x])) flat_asts - flat_asts = concat [ tasts , rasts , imps , exps ] + + modulify file xs' = do + + top_ev_asts <- + toHie $ EvBindContext ModuleScope Nothing + $ L (RealSrcSpan (realSrcLocSpan $ mkRealSrcLoc file 1 1) Nothing) + $ EvBinds ev_bs + + (uloc_evs,more_ev_asts) <- getUnlocatedEvBinds file + + let xs = mergeSortAsts $ xs' ++ top_ev_asts ++ more_ev_asts + span = spanFile file xs + + moduleInfo = SourcedNodeInfo + $ M.singleton SourceInfo + $ (simpleNodeInfo "Module" "Module") + {nodeIdentifiers = uloc_evs} + + moduleNode = Node moduleInfo span [] + + case mergeSortAsts $ moduleNode : xs of + [x] -> return x + xs -> panicDoc "enrichHie: mergeSortAsts returned more than one result" (ppr $ map nodeSpan xs) + + asts' <- sequence + $ M.mapWithKey modulify + $ M.fromListWith (++) + $ map (\x -> (srcSpanFile (nodeSpan x),[x])) flat_asts + + let asts = HieASTs $ resolveTyVarScopes asts' return asts where processGrp grp = concatM @@ -305,13 +389,16 @@ grhss_span :: GRHSs p body -> SrcSpan grhss_span (GRHSs _ xs bs) = foldl' combineSrcSpans (getLoc bs) (map getLoc xs) grhss_span (XGRHSs _) = panic "XGRHS has no span" -bindingsOnly :: [Context Name] -> [HieAST a] -bindingsOnly [] = [] -bindingsOnly (C c n : xs) = case nameSrcSpan n of - RealSrcSpan span _ -> Node nodeinfo span [] : bindingsOnly xs - where nodeinfo = NodeInfo S.empty [] (M.singleton (Right n) info) - info = mempty{identInfo = S.singleton c} - _ -> bindingsOnly xs +bindingsOnly :: [Context Name] -> HieM [HieAST a] +bindingsOnly [] = pure [] +bindingsOnly (C c n : xs) = do + org <- ask + rest <- bindingsOnly xs + pure $ case nameSrcSpan n of + RealSrcSpan span _ -> Node (mkSourcedNodeInfo org nodeinfo) span [] : rest + where nodeinfo = NodeInfo S.empty [] (M.singleton (Right n) info) + info = mempty{identInfo = S.singleton c} + _ -> rest concatM :: Monad m => [m [a]] -> m [a] concatM xs = concat <$> sequence xs @@ -345,6 +432,8 @@ data SigInfo = SI SigType (Maybe Span) data SigType = BindSig | ClassSig | InstSig +data EvBindContext a = EvBindContext Scope (Maybe Span) a + data RScoped a = RS Scope a -- ^ Scope spans over everything to the right of a, (mostly) not -- including a itself @@ -502,8 +591,9 @@ instance ToHie (TScoped NoExtField) where toHie _ = pure [] instance ToHie (IEContext (Located ModuleName)) where - toHie (IEC c (L (RealSrcSpan span _) mname)) = - pure $ [Node (NodeInfo S.empty [] idents) span []] + toHie (IEC c (L (RealSrcSpan span _) mname)) = do + org <- ask + pure $ [Node (mkSourcedNodeInfo org $ NodeInfo S.empty [] idents) span []] where details = mempty{identInfo = S.singleton (IEThing c)} idents = M.singleton (Left mname) details toHie _ = pure [] @@ -511,38 +601,90 @@ instance ToHie (IEContext (Located ModuleName)) where instance ToHie (Context (Located Var)) where toHie c = case c of C context (L (RealSrcSpan span _) name') - -> do - m <- asks name_remapping - let name = case lookupNameEnv m (varName name') of - Just var -> var - Nothing-> name' - pure - [Node - (NodeInfo S.empty [] $ - M.singleton (Right $ varName name) - (IdentifierDetails (Just $ varType name') - (S.singleton context))) - span - []] + | varUnique name' == mkBuiltinUnique 1 -> pure [] + -- `mkOneRecordSelector` makes a field var using this unique, which we ignore + | otherwise -> do + m <- lift $ gets name_remapping + org <- ask + let name = case lookupNameEnv m (varName name') of + Just var -> var + Nothing-> name' + pure + [Node + (mkSourcedNodeInfo org $ NodeInfo S.empty [] $ + M.singleton (Right $ varName name) + (IdentifierDetails (Just $ varType name') + (S.singleton context))) + span + []] + C (EvidenceVarBind i _ sp) (L _ name) -> do + addUnlocatedEvBind name (EvidenceVarBind i ModuleScope sp) + pure [] _ -> pure [] instance ToHie (Context (Located Name)) where toHie c = case c of - C context (L (RealSrcSpan span _) name') -> do - m <- asks name_remapping - let name = case lookupNameEnv m name' of - Just var -> varName var - Nothing -> name' - pure - [Node - (NodeInfo S.empty [] $ - M.singleton (Right name) - (IdentifierDetails Nothing - (S.singleton context))) - span - []] + C context (L (RealSrcSpan span _) name') + | nameUnique name' == mkBuiltinUnique 1 -> pure [] + -- `mkOneRecordSelector` makes a field var using this unique, which we ignore + | otherwise -> do + m <- lift $ gets name_remapping + org <- ask + let name = case lookupNameEnv m name' of + Just var -> varName var + Nothing -> name' + pure + [Node + (mkSourcedNodeInfo org $ NodeInfo S.empty [] $ + M.singleton (Right name) + (IdentifierDetails Nothing + (S.singleton context))) + span + []] _ -> pure [] +evVarsOfTermList :: EvTerm -> [EvId] +evVarsOfTermList (EvExpr e) = exprSomeFreeVarsList isEvVar e +evVarsOfTermList (EvTypeable _ ev) = + case ev of + EvTypeableTyCon _ e -> concatMap evVarsOfTermList e + EvTypeableTyApp e1 e2 -> concatMap evVarsOfTermList [e1,e2] + EvTypeableTrFun e1 e2 -> concatMap evVarsOfTermList [e1,e2] + EvTypeableTyLit e -> evVarsOfTermList e +evVarsOfTermList (EvFun{}) = [] + +instance ToHie (EvBindContext (Located TcEvBinds)) where + toHie (EvBindContext sc sp (L span (EvBinds bs))) + = concatMapM go $ bagToList bs + where + go evbind = do + let evDeps = evVarsOfTermList $ eb_rhs evbind + depNames = EvBindDeps $ map varName evDeps + concatM $ + [ toHie (C (EvidenceVarBind (EvLetBind depNames) (combineScopes sc (mkScope span)) sp) + (L span $ eb_lhs evbind)) + , toHie $ map (C EvidenceVarUse . L span) $ evDeps + ] + toHie _ = pure [] + +instance ToHie (EvBindContext (Located NoExtField)) where + toHie _ = pure [] + +instance ToHie (Located HsWrapper) where + toHie (L osp wrap) + = case wrap of + (WpLet bs) -> toHie $ EvBindContext (mkScope osp) (getRealSpan osp) (L osp bs) + (WpCompose a b) -> concatM $ + [toHie (L osp a), toHie (L osp b)] + (WpFun a b _ _) -> concatM $ + [toHie (L osp a), toHie (L osp b)] + (WpEvLam a) -> + toHie $ C (EvidenceVarBind EvWrapperBind (mkScope osp) (getRealSpan osp)) + $ L osp a + (WpEvApp a) -> + concatMapM (toHie . C EvidenceVarUse . L osp) $ evVarsOfTermList a + _ -> pure [] + -- | Dummy instances - never called instance ToHie (TScoped (LHsSigWcType GhcTc)) where toHie _ = pure [] @@ -586,7 +728,7 @@ instance HasType (LHsExpr GhcRn) where -- -- See #16233 instance HasType (LHsExpr GhcTc) where - getTypeNode e@(L spn e') = lift $ + getTypeNode e@(L spn e') = -- Some expression forms have their type immediately available let tyOpt = case e' of HsLit _ l -> Just (hsLitType l) @@ -609,7 +751,7 @@ instance HasType (LHsExpr GhcTc) where Nothing | skipDesugaring e' -> fallback | otherwise -> do - hs_env <- Hsc $ \e w -> return (e,w) + hs_env <- lift $ lift $ Hsc $ \e w -> return (e,w) (_,mbe) <- liftIO $ deSugarExpr hs_env e maybe fallback (makeTypeNode e' spn . exprType) mbe where @@ -634,21 +776,25 @@ instance HasType (LHsExpr GhcTc) where XExpr (HsWrap{}) -> False _ -> True -instance ( ToHie (Context (Located (IdP a))) - , ToHie (MatchGroup a (LHsExpr a)) - , ToHie (PScoped (LPat a)) - , ToHie (GRHSs a (LHsExpr a)) - , ToHie (LHsExpr a) - , ToHie (Located (PatSynBind a a)) - , HasType (LHsBind a) - , ModifyState (IdP a) - , Data (HsBind a) - ) => ToHie (BindContext (LHsBind a)) where +instance ( ToHie (Context (Located (IdP (GhcPass a)))) + , ToHie (MatchGroup (GhcPass a) (LHsExpr (GhcPass a))) + , ToHie (PScoped (LPat (GhcPass a))) + , ToHie (GRHSs (GhcPass a) (LHsExpr (GhcPass a))) + , ToHie (LHsExpr (GhcPass a)) + , ToHie (Located (PatSynBind (GhcPass a) (GhcPass a))) + , HasType (LHsBind (GhcPass a)) + , ModifyState (IdP (GhcPass a)) + , Data (HsBind (GhcPass a)) + , IsPass a + ) => ToHie (BindContext (LHsBind (GhcPass a))) where toHie (BC context scope b@(L span bind)) = concatM $ getTypeNode b : case bind of - FunBind{fun_id = name, fun_matches = matches} -> + FunBind{fun_id = name, fun_matches = matches, fun_ext = wrap} -> [ toHie $ C (ValBind context scope $ getRealSpan span) name , toHie matches + , case ghcPass @a of + GhcTc -> toHie $ L span wrap + _ -> pure [] ] PatBind{pat_lhs = lhs, pat_rhs = rhs} -> [ toHie $ PS (getRealSpan span) scope NoScope lhs @@ -657,39 +803,55 @@ instance ( ToHie (Context (Located (IdP a))) VarBind{var_rhs = expr} -> [ toHie expr ] - AbsBinds{abs_exports = xs, abs_binds = binds} -> - [ local (modifyState xs) $ -- Note [Name Remapping] - toHie $ fmap (BC context scope) binds + AbsBinds{ abs_exports = xs, abs_binds = binds + , abs_ev_binds = ev_binds + , abs_ev_vars = ev_vars } -> + [ lift (modify (modifyState xs)) >> -- Note [Name Remapping] + (toHie $ fmap (BC context scope) binds) + , toHie $ map (L span . abe_wrap) xs + , toHie $ + map (EvBindContext (mkScope span) (getRealSpan span) + . L span) ev_binds + , toHie $ + map (C (EvidenceVarBind EvSigBind + (mkScope span) + (getRealSpan span)) + . L span) ev_vars ] PatSynBind _ psb -> [ toHie $ L span psb -- PatSynBinds only occur at the top level ] - XHsBindsLR _ -> [] instance ( ToHie (LMatch a body) ) => ToHie (MatchGroup a body) where - toHie mg = concatM $ case mg of - MG{ mg_alts = (L span alts) , mg_origin = FromSource } -> - [ pure $ locOnly span - , toHie alts - ] - MG{} -> [] - XMatchGroup _ -> [] + toHie mg = case mg of + MG{ mg_alts = (L span alts) , mg_origin = origin} -> + local (setOrigin origin) $ concatM + [ locOnly span + , toHie alts + ] + XMatchGroup _ -> pure [] + +setOrigin :: Origin -> NodeOrigin -> NodeOrigin +setOrigin FromSource _ = SourceInfo +setOrigin Generated _ = GeneratedInfo instance ( ToHie (Context (Located (IdP a))) , ToHie (PScoped (LPat a)) , ToHie (HsPatSynDir a) + , (a ~ GhcPass p) ) => ToHie (Located (PatSynBind a a)) where toHie (L sp psb) = concatM $ case psb of PSB{psb_id=var, psb_args=dets, psb_def=pat, psb_dir=dir} -> [ toHie $ C (Decl PatSynDec $ getRealSpan sp) var , toHie $ toBind dets - , toHie $ PS Nothing lhsScope NoScope pat + , toHie $ PS Nothing lhsScope patScope pat , toHie dir ] where lhsScope = combineScopes varScope detScope varScope = mkLScope var + patScope = mkScope $ getLoc pat detScope = case dets of (PrefixCon args) -> foldr combineScopes NoScope $ map mkLScope args (InfixCon a b) -> combineScopes (mkLScope a) (mkLScope b) @@ -702,7 +864,6 @@ instance ( ToHie (Context (Located (IdP a))) toBind (PrefixCon args) = PrefixCon $ map (C Use) args toBind (InfixCon a b) = InfixCon (C Use a) (C Use b) toBind (RecCon r) = RecCon $ map (PSC detSpan) r - XPatSynBind _ -> [] instance ( ToHie (MatchGroup a (LHsExpr a)) ) => ToHie (HsPatSynDir a) where @@ -780,12 +941,24 @@ instance ( a ~ GhcPass p SumPat _ pat _ _ -> [ toHie $ PS rsp scope pscope pat ] - ConPat {pat_con = con, pat_args = dets}-> + ConPat {pat_con = con, pat_args = dets, pat_con_ext = ext}-> [ case ghcPass @p of GhcPs -> toHie $ C Use $ con GhcRn -> toHie $ C Use $ con GhcTc -> toHie $ C Use $ fmap conLikeName con , toHie $ contextify dets + , case ghcPass @p of + GhcTc -> + let ev_binds = cpt_binds ext + ev_vars = cpt_dicts ext + wrap = cpt_wrap ext + evscope = mkScope ospan `combineScopes` scope `combineScopes` pscope + in concatM [ toHie $ EvBindContext scope rsp $ L ospan ev_binds + , toHie $ L ospan wrap + , toHie $ map (C (EvidenceVarBind EvPatternBind evscope rsp) + . L ospan) ev_vars + ] + _ -> pure [] ] ViewPat _ expr pat -> [ toHie expr @@ -816,10 +989,12 @@ instance ( a ~ GhcPass p GhcPs -> noExtCon e GhcRn -> noExtCon e #endif - GhcTc -> [] + GhcTc -> + [ toHie $ L ospan wrap + , toHie $ PS rsp scope pscope $ (L ospan pat :: LPat a) + ] where - -- Make sure we get an error if this changes - _noWarn@(CoPat _ _ _) = e + CoPat wrap pat _ = e where contextify (PrefixCon args) = PrefixCon $ patScopes rsp scope pscope args contextify (InfixCon a b) = InfixCon a' b' @@ -833,7 +1008,7 @@ instance ( a ~ GhcPass p 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) + [ bindingsOnly $ map (C $ TyVarBind (mkScope span) sc) (wcs++tvs) , toHie body ] -- See Note [Scoping Rules for SigPat] @@ -850,15 +1025,14 @@ instance ( ToHie body XGRHSs _ -> [] instance ( ToHie (Located body) - , ToHie (RScoped (GuardLStmt a)) - , Data (GRHS a (Located body)) - ) => ToHie (LGRHS a (Located body)) where + , ToHie (RScoped (GuardLStmt (GhcPass a))) + , Data (GRHS (GhcPass a) (Located body)) + ) => ToHie (LGRHS (GhcPass a) (Located body)) where toHie (L span g) = concatM $ makeNode g span : case g of GRHS _ guards body -> [ toHie $ listScopes (mkLScope body) guards , toHie body ] - XGRHS _ -> [] instance ( a ~ GhcPass p , ToHie (Context (Located (IdP a))) @@ -954,7 +1128,7 @@ instance ( a ~ GhcPass p , toHie expr ] HsDo _ _ (L ispan stmts) -> - [ pure $ locOnly ispan + [ locOnly ispan , toHie $ listScopes NoScope stmts ] ExplicitList _ _ exprs -> @@ -1008,9 +1182,10 @@ instance ( a ~ GhcPass p ] XExpr x | GhcTc <- ghcPass @p - , HsWrap _ a <- x - -> [ toHie $ L mspan a ] - + , HsWrap w a <- x + -> [ toHie $ L mspan a + , toHie (L mspan w) + ] | otherwise -> [] @@ -1070,17 +1245,37 @@ instance ( ToHie (LHsExpr a) , ToHie (BindContext (LHsBind a)) , ToHie (SigContext (LSig a)) , ToHie (RScoped (HsValBindsLR a a)) + , ToHie (EvBindContext (Located (XIPBinds a))) + , ToHie (RScoped (LIPBind a)) , Data (HsLocalBinds a) ) => ToHie (RScoped (LHsLocalBinds a)) where toHie (RS scope (L sp binds)) = concatM $ makeNode binds sp : case binds of EmptyLocalBinds _ -> [] - HsIPBinds _ _ -> [] + HsIPBinds _ ipbinds -> case ipbinds of + IPBinds evbinds xs -> let sc = combineScopes scope $ mkScope sp in + [ toHie $ EvBindContext sc (getRealSpan sp) $ L sp evbinds + , toHie $ map (RS sc) xs + ] + XHsIPBinds _ -> [] HsValBinds _ valBinds -> [ toHie $ RS (combineScopes scope $ mkScope sp) valBinds ] XHsLocalBindsLR _ -> [] +instance ( ToHie (LHsExpr a) + , ToHie (Context (Located (IdP a))) + , Data (IPBind a) + ) => ToHie (RScoped (LIPBind a)) where + toHie (RS scope (L sp bind)) = concatM $ makeNode bind sp : case bind of + IPBind _ (Left _) expr -> [toHie expr] + IPBind _ (Right v) expr -> + [ toHie $ C (EvidenceVarBind EvImplicitBind scope (getRealSpan sp)) + $ L sp v + , toHie expr + ] + XIPBind _ -> [] + instance ( ToHie (BindContext (LHsBind a)) , ToHie (SigContext (LSig a)) , ToHie (RScoped (XXValBindsLR a a)) @@ -1160,6 +1355,7 @@ instance ( a ~ GhcPass p , ToHie (LHsExpr a) , ToHie (SigContext (LSig a)) , ToHie (RScoped (HsValBindsLR a a)) + , ToHie (RScoped (ExprLStmt a)) , Data (StmtLR a a (Located (HsExpr a))) , Data (HsLocalBinds a) ) => ToHie (RScoped (ApplicativeArg (GhcPass p))) where @@ -1193,6 +1389,7 @@ instance ( a ~ GhcPass p , ToHie (MatchGroup a (LHsCmd a)) , ToHie (SigContext (LSig a)) , ToHie (RScoped (HsValBindsLR a a)) + , ToHie (RScoped (LHsLocalBinds a)) , Data (HsCmd a) , Data (HsCmdTop a) , Data (StmtLR a a (Located (HsCmd a))) @@ -1235,7 +1432,7 @@ instance ( a ~ GhcPass p , toHie cmd' ] HsCmdDo _ (L ispan stmts) -> - [ pure $ locOnly ispan + [ locOnly ispan , toHie $ listScopes NoScope stmts ] XCmd _ -> [] @@ -1289,7 +1486,7 @@ instance ToHie (LTyClDecl GhcRn) where , toHie $ map (SC $ SI ClassSig $ getRealSpan span) sigs , toHie $ fmap (BC InstanceBind ModuleScope) meths , toHie typs - , concatMapM (pure . locOnly . getLoc) deftyps + , concatMapM (locOnly . getLoc) deftyps , toHie deftyps ] where @@ -1313,7 +1510,7 @@ instance ToHie (LFamilyDecl GhcRn) where instance ToHie (FamilyInfo GhcRn) where toHie (ClosedTypeFamily (Just eqns)) = concatM $ - [ concatMapM (pure . locOnly . getLoc) eqns + [ concatMapM (locOnly . getLoc) eqns , toHie $ map go eqns ] where @@ -1371,7 +1568,7 @@ instance ToHie (HsDataDefn GhcRn) where instance ToHie (HsDeriving GhcRn) where toHie (L span clauses) = concatM - [ pure $ locOnly span + [ locOnly span , toHie clauses ] @@ -1379,7 +1576,7 @@ instance ToHie (LHsDerivingClause GhcRn) where toHie (L span cl) = concatM $ makeNode cl span : case cl of HsDerivingClause _ strat (L ispan tys) -> [ toHie strat - , pure $ locOnly ispan + , locOnly ispan , toHie $ map (TS (ResolvedScopes [])) tys ] @@ -1391,14 +1588,14 @@ instance ToHie (Located (DerivStrategy GhcRn)) where ViaStrategy s -> [ toHie $ TS (ResolvedScopes []) s ] instance ToHie (Located OverlapMode) where - toHie (L span _) = pure $ locOnly span + toHie (L span _) = locOnly span instance ToHie (LConDecl GhcRn) where toHie (L span decl) = concatM $ makeNode decl span : case decl of ConDeclGADT { con_names = names, con_qvars = exp_vars, con_g_ext = imp_vars , con_mb_cxt = ctx, con_args = args, con_res_ty = typ } -> [ toHie $ map (C (Decl ConDec $ getRealSpan span)) names - , concatM $ [ pure $ bindingsOnly bindings + , concatM $ [ bindingsOnly bindings , toHie $ tvScopes resScope NoScope exp_vars ] , toHie ctx , toHie args @@ -1429,7 +1626,7 @@ instance ToHie (LConDecl GhcRn) where instance ToHie (Located [LConDeclField GhcRn]) where toHie (L span decls) = concatM $ - [ pure $ locOnly span + [ locOnly span , toHie decls ] @@ -1437,7 +1634,7 @@ instance ( HasLoc thing , ToHie (TScoped thing) ) => ToHie (TScoped (HsImplicitBndrs GhcRn thing)) where toHie (TS sc (HsIB ibrn a)) = concatM $ - [ pure $ bindingsOnly $ map (C $ TyVarBind (mkScope span) sc) ibrn + [ bindingsOnly $ map (C $ TyVarBind (mkScope span) sc) ibrn , toHie $ TS sc a ] where span = loc a @@ -1446,7 +1643,7 @@ instance ( HasLoc thing , ToHie (TScoped thing) ) => ToHie (TScoped (HsWildCardBndrs GhcRn thing)) where toHie (TS sc (HsWC names a)) = concatM $ - [ pure $ bindingsOnly $ map (C $ TyVarBind (mkScope span) sc) names + [ bindingsOnly $ map (C $ TyVarBind (mkScope span) sc) names , toHie $ TS sc a ] where span = loc a @@ -1496,10 +1693,10 @@ instance ToHie (SigContext (LSig GhcRn)) where ] SCCFunSig _ _ name mtxt -> [ toHie $ (C Use) name - , pure $ maybe [] (locOnly . getLoc) mtxt + , maybe (pure []) (locOnly . getLoc) mtxt ] CompleteMatchSig _ _ (L ispan names) typ -> - [ pure $ locOnly ispan + [ locOnly ispan , toHie $ map (C Use) names , toHie $ fmap (C Use) typ ] @@ -1583,7 +1780,7 @@ instance ToHie (TScoped (LHsType GhcRn)) where instance (ToHie tm, ToHie ty) => ToHie (HsArg tm ty) where toHie (HsValArg tm) = toHie tm toHie (HsTypeArg _ ty) = toHie ty - toHie (HsArgPar sp) = pure $ locOnly sp + toHie (HsArgPar sp) = locOnly sp instance Data flag => ToHie (TVScoped (LHsTyVarBndr flag GhcRn)) where toHie (TVS tsc sc (L span bndr)) = concatM $ makeNode bndr span : case bndr of @@ -1597,7 +1794,7 @@ instance Data flag => ToHie (TVScoped (LHsTyVarBndr flag GhcRn)) where instance ToHie (TScoped (LHsQTyVars GhcRn)) where toHie (TS sc (HsQTvs implicits vars)) = concatM $ - [ pure $ bindingsOnly bindings + [ bindingsOnly bindings , toHie $ tvScopes sc NoScope vars ] where @@ -1606,7 +1803,7 @@ instance ToHie (TScoped (LHsQTyVars GhcRn)) where instance ToHie (LHsContext GhcRn) where toHie (L span tys) = concatM $ - [ pure $ locOnly span + [ locOnly span , toHie tys ] @@ -1679,7 +1876,7 @@ instance ( a ~ GhcPass p [ toHie expr ] HsQuasiQuote _ _ _ ispan _ -> - [ pure $ locOnly ispan + [ locOnly ispan ] HsSpliced _ _ _ -> [] @@ -1695,7 +1892,7 @@ instance ToHie (LRoleAnnotDecl GhcRn) where toHie (L span annot) = concatM $ makeNode annot span : case annot of RoleAnnotDecl _ var roles -> [ toHie $ C Use var - , concatMapM (pure . locOnly . getLoc) roles + , concatMapM (locOnly . getLoc) roles ] instance ToHie (LInstDecl GhcRn) where @@ -1715,9 +1912,9 @@ instance ToHie (LClsInstDecl GhcRn) where [ toHie $ TS (ResolvedScopes [mkScope span]) $ cid_poly_ty decl , toHie $ fmap (BC InstanceBind ModuleScope) $ cid_binds decl , toHie $ map (SC $ SI InstSig $ getRealSpan span) $ cid_sigs decl - , pure $ concatMap (locOnly . getLoc) $ cid_tyfam_insts decl + , concatMapM (locOnly . getLoc) $ cid_tyfam_insts decl , toHie $ cid_tyfam_insts decl - , pure $ concatMap (locOnly . getLoc) $ cid_datafam_insts decl + , concatMapM (locOnly . getLoc) $ cid_datafam_insts decl , toHie $ cid_datafam_insts decl , toHie $ cid_overlap_mode decl ] @@ -1769,14 +1966,14 @@ instance ToHie (LForeignDecl GhcRn) where ] instance ToHie ForeignImport where - toHie (CImport (L a _) (L b _) _ _ (L c _)) = pure $ concat $ + toHie (CImport (L a _) (L b _) _ _ (L c _)) = concatM $ [ locOnly a , locOnly b , locOnly c ] instance ToHie ForeignExport where - toHie (CExport (L a _) (L b _)) = pure $ concat $ + toHie (CExport (L a _) (L b _)) = concatM $ [ locOnly a , locOnly b ] @@ -1814,7 +2011,7 @@ instance ToHie (LRuleDecls GhcRn) where instance ToHie (LRuleDecl GhcRn) where toHie (L span r@(HsRule _ rname _ tybndrs bndrs exprA exprB)) = concatM [ makeNode r span - , pure $ locOnly $ getLoc rname + , locOnly $ getLoc rname , toHie $ fmap (tvScopes (ResolvedScopes []) scope) tybndrs , toHie $ map (RS $ mkScope span) bndrs , toHie exprA @@ -1844,7 +2041,7 @@ instance ToHie (LImportDecl GhcRn) where ] where goIE (hiding, (L sp liens)) = concatM $ - [ pure $ locOnly sp + [ locOnly sp , toHie $ map (IEC c) liens ] where ===================================== compiler/GHC/Iface/Ext/Binary.hs ===================================== @@ -23,7 +23,6 @@ import GHC.Utils.Binary import GHC.Iface.Binary ( getDictFastString ) import GHC.Data.FastMutInt import GHC.Data.FastString ( FastString ) -import GHC.Unit.Module ( Module ) import GHC.Types.Name import GHC.Types.Name.Cache import GHC.Utils.Outputable @@ -32,7 +31,6 @@ import GHC.Types.SrcLoc as SrcLoc 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 @@ -48,42 +46,6 @@ import System.FilePath ( takeDirectory ) import GHC.Iface.Ext.Types --- | `Name`'s get converted into `HieName`'s before being written into @.hie@ --- files. See 'toHieName' and 'fromHieName' for logic on how to convert between --- these two types. -data HieName - = ExternalName !Module !OccName !SrcSpan - | LocalName !OccName !SrcSpan - | KnownKeyName !Unique - deriving (Eq) - -instance Ord HieName where - compare (ExternalName a b c) (ExternalName d e f) = compare (a,b) (d,e) `thenCmp` SrcLoc.leftmost_smallest c f - -- TODO (int-index): Perhaps use RealSrcSpan in HieName? - compare (LocalName a b) (LocalName c d) = compare a c `thenCmp` SrcLoc.leftmost_smallest b d - -- TODO (int-index): Perhaps use RealSrcSpan in HieName? - compare (KnownKeyName a) (KnownKeyName b) = nonDetCmpUnique a b - -- Not actually non deterministic as it is a KnownKey - compare ExternalName{} _ = LT - compare LocalName{} ExternalName{} = GT - compare LocalName{} _ = LT - compare KnownKeyName{} _ = GT - -instance Outputable HieName where - ppr (ExternalName m n sp) = text "ExternalName" <+> ppr m <+> ppr n <+> ppr sp - ppr (LocalName n sp) = text "LocalName" <+> ppr n <+> ppr sp - ppr (KnownKeyName u) = text "KnownKeyName" <+> ppr u - -hieNameOcc :: HieName -> OccName -hieNameOcc (ExternalName _ occ _) = occ -hieNameOcc (LocalName occ _) = occ -hieNameOcc (KnownKeyName u) = - case lookupKnownKeyName u of - Just n -> nameOccName n - Nothing -> pprPanic "hieNameOcc:unknown known-key unique" - (ppr (unpkUnique u)) - - data HieSymbolTable = HieSymbolTable { hie_symtab_next :: !FastMutInt , hie_symtab_map :: !(IORef (UniqFM (Int, HieName))) @@ -352,14 +314,6 @@ putName (HieSymbolTable next ref) bh name = do -- ** Converting to and from `HieName`'s -toHieName :: Name -> HieName -toHieName name - | isKnownKeyName name = KnownKeyName (nameUnique name) - | isExternalName name = ExternalName (nameModule name) - (nameOccName name) - (nameSrcSpan name) - | otherwise = LocalName (nameOccName name) (nameSrcSpan name) - fromHieName :: NameCache -> HieName -> (NameCache, Name) fromHieName nc (ExternalName mod occ span) = let cache = nsNames nc ===================================== compiler/GHC/Iface/Ext/Debug.hs ===================================== @@ -15,7 +15,6 @@ import GHC.Data.FastString import GHC.Utils.Outputable import GHC.Iface.Ext.Types -import GHC.Iface.Ext.Binary import GHC.Iface.Ext.Utils import GHC.Types.Name @@ -39,17 +38,18 @@ diffAst diffType (Node info1 span1 xs1) (Node info2 span2 xs2) = spanDiff | span1 /= span2 = [hsep ["Spans", ppr span1, "and", ppr span2, "differ"]] | otherwise = [] - infoDiff' - = (diffList eqDiff `on` (S.toAscList . nodeAnnotations)) info1 info2 - ++ (diffList diffType `on` nodeType) info1 info2 - ++ (diffIdents `on` nodeIdentifiers) info1 info2 - infoDiff = case infoDiff' of + infoDiff' i1 i2 + = (diffList eqDiff `on` (S.toAscList . nodeAnnotations)) i1 i2 + ++ (diffList diffType `on` nodeType) i1 i2 + ++ (diffIdents `on` nodeIdentifiers) i1 i2 + sinfoDiff = diffList (\(k1,a) (k2,b) -> eqDiff k1 k2 ++ infoDiff' a b) `on` (M.toList . getSourcedNodeInfo) + infoDiff = case sinfoDiff info1 info2 of [] -> [] - xs -> xs ++ [vcat ["In Node:",ppr (nodeIdentifiers info1,span1) - , "and", ppr (nodeIdentifiers info2,span2) + xs -> xs ++ [vcat ["In Node:",ppr (sourcedNodeIdents info1,span1) + , "and", ppr (sourcedNodeIdents info2,span2) , "While comparing" - , ppr (normalizeIdents $ nodeIdentifiers info1), "and" - , ppr (normalizeIdents $ nodeIdentifiers info2) + , ppr (normalizeIdents $ sourcedNodeIdents info1), "and" + , ppr (normalizeIdents $ sourcedNodeIdents info2) ] ] @@ -107,11 +107,24 @@ validAst (Node _ span children) = do -- | Look for any identifiers which occur outside of their supposed scopes. -- Returns a list of error messages. validateScopes :: Module -> M.Map FastString (HieAST a) -> [SDoc] -validateScopes mod asts = validScopes +validateScopes mod asts = validScopes ++ validEvs where refMap = generateReferencesMap asts -- We use a refmap for most of the computation + evs = M.keys + $ M.filter (any isEvidenceContext . concatMap (S.toList . identInfo . snd)) refMap + + validEvs = do + i@(Right ev) <- evs + case M.lookup i refMap of + Nothing -> ["Impossible, ev"<+> ppr ev <+> "not found in refmap" ] + Just refs + | nameIsLocalOrFrom mod ev + , not (any isEvidenceBind . concatMap (S.toList . identInfo . snd) $ refs) + -> ["Evidence var" <+> ppr ev <+> "not bound in refmap"] + | otherwise -> [] + -- Check if all the names occur in their calculated scopes validScopes = M.foldrWithKey (\k a b -> valid k a ++ b) [] refMap valid (Left _) _ = [] @@ -122,15 +135,18 @@ validateScopes mod asts = validScopes Just xs -> xs Nothing -> [] inScope (sp, dets) - | (definedInAsts asts n) + | (definedInAsts asts n || (any isEvidenceContext (identInfo dets))) && any isOccurrence (identInfo dets) -- We validate scopes for names which are defined locally, and occur - -- in this span + -- in this span, or are evidence variables = case scopes of - [] | (nameIsLocalOrFrom mod n - && not (isDerivedOccName $ nameOccName n)) - -- If we don't get any scopes for a local name then its an error. - -- We can ignore derived names. + [] | nameIsLocalOrFrom mod n + , ( not (isDerivedOccName $ nameOccName n) + || any isEvidenceContext (identInfo dets)) + -- If we don't get any scopes for a local name or + -- an evidence variable, then its an error. + -- We can ignore other kinds of derived names as + -- long as we take evidence vars into account -> return $ hsep $ [ "Locally defined Name", ppr n,pprDefinedAt n , "at position", ppr sp , "Doesn't have a calculated scope: ", ppr scopes] ===================================== compiler/GHC/Iface/Ext/Types.hs ===================================== @@ -17,13 +17,16 @@ import GHC.Prelude import GHC.Settings.Config import GHC.Utils.Binary import GHC.Data.FastString ( FastString ) +import GHC.Builtin.Utils import GHC.Iface.Type -import GHC.Unit.Module ( ModuleName, Module ) -import GHC.Types.Name ( Name ) +import GHC.Unit.Module ( ModuleName, Module ) +import GHC.Types.Name import GHC.Utils.Outputable hiding ( (<>) ) -import GHC.Types.SrcLoc ( RealSrcSpan ) +import GHC.Types.SrcLoc import GHC.Types.Avail +import GHC.Types.Unique import qualified GHC.Utils.Outputable as O ( (<>) ) +import GHC.Utils.Misc import qualified Data.Array as A import qualified Data.Map as M @@ -33,6 +36,8 @@ import Data.Data ( Typeable, Data ) import Data.Semigroup ( Semigroup(..) ) import Data.Word ( Word8 ) import Control.Applicative ( (<|>) ) +import Data.Coerce ( coerce ) +import Data.Function ( on ) type Span = RealSrcSpan @@ -222,17 +227,16 @@ instance Outputable a => Outputable (HieASTs a) where , rest ] - data HieAST a = Node - { nodeInfo :: NodeInfo a + { sourcedNodeInfo :: SourcedNodeInfo a , nodeSpan :: Span , nodeChildren :: [HieAST a] } deriving (Functor, Foldable, Traversable) instance Binary (HieAST TypeIndex) where put_ bh ast = do - put_ bh $ nodeInfo ast + put_ bh $ sourcedNodeInfo ast put_ bh $ nodeSpan ast put_ bh $ nodeChildren ast @@ -247,6 +251,38 @@ instance Outputable a => Outputable (HieAST a) where header = text "Node@" O.<> ppr sp O.<> ":" <+> ppr ni rest = vcat (map ppr ch) + +-- | NodeInfos grouped by source +newtype SourcedNodeInfo a = SourcedNodeInfo { getSourcedNodeInfo :: (M.Map NodeOrigin (NodeInfo a)) } + deriving (Functor, Foldable, Traversable) + +instance Binary (SourcedNodeInfo TypeIndex) where + put_ bh asts = put_ bh $ M.toAscList $ getSourcedNodeInfo asts + get bh = SourcedNodeInfo <$> fmap M.fromDistinctAscList (get bh) + +instance Outputable a => Outputable (SourcedNodeInfo a) where + ppr (SourcedNodeInfo asts) = M.foldrWithKey go "" asts + where + go k a rest = vcat $ + [ "Source: " O.<> ppr k + , ppr a + , rest + ] + +-- | Source of node info +data NodeOrigin + = SourceInfo + | GeneratedInfo + deriving (Eq, Enum, Ord) + +instance Outputable NodeOrigin where + ppr SourceInfo = text "From source" + ppr GeneratedInfo = text "generated by ghc" + +instance Binary NodeOrigin where + put_ bh b = putByte bh (fromIntegral (fromEnum b)) + get bh = do x <- getByte bh; pure $! (toEnum (fromIntegral x)) + -- | The information stored in one AST node. -- -- The type parameter exists to provide flexibility in representation of types @@ -314,7 +350,7 @@ instance Monoid (IdentifierDetails a) where instance Binary (IdentifierDetails TypeIndex) where put_ bh dets = do put_ bh $ identType dets - put_ bh $ S.toAscList $ identInfo dets + put_ bh $ S.toList $ identInfo dets get bh = IdentifierDetails <$> get bh <*> fmap S.fromDistinctAscList (get bh) @@ -363,6 +399,14 @@ data ContextInfo -- | Record field | RecField RecFieldContext (Maybe Span) + -- | Constraint/Dictionary evidence variable binding + | EvidenceVarBind + EvVarSource -- ^ how did this bind come into being + Scope -- ^ scope over which the value is bound + (Maybe Span) -- ^ span of the binding site + + -- | Usage of evidence variable + | EvidenceVarUse deriving (Eq, Ord) instance Outputable ContextInfo where @@ -385,10 +429,16 @@ instance Outputable ContextInfo where <+> ppr sc1 <+> "," <+> ppr sc2 ppr (RecField ctx sp) = text "record field" <+> ppr ctx <+> pprBindSpan sp + ppr (EvidenceVarBind ctx sc sp) = + text "evidence variable" <+> ppr ctx + $$ "with scope:" <+> ppr sc + $$ pprBindSpan sp + ppr (EvidenceVarUse) = + text "usage of evidence variable" pprBindSpan :: Maybe Span -> SDoc pprBindSpan Nothing = text "" -pprBindSpan (Just sp) = text "at:" <+> ppr sp +pprBindSpan (Just sp) = text "bound at:" <+> ppr sp instance Binary ContextInfo where put_ bh Use = putByte bh 0 @@ -422,6 +472,12 @@ instance Binary ContextInfo where put_ bh a put_ bh b put_ bh MatchBind = putByte bh 9 + put_ bh (EvidenceVarBind a b c) = do + putByte bh 10 + put_ bh a + put_ bh b + put_ bh c + put_ bh EvidenceVarUse = putByte bh 11 get bh = do (t :: Word8) <- get bh @@ -436,8 +492,69 @@ instance Binary ContextInfo where 7 -> TyVarBind <$> get bh <*> get bh 8 -> RecField <$> get bh <*> get bh 9 -> return MatchBind + 10 -> EvidenceVarBind <$> get bh <*> get bh <*> get bh + 11 -> return EvidenceVarUse _ -> panic "Binary ContextInfo: invalid tag" +data EvVarSource + = EvPatternBind -- ^ bound by a pattern match + | EvSigBind -- ^ bound by a type signature + | EvWrapperBind -- ^ bound by a hswrapper + | EvImplicitBind -- ^ bound by an implicit variable + | EvInstBind { isSuperInst :: Bool, cls :: Name } -- ^ Bound by some instance of given class + | EvLetBind EvBindDeps -- ^ A direct let binding + deriving (Eq,Ord) + +instance Binary EvVarSource where + put_ bh EvPatternBind = putByte bh 0 + put_ bh EvSigBind = putByte bh 1 + put_ bh EvWrapperBind = putByte bh 2 + put_ bh EvImplicitBind = putByte bh 3 + put_ bh (EvInstBind b cls) = do + putByte bh 4 + put_ bh b + put_ bh cls + put_ bh (EvLetBind deps) = do + putByte bh 5 + put_ bh deps + + get bh = do + (t :: Word8) <- get bh + case t of + 0 -> pure EvPatternBind + 1 -> pure EvSigBind + 2 -> pure EvWrapperBind + 3 -> pure EvImplicitBind + 4 -> EvInstBind <$> get bh <*> get bh + 5 -> EvLetBind <$> get bh + _ -> panic "Binary EvVarSource: invalid tag" + +instance Outputable EvVarSource where + ppr EvPatternBind = text "bound by a pattern" + ppr EvSigBind = text "bound by a type signature" + ppr EvWrapperBind = text "bound by a HsWrapper" + ppr EvImplicitBind = text "bound by an implicit variable binding" + ppr (EvInstBind False cls) = text "bound by an instance of class" <+> ppr cls + ppr (EvInstBind True cls) = text "bound due to a superclass of " <+> ppr cls + ppr (EvLetBind deps) = text "bound by a let, depending on:" <+> ppr deps + +-- | Eq/Ord instances compare on the converted HieName, +-- as non-exported names may have different uniques after +-- a roundtrip +newtype EvBindDeps = EvBindDeps { getEvBindDeps :: [Name] } + deriving Outputable + +instance Eq EvBindDeps where + (==) = coerce ((==) `on` map toHieName) + +instance Ord EvBindDeps where + compare = coerce (compare `on` map toHieName) + +instance Binary EvBindDeps where + put_ bh (EvBindDeps xs) = put_ bh xs + get bh = EvBindDeps <$> get bh + + -- | Types of imports and exports data IEType = Import @@ -587,3 +704,46 @@ instance Binary TyVarScope where 0 -> ResolvedScopes <$> get bh 1 -> UnresolvedScope <$> get bh <*> get bh _ -> panic "Binary TyVarScope: invalid tag" + +-- | `Name`'s get converted into `HieName`'s before being written into @.hie@ +-- files. See 'toHieName' and 'fromHieName' for logic on how to convert between +-- these two types. +data HieName + = ExternalName !Module !OccName !SrcSpan + | LocalName !OccName !SrcSpan + | KnownKeyName !Unique + deriving (Eq) + +instance Ord HieName where + compare (ExternalName a b c) (ExternalName d e f) = compare (a,b) (d,e) `thenCmp` leftmost_smallest c f + -- TODO (int-index): Perhaps use RealSrcSpan in HieName? + compare (LocalName a b) (LocalName c d) = compare a c `thenCmp` leftmost_smallest b d + -- TODO (int-index): Perhaps use RealSrcSpan in HieName? + compare (KnownKeyName a) (KnownKeyName b) = nonDetCmpUnique a b + -- Not actually non deterministic as it is a KnownKey + compare ExternalName{} _ = LT + compare LocalName{} ExternalName{} = GT + compare LocalName{} _ = LT + compare KnownKeyName{} _ = GT + +instance Outputable HieName where + ppr (ExternalName m n sp) = text "ExternalName" <+> ppr m <+> ppr n <+> ppr sp + ppr (LocalName n sp) = text "LocalName" <+> ppr n <+> ppr sp + ppr (KnownKeyName u) = text "KnownKeyName" <+> ppr u + +hieNameOcc :: HieName -> OccName +hieNameOcc (ExternalName _ occ _) = occ +hieNameOcc (LocalName occ _) = occ +hieNameOcc (KnownKeyName u) = + case lookupKnownKeyName u of + Just n -> nameOccName n + Nothing -> pprPanic "hieNameOcc:unknown known-key unique" + (ppr (unpkUnique u)) + +toHieName :: Name -> HieName +toHieName name + | isKnownKeyName name = KnownKeyName (nameUnique name) + | isExternalName name = ExternalName (nameModule name) + (nameOccName name) + (nameSrcSpan name) + | otherwise = LocalName (nameOccName name) (nameSrcSpan name) ===================================== compiler/GHC/Iface/Ext/Utils.hs ===================================== @@ -1,7 +1,9 @@ {-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE ViewPatterns #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE DeriveFunctor #-} module GHC.Iface.Ext.Utils where import GHC.Prelude @@ -11,7 +13,9 @@ import GHC.Driver.Session ( DynFlags ) import GHC.Data.FastString ( FastString, mkFastString ) import GHC.Iface.Type import GHC.Types.Name hiding (varName) -import GHC.Utils.Outputable ( renderWithStyle, ppr, defaultUserStyle, initSDocContext ) +import GHC.Types.Name.Set +import GHC.Utils.Outputable hiding ( (<>) ) +import qualified GHC.Utils.Outputable as O import GHC.Types.SrcLoc import GHC.CoreToIface import GHC.Core.TyCon @@ -27,21 +31,26 @@ import qualified Data.Set as S import qualified Data.IntMap.Strict as IM import qualified Data.Array as A import Data.Data ( typeOf, typeRepTyCon, Data(toConstr) ) -import Data.Maybe ( maybeToList ) +import Data.Maybe ( maybeToList, mapMaybe) import Data.Monoid +import Data.List (find) import Data.Traversable ( for ) +import Data.Coerce import Control.Monad.Trans.State.Strict hiding (get) +import Control.Monad.Trans.Reader +import qualified Data.Tree as Tree +type RefMap a = M.Map Identifier [(Span, IdentifierDetails a)] generateReferencesMap :: Foldable f => f (HieAST a) - -> M.Map Identifier [(Span, IdentifierDetails a)] + -> RefMap a generateReferencesMap = foldr (\ast m -> M.unionWith (++) (go ast) m) M.empty where go ast = M.unionsWith (++) (this : map go (nodeChildren ast)) where - this = fmap (pure . (nodeSpan ast,)) $ nodeIdentifiers $ nodeInfo ast + this = fmap (pure . (nodeSpan ast,)) $ sourcedNodeIdents $ sourcedNodeInfo ast renderHieType :: DynFlags -> HieTypeFix -> String renderHieType dflags ht = renderWithStyle (initSDocContext dflags defaultUserStyle) (ppr $ hieTypeToIface ht) @@ -72,6 +81,73 @@ resolveVisibility kind ty_args foldType :: (HieType a -> a) -> HieTypeFix -> a foldType f (Roll t) = f $ fmap (foldType f) t +selectPoint :: HieFile -> (Int,Int) -> Maybe (HieAST Int) +selectPoint hf (sl,sc) = getFirst $ + flip foldMap (M.toList (getAsts $ hie_asts hf)) $ \(fs,ast) -> First $ + case selectSmallestContaining (sp fs) ast of + Nothing -> Nothing + Just ast' -> Just ast' + where + sloc fs = mkRealSrcLoc fs sl sc + sp fs = mkRealSrcSpan (sloc fs) (sloc fs) + +findEvidenceUse :: NodeIdentifiers a -> [Name] +findEvidenceUse ni = [n | (Right n, dets) <- xs, any isEvidenceUse (identInfo dets)] + where + xs = M.toList ni + +data EvidenceInfo a + = EvidenceInfo + { evidenceVar :: Name + , evidenceSpan :: RealSrcSpan + , evidenceType :: a + , evidenceDetails :: Maybe (EvVarSource, Scope, Maybe Span) + } deriving (Eq,Ord,Functor) + +instance (Outputable a) => Outputable (EvidenceInfo a) where + ppr (EvidenceInfo name span typ dets) = + hang (ppr name <+> text "at" <+> ppr span O.<> text ", of type:" <+> ppr typ) 4 $ + pdets $$ (pprDefinedAt name) + where + pdets = case dets of + Nothing -> text "is a usage of an external evidence variable" + Just (src,scp,spn) -> text "is an" <+> ppr (EvidenceVarBind src scp spn) + +getEvidenceTreesAtPoint :: HieFile -> RefMap a -> (Int,Int) -> Tree.Forest (EvidenceInfo a) +getEvidenceTreesAtPoint hf refmap point = + [t | Just ast <- pure $ selectPoint hf point + , n <- findEvidenceUse (sourcedNodeIdents $ sourcedNodeInfo ast) + , Just t <- pure $ getEvidenceTree refmap n + ] + +getEvidenceTree :: RefMap a -> Name -> Maybe (Tree.Tree (EvidenceInfo a)) +getEvidenceTree refmap var = go emptyNameSet var + where + go seen var + | var `elemNameSet` seen = Nothing + | otherwise = do + xs <- M.lookup (Right var) refmap + case find (any isEvidenceBind . identInfo . snd) xs of + Just (sp,dets) -> do + typ <- identType dets + (evdet,children) <- getFirst $ foldMap First $ do + det <- S.toList $ identInfo dets + case det of + EvidenceVarBind src@(EvLetBind (getEvBindDeps -> xs)) scp spn -> + pure $ Just ((src,scp,spn),mapMaybe (go $ extendNameSet seen var) xs) + EvidenceVarBind src scp spn -> pure $ Just ((src,scp,spn),[]) + _ -> pure Nothing + pure $ Tree.Node (EvidenceInfo var sp typ (Just evdet)) children + -- It is externally bound + Nothing -> getFirst $ foldMap First $ do + (sp,dets) <- xs + if (any isEvidenceUse $ identInfo dets) + then do + case identType dets of + Nothing -> pure Nothing + Just typ -> pure $ Just $ Tree.Node (EvidenceInfo var sp typ Nothing) [] + else pure Nothing + hieTypeToIface :: HieTypeFix -> IfaceType hieTypeToIface = foldType go where @@ -194,8 +270,10 @@ resolveTyVarScopeLocal ast asts = go ast resolveScope scope = scope go (Node info span children) = Node info' span $ map go children where - info' = info { nodeIdentifiers = idents } - idents = M.map resolveNameScope $ nodeIdentifiers info + info' = SourcedNodeInfo (updateNodeInfo <$> getSourcedNodeInfo info) + updateNodeInfo i = i { nodeIdentifiers = idents } + where + idents = M.map resolveNameScope $ nodeIdentifiers i getNameBinding :: Name -> M.Map FastString (HieAST a) -> Maybe Span getNameBinding n asts = do @@ -217,7 +295,7 @@ getNameBindingInClass n sp asts = do getFirst $ foldMap First $ do child <- flattenAst ast dets <- maybeToList - $ M.lookup (Right n) $ nodeIdentifiers $ nodeInfo child + $ M.lookup (Right n) $ sourcedNodeIdents $ sourcedNodeInfo child let binding = foldMap (First . getBindSiteFromContext) (identInfo dets) return (getFirst binding) @@ -232,7 +310,7 @@ getNameScopeAndBinding n asts = case nameSrcSpan n of getFirst $ foldMap First $ do -- @[] node <- flattenAst defNode dets <- maybeToList - $ M.lookup (Right n) $ nodeIdentifiers $ nodeInfo node + $ M.lookup (Right n) $ sourcedNodeIdents $ sourcedNodeInfo node scopes <- maybeToList $ foldMap getScopeFromContext (identInfo dets) let binding = foldMap (First . getBindSiteFromContext) (identInfo dets) return $ Just (scopes, getFirst binding) @@ -245,6 +323,7 @@ getScopeFromContext (ClassTyDecl _) = Just [ModuleScope] getScopeFromContext (Decl _ _) = Just [ModuleScope] getScopeFromContext (TyVarBind a (ResolvedScopes xs)) = Just $ a:xs getScopeFromContext (TyVarBind a _) = Just [a] +getScopeFromContext (EvidenceVarBind _ a _) = Just [a] getScopeFromContext _ = Nothing getBindSiteFromContext :: ContextInfo -> Maybe Span @@ -292,8 +371,27 @@ definedInAsts asts n = case nameSrcSpan n of RealSrcSpan sp _ -> srcSpanFile sp `elem` M.keys asts _ -> False +getEvidenceBindDeps :: ContextInfo -> [Name] +getEvidenceBindDeps (EvidenceVarBind (EvLetBind xs) _ _) = + getEvBindDeps xs +getEvidenceBindDeps _ = [] + +isEvidenceBind :: ContextInfo -> Bool +isEvidenceBind EvidenceVarBind{} = True +isEvidenceBind _ = False + +isEvidenceContext :: ContextInfo -> Bool +isEvidenceContext EvidenceVarUse = True +isEvidenceContext EvidenceVarBind{} = True +isEvidenceContext _ = False + +isEvidenceUse :: ContextInfo -> Bool +isEvidenceUse EvidenceVarUse = True +isEvidenceUse _ = False + isOccurrence :: ContextInfo -> Bool isOccurrence Use = True +isOccurrence EvidenceVarUse = True isOccurrence _ = False scopeContainsSpan :: Scope -> Span -> Bool @@ -304,7 +402,7 @@ scopeContainsSpan (LocalScope a) b = a `containsSpan` b -- | One must contain the other. Leaf nodes cannot contain anything combineAst :: HieAST Type -> HieAST Type -> HieAST Type combineAst a@(Node aInf aSpn xs) b@(Node bInf bSpn ys) - | aSpn == bSpn = Node (aInf `combineNodeInfo` bInf) aSpn (mergeAsts xs ys) + | aSpn == bSpn = Node (aInf `combineSourcedNodeInfo` bInf) aSpn (mergeAsts xs ys) | aSpn `containsSpan` bSpn = combineAst b a combineAst a (Node xs span children) = Node xs span (insertAst a children) @@ -312,6 +410,18 @@ combineAst a (Node xs span children) = Node xs span (insertAst a children) insertAst :: HieAST Type -> [HieAST Type] -> [HieAST Type] insertAst x = mergeAsts [x] +nodeInfo :: HieAST Type -> NodeInfo Type +nodeInfo = foldl' combineNodeInfo emptyNodeInfo . getSourcedNodeInfo . sourcedNodeInfo + +emptyNodeInfo :: NodeInfo a +emptyNodeInfo = NodeInfo S.empty [] M.empty + +sourcedNodeIdents :: SourcedNodeInfo a -> NodeIdentifiers a +sourcedNodeIdents = M.unionsWith (<>) . fmap nodeIdentifiers . getSourcedNodeInfo + +combineSourcedNodeInfo :: SourcedNodeInfo Type -> SourcedNodeInfo Type -> SourcedNodeInfo Type +combineSourcedNodeInfo = coerce $ M.unionWith combineNodeInfo + -- | Merge two nodes together. -- -- Precondition and postcondition: elements in 'nodeType' are ordered. @@ -404,11 +514,12 @@ mergeSortAsts = go . map pure simpleNodeInfo :: FastString -> FastString -> NodeInfo a simpleNodeInfo cons typ = NodeInfo (S.singleton (cons, typ)) [] M.empty -locOnly :: SrcSpan -> [HieAST a] -locOnly (RealSrcSpan span _) = - [Node e span []] - where e = NodeInfo S.empty [] M.empty -locOnly _ = [] +locOnly :: Monad m => SrcSpan -> ReaderT NodeOrigin m [HieAST a] +locOnly (RealSrcSpan span _) = do + org <- ask + let e = mkSourcedNodeInfo org $ emptyNodeInfo + pure [Node e span []] +locOnly _ = pure [] mkScope :: SrcSpan -> Scope mkScope (RealSrcSpan sp _) = LocalScope sp @@ -425,30 +536,37 @@ combineScopes x NoScope = x combineScopes (LocalScope a) (LocalScope b) = mkScope $ combineSrcSpans (RealSrcSpan a Nothing) (RealSrcSpan b Nothing) +mkSourcedNodeInfo :: NodeOrigin -> NodeInfo a -> SourcedNodeInfo a +mkSourcedNodeInfo org ni = SourcedNodeInfo $ M.singleton org ni + {-# INLINEABLE makeNode #-} makeNode - :: (Applicative m, Data a) + :: (Monad m, Data a) => a -- ^ helps fill in 'nodeAnnotations' (with 'Data') -> SrcSpan -- ^ return an empty list if this is unhelpful - -> m [HieAST b] -makeNode x spn = pure $ case spn of - RealSrcSpan span _ -> [Node (simpleNodeInfo cons typ) span []] - _ -> [] + -> ReaderT NodeOrigin m [HieAST b] +makeNode x spn = do + org <- ask + pure $ case spn of + RealSrcSpan span _ -> [Node (mkSourcedNodeInfo org $ simpleNodeInfo cons typ) span []] + _ -> [] where cons = mkFastString . show . toConstr $ x typ = mkFastString . show . typeRepTyCon . typeOf $ x {-# INLINEABLE makeTypeNode #-} makeTypeNode - :: (Applicative m, Data a) + :: (Monad m, Data a) => a -- ^ helps fill in 'nodeAnnotations' (with 'Data') -> SrcSpan -- ^ return an empty list if this is unhelpful -> Type -- ^ type to associate with the node - -> m [HieAST Type] -makeTypeNode x spn etyp = pure $ case spn of - RealSrcSpan span _ -> - [Node (NodeInfo (S.singleton (cons,typ)) [etyp] M.empty) span []] - _ -> [] + -> ReaderT NodeOrigin m [HieAST Type] +makeTypeNode x spn etyp = do + org <- ask + pure $ case spn of + RealSrcSpan span _ -> + [Node (mkSourcedNodeInfo org $ NodeInfo (S.singleton (cons,typ)) [etyp] M.empty) span []] + _ -> [] where cons = mkFastString . show . toConstr $ x typ = mkFastString . show . typeRepTyCon . typeOf $ x ===================================== compiler/GHC/Parser.y ===================================== @@ -644,6 +644,8 @@ identifier :: { Located RdrName } | qconop { $1 } | '(' '->' ')' {% ams (sLL $1 $> $ getRdrName funTyCon) [mop $1,mu AnnRarrow $2,mcp $3] } + | '->' {% ams (sLL $1 $> $ getRdrName funTyCon) + [mu AnnRarrow $1] } ----------------------------------------------------------------------------- -- Backpack stuff ===================================== compiler/GHC/Unit.hs ===================================== @@ -21,237 +21,334 @@ import GHC.Unit.State import GHC.Unit.Subst import GHC.Unit.Module --- Note [About Units] --- ~~~~~~~~~~~~~~~~~~ --- --- Haskell users are used to manipulate Cabal packages. These packages are --- identified by: --- - a package name :: String --- - a package version :: Version --- - (a revision number, when they are registered on Hackage) --- --- Cabal packages may contain several components (libraries, programs, --- testsuites). In GHC we are mostly interested in libraries because those are --- the components that can be depended upon by other components. Components in a --- package are identified by their component name. Historically only one library --- component was allowed per package, hence it didn't need a name. For this --- reason, component name may be empty for one library component in each --- package: --- - a component name :: Maybe String --- --- UnitId --- ------ --- --- Cabal libraries can be compiled in various ways (different compiler options --- or Cabal flags, different dependencies, etc.), hence using package name, --- package version and component name isn't enough to identify a built library. --- We use another identifier called UnitId: --- --- package name \ --- package version | ________ --- component name | hash of all this ==> | UnitId | --- Cabal flags | -------- --- compiler options | --- dependencies' UnitId / --- --- Fortunately GHC doesn't have to generate these UnitId: they are provided by --- external build tools (e.g. Cabal) with `-this-unit-id` command-line parameter. --- --- UnitIds are important because they are used to generate internal names --- (symbols, etc.). --- --- Wired-in units --- -------------- --- --- Certain libraries are known to the compiler, in that we know about certain --- entities that reside in these libraries. The compiler needs to declare static --- Modules and Names that refer to units built from these libraries. --- --- Hence UnitIds of wired-in libraries are fixed. Instead of letting Cabal chose --- the UnitId for these libraries, their .cabal file uses the following stanza to --- force it to a specific value: --- --- ghc-options: -this-unit-id ghc-prim -- taken from ghc-prim.cabal --- --- The RTS also uses entities of wired-in units by directly referring to symbols --- such as "base_GHCziIOziException_heapOverflow_closure" where the prefix is --- the UnitId of "base" unit. --- --- Unit databases --- -------------- --- --- Units are stored in databases in order to be reused by other codes: --- --- UnitKey ---> UnitInfo { exposed modules, package name, package version --- component name, various file paths, --- dependencies :: [UnitKey], etc. } --- --- Because of the wired-in units described above, we can't exactly use UnitIds --- as UnitKeys in the database: if we did this, we could only have a single unit --- (compiled library) in the database for each wired-in library. As we want to --- support databases containing several different units for the same wired-in --- library, we do this: --- --- * for non wired-in units: --- * UnitId = UnitKey = Identifier (hash) computed by Cabal --- --- * for wired-in units: --- * UnitKey = Identifier computed by Cabal (just like for non wired-in units) --- * UnitId = unit-id specified with -this-unit-id command-line flag --- --- We can expose several units to GHC via the `package-id ` --- command-line parameter. We must use the UnitKeys of the units so that GHC can --- find them in the database. --- --- GHC then replaces the UnitKeys with UnitIds by taking into account wired-in --- units: these units are detected thanks to their UnitInfo (especially their --- package name). --- --- For example, knowing that "base", "ghc-prim" and "rts" are wired-in packages, --- the following dependency graph expressed with UnitKeys (as found in the --- database) will be transformed into a similar graph expressed with UnitIds --- (that are what matters for compilation): --- --- UnitKeys --- ~~~~~~~~ ---> rts-1.0-hashABC <-- --- | | --- | | --- foo-2.0-hash123 --> base-4.1-hashXYZ ---> ghc-prim-0.5.3-hashABC --- --- UnitIds --- ~~~~~~~ ---> rts <-- --- | | --- | | --- foo-2.0-hash123 --> base ---------------> ghc-prim --- --- --- Module signatures / indefinite units / instantiated units --- --------------------------------------------------------- --- --- GHC distinguishes two kinds of units: --- --- * definite: units for which every module has an associated code object --- (i.e. real compiled code in a .o/.a/.so/.dll/...) --- --- * indefinite: units for which some modules are replaced by module --- signatures. --- --- Module signatures are a kind of interface (similar to .hs-boot files). They --- are used in place of some real code. GHC allows real modules from other --- units to be used to fill these module holes. The process is called --- "unit/module instantiation". --- --- You can think of this as polymorphism at the module level: module signatures --- give constraints on the "type" of module that can be used to fill the hole --- (where "type" means types of the exported module entitites, etc.). --- --- Module signatures contain enough information (datatypes, abstract types, type --- synonyms, classes, etc.) to typecheck modules depending on them but not --- enough to compile them. As such, indefinite units found in databases only --- provide module interfaces (the .hi ones this time), not object code. --- --- To distinguish between indefinite and finite unit ids at the type level, we --- respectively use 'IndefUnitId' and 'DefUnitId' datatypes that are basically --- wrappers over 'UnitId'. --- --- Unit instantiation --- ------------------ --- --- Indefinite units can be instantiated with modules from other units. The --- instantiating units can also be instantiated themselves (if there are --- indefinite) and so on. The 'Unit' datatype represents a unit which may have --- been instantiated: --- --- data Unit = RealUnit DefUnitId --- | VirtUnit InstantiatedUnit --- --- 'InstantiatedUnit' has two interesting fields: --- --- * instUnitInstanceOf :: IndefUnitId --- -- ^ the indefinite unit that is instantiated --- --- * instUnitInsts :: [(ModuleName,(Unit,ModuleName)] --- -- ^ a list of instantiations, where an instantiation is: --- (module hole name, (instantiating unit, instantiating module name)) --- --- A 'Unit' may be indefinite or definite, it depends on whether some holes --- remain in the instantiated unit OR in the instantiating units (recursively). --- --- Pretty-printing UnitId --- ---------------------- --- --- GHC mostly deals with UnitIds which are some opaque strings. We could display --- them when we pretty-print a module origin, a name, etc. But it wouldn't be --- very friendly to the user because of the hash they usually contain. E.g. --- --- foo-4.18.1:thelib-XYZsomeUglyHashABC --- --- Instead when we want to pretty-print a 'UnitId' we query the database to --- get the 'UnitInfo' and print something nicer to the user: --- --- foo-4.18.1:thelib --- --- We do the same for wired-in units. --- --- Currently (2020-04-06), we don't thread the database into every function that --- pretty-prints a Name/Module/Unit. Instead querying the database is delayed --- until the `SDoc` is transformed into a `Doc` using the database that is --- active at this point in time. This is an issue because we want to be able to --- unload units from the database and we also want to support several --- independent databases loaded at the same time (see #14335). The alternatives --- we have are: --- --- * threading the database into every function that pretty-prints a UnitId --- for the user (directly or indirectly). --- --- * storing enough info to correctly display a UnitId into the UnitId --- datatype itself. This is done in the IndefUnitId wrapper (see --- 'UnitPprInfo' datatype) but not for every 'UnitId'. Statically defined --- 'UnitId' for wired-in units would have empty UnitPprInfo so we need to --- find some places to update them if we want to display wired-in UnitId --- correctly. This leads to a solution similar to the first one above. --- --- Note [VirtUnit to RealUnit improvement] --- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --- --- Over the course of instantiating VirtUnits on the fly while typechecking an --- indefinite library, we may end up with a fully instantiated VirtUnit. I.e. --- one that could be compiled and installed in the database. During --- type-checking we generate a virtual UnitId for it, say "abc". --- --- Now the question is: do we have a matching installed unit in the database? --- Suppose we have one with UnitId "xyz" (provided by Cabal so we don't know how --- to generate it). The trouble is that if both units end up being used in the --- same type-checking session, their names won't match (e.g. "abc:M.X" vs --- "xyz:M.X"). --- --- As we want them to match we just replace the virtual unit with the installed --- one: for some reason this is called "improvement". --- --- There is one last niggle: improvement based on the package database means --- that we might end up developing on a package that is not transitively --- depended upon by the packages the user specified directly via command line --- flags. This could lead to strange and difficult to understand bugs if those --- instantiations are out of date. The solution is to only improve a --- unit id if the new unit id is part of the 'preloadClosure'; i.e., the --- closure of all the packages which were explicitly specified. - --- Note [Representation of module/name variables] --- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --- In our ICFP'16, we use to represent module holes, and {A.T} to represent --- name holes. This could have been represented by adding some new cases --- to the core data types, but this would have made the existing 'moduleName' --- and 'moduleUnit' partial, which would have required a lot of modifications --- to existing code. --- --- Instead, we use a fake "hole" unit: --- --- ===> hole:A --- {A.T} ===> hole:A.T --- --- This encoding is quite convenient, but it is also a bit dangerous too, --- because if you have a 'hole:A' you need to know if it's actually a --- 'Module' or just a module stored in a 'Name'; these two cases must be --- treated differently when doing substitutions. 'renameHoleModule' --- and 'renameHoleUnit' assume they are NOT operating on a --- 'Name'; 'NameShape' handles name substitutions exclusively. +{- + +Note [About Units] +~~~~~~~~~~~~~~~~~~ + +Haskell users are used to manipulate Cabal packages. These packages are +identified by: + - a package name :: String + - a package version :: Version + - (a revision number, when they are registered on Hackage) + +Cabal packages may contain several components (libraries, programs, +testsuites). In GHC we are mostly interested in libraries because those are +the components that can be depended upon by other components. Components in a +package are identified by their component name. Historically only one library +component was allowed per package, hence it didn't need a name. For this +reason, component name may be empty for one library component in each +package: + - a component name :: Maybe String + +UnitId +------ + +Cabal libraries can be compiled in various ways (different compiler options +or Cabal flags, different dependencies, etc.), hence using package name, +package version and component name isn't enough to identify a built library. +We use another identifier called UnitId: + + package name \ + package version | ________ + component name | hash of all this ==> | UnitId | + Cabal flags | -------- + compiler options | + dependencies' UnitId / + +Fortunately GHC doesn't have to generate these UnitId: they are provided by +external build tools (e.g. Cabal) with `-this-unit-id` command-line parameter. + +UnitIds are important because they are used to generate internal names +(symbols, etc.). + +Wired-in units +-------------- + +Certain libraries (ghc-prim, base, etc.) are known to the compiler and to the +RTS as they provide some basic primitives. Hence UnitIds of wired-in libraries +are fixed. Instead of letting Cabal chose the UnitId for these libraries, their +.cabal file uses the following stanza to force it to a specific value: + + ghc-options: -this-unit-id ghc-prim -- taken from ghc-prim.cabal + +The RTS also uses entities of wired-in units by directly referring to symbols +such as "base_GHCziIOziException_heapOverflow_closure" where the prefix is +the UnitId of "base" unit. + +Unit databases +-------------- + +Units are stored in databases in order to be reused by other codes: + + UnitKey ---> UnitInfo { exposed modules, package name, package version + component name, various file paths, + dependencies :: [UnitKey], etc. } + +Because of the wired-in units described above, we can't exactly use UnitIds +as UnitKeys in the database: if we did this, we could only have a single unit +(compiled library) in the database for each wired-in library. As we want to +support databases containing several different units for the same wired-in +library, we do this: + + * for non wired-in units: + * UnitId = UnitKey = Identifier (hash) computed by Cabal + + * for wired-in units: + * UnitKey = Identifier computed by Cabal (just like for non wired-in units) + * UnitId = unit-id specified with -this-unit-id command-line flag + +We can expose several units to GHC via the `package-id ` command-line +parameter. We must use the UnitKeys of the units so that GHC can find them in +the database. + +During unit loading, GHC replaces UnitKeys with UnitIds. It identifies wired +units by their package name (stored in their UnitInfo) and uses wired-in UnitIds +for them. + +For example, knowing that "base", "ghc-prim" and "rts" are wired-in units, the +following dependency graph expressed with database UnitKeys will be transformed +into a similar graph expressed with UnitIds: + + UnitKeys + ~~~~~~~~ ----------> rts-1.0-hashABC <-- + | | + | | + foo-2.0-hash123 --> base-4.1-hashXYZ ---> ghc-prim-0.5.3-hashUVW + + UnitIds + ~~~~~~~ ---------------> rts <-- + | | + | | + foo-2.0-hash123 --> base ---------------> ghc-prim + + +Note that "foo-2.0-hash123" isn't wired-in so its UnitId is the same as its UnitKey. + + +Module signatures / indefinite units / instantiated units +--------------------------------------------------------- + +GHC distinguishes two kinds of units: + + * definite units: + * units without module holes and with definite dependencies + * can be compiled into machine code (.o/.a/.so/.dll/...) + + * indefinite units: + * units with some module holes or with some indefinite dependencies + * can only be type-checked + +Module holes are constrained by module signatures (.hsig files). Module +signatures are a kind of interface (similar to .hs-boot files). They are used in +place of some real code. GHC allows modules from other units to be used to fill +these module holes: the process is called "unit/module instantiation". The +instantiating module may either be a concrete module or a module signature. In +the latter case, the signatures are merged to form a new one. + +You can think of this as polymorphism at the module level: module signatures +give constraints on the "type" of module that can be used to fill the hole +(where "type" means types of the exported module entitites, etc.). + +Module signatures contain enough information (datatypes, abstract types, type +synonyms, classes, etc.) to typecheck modules depending on them but not +enough to compile them. As such, indefinite units found in databases only +provide module interfaces (the .hi ones this time), not object code. + +To distinguish between indefinite and definite unit ids at the type level, we +respectively use 'IndefUnitId' and 'DefUnitId' datatypes that are basically +wrappers over 'UnitId'. + +Unit instantiation / on-the-fly instantiation +--------------------------------------------- + +Indefinite units can be instantiated with modules from other units. The +instantiating units can also be instantiated themselves (if there are +indefinite) and so on. + +On-the-fly unit instantiation is a tricky optimization explained in +http://blog.ezyang.com/2016/08/optimizing-incremental-compilation +Here is a summary: + + 1. Indefinite units can only be type-checked, not compiled into real code. + Type-checking produces interface files (.hi) which are incomplete for code + generation (they lack unfoldings, etc.) but enough to perform type-checking + of units depending on them. + + 2. Type-checking an instantiated unit is cheap as we only have to merge + interface files (.hi) of the instantiated unit and of the instantiating + units, hence it can be done on-the-fly. Interface files of the dependencies + can be concrete or produced on-the-fly recursively. + + 3. When we compile a unit, we mustn't use interfaces produced by the + type-checker (on-the-fly or not) for the instantiated unit dependencies + because they lack some information. + + 4. When we type-check an indefinite unit, we must be consistent about the + interfaces we use for each dependency: only those produced by the + type-checker (on-the-fly or not) or only those produced after a full + compilation, but not both at the same time. + + It can be tricky if we have the following kind of dependency graph: + + X (indefinite) ------> D (definite, compiled) -----> I (instantiated, definite, compiled) + |----------------------------------------------------^ + + Suppose we want to type-check unit X which depends on unit I and D: + * I is definite and compiled: we have compiled .hi files for its modules on disk + * I is instantiated: it is cheap to produce type-checker .hi files for its modules on-the-fly + + But we must not do: + + X (indefinite) ------> D (definite, compiled) -----> I (instantiated, definite, compiled) + |--------------------------------------------------> I (instantiated on-the-fly) + + ==> inconsistent module interfaces for I + + Nor: + + X (indefinite) ------> D (definite, compiled) -------v + |--------------------------------------------------> I (instantiated on-the-fly) + + ==> D's interfaces may refer to things that only exist in I's *compiled* interfaces + + An alternative would be to store both type-checked and compiled interfaces + for every compiled non-instantiated unit (instantiated unit can be done + on-the-fly) so that we could use type-checked interfaces of D in the + example above. But it would increase compilation time and unit size. + + +The 'Unit' datatype represents a unit which may have been instantiated +on-the-fly: + + data Unit = RealUnit DefUnitId -- use compiled interfaces on disk + | VirtUnit InstantiatedUnit -- use on-the-fly instantiation + +'InstantiatedUnit' has two interesting fields: + + * instUnitInstanceOf :: IndefUnitId + -- ^ the indefinite unit that is instantiated + + * instUnitInsts :: [(ModuleName,(Unit,ModuleName)] + -- ^ a list of instantiations, where an instantiation is: + (module hole name, (instantiating unit, instantiating module name)) + +A 'VirtUnit' may be indefinite or definite, it depends on whether some holes +remain in the instantiated unit OR in the instantiating units (recursively). +Having a fully instantiated (i.e. definite) virtual unit can lead to some issues +if there is a matching compiled unit in the preload closure. See Note [VirtUnit +to RealUnit improvement] + +Unit database and indefinite units +---------------------------------- + +We don't store partially instantiated units in the unit database. Units in the +database are either: + + * definite (fully instantiated or without holes): in this case we have + *compiled* module interfaces (.hi) and object codes (.o/.a/.so/.dll/...). + + * fully indefinite (not instantiated at all): in this case we only have + *type-checked* module interfaces (.hi). + +Note that indefinite units are stored as an instantiation of themselves where +each instantiating module is a module variable (see Note [Representation of +module/name variables]). E.g. + + "xyz" (UnitKey) ---> UnitInfo { instanceOf = "xyz" + , instantiatedWith = [A=,B=...] + , ... + } + +Note that non-instantiated units are also stored as an instantiation of +themselves. It is a reminiscence of previous terminology (when "instanceOf" was +"componentId"). E.g. + + "xyz" (UnitKey) ---> UnitInfo { instanceOf = "xyz" + , instantiatedWith = [] + , ... + } + +TODO: We should probably have `instanceOf :: Maybe IndefUnitId` instead. + + +Pretty-printing UnitId +---------------------- + +GHC mostly deals with UnitIds which are some opaque strings. We could display +them when we pretty-print a module origin, a name, etc. But it wouldn't be +very friendly to the user because of the hash they usually contain. E.g. + + foo-4.18.1:thelib-XYZsomeUglyHashABC + +Instead when we want to pretty-print a 'UnitId' we query the database to +get the 'UnitInfo' and print something nicer to the user: + + foo-4.18.1:thelib + +We do the same for wired-in units. + +Currently (2020-04-06), we don't thread the database into every function that +pretty-prints a Name/Module/Unit. Instead querying the database is delayed +until the `SDoc` is transformed into a `Doc` using the database that is +active at this point in time. This is an issue because we want to be able to +unload units from the database and we also want to support several +independent databases loaded at the same time (see #14335). The alternatives +we have are: + + * threading the database into every function that pretty-prints a UnitId + for the user (directly or indirectly). + + * storing enough info to correctly display a UnitId into the UnitId + datatype itself. This is done in the IndefUnitId wrapper (see + 'UnitPprInfo' datatype) but not for every 'UnitId'. Statically defined + 'UnitId' for wired-in units would have empty UnitPprInfo so we need to + find some places to update them if we want to display wired-in UnitId + correctly. This leads to a solution similar to the first one above. + +Note [VirtUnit to RealUnit improvement] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Over the course of instantiating VirtUnits on the fly while typechecking an +indefinite library, we may end up with a fully instantiated VirtUnit. I.e. +one that could be compiled and installed in the database. During +type-checking we generate a virtual UnitId for it, say "abc". + +Now the question is: do we have a matching installed unit in the database? +Suppose we have one with UnitId "xyz" (provided by Cabal so we don't know how +to generate it). The trouble is that if both units end up being used in the +same type-checking session, their names won't match (e.g. "abc:M.X" vs +"xyz:M.X"). + +As we want them to match we just replace the virtual unit with the installed +one: for some reason this is called "improvement". + +There is one last niggle: improvement based on the unit database means +that we might end up developing on a unit that is not transitively +depended upon by the units the user specified directly via command line +flags. This could lead to strange and difficult to understand bugs if those +instantiations are out of date. The solution is to only improve a +unit id if the new unit id is part of the 'preloadClosure'; i.e., the +closure of all the units which were explicitly specified. + +Note [Representation of module/name variables] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In our ICFP'16, we use to represent module holes, and {A.T} to represent +name holes. This could have been represented by adding some new cases +to the core data types, but this would have made the existing 'moduleName' +and 'moduleUnit' partial, which would have required a lot of modifications +to existing code. + +Instead, we use a fake "hole" unit: + + ===> hole:A + {A.T} ===> hole:A.T + +This encoding is quite convenient, but it is also a bit dangerous too, +because if you have a 'hole:A' you need to know if it's actually a +'Module' or just a module stored in a 'Name'; these two cases must be +treated differently when doing substitutions. 'renameHoleModule' +and 'renameHoleUnit' assume they are NOT operating on a +'Name'; 'NameShape' handles name substitutions exclusively. + +-} ===================================== docs/core-spec/CoreLint.ott ===================================== @@ -12,7 +12,7 @@ defns CoreLint :: '' ::= -defn |- prog program :: :: lintCoreBindings :: 'Prog_' {{ com Program typing, \coderef{coreSyn/CoreLint.hs}{lintCoreBindings} }} +defn |- prog program :: :: lintCoreBindings :: 'Prog_' {{ com Program typing, \coderef{GHC/Core/Lint.hs}{lintCoreBindings} }} {{ tex \labeledjudge{prog} [[program]] }} by @@ -22,7 +22,7 @@ no_duplicates --------------------- :: CoreBindings |-prog -defn G |- bind binding :: :: lint_bind :: 'Binding_' {{ com Binding typing, \coderef{coreSyn/CoreLint.hs}{lint\_bind} }} +defn G |- bind binding :: :: lint_bind :: 'Binding_' {{ com Binding typing, \coderef{GHC/Core/Lint.hs}{lint\_bind} }} {{ tex [[G]] \labeledjudge{bind} [[binding]] }} by @@ -34,7 +34,7 @@ G |-bind n = e ---------------------- :: Rec G |-bind rec -defn G |- sbind n <- e :: :: lintSingleBinding :: 'SBinding_' {{ com Single binding typing, \coderef{coreSyn/CoreLint.hs}{lintSingleBinding} }} +defn G |- sbind n <- e :: :: lintSingleBinding :: 'SBinding_' {{ com Single binding typing, \coderef{GHC/Core/Lint.hs}{lintSingleBinding} }} {{ tex [[G]] \labeledjudge{sbind} [[n]] [[<-]] [[e]] }} by @@ -45,7 +45,7 @@ G |-name z_t ok ----------------- :: SingleBinding G |-sbind z_t <- e -defn G ; D |-sjbind l vars <- e : t :: :: lintSingleBinding_joins :: 'SJBinding_' {{ com Single join binding typing, \coderef{coreSyn/CoreLint.hs}{lintSingleBinding} }} +defn G ; D |-sjbind l vars <- e : t :: :: lintSingleBinding_joins :: 'SJBinding_' {{ com Single join binding typing, \coderef{GHC/Core/Lint.hs}{lintSingleBinding} }} {{ tex [[G]];[[D]] \labeledjudge{sjbind} [[l]] \, [[vars]] [[<-]] [[e]] : [[t]] }} by @@ -60,7 +60,7 @@ split_I s = t G; D |-sjbind p/I_s <- e : t defn G ; D |- tm e : t :: :: lintCoreExpr :: 'Tm_' - {{ com Expression typing, \coderef{coreSyn/CoreLint.hs}{lintCoreExpr} }} + {{ com Expression typing, \coderef{GHC/Core/Lint.hs}{lintCoreExpr} }} {{ tex [[G]]; [[D]] \labeledjudge{tm} [[e]] : [[t]] }} by @@ -171,7 +171,7 @@ G |-co g : t1 k1~Rep k2 t2 G; D |-tm g : (~Rep#) k1 k2 t1 t2 defn G |- name n ok :: :: lintSingleBinding_lintBinder :: 'Name_' - {{ com Name consistency check, \coderef{coreSyn/CoreLint.hs}{lintSingleBinding\#lintBinder} }} + {{ com Name consistency check, \coderef{GHC/Core/Lint.hs}{lintSingleBinding\#lintBinder} }} {{ tex [[G]] \labeledjudge{n} [[n]] [[ok]] }} by @@ -184,7 +184,7 @@ G |-name x_t ok G |-name alpha_k ok defn G |- label l ok :: :: lintSingleBinding_lintBinder_join :: 'Label_' - {{ com Label consistency check, \coderef{coreSyn/CoreLint.hs}{lintSingleBinding\#lintBinder} }} + {{ com Label consistency check, \coderef{GHC/Core/Lint.hs}{lintSingleBinding\#lintBinder} }} {{ tex [[G]] \labeledjudge{label} [[l]] [[ok]] }} by @@ -197,7 +197,7 @@ k' = * \/ k' = # G |-label p / I _ t ok defn G |- bnd n ok :: :: lintBinder :: 'Binding_' - {{ com Binding consistency, \coderef{coreSyn/CoreLint.hs}{lintBinder} }} + {{ com Binding consistency, \coderef{GHC/Core/Lint.hs}{lintBinder} }} {{ tex [[G]] \labeledjudge{bnd} [[n]] [[ok]] }} by @@ -211,7 +211,7 @@ G |-ki k ok G |-bnd alpha_k ok defn G |- co g : t1 k1 ~ R k2 t2 :: :: lintCoercion :: 'Co_' - {{ com Coercion typing, \coderef{coreSyn/CoreLint.hs}{lintCoercion} }} + {{ com Coercion typing, \coderef{GHC/Core/Lint.hs}{lintCoercion} }} {{ tex [[G]] \labeledjudge{co} [[g]] : [[t1]] \mathop{ {}^{[[k1]]} {\sim}_{[[R]]}^{[[k2]]} } [[t2]] }} by @@ -375,7 +375,7 @@ G |-ty t'2 : k0' G |-co mu $ : t'1 k0 ~R' k0' t'2 defn G |- axk [ namesroles |-> gs ] ~> ( subst1 , subst2 ) :: :: check_ki :: 'AxiomKind_' - {{ com Axiom argument kinding, \coderef{coreSyn/CoreLint.hs}{lintCoercion\#check\_ki} }} + {{ com Axiom argument kinding, \coderef{GHC/Core/Lint.hs}{lintCoercion\#check\_ki} }} {{ tex [[G]] \labeledjudge{axk} [ [[namesroles]] [[|->]] [[gs]] ] [[~>]] ([[subst1]], [[subst2]]) }} by @@ -451,7 +451,7 @@ O |- t |> g : R O |- g : Ph defn R1 <= R2 :: :: ltRole :: 'Rlt_' - {{ com Sub-role relation, \coderef{types/Coercion.hs}{ltRole} }} + {{ com Sub-role relation, \coderef{GHC/Core/Coercion.hs}{ltRole} }} {{ tex [[R1]] \leq [[R2]] }} by @@ -465,7 +465,7 @@ R <= Ph R <= R defn G |- ki k ok :: :: lintKind :: 'K_' - {{ com Kind validity, \coderef{coreSyn/CoreLint.hs}{lintKind} }} + {{ com Kind validity, \coderef{GHC/Core/Lint.hs}{lintKind} }} {{ tex [[G]] \labeledjudge{k} [[k]] [[ok]] }} by @@ -478,7 +478,7 @@ G |-ty k : # G |-ki k ok defn G |- ty t : k :: :: lintType :: 'Ty_' - {{ com Kinding, \coderef{coreSyn/CoreLint.hs}{lintType} }} + {{ com Kinding, \coderef{GHC/Core/Lint.hs}{lintType} }} {{ tex [[G]] \labeledjudge{ty} [[t]] : [[k]] }} by @@ -535,7 +535,7 @@ G |-co g : t1 k1 ~Rep k2 t2 G |-ty g : (~Rep#) k1 k2 t1 t2 defn G |- subst n |-> t ok :: :: lintTyKind :: 'Subst_' - {{ com Substitution consistency, \coderef{coreSyn/CoreLint.hs}{lintTyKind} }} + {{ com Substitution consistency, \coderef{GHC/Core/Lint.hs}{lintTyKind} }} {{ tex [[G]] \labeledjudge{subst} [[n]] [[|->]] [[t]] [[ok]] }} by @@ -544,7 +544,7 @@ G |-ty t : k G |-subst z_k |-> t ok defn G ; D ; s |- altern alt : t :: :: lintCoreAlt :: 'Alt_' - {{ com Case alternative consistency, \coderef{coreSyn/CoreLint.hs}{lintCoreAlt} }} + {{ com Case alternative consistency, \coderef{GHC/Core/Lint.hs}{lintCoreAlt} }} {{ tex [[G]];[[D]];[[s]] \labeledjudge{alt} [[alt]] : [[t]] }} by @@ -569,7 +569,7 @@ G'; D |-tm e : t G; D; T |-altern K -> e : t defn t' = t { } :: :: applyTys :: 'ApplyTys_' - {{ com Telescope substitution, \coderef{types/Type.hs}{applyTys} }} + {{ com Telescope substitution, \coderef{GHC/Core/Type.hs}{applyTys} }} by --------------------- :: Empty @@ -581,7 +581,7 @@ t'' = t'[n |-> s] t'' = (forall n. t) { s, } defn G |- altbnd vars : t1 ~> t2 :: :: lintAltBinders :: 'AltBinders_' - {{ com Case alternative binding consistency, \coderef{coreSyn/CoreLint.hs}{lintAltBinders} }} + {{ com Case alternative binding consistency, \coderef{GHC/Core/Lint.hs}{lintAltBinders} }} {{ tex [[G]] \labeledjudge{altbnd} [[vars]] : [[t1]] [[~>]] [[t2]] }} by @@ -602,7 +602,7 @@ G |-altbnd : t2 ~> s G |-altbnd x_t1, : (t1 -> t2) ~> s defn G |- arrow k1 -> k2 : k :: :: lintArrow :: 'Arrow_' - {{ com Arrow kinding, \coderef{coreSyn/CoreLint.hs}{lintArrow} }} + {{ com Arrow kinding, \coderef{GHC/Core/Lint.hs}{lintArrow} }} {{ tex [[G]] \labeledjudge{\rightarrow} [[k1]] [[->]] [[k2]] : [[k]] }} by @@ -612,7 +612,7 @@ k2 = TYPE s G |-arrow k1 -> k2 : * defn G |- app kinded_types : k1 ~> k2 :: :: lint_app :: 'App_' - {{ com Type application kinding, \coderef{coreSyn/CoreLint.hs}{lint\_app} }} + {{ com Type application kinding, \coderef{GHC/Core/Lint.hs}{lint\_app} }} {{ tex [[G]] \labeledjudge{app} [[kinded_types]] : [[k1]] [[~>]] [[k2]] }} by @@ -628,7 +628,7 @@ G |-app : k2[z_k1 |-> t] ~> k' G |-app (t : k1), : (forall z_k1. k2) ~> k' defn no_conflict ( C , , ind1 , ind2 ) :: :: check_no_conflict :: 'NoConflict_' - {{ com \parbox{5in}{Branched axiom conflict checking, \coderef{types/OptCoercion.hs}{checkAxInstCo} \\ and \coderef{types/FamInstEnv.hs}{compatibleBranches} } }} + {{ com \parbox{5in}{Branched axiom conflict checking, \coderef{GHC/Core/Coercion/Opt.hs}{checkAxInstCo} \\ and \coderef{GHC/Core/FamInstEnv.hs}{compatibleBranches} } }} by ------------------------------------------------ :: NoBranch ===================================== docs/core-spec/CoreSyn.ott ===================================== @@ -34,19 +34,19 @@ indexvar i, j, kk {{ tex k }}, aa {{ tex a }}, bb {{ tex b }}, cc {{ tex c }} :: grammar lit {{ tex \textsf{lit} }} :: 'Literal_' ::= - {{ com Literals, \coderef{basicTypes/Literal.hs}{Literal} }} + {{ com Literals, \coderef{GHC/Types/Literal.hs}{Literal} }} z :: 'Name_' ::= {{ com Term or type name }} | alpha :: :: Type {{ com Type-level name }} | x :: :: Term {{ com Term-level name }} -n, m, aname {{ tex \alpha }}, xname {{ tex x }} :: 'Var_' ::= {{ com Variable names, \coderef{basicTypes/Var.hs}{Var} }} +n, m, aname {{ tex \alpha }}, xname {{ tex x }} :: 'Var_' ::= {{ com Variable names, \coderef{GHC/Types/Var.hs}{Var} }} | z _ t :: :: IdOrTyVar {{ com Name, labeled with type/kind }} {{ tex {[[z]]}^{[[t]]} }} | z $ :: M :: NoSupScript {{ com Name without an explicit type/kind }} | K :: M :: DataCon {{ com Data constructor }} -l :: 'Label_' ::= {{ com Labels for join points, also \coderef{basicTypes/Var.hs}{Var} }} +l :: 'Label_' ::= {{ com Labels for join points, also \coderef{GHC/Types/Var.hs}{Var} }} | p / I _ t :: :: Label {{ com Label with join arity and type }} {{ tex {[[p]]}_{[[I]]}^{[[t]]} }} @@ -64,7 +64,7 @@ labels :: 'Labels_' ::= {{ com List of labels }} | :: :: List | empty :: M :: empty -e, u :: 'Expr_' ::= {{ com Expressions, \coderef{coreSyn/CoreSyn.hs}{Expr} }} +e, u :: 'Expr_' ::= {{ com Expressions, \coderef{GHC/Core.hs}{Expr} }} | n :: :: Var {{ com \ctor{Var}: Variable }} | lit :: :: Lit {{ com \ctor{Lit}: Literal }} | e1 e2 :: :: App {{ com \ctor{App}: Application }} @@ -85,31 +85,31 @@ e, u :: 'Expr_' ::= {{ com Expressions, \coderef{coreSyn/CoreSyn.hs}{Expr} }} | \\ e :: M :: Newline {{ tex \qquad \\ \multicolumn{1}{r}{[[e]]} }} -binding :: 'Bind_' ::= {{ com Let-bindings, \coderef{coreSyn/CoreSyn.hs}{Bind} }} +binding :: 'Bind_' ::= {{ com Let-bindings, \coderef{GHC/Core.hs}{Bind} }} | n = e :: :: NonRec {{ com \ctor{NonRec}: Non-recursive binding }} | rec :: :: Rec {{ com \ctor{Rec}: Recursive binding }} -jbinding :: 'JoinBind_' ::= {{ com Join bindings, also \coderef{coreSyn/CoreSyn.hs}{Bind} }} +jbinding :: 'JoinBind_' ::= {{ com Join bindings, also \coderef{GHC/Core.hs}{Bind} }} | l = e :: :: NonRec {{ com \ctor{NonRec}: Non-recursive binding }} | rec = ei // i /> :: :: Rec {{ com \ctor{Rec}: Recursive binding }} -alt :: 'Alt_' ::= {{ com Case alternative, \coderef{coreSyn/CoreSyn.hs}{Alt} }} +alt :: 'Alt_' ::= {{ com Case alternative, \coderef{GHC/Core.hs}{Alt} }} | Kp -> e :: :: Alt {{ com Constructor applied to fresh names }} -tick :: 'Tickish_' ::= {{ com Internal notes, \coderef{coreSyn/CoreSyn.hs}{Tickish} }} +tick :: 'Tickish_' ::= {{ com Internal notes, \coderef{GHC/Core.hs}{Tickish} }} -Kp {{ tex \mathbb{K} }} :: 'AltCon_' ::= {{ com Constructors used in patterns, \coderef{coreSyn/CoreSyn.hs}{AltCon} }} +Kp {{ tex \mathbb{K} }} :: 'AltCon_' ::= {{ com Constructors used in patterns, \coderef{GHC/Core.hs}{AltCon} }} | K :: :: DataAlt {{ com \ctor{DataAlt}: Data constructor }} | lit :: :: LitAlt {{ com \ctor{LitAlt}: Literal (such as an integer or character) }} | _ :: :: DEFAULT {{ com \ctor{DEFAULT}: Wildcard }} -program :: 'CoreProgram_' ::= {{ com A System FC program, \coderef{coreSyn/CoreSyn.hs}{CoreProgram} }} +program :: 'CoreProgram_' ::= {{ com A System FC program, \coderef{GHC/Core.hs}{CoreProgram} }} | :: :: CoreProgram {{ com List of bindings }} %% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% t {{ tex \tau }}, k {{ tex \kappa }}, s {{ tex \sigma }}, phi {{ tex \phi }} - :: 'Type_' ::= {{ com Types/kinds, \coderef{types/TyCoRep.hs}{Type} }} + :: 'Type_' ::= {{ com Types/kinds, \coderef{GHC/Core/TyCo/Rep.hs}{Type} }} | n :: :: TyVarTy {{ com \ctor{TyVarTy}: Variable }} | t1 t2 :: :: AppTy {{ com \ctor{AppTy}: Application }} | T :: :: TyConApp {{ com \ctor{TyConApp}: Application of type constructor }} @@ -118,12 +118,12 @@ t {{ tex \tau }}, k {{ tex \kappa }}, s {{ tex \sigma }}, phi {{ tex \phi }} | lit :: :: LitTy {{ com \ctor{LitTy}: Type-level literal }} | t |> g :: :: CastTy {{ com \ctor{CastTy}: Kind cast }} | g :: :: CoercionTy {{ com \ctor{CoercionTy}: Coercion used in type }} - | tyConKind T :: M :: tyConKind {{ com \coderef{types/TyCon.hs}{tyConKind} }} + | tyConKind T :: M :: tyConKind {{ com \coderef{GHC/Core/TyCon.hs}{tyConKind} }} | t1 k1 ~# k2 t2 :: M :: unliftedEq {{ com Metanotation for coercion types }} {{ tex [[t1]] \mathop{ {}^{[[k1]]}\!\! \sim_{\#}^{[[k2]]} } [[t2]] }} | t1 k1 ~Rep# k2 t2 :: M :: unliftedREq {{ com Metanotation for coercion types }} {{ tex [[t1]] \mathop{ {}^{[[k1]]}\!\! \sim_{\mathsf{R}\#}^{[[k2]]} } [[t2]] }} - | literalType lit :: M :: literalType {{ com \coderef{basicTypes/Literal.hs}{literalType} }} + | literalType lit :: M :: literalType {{ com \coderef{GHC/Types/Literal.hs}{literalType} }} | ( t ) :: M :: parens {{ com Parentheses }} | { t } :: M :: IParens {{ com Invisible parentheses }} {{ tex [[t]] }} @@ -137,7 +137,7 @@ t {{ tex \tau }}, k {{ tex \kappa }}, s {{ tex \sigma }}, phi {{ tex \phi }} %% COERCIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -g {{ tex \gamma }}, h {{ tex \eta }} :: 'Coercion_' ::= {{ com Coercions, \coderef{types/TyCoRep.hs}{Coercion} }} +g {{ tex \gamma }}, h {{ tex \eta }} :: 'Coercion_' ::= {{ com Coercions, \coderef{GHC/Core/TyCo/Rep.hs}{Coercion} }} | < t > :: :: Refl {{ com \ctor{Refl}: Nominal Reflexivity }} {{ tex {\langle [[t]] \rangle} }} | < t > R mg :: :: GRefl {{ com \ctor{GRefl}: Generalized Reflexivity }} @@ -165,7 +165,7 @@ g {{ tex \gamma }}, h {{ tex \eta }} :: 'Coercion_' ::= {{ com Coercions, \coder | t $ liftingsubst :: M :: Lifted {{ com Type lifted to coercion }} | downgradeRole R g :: M :: downgradeRole {{ com \textsf{downgradeRole} }} -prov :: 'UnivCoProvenance_' ::= {{ com \ctor{UnivCo} provenance, \coderef{types/TyCoRep.hs}{UnivCoProvenance} }} +prov :: 'UnivCoProvenance_' ::= {{ com \ctor{UnivCo} provenance, \coderef{GHC/Core/TyCo/Rep.hs}{UnivCoProvenance} }} | UnsafeCoerceProv :: :: UnsafeCoerceProv {{ com From \texttt{unsafeCoerce\#} }} {{ tex \mathsf{unsafe} }} | PhantomProv :: :: PhantomProv {{ com From the need for a phantom coercion }} @@ -173,20 +173,20 @@ prov :: 'UnivCoProvenance_' ::= {{ com \ctor{UnivCo} provenance, \coderef{types/ | ProofIrrelProv :: :: ProofIrrelProv {{ com From proof irrelevance }} {{ tex \mathsf{irrel} }} -mg {{ tex m }} :: 'MCoercion_' ::= {{ com A possibly reflexive coercion , \coderef{types/TyCoRep.hs}{MCoercion} }} +mg {{ tex m }} :: 'MCoercion_' ::= {{ com A possibly reflexive coercion , \coderef{GHC/Core/TyCo/Rep.hs}{MCoercion} }} | MRefl :: :: MRefl {{ com \ctor{MRefl}: A trivial reflexive coercion }} | MCo g :: :: MCo {{ com \ctor{MCo}: Other coercions }} {{ tex [[g]] }} -LorR :: 'LeftOrRight_' ::= {{ com left or right deconstructor, \coderef{types/TyCoRep.hs}{LeftOrRight} }} +LorR :: 'LeftOrRight_' ::= {{ com left or right deconstructor, \coderef{GHC/Core/TyCo/Rep.hs}{LeftOrRight} }} | Left :: :: CLeft {{ com \ctor{CLeft}: Left projection }} | Right :: :: CRight {{ com \ctor{CRight}: Right projection }} -C :: 'CoAxiom_' ::= {{ com Axioms, \coderef{types/TyCon.hs}{CoAxiom} }} +C :: 'CoAxiom_' ::= {{ com Axioms, \coderef{GHC/Core/TyCon.hs}{CoAxiom} }} | T RA :: :: CoAxiom {{ com \ctor{CoAxiom}: Axiom }} | ( C ) :: M :: Parens {{ com Parentheses }} -R {{ tex \rho }} :: 'Role_' ::= {{ com Roles, \coderef{types/CoAxiom.hs}{Role} }} +R {{ tex \rho }} :: 'Role_' ::= {{ com Roles, \coderef{GHC/Core/Coercion/Axiom.hs}{Role} }} | Nom :: :: Nominal {{ com Nominal }} {{ tex \mathsf{N} }} | Rep :: :: Representational {{ com Representational }} @@ -195,17 +195,17 @@ R {{ tex \rho }} :: 'Role_' ::= {{ com Roles, \coderef{types/CoAxiom.hs}{Role} } {{ tex \mathsf{P} }} | role_list [ i ] :: M :: RoleListIndex {{ com Look up in list }} -axBranch, b :: 'CoAxBranch_' ::= {{ com Axiom branches, \coderef{types/TyCon.hs}{CoAxBranch} }} +axBranch, b :: 'CoAxBranch_' ::= {{ com Axiom branches, \coderef{GHC/Core/TyCon.hs}{CoAxBranch} }} | forall . ( ~> s ) :: :: CoAxBranch {{ com \ctor{CoAxBranch}: Axiom branch }} | ( ) [ ind ] :: M :: lookup {{ com List lookup }} -mu {{ tex \mu }} :: 'CoAxiomRule_' ::= {{ com CoAxiomRules, \coderef{types/CoAxiom.hs}{CoAxiomRule} }} +mu {{ tex \mu }} :: 'CoAxiomRule_' ::= {{ com CoAxiomRules, \coderef{GHC/Core/Coercion/Axiom.hs}{CoAxiomRule} }} | M ( I , role_list , R' ) :: :: CoAxiomRule {{ com Named rule, with parameter info }} {{ tex {[[M]]}_{([[I]], [[ role_list ]], [[R']])} }} %% TYCONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -T :: 'TyCon_' ::= {{ com Type constructors, \coderef{types/TyCon.hs}{TyCon} }} +T :: 'TyCon_' ::= {{ com Type constructors, \coderef{GHC/Core/TyCon.hs}{TyCon} }} | ( -> ) :: :: FunTyCon {{ com \ctor{FunTyCon}: Arrow }} % the following also includes TupleTyCon, SynTyCon @@ -226,22 +226,22 @@ H :: 'PrimTyCon_' ::= {{ com Primitive type constructors, \coderef{GHC.Builtin.T | TYPE :: :: TYPE {{ com TYPE (\texttt{tYPETyCon}) }} | Levity :: :: Levity {{ com Levity (\texttt{LevityTyCon}) }} -K :: 'DataCon_' ::= {{ com Data constructors, \coderef{basicTypes/DataCon.hs}{DataCon} }} +K :: 'DataCon_' ::= {{ com Data constructors, \coderef{GHC/Core/DataCon.hs}{DataCon} }} | Lifted :: :: Lifted {{ com \ctor{Lifted}, a lifted type }} | Unlifted :: :: Unlifted {{ com \ctor{Unlifted}, an unlifted type }} %% CONTEXTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -G {{ tex \Gamma }} :: 'LintM_Bindings_' ::= {{ com List of bindings, \coderef{coreSyn/CoreLint.hs}{LintM} }} +G {{ tex \Gamma }} :: 'LintM_Bindings_' ::= {{ com List of bindings, \coderef{GHC/Core/Lint.hs}{LintM} }} | n :: :: Binding {{ com Single binding }} | :: :: Concat {{ com Context concatenation }} - | vars_of binding :: M :: VarsOf {{ com \coderef{coreSyn/CoreSyn.hs}{bindersOf} }} + | vars_of binding :: M :: VarsOf {{ com \coderef{GHC/Core.hs}{bindersOf} }} -D {{ tex \Delta }} :: 'LintM_JoinBindings_' ::= {{ com List of join bindings, \coderef{coreSyn/CoreLint.hs}{LintM} }} +D {{ tex \Delta }} :: 'LintM_JoinBindings_' ::= {{ com List of join bindings, \coderef{GHC/Core/Lint.hs}{LintM} }} | l :: :: Binding {{ com Single binding }} | :: :: Concat {{ com Context concatenation }} | empty :: M :: Empty {{ com Empty context }} - | labels_of binding :: M :: LabelsOf {{ com \coderef{coreSyn/CoreSyn.hs}{bindersOf} }} + | labels_of binding :: M :: LabelsOf {{ com \coderef{GHC/Core.hs}{bindersOf} }} O {{ tex \Omega }} :: 'VarEnv_Role_' ::= {{ com Mapping from type variables to roles }} | :: :: List {{ com List of bindings }} ===================================== docs/core-spec/README ===================================== @@ -30,7 +30,7 @@ into LaTeX math-mode code. Thus, the file core-spec.mng is the source for core-spec.tex, which gets processed into core-spec.pdf. The file CoreSyn.ott contains the grammar of System FC, mostly extracted from -compiler/coreSyn/CoreSyn.hs. Here are a few pointers to help those of you +compiler/GHC/Core.hs. Here are a few pointers to help those of you unfamiliar with Ott: - The {{ ... }} snippets are called "homs", and they assist ott in translating @@ -69,7 +69,7 @@ your notation to LaTeX. Three different homs are used: it if necessary to disambiguate other parses. The file CoreLint.ott contains inductively defined judgements for many of the -functions in compiler/coreSyn/CoreLint.hs. Each judgement is labeled with an +functions in compiler/GHC/Core/Lint.hs. Each judgement is labeled with an abbreviation to distinguish it from the others. These abbreviations appear in the source code right after a turnstile |-. The declaration for each judgment contains a reference to the function it represents. Each rule is labeled with ===================================== docs/core-spec/core-spec.mng ===================================== @@ -31,7 +31,7 @@ System FC, as implemented in GHC\footnote{This document was originally prepared by Richard Eisenberg (\texttt{eir at cis.upenn.edu}), but it should be maintained by anyone who edits the functions or data structures mentioned in this file. Please feel free to contact Richard for more information.}\\ -\Large 26 January, 2018 +\Large 26 May, 2020 \end{center} \section{Introduction} @@ -72,8 +72,8 @@ Literals do not play a major role, so we leave them abstract: \gram{\ottlit} -We also leave abstract the function \coderef{basicTypes/Literal.hs}{literalType} -and the judgment \coderef{coreSyn/CoreLint.hs}{lintTyLit} (written $[[G |-tylit lit : k]]$). +We also leave abstract the function \coderef{GHC/Types/Literal.hs}{literalType} +and the judgment \coderef{GHC/Core/Lint.hs}{lintTyLit} (written $[[G |-tylit lit : k]]$). \subsection{Variables} \enlargethispage{10pt} % without this first line of "z" definition is placed on @@ -351,13 +351,13 @@ fresh in the context. In the implementation, of course, some work is done to guarantee this freshness. In particular, adding a new type variable to the context sometimes requires creating a new, fresh variable name and then applying a substitution. We elide these details in this formalism, but -see \coderef{types/Type.hs}{substTyVarBndr} for details. +see \coderef{GHC/Core/Type.hs}{substTyVarBndr} for details. \section{Typing judgments} The following functions are used from GHC. Their names are descriptive, and they -are not formalized here: \coderef{types/TyCon.hs}{tyConKind}, -\coderef{types/TyCon.hs}{tyConArity}, \coderef{basicTypes/DataCon.hs}{dataConTyCon}, \coderef{types/TyCon.hs}{isNewTyCon}, \coderef{basicTypes/DataCon.hs}{dataConRepType}. +are not formalized here: \coderef{GHC/Core/TyCon.hs}{tyConKind}, +\coderef{GHC/Core/TyCon.hs}{tyConArity}, \coderef{GHC/Core/DataCon.hs}{dataConTyCon}, \coderef{GHC/Core/TyCon.hs}{isNewTyCon}, \coderef{GHC/Core/DataCon.hs}{dataConRepType}. \subsection{Program consistency} @@ -367,7 +367,7 @@ and then check each binding. \ottdefnlintCoreBindings{} -Here is the definition of $[[vars_of]]$, taken from \coderef{coreSyn/CoreSyn.hs}{bindersOf}: +Here is the definition of $[[vars_of]]$, taken from \coderef{GHC/Core.hs}{bindersOf}: \[ \begin{array}{ll} @@ -413,11 +413,11 @@ to check each substituted type $[[s'i]]$ in a context containing all the types that come before it in the list of bindings. The $[[G'i]]$ are contexts containing the names and kinds of all type variables (and term variables, for that matter) up to the $i$th binding. This logic is extracted from -\coderef{coreSyn/CoreLint.hs}{lintAndScopeIds}. +\coderef{GHC/Core/Lint.hs}{lintAndScopeIds}. \item The GHC source code checks all arguments in an application expression -all at once using \coderef{coreSyn/CoreSyn.hs}{collectArgs} -and \coderef{coreSyn/CoreLint.hs}{lintCoreArgs}. The operation +all at once using \coderef{GHC/Core.hs}{collectArgs} +and \coderef{GHC/Core/Lint.hs}{lintCoreArgs}. The operation has been unfolded for presentation here. \item If a $[[tick]]$ contains breakpoints, the GHC source performs additional @@ -481,7 +481,7 @@ We believe both technical approaches are equivalent in what coercions they accep \label{sec:name_consistency} There are three very similar checks for names, two performed as part of -\coderef{coreSyn/CoreLint.hs}{lintSingleBinding}: +\coderef{GHC/Core/Lint.hs}{lintSingleBinding}: \ottdefnlintSingleBindingXXlintBinder{} @@ -565,12 +565,12 @@ The judgment $[[apart]]$ checks to see whether two lists of types are surely apart. $[[apart( , )]]$, where $[[ ]]$ is a list of types and $[[ ]]$ is a list of type \emph{patterns} (as in a type family equation), first flattens the $[[ ]]$ using \coderef{types/FamInstEnv.hs}{flattenTys} and then checks to -see if \coderef{types/Unify.hs}{tcUnifyTysFG} returns \texttt{SurelyApart}. + // i /> ]]$ using \coderef{GHC/Core/FamInstEnv.hs}{flattenTys} and then checks to +see if \coderef{GHC/Core/Unify.hs}{tcUnifyTysFG} returns \texttt{SurelyApart}. Flattening takes all type family applications and replaces them with fresh variables, taking care to map identical type family applications to the same fresh variable. -The algorithm $[[unify]]$ is implemented in \coderef{types/Unify.hs}{tcUnifyTys}. +The algorithm $[[unify]]$ is implemented in \coderef{GHC/Core/Unify.hs}{tcUnifyTys}. It performs a standard unification, returning a substitution upon success. \section{Operational semantics} @@ -579,7 +579,7 @@ It performs a standard unification, returning a substitution upon success. GHC does not implement an operational semantics in any concrete form. Most of the rules below are implied by algorithms in, for example, the simplifier and optimizer. Yet, there is no one place in GHC that states these rules, -analogously to \texttt{CoreLint.hs}. +analogously to \texttt{GHC/Core/Lint.hs}. Nevertheless, these rules are included in this document to help the reader understand System FC. @@ -607,17 +607,17 @@ to the constructor. The terms are the regular term arguments stored in an algebraic datatype. Coercions (say, in a GADT) are considered term arguments. \item The rule \ottdrulename{S\_CasePush} is the most complex rule. \begin{itemize} -\item The logic in this rule is implemented in \coderef{coreSyn/CoreSubst.hs}{exprIsConApp\_maybe}. -\item The $[[coercionKind]]$ function (\coderef{types/Coercion.hs}{coercionKind}) +\item The logic in this rule is implemented in \coderef{GHC/Core/Subst.hs}{exprIsConApp\_maybe}. +\item The $[[coercionKind]]$ function (\coderef{GHC/Core/Coercion.hs}{coercionKind}) extracts the two types (and their kinds) from a coercion. It does not require a typing context, as it does not \emph{check} the coercion, just extracts its types. -\item The $[[dataConRepType]]$ function (\coderef{basicTypes/DataCon.hs}{dataConRepType}) extracts the full type of a data constructor. Following the notation for +\item The $[[dataConRepType]]$ function (\coderef{GHC/Core/DataCon.hs}{dataConRepType}) extracts the full type of a data constructor. Following the notation for constructor expressions, the parameters to the constructor are broken into three groups: universally quantified types, existentially quantified types, and terms. \item The substitutions in the last premise to the rule are unusual: they replace \emph{type} variables with \emph{coercions}. This substitution is called lifting -and is implemented in \coderef{types/Coercion.hs}{liftCoSubst}. The notation is +and is implemented in \coderef{GHC/Core/Coercion.hs}{liftCoSubst}. The notation is essentially a pun on the fact that types and coercions have such similar structure. This operation is quite non-trivial. Please see \emph{System FC with Explicit Kind Equality} for details. ===================================== docs/core-spec/core-spec.pdf ===================================== Binary files a/docs/core-spec/core-spec.pdf and b/docs/core-spec/core-spec.pdf differ ===================================== docs/users_guide/using-optimisation.rst ===================================== @@ -655,14 +655,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/ghci/T18060/T18060.script ===================================== @@ -0,0 +1,2 @@ +:i -> +:i ~ ===================================== testsuite/tests/ghci/T18060/T18060.stdout ===================================== @@ -0,0 +1,12 @@ +type (->) :: * -> * -> * +data (->) a b + -- Defined in ‘GHC.Prim’ +infixr -1 -> +instance Applicative ((->) r) -- Defined in ‘GHC.Base’ +instance Functor ((->) r) -- Defined in ‘GHC.Base’ +instance Monad ((->) r) -- Defined in ‘GHC.Base’ +instance Monoid b => Monoid (a -> b) -- Defined in ‘GHC.Base’ +instance Semigroup b => Semigroup (a -> b) -- Defined in ‘GHC.Base’ +type (~) :: forall k. k -> k -> Constraint +class (a ~ b) => (~) a b + -- Defined in ‘GHC.Types’ ===================================== testsuite/tests/ghci/T18060/all.T ===================================== @@ -0,0 +1 @@ +test('T18060', normal, ghci_script, ['T18060.script']) ===================================== testsuite/tests/hiefile/should_compile/Scopes.hs ===================================== @@ -1,10 +1,33 @@ +{-# LANGUAGE PatternSynonyms, ViewPatterns #-} +{-# LANGUAGE ImplicitParams #-} {-# LANGUAGE RecordWildCards #-} module Scopes where + +-- Verify that evidence bound by patern +-- synonyms has correct scope +pattern LL :: Num a => a -> a +pattern LL x <- (subtract 1 -> x) + where + LL x = x + 1 + data T = C { x :: Int, y :: Char } --- Verify that names generated from record construction are in scope +-- Verify that names generated from record construction +-- have correct scope foo = C { x = 1 , y = 'a' } +-- Verify that implicit paramters have correct scope +bar :: (?x :: Int) => Int +bar = ?x + 1 + +baz :: Int +baz = bar + ?x + where ?x = 2 + +-- Verify that variables bound in pattern +-- synonyms have the correct scope +pattern A a b = (a , b) + -- Verify that record wildcards are in scope sdaf :: T sdaf = C{..} ===================================== testsuite/tests/hiefile/should_run/HieQueries.hs ===================================== @@ -0,0 +1,82 @@ +{-# LANGUAGE ScopedTypeVariables #-} +module Main where + +import System.Environment + +import GHC.Types.Name.Cache +import GHC.Types.SrcLoc +import GHC.Types.Unique.Supply +import GHC.Types.Name +import Data.Tree +import GHC.Iface.Ext.Binary +import GHC.Iface.Ext.Types +import GHC.Iface.Ext.Utils +import Data.Maybe (fromJust) +import GHC.Driver.Session +import GHC.SysTools +import GHC.Utils.Outputable ( Outputable, renderWithStyle, ppr, defaultUserStyle, initSDocContext, text) +import qualified Data.Map as M +import Data.Foldable + +class C a where + f :: a -> Char + +instance C Char where + f x = x + +instance C a => C [a] where + f x = 'a' + +foo :: C a => a -> Char +foo x = f [x] +-- ^ this is the point +point :: (Int,Int) +point = (31,9) + +bar :: Show x => x -> String +bar x = show [(1,x,A)] +-- ^ this is the point' +point' :: (Int,Int) +point' = (37,9) + +data A = A deriving Show + +makeNc :: IO NameCache +makeNc = do + uniq_supply <- mkSplitUniqSupply 'z' + return $ initNameCache uniq_supply [] + +dynFlagsForPrinting :: String -> IO DynFlags +dynFlagsForPrinting libdir = do + systemSettings <- initSysTools libdir + return $ defaultDynFlags systemSettings (LlvmConfig [] []) + +main = do + libdir:_ <- getArgs + df <- dynFlagsForPrinting libdir + nc <- makeNc + hfr <- readHieFile (NCU (\f -> pure $ snd $ f nc)) "HieQueries.hie" + let hf = hie_file_result hfr + refmap = generateReferencesMap $ getAsts $ hie_asts hf + explainEv df hf refmap point + explainEv df hf refmap point' + return () + +explainEv :: DynFlags -> HieFile -> RefMap Int -> (Int,Int) -> IO () +explainEv df hf refmap point = do + putStrLn $ replicate 26 '=' + putStrLn $ "At point " ++ show point ++ ", we found:" + putStrLn $ replicate 26 '=' + putStr $ drawForest ptrees + where + trees = getEvidenceTreesAtPoint hf refmap point + + ptrees = fmap (pprint . fmap expandType) <$> trees + + expandType = text . renderHieType df . + flip recoverFullType (hie_types hf) + + pretty = unlines . (++["└"]) . ("┌":) . map ("│ "++) . lines + + pprint = pretty . renderWithStyle (initSDocContext df sty) . ppr + sty = defaultUserStyle ===================================== testsuite/tests/hiefile/should_run/HieQueries.stdout ===================================== @@ -0,0 +1,98 @@ +========================== +At point (31,9), we found: +========================== +┌ +│ $dC at HieQueries.hs:31:1-13, of type: C [a] +│ is an evidence variable bound by a let, depending on: [$fC[], $dC] +│ with scope: LocalScope HieQueries.hs:31:1-13 +│ bound at: HieQueries.hs:31:1-13 +│ Defined at +└ +| ++- ┌ +| │ $fC[] at HieQueries.hs:27:10-21, of type: forall a. C a => C [a] +| │ is an evidence variable bound by an instance of class C +| │ with scope: ModuleScope +| │ +| │ Defined at HieQueries.hs:27:10 +| └ +| +`- ┌ + │ $dC at HieQueries.hs:31:1-13, of type: C a + │ is an evidence variable bound by a type signature + │ with scope: LocalScope HieQueries.hs:31:1-13 + │ bound at: HieQueries.hs:31:1-13 + │ Defined at + └ + +========================== +At point (37,9), we found: +========================== +┌ +│ $dShow at HieQueries.hs:37:1-22, of type: Show [(Integer, x, A)] +│ is an evidence variable bound by a let, depending on: [$fShow[], +│ $dShow] +│ with scope: LocalScope HieQueries.hs:37:1-22 +│ bound at: HieQueries.hs:37:1-22 +│ Defined at +└ +| ++- ┌ +| │ $fShow[] at HieQueries.hs:37:1-22, of type: forall a. Show a => Show [a] +| │ is a usage of an external evidence variable +| │ Defined in `GHC.Show' +| └ +| +`- ┌ + │ $dShow at HieQueries.hs:37:1-22, of type: Show (Integer, x, A) + │ is an evidence variable bound by a let, depending on: [$fShow(,,), + │ $dShow, $dShow, $dShow] + │ with scope: LocalScope HieQueries.hs:37:1-22 + │ bound at: HieQueries.hs:37:1-22 + │ Defined at + └ + | + +- ┌ + | │ $fShow(,,) at HieQueries.hs:37:1-22, of type: forall a b c. (Show a, Show b, Show c) => Show (a, b, c) + | │ is a usage of an external evidence variable + | │ Defined in `GHC.Show' + | └ + | + +- ┌ + | │ $dShow at HieQueries.hs:37:1-22, of type: Show Integer + | │ is an evidence variable bound by a let, depending on: [$fShowInteger] + | │ with scope: LocalScope HieQueries.hs:37:1-22 + | │ bound at: HieQueries.hs:37:1-22 + | │ Defined at + | └ + | | + | `- ┌ + | │ $fShowInteger at HieQueries.hs:37:1-22, of type: Show Integer + | │ is a usage of an external evidence variable + | │ Defined in `GHC.Show' + | └ + | + +- ┌ + | │ $dShow at HieQueries.hs:37:1-22, of type: Show x + | │ is an evidence variable bound by a type signature + | │ with scope: LocalScope HieQueries.hs:37:1-22 + | │ bound at: HieQueries.hs:37:1-22 + | │ Defined at + | └ + | + `- ┌ + │ $dShow at HieQueries.hs:37:1-22, of type: Show A + │ is an evidence variable bound by a let, depending on: [$fShowA] + │ with scope: LocalScope HieQueries.hs:37:1-22 + │ bound at: HieQueries.hs:37:1-22 + │ Defined at + └ + | + `- ┌ + │ $fShowA at HieQueries.hs:42:21-24, of type: Show A + │ is an evidence variable bound by an instance of class Show + │ with scope: ModuleScope + │ + │ Defined at HieQueries.hs:42:21 + └ + ===================================== testsuite/tests/hiefile/should_run/PatTypes.hs ===================================== @@ -42,16 +42,9 @@ dynFlagsForPrinting libdir = do systemSettings <- initSysTools libdir return $ defaultDynFlags systemSettings (LlvmConfig [] []) -selectPoint :: HieFile -> (Int,Int) -> HieAST Int -selectPoint hf (sl,sc) = case M.toList (getAsts $ hie_asts hf) of - [(fs,ast)] -> - case selectSmallestContaining (sp fs) ast of - Nothing -> error "point not found" - Just ast' -> ast' - _ -> error "map should only contain a single AST" - where - sloc fs = mkRealSrcLoc fs sl sc - sp fs = mkRealSrcSpan (sloc fs) (sloc fs) +selectPoint' :: HieFile -> (Int,Int) -> HieAST Int +selectPoint' hf loc = + maybe (error "point not found") id $ selectPoint hf loc main = do libdir:_ <- getArgs @@ -61,6 +54,6 @@ main = do let hf = hie_file_result hfr forM_ [p1,p2,p3,p4] $ \point -> do putStr $ "At " ++ show point ++ ", got type: " - let types = nodeType $ nodeInfo $ selectPoint hf point + let types = concatMap nodeType $ getSourcedNodeInfo $ sourcedNodeInfo $ selectPoint' hf point forM_ types $ \typ -> do putStrLn (renderHieType df $ recoverFullType typ (hie_types hf)) ===================================== testsuite/tests/hiefile/should_run/all.T ===================================== @@ -1 +1,2 @@ test('PatTypes', [extra_run_opts('"' + config.libdir + '"')], compile_and_run, ['-package ghc -fwrite-ide-info']) +test('HieQueries', [extra_run_opts('"' + config.libdir + '"')], compile_and_run, ['-package ghc -fwrite-ide-info']) ===================================== 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 ===================================== @@ -52,3 +52,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']) test('T13380b', [ grep_errmsg('bigDeadAction') ], 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']) ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 8f340aef12df5f5df02d49ab5c6c5d7cccfa398b +Subproject commit 8134a3be2c01ab5f1b88fed86c4ad7cc2f417f0a View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/38ad4a1965699128fb4858fc2b1fd8022cc9df49...d293975d3477749ad378ecbce0ca1c0249f9c03a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/38ad4a1965699128fb4858fc2b1fd8022cc9df49...d293975d3477749ad378ecbce0ca1c0249f9c03a You're receiving 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 26 16:50:49 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Tue, 26 May 2020 12:50:49 -0400 Subject: [Git][ghc/ghc][wip/T17775] 31 commits: docs: fix formatting and add some links Message-ID: <5ecd48e97a367_6e263f9f01f3c480174843f@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: d830bbc9 by Adam Sandberg Ericsson at 2020-05-23T13:36:20-04:00 docs: fix formatting and add some links [skip ci] - - - - - 49301ad6 by Andrew Martin at 2020-05-23T13:37:01-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. - - - - - dcd6bdcc by Ben Gamari at 2020-05-23T13:37:48-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. - - - - - 82cb8913 by John Ericson at 2020-05-23T13:38:32-04:00 Fix #18145 and also avoid needless work with implicit vars - `forAllOrNothing` now is monadic, so we can trace whether we bind an explicit `forall` or not. - #18145 arose because the free vars calculation was needlessly complex. It is now greatly simplified. - Replaced some other implicit var code with `filterFreeVarsToBind`. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - a60dc835 by Ben Gamari at 2020-05-23T13:39:12-04:00 Bump process submodule Fixes #17926. - - - - - 856adf54 by Ben Gamari at 2020-05-23T13:40:21-04:00 users-guide: Clarify meaning of -haddock flag Fixes #18206. - - - - - 7ae57afd by Ben Gamari at 2020-05-23T13:41:03-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 - - - - - 63d30e60 by jneira at 2020-05-24T01:54:42-04:00 Add hie-bios script for windows systems It is a direct translation of the sh script - - - - - 59182b88 by jneira at 2020-05-24T01:54:42-04:00 Honour previous values for CABAL and CABFLAGS The immediate goal is let the hie-bios.bat script set CABFLAGS with `-v0` and remove all cabal output except the compiler arguments - - - - - 932dc54e by jneira at 2020-05-24T01:54:42-04:00 Add specific configuration for windows in hie.yaml - - - - - e0eda070 by jneira at 2020-05-24T01:54:42-04:00 Remove not needed hie-bios output - - - - - a0ea59d6 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Move Config module into GHC.Settings - - - - - 37430251 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Core.Arity into GHC.Core.Opt.Arity - - - - - a426abb9 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Hs.Types into GHC.Hs.Type See discussion in https://gitlab.haskell.org/ghc/ghc/issues/13009#note_268610 - - - - - 1c91a7a0 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Bump haddock submodule - - - - - 66bd24d1 by Ryan Scott at 2020-05-24T01:56:03-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. - - - - - 01c43634 by Matthew Pickering at 2020-05-24T01:56:42-04:00 Remove unused hs-boot file - - - - - 7a07aa71 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix cross-compiler build (#16051) - - - - - 15ccca16 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix distDir per stage - - - - - b420fb24 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix hp2ps error during cross-compilation Fixed by @alp (see https://gitlab.haskell.org/ghc/ghc/issues/16051#note_274265) - - - - - cd339ef0 by Joshua Price at 2020-05-24T15:22:56-04:00 Make Unicode brackets opening/closing tokens (#18225) The tokens `[|`, `|]`, `(|`, and `|)` are opening/closing tokens as described in GHC Proposal #229. This commit makes the unicode variants (`⟦`, `⟧`, `⦇`, and `⦈`) act the same as their ASCII counterparts. - - - - - 013d7120 by Ben Gamari at 2020-05-25T09:48:17-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. - - - - - 4c4312ed by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Drop redundant ad-hoc boot module check To determine whether the module is a boot module Coverage.addTicksToBinds was checking for a `boot` suffix in the module source filename. This is quite ad-hoc and shouldn't be necessary; the callsite in `deSugar` already checks that the module isn't a boot module. - - - - - 1abf3c84 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make tickBoxCount strict This could otherwise easily cause a leak of (+) thunks. - - - - - b2813750 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make ccIndices strict This just seems like a good idea. - - - - - 02e278eb by Ben Gamari at 2020-05-25T09:48:53-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. - - - - - b8c014ce by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Factor out addMixEntry - - - - - 53814a64 by Zubin Duggal at 2020-05-26T03:03:24-04:00 Add info about typeclass evidence to .hie files See `testsuite/tests/hiefile/should_run/HieQueries.hs` and `testsuite/tests/hiefile/should_run/HieQueries.stdout` for an example of this We add two new fields, `EvidenceVarBind` and `EvidenceVarUse` to the `ContextInfo` associated with an Identifier. These are associated with the appropriate identifiers for the evidence variables collected when we come across `HsWrappers`, `TcEvBinds` and `IPBinds` while traversing the AST. Instance dictionary and superclass selector dictionaries from `tcg_insts` and classes defined in `tcg_tcs` are also recorded in the AST as originating from their definition span This allows us to save a complete picture of the evidence constructed by the constraint solver, and will let us report this to the user, enabling features like going to the instance definition from the invocation of a class method(or any other method taking a constraint) and finding all usages of a particular instance. Additionally, - Mark NodeInfo with an origin so we can differentiate between bindings origininating in the source vs those in ghc - Along with typeclass evidence info, also include information on Implicit Parameters - Add a few utility functions to HieUtils in order to query the new info Updates haddock submodule - - - - - 6604906c by Sebastian Graf at 2020-05-26T03:04:04-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. - - - - - cf772f19 by Sylvain Henry at 2020-05-26T03:04:45-04:00 Enhance Note [About units] for Backpack - - - - - 7d3b9ac7 by Simon Peyton Jones at 2020-05-26T17:49:50+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 Updates Cabal submodule. - - - - - 30 changed files: - + .git-ignore-revs - compiler/GHC/Builtin/Names.hs - − compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Types.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Arity.hs → compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/CallArity.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/DmdAnal.hs - compiler/GHC/Core/Opt/FloatOut.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/Rules.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Data/FastString.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/1d118923df3e58c1b6bd39855e32fd48188c2bc3...7d3b9ac7dd3bec8d8c96b652382151922f1ea9c3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1d118923df3e58c1b6bd39855e32fd48188c2bc3...7d3b9ac7dd3bec8d8c96b652382151922f1ea9c3 You're receiving 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 26 18:08:28 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Tue, 26 May 2020 14:08:28 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/andreask/inlineable_mapAccumLM Message-ID: <5ecd5b1c6ba33_6e26115afe7c17629d2@gitlab.haskell.org.mail> Andreas Klebinger pushed new branch wip/andreask/inlineable_mapAccumLM at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/andreask/inlineable_mapAccumLM You're receiving 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 26 18:15:03 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Tue, 26 May 2020 14:15:03 -0400 Subject: [Git][ghc/ghc][wip/bump-base] base: Bump to 4.15.0.0 Message-ID: <5ecd5ca75536a_6e26115afe7c1764594@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/bump-base at Glasgow Haskell Compiler / GHC Commits: 1a30919b by Ben Gamari at 2020-05-26T14:14:53-04:00 base: Bump to 4.15.0.0 - - - - - 20 changed files: - compiler/ghc.cabal.in - libraries/array - libraries/base/base.cabal - libraries/deepseq - libraries/directory - libraries/filepath - libraries/ghc-boot-th/ghc-boot-th.cabal.in - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghc-compact/ghc-compact.cabal - libraries/ghci/ghci.cabal.in - libraries/haskeline - libraries/hpc - libraries/parsec - libraries/process - libraries/stm - libraries/template-haskell/template-haskell.cabal.in - libraries/terminfo - libraries/unix - utils/haddock - utils/hsc2hs Changes: ===================================== compiler/ghc.cabal.in ===================================== @@ -59,7 +59,7 @@ Library Default-Language: Haskell2010 Exposed: False - Build-Depends: base >= 4.11 && < 4.15, + Build-Depends: base >= 4.11 && < 4.16, deepseq >= 1.4 && < 1.5, directory >= 1 && < 1.4, process >= 1 && < 1.7, ===================================== libraries/array ===================================== @@ -1 +1 @@ -Subproject commit f73f681e52546b1e35cb9e8a62fe49c33f259d98 +Subproject commit ab535173d7885ebfc2005d8da2765f0f52c923ce ===================================== 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 ===================================== libraries/deepseq ===================================== @@ -1 +1 @@ -Subproject commit da0eda33f540786b6823c6f542ab59cf9d1b71d9 +Subproject commit 13c1c84415da727ab56e9fa33aca5046b6683848 ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit 36bd1921258b759724a95ce56c5e880edf0972a2 +Subproject commit 0dcb228388a6e306c11f419c7c5575eaa6af40b3 ===================================== libraries/filepath ===================================== @@ -1 +1 @@ -Subproject commit 023eedaeb142d47b7b5a41fe4cc4150da0bd0042 +Subproject commit 7cb3dc285cd595a7b6cf0b74a58b6583fb67772e ===================================== libraries/ghc-boot-th/ghc-boot-th.cabal.in ===================================== @@ -36,4 +36,4 @@ Library GHC.ForeignSrcLang.Type GHC.Lexeme - build-depends: base >= 4.7 && < 4.15 + build-depends: base >= 4.7 && < 4.16 ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -55,7 +55,7 @@ Library -- GHC.Version -- GHC.Platform.Host - build-depends: base >= 4.7 && < 4.15, + build-depends: base >= 4.7 && < 4.16, binary == 0.8.*, bytestring == 0.10.*, containers >= 0.5 && < 0.7, ===================================== libraries/ghc-compact/ghc-compact.cabal ===================================== @@ -37,7 +37,7 @@ library CPP build-depends: ghc-prim >= 0.5.3 && < 0.7, - base >= 4.9.0 && < 4.15, + base >= 4.9.0 && < 4.16, bytestring >= 0.10.6.0 ghc-options: -Wall ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -72,7 +72,7 @@ library Build-Depends: array == 0.5.*, - base >= 4.8 && < 4.15, + base >= 4.8 && < 4.16, binary == 0.8.*, bytestring == 0.10.*, containers >= 0.5 && < 0.7, ===================================== libraries/haskeline ===================================== @@ -1 +1 @@ -Subproject commit 463fc49d17bfab846cceba48bccc02ef285e6cba +Subproject commit 0382e3acdb8433e1d9c33ca5947784e78134f838 ===================================== libraries/hpc ===================================== @@ -1 +1 @@ -Subproject commit f73c482db30a40cfa12074de51335b70a0974931 +Subproject commit 43bb9061a748aee6a95a9f1db33a2b1e5f770634 ===================================== libraries/parsec ===================================== @@ -1 +1 @@ -Subproject commit ce416997e15438ca616667995660e123ef7e219d +Subproject commit 190492494fe92e8dd42165190b7ac112be1f7389 ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit 1afc36ecd38c069251a836e1c1c8b3a3043ddc01 +Subproject commit 8f4ecebb6578a179a6c04074cb06600683e2e50c ===================================== libraries/stm ===================================== @@ -1 +1 @@ -Subproject commit faf9904137044e35a589c7c1579e1bfa03789c84 +Subproject commit 444f672416a354c3cfde9d94ec237a36be46ef59 ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -55,7 +55,7 @@ Library Language.Haskell.TH.Lib.Map build-depends: - base >= 4.11 && < 4.15, + base >= 4.11 && < 4.16, ghc-boot-th == @ProjectVersionMunged@, ghc-prim, pretty == 1.1.* ===================================== libraries/terminfo ===================================== @@ -1 +1 @@ -Subproject commit 27e694688d2d6eee69959a8b6a128c584c84aa72 +Subproject commit 3ebb36f4a2c42b74ec4e35efccc2be34c198a830 ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 1a993b89c570e03ba74f196f5d065a0ebe624010 +Subproject commit ea13d990580273a883368793dfbb826cab5a22d4 ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 8f340aef12df5f5df02d49ab5c6c5d7cccfa398b +Subproject commit be2dfbd166f6bb0790ad94f0b4b9a90f02849d84 ===================================== utils/hsc2hs ===================================== @@ -1 +1 @@ -Subproject commit 24100ea521596922d3edc8370b3d9f7b845ae4cf +Subproject commit e792dd8e5589d42a4d416f78df8efb70995f95e3 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1a30919b2a515a4cd252fff7018fc7209b28df61 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1a30919b2a515a4cd252fff7018fc7209b28df61 You're receiving 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 26 18:17:35 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Tue, 26 May 2020 14:17:35 -0400 Subject: [Git][ghc/ghc][wip/T18232] Rip out CmmStackInfo(updfr_space) Message-ID: <5ecd5d3f5e34b_6e263f9ed71435d817650e4@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18232 at Glasgow Haskell Compiler / GHC Commits: 2d02613c by Ben Gamari at 2020-05-26T14:17:28-04:00 Rip out CmmStackInfo(updfr_space) As noted in #18232, this field is currently completely unused and moreover doesn't have a clear meaning. - - - - - 5 changed files: - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/LayoutStack.hs - compiler/GHC/Cmm/Ppr.hs - compiler/GHC/Cmm/ProcPoint.hs - compiler/GHC/StgToCmm/Monad.hs Changes: ===================================== compiler/GHC/Cmm.hs ===================================== @@ -132,9 +132,6 @@ data CmmStackInfo -- number of bytes of arguments on the stack on entry to the -- the proc. This is filled in by GHC.StgToCmm.codeGen, and -- used by the stack allocator later. - updfr_space :: Maybe ByteOff, - -- XXX: this never contains anything useful, but it should. - -- See comment in GHC.Cmm.LayoutStack. do_layout :: Bool -- Do automatic stack layout for this proc. This is -- True for all code generated by the code generator, ===================================== compiler/GHC/Cmm/LayoutStack.hs ===================================== @@ -357,10 +357,9 @@ isGcJump _something_else = False -- This doesn't seem right somehow. We need to find out whether this -- proc will push some update frame material at some point, so that we --- can avoid using that area of the stack for spilling. The --- updfr_space field of the CmmProc *should* tell us, but it doesn't --- (I think maybe it gets filled in later when we do proc-point --- splitting). +-- can avoid using that area of the stack for spilling. Ideally we would +-- capture this information in the CmmProc (e.g. in CmmStackInfo; see #18232 +-- for details on one ill-fated attempt at this). -- -- So we'll just take the max of all the cml_ret_offs. This could be -- unnecessarily pessimistic, but probably not in the code we ===================================== compiler/GHC/Cmm/Ppr.hs ===================================== @@ -103,9 +103,8 @@ instance Outputable CmmGraph where -- Outputting types Cmm contains pprStackInfo :: CmmStackInfo -> SDoc -pprStackInfo (StackInfo {arg_space=arg_space, updfr_space=updfr_space}) = - text "arg_space: " <> ppr arg_space <+> - text "updfr_space: " <> ppr updfr_space +pprStackInfo (StackInfo {arg_space=arg_space}) = + text "arg_space: " <> ppr arg_space pprTopInfo :: CmmTopInfo -> SDoc pprTopInfo (TopInfo {info_tbls=info_tbl, stack_info=stack_info}) = ===================================== compiler/GHC/Cmm/ProcPoint.hs ===================================== @@ -356,7 +356,6 @@ splitAtProcPoints dflags entry_label callPPs procPoints procMap g' = replacePPIds g live = ppLiveness (g_entry g') stack_info = StackInfo { arg_space = 0 - , updfr_space = Nothing , do_layout = True } -- cannot use panic, this is printed by -ddump-cmm ===================================== compiler/GHC/StgToCmm/Monad.hs ===================================== @@ -762,8 +762,7 @@ emitProcWithConvention conv mb_info lbl args blocks emitProc :: Maybe CmmInfoTable -> CLabel -> [GlobalReg] -> CmmAGraphScoped -> Int -> Bool -> FCode () emitProc mb_info lbl live blocks offset do_layout - = do { platform <- getPlatform - ; l <- newBlockId + = do { l <- newBlockId ; let blks :: CmmGraph blks = labelAGraph l blocks @@ -772,7 +771,6 @@ emitProc mb_info lbl live blocks offset do_layout | otherwise = mapEmpty sinfo = StackInfo { arg_space = offset - , updfr_space = Just (initUpdFrameOff platform) , do_layout = do_layout } tinfo = TopInfo { info_tbls = infos View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2d02613c20928559c27869ed16c5d90048436fa9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/2d02613c20928559c27869ed16c5d90048436fa9 You're receiving 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 26 18:49:28 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Tue, 26 May 2020 14:49:28 -0400 Subject: [Git][ghc/ghc][wip/ticky-eventlog] 5 commits: Add info about typeclass evidence to .hie files Message-ID: <5ecd64b825b4b_6e26c5c8abc176753a@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/ticky-eventlog at Glasgow Haskell Compiler / GHC Commits: 53814a64 by Zubin Duggal at 2020-05-26T03:03:24-04:00 Add info about typeclass evidence to .hie files See `testsuite/tests/hiefile/should_run/HieQueries.hs` and `testsuite/tests/hiefile/should_run/HieQueries.stdout` for an example of this We add two new fields, `EvidenceVarBind` and `EvidenceVarUse` to the `ContextInfo` associated with an Identifier. These are associated with the appropriate identifiers for the evidence variables collected when we come across `HsWrappers`, `TcEvBinds` and `IPBinds` while traversing the AST. Instance dictionary and superclass selector dictionaries from `tcg_insts` and classes defined in `tcg_tcs` are also recorded in the AST as originating from their definition span This allows us to save a complete picture of the evidence constructed by the constraint solver, and will let us report this to the user, enabling features like going to the instance definition from the invocation of a class method(or any other method taking a constraint) and finding all usages of a particular instance. Additionally, - Mark NodeInfo with an origin so we can differentiate between bindings origininating in the source vs those in ghc - Along with typeclass evidence info, also include information on Implicit Parameters - Add a few utility functions to HieUtils in order to query the new info Updates haddock submodule - - - - - 6604906c by Sebastian Graf at 2020-05-26T03:04:04-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. - - - - - cf772f19 by Sylvain Henry at 2020-05-26T03:04:45-04:00 Enhance Note [About units] for Backpack - - - - - 5b58e3cf by Ben Gamari at 2020-05-26T14:49:23-04:00 rts: Post ticky entry counts to the eventlog We currently only post the entry counters, not the other global counters as in my experience the former are more useful. We use the heap profiler's census period to decide when to dump. Also adds documentation for a few more ticky flags. - - - - - 85683db8 by Ben Gamari at 2020-05-26T14:49:23-04:00 users guide: Fix a few sundry formatting issues - - - - - 30 changed files: - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Debug.hs - compiler/GHC/Iface/Ext/Types.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Unit.hs - docs/users_guide/eventlog-formats.rst - docs/users_guide/expected-undocumented-flags.txt - docs/users_guide/extending_ghc.rst - docs/users_guide/profiling.rst - docs/users_guide/runtime_control.rst - docs/users_guide/using-optimisation.rst - docs/users_guide/using-warnings.rst - includes/rts/EventLogFormat.h - includes/rts/Flags.h - rts/Proftimer.c - rts/Proftimer.h - rts/RtsFlags.c - rts/RtsStartup.c - rts/Ticky.c - rts/Ticky.h - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h - rts/sm/GC.c - testsuite/tests/hiefile/should_compile/Scopes.hs - + testsuite/tests/hiefile/should_run/HieQueries.hs - + testsuite/tests/hiefile/should_run/HieQueries.stdout The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6dc64b7ca21a0efbdeb805833198768f7ec081f6...85683db81c3bf7a12a28236f1701599985bf0969 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6dc64b7ca21a0efbdeb805833198768f7ec081f6...85683db81c3bf7a12a28236f1701599985bf0969 You're receiving 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 26 18:53:22 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Tue, 26 May 2020 14:53:22 -0400 Subject: [Git][ghc/ghc][wip/ticky-eventlog] 2 commits: rts: Post ticky entry counts to the eventlog Message-ID: <5ecd65a21061b_6e263f9f01f3c4801768097@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/ticky-eventlog at Glasgow Haskell Compiler / GHC Commits: c95667f5 by Ben Gamari at 2020-05-26T14:53:11-04:00 rts: Post ticky entry counts to the eventlog We currently only post the entry counters, not the other global counters as in my experience the former are more useful. We use the heap profiler's census period to decide when to dump. Also adds documentation for a few more ticky flags. - - - - - 43201e39 by Ben Gamari at 2020-05-26T14:53:11-04:00 users guide: Fix a few sundry formatting issues - - - - - 17 changed files: - docs/users_guide/eventlog-formats.rst - docs/users_guide/expected-undocumented-flags.txt - docs/users_guide/extending_ghc.rst - docs/users_guide/profiling.rst - docs/users_guide/runtime_control.rst - docs/users_guide/using-warnings.rst - includes/rts/EventLogFormat.h - includes/rts/Flags.h - rts/Proftimer.c - rts/Proftimer.h - rts/RtsFlags.c - rts/RtsStartup.c - rts/Ticky.c - rts/Ticky.h - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h - rts/sm/GC.c Changes: ===================================== docs/users_guide/eventlog-formats.rst ===================================== @@ -755,3 +755,37 @@ intended to provide insight into fragmentation of the non-moving heap. :field Word32: number of live blocks. Describes the occupancy of the *blk_sz* sub-heap. + +.. _ticky-counter-events: + +Ticky counters +~~~~~~~~~~~~~~ + +Programs compiled with :ghc-flag:`-ticky` and :ghc-flag:`-eventlog` and invoked +with ``+RTS -lT`` will emit periodic samples of the ticky entry counters to the +eventlog. + +.. event-type:: TICKY_COUNTER_DEF + + :tag: 210 + :length: variable + :field Word64: counter ID + :field Word16: arity/field count + :field String: argument kinds. This is the same as the synonymous field in the + textual ticky summary. + :field String: counter name + + Defines a ticky counter. + +.. event-type:: TICKY_COUNTER_SAMPLE + + :tag: 211 + :length: fixed + :field Word64: counter ID + :field Word64: number of times closures of this type has been entered. + :field Word64: number of allocations (words) + :field Word64: number of times this has been allocated (words). Only + produced for modules compiled with :ghc-flag:`-ticky-allocd`. + + Records the number of entries, and allocations by/of a particular + closure since the last sample. ===================================== docs/users_guide/expected-undocumented-flags.txt ===================================== @@ -167,6 +167,3 @@ -split-objs -syslib -this-component-id --ticky-LNE --ticky-allocd --ticky-dyn-thunk ===================================== docs/users_guide/extending_ghc.rst ===================================== @@ -775,7 +775,7 @@ each case: package/field-n To read an interface file from an external tool without linking to GHC, the format -is described at `Extensible Interface Files`_. +is described at `Extensible Interface Files `_. Source plugin example ^^^^^^^^^^^^^^^^^^^^^ ===================================== docs/users_guide/profiling.rst ===================================== @@ -1630,11 +1630,46 @@ Using “ticky-ticky” profiling (for implementors) Enable ticky-ticky profiling. +.. ghc-flag:: -ticky-allocd + :shortdesc: Enable ticky-ticky counters for number of thunk allocations. + :type: dynamic + :category: + + By default ticky reports only the amount of allocation done *by* a closure. + With :ghc-flag:`-ticky-allocd`, it also reports on allocation *of* a + closure. + +.. ghc-flag:: -ticky-LNE + :shortdesc: Enable ticky-ticky counters for let-no-escape bindings. + :type: dynamic + :category: + + Enable ticky-ticky counters for let-no-escape bindings (i.e. join points). + +.. ghc-flag:: -ticky-dyn-thunk + :shortdesc: Enable ticky-ticky counters on dynamic closures. + :type: dynamic + :category: + + By default ticky reports counts only for *static* closures. With + :ghc-flag:`-ticky-dyn-thunk` it will also report counts for + dynamically-allocated thunks. Note that this will significantly + increase instrumentation costs. + Because ticky-ticky profiling requires a certain familiarity with GHC internals, we have moved the documentation to the GHC developers wiki. Take a look at its :ghc-wiki:`overview of the profiling options `, -which includeds a link to the ticky-ticky profiling page. +which includes a link to the ticky-ticky profiling page. + +Note that GHC can also periodically emit samples of ticky counters to +the :ghc-flag:`eventlog <-eventlog>` by enabling the :rts-flag:`+RTS -lT <-l +⟨flags⟩>` event flag. The sampling period can be set via :rts-flag:`-i ⟨secs⟩` +RTS flag. See the :ref:`eventlog formats ` section for +details on the eventlog representation. + +Note that the traditional text output (e.g. :rts-flag:`-r`) and +the eventlog output are mutually exclusive. .. [1] :ghc-flag:`-fprof-auto` was known as ``-auto-all`` prior to ===================================== docs/users_guide/runtime_control.rst ===================================== @@ -1169,6 +1169,9 @@ When the program is linked with the :ghc-flag:`-eventlog` option - ``f`` — parallel sparks (fully accurate). Disabled by default. + - ``T`` — :ref:`ticky-ticky ` profiler counter samples. + Disabled by default. + - ``u`` — user events. These are events emitted from Haskell code using functions such as ``Debug.Trace.traceEvent``. Enabled by default. @@ -1192,10 +1195,10 @@ When the program is linked with the :ghc-flag:`-eventlog` option 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 `__ + `ghc-events `_ library. To dump the contents of a ``.eventlog`` file as text, use the tool ``ghc-events show`` that comes with the - `ghc-events `__ + `ghc-events `_ package. Each event is associated with a timestamp which is the number of ===================================== docs/users_guide/using-warnings.rst ===================================== @@ -239,8 +239,8 @@ of ``-W(no-)*``. - ``Data.List`` due to the future addition of ``Data.List.singleton`` and specialisation of exports to the ``[]`` type. See the - :ref:`mailing list - ` + `mailing list + `_ for details. This warning can be addressed by either adding an explicit import list or ===================================== includes/rts/EventLogFormat.h ===================================== @@ -154,12 +154,15 @@ #define EVENT_CONC_UPD_REM_SET_FLUSH 206 #define EVENT_NONMOVING_HEAP_CENSUS 207 +#define EVENT_TICKY_COUNTER_DEF 210 +#define EVENT_TICKY_COUNTER_SAMPLE 211 + /* * The highest event code +1 that ghc itself emits. Note that some event * ranges higher than this are reserved but not currently emitted by ghc. * This must match the size of the EventDesc[] array in EventLog.c */ -#define NUM_GHC_EVENT_TAGS 208 +#define NUM_GHC_EVENT_TAGS 212 #if 0 /* DEPRECATED EVENTS: */ /* we don't actually need to record the thread, it's implicit */ ===================================== includes/rts/Flags.h ===================================== @@ -176,6 +176,7 @@ typedef struct _TRACE_FLAGS { bool nonmoving_gc; /* trace nonmoving GC events */ bool sparks_sampled; /* trace spark events by a sampled method */ bool sparks_full; /* trace spark events 100% accurately */ + bool ticky; /* trace ticky-ticky samples */ bool user; /* trace user events (emitted from Haskell code) */ char *trace_output; /* output filename for eventlog */ } TRACE_FLAGS; ===================================== rts/Proftimer.c ===================================== @@ -20,6 +20,12 @@ static bool do_prof_ticks = false; // enable profiling ticks static bool do_heap_prof_ticks = false; // enable heap profiling ticks +// Sampling of Ticky-Ticky profiler to eventlog +#if defined(TICKY_TICKY) && defined(TRACING) +static int ticks_to_ticky_sample = 0; +bool performTickySample = false; +#endif + // Number of ticks until next heap census static int ticks_to_heap_profile; @@ -83,6 +89,16 @@ handleProfTick(void) } #endif +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + ticks_to_ticky_sample--; + if (ticks_to_ticky_sample <= 0) { + ticks_to_ticky_sample = RtsFlags.ProfFlags.heapProfileIntervalTicks; + performTickySample = true; + } + } +#endif + if (do_heap_prof_ticks) { ticks_to_heap_profile--; if (ticks_to_heap_profile <= 0) { ===================================== rts/Proftimer.h ===================================== @@ -17,5 +17,6 @@ void stopHeapProfTimer ( void ); void startHeapProfTimer ( void ); extern bool performHeapProfile; +extern bool performTickySample; #include "EndPrivate.h" ===================================== rts/RtsFlags.c ===================================== @@ -234,6 +234,7 @@ void initRtsFlagsDefaults(void) RtsFlags.TraceFlags.sparks_sampled= false; RtsFlags.TraceFlags.sparks_full = false; RtsFlags.TraceFlags.user = false; + RtsFlags.TraceFlags.ticky = false; RtsFlags.TraceFlags.trace_output = NULL; #endif @@ -386,6 +387,9 @@ usage_text[] = { " p par spark events (sampled)", " f par spark events (full detail)", " u user events (emitted from Haskell code)", +#if defined(TICKY_TICKY) +" T ticky-ticky counter samples", +#endif " a all event classes above", # if defined(DEBUG) " t add time stamps (only useful with -v)", @@ -1791,6 +1795,11 @@ static void normaliseRtsOpts (void) "the compacting collector."); errorUsage(); } + + if (RtsFlags.TraceFlags.ticky && RtsFlags.TickyFlags.showTickyStats) { + barf("The ticky-ticky eventlog output cannot be used in conjunction with\n" + "+RTS -r."); + } } static void errorUsage (void) @@ -2233,6 +2242,15 @@ static void read_trace_flags(const char *arg) RtsFlags.TraceFlags.user = enabled; enabled = true; break; + case 'T': +#if defined(TICKY_TICKY) + RtsFlags.TraceFlags.ticky = enabled; + enabled = true; + break; +#else + errorBelch("Program not compiled with ticky-ticky support"); + break; +#endif default: errorBelch("unknown trace option: %c",*c); break; ===================================== rts/RtsStartup.c ===================================== @@ -415,6 +415,17 @@ hs_exit_(bool wait_foreign) */ exitTimer(true); + /* + * Dump the ticky counter definitions + * We do this at the end of execution since tickers are registered in the + * course of program execution. + */ +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + emitTickyCounterDefs(); + } +#endif + // set the terminal settings back to what they were #if !defined(mingw32_HOST_OS) resetTerminalSettings(); ===================================== rts/Ticky.c ===================================== @@ -10,6 +10,8 @@ #include "PosixSource.h" #include "Rts.h" +#include "eventlog/EventLog.h" + /* Catch-all top-level counter struct. Allocations from CAFs will go * here. */ @@ -46,6 +48,10 @@ static void printRegisteredCounterInfo (FILE *); /* fwd decl */ void PrintTickyInfo(void) { + if (RtsFlags.TraceFlags.ticky) { + barf("Ticky eventlog output can't be used with +RTS -r"); + } + unsigned long i; unsigned long tot_thk_enters = ENT_STATIC_THK_MANY_ctr + ENT_DYN_THK_MANY_ctr @@ -374,4 +380,19 @@ printRegisteredCounterInfo (FILE *tf) } } + +void emitTickyCounterDefs() +{ +#if defined(TRACING) + postTickyCounterDefs(ticky_entry_ctrs); +#endif +} + +void emitTickyCounterSamples() +{ +#if defined(TRACING) + postTickyCounterSamples(ticky_entry_ctrs); +#endif +} + #endif /* TICKY_TICKY */ ===================================== rts/Ticky.h ===================================== @@ -8,4 +8,11 @@ #pragma once -RTS_PRIVATE void PrintTickyInfo(void); +#include "BeginPrivate.h" + +void PrintTickyInfo(void); + +void emitTickyCounterSamples(void); +void emitTickyCounterDefs(void); + +#include "EndPrivate.h" ===================================== rts/eventlog/EventLog.c ===================================== @@ -119,7 +119,9 @@ char *EventDesc[] = { [EVENT_CONC_SWEEP_BEGIN] = "Begin concurrent sweep", [EVENT_CONC_SWEEP_END] = "End concurrent sweep", [EVENT_CONC_UPD_REM_SET_FLUSH] = "Update remembered set flushed", - [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census" + [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census", + [EVENT_TICKY_COUNTER_DEF] = "Ticky-ticky entry counter definition", + [EVENT_TICKY_COUNTER_SAMPLE] = "Ticky-ticky entry counter sample", }; // Event type. @@ -487,6 +489,14 @@ init_event_types(void) eventTypes[t].size = 13; break; + case EVENT_TICKY_COUNTER_DEF: // (counter_id, arity, arg_kinds, name) + eventTypes[t].size = EVENT_SIZE_DYNAMIC; + break; + + case EVENT_TICKY_COUNTER_SAMPLE: // (counter_id, entry_count, allocs, allocd) + eventTypes[t].size = 8*4; + break; + default: continue; /* ignore deprecated events */ } @@ -1472,6 +1482,58 @@ void postProfBegin(void) } #endif /* PROFILING */ +#if defined(TICKY_TICKY) +static void postTickyCounterDef(EventsBuf *eb, StgEntCounter *p) +{ + StgWord len = 8 + 2 + strlen(p->arg_kinds)+1 + strlen(p->str)+1; + ensureRoomForVariableEvent(eb, len); + postEventHeader(eb, EVENT_TICKY_COUNTER_DEF); + postPayloadSize(eb, len); + postWord64(eb, (uint64_t) p); + postWord16(eb, (uint16_t) p->arity); + postString(eb, p->arg_kinds); + postString(eb, p->str); +} + +void postTickyCounterDefs(StgEntCounter *counters) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = counters; p != NULL; p = p->link) { + postTickyCounterDef(&eventBuf, p); + } + RELEASE_LOCK(&eventBufMutex); +} + +static void postTickyCounterSample(EventsBuf *eb, StgEntCounter *p) +{ + if ( p->entry_count == 0 + && p->allocs == 0 + && p->allocd == 0) + return; + + ensureRoomForEvent(eb, EVENT_TICKY_COUNTER_SAMPLE); + postEventHeader(eb, EVENT_TICKY_COUNTER_SAMPLE); + postWord64(eb, (uint64_t) p); + postWord64(eb, p->entry_count); + postWord64(eb, p->allocs); + postWord64(eb, p->allocd); + + // Zero the ticker counts for the next sample. + p->entry_count = 0; + p->allocs = 0; + p->allocd = 0; +} + +void postTickyCounterSamples(StgEntCounter *counters) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = counters; p != NULL; p = p->link) { + postTickyCounterSample(&eventBuf, p); + } + RELEASE_LOCK(&eventBufMutex); +} +#endif /* TICKY_TICKY */ + void printAndClearEventBuf (EventsBuf *ebuf) { closeBlockMarker(ebuf); ===================================== rts/eventlog/EventLog.h ===================================== @@ -173,6 +173,11 @@ void postConcMarkEnd(StgWord32 marked_obj_count); void postNonmovingHeapCensus(int log_blk_size, const struct NonmovingAllocCensus *census); +#if defined(TICKY_TICKY) +void postTickyCounterDefs(StgEntCounter *p); +void postTickyCounterSamples(StgEntCounter *p); +#endif /* TICKY_TICKY */ + #else /* !TRACING */ INLINE_HEADER void postSchedEvent (Capability *cap STG_UNUSED, ===================================== rts/sm/GC.c ===================================== @@ -38,6 +38,7 @@ #include "Sanity.h" #include "BlockAlloc.h" #include "ProfHeap.h" +#include "Proftimer.h" #include "Weak.h" #include "Prelude.h" #include "RtsSignals.h" @@ -52,6 +53,7 @@ #include "CNF.h" #include "RtsFlags.h" #include "NonMoving.h" +#include "Ticky.h" #include // for memset() #include @@ -860,6 +862,16 @@ GarbageCollect (uint32_t collect_gen, ACQUIRE_SM_LOCK; } +#if defined(TICKY_TICKY) + // Post ticky counter sample. + // We do this at the end of execution since tickers are registered in the + // course of program execution. + if (performTickySample) { + emitTickyCounterSamples(); + performTickySample = false; + } +#endif + // send exceptions to any threads which were about to die RELEASE_SM_LOCK; resurrectThreads(resurrected_threads); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/85683db81c3bf7a12a28236f1701599985bf0969...43201e39a98a30364c1108c5646de828dfc11878 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/85683db81c3bf7a12a28236f1701599985bf0969...43201e39a98a30364c1108c5646de828dfc11878 You're receiving 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 26 19:51:05 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Tue, 26 May 2020 15:51:05 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/always-use-rnImplicitBndrs Message-ID: <5ecd73295f3b4_6e263f9f00579e08177269e@gitlab.haskell.org.mail> Ryan Scott pushed new branch wip/always-use-rnImplicitBndrs at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/always-use-rnImplicitBndrs You're receiving 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 26 20:03:48 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Tue, 26 May 2020 16:03:48 -0400 Subject: [Git][ghc/ghc][wip/T18234] gitlab-ci: Introduce a nightly cross-compilation job Message-ID: <5ecd762483e82_6e263f9f01f3c48017782fe@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18234 at Glasgow Haskell Compiler / GHC Commits: 8376582b by Ben Gamari at 2020-05-26T16:03:32-04:00 gitlab-ci: Introduce a nightly cross-compilation job This adds a job to test cross-compilation from x86-64 to AArch64 with Hadrian. Fixes #18234. - - - - - 2 changed files: - .gitlab-ci.yml - .gitlab/ci.sh 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: 6223fe0b5942f4fa35bdec92c74566cf195bfb42 + DOCKER_REV: 35d6418c6ee0297352e6ea5f93a8ede0f2c2f931 # Sequential version number capturing the versions of all tools fetched by # .gitlab/ci.sh. @@ -648,6 +648,12 @@ release-x86_64-linux-deb10: <<: *release extends: .build-x86_64-linux-deb10 +nightly-x86_64-linux-deb10-cross-aarch64: + <<: *nightly + extends: .build-x86_64-linux-deb10 + variables: + CROSS_TARGET: "aarch64-linux-gnu" + ################################# # x86_64-linux-deb8 ################################# ===================================== .gitlab/ci.sh ===================================== @@ -80,6 +80,7 @@ Modes: Environment variables: + CROSS_TARGET Triple of cross-compilation target. MSYSTEM (Windows-only) Which platform to build form (MINGW64 or MINGW32). Environment variables determining build configuration of Make system: @@ -114,11 +115,11 @@ EOF function mingw_init() { case "$MSYSTEM" in MINGW32) - triple="i386-unknown-mingw32" + target_triple="i386-unknown-mingw32" boot_triple="i386-unknown-mingw32" # triple of bootstrap GHC ;; MINGW64) - triple="x86_64-unknown-mingw32" + target_triple="x86_64-unknown-mingw32" boot_triple="x86_64-unknown-mingw32" # triple of bootstrap GHC ;; *) @@ -375,8 +376,8 @@ function configure() { end_section "booting" local target_args="" - if [[ -n "$triple" ]]; then - target_args="--target=$triple" + if [[ -n "$target_triple" ]]; then + target_args="--target=$target_triple" fi start_section "configuring" @@ -415,6 +416,11 @@ function push_perf_notes() { } function test_make() { + if [ -n "$CROSS_TARGET" ]; then + info "Can't test cross-compiled build." + return + fi + run "$MAKE" test_bindist TEST_PREP=YES run "$MAKE" V=0 test \ THREADS="$cores" \ @@ -432,6 +438,11 @@ function build_hadrian() { } function test_hadrian() { + if [ -n "$CROSS_TARGET" ]; then + info "Can't test cross-compiled build." + return + fi + cd _build/bindist/ghc-*/ run ./configure --prefix="$TOP"/_build/install run "$MAKE" install @@ -486,6 +497,11 @@ case "$(uname)" in *) fail "uname $(uname) is not supported" ;; esac +if [ -n "$CROSS_TARGET" ]; then + info "Cross-compiling for $CROSS_TARGET..." + target_triple="$CROSS_TARGET" +fi + set_toolchain_paths case $1 in View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8376582b627b419adcab2def2aefcb1406c000ef -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8376582b627b419adcab2def2aefcb1406c000ef You're receiving 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 26 20:05:55 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Tue, 26 May 2020 16:05:55 -0400 Subject: [Git][ghc/ghc][wip/T17775] Simple subsumption Message-ID: <5ecd76a35db94_6e263f9f0ba0f84017786b2@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: d965f236 by Simon Peyton Jones at 2020-05-26T16:05:42-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 Updates Cabal submodule. - - - - - 20 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/Type.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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d965f23692cb705b453b4845d9afc746f860ee3c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d965f23692cb705b453b4845d9afc746f860ee3c You're receiving 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 26 20:20:16 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Tue, 26 May 2020 16:20:16 -0400 Subject: [Git][ghc/ghc][wip/T18078] Move around new regression tests Message-ID: <5ecd7a0064e75_6e2687ddb0817822a3@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/T18078 at Glasgow Haskell Compiler / GHC Commits: 638d946f by Sebastian Graf at 2020-05-26T22:20:09+02:00 Move around new regression tests - - - - - 9 changed files: - testsuite/tests/stranal/should_compile/T17673.hs → testsuite/tests/simplCore/should_compile/T17673.hs - + testsuite/tests/simplCore/should_compile/T17673.stderr - testsuite/tests/stranal/should_compile/T18078.hs → testsuite/tests/simplCore/should_compile/T18078.hs - + testsuite/tests/simplCore/should_compile/T18078.stderr - testsuite/tests/simplCore/should_compile/all.T - testsuite/tests/stranal/should_compile/Makefile - − testsuite/tests/stranal/should_compile/T17673.stdout - − testsuite/tests/stranal/should_compile/T18078.stdout - testsuite/tests/stranal/should_compile/all.T Changes: ===================================== testsuite/tests/stranal/should_compile/T17673.hs → testsuite/tests/simplCore/should_compile/T17673.hs ===================================== ===================================== testsuite/tests/simplCore/should_compile/T17673.stderr ===================================== @@ -0,0 +1,66 @@ + +==================== Tidy Core ==================== +Result size of Tidy Core = {terms: 56, types: 67, coercions: 5, joins: 0/0} + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T17673.$trModule4 :: GHC.Prim.Addr# +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +T17673.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T17673.$trModule3 :: GHC.Types.TrName +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +T17673.$trModule3 = GHC.Types.TrNameS T17673.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T17673.$trModule2 :: GHC.Prim.Addr# +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] +T17673.$trModule2 = "T17673"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T17673.$trModule1 :: GHC.Types.TrName +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +T17673.$trModule1 = GHC.Types.TrNameS T17673.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +T17673.$trModule :: GHC.Types.Module +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] +T17673.$trModule = GHC.Types.Module T17673.$trModule3 T17673.$trModule1 + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl :: Int +[GblId, Unf=OtherCon []] +lvl = GHC.Types.I# 1# + +Rec { +-- RHS size: {terms: 27, types: 31, coercions: 0, joins: 0/0} +T17673.$wfacIO [InlPrag=NOINLINE, Occ=LoopBreaker] :: GHC.Prim.Int# -> GHC.Prim.State# GHC.Prim.RealWorld -> (# GHC.Prim.State# GHC.Prim.RealWorld, Int #) +[GblId, Arity=2, Str=, Unf=OtherCon []] +T17673.$wfacIO + = \ (ww :: GHC.Prim.Int#) (w :: GHC.Prim.State# GHC.Prim.RealWorld) -> + case GHC.Prim.<# ww 2# of { + __DEFAULT -> case T17673.$wfacIO (GHC.Prim.-# ww 1#) w of { (# ipv, ipv1 #) -> (# ipv, case ipv1 of { GHC.Types.I# y -> GHC.Types.I# (GHC.Prim.*# ww y) } #) }; + 1# -> (# w, lvl #) + } +end Rec } + +-- RHS size: {terms: 8, types: 5, coercions: 0, joins: 0/0} +T17673.facIO1 [InlPrag=NOUSERINLINE[-1]] :: Int -> GHC.Prim.State# GHC.Prim.RealWorld -> (# GHC.Prim.State# GHC.Prim.RealWorld, Int #) +[GblId, + Arity=2, + 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= \ (w [Occ=Once!] :: Int) (w1 [Occ=Once] :: GHC.Prim.State# GHC.Prim.RealWorld) -> case w of { GHC.Types.I# ww1 [Occ=Once] -> T17673.$wfacIO ww1 w1 }}] +T17673.facIO1 = \ (w :: Int) (w1 :: GHC.Prim.State# GHC.Prim.RealWorld) -> case w of { GHC.Types.I# ww1 -> T17673.$wfacIO ww1 w1 } + +-- RHS size: {terms: 1, types: 0, coercions: 5, joins: 0/0} +facIO [InlPrag=NOUSERINLINE[-1]] :: Int -> IO Int +[GblId, + Arity=2, + Str=, + Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=True) + Tmpl= T17673.facIO1 `cast` (_R ->_R Sym (GHC.Types.N:IO[0] _R) :: (Int -> GHC.Prim.State# GHC.Prim.RealWorld -> (# GHC.Prim.State# GHC.Prim.RealWorld, Int #)) ~R# (Int -> IO Int))}] +facIO = T17673.facIO1 `cast` (_R ->_R Sym (GHC.Types.N:IO[0] _R) :: (Int -> GHC.Prim.State# GHC.Prim.RealWorld -> (# GHC.Prim.State# GHC.Prim.RealWorld, Int #)) ~R# (Int -> IO Int)) + + + ===================================== testsuite/tests/stranal/should_compile/T18078.hs → testsuite/tests/simplCore/should_compile/T18078.hs ===================================== ===================================== testsuite/tests/simplCore/should_compile/T18078.stderr ===================================== @@ -0,0 +1,141 @@ + +==================== Tidy Core ==================== +Result size of Tidy Core = {terms: 98, types: 40, coercions: 5, joins: 0/0} + +-- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0} +T18078.unN1 :: N -> N +[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=True) + Tmpl= \ (ds [Occ=Once] :: N) -> ds}] +T18078.unN1 = \ (ds :: N) -> ds + +-- RHS size: {terms: 1, types: 0, coercions: 3, joins: 0/0} +unN :: N -> Int -> Int +[GblId[[RecSel]], + Arity=1, + Str=, + Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=True) + Tmpl= T18078.unN1 `cast` (_R ->_R T18078.N:N[0] :: (N -> N) ~R# (N -> Int -> Int))}] +unN = T18078.unN1 `cast` (_R ->_R T18078.N:N[0] :: (N -> N) ~R# (N -> Int -> Int)) + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T18078.$trModule4 :: GHC.Prim.Addr# +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +T18078.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T18078.$trModule3 :: GHC.Types.TrName +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +T18078.$trModule3 = GHC.Types.TrNameS T18078.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T18078.$trModule2 :: GHC.Prim.Addr# +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] +T18078.$trModule2 = "T18078"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T18078.$trModule1 :: GHC.Types.TrName +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +T18078.$trModule1 = GHC.Types.TrNameS T18078.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +T18078.$trModule :: GHC.Types.Module +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] +T18078.$trModule = GHC.Types.Module T18078.$trModule3 T18078.$trModule1 + +-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0} +$krep :: GHC.Types.KindRep +[GblId, Cpr=m1, Unf=OtherCon []] +$krep = GHC.Types.KindRepTyConApp GHC.Types.$tcInt (GHC.Types.[] @GHC.Types.KindRep) + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +$krep1 :: GHC.Types.KindRep +[GblId, Cpr=m4, Unf=OtherCon []] +$krep1 = GHC.Types.KindRepFun $krep $krep + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T18078.$tcN2 :: GHC.Prim.Addr# +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +T18078.$tcN2 = "N"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T18078.$tcN1 :: GHC.Types.TrName +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +T18078.$tcN1 = GHC.Types.TrNameS T18078.$tcN2 + +-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} +T18078.$tcN :: GHC.Types.TyCon +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 70}] +T18078.$tcN = GHC.Types.TyCon 8242209344145137716## 16993518540698548720## T18078.$trModule T18078.$tcN1 0# GHC.Types.krep$* + +-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0} +$krep2 :: GHC.Types.KindRep +[GblId, Cpr=m1, Unf=OtherCon []] +$krep2 = GHC.Types.KindRepTyConApp T18078.$tcN (GHC.Types.[] @GHC.Types.KindRep) + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +T18078.$tc'N1 [InlPrag=NOUSERINLINE[~]] :: GHC.Types.KindRep +[GblId, Cpr=m4, Unf=OtherCon []] +T18078.$tc'N1 = GHC.Types.KindRepFun $krep1 $krep2 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T18078.$tc'N3 :: GHC.Prim.Addr# +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +T18078.$tc'N3 = "'N"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T18078.$tc'N2 :: GHC.Types.TrName +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +T18078.$tc'N2 = GHC.Types.TrNameS T18078.$tc'N3 + +-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} +T18078.$tc'N :: GHC.Types.TyCon +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 70}] +T18078.$tc'N = GHC.Types.TyCon 15484649745433776318## 6635095266531093649## T18078.$trModule T18078.$tc'N2 0# T18078.$tc'N1 + +Rec { +-- RHS size: {terms: 10, types: 2, coercions: 0, joins: 0/0} +T18078.$wf [InlPrag=NOINLINE, Occ=LoopBreaker] :: GHC.Prim.Int# -> GHC.Prim.Int# +[GblId, Arity=1, Str=, Unf=OtherCon []] +T18078.$wf + = \ (ww :: GHC.Prim.Int#) -> + case ww of wild { + __DEFAULT -> T18078.$wf (GHC.Prim.-# wild 1#); + 0# -> 0# + } +end Rec } + +-- RHS size: {terms: 10, types: 4, coercions: 0, joins: 0/0} +T18078.f1 [InlPrag=NOUSERINLINE[-1]] :: Int -> Int +[GblId, + Arity=1, + Str=, + Cpr=m1, + 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= \ (w [Occ=Once!] :: Int) -> case w of { GHC.Types.I# ww1 [Occ=Once] -> case T18078.$wf ww1 of ww2 [Occ=Once] { __DEFAULT -> GHC.Types.I# ww2 } }}] +T18078.f1 = \ (w :: Int) -> case w of { GHC.Types.I# ww1 -> case T18078.$wf ww1 of ww2 { __DEFAULT -> GHC.Types.I# ww2 } } + +-- RHS size: {terms: 1, types: 0, coercions: 2, joins: 0/0} +f [InlPrag=NOUSERINLINE[-1]] :: N +[GblId, + Arity=1, + Str=, + Cpr=m1, + Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=True) + Tmpl= T18078.f1 `cast` (Sym (T18078.N:N[0]) :: (Int -> Int) ~R# N)}] +f = T18078.f1 `cast` (Sym (T18078.N:N[0]) :: (Int -> Int) ~R# N) + +-- RHS size: {terms: 12, types: 4, coercions: 0, joins: 0/0} +g :: Int -> Int +[GblId, + Arity=1, + Str=, + Cpr=m1, + 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= \ (x [Occ=Once!] :: Int) -> case x of { GHC.Types.I# x1 [Occ=Once] -> T18078.f1 (GHC.Types.I# (GHC.Prim.+# x1 1#)) }}] +g = \ (x :: Int) -> case x of { GHC.Types.I# x1 -> case T18078.$wf (GHC.Prim.+# x1 1#) of ww { __DEFAULT -> GHC.Types.I# ww } } + + + ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -319,3 +319,7 @@ test('T17810', normal, multimod_compile, ['T17810', '-fspecialise-aggressively - test('T18013', normal, multimod_compile, ['T18013', '-v0 -O']) test('T18098', normal, compile, ['-dcore-lint -O2']) test('T18120', normal, compile, ['-dcore-lint -O']) + +# Cast WW +test('T17673', [ only_ways(['optasm']), check_errmsg(r'^\w+\.\$wf') ], compile, ['-ddump-simpl -dsuppress-uniques -dppr-cols=9999']) +test('T18078', [ only_ways(['optasm']), check_errmsg(r'^\w+\.\$wf') ], compile, ['-ddump-simpl -dsuppress-uniques -dppr-cols=9999']) ===================================== testsuite/tests/stranal/should_compile/Makefile ===================================== @@ -10,9 +10,3 @@ T13031: # take only one Int# argument T16029: '$(TEST_HC)' $(TEST_HC_OPTS) -c -O -fforce-recomp T16029.hs -dsuppress-uniques -ddump-simpl | grep '::.*Int' - -T18078: - '$(TEST_HC)' $(TEST_HC_OPTS) -c -O -fforce-recomp T18078.hs -dsuppress-uniques -ddump-simpl | grep 'wf' - -T17673: - '$(TEST_HC)' $(TEST_HC_OPTS) -c -O -fforce-recomp T17673.hs -dsuppress-uniques -ddump-simpl | grep 'wf' ===================================== testsuite/tests/stranal/should_compile/T17673.stdout deleted ===================================== @@ -1,5 +0,0 @@ -T17673.$wfacIO [InlPrag=NOINLINE, Occ=LoopBreaker] -T17673.$wfacIO - case T17673.$wfacIO (GHC.Prim.-# ww 1#) w of { (# ipv, ipv1 #) -> - T17673.$wfacIO ww1 w1 - case w of { GHC.Types.I# ww1 -> T17673.$wfacIO ww1 w1 } ===================================== testsuite/tests/stranal/should_compile/T18078.stdout deleted ===================================== @@ -1,6 +0,0 @@ -T18078.$wf [InlPrag=NOINLINE, Occ=LoopBreaker] -T18078.$wf - __DEFAULT -> T18078.$wf (GHC.Prim.-# wild 1#); - case T18078.$wf ww1 of ww2 [Occ=Once] { __DEFAULT -> - case T18078.$wf ww1 of ww2 { __DEFAULT -> GHC.Types.I# ww2 } - case T18078.$wf (GHC.Prim.+# x1 1#) of ww { __DEFAULT -> ===================================== testsuite/tests/stranal/should_compile/all.T ===================================== @@ -52,6 +52,3 @@ 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']) test('T13380b', [ grep_errmsg('bigDeadAction') ], compile, ['-dppr-cols=200 -ddump-simpl']) -test('T18078', normal, makefile_test, []) -test('T17673', normal, makefile_test, []) - View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/638d946f6bf934309116b53fdd5ca6f22336df82 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/638d946f6bf934309116b53fdd5ca6f22336df82 You're receiving 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 26 20:29:48 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Tue, 26 May 2020 16:29:48 -0400 Subject: [Git][ghc/ghc][wip/T18078] Move around new regression tests Message-ID: <5ecd7c3cc9f4b_6e263f9f00579e08178341b@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/T18078 at Glasgow Haskell Compiler / GHC Commits: fe99560e by Sebastian Graf at 2020-05-26T22:29:41+02:00 Move around new regression tests - - - - - 9 changed files: - testsuite/tests/stranal/should_compile/T17673.hs → testsuite/tests/simplCore/should_compile/T17673.hs - + testsuite/tests/simplCore/should_compile/T17673.stderr - testsuite/tests/stranal/should_compile/T18078.hs → testsuite/tests/simplCore/should_compile/T18078.hs - + testsuite/tests/simplCore/should_compile/T18078.stderr - testsuite/tests/simplCore/should_compile/all.T - testsuite/tests/stranal/should_compile/Makefile - − testsuite/tests/stranal/should_compile/T17673.stdout - − testsuite/tests/stranal/should_compile/T18078.stdout - testsuite/tests/stranal/should_compile/all.T Changes: ===================================== testsuite/tests/stranal/should_compile/T17673.hs → testsuite/tests/simplCore/should_compile/T17673.hs ===================================== ===================================== testsuite/tests/simplCore/should_compile/T17673.stderr ===================================== @@ -0,0 +1,66 @@ + +==================== Tidy Core ==================== +Result size of Tidy Core = {terms: 56, types: 67, coercions: 5, joins: 0/0} + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T17673.$trModule4 :: GHC.Prim.Addr# +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +T17673.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T17673.$trModule3 :: GHC.Types.TrName +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +T17673.$trModule3 = GHC.Types.TrNameS T17673.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T17673.$trModule2 :: GHC.Prim.Addr# +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] +T17673.$trModule2 = "T17673"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T17673.$trModule1 :: GHC.Types.TrName +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +T17673.$trModule1 = GHC.Types.TrNameS T17673.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +T17673.$trModule :: GHC.Types.Module +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] +T17673.$trModule = GHC.Types.Module T17673.$trModule3 T17673.$trModule1 + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +lvl :: Int +[GblId, Unf=OtherCon []] +lvl = GHC.Types.I# 1# + +Rec { +-- RHS size: {terms: 27, types: 31, coercions: 0, joins: 0/0} +T17673.$wfacIO [InlPrag=NOINLINE, Occ=LoopBreaker] :: GHC.Prim.Int# -> GHC.Prim.State# GHC.Prim.RealWorld -> (# GHC.Prim.State# GHC.Prim.RealWorld, Int #) +[GblId, Arity=2, Str=, Unf=OtherCon []] +T17673.$wfacIO + = \ (ww :: GHC.Prim.Int#) (w :: GHC.Prim.State# GHC.Prim.RealWorld) -> + case GHC.Prim.<# ww 2# of { + __DEFAULT -> case T17673.$wfacIO (GHC.Prim.-# ww 1#) w of { (# ipv, ipv1 #) -> (# ipv, case ipv1 of { GHC.Types.I# y -> GHC.Types.I# (GHC.Prim.*# ww y) } #) }; + 1# -> (# w, lvl #) + } +end Rec } + +-- RHS size: {terms: 8, types: 5, coercions: 0, joins: 0/0} +T17673.facIO1 [InlPrag=NOUSERINLINE[-1]] :: Int -> GHC.Prim.State# GHC.Prim.RealWorld -> (# GHC.Prim.State# GHC.Prim.RealWorld, Int #) +[GblId, + Arity=2, + 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= \ (w [Occ=Once!] :: Int) (w1 [Occ=Once] :: GHC.Prim.State# GHC.Prim.RealWorld) -> case w of { GHC.Types.I# ww1 [Occ=Once] -> T17673.$wfacIO ww1 w1 }}] +T17673.facIO1 = \ (w :: Int) (w1 :: GHC.Prim.State# GHC.Prim.RealWorld) -> case w of { GHC.Types.I# ww1 -> T17673.$wfacIO ww1 w1 } + +-- RHS size: {terms: 1, types: 0, coercions: 5, joins: 0/0} +facIO [InlPrag=NOUSERINLINE[-1]] :: Int -> IO Int +[GblId, + Arity=2, + Str=, + Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=True) + Tmpl= T17673.facIO1 `cast` (_R ->_R Sym (GHC.Types.N:IO[0] _R) :: (Int -> GHC.Prim.State# GHC.Prim.RealWorld -> (# GHC.Prim.State# GHC.Prim.RealWorld, Int #)) ~R# (Int -> IO Int))}] +facIO = T17673.facIO1 `cast` (_R ->_R Sym (GHC.Types.N:IO[0] _R) :: (Int -> GHC.Prim.State# GHC.Prim.RealWorld -> (# GHC.Prim.State# GHC.Prim.RealWorld, Int #)) ~R# (Int -> IO Int)) + + + ===================================== testsuite/tests/stranal/should_compile/T18078.hs → testsuite/tests/simplCore/should_compile/T18078.hs ===================================== ===================================== testsuite/tests/simplCore/should_compile/T18078.stderr ===================================== @@ -0,0 +1,141 @@ + +==================== Tidy Core ==================== +Result size of Tidy Core = {terms: 98, types: 40, coercions: 5, joins: 0/0} + +-- RHS size: {terms: 2, types: 1, coercions: 0, joins: 0/0} +T18078.unN1 :: N -> N +[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=True) + Tmpl= \ (ds [Occ=Once] :: N) -> ds}] +T18078.unN1 = \ (ds :: N) -> ds + +-- RHS size: {terms: 1, types: 0, coercions: 3, joins: 0/0} +unN :: N -> Int -> Int +[GblId[[RecSel]], + Arity=1, + Str=, + Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=True) + Tmpl= T18078.unN1 `cast` (_R ->_R T18078.N:N[0] :: (N -> N) ~R# (N -> Int -> Int))}] +unN = T18078.unN1 `cast` (_R ->_R T18078.N:N[0] :: (N -> N) ~R# (N -> Int -> Int)) + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T18078.$trModule4 :: GHC.Prim.Addr# +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +T18078.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T18078.$trModule3 :: GHC.Types.TrName +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +T18078.$trModule3 = GHC.Types.TrNameS T18078.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T18078.$trModule2 :: GHC.Prim.Addr# +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 30 0}] +T18078.$trModule2 = "T18078"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T18078.$trModule1 :: GHC.Types.TrName +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +T18078.$trModule1 = GHC.Types.TrNameS T18078.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +T18078.$trModule :: GHC.Types.Module +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 30}] +T18078.$trModule = GHC.Types.Module T18078.$trModule3 T18078.$trModule1 + +-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0} +$krep :: GHC.Types.KindRep +[GblId, Cpr=m1, Unf=OtherCon []] +$krep = GHC.Types.KindRepTyConApp GHC.Types.$tcInt (GHC.Types.[] @GHC.Types.KindRep) + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +$krep1 :: GHC.Types.KindRep +[GblId, Cpr=m4, Unf=OtherCon []] +$krep1 = GHC.Types.KindRepFun $krep $krep + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T18078.$tcN2 :: GHC.Prim.Addr# +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +T18078.$tcN2 = "N"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T18078.$tcN1 :: GHC.Types.TrName +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +T18078.$tcN1 = GHC.Types.TrNameS T18078.$tcN2 + +-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} +T18078.$tcN :: GHC.Types.TyCon +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 70}] +T18078.$tcN = GHC.Types.TyCon 8242209344145137716## 16993518540698548720## T18078.$trModule T18078.$tcN1 0# GHC.Types.krep$* + +-- RHS size: {terms: 3, types: 1, coercions: 0, joins: 0/0} +$krep2 :: GHC.Types.KindRep +[GblId, Cpr=m1, Unf=OtherCon []] +$krep2 = GHC.Types.KindRepTyConApp T18078.$tcN (GHC.Types.[] @GHC.Types.KindRep) + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +T18078.$tc'N1 [InlPrag=NOUSERINLINE[~]] :: GHC.Types.KindRep +[GblId, Cpr=m4, Unf=OtherCon []] +T18078.$tc'N1 = GHC.Types.KindRepFun $krep1 $krep2 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T18078.$tc'N3 :: GHC.Prim.Addr# +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 20 0}] +T18078.$tc'N3 = "'N"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T18078.$tc'N2 :: GHC.Types.TrName +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] +T18078.$tc'N2 = GHC.Types.TrNameS T18078.$tc'N3 + +-- RHS size: {terms: 7, types: 0, coercions: 0, joins: 0/0} +T18078.$tc'N :: GHC.Types.TyCon +[GblId, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 70}] +T18078.$tc'N = GHC.Types.TyCon 15484649745433776318## 6635095266531093649## T18078.$trModule T18078.$tc'N2 0# T18078.$tc'N1 + +Rec { +-- RHS size: {terms: 10, types: 2, coercions: 0, joins: 0/0} +T18078.$wf [InlPrag=NOINLINE, Occ=LoopBreaker] :: GHC.Prim.Int# -> GHC.Prim.Int# +[GblId, Arity=1, Str=, Unf=OtherCon []] +T18078.$wf + = \ (ww :: GHC.Prim.Int#) -> + case ww of wild { + __DEFAULT -> T18078.$wf (GHC.Prim.-# wild 1#); + 0# -> 0# + } +end Rec } + +-- RHS size: {terms: 10, types: 4, coercions: 0, joins: 0/0} +T18078.f1 [InlPrag=NOUSERINLINE[-1]] :: Int -> Int +[GblId, + Arity=1, + Str=, + Cpr=m1, + 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= \ (w [Occ=Once!] :: Int) -> case w of { GHC.Types.I# ww1 [Occ=Once] -> case T18078.$wf ww1 of ww2 [Occ=Once] { __DEFAULT -> GHC.Types.I# ww2 } }}] +T18078.f1 = \ (w :: Int) -> case w of { GHC.Types.I# ww1 -> case T18078.$wf ww1 of ww2 { __DEFAULT -> GHC.Types.I# ww2 } } + +-- RHS size: {terms: 1, types: 0, coercions: 2, joins: 0/0} +f [InlPrag=NOUSERINLINE[-1]] :: N +[GblId, + Arity=1, + Str=, + Cpr=m1, + Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True, WorkFree=True, Expandable=True, Guidance=ALWAYS_IF(arity=0,unsat_ok=True,boring_ok=True) + Tmpl= T18078.f1 `cast` (Sym (T18078.N:N[0]) :: (Int -> Int) ~R# N)}] +f = T18078.f1 `cast` (Sym (T18078.N:N[0]) :: (Int -> Int) ~R# N) + +-- RHS size: {terms: 12, types: 4, coercions: 0, joins: 0/0} +g :: Int -> Int +[GblId, + Arity=1, + Str=, + Cpr=m1, + 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= \ (x [Occ=Once!] :: Int) -> case x of { GHC.Types.I# x1 [Occ=Once] -> T18078.f1 (GHC.Types.I# (GHC.Prim.+# x1 1#)) }}] +g = \ (x :: Int) -> case x of { GHC.Types.I# x1 -> case T18078.$wf (GHC.Prim.+# x1 1#) of ww { __DEFAULT -> GHC.Types.I# ww } } + + + ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -319,3 +319,7 @@ test('T17810', normal, multimod_compile, ['T17810', '-fspecialise-aggressively - test('T18013', normal, multimod_compile, ['T18013', '-v0 -O']) test('T18098', normal, compile, ['-dcore-lint -O2']) test('T18120', normal, compile, ['-dcore-lint -O']) + +# Cast WW +test('T17673', [ only_ways(['optasm']), grep_errmsg(r'^\w+\.\$wf') ], compile, ['-ddump-simpl -dsuppress-uniques -dppr-cols=9999']) +test('T18078', [ only_ways(['optasm']), grep_errmsg(r'^\w+\.\$wf') ], compile, ['-ddump-simpl -dsuppress-uniques -dppr-cols=9999']) ===================================== testsuite/tests/stranal/should_compile/Makefile ===================================== @@ -10,9 +10,3 @@ T13031: # take only one Int# argument T16029: '$(TEST_HC)' $(TEST_HC_OPTS) -c -O -fforce-recomp T16029.hs -dsuppress-uniques -ddump-simpl | grep '::.*Int' - -T18078: - '$(TEST_HC)' $(TEST_HC_OPTS) -c -O -fforce-recomp T18078.hs -dsuppress-uniques -ddump-simpl | grep 'wf' - -T17673: - '$(TEST_HC)' $(TEST_HC_OPTS) -c -O -fforce-recomp T17673.hs -dsuppress-uniques -ddump-simpl | grep 'wf' ===================================== testsuite/tests/stranal/should_compile/T17673.stdout deleted ===================================== @@ -1,5 +0,0 @@ -T17673.$wfacIO [InlPrag=NOINLINE, Occ=LoopBreaker] -T17673.$wfacIO - case T17673.$wfacIO (GHC.Prim.-# ww 1#) w of { (# ipv, ipv1 #) -> - T17673.$wfacIO ww1 w1 - case w of { GHC.Types.I# ww1 -> T17673.$wfacIO ww1 w1 } ===================================== testsuite/tests/stranal/should_compile/T18078.stdout deleted ===================================== @@ -1,6 +0,0 @@ -T18078.$wf [InlPrag=NOINLINE, Occ=LoopBreaker] -T18078.$wf - __DEFAULT -> T18078.$wf (GHC.Prim.-# wild 1#); - case T18078.$wf ww1 of ww2 [Occ=Once] { __DEFAULT -> - case T18078.$wf ww1 of ww2 { __DEFAULT -> GHC.Types.I# ww2 } - case T18078.$wf (GHC.Prim.+# x1 1#) of ww { __DEFAULT -> ===================================== testsuite/tests/stranal/should_compile/all.T ===================================== @@ -52,6 +52,3 @@ 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']) test('T13380b', [ grep_errmsg('bigDeadAction') ], compile, ['-dppr-cols=200 -ddump-simpl']) -test('T18078', normal, makefile_test, []) -test('T17673', normal, makefile_test, []) - View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fe99560e3942c64dc5e397ec9c3c8e8423b626aa -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fe99560e3942c64dc5e397ec9c3c8e8423b626aa You're receiving 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 26 20:40:06 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Tue, 26 May 2020 16:40:06 -0400 Subject: [Git][ghc/ghc][wip/ticky-eventlog] 2 commits: rts: Post ticky entry counts to the eventlog Message-ID: <5ecd7ea68afaa_6e26c5c8abc17854cb@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/ticky-eventlog at Glasgow Haskell Compiler / GHC Commits: ad25269c by Ben Gamari at 2020-05-26T16:40:00-04:00 rts: Post ticky entry counts to the eventlog We currently only post the entry counters, not the other global counters as in my experience the former are more useful. We use the heap profiler's census period to decide when to dump. Also adds documentation for a few more ticky flags. - - - - - a6ec2bb3 by Ben Gamari at 2020-05-26T16:40:00-04:00 users guide: Fix a few sundry formatting issues - - - - - 17 changed files: - docs/users_guide/eventlog-formats.rst - docs/users_guide/expected-undocumented-flags.txt - docs/users_guide/extending_ghc.rst - docs/users_guide/profiling.rst - docs/users_guide/runtime_control.rst - docs/users_guide/using-warnings.rst - includes/rts/EventLogFormat.h - includes/rts/Flags.h - rts/Proftimer.c - rts/Proftimer.h - rts/RtsFlags.c - rts/RtsStartup.c - rts/Ticky.c - rts/Ticky.h - rts/eventlog/EventLog.c - rts/eventlog/EventLog.h - rts/sm/GC.c Changes: ===================================== docs/users_guide/eventlog-formats.rst ===================================== @@ -755,3 +755,37 @@ intended to provide insight into fragmentation of the non-moving heap. :field Word32: number of live blocks. Describes the occupancy of the *blk_sz* sub-heap. + +.. _ticky-counter-events: + +Ticky counters +~~~~~~~~~~~~~~ + +Programs compiled with :ghc-flag:`-ticky` and :ghc-flag:`-eventlog` and invoked +with ``+RTS -lT`` will emit periodic samples of the ticky entry counters to the +eventlog. + +.. event-type:: TICKY_COUNTER_DEF + + :tag: 210 + :length: variable + :field Word64: counter ID + :field Word16: arity/field count + :field String: argument kinds. This is the same as the synonymous field in the + textual ticky summary. + :field String: counter name + + Defines a ticky counter. + +.. event-type:: TICKY_COUNTER_SAMPLE + + :tag: 211 + :length: fixed + :field Word64: counter ID + :field Word64: number of times closures of this type has been entered. + :field Word64: number of allocations (words) + :field Word64: number of times this has been allocated (words). Only + produced for modules compiled with :ghc-flag:`-ticky-allocd`. + + Records the number of entries, and allocations by/of a particular + closure since the last sample. ===================================== docs/users_guide/expected-undocumented-flags.txt ===================================== @@ -167,6 +167,3 @@ -split-objs -syslib -this-component-id --ticky-LNE --ticky-allocd --ticky-dyn-thunk ===================================== docs/users_guide/extending_ghc.rst ===================================== @@ -775,7 +775,7 @@ each case: package/field-n To read an interface file from an external tool without linking to GHC, the format -is described at `Extensible Interface Files`_. +is described at `Extensible Interface Files `_. Source plugin example ^^^^^^^^^^^^^^^^^^^^^ ===================================== docs/users_guide/profiling.rst ===================================== @@ -1630,11 +1630,46 @@ Using “ticky-ticky” profiling (for implementors) Enable ticky-ticky profiling. +.. ghc-flag:: -ticky-allocd + :shortdesc: Enable ticky-ticky counters for number of thunk allocations. + :type: dynamic + :category: + + By default ticky reports only the amount of allocation done *by* a closure. + With :ghc-flag:`-ticky-allocd`, it also reports on allocation *of* a + closure. + +.. ghc-flag:: -ticky-LNE + :shortdesc: Enable ticky-ticky counters for let-no-escape bindings. + :type: dynamic + :category: + + Enable ticky-ticky counters for let-no-escape bindings (i.e. join points). + +.. ghc-flag:: -ticky-dyn-thunk + :shortdesc: Enable ticky-ticky counters on dynamic closures. + :type: dynamic + :category: + + By default ticky reports counts only for *static* closures. With + :ghc-flag:`-ticky-dyn-thunk` it will also report counts for + dynamically-allocated thunks. Note that this will significantly + increase instrumentation costs. + Because ticky-ticky profiling requires a certain familiarity with GHC internals, we have moved the documentation to the GHC developers wiki. Take a look at its :ghc-wiki:`overview of the profiling options `, -which includeds a link to the ticky-ticky profiling page. +which includes a link to the ticky-ticky profiling page. + +Note that GHC can also periodically emit samples of ticky counters to +the :ghc-flag:`eventlog <-eventlog>` by enabling the :rts-flag:`+RTS -lT <-l +⟨flags⟩>` event flag. The sampling period can be set via :rts-flag:`-i ⟨secs⟩` +RTS flag. See the :ref:`eventlog formats ` section for +details on the eventlog representation. + +Note that the traditional text output (e.g. :rts-flag:`-r ⟨file⟩`) and +the eventlog output are mutually exclusive. .. [1] :ghc-flag:`-fprof-auto` was known as ``-auto-all`` prior to ===================================== docs/users_guide/runtime_control.rst ===================================== @@ -1169,6 +1169,9 @@ When the program is linked with the :ghc-flag:`-eventlog` option - ``f`` — parallel sparks (fully accurate). Disabled by default. + - ``T`` — :ref:`ticky-ticky ` profiler counter samples. + Disabled by default. + - ``u`` — user events. These are events emitted from Haskell code using functions such as ``Debug.Trace.traceEvent``. Enabled by default. @@ -1192,10 +1195,10 @@ When the program is linked with the :ghc-flag:`-eventlog` option 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 `__ + `ghc-events `_ library. To dump the contents of a ``.eventlog`` file as text, use the tool ``ghc-events show`` that comes with the - `ghc-events `__ + `ghc-events `_ package. Each event is associated with a timestamp which is the number of ===================================== docs/users_guide/using-warnings.rst ===================================== @@ -239,8 +239,8 @@ of ``-W(no-)*``. - ``Data.List`` due to the future addition of ``Data.List.singleton`` and specialisation of exports to the ``[]`` type. See the - :ref:`mailing list - ` + `mailing list + `_ for details. This warning can be addressed by either adding an explicit import list or ===================================== includes/rts/EventLogFormat.h ===================================== @@ -154,12 +154,15 @@ #define EVENT_CONC_UPD_REM_SET_FLUSH 206 #define EVENT_NONMOVING_HEAP_CENSUS 207 +#define EVENT_TICKY_COUNTER_DEF 210 +#define EVENT_TICKY_COUNTER_SAMPLE 211 + /* * The highest event code +1 that ghc itself emits. Note that some event * ranges higher than this are reserved but not currently emitted by ghc. * This must match the size of the EventDesc[] array in EventLog.c */ -#define NUM_GHC_EVENT_TAGS 208 +#define NUM_GHC_EVENT_TAGS 212 #if 0 /* DEPRECATED EVENTS: */ /* we don't actually need to record the thread, it's implicit */ ===================================== includes/rts/Flags.h ===================================== @@ -176,6 +176,7 @@ typedef struct _TRACE_FLAGS { bool nonmoving_gc; /* trace nonmoving GC events */ bool sparks_sampled; /* trace spark events by a sampled method */ bool sparks_full; /* trace spark events 100% accurately */ + bool ticky; /* trace ticky-ticky samples */ bool user; /* trace user events (emitted from Haskell code) */ char *trace_output; /* output filename for eventlog */ } TRACE_FLAGS; ===================================== rts/Proftimer.c ===================================== @@ -20,6 +20,12 @@ static bool do_prof_ticks = false; // enable profiling ticks static bool do_heap_prof_ticks = false; // enable heap profiling ticks +// Sampling of Ticky-Ticky profiler to eventlog +#if defined(TICKY_TICKY) && defined(TRACING) +static int ticks_to_ticky_sample = 0; +bool performTickySample = false; +#endif + // Number of ticks until next heap census static int ticks_to_heap_profile; @@ -83,6 +89,16 @@ handleProfTick(void) } #endif +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + ticks_to_ticky_sample--; + if (ticks_to_ticky_sample <= 0) { + ticks_to_ticky_sample = RtsFlags.ProfFlags.heapProfileIntervalTicks; + performTickySample = true; + } + } +#endif + if (do_heap_prof_ticks) { ticks_to_heap_profile--; if (ticks_to_heap_profile <= 0) { ===================================== rts/Proftimer.h ===================================== @@ -17,5 +17,6 @@ void stopHeapProfTimer ( void ); void startHeapProfTimer ( void ); extern bool performHeapProfile; +extern bool performTickySample; #include "EndPrivate.h" ===================================== rts/RtsFlags.c ===================================== @@ -234,6 +234,7 @@ void initRtsFlagsDefaults(void) RtsFlags.TraceFlags.sparks_sampled= false; RtsFlags.TraceFlags.sparks_full = false; RtsFlags.TraceFlags.user = false; + RtsFlags.TraceFlags.ticky = false; RtsFlags.TraceFlags.trace_output = NULL; #endif @@ -386,6 +387,9 @@ usage_text[] = { " p par spark events (sampled)", " f par spark events (full detail)", " u user events (emitted from Haskell code)", +#if defined(TICKY_TICKY) +" T ticky-ticky counter samples", +#endif " a all event classes above", # if defined(DEBUG) " t add time stamps (only useful with -v)", @@ -1791,6 +1795,11 @@ static void normaliseRtsOpts (void) "the compacting collector."); errorUsage(); } + + if (RtsFlags.TraceFlags.ticky && RtsFlags.TickyFlags.showTickyStats) { + barf("The ticky-ticky eventlog output cannot be used in conjunction with\n" + "+RTS -r."); + } } static void errorUsage (void) @@ -2233,6 +2242,15 @@ static void read_trace_flags(const char *arg) RtsFlags.TraceFlags.user = enabled; enabled = true; break; + case 'T': +#if defined(TICKY_TICKY) + RtsFlags.TraceFlags.ticky = enabled; + enabled = true; + break; +#else + errorBelch("Program not compiled with ticky-ticky support"); + break; +#endif default: errorBelch("unknown trace option: %c",*c); break; ===================================== rts/RtsStartup.c ===================================== @@ -415,6 +415,17 @@ hs_exit_(bool wait_foreign) */ exitTimer(true); + /* + * Dump the ticky counter definitions + * We do this at the end of execution since tickers are registered in the + * course of program execution. + */ +#if defined(TICKY_TICKY) && defined(TRACING) + if (RtsFlags.TraceFlags.ticky) { + emitTickyCounterDefs(); + } +#endif + // set the terminal settings back to what they were #if !defined(mingw32_HOST_OS) resetTerminalSettings(); ===================================== rts/Ticky.c ===================================== @@ -10,6 +10,8 @@ #include "PosixSource.h" #include "Rts.h" +#include "eventlog/EventLog.h" + /* Catch-all top-level counter struct. Allocations from CAFs will go * here. */ @@ -46,6 +48,10 @@ static void printRegisteredCounterInfo (FILE *); /* fwd decl */ void PrintTickyInfo(void) { + if (RtsFlags.TraceFlags.ticky) { + barf("Ticky eventlog output can't be used with +RTS -r"); + } + unsigned long i; unsigned long tot_thk_enters = ENT_STATIC_THK_MANY_ctr + ENT_DYN_THK_MANY_ctr @@ -374,4 +380,19 @@ printRegisteredCounterInfo (FILE *tf) } } + +void emitTickyCounterDefs() +{ +#if defined(TRACING) + postTickyCounterDefs(ticky_entry_ctrs); +#endif +} + +void emitTickyCounterSamples() +{ +#if defined(TRACING) + postTickyCounterSamples(ticky_entry_ctrs); +#endif +} + #endif /* TICKY_TICKY */ ===================================== rts/Ticky.h ===================================== @@ -8,4 +8,11 @@ #pragma once -RTS_PRIVATE void PrintTickyInfo(void); +#include "BeginPrivate.h" + +void PrintTickyInfo(void); + +void emitTickyCounterSamples(void); +void emitTickyCounterDefs(void); + +#include "EndPrivate.h" ===================================== rts/eventlog/EventLog.c ===================================== @@ -119,7 +119,9 @@ char *EventDesc[] = { [EVENT_CONC_SWEEP_BEGIN] = "Begin concurrent sweep", [EVENT_CONC_SWEEP_END] = "End concurrent sweep", [EVENT_CONC_UPD_REM_SET_FLUSH] = "Update remembered set flushed", - [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census" + [EVENT_NONMOVING_HEAP_CENSUS] = "Nonmoving heap census", + [EVENT_TICKY_COUNTER_DEF] = "Ticky-ticky entry counter definition", + [EVENT_TICKY_COUNTER_SAMPLE] = "Ticky-ticky entry counter sample", }; // Event type. @@ -487,6 +489,14 @@ init_event_types(void) eventTypes[t].size = 13; break; + case EVENT_TICKY_COUNTER_DEF: // (counter_id, arity, arg_kinds, name) + eventTypes[t].size = EVENT_SIZE_DYNAMIC; + break; + + case EVENT_TICKY_COUNTER_SAMPLE: // (counter_id, entry_count, allocs, allocd) + eventTypes[t].size = 8*4; + break; + default: continue; /* ignore deprecated events */ } @@ -1472,6 +1482,58 @@ void postProfBegin(void) } #endif /* PROFILING */ +#if defined(TICKY_TICKY) +static void postTickyCounterDef(EventsBuf *eb, StgEntCounter *p) +{ + StgWord len = 8 + 2 + strlen(p->arg_kinds)+1 + strlen(p->str)+1; + ensureRoomForVariableEvent(eb, len); + postEventHeader(eb, EVENT_TICKY_COUNTER_DEF); + postPayloadSize(eb, len); + postWord64(eb, (uint64_t) p); + postWord16(eb, (uint16_t) p->arity); + postString(eb, p->arg_kinds); + postString(eb, p->str); +} + +void postTickyCounterDefs(StgEntCounter *counters) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = counters; p != NULL; p = p->link) { + postTickyCounterDef(&eventBuf, p); + } + RELEASE_LOCK(&eventBufMutex); +} + +static void postTickyCounterSample(EventsBuf *eb, StgEntCounter *p) +{ + if ( p->entry_count == 0 + && p->allocs == 0 + && p->allocd == 0) + return; + + ensureRoomForEvent(eb, EVENT_TICKY_COUNTER_SAMPLE); + postEventHeader(eb, EVENT_TICKY_COUNTER_SAMPLE); + postWord64(eb, (uint64_t) p); + postWord64(eb, p->entry_count); + postWord64(eb, p->allocs); + postWord64(eb, p->allocd); + + // Zero the ticker counts for the next sample. + p->entry_count = 0; + p->allocs = 0; + p->allocd = 0; +} + +void postTickyCounterSamples(StgEntCounter *counters) +{ + ACQUIRE_LOCK(&eventBufMutex); + for (StgEntCounter *p = counters; p != NULL; p = p->link) { + postTickyCounterSample(&eventBuf, p); + } + RELEASE_LOCK(&eventBufMutex); +} +#endif /* TICKY_TICKY */ + void printAndClearEventBuf (EventsBuf *ebuf) { closeBlockMarker(ebuf); ===================================== rts/eventlog/EventLog.h ===================================== @@ -173,6 +173,11 @@ void postConcMarkEnd(StgWord32 marked_obj_count); void postNonmovingHeapCensus(int log_blk_size, const struct NonmovingAllocCensus *census); +#if defined(TICKY_TICKY) +void postTickyCounterDefs(StgEntCounter *p); +void postTickyCounterSamples(StgEntCounter *p); +#endif /* TICKY_TICKY */ + #else /* !TRACING */ INLINE_HEADER void postSchedEvent (Capability *cap STG_UNUSED, ===================================== rts/sm/GC.c ===================================== @@ -38,6 +38,7 @@ #include "Sanity.h" #include "BlockAlloc.h" #include "ProfHeap.h" +#include "Proftimer.h" #include "Weak.h" #include "Prelude.h" #include "RtsSignals.h" @@ -52,6 +53,7 @@ #include "CNF.h" #include "RtsFlags.h" #include "NonMoving.h" +#include "Ticky.h" #include // for memset() #include @@ -860,6 +862,16 @@ GarbageCollect (uint32_t collect_gen, ACQUIRE_SM_LOCK; } +#if defined(TICKY_TICKY) + // Post ticky counter sample. + // We do this at the end of execution since tickers are registered in the + // course of program execution. + if (performTickySample) { + emitTickyCounterSamples(); + performTickySample = false; + } +#endif + // send exceptions to any threads which were about to die RELEASE_SM_LOCK; resurrectThreads(resurrected_threads); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/43201e39a98a30364c1108c5646de828dfc11878...a6ec2bb3f31837896cd0ef17efb9c0c7845033e6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/43201e39a98a30364c1108c5646de828dfc11878...a6ec2bb3f31837896cd0ef17efb9c0c7845033e6 You're receiving 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 26 22:13:47 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Tue, 26 May 2020 18:13:47 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 3 commits: core-spec: Modify file paths according to new module hierarchy Message-ID: <5ecd949be3ec5_6e26c5c8abc1793821@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: e7541f7a by Takenobu Tani at 2020-05-26T18:13:35-04:00 core-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Core.hs <= coreSyn/CoreSyn.hs * GHC/Core/Coercion.hs <= types/Coercion.hs * GHC/Core/Coercion/Axiom.hs <= types/CoAxiom.hs * GHC/Core/Coercion/Opt.hs <= types/OptCoercion.hs * GHC/Core/DataCon.hs <= basicTypes/DataCon.hs * GHC/Core/FamInstEnv.hs <= types/FamInstEnv.hs * GHC/Core/Lint.hs <= coreSyn/CoreLint.hs * GHC/Core/Subst.hs <= coreSyn/CoreSubst.hs * GHC/Core/TyCo/Rep.hs <= types/TyCoRep.hs * GHC/Core/TyCon.hs <= types/TyCon.hs * GHC/Core/Type.hs <= types/Type.hs * GHC/Core/Unify.hs <= types/Unify.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/Var.hs <= basicTypes/Var.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [skip ci] - - - - - c7c170a8 by Ben Gamari at 2020-05-26T18:13:36-04:00 eventlog: Fix racy flushing Previously no attempt was made to avoid multiple threads writing their capability-local eventlog buffers to the eventlog writer simultaneously. This could result in multiple eventlog streams being interleaved. Fix this by documenting that the EventLogWriter's write() and flush() functions may be called reentrantly and fix the default writer to protect its FILE* by a mutex. Fixes #18210. - - - - - 1ecba71e by Joshua Price at 2020-05-26T18:13:39-04:00 Make `identifier` parse unparenthesized `->` (#18060) - - - - - 12 changed files: - compiler/GHC/Parser.y - docs/core-spec/CoreLint.ott - docs/core-spec/CoreSyn.ott - docs/core-spec/README - docs/core-spec/core-spec.mng - docs/core-spec/core-spec.pdf - docs/users_guide/runtime_control.rst - includes/rts/EventLogWriter.h - rts/eventlog/EventLogWriter.c - + testsuite/tests/ghci/T18060/T18060.script - + testsuite/tests/ghci/T18060/T18060.stdout - + testsuite/tests/ghci/T18060/all.T Changes: ===================================== compiler/GHC/Parser.y ===================================== @@ -644,6 +644,8 @@ identifier :: { Located RdrName } | qconop { $1 } | '(' '->' ')' {% ams (sLL $1 $> $ getRdrName funTyCon) [mop $1,mu AnnRarrow $2,mcp $3] } + | '->' {% ams (sLL $1 $> $ getRdrName funTyCon) + [mu AnnRarrow $1] } ----------------------------------------------------------------------------- -- Backpack stuff ===================================== docs/core-spec/CoreLint.ott ===================================== @@ -12,7 +12,7 @@ defns CoreLint :: '' ::= -defn |- prog program :: :: lintCoreBindings :: 'Prog_' {{ com Program typing, \coderef{coreSyn/CoreLint.hs}{lintCoreBindings} }} +defn |- prog program :: :: lintCoreBindings :: 'Prog_' {{ com Program typing, \coderef{GHC/Core/Lint.hs}{lintCoreBindings} }} {{ tex \labeledjudge{prog} [[program]] }} by @@ -22,7 +22,7 @@ no_duplicates --------------------- :: CoreBindings |-prog -defn G |- bind binding :: :: lint_bind :: 'Binding_' {{ com Binding typing, \coderef{coreSyn/CoreLint.hs}{lint\_bind} }} +defn G |- bind binding :: :: lint_bind :: 'Binding_' {{ com Binding typing, \coderef{GHC/Core/Lint.hs}{lint\_bind} }} {{ tex [[G]] \labeledjudge{bind} [[binding]] }} by @@ -34,7 +34,7 @@ G |-bind n = e ---------------------- :: Rec G |-bind rec -defn G |- sbind n <- e :: :: lintSingleBinding :: 'SBinding_' {{ com Single binding typing, \coderef{coreSyn/CoreLint.hs}{lintSingleBinding} }} +defn G |- sbind n <- e :: :: lintSingleBinding :: 'SBinding_' {{ com Single binding typing, \coderef{GHC/Core/Lint.hs}{lintSingleBinding} }} {{ tex [[G]] \labeledjudge{sbind} [[n]] [[<-]] [[e]] }} by @@ -45,7 +45,7 @@ G |-name z_t ok ----------------- :: SingleBinding G |-sbind z_t <- e -defn G ; D |-sjbind l vars <- e : t :: :: lintSingleBinding_joins :: 'SJBinding_' {{ com Single join binding typing, \coderef{coreSyn/CoreLint.hs}{lintSingleBinding} }} +defn G ; D |-sjbind l vars <- e : t :: :: lintSingleBinding_joins :: 'SJBinding_' {{ com Single join binding typing, \coderef{GHC/Core/Lint.hs}{lintSingleBinding} }} {{ tex [[G]];[[D]] \labeledjudge{sjbind} [[l]] \, [[vars]] [[<-]] [[e]] : [[t]] }} by @@ -60,7 +60,7 @@ split_I s = t G; D |-sjbind p/I_s <- e : t defn G ; D |- tm e : t :: :: lintCoreExpr :: 'Tm_' - {{ com Expression typing, \coderef{coreSyn/CoreLint.hs}{lintCoreExpr} }} + {{ com Expression typing, \coderef{GHC/Core/Lint.hs}{lintCoreExpr} }} {{ tex [[G]]; [[D]] \labeledjudge{tm} [[e]] : [[t]] }} by @@ -171,7 +171,7 @@ G |-co g : t1 k1~Rep k2 t2 G; D |-tm g : (~Rep#) k1 k2 t1 t2 defn G |- name n ok :: :: lintSingleBinding_lintBinder :: 'Name_' - {{ com Name consistency check, \coderef{coreSyn/CoreLint.hs}{lintSingleBinding\#lintBinder} }} + {{ com Name consistency check, \coderef{GHC/Core/Lint.hs}{lintSingleBinding\#lintBinder} }} {{ tex [[G]] \labeledjudge{n} [[n]] [[ok]] }} by @@ -184,7 +184,7 @@ G |-name x_t ok G |-name alpha_k ok defn G |- label l ok :: :: lintSingleBinding_lintBinder_join :: 'Label_' - {{ com Label consistency check, \coderef{coreSyn/CoreLint.hs}{lintSingleBinding\#lintBinder} }} + {{ com Label consistency check, \coderef{GHC/Core/Lint.hs}{lintSingleBinding\#lintBinder} }} {{ tex [[G]] \labeledjudge{label} [[l]] [[ok]] }} by @@ -197,7 +197,7 @@ k' = * \/ k' = # G |-label p / I _ t ok defn G |- bnd n ok :: :: lintBinder :: 'Binding_' - {{ com Binding consistency, \coderef{coreSyn/CoreLint.hs}{lintBinder} }} + {{ com Binding consistency, \coderef{GHC/Core/Lint.hs}{lintBinder} }} {{ tex [[G]] \labeledjudge{bnd} [[n]] [[ok]] }} by @@ -211,7 +211,7 @@ G |-ki k ok G |-bnd alpha_k ok defn G |- co g : t1 k1 ~ R k2 t2 :: :: lintCoercion :: 'Co_' - {{ com Coercion typing, \coderef{coreSyn/CoreLint.hs}{lintCoercion} }} + {{ com Coercion typing, \coderef{GHC/Core/Lint.hs}{lintCoercion} }} {{ tex [[G]] \labeledjudge{co} [[g]] : [[t1]] \mathop{ {}^{[[k1]]} {\sim}_{[[R]]}^{[[k2]]} } [[t2]] }} by @@ -375,7 +375,7 @@ G |-ty t'2 : k0' G |-co mu $ : t'1 k0 ~R' k0' t'2 defn G |- axk [ namesroles |-> gs ] ~> ( subst1 , subst2 ) :: :: check_ki :: 'AxiomKind_' - {{ com Axiom argument kinding, \coderef{coreSyn/CoreLint.hs}{lintCoercion\#check\_ki} }} + {{ com Axiom argument kinding, \coderef{GHC/Core/Lint.hs}{lintCoercion\#check\_ki} }} {{ tex [[G]] \labeledjudge{axk} [ [[namesroles]] [[|->]] [[gs]] ] [[~>]] ([[subst1]], [[subst2]]) }} by @@ -451,7 +451,7 @@ O |- t |> g : R O |- g : Ph defn R1 <= R2 :: :: ltRole :: 'Rlt_' - {{ com Sub-role relation, \coderef{types/Coercion.hs}{ltRole} }} + {{ com Sub-role relation, \coderef{GHC/Core/Coercion.hs}{ltRole} }} {{ tex [[R1]] \leq [[R2]] }} by @@ -465,7 +465,7 @@ R <= Ph R <= R defn G |- ki k ok :: :: lintKind :: 'K_' - {{ com Kind validity, \coderef{coreSyn/CoreLint.hs}{lintKind} }} + {{ com Kind validity, \coderef{GHC/Core/Lint.hs}{lintKind} }} {{ tex [[G]] \labeledjudge{k} [[k]] [[ok]] }} by @@ -478,7 +478,7 @@ G |-ty k : # G |-ki k ok defn G |- ty t : k :: :: lintType :: 'Ty_' - {{ com Kinding, \coderef{coreSyn/CoreLint.hs}{lintType} }} + {{ com Kinding, \coderef{GHC/Core/Lint.hs}{lintType} }} {{ tex [[G]] \labeledjudge{ty} [[t]] : [[k]] }} by @@ -535,7 +535,7 @@ G |-co g : t1 k1 ~Rep k2 t2 G |-ty g : (~Rep#) k1 k2 t1 t2 defn G |- subst n |-> t ok :: :: lintTyKind :: 'Subst_' - {{ com Substitution consistency, \coderef{coreSyn/CoreLint.hs}{lintTyKind} }} + {{ com Substitution consistency, \coderef{GHC/Core/Lint.hs}{lintTyKind} }} {{ tex [[G]] \labeledjudge{subst} [[n]] [[|->]] [[t]] [[ok]] }} by @@ -544,7 +544,7 @@ G |-ty t : k G |-subst z_k |-> t ok defn G ; D ; s |- altern alt : t :: :: lintCoreAlt :: 'Alt_' - {{ com Case alternative consistency, \coderef{coreSyn/CoreLint.hs}{lintCoreAlt} }} + {{ com Case alternative consistency, \coderef{GHC/Core/Lint.hs}{lintCoreAlt} }} {{ tex [[G]];[[D]];[[s]] \labeledjudge{alt} [[alt]] : [[t]] }} by @@ -569,7 +569,7 @@ G'; D |-tm e : t G; D; T |-altern K -> e : t defn t' = t { } :: :: applyTys :: 'ApplyTys_' - {{ com Telescope substitution, \coderef{types/Type.hs}{applyTys} }} + {{ com Telescope substitution, \coderef{GHC/Core/Type.hs}{applyTys} }} by --------------------- :: Empty @@ -581,7 +581,7 @@ t'' = t'[n |-> s] t'' = (forall n. t) { s, } defn G |- altbnd vars : t1 ~> t2 :: :: lintAltBinders :: 'AltBinders_' - {{ com Case alternative binding consistency, \coderef{coreSyn/CoreLint.hs}{lintAltBinders} }} + {{ com Case alternative binding consistency, \coderef{GHC/Core/Lint.hs}{lintAltBinders} }} {{ tex [[G]] \labeledjudge{altbnd} [[vars]] : [[t1]] [[~>]] [[t2]] }} by @@ -602,7 +602,7 @@ G |-altbnd : t2 ~> s G |-altbnd x_t1, : (t1 -> t2) ~> s defn G |- arrow k1 -> k2 : k :: :: lintArrow :: 'Arrow_' - {{ com Arrow kinding, \coderef{coreSyn/CoreLint.hs}{lintArrow} }} + {{ com Arrow kinding, \coderef{GHC/Core/Lint.hs}{lintArrow} }} {{ tex [[G]] \labeledjudge{\rightarrow} [[k1]] [[->]] [[k2]] : [[k]] }} by @@ -612,7 +612,7 @@ k2 = TYPE s G |-arrow k1 -> k2 : * defn G |- app kinded_types : k1 ~> k2 :: :: lint_app :: 'App_' - {{ com Type application kinding, \coderef{coreSyn/CoreLint.hs}{lint\_app} }} + {{ com Type application kinding, \coderef{GHC/Core/Lint.hs}{lint\_app} }} {{ tex [[G]] \labeledjudge{app} [[kinded_types]] : [[k1]] [[~>]] [[k2]] }} by @@ -628,7 +628,7 @@ G |-app : k2[z_k1 |-> t] ~> k' G |-app (t : k1), : (forall z_k1. k2) ~> k' defn no_conflict ( C , , ind1 , ind2 ) :: :: check_no_conflict :: 'NoConflict_' - {{ com \parbox{5in}{Branched axiom conflict checking, \coderef{types/OptCoercion.hs}{checkAxInstCo} \\ and \coderef{types/FamInstEnv.hs}{compatibleBranches} } }} + {{ com \parbox{5in}{Branched axiom conflict checking, \coderef{GHC/Core/Coercion/Opt.hs}{checkAxInstCo} \\ and \coderef{GHC/Core/FamInstEnv.hs}{compatibleBranches} } }} by ------------------------------------------------ :: NoBranch ===================================== docs/core-spec/CoreSyn.ott ===================================== @@ -34,19 +34,19 @@ indexvar i, j, kk {{ tex k }}, aa {{ tex a }}, bb {{ tex b }}, cc {{ tex c }} :: grammar lit {{ tex \textsf{lit} }} :: 'Literal_' ::= - {{ com Literals, \coderef{basicTypes/Literal.hs}{Literal} }} + {{ com Literals, \coderef{GHC/Types/Literal.hs}{Literal} }} z :: 'Name_' ::= {{ com Term or type name }} | alpha :: :: Type {{ com Type-level name }} | x :: :: Term {{ com Term-level name }} -n, m, aname {{ tex \alpha }}, xname {{ tex x }} :: 'Var_' ::= {{ com Variable names, \coderef{basicTypes/Var.hs}{Var} }} +n, m, aname {{ tex \alpha }}, xname {{ tex x }} :: 'Var_' ::= {{ com Variable names, \coderef{GHC/Types/Var.hs}{Var} }} | z _ t :: :: IdOrTyVar {{ com Name, labeled with type/kind }} {{ tex {[[z]]}^{[[t]]} }} | z $ :: M :: NoSupScript {{ com Name without an explicit type/kind }} | K :: M :: DataCon {{ com Data constructor }} -l :: 'Label_' ::= {{ com Labels for join points, also \coderef{basicTypes/Var.hs}{Var} }} +l :: 'Label_' ::= {{ com Labels for join points, also \coderef{GHC/Types/Var.hs}{Var} }} | p / I _ t :: :: Label {{ com Label with join arity and type }} {{ tex {[[p]]}_{[[I]]}^{[[t]]} }} @@ -64,7 +64,7 @@ labels :: 'Labels_' ::= {{ com List of labels }} | :: :: List | empty :: M :: empty -e, u :: 'Expr_' ::= {{ com Expressions, \coderef{coreSyn/CoreSyn.hs}{Expr} }} +e, u :: 'Expr_' ::= {{ com Expressions, \coderef{GHC/Core.hs}{Expr} }} | n :: :: Var {{ com \ctor{Var}: Variable }} | lit :: :: Lit {{ com \ctor{Lit}: Literal }} | e1 e2 :: :: App {{ com \ctor{App}: Application }} @@ -85,31 +85,31 @@ e, u :: 'Expr_' ::= {{ com Expressions, \coderef{coreSyn/CoreSyn.hs}{Expr} }} | \\ e :: M :: Newline {{ tex \qquad \\ \multicolumn{1}{r}{[[e]]} }} -binding :: 'Bind_' ::= {{ com Let-bindings, \coderef{coreSyn/CoreSyn.hs}{Bind} }} +binding :: 'Bind_' ::= {{ com Let-bindings, \coderef{GHC/Core.hs}{Bind} }} | n = e :: :: NonRec {{ com \ctor{NonRec}: Non-recursive binding }} | rec :: :: Rec {{ com \ctor{Rec}: Recursive binding }} -jbinding :: 'JoinBind_' ::= {{ com Join bindings, also \coderef{coreSyn/CoreSyn.hs}{Bind} }} +jbinding :: 'JoinBind_' ::= {{ com Join bindings, also \coderef{GHC/Core.hs}{Bind} }} | l = e :: :: NonRec {{ com \ctor{NonRec}: Non-recursive binding }} | rec = ei // i /> :: :: Rec {{ com \ctor{Rec}: Recursive binding }} -alt :: 'Alt_' ::= {{ com Case alternative, \coderef{coreSyn/CoreSyn.hs}{Alt} }} +alt :: 'Alt_' ::= {{ com Case alternative, \coderef{GHC/Core.hs}{Alt} }} | Kp -> e :: :: Alt {{ com Constructor applied to fresh names }} -tick :: 'Tickish_' ::= {{ com Internal notes, \coderef{coreSyn/CoreSyn.hs}{Tickish} }} +tick :: 'Tickish_' ::= {{ com Internal notes, \coderef{GHC/Core.hs}{Tickish} }} -Kp {{ tex \mathbb{K} }} :: 'AltCon_' ::= {{ com Constructors used in patterns, \coderef{coreSyn/CoreSyn.hs}{AltCon} }} +Kp {{ tex \mathbb{K} }} :: 'AltCon_' ::= {{ com Constructors used in patterns, \coderef{GHC/Core.hs}{AltCon} }} | K :: :: DataAlt {{ com \ctor{DataAlt}: Data constructor }} | lit :: :: LitAlt {{ com \ctor{LitAlt}: Literal (such as an integer or character) }} | _ :: :: DEFAULT {{ com \ctor{DEFAULT}: Wildcard }} -program :: 'CoreProgram_' ::= {{ com A System FC program, \coderef{coreSyn/CoreSyn.hs}{CoreProgram} }} +program :: 'CoreProgram_' ::= {{ com A System FC program, \coderef{GHC/Core.hs}{CoreProgram} }} | :: :: CoreProgram {{ com List of bindings }} %% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% t {{ tex \tau }}, k {{ tex \kappa }}, s {{ tex \sigma }}, phi {{ tex \phi }} - :: 'Type_' ::= {{ com Types/kinds, \coderef{types/TyCoRep.hs}{Type} }} + :: 'Type_' ::= {{ com Types/kinds, \coderef{GHC/Core/TyCo/Rep.hs}{Type} }} | n :: :: TyVarTy {{ com \ctor{TyVarTy}: Variable }} | t1 t2 :: :: AppTy {{ com \ctor{AppTy}: Application }} | T :: :: TyConApp {{ com \ctor{TyConApp}: Application of type constructor }} @@ -118,12 +118,12 @@ t {{ tex \tau }}, k {{ tex \kappa }}, s {{ tex \sigma }}, phi {{ tex \phi }} | lit :: :: LitTy {{ com \ctor{LitTy}: Type-level literal }} | t |> g :: :: CastTy {{ com \ctor{CastTy}: Kind cast }} | g :: :: CoercionTy {{ com \ctor{CoercionTy}: Coercion used in type }} - | tyConKind T :: M :: tyConKind {{ com \coderef{types/TyCon.hs}{tyConKind} }} + | tyConKind T :: M :: tyConKind {{ com \coderef{GHC/Core/TyCon.hs}{tyConKind} }} | t1 k1 ~# k2 t2 :: M :: unliftedEq {{ com Metanotation for coercion types }} {{ tex [[t1]] \mathop{ {}^{[[k1]]}\!\! \sim_{\#}^{[[k2]]} } [[t2]] }} | t1 k1 ~Rep# k2 t2 :: M :: unliftedREq {{ com Metanotation for coercion types }} {{ tex [[t1]] \mathop{ {}^{[[k1]]}\!\! \sim_{\mathsf{R}\#}^{[[k2]]} } [[t2]] }} - | literalType lit :: M :: literalType {{ com \coderef{basicTypes/Literal.hs}{literalType} }} + | literalType lit :: M :: literalType {{ com \coderef{GHC/Types/Literal.hs}{literalType} }} | ( t ) :: M :: parens {{ com Parentheses }} | { t } :: M :: IParens {{ com Invisible parentheses }} {{ tex [[t]] }} @@ -137,7 +137,7 @@ t {{ tex \tau }}, k {{ tex \kappa }}, s {{ tex \sigma }}, phi {{ tex \phi }} %% COERCIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -g {{ tex \gamma }}, h {{ tex \eta }} :: 'Coercion_' ::= {{ com Coercions, \coderef{types/TyCoRep.hs}{Coercion} }} +g {{ tex \gamma }}, h {{ tex \eta }} :: 'Coercion_' ::= {{ com Coercions, \coderef{GHC/Core/TyCo/Rep.hs}{Coercion} }} | < t > :: :: Refl {{ com \ctor{Refl}: Nominal Reflexivity }} {{ tex {\langle [[t]] \rangle} }} | < t > R mg :: :: GRefl {{ com \ctor{GRefl}: Generalized Reflexivity }} @@ -165,7 +165,7 @@ g {{ tex \gamma }}, h {{ tex \eta }} :: 'Coercion_' ::= {{ com Coercions, \coder | t $ liftingsubst :: M :: Lifted {{ com Type lifted to coercion }} | downgradeRole R g :: M :: downgradeRole {{ com \textsf{downgradeRole} }} -prov :: 'UnivCoProvenance_' ::= {{ com \ctor{UnivCo} provenance, \coderef{types/TyCoRep.hs}{UnivCoProvenance} }} +prov :: 'UnivCoProvenance_' ::= {{ com \ctor{UnivCo} provenance, \coderef{GHC/Core/TyCo/Rep.hs}{UnivCoProvenance} }} | UnsafeCoerceProv :: :: UnsafeCoerceProv {{ com From \texttt{unsafeCoerce\#} }} {{ tex \mathsf{unsafe} }} | PhantomProv :: :: PhantomProv {{ com From the need for a phantom coercion }} @@ -173,20 +173,20 @@ prov :: 'UnivCoProvenance_' ::= {{ com \ctor{UnivCo} provenance, \coderef{types/ | ProofIrrelProv :: :: ProofIrrelProv {{ com From proof irrelevance }} {{ tex \mathsf{irrel} }} -mg {{ tex m }} :: 'MCoercion_' ::= {{ com A possibly reflexive coercion , \coderef{types/TyCoRep.hs}{MCoercion} }} +mg {{ tex m }} :: 'MCoercion_' ::= {{ com A possibly reflexive coercion , \coderef{GHC/Core/TyCo/Rep.hs}{MCoercion} }} | MRefl :: :: MRefl {{ com \ctor{MRefl}: A trivial reflexive coercion }} | MCo g :: :: MCo {{ com \ctor{MCo}: Other coercions }} {{ tex [[g]] }} -LorR :: 'LeftOrRight_' ::= {{ com left or right deconstructor, \coderef{types/TyCoRep.hs}{LeftOrRight} }} +LorR :: 'LeftOrRight_' ::= {{ com left or right deconstructor, \coderef{GHC/Core/TyCo/Rep.hs}{LeftOrRight} }} | Left :: :: CLeft {{ com \ctor{CLeft}: Left projection }} | Right :: :: CRight {{ com \ctor{CRight}: Right projection }} -C :: 'CoAxiom_' ::= {{ com Axioms, \coderef{types/TyCon.hs}{CoAxiom} }} +C :: 'CoAxiom_' ::= {{ com Axioms, \coderef{GHC/Core/TyCon.hs}{CoAxiom} }} | T RA :: :: CoAxiom {{ com \ctor{CoAxiom}: Axiom }} | ( C ) :: M :: Parens {{ com Parentheses }} -R {{ tex \rho }} :: 'Role_' ::= {{ com Roles, \coderef{types/CoAxiom.hs}{Role} }} +R {{ tex \rho }} :: 'Role_' ::= {{ com Roles, \coderef{GHC/Core/Coercion/Axiom.hs}{Role} }} | Nom :: :: Nominal {{ com Nominal }} {{ tex \mathsf{N} }} | Rep :: :: Representational {{ com Representational }} @@ -195,17 +195,17 @@ R {{ tex \rho }} :: 'Role_' ::= {{ com Roles, \coderef{types/CoAxiom.hs}{Role} } {{ tex \mathsf{P} }} | role_list [ i ] :: M :: RoleListIndex {{ com Look up in list }} -axBranch, b :: 'CoAxBranch_' ::= {{ com Axiom branches, \coderef{types/TyCon.hs}{CoAxBranch} }} +axBranch, b :: 'CoAxBranch_' ::= {{ com Axiom branches, \coderef{GHC/Core/TyCon.hs}{CoAxBranch} }} | forall . ( ~> s ) :: :: CoAxBranch {{ com \ctor{CoAxBranch}: Axiom branch }} | ( ) [ ind ] :: M :: lookup {{ com List lookup }} -mu {{ tex \mu }} :: 'CoAxiomRule_' ::= {{ com CoAxiomRules, \coderef{types/CoAxiom.hs}{CoAxiomRule} }} +mu {{ tex \mu }} :: 'CoAxiomRule_' ::= {{ com CoAxiomRules, \coderef{GHC/Core/Coercion/Axiom.hs}{CoAxiomRule} }} | M ( I , role_list , R' ) :: :: CoAxiomRule {{ com Named rule, with parameter info }} {{ tex {[[M]]}_{([[I]], [[ role_list ]], [[R']])} }} %% TYCONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -T :: 'TyCon_' ::= {{ com Type constructors, \coderef{types/TyCon.hs}{TyCon} }} +T :: 'TyCon_' ::= {{ com Type constructors, \coderef{GHC/Core/TyCon.hs}{TyCon} }} | ( -> ) :: :: FunTyCon {{ com \ctor{FunTyCon}: Arrow }} % the following also includes TupleTyCon, SynTyCon @@ -226,22 +226,22 @@ H :: 'PrimTyCon_' ::= {{ com Primitive type constructors, \coderef{GHC.Builtin.T | TYPE :: :: TYPE {{ com TYPE (\texttt{tYPETyCon}) }} | Levity :: :: Levity {{ com Levity (\texttt{LevityTyCon}) }} -K :: 'DataCon_' ::= {{ com Data constructors, \coderef{basicTypes/DataCon.hs}{DataCon} }} +K :: 'DataCon_' ::= {{ com Data constructors, \coderef{GHC/Core/DataCon.hs}{DataCon} }} | Lifted :: :: Lifted {{ com \ctor{Lifted}, a lifted type }} | Unlifted :: :: Unlifted {{ com \ctor{Unlifted}, an unlifted type }} %% CONTEXTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -G {{ tex \Gamma }} :: 'LintM_Bindings_' ::= {{ com List of bindings, \coderef{coreSyn/CoreLint.hs}{LintM} }} +G {{ tex \Gamma }} :: 'LintM_Bindings_' ::= {{ com List of bindings, \coderef{GHC/Core/Lint.hs}{LintM} }} | n :: :: Binding {{ com Single binding }} | :: :: Concat {{ com Context concatenation }} - | vars_of binding :: M :: VarsOf {{ com \coderef{coreSyn/CoreSyn.hs}{bindersOf} }} + | vars_of binding :: M :: VarsOf {{ com \coderef{GHC/Core.hs}{bindersOf} }} -D {{ tex \Delta }} :: 'LintM_JoinBindings_' ::= {{ com List of join bindings, \coderef{coreSyn/CoreLint.hs}{LintM} }} +D {{ tex \Delta }} :: 'LintM_JoinBindings_' ::= {{ com List of join bindings, \coderef{GHC/Core/Lint.hs}{LintM} }} | l :: :: Binding {{ com Single binding }} | :: :: Concat {{ com Context concatenation }} | empty :: M :: Empty {{ com Empty context }} - | labels_of binding :: M :: LabelsOf {{ com \coderef{coreSyn/CoreSyn.hs}{bindersOf} }} + | labels_of binding :: M :: LabelsOf {{ com \coderef{GHC/Core.hs}{bindersOf} }} O {{ tex \Omega }} :: 'VarEnv_Role_' ::= {{ com Mapping from type variables to roles }} | :: :: List {{ com List of bindings }} ===================================== docs/core-spec/README ===================================== @@ -30,7 +30,7 @@ into LaTeX math-mode code. Thus, the file core-spec.mng is the source for core-spec.tex, which gets processed into core-spec.pdf. The file CoreSyn.ott contains the grammar of System FC, mostly extracted from -compiler/coreSyn/CoreSyn.hs. Here are a few pointers to help those of you +compiler/GHC/Core.hs. Here are a few pointers to help those of you unfamiliar with Ott: - The {{ ... }} snippets are called "homs", and they assist ott in translating @@ -69,7 +69,7 @@ your notation to LaTeX. Three different homs are used: it if necessary to disambiguate other parses. The file CoreLint.ott contains inductively defined judgements for many of the -functions in compiler/coreSyn/CoreLint.hs. Each judgement is labeled with an +functions in compiler/GHC/Core/Lint.hs. Each judgement is labeled with an abbreviation to distinguish it from the others. These abbreviations appear in the source code right after a turnstile |-. The declaration for each judgment contains a reference to the function it represents. Each rule is labeled with ===================================== docs/core-spec/core-spec.mng ===================================== @@ -31,7 +31,7 @@ System FC, as implemented in GHC\footnote{This document was originally prepared by Richard Eisenberg (\texttt{eir at cis.upenn.edu}), but it should be maintained by anyone who edits the functions or data structures mentioned in this file. Please feel free to contact Richard for more information.}\\ -\Large 26 January, 2018 +\Large 26 May, 2020 \end{center} \section{Introduction} @@ -72,8 +72,8 @@ Literals do not play a major role, so we leave them abstract: \gram{\ottlit} -We also leave abstract the function \coderef{basicTypes/Literal.hs}{literalType} -and the judgment \coderef{coreSyn/CoreLint.hs}{lintTyLit} (written $[[G |-tylit lit : k]]$). +We also leave abstract the function \coderef{GHC/Types/Literal.hs}{literalType} +and the judgment \coderef{GHC/Core/Lint.hs}{lintTyLit} (written $[[G |-tylit lit : k]]$). \subsection{Variables} \enlargethispage{10pt} % without this first line of "z" definition is placed on @@ -351,13 +351,13 @@ fresh in the context. In the implementation, of course, some work is done to guarantee this freshness. In particular, adding a new type variable to the context sometimes requires creating a new, fresh variable name and then applying a substitution. We elide these details in this formalism, but -see \coderef{types/Type.hs}{substTyVarBndr} for details. +see \coderef{GHC/Core/Type.hs}{substTyVarBndr} for details. \section{Typing judgments} The following functions are used from GHC. Their names are descriptive, and they -are not formalized here: \coderef{types/TyCon.hs}{tyConKind}, -\coderef{types/TyCon.hs}{tyConArity}, \coderef{basicTypes/DataCon.hs}{dataConTyCon}, \coderef{types/TyCon.hs}{isNewTyCon}, \coderef{basicTypes/DataCon.hs}{dataConRepType}. +are not formalized here: \coderef{GHC/Core/TyCon.hs}{tyConKind}, +\coderef{GHC/Core/TyCon.hs}{tyConArity}, \coderef{GHC/Core/DataCon.hs}{dataConTyCon}, \coderef{GHC/Core/TyCon.hs}{isNewTyCon}, \coderef{GHC/Core/DataCon.hs}{dataConRepType}. \subsection{Program consistency} @@ -367,7 +367,7 @@ and then check each binding. \ottdefnlintCoreBindings{} -Here is the definition of $[[vars_of]]$, taken from \coderef{coreSyn/CoreSyn.hs}{bindersOf}: +Here is the definition of $[[vars_of]]$, taken from \coderef{GHC/Core.hs}{bindersOf}: \[ \begin{array}{ll} @@ -413,11 +413,11 @@ to check each substituted type $[[s'i]]$ in a context containing all the types that come before it in the list of bindings. The $[[G'i]]$ are contexts containing the names and kinds of all type variables (and term variables, for that matter) up to the $i$th binding. This logic is extracted from -\coderef{coreSyn/CoreLint.hs}{lintAndScopeIds}. +\coderef{GHC/Core/Lint.hs}{lintAndScopeIds}. \item The GHC source code checks all arguments in an application expression -all at once using \coderef{coreSyn/CoreSyn.hs}{collectArgs} -and \coderef{coreSyn/CoreLint.hs}{lintCoreArgs}. The operation +all at once using \coderef{GHC/Core.hs}{collectArgs} +and \coderef{GHC/Core/Lint.hs}{lintCoreArgs}. The operation has been unfolded for presentation here. \item If a $[[tick]]$ contains breakpoints, the GHC source performs additional @@ -481,7 +481,7 @@ We believe both technical approaches are equivalent in what coercions they accep \label{sec:name_consistency} There are three very similar checks for names, two performed as part of -\coderef{coreSyn/CoreLint.hs}{lintSingleBinding}: +\coderef{GHC/Core/Lint.hs}{lintSingleBinding}: \ottdefnlintSingleBindingXXlintBinder{} @@ -565,12 +565,12 @@ The judgment $[[apart]]$ checks to see whether two lists of types are surely apart. $[[apart( , )]]$, where $[[ ]]$ is a list of types and $[[ ]]$ is a list of type \emph{patterns} (as in a type family equation), first flattens the $[[ ]]$ using \coderef{types/FamInstEnv.hs}{flattenTys} and then checks to -see if \coderef{types/Unify.hs}{tcUnifyTysFG} returns \texttt{SurelyApart}. + // i /> ]]$ using \coderef{GHC/Core/FamInstEnv.hs}{flattenTys} and then checks to +see if \coderef{GHC/Core/Unify.hs}{tcUnifyTysFG} returns \texttt{SurelyApart}. Flattening takes all type family applications and replaces them with fresh variables, taking care to map identical type family applications to the same fresh variable. -The algorithm $[[unify]]$ is implemented in \coderef{types/Unify.hs}{tcUnifyTys}. +The algorithm $[[unify]]$ is implemented in \coderef{GHC/Core/Unify.hs}{tcUnifyTys}. It performs a standard unification, returning a substitution upon success. \section{Operational semantics} @@ -579,7 +579,7 @@ It performs a standard unification, returning a substitution upon success. GHC does not implement an operational semantics in any concrete form. Most of the rules below are implied by algorithms in, for example, the simplifier and optimizer. Yet, there is no one place in GHC that states these rules, -analogously to \texttt{CoreLint.hs}. +analogously to \texttt{GHC/Core/Lint.hs}. Nevertheless, these rules are included in this document to help the reader understand System FC. @@ -607,17 +607,17 @@ to the constructor. The terms are the regular term arguments stored in an algebraic datatype. Coercions (say, in a GADT) are considered term arguments. \item The rule \ottdrulename{S\_CasePush} is the most complex rule. \begin{itemize} -\item The logic in this rule is implemented in \coderef{coreSyn/CoreSubst.hs}{exprIsConApp\_maybe}. -\item The $[[coercionKind]]$ function (\coderef{types/Coercion.hs}{coercionKind}) +\item The logic in this rule is implemented in \coderef{GHC/Core/Subst.hs}{exprIsConApp\_maybe}. +\item The $[[coercionKind]]$ function (\coderef{GHC/Core/Coercion.hs}{coercionKind}) extracts the two types (and their kinds) from a coercion. It does not require a typing context, as it does not \emph{check} the coercion, just extracts its types. -\item The $[[dataConRepType]]$ function (\coderef{basicTypes/DataCon.hs}{dataConRepType}) extracts the full type of a data constructor. Following the notation for +\item The $[[dataConRepType]]$ function (\coderef{GHC/Core/DataCon.hs}{dataConRepType}) extracts the full type of a data constructor. Following the notation for constructor expressions, the parameters to the constructor are broken into three groups: universally quantified types, existentially quantified types, and terms. \item The substitutions in the last premise to the rule are unusual: they replace \emph{type} variables with \emph{coercions}. This substitution is called lifting -and is implemented in \coderef{types/Coercion.hs}{liftCoSubst}. The notation is +and is implemented in \coderef{GHC/Core/Coercion.hs}{liftCoSubst}. The notation is essentially a pun on the fact that types and coercions have such similar structure. This operation is quite non-trivial. Please see \emph{System FC with Explicit Kind Equality} for details. ===================================== docs/core-spec/core-spec.pdf ===================================== Binary files a/docs/core-spec/core-spec.pdf and b/docs/core-spec/core-spec.pdf differ ===================================== docs/users_guide/runtime_control.rst ===================================== @@ -196,11 +196,17 @@ Furthermore GHC lets you specify the way event log data (see :rts-flag:`-l Hands buffered event log data to your event log writer. Return true on success. Required for a custom :c:type:`EventLogWriter`. + Note that this function may be called by multiple threads + simultaneously. + .. c:member:: void flushEventLog(void) Flush buffers (if any) of your custom :c:type:`EventLogWriter`. This can be ``NULL``. + Note that this function may be called by multiple threads + simultaneously. + .. c:member:: void stopEventLogWriter(void) Called when event logging is about to stop. This can be ``NULL``. ===================================== includes/rts/EventLogWriter.h ===================================== @@ -24,9 +24,13 @@ typedef struct { void (* initEventLogWriter) (void); // Write a series of events returning true on success. + // Note that this may be called by multiple threads simultaneously. + // The writer is responsible for concurrency control. bool (* writeEventLog) (void *eventlog, size_t eventlog_size); // Flush possibly existing buffers (may be NULL) + // Note that this may be called by multiple threads simultaneously. + // The writer is responsible for concurrency control. void (* flushEventLog) (void); // Close an initialized EventLogOutput (may be NULL) ===================================== rts/eventlog/EventLogWriter.c ===================================== @@ -28,6 +28,17 @@ static pid_t event_log_pid = -1; // File for logging events static FILE *event_log_file = NULL; +#if defined(THREADED_RTS) +// Protects event_log_file +static Mutex event_log_mutex; + +static void acquire_event_log_lock(void) { ACQUIRE_LOCK(&event_log_mutex); } +static void release_event_log_lock(void) { RELEASE_LOCK(&event_log_mutex); } +#else +static void acquire_event_log_lock(void) {} +static void release_event_log_lock(void) {} +#endif + static void initEventLogFileWriter(void); static bool writeEventLogFile(void *eventlog, size_t eventlog_size); static void flushEventLogFile(void); @@ -89,6 +100,9 @@ initEventLogFileWriter(void) } stgFree(event_log_filename); +#if defined(THREADED_RTS) + initMutex(&event_log_mutex); +#endif } static bool @@ -97,15 +111,17 @@ writeEventLogFile(void *eventlog, size_t eventlog_size) unsigned char *begin = eventlog; size_t remain = eventlog_size; + acquire_event_log_lock(); while (remain > 0) { size_t written = fwrite(begin, 1, remain, event_log_file); if (written == 0) { + release_event_log_lock(); return false; } remain -= written; begin += written; } - + release_event_log_lock(); return true; } @@ -124,6 +140,9 @@ stopEventLogFileWriter(void) fclose(event_log_file); event_log_file = NULL; } +#if defined(THREADED_RTS) + closeMutex(&event_log_mutex); +#endif } const EventLogWriter FileEventLogWriter = { ===================================== testsuite/tests/ghci/T18060/T18060.script ===================================== @@ -0,0 +1,2 @@ +:i -> +:i ~ ===================================== testsuite/tests/ghci/T18060/T18060.stdout ===================================== @@ -0,0 +1,12 @@ +type (->) :: * -> * -> * +data (->) a b + -- Defined in ‘GHC.Prim’ +infixr -1 -> +instance Applicative ((->) r) -- Defined in ‘GHC.Base’ +instance Functor ((->) r) -- Defined in ‘GHC.Base’ +instance Monad ((->) r) -- Defined in ‘GHC.Base’ +instance Monoid b => Monoid (a -> b) -- Defined in ‘GHC.Base’ +instance Semigroup b => Semigroup (a -> b) -- Defined in ‘GHC.Base’ +type (~) :: forall k. k -> k -> Constraint +class (a ~ b) => (~) a b + -- Defined in ‘GHC.Types’ ===================================== testsuite/tests/ghci/T18060/all.T ===================================== @@ -0,0 +1 @@ +test('T18060', normal, ghci_script, ['T18060.script']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d293975d3477749ad378ecbce0ca1c0249f9c03a...1ecba71ee3ca880032d87e6e5dc89eb4a60d6ecc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d293975d3477749ad378ecbce0ca1c0249f9c03a...1ecba71ee3ca880032d87e6e5dc89eb4a60d6ecc You're receiving 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 27 04:14:01 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 27 May 2020 00:14:01 -0400 Subject: [Git][ghc/ghc][master] core-spec: Modify file paths according to new module hierarchy Message-ID: <5ecde909aa307_6e26c5c8abc180943d@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: ede24126 by Takenobu Tani at 2020-05-27T00:13:55-04:00 core-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Core.hs <= coreSyn/CoreSyn.hs * GHC/Core/Coercion.hs <= types/Coercion.hs * GHC/Core/Coercion/Axiom.hs <= types/CoAxiom.hs * GHC/Core/Coercion/Opt.hs <= types/OptCoercion.hs * GHC/Core/DataCon.hs <= basicTypes/DataCon.hs * GHC/Core/FamInstEnv.hs <= types/FamInstEnv.hs * GHC/Core/Lint.hs <= coreSyn/CoreLint.hs * GHC/Core/Subst.hs <= coreSyn/CoreSubst.hs * GHC/Core/TyCo/Rep.hs <= types/TyCoRep.hs * GHC/Core/TyCon.hs <= types/TyCon.hs * GHC/Core/Type.hs <= types/Type.hs * GHC/Core/Unify.hs <= types/Unify.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/Var.hs <= basicTypes/Var.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [skip ci] - - - - - 5 changed files: - docs/core-spec/CoreLint.ott - docs/core-spec/CoreSyn.ott - docs/core-spec/README - docs/core-spec/core-spec.mng - docs/core-spec/core-spec.pdf Changes: ===================================== docs/core-spec/CoreLint.ott ===================================== @@ -12,7 +12,7 @@ defns CoreLint :: '' ::= -defn |- prog program :: :: lintCoreBindings :: 'Prog_' {{ com Program typing, \coderef{coreSyn/CoreLint.hs}{lintCoreBindings} }} +defn |- prog program :: :: lintCoreBindings :: 'Prog_' {{ com Program typing, \coderef{GHC/Core/Lint.hs}{lintCoreBindings} }} {{ tex \labeledjudge{prog} [[program]] }} by @@ -22,7 +22,7 @@ no_duplicates --------------------- :: CoreBindings |-prog -defn G |- bind binding :: :: lint_bind :: 'Binding_' {{ com Binding typing, \coderef{coreSyn/CoreLint.hs}{lint\_bind} }} +defn G |- bind binding :: :: lint_bind :: 'Binding_' {{ com Binding typing, \coderef{GHC/Core/Lint.hs}{lint\_bind} }} {{ tex [[G]] \labeledjudge{bind} [[binding]] }} by @@ -34,7 +34,7 @@ G |-bind n = e ---------------------- :: Rec G |-bind rec -defn G |- sbind n <- e :: :: lintSingleBinding :: 'SBinding_' {{ com Single binding typing, \coderef{coreSyn/CoreLint.hs}{lintSingleBinding} }} +defn G |- sbind n <- e :: :: lintSingleBinding :: 'SBinding_' {{ com Single binding typing, \coderef{GHC/Core/Lint.hs}{lintSingleBinding} }} {{ tex [[G]] \labeledjudge{sbind} [[n]] [[<-]] [[e]] }} by @@ -45,7 +45,7 @@ G |-name z_t ok ----------------- :: SingleBinding G |-sbind z_t <- e -defn G ; D |-sjbind l vars <- e : t :: :: lintSingleBinding_joins :: 'SJBinding_' {{ com Single join binding typing, \coderef{coreSyn/CoreLint.hs}{lintSingleBinding} }} +defn G ; D |-sjbind l vars <- e : t :: :: lintSingleBinding_joins :: 'SJBinding_' {{ com Single join binding typing, \coderef{GHC/Core/Lint.hs}{lintSingleBinding} }} {{ tex [[G]];[[D]] \labeledjudge{sjbind} [[l]] \, [[vars]] [[<-]] [[e]] : [[t]] }} by @@ -60,7 +60,7 @@ split_I s = t G; D |-sjbind p/I_s <- e : t defn G ; D |- tm e : t :: :: lintCoreExpr :: 'Tm_' - {{ com Expression typing, \coderef{coreSyn/CoreLint.hs}{lintCoreExpr} }} + {{ com Expression typing, \coderef{GHC/Core/Lint.hs}{lintCoreExpr} }} {{ tex [[G]]; [[D]] \labeledjudge{tm} [[e]] : [[t]] }} by @@ -171,7 +171,7 @@ G |-co g : t1 k1~Rep k2 t2 G; D |-tm g : (~Rep#) k1 k2 t1 t2 defn G |- name n ok :: :: lintSingleBinding_lintBinder :: 'Name_' - {{ com Name consistency check, \coderef{coreSyn/CoreLint.hs}{lintSingleBinding\#lintBinder} }} + {{ com Name consistency check, \coderef{GHC/Core/Lint.hs}{lintSingleBinding\#lintBinder} }} {{ tex [[G]] \labeledjudge{n} [[n]] [[ok]] }} by @@ -184,7 +184,7 @@ G |-name x_t ok G |-name alpha_k ok defn G |- label l ok :: :: lintSingleBinding_lintBinder_join :: 'Label_' - {{ com Label consistency check, \coderef{coreSyn/CoreLint.hs}{lintSingleBinding\#lintBinder} }} + {{ com Label consistency check, \coderef{GHC/Core/Lint.hs}{lintSingleBinding\#lintBinder} }} {{ tex [[G]] \labeledjudge{label} [[l]] [[ok]] }} by @@ -197,7 +197,7 @@ k' = * \/ k' = # G |-label p / I _ t ok defn G |- bnd n ok :: :: lintBinder :: 'Binding_' - {{ com Binding consistency, \coderef{coreSyn/CoreLint.hs}{lintBinder} }} + {{ com Binding consistency, \coderef{GHC/Core/Lint.hs}{lintBinder} }} {{ tex [[G]] \labeledjudge{bnd} [[n]] [[ok]] }} by @@ -211,7 +211,7 @@ G |-ki k ok G |-bnd alpha_k ok defn G |- co g : t1 k1 ~ R k2 t2 :: :: lintCoercion :: 'Co_' - {{ com Coercion typing, \coderef{coreSyn/CoreLint.hs}{lintCoercion} }} + {{ com Coercion typing, \coderef{GHC/Core/Lint.hs}{lintCoercion} }} {{ tex [[G]] \labeledjudge{co} [[g]] : [[t1]] \mathop{ {}^{[[k1]]} {\sim}_{[[R]]}^{[[k2]]} } [[t2]] }} by @@ -375,7 +375,7 @@ G |-ty t'2 : k0' G |-co mu $ : t'1 k0 ~R' k0' t'2 defn G |- axk [ namesroles |-> gs ] ~> ( subst1 , subst2 ) :: :: check_ki :: 'AxiomKind_' - {{ com Axiom argument kinding, \coderef{coreSyn/CoreLint.hs}{lintCoercion\#check\_ki} }} + {{ com Axiom argument kinding, \coderef{GHC/Core/Lint.hs}{lintCoercion\#check\_ki} }} {{ tex [[G]] \labeledjudge{axk} [ [[namesroles]] [[|->]] [[gs]] ] [[~>]] ([[subst1]], [[subst2]]) }} by @@ -451,7 +451,7 @@ O |- t |> g : R O |- g : Ph defn R1 <= R2 :: :: ltRole :: 'Rlt_' - {{ com Sub-role relation, \coderef{types/Coercion.hs}{ltRole} }} + {{ com Sub-role relation, \coderef{GHC/Core/Coercion.hs}{ltRole} }} {{ tex [[R1]] \leq [[R2]] }} by @@ -465,7 +465,7 @@ R <= Ph R <= R defn G |- ki k ok :: :: lintKind :: 'K_' - {{ com Kind validity, \coderef{coreSyn/CoreLint.hs}{lintKind} }} + {{ com Kind validity, \coderef{GHC/Core/Lint.hs}{lintKind} }} {{ tex [[G]] \labeledjudge{k} [[k]] [[ok]] }} by @@ -478,7 +478,7 @@ G |-ty k : # G |-ki k ok defn G |- ty t : k :: :: lintType :: 'Ty_' - {{ com Kinding, \coderef{coreSyn/CoreLint.hs}{lintType} }} + {{ com Kinding, \coderef{GHC/Core/Lint.hs}{lintType} }} {{ tex [[G]] \labeledjudge{ty} [[t]] : [[k]] }} by @@ -535,7 +535,7 @@ G |-co g : t1 k1 ~Rep k2 t2 G |-ty g : (~Rep#) k1 k2 t1 t2 defn G |- subst n |-> t ok :: :: lintTyKind :: 'Subst_' - {{ com Substitution consistency, \coderef{coreSyn/CoreLint.hs}{lintTyKind} }} + {{ com Substitution consistency, \coderef{GHC/Core/Lint.hs}{lintTyKind} }} {{ tex [[G]] \labeledjudge{subst} [[n]] [[|->]] [[t]] [[ok]] }} by @@ -544,7 +544,7 @@ G |-ty t : k G |-subst z_k |-> t ok defn G ; D ; s |- altern alt : t :: :: lintCoreAlt :: 'Alt_' - {{ com Case alternative consistency, \coderef{coreSyn/CoreLint.hs}{lintCoreAlt} }} + {{ com Case alternative consistency, \coderef{GHC/Core/Lint.hs}{lintCoreAlt} }} {{ tex [[G]];[[D]];[[s]] \labeledjudge{alt} [[alt]] : [[t]] }} by @@ -569,7 +569,7 @@ G'; D |-tm e : t G; D; T |-altern K -> e : t defn t' = t { } :: :: applyTys :: 'ApplyTys_' - {{ com Telescope substitution, \coderef{types/Type.hs}{applyTys} }} + {{ com Telescope substitution, \coderef{GHC/Core/Type.hs}{applyTys} }} by --------------------- :: Empty @@ -581,7 +581,7 @@ t'' = t'[n |-> s] t'' = (forall n. t) { s, } defn G |- altbnd vars : t1 ~> t2 :: :: lintAltBinders :: 'AltBinders_' - {{ com Case alternative binding consistency, \coderef{coreSyn/CoreLint.hs}{lintAltBinders} }} + {{ com Case alternative binding consistency, \coderef{GHC/Core/Lint.hs}{lintAltBinders} }} {{ tex [[G]] \labeledjudge{altbnd} [[vars]] : [[t1]] [[~>]] [[t2]] }} by @@ -602,7 +602,7 @@ G |-altbnd : t2 ~> s G |-altbnd x_t1, : (t1 -> t2) ~> s defn G |- arrow k1 -> k2 : k :: :: lintArrow :: 'Arrow_' - {{ com Arrow kinding, \coderef{coreSyn/CoreLint.hs}{lintArrow} }} + {{ com Arrow kinding, \coderef{GHC/Core/Lint.hs}{lintArrow} }} {{ tex [[G]] \labeledjudge{\rightarrow} [[k1]] [[->]] [[k2]] : [[k]] }} by @@ -612,7 +612,7 @@ k2 = TYPE s G |-arrow k1 -> k2 : * defn G |- app kinded_types : k1 ~> k2 :: :: lint_app :: 'App_' - {{ com Type application kinding, \coderef{coreSyn/CoreLint.hs}{lint\_app} }} + {{ com Type application kinding, \coderef{GHC/Core/Lint.hs}{lint\_app} }} {{ tex [[G]] \labeledjudge{app} [[kinded_types]] : [[k1]] [[~>]] [[k2]] }} by @@ -628,7 +628,7 @@ G |-app : k2[z_k1 |-> t] ~> k' G |-app (t : k1), : (forall z_k1. k2) ~> k' defn no_conflict ( C , , ind1 , ind2 ) :: :: check_no_conflict :: 'NoConflict_' - {{ com \parbox{5in}{Branched axiom conflict checking, \coderef{types/OptCoercion.hs}{checkAxInstCo} \\ and \coderef{types/FamInstEnv.hs}{compatibleBranches} } }} + {{ com \parbox{5in}{Branched axiom conflict checking, \coderef{GHC/Core/Coercion/Opt.hs}{checkAxInstCo} \\ and \coderef{GHC/Core/FamInstEnv.hs}{compatibleBranches} } }} by ------------------------------------------------ :: NoBranch ===================================== docs/core-spec/CoreSyn.ott ===================================== @@ -34,19 +34,19 @@ indexvar i, j, kk {{ tex k }}, aa {{ tex a }}, bb {{ tex b }}, cc {{ tex c }} :: grammar lit {{ tex \textsf{lit} }} :: 'Literal_' ::= - {{ com Literals, \coderef{basicTypes/Literal.hs}{Literal} }} + {{ com Literals, \coderef{GHC/Types/Literal.hs}{Literal} }} z :: 'Name_' ::= {{ com Term or type name }} | alpha :: :: Type {{ com Type-level name }} | x :: :: Term {{ com Term-level name }} -n, m, aname {{ tex \alpha }}, xname {{ tex x }} :: 'Var_' ::= {{ com Variable names, \coderef{basicTypes/Var.hs}{Var} }} +n, m, aname {{ tex \alpha }}, xname {{ tex x }} :: 'Var_' ::= {{ com Variable names, \coderef{GHC/Types/Var.hs}{Var} }} | z _ t :: :: IdOrTyVar {{ com Name, labeled with type/kind }} {{ tex {[[z]]}^{[[t]]} }} | z $ :: M :: NoSupScript {{ com Name without an explicit type/kind }} | K :: M :: DataCon {{ com Data constructor }} -l :: 'Label_' ::= {{ com Labels for join points, also \coderef{basicTypes/Var.hs}{Var} }} +l :: 'Label_' ::= {{ com Labels for join points, also \coderef{GHC/Types/Var.hs}{Var} }} | p / I _ t :: :: Label {{ com Label with join arity and type }} {{ tex {[[p]]}_{[[I]]}^{[[t]]} }} @@ -64,7 +64,7 @@ labels :: 'Labels_' ::= {{ com List of labels }} | :: :: List | empty :: M :: empty -e, u :: 'Expr_' ::= {{ com Expressions, \coderef{coreSyn/CoreSyn.hs}{Expr} }} +e, u :: 'Expr_' ::= {{ com Expressions, \coderef{GHC/Core.hs}{Expr} }} | n :: :: Var {{ com \ctor{Var}: Variable }} | lit :: :: Lit {{ com \ctor{Lit}: Literal }} | e1 e2 :: :: App {{ com \ctor{App}: Application }} @@ -85,31 +85,31 @@ e, u :: 'Expr_' ::= {{ com Expressions, \coderef{coreSyn/CoreSyn.hs}{Expr} }} | \\ e :: M :: Newline {{ tex \qquad \\ \multicolumn{1}{r}{[[e]]} }} -binding :: 'Bind_' ::= {{ com Let-bindings, \coderef{coreSyn/CoreSyn.hs}{Bind} }} +binding :: 'Bind_' ::= {{ com Let-bindings, \coderef{GHC/Core.hs}{Bind} }} | n = e :: :: NonRec {{ com \ctor{NonRec}: Non-recursive binding }} | rec :: :: Rec {{ com \ctor{Rec}: Recursive binding }} -jbinding :: 'JoinBind_' ::= {{ com Join bindings, also \coderef{coreSyn/CoreSyn.hs}{Bind} }} +jbinding :: 'JoinBind_' ::= {{ com Join bindings, also \coderef{GHC/Core.hs}{Bind} }} | l = e :: :: NonRec {{ com \ctor{NonRec}: Non-recursive binding }} | rec = ei // i /> :: :: Rec {{ com \ctor{Rec}: Recursive binding }} -alt :: 'Alt_' ::= {{ com Case alternative, \coderef{coreSyn/CoreSyn.hs}{Alt} }} +alt :: 'Alt_' ::= {{ com Case alternative, \coderef{GHC/Core.hs}{Alt} }} | Kp -> e :: :: Alt {{ com Constructor applied to fresh names }} -tick :: 'Tickish_' ::= {{ com Internal notes, \coderef{coreSyn/CoreSyn.hs}{Tickish} }} +tick :: 'Tickish_' ::= {{ com Internal notes, \coderef{GHC/Core.hs}{Tickish} }} -Kp {{ tex \mathbb{K} }} :: 'AltCon_' ::= {{ com Constructors used in patterns, \coderef{coreSyn/CoreSyn.hs}{AltCon} }} +Kp {{ tex \mathbb{K} }} :: 'AltCon_' ::= {{ com Constructors used in patterns, \coderef{GHC/Core.hs}{AltCon} }} | K :: :: DataAlt {{ com \ctor{DataAlt}: Data constructor }} | lit :: :: LitAlt {{ com \ctor{LitAlt}: Literal (such as an integer or character) }} | _ :: :: DEFAULT {{ com \ctor{DEFAULT}: Wildcard }} -program :: 'CoreProgram_' ::= {{ com A System FC program, \coderef{coreSyn/CoreSyn.hs}{CoreProgram} }} +program :: 'CoreProgram_' ::= {{ com A System FC program, \coderef{GHC/Core.hs}{CoreProgram} }} | :: :: CoreProgram {{ com List of bindings }} %% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% t {{ tex \tau }}, k {{ tex \kappa }}, s {{ tex \sigma }}, phi {{ tex \phi }} - :: 'Type_' ::= {{ com Types/kinds, \coderef{types/TyCoRep.hs}{Type} }} + :: 'Type_' ::= {{ com Types/kinds, \coderef{GHC/Core/TyCo/Rep.hs}{Type} }} | n :: :: TyVarTy {{ com \ctor{TyVarTy}: Variable }} | t1 t2 :: :: AppTy {{ com \ctor{AppTy}: Application }} | T :: :: TyConApp {{ com \ctor{TyConApp}: Application of type constructor }} @@ -118,12 +118,12 @@ t {{ tex \tau }}, k {{ tex \kappa }}, s {{ tex \sigma }}, phi {{ tex \phi }} | lit :: :: LitTy {{ com \ctor{LitTy}: Type-level literal }} | t |> g :: :: CastTy {{ com \ctor{CastTy}: Kind cast }} | g :: :: CoercionTy {{ com \ctor{CoercionTy}: Coercion used in type }} - | tyConKind T :: M :: tyConKind {{ com \coderef{types/TyCon.hs}{tyConKind} }} + | tyConKind T :: M :: tyConKind {{ com \coderef{GHC/Core/TyCon.hs}{tyConKind} }} | t1 k1 ~# k2 t2 :: M :: unliftedEq {{ com Metanotation for coercion types }} {{ tex [[t1]] \mathop{ {}^{[[k1]]}\!\! \sim_{\#}^{[[k2]]} } [[t2]] }} | t1 k1 ~Rep# k2 t2 :: M :: unliftedREq {{ com Metanotation for coercion types }} {{ tex [[t1]] \mathop{ {}^{[[k1]]}\!\! \sim_{\mathsf{R}\#}^{[[k2]]} } [[t2]] }} - | literalType lit :: M :: literalType {{ com \coderef{basicTypes/Literal.hs}{literalType} }} + | literalType lit :: M :: literalType {{ com \coderef{GHC/Types/Literal.hs}{literalType} }} | ( t ) :: M :: parens {{ com Parentheses }} | { t } :: M :: IParens {{ com Invisible parentheses }} {{ tex [[t]] }} @@ -137,7 +137,7 @@ t {{ tex \tau }}, k {{ tex \kappa }}, s {{ tex \sigma }}, phi {{ tex \phi }} %% COERCIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -g {{ tex \gamma }}, h {{ tex \eta }} :: 'Coercion_' ::= {{ com Coercions, \coderef{types/TyCoRep.hs}{Coercion} }} +g {{ tex \gamma }}, h {{ tex \eta }} :: 'Coercion_' ::= {{ com Coercions, \coderef{GHC/Core/TyCo/Rep.hs}{Coercion} }} | < t > :: :: Refl {{ com \ctor{Refl}: Nominal Reflexivity }} {{ tex {\langle [[t]] \rangle} }} | < t > R mg :: :: GRefl {{ com \ctor{GRefl}: Generalized Reflexivity }} @@ -165,7 +165,7 @@ g {{ tex \gamma }}, h {{ tex \eta }} :: 'Coercion_' ::= {{ com Coercions, \coder | t $ liftingsubst :: M :: Lifted {{ com Type lifted to coercion }} | downgradeRole R g :: M :: downgradeRole {{ com \textsf{downgradeRole} }} -prov :: 'UnivCoProvenance_' ::= {{ com \ctor{UnivCo} provenance, \coderef{types/TyCoRep.hs}{UnivCoProvenance} }} +prov :: 'UnivCoProvenance_' ::= {{ com \ctor{UnivCo} provenance, \coderef{GHC/Core/TyCo/Rep.hs}{UnivCoProvenance} }} | UnsafeCoerceProv :: :: UnsafeCoerceProv {{ com From \texttt{unsafeCoerce\#} }} {{ tex \mathsf{unsafe} }} | PhantomProv :: :: PhantomProv {{ com From the need for a phantom coercion }} @@ -173,20 +173,20 @@ prov :: 'UnivCoProvenance_' ::= {{ com \ctor{UnivCo} provenance, \coderef{types/ | ProofIrrelProv :: :: ProofIrrelProv {{ com From proof irrelevance }} {{ tex \mathsf{irrel} }} -mg {{ tex m }} :: 'MCoercion_' ::= {{ com A possibly reflexive coercion , \coderef{types/TyCoRep.hs}{MCoercion} }} +mg {{ tex m }} :: 'MCoercion_' ::= {{ com A possibly reflexive coercion , \coderef{GHC/Core/TyCo/Rep.hs}{MCoercion} }} | MRefl :: :: MRefl {{ com \ctor{MRefl}: A trivial reflexive coercion }} | MCo g :: :: MCo {{ com \ctor{MCo}: Other coercions }} {{ tex [[g]] }} -LorR :: 'LeftOrRight_' ::= {{ com left or right deconstructor, \coderef{types/TyCoRep.hs}{LeftOrRight} }} +LorR :: 'LeftOrRight_' ::= {{ com left or right deconstructor, \coderef{GHC/Core/TyCo/Rep.hs}{LeftOrRight} }} | Left :: :: CLeft {{ com \ctor{CLeft}: Left projection }} | Right :: :: CRight {{ com \ctor{CRight}: Right projection }} -C :: 'CoAxiom_' ::= {{ com Axioms, \coderef{types/TyCon.hs}{CoAxiom} }} +C :: 'CoAxiom_' ::= {{ com Axioms, \coderef{GHC/Core/TyCon.hs}{CoAxiom} }} | T RA :: :: CoAxiom {{ com \ctor{CoAxiom}: Axiom }} | ( C ) :: M :: Parens {{ com Parentheses }} -R {{ tex \rho }} :: 'Role_' ::= {{ com Roles, \coderef{types/CoAxiom.hs}{Role} }} +R {{ tex \rho }} :: 'Role_' ::= {{ com Roles, \coderef{GHC/Core/Coercion/Axiom.hs}{Role} }} | Nom :: :: Nominal {{ com Nominal }} {{ tex \mathsf{N} }} | Rep :: :: Representational {{ com Representational }} @@ -195,17 +195,17 @@ R {{ tex \rho }} :: 'Role_' ::= {{ com Roles, \coderef{types/CoAxiom.hs}{Role} } {{ tex \mathsf{P} }} | role_list [ i ] :: M :: RoleListIndex {{ com Look up in list }} -axBranch, b :: 'CoAxBranch_' ::= {{ com Axiom branches, \coderef{types/TyCon.hs}{CoAxBranch} }} +axBranch, b :: 'CoAxBranch_' ::= {{ com Axiom branches, \coderef{GHC/Core/TyCon.hs}{CoAxBranch} }} | forall . ( ~> s ) :: :: CoAxBranch {{ com \ctor{CoAxBranch}: Axiom branch }} | ( ) [ ind ] :: M :: lookup {{ com List lookup }} -mu {{ tex \mu }} :: 'CoAxiomRule_' ::= {{ com CoAxiomRules, \coderef{types/CoAxiom.hs}{CoAxiomRule} }} +mu {{ tex \mu }} :: 'CoAxiomRule_' ::= {{ com CoAxiomRules, \coderef{GHC/Core/Coercion/Axiom.hs}{CoAxiomRule} }} | M ( I , role_list , R' ) :: :: CoAxiomRule {{ com Named rule, with parameter info }} {{ tex {[[M]]}_{([[I]], [[ role_list ]], [[R']])} }} %% TYCONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -T :: 'TyCon_' ::= {{ com Type constructors, \coderef{types/TyCon.hs}{TyCon} }} +T :: 'TyCon_' ::= {{ com Type constructors, \coderef{GHC/Core/TyCon.hs}{TyCon} }} | ( -> ) :: :: FunTyCon {{ com \ctor{FunTyCon}: Arrow }} % the following also includes TupleTyCon, SynTyCon @@ -226,22 +226,22 @@ H :: 'PrimTyCon_' ::= {{ com Primitive type constructors, \coderef{GHC.Builtin.T | TYPE :: :: TYPE {{ com TYPE (\texttt{tYPETyCon}) }} | Levity :: :: Levity {{ com Levity (\texttt{LevityTyCon}) }} -K :: 'DataCon_' ::= {{ com Data constructors, \coderef{basicTypes/DataCon.hs}{DataCon} }} +K :: 'DataCon_' ::= {{ com Data constructors, \coderef{GHC/Core/DataCon.hs}{DataCon} }} | Lifted :: :: Lifted {{ com \ctor{Lifted}, a lifted type }} | Unlifted :: :: Unlifted {{ com \ctor{Unlifted}, an unlifted type }} %% CONTEXTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -G {{ tex \Gamma }} :: 'LintM_Bindings_' ::= {{ com List of bindings, \coderef{coreSyn/CoreLint.hs}{LintM} }} +G {{ tex \Gamma }} :: 'LintM_Bindings_' ::= {{ com List of bindings, \coderef{GHC/Core/Lint.hs}{LintM} }} | n :: :: Binding {{ com Single binding }} | :: :: Concat {{ com Context concatenation }} - | vars_of binding :: M :: VarsOf {{ com \coderef{coreSyn/CoreSyn.hs}{bindersOf} }} + | vars_of binding :: M :: VarsOf {{ com \coderef{GHC/Core.hs}{bindersOf} }} -D {{ tex \Delta }} :: 'LintM_JoinBindings_' ::= {{ com List of join bindings, \coderef{coreSyn/CoreLint.hs}{LintM} }} +D {{ tex \Delta }} :: 'LintM_JoinBindings_' ::= {{ com List of join bindings, \coderef{GHC/Core/Lint.hs}{LintM} }} | l :: :: Binding {{ com Single binding }} | :: :: Concat {{ com Context concatenation }} | empty :: M :: Empty {{ com Empty context }} - | labels_of binding :: M :: LabelsOf {{ com \coderef{coreSyn/CoreSyn.hs}{bindersOf} }} + | labels_of binding :: M :: LabelsOf {{ com \coderef{GHC/Core.hs}{bindersOf} }} O {{ tex \Omega }} :: 'VarEnv_Role_' ::= {{ com Mapping from type variables to roles }} | :: :: List {{ com List of bindings }} ===================================== docs/core-spec/README ===================================== @@ -30,7 +30,7 @@ into LaTeX math-mode code. Thus, the file core-spec.mng is the source for core-spec.tex, which gets processed into core-spec.pdf. The file CoreSyn.ott contains the grammar of System FC, mostly extracted from -compiler/coreSyn/CoreSyn.hs. Here are a few pointers to help those of you +compiler/GHC/Core.hs. Here are a few pointers to help those of you unfamiliar with Ott: - The {{ ... }} snippets are called "homs", and they assist ott in translating @@ -69,7 +69,7 @@ your notation to LaTeX. Three different homs are used: it if necessary to disambiguate other parses. The file CoreLint.ott contains inductively defined judgements for many of the -functions in compiler/coreSyn/CoreLint.hs. Each judgement is labeled with an +functions in compiler/GHC/Core/Lint.hs. Each judgement is labeled with an abbreviation to distinguish it from the others. These abbreviations appear in the source code right after a turnstile |-. The declaration for each judgment contains a reference to the function it represents. Each rule is labeled with ===================================== docs/core-spec/core-spec.mng ===================================== @@ -31,7 +31,7 @@ System FC, as implemented in GHC\footnote{This document was originally prepared by Richard Eisenberg (\texttt{eir at cis.upenn.edu}), but it should be maintained by anyone who edits the functions or data structures mentioned in this file. Please feel free to contact Richard for more information.}\\ -\Large 26 January, 2018 +\Large 26 May, 2020 \end{center} \section{Introduction} @@ -72,8 +72,8 @@ Literals do not play a major role, so we leave them abstract: \gram{\ottlit} -We also leave abstract the function \coderef{basicTypes/Literal.hs}{literalType} -and the judgment \coderef{coreSyn/CoreLint.hs}{lintTyLit} (written $[[G |-tylit lit : k]]$). +We also leave abstract the function \coderef{GHC/Types/Literal.hs}{literalType} +and the judgment \coderef{GHC/Core/Lint.hs}{lintTyLit} (written $[[G |-tylit lit : k]]$). \subsection{Variables} \enlargethispage{10pt} % without this first line of "z" definition is placed on @@ -351,13 +351,13 @@ fresh in the context. In the implementation, of course, some work is done to guarantee this freshness. In particular, adding a new type variable to the context sometimes requires creating a new, fresh variable name and then applying a substitution. We elide these details in this formalism, but -see \coderef{types/Type.hs}{substTyVarBndr} for details. +see \coderef{GHC/Core/Type.hs}{substTyVarBndr} for details. \section{Typing judgments} The following functions are used from GHC. Their names are descriptive, and they -are not formalized here: \coderef{types/TyCon.hs}{tyConKind}, -\coderef{types/TyCon.hs}{tyConArity}, \coderef{basicTypes/DataCon.hs}{dataConTyCon}, \coderef{types/TyCon.hs}{isNewTyCon}, \coderef{basicTypes/DataCon.hs}{dataConRepType}. +are not formalized here: \coderef{GHC/Core/TyCon.hs}{tyConKind}, +\coderef{GHC/Core/TyCon.hs}{tyConArity}, \coderef{GHC/Core/DataCon.hs}{dataConTyCon}, \coderef{GHC/Core/TyCon.hs}{isNewTyCon}, \coderef{GHC/Core/DataCon.hs}{dataConRepType}. \subsection{Program consistency} @@ -367,7 +367,7 @@ and then check each binding. \ottdefnlintCoreBindings{} -Here is the definition of $[[vars_of]]$, taken from \coderef{coreSyn/CoreSyn.hs}{bindersOf}: +Here is the definition of $[[vars_of]]$, taken from \coderef{GHC/Core.hs}{bindersOf}: \[ \begin{array}{ll} @@ -413,11 +413,11 @@ to check each substituted type $[[s'i]]$ in a context containing all the types that come before it in the list of bindings. The $[[G'i]]$ are contexts containing the names and kinds of all type variables (and term variables, for that matter) up to the $i$th binding. This logic is extracted from -\coderef{coreSyn/CoreLint.hs}{lintAndScopeIds}. +\coderef{GHC/Core/Lint.hs}{lintAndScopeIds}. \item The GHC source code checks all arguments in an application expression -all at once using \coderef{coreSyn/CoreSyn.hs}{collectArgs} -and \coderef{coreSyn/CoreLint.hs}{lintCoreArgs}. The operation +all at once using \coderef{GHC/Core.hs}{collectArgs} +and \coderef{GHC/Core/Lint.hs}{lintCoreArgs}. The operation has been unfolded for presentation here. \item If a $[[tick]]$ contains breakpoints, the GHC source performs additional @@ -481,7 +481,7 @@ We believe both technical approaches are equivalent in what coercions they accep \label{sec:name_consistency} There are three very similar checks for names, two performed as part of -\coderef{coreSyn/CoreLint.hs}{lintSingleBinding}: +\coderef{GHC/Core/Lint.hs}{lintSingleBinding}: \ottdefnlintSingleBindingXXlintBinder{} @@ -565,12 +565,12 @@ The judgment $[[apart]]$ checks to see whether two lists of types are surely apart. $[[apart( , )]]$, where $[[ ]]$ is a list of types and $[[ ]]$ is a list of type \emph{patterns} (as in a type family equation), first flattens the $[[ ]]$ using \coderef{types/FamInstEnv.hs}{flattenTys} and then checks to -see if \coderef{types/Unify.hs}{tcUnifyTysFG} returns \texttt{SurelyApart}. + // i /> ]]$ using \coderef{GHC/Core/FamInstEnv.hs}{flattenTys} and then checks to +see if \coderef{GHC/Core/Unify.hs}{tcUnifyTysFG} returns \texttt{SurelyApart}. Flattening takes all type family applications and replaces them with fresh variables, taking care to map identical type family applications to the same fresh variable. -The algorithm $[[unify]]$ is implemented in \coderef{types/Unify.hs}{tcUnifyTys}. +The algorithm $[[unify]]$ is implemented in \coderef{GHC/Core/Unify.hs}{tcUnifyTys}. It performs a standard unification, returning a substitution upon success. \section{Operational semantics} @@ -579,7 +579,7 @@ It performs a standard unification, returning a substitution upon success. GHC does not implement an operational semantics in any concrete form. Most of the rules below are implied by algorithms in, for example, the simplifier and optimizer. Yet, there is no one place in GHC that states these rules, -analogously to \texttt{CoreLint.hs}. +analogously to \texttt{GHC/Core/Lint.hs}. Nevertheless, these rules are included in this document to help the reader understand System FC. @@ -607,17 +607,17 @@ to the constructor. The terms are the regular term arguments stored in an algebraic datatype. Coercions (say, in a GADT) are considered term arguments. \item The rule \ottdrulename{S\_CasePush} is the most complex rule. \begin{itemize} -\item The logic in this rule is implemented in \coderef{coreSyn/CoreSubst.hs}{exprIsConApp\_maybe}. -\item The $[[coercionKind]]$ function (\coderef{types/Coercion.hs}{coercionKind}) +\item The logic in this rule is implemented in \coderef{GHC/Core/Subst.hs}{exprIsConApp\_maybe}. +\item The $[[coercionKind]]$ function (\coderef{GHC/Core/Coercion.hs}{coercionKind}) extracts the two types (and their kinds) from a coercion. It does not require a typing context, as it does not \emph{check} the coercion, just extracts its types. -\item The $[[dataConRepType]]$ function (\coderef{basicTypes/DataCon.hs}{dataConRepType}) extracts the full type of a data constructor. Following the notation for +\item The $[[dataConRepType]]$ function (\coderef{GHC/Core/DataCon.hs}{dataConRepType}) extracts the full type of a data constructor. Following the notation for constructor expressions, the parameters to the constructor are broken into three groups: universally quantified types, existentially quantified types, and terms. \item The substitutions in the last premise to the rule are unusual: they replace \emph{type} variables with \emph{coercions}. This substitution is called lifting -and is implemented in \coderef{types/Coercion.hs}{liftCoSubst}. The notation is +and is implemented in \coderef{GHC/Core/Coercion.hs}{liftCoSubst}. The notation is essentially a pun on the fact that types and coercions have such similar structure. This operation is quite non-trivial. Please see \emph{System FC with Explicit Kind Equality} for details. ===================================== docs/core-spec/core-spec.pdf ===================================== Binary files a/docs/core-spec/core-spec.pdf and b/docs/core-spec/core-spec.pdf differ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ede241268171e8eee1e750d88ff356ddbfc357f2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ede241268171e8eee1e750d88ff356ddbfc357f2 You're receiving 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 27 04:15:28 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 27 May 2020 00:15:28 -0400 Subject: [Git][ghc/ghc][master] Make `identifier` parse unparenthesized `->` (#18060) Message-ID: <5ecde9606ac5d_6e2612c3348c18193b9@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: d6203f24 by Joshua Price at 2020-05-27T00:15:17-04:00 Make `identifier` parse unparenthesized `->` (#18060) - - - - - 4 changed files: - compiler/GHC/Parser.y - + testsuite/tests/ghci/T18060/T18060.script - + testsuite/tests/ghci/T18060/T18060.stdout - + testsuite/tests/ghci/T18060/all.T Changes: ===================================== compiler/GHC/Parser.y ===================================== @@ -644,6 +644,8 @@ identifier :: { Located RdrName } | qconop { $1 } | '(' '->' ')' {% ams (sLL $1 $> $ getRdrName funTyCon) [mop $1,mu AnnRarrow $2,mcp $3] } + | '->' {% ams (sLL $1 $> $ getRdrName funTyCon) + [mu AnnRarrow $1] } ----------------------------------------------------------------------------- -- Backpack stuff ===================================== testsuite/tests/ghci/T18060/T18060.script ===================================== @@ -0,0 +1,2 @@ +:i -> +:i ~ ===================================== testsuite/tests/ghci/T18060/T18060.stdout ===================================== @@ -0,0 +1,12 @@ +type (->) :: * -> * -> * +data (->) a b + -- Defined in ‘GHC.Prim’ +infixr -1 -> +instance Applicative ((->) r) -- Defined in ‘GHC.Base’ +instance Functor ((->) r) -- Defined in ‘GHC.Base’ +instance Monad ((->) r) -- Defined in ‘GHC.Base’ +instance Monoid b => Monoid (a -> b) -- Defined in ‘GHC.Base’ +instance Semigroup b => Semigroup (a -> b) -- Defined in ‘GHC.Base’ +type (~) :: forall k. k -> k -> Constraint +class (a ~ b) => (~) a b + -- Defined in ‘GHC.Types’ ===================================== testsuite/tests/ghci/T18060/all.T ===================================== @@ -0,0 +1 @@ +test('T18060', normal, ghci_script, ['T18060.script']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d6203f24cf421749616a247c047a9b44192f963a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d6203f24cf421749616a247c047a9b44192f963a You're receiving 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 27 04:14:43 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 27 May 2020 00:14:43 -0400 Subject: [Git][ghc/ghc][master] eventlog: Fix racy flushing Message-ID: <5ecde933908e3_6e263f9f00579e081816414@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 04750304 by Ben Gamari at 2020-05-27T00:14:33-04:00 eventlog: Fix racy flushing Previously no attempt was made to avoid multiple threads writing their capability-local eventlog buffers to the eventlog writer simultaneously. This could result in multiple eventlog streams being interleaved. Fix this by documenting that the EventLogWriter's write() and flush() functions may be called reentrantly and fix the default writer to protect its FILE* by a mutex. Fixes #18210. - - - - - 3 changed files: - docs/users_guide/runtime_control.rst - includes/rts/EventLogWriter.h - rts/eventlog/EventLogWriter.c Changes: ===================================== docs/users_guide/runtime_control.rst ===================================== @@ -196,11 +196,17 @@ Furthermore GHC lets you specify the way event log data (see :rts-flag:`-l Hands buffered event log data to your event log writer. Return true on success. Required for a custom :c:type:`EventLogWriter`. + Note that this function may be called by multiple threads + simultaneously. + .. c:member:: void flushEventLog(void) Flush buffers (if any) of your custom :c:type:`EventLogWriter`. This can be ``NULL``. + Note that this function may be called by multiple threads + simultaneously. + .. c:member:: void stopEventLogWriter(void) Called when event logging is about to stop. This can be ``NULL``. ===================================== includes/rts/EventLogWriter.h ===================================== @@ -24,9 +24,13 @@ typedef struct { void (* initEventLogWriter) (void); // Write a series of events returning true on success. + // Note that this may be called by multiple threads simultaneously. + // The writer is responsible for concurrency control. bool (* writeEventLog) (void *eventlog, size_t eventlog_size); // Flush possibly existing buffers (may be NULL) + // Note that this may be called by multiple threads simultaneously. + // The writer is responsible for concurrency control. void (* flushEventLog) (void); // Close an initialized EventLogOutput (may be NULL) ===================================== rts/eventlog/EventLogWriter.c ===================================== @@ -28,6 +28,17 @@ static pid_t event_log_pid = -1; // File for logging events static FILE *event_log_file = NULL; +#if defined(THREADED_RTS) +// Protects event_log_file +static Mutex event_log_mutex; + +static void acquire_event_log_lock(void) { ACQUIRE_LOCK(&event_log_mutex); } +static void release_event_log_lock(void) { RELEASE_LOCK(&event_log_mutex); } +#else +static void acquire_event_log_lock(void) {} +static void release_event_log_lock(void) {} +#endif + static void initEventLogFileWriter(void); static bool writeEventLogFile(void *eventlog, size_t eventlog_size); static void flushEventLogFile(void); @@ -89,6 +100,9 @@ initEventLogFileWriter(void) } stgFree(event_log_filename); +#if defined(THREADED_RTS) + initMutex(&event_log_mutex); +#endif } static bool @@ -97,15 +111,17 @@ writeEventLogFile(void *eventlog, size_t eventlog_size) unsigned char *begin = eventlog; size_t remain = eventlog_size; + acquire_event_log_lock(); while (remain > 0) { size_t written = fwrite(begin, 1, remain, event_log_file); if (written == 0) { + release_event_log_lock(); return false; } remain -= written; begin += written; } - + release_event_log_lock(); return true; } @@ -124,6 +140,9 @@ stopEventLogFileWriter(void) fclose(event_log_file); event_log_file = NULL; } +#if defined(THREADED_RTS) + closeMutex(&event_log_mutex); +#endif } const EventLogWriter FileEventLogWriter = { View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/04750304deae2128a8350e28224e1f62ae949820 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/04750304deae2128a8350e28224e1f62ae949820 You're receiving 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 27 07:58:03 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Wed, 27 May 2020 03:58:03 -0400 Subject: [Git][ghc/ghc][wip/osa1/lfinfo] 4 commits: core-spec: Modify file paths according to new module hierarchy Message-ID: <5ece1d8b434d9_6e263f9f00579e0818262ca@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/lfinfo at Glasgow Haskell Compiler / GHC Commits: ede24126 by Takenobu Tani at 2020-05-27T00:13:55-04:00 core-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Core.hs <= coreSyn/CoreSyn.hs * GHC/Core/Coercion.hs <= types/Coercion.hs * GHC/Core/Coercion/Axiom.hs <= types/CoAxiom.hs * GHC/Core/Coercion/Opt.hs <= types/OptCoercion.hs * GHC/Core/DataCon.hs <= basicTypes/DataCon.hs * GHC/Core/FamInstEnv.hs <= types/FamInstEnv.hs * GHC/Core/Lint.hs <= coreSyn/CoreLint.hs * GHC/Core/Subst.hs <= coreSyn/CoreSubst.hs * GHC/Core/TyCo/Rep.hs <= types/TyCoRep.hs * GHC/Core/TyCon.hs <= types/TyCon.hs * GHC/Core/Type.hs <= types/Type.hs * GHC/Core/Unify.hs <= types/Unify.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/Var.hs <= basicTypes/Var.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [skip ci] - - - - - 04750304 by Ben Gamari at 2020-05-27T00:14:33-04:00 eventlog: Fix racy flushing Previously no attempt was made to avoid multiple threads writing their capability-local eventlog buffers to the eventlog writer simultaneously. This could result in multiple eventlog streams being interleaved. Fix this by documenting that the EventLogWriter's write() and flush() functions may be called reentrantly and fix the default writer to protect its FILE* by a mutex. Fixes #18210. - - - - - d6203f24 by Joshua Price at 2020-05-27T00:15:17-04:00 Make `identifier` parse unparenthesized `->` (#18060) - - - - - 3c27d986 by Ömer Sinan Ağacan at 2020-05-27T10:57:47+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) | | GHC HEAD | This patch | Diff | |-----|----------|------------|----------------| | -O0 | 0:35.89 | 0:34.10 | -1.78s, -4.98% | | -O1 | 2:24.01 | 2:23.62 | -0.39s, -0.27% | | -O2 | 2:52.23 | 2:51.35 | -0.88s, -0.51% | | | GHC HEAD | This patch | Diff | |-----|-----------------|-----------------|----------------------------| | -O0 | 54,843,608,416 | 54,878,769,544 | +35,161,128 bytes, +0.06% | | -O1 | 227,136,076,400 | 227,569,045,168 | +432,968,768 bytes, +0.19% | | -O2 | 266,147,063,296 | 266,749,643,440 | +602,580,144 bytes, +0.22% | 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 | 410,284,000 (910 samples) | 411,745,008 (906 samples) | +1,461,008 bytes, +0.35% | | -O1 | 928,580,856 (2109 samples) | 943,506,552 (2103 samples) | +14,925,696 bytes, +1.60% | | -O2 | 993,951,352 (2549 samples) | 1,010,156,328 (2545 samples) | +16,204,9760 bytes, +1.63% | 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 T9233 Co-authored-by: Andreas Klebinger <klebinger.andreas at gmx.at> - - - - - 30 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/Parser.y - 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 - docs/core-spec/CoreLint.ott - docs/core-spec/CoreSyn.ott - docs/core-spec/README - docs/core-spec/core-spec.mng - docs/core-spec/core-spec.pdf - docs/users_guide/runtime_control.rst - includes/rts/EventLogWriter.h - rts/eventlog/EventLogWriter.c - 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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2276d4d7c1c589b6f1ac49a72c37e5c58e4d72c9...3c27d98668499198cee5e0a57c15273068b2471e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/2276d4d7c1c589b6f1ac49a72c37e5c58e4d72c9...3c27d98668499198cee5e0a57c15273068b2471e You're receiving 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 27 10:38:39 2020 From: gitlab at gitlab.haskell.org (Matthew Pickering) Date: Wed, 27 May 2020 06:38:39 -0400 Subject: [Git][ghc/ghc][wip/proposal-195] Use a newtype `Code` for the return type of typed quotations (Proposal #195) Message-ID: <5ece432f1b947_6e2612c6bd781843732@gitlab.haskell.org.mail> Matthew Pickering pushed to branch wip/proposal-195 at Glasgow Haskell Compiler / GHC Commits: 87d883e1 by Matthew Pickering at 2020-05-27T11:38:19+01:00 Use a newtype `Code` for the return type of typed quotations (Proposal #195) There are three problems with the current API: 1. It is hard to properly write instances for ``Quote m => m (TExp a)`` as the type is the composition of two type constructors. Doing so in your program involves making your own newtype and doing a lot of wrapping/unwrapping. For example, if I want to create a language which I can either run immediately or generate code from I could write the following with the new API. :: class Lang r where _int :: Int -> r Int _if :: r Bool -> r a -> r a -> r a instance Lang Identity where _int = Identity _if (Identity b) (Identity t) (Identity f) = Identity (if b then t else f) instance Quote m => Lang (Code m) where _int = liftTyped _if cb ct cf = [|| if $$cb then $$ct else $$cf ||] 2. When doing code generation it is common to want to store code fragments in a map. When doing typed code generation, these code fragments contain a type index so it is desirable to store them in one of the parameterised map data types such as ``DMap`` from ``dependent-map`` or ``MapF`` from ``parameterized-utils``. :: compiler :: Env -> AST a -> Code Q a data AST a where ... data Ident a = ... type Env = MapF Ident (Code Q) newtype Code m a = Code (m (TExp a)) In this example, the ``MapF`` maps an ``Ident String`` directly to a ``Code Q String``. Using one of these map types currently requires creating your own newtype and constantly wrapping every quotation and unwrapping it when using a splice. Achievable, but it creates even more syntactic noise than normal metaprogramming. 3. ``m (TExp a)`` is ugly to read and write, understanding ``Code m a`` is easier. This is a weak reason but one everyone can surely agree with. - - - - - 27 changed files: - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Gen/Splice.hs - docs/users_guide/exts/deriving_extra.rst - docs/users_guide/exts/template_haskell.rst - libraries/template-haskell/Language/Haskell/TH.hs - + libraries/template-haskell/Language/Haskell/TH/CodeDo.hs - libraries/template-haskell/Language/Haskell/TH/Lib.hs - libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/changelog.md - libraries/template-haskell/template-haskell.cabal.in - libraries/text - testsuite/tests/quotes/T17857.hs - testsuite/tests/th/T10945.stderr - testsuite/tests/th/T15471A.hs - testsuite/tests/th/T15843.hs - testsuite/tests/th/T16195A.hs - testsuite/tests/th/T18121.hs - testsuite/tests/th/T8577.stderr - testsuite/tests/th/T8577a.hs - testsuite/tests/th/TH_StringLift.hs - testsuite/tests/th/TH_reifyLocalDefs.hs - testsuite/tests/th/overloaded/T17839.hs - testsuite/tests/th/overloaded/TH_overloaded_constraints.hs - testsuite/tests/th/overloaded/TH_overloaded_csp.hs - testsuite/tests/th/overloaded/TH_overloaded_extract.hs Changes: ===================================== compiler/GHC/Builtin/Names/TH.hs ===================================== @@ -31,9 +31,8 @@ templateHaskellNames = [ mkNameName, mkNameG_vName, mkNameG_dName, mkNameG_tcName, mkNameLName, mkNameSName, liftStringName, - unTypeName, - unTypeQName, - unsafeTExpCoerceName, + unTypeName, unTypeCodeName, + unsafeCodeCoerceName, -- Lit charLName, stringLName, integerLName, intPrimLName, wordPrimLName, @@ -134,8 +133,6 @@ templateHaskellNames = [ -- DerivStrategy stockStrategyName, anyclassStrategyName, newtypeStrategyName, viaStrategyName, - -- TExp - tExpDataConName, -- RuleBndr ruleVarName, typedRuleVarName, -- FunDep @@ -158,7 +155,7 @@ templateHaskellNames = [ typeTyConName, tyVarBndrUnitTyConName, tyVarBndrSpecTyConName, clauseTyConName, patQTyConName, funDepTyConName, decsQTyConName, ruleBndrTyConName, tySynEqnTyConName, - roleTyConName, tExpTyConName, injAnnTyConName, kindTyConName, + roleTyConName, codeTyConName, injAnnTyConName, kindTyConName, overlapTyConName, derivClauseTyConName, derivStrategyTyConName, -- Quasiquoting @@ -191,7 +188,7 @@ quoteClassName = thCls (fsLit "Quote") quoteClassKey qTyConName, nameTyConName, fieldExpTyConName, patTyConName, fieldPatTyConName, expTyConName, decTyConName, typeTyConName, matchTyConName, clauseTyConName, funDepTyConName, predTyConName, - tExpTyConName, injAnnTyConName, overlapTyConName, decsTyConName :: Name + codeTyConName, injAnnTyConName, overlapTyConName, decsTyConName :: Name qTyConName = thTc (fsLit "Q") qTyConKey nameTyConName = thTc (fsLit "Name") nameTyConKey fieldExpTyConName = thTc (fsLit "FieldExp") fieldExpTyConKey @@ -205,14 +202,14 @@ matchTyConName = thTc (fsLit "Match") matchTyConKey clauseTyConName = thTc (fsLit "Clause") clauseTyConKey funDepTyConName = thTc (fsLit "FunDep") funDepTyConKey predTyConName = thTc (fsLit "Pred") predTyConKey -tExpTyConName = thTc (fsLit "TExp") tExpTyConKey +codeTyConName = thTc (fsLit "Code") codeTyConKey injAnnTyConName = thTc (fsLit "InjectivityAnn") injAnnTyConKey overlapTyConName = thTc (fsLit "Overlap") overlapTyConKey returnQName, bindQName, sequenceQName, newNameName, liftName, mkNameName, mkNameG_vName, mkNameG_dName, mkNameG_tcName, - mkNameLName, mkNameSName, liftStringName, unTypeName, unTypeQName, - unsafeTExpCoerceName, liftTypedName :: Name + mkNameLName, mkNameSName, liftStringName, unTypeName, unTypeCodeName, + unsafeCodeCoerceName, liftTypedName :: Name returnQName = thFun (fsLit "returnQ") returnQIdKey bindQName = thFun (fsLit "bindQ") bindQIdKey sequenceQName = thFun (fsLit "sequenceQ") sequenceQIdKey @@ -226,8 +223,8 @@ mkNameG_tcName = thFun (fsLit "mkNameG_tc") mkNameG_tcIdKey mkNameLName = thFun (fsLit "mkNameL") mkNameLIdKey mkNameSName = thFun (fsLit "mkNameS") mkNameSIdKey unTypeName = thFun (fsLit "unType") unTypeIdKey -unTypeQName = thFun (fsLit "unTypeQ") unTypeQIdKey -unsafeTExpCoerceName = thFun (fsLit "unsafeTExpCoerce") unsafeTExpCoerceIdKey +unTypeCodeName = thFun (fsLit "unTypeCode") unTypeCodeIdKey +unsafeCodeCoerceName = thFun (fsLit "unsafeCodeCoerce") unsafeCodeCoerceIdKey liftTypedName = thFun (fsLit "liftTyped") liftTypedIdKey @@ -519,10 +516,6 @@ unsafeName = libFun (fsLit "unsafe") unsafeIdKey safeName = libFun (fsLit "safe") safeIdKey interruptibleName = libFun (fsLit "interruptible") interruptibleIdKey --- newtype TExp a = ... -tExpDataConName :: Name -tExpDataConName = thCon (fsLit "TExp") tExpDataConKey - -- data RuleBndr = ... ruleVarName, typedRuleVarName :: Name ruleVarName = libFun (fsLit ("ruleVar")) ruleVarIdKey @@ -647,7 +640,7 @@ expTyConKey, matchTyConKey, clauseTyConKey, qTyConKey, expQTyConKey, fieldExpTyConKey, fieldPatTyConKey, nameTyConKey, patQTyConKey, funDepTyConKey, predTyConKey, predQTyConKey, decsQTyConKey, ruleBndrTyConKey, tySynEqnTyConKey, - roleTyConKey, tExpTyConKey, injAnnTyConKey, kindTyConKey, + roleTyConKey, tExpTyConKey, codeTyConKey, injAnnTyConKey, kindTyConKey, overlapTyConKey, derivClauseTyConKey, derivStrategyTyConKey, decsTyConKey :: Unique expTyConKey = mkPreludeTyConUnique 200 @@ -671,7 +664,6 @@ funDepTyConKey = mkPreludeTyConUnique 222 predTyConKey = mkPreludeTyConUnique 223 predQTyConKey = mkPreludeTyConUnique 224 tyVarBndrUnitTyConKey = mkPreludeTyConUnique 225 -tyVarBndrSpecTyConKey = mkPreludeTyConUnique 237 decsQTyConKey = mkPreludeTyConUnique 226 ruleBndrTyConKey = mkPreludeTyConUnique 227 tySynEqnTyConKey = mkPreludeTyConUnique 228 @@ -683,6 +675,8 @@ overlapTyConKey = mkPreludeTyConUnique 233 derivClauseTyConKey = mkPreludeTyConUnique 234 derivStrategyTyConKey = mkPreludeTyConUnique 235 decsTyConKey = mkPreludeTyConUnique 236 +tyVarBndrSpecTyConKey = mkPreludeTyConUnique 237 +codeTyConKey = mkPreludeTyConUnique 238 {- ********************************************************************* * * @@ -710,10 +704,6 @@ allPhasesDataConKey = mkPreludeDataConUnique 205 fromPhaseDataConKey = mkPreludeDataConUnique 206 beforePhaseDataConKey = mkPreludeDataConUnique 207 --- newtype TExp a = ... -tExpDataConKey :: Unique -tExpDataConKey = mkPreludeDataConUnique 208 - -- data Overlap = .. overlappableDataConKey, overlappingDataConKey, @@ -735,8 +725,8 @@ incoherentDataConKey = mkPreludeDataConUnique 212 returnQIdKey, bindQIdKey, sequenceQIdKey, liftIdKey, newNameIdKey, mkNameIdKey, mkNameG_vIdKey, mkNameG_dIdKey, mkNameG_tcIdKey, - mkNameLIdKey, mkNameSIdKey, unTypeIdKey, unTypeQIdKey, - unsafeTExpCoerceIdKey, liftTypedIdKey :: Unique + mkNameLIdKey, mkNameSIdKey, unTypeIdKey, unTypeCodeIdKey, + liftTypedIdKey, unsafeCodeCoerceIdKey :: Unique returnQIdKey = mkPreludeMiscIdUnique 200 bindQIdKey = mkPreludeMiscIdUnique 201 sequenceQIdKey = mkPreludeMiscIdUnique 202 @@ -749,9 +739,9 @@ mkNameG_tcIdKey = mkPreludeMiscIdUnique 208 mkNameLIdKey = mkPreludeMiscIdUnique 209 mkNameSIdKey = mkPreludeMiscIdUnique 210 unTypeIdKey = mkPreludeMiscIdUnique 211 -unTypeQIdKey = mkPreludeMiscIdUnique 212 -unsafeTExpCoerceIdKey = mkPreludeMiscIdUnique 213 +unTypeCodeIdKey = mkPreludeMiscIdUnique 212 liftTypedIdKey = mkPreludeMiscIdUnique 214 +unsafeCodeCoerceIdKey = mkPreludeMiscIdUnique 215 -- data Lit = ... @@ -1093,9 +1083,10 @@ inferredSpecKey = mkPreludeMiscIdUnique 499 ************************************************************************ -} -lift_RDR, liftTyped_RDR, mkNameG_dRDR, mkNameG_vRDR :: RdrName +lift_RDR, liftTyped_RDR, mkNameG_dRDR, mkNameG_vRDR, unsafeCodeCoerce_RDR :: RdrName lift_RDR = nameRdrName liftName liftTyped_RDR = nameRdrName liftTypedName +unsafeCodeCoerce_RDR = nameRdrName unsafeCodeCoerceName mkNameG_dRDR = nameRdrName mkNameG_dName mkNameG_vRDR = nameRdrName mkNameG_vName ===================================== compiler/GHC/Tc/Deriv/Generate.hs ===================================== @@ -1576,7 +1576,7 @@ gen_Lift_binds loc tycon = (listToBag [lift_bind, liftTyped_bind], emptyBag) where lift_bind = mkFunBindEC 1 loc lift_RDR (nlHsApp pure_Expr) (map (pats_etc mk_exp) data_cons) - liftTyped_bind = mkFunBindEC 1 loc liftTyped_RDR (nlHsApp pure_Expr) + liftTyped_bind = mkFunBindEC 1 loc liftTyped_RDR (nlHsApp unsafeCodeCoerce_Expr . nlHsApp pure_Expr) (map (pats_etc mk_texp) data_cons) mk_exp = ExpBr noExtField @@ -2352,17 +2352,18 @@ bs_RDRs = [ mkVarUnqual (mkFastString ("b"++show i)) | i <- [(1::Int) .. cs_RDRs = [ mkVarUnqual (mkFastString ("c"++show i)) | i <- [(1::Int) .. ] ] a_Expr, b_Expr, c_Expr, z_Expr, ltTag_Expr, eqTag_Expr, gtTag_Expr, false_Expr, - true_Expr, pure_Expr :: LHsExpr GhcPs -a_Expr = nlHsVar a_RDR -b_Expr = nlHsVar b_RDR -c_Expr = nlHsVar c_RDR -z_Expr = nlHsVar z_RDR -ltTag_Expr = nlHsVar ltTag_RDR -eqTag_Expr = nlHsVar eqTag_RDR -gtTag_Expr = nlHsVar gtTag_RDR -false_Expr = nlHsVar false_RDR -true_Expr = nlHsVar true_RDR -pure_Expr = nlHsVar pure_RDR + true_Expr, pure_Expr, unsafeCodeCoerce_Expr :: LHsExpr GhcPs +a_Expr = nlHsVar a_RDR +b_Expr = nlHsVar b_RDR +c_Expr = nlHsVar c_RDR +z_Expr = nlHsVar z_RDR +ltTag_Expr = nlHsVar ltTag_RDR +eqTag_Expr = nlHsVar eqTag_RDR +gtTag_Expr = nlHsVar gtTag_RDR +false_Expr = nlHsVar false_RDR +true_Expr = nlHsVar true_RDR +pure_Expr = nlHsVar pure_RDR +unsafeCodeCoerce_Expr = nlHsVar unsafeCodeCoerce_RDR a_Pat, b_Pat, c_Pat, d_Pat, k_Pat, z_Pat :: LPat GhcPs a_Pat = nlVarPat a_RDR ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -196,7 +196,7 @@ tcTypedBracket rn_expr brack@(TExpBr _ expr) res_ty ; let rep = getRuntimeRep expr_ty ; meta_ty <- tcTExpTy m_var expr_ty ; ps' <- readMutVar ps_ref - ; texpco <- tcLookupId unsafeTExpCoerceName + ; texpco <- tcLookupId unsafeCodeCoerceName ; tcWrapResultO (Shouldn'tHappenOrigin "TExpBr") rn_expr (unLoc (mkHsApp (mkLHsWrap (applyQuoteWrapper wrapper) @@ -302,9 +302,9 @@ tcPendingSplice m_var (PendingRnSplice flavour splice_name expr) tcTExpTy :: TcType -> TcType -> TcM TcType tcTExpTy m_ty exp_ty = do { unless (isTauTy exp_ty) $ addErr (err_msg exp_ty) - ; texp <- tcLookupTyCon tExpTyConName + ; codeCon <- tcLookupTyCon codeTyConName ; let rep = getRuntimeRep exp_ty - ; return (mkAppTy m_ty (mkTyConApp texp [rep, exp_ty])) } + ; return (mkTyConApp codeCon [rep, m_ty, exp_ty]) } where err_msg ty = vcat [ text "Illegal polytype:" <+> ppr ty @@ -619,10 +619,10 @@ tcNestedSplice pop_stage (TcPending ps_var lie_var q@(QuoteWrapper _ m_var)) spl ; expr' <- setStage pop_stage $ setConstraintVar lie_var $ tcLExpr expr (mkCheckExpType meta_exp_ty) - ; untypeq <- tcLookupId unTypeQName + ; untypeCode <- tcLookupId unTypeCodeName ; let expr'' = mkHsApp (mkLHsWrap (applyQuoteWrapper q) - (nlHsTyApp untypeq [rep, res_ty])) expr' + (nlHsTyApp untypeCode [rep, res_ty])) expr' ; ps <- readMutVar ps_var ; writeMutVar ps_var (PendingTcSplice splice_name expr'' : ps) ===================================== docs/users_guide/exts/deriving_extra.rst ===================================== @@ -528,7 +528,7 @@ Deriving ``Lift`` instances The class ``Lift``, unlike other derivable classes, lives in ``template-haskell`` instead of ``base``. Having a data type be an instance of ``Lift`` permits its values to be promoted to Template Haskell expressions (of -type ``ExpQ`` and ``TExpQ a``), which can then be spliced into Haskell source +type ``ExpQ`` and ``Code Q a``), which can then be spliced into Haskell source code. Here is an example of how one can derive ``Lift``: ===================================== docs/users_guide/exts/template_haskell.rst ===================================== @@ -133,15 +133,15 @@ The :extension:`TemplateHaskellQuotes` extension is considered safe under is an arbitrary expression. A top-level typed expression splice can occur in place of an expression; the - spliced expression must have type ``Q (TExp a)`` + spliced expression must have type ``Code Q a`` - A *typed* expression quotation is written as ``[|| ... ||]``, or ``[e|| ... ||]``, where the "..." is an expression; if the "..." expression has type ``a``, then the quotation has type - ``Quote m => m (TExp a)``. + ``Quote m => Code m a``. - Values of type ``TExp a`` may be converted to values of type ``Exp`` - using the function ``unType :: TExp a -> Exp``. + It is possible to extract a value of type ``m Exp`` from ``Code m a`` + using the ``unTypeCode :: Code m a -> m Exp`` function. - A quasi-quotation can appear in a pattern, type, expression, or declaration context and is also written in Oxford brackets: @@ -202,7 +202,7 @@ The :extension:`TemplateHaskellQuotes` extension is considered safe under class Lift t where lift :: Quote m => t -> m Exp - liftTyped :: Quote m => t -> m (TExp t) + liftTyped :: Quote m => t -> Code m t In general, if GHC sees an expression within Oxford brackets (e.g., ``[| foo bar |]``, then GHC looks up each name within the brackets. If a name ===================================== libraries/template-haskell/Language/Haskell/TH.hs ===================================== @@ -50,6 +50,7 @@ module Language.Haskell.TH( -- * Typed expressions TExp, unType, + Code(..), unTypeCode, unsafeCodeCoerce, hoistCode, -- * Names Name, NameSpace, -- Abstract ===================================== libraries/template-haskell/Language/Haskell/TH/CodeDo.hs ===================================== @@ -0,0 +1,20 @@ +-- | This module exists to work nicely with the QualifiedDo +-- extension. +-- @ +-- import qualified Language.Haskell.TH.CodeDo as Code +-- myExample :: Monad m => Code m a -> Code m a -> Code m a +-- myExample opt1 opt2 = +-- Code.do +-- x <- someSideEffect -- This one is of type `M Bool` +-- if x then opt1 else opt2 +-- @ +module Language.Haskell.TH.CodeDo((>>=), (>>)) where + +import Language.Haskell.TH.Syntax +import Prelude(Monad) + +-- | Module over monad operator for 'Code' +(>>=) :: Monad m => m a -> (a -> Code m b) -> Code m b +(>>=) = bindCode +(>>) :: Monad m => m a -> Code m b -> Code m b +(>>) = bindCode_ \ No newline at end of file ===================================== libraries/template-haskell/Language/Haskell/TH/Lib.hs ===================================== @@ -18,7 +18,7 @@ module Language.Haskell.TH.Lib ( -- * Library functions -- ** Abbreviations - InfoQ, ExpQ, TExpQ, DecQ, DecsQ, ConQ, TypeQ, KindQ, + InfoQ, ExpQ, TExpQ, CodeQ, DecQ, DecsQ, ConQ, TypeQ, KindQ, TyLitQ, CxtQ, PredQ, DerivClauseQ, MatchQ, ClauseQ, BodyQ, GuardQ, StmtQ, RangeQ, SourceStrictnessQ, SourceUnpackednessQ, BangQ, BangTypeQ, VarBangTypeQ, StrictTypeQ, VarStrictTypeQ, FieldExpQ, PatQ, ===================================== libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs ===================================== @@ -31,6 +31,7 @@ type PatQ = Q Pat type FieldPatQ = Q FieldPat type ExpQ = Q Exp type TExpQ a = Q (TExp a) +type CodeQ = Code Q type DecQ = Q Dec type DecsQ = Q [Dec] type Decs = [Dec] -- Defined as it is more convenient to wire-in ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -343,6 +343,63 @@ be inferred (#8459). Consider The splice will evaluate to (MkAge 3) and you can't add that to 4::Int. So you can't coerce a (TExp Age) to a (TExp Int). -} +-- Code constructor + +type role Code representational nominal -- See Note [Role of TExp] +newtype Code m (a :: TYPE (r :: RuntimeRep)) = Code + { examineCode :: m (TExp a) -- ^ Underlying monadic value + } + +-- | Unsafely convert an untyped code representation into a typed code +-- representation. +unsafeCodeCoerce :: forall (r :: RuntimeRep) (a :: TYPE r) m . + Quote m => m Exp -> Code m a +unsafeCodeCoerce m = Code (unsafeTExpCoerce m) + +-- | Lift a monadic action producing code into the typed 'Code' +-- representation +liftCode :: forall (r :: RuntimeRep) (a :: TYPE r) m . m (TExp a) -> Code m a +liftCode = Code + +-- | Extract the untyped representation from the typed representation +unTypeCode :: forall (r :: RuntimeRep) (a :: TYPE r) m . Quote m + => Code m a -> m Exp +unTypeCode = unTypeQ . examineCode + +-- | Modify the ambient monad used during code generation. For example, you +-- can use `hoistCode` to handle a state effect: +-- @ +-- handleState :: Code (StateT Int Q) a -> Code Q a +-- handleState = hoistCode (flip runState 0) +-- @ +hoistCode :: forall m n (r :: RuntimeRep) (a :: TYPE r) . Monad m + => (forall x . m x -> n x) -> Code m a -> Code n a +hoistCode f (Code a) = Code (f a) + + +-- | Variant of (>>=) which allows effectful computations to be injected +-- into code generation. +bindCode :: forall m a (r :: RuntimeRep) (b :: TYPE r) . Monad m + => m a -> (a -> Code m b) -> Code m b +bindCode q k = liftCode (q >>= examineCode . k) + +-- | Variant of (>>) which allows effectful computations to be injected +-- into code generation. +bindCode_ :: forall m a (r :: RuntimeRep) (b :: TYPE r) . Monad m + => m a -> Code m b -> Code m b +bindCode_ q c = liftCode ( q >> examineCode c) + +-- | A useful combinator for embedding monadic actions into 'Code' +-- @ +-- myCode :: ... => Code m a +-- myCode = joinCode $ do +-- x <- someSideEffect +-- return (makeCodeWith x) +-- @ +joinCode :: forall m (r :: RuntimeRep) (a :: TYPE r) . Monad m + => m (Code m a) -> Code m a +joinCode = flip bindCode id + ---------------------------------------------------- -- Packaged versions for the programmer, hiding the Quasi-ness @@ -727,107 +784,107 @@ class Lift (t :: TYPE r) where -- a splice. lift :: Quote m => t -> m Exp default lift :: (r ~ 'LiftedRep, Quote m) => t -> m Exp - lift = unTypeQ . liftTyped + lift = unTypeCode . liftTyped -- | Turn a value into a Template Haskell typed expression, suitable for use -- in a typed splice. -- -- @since 2.16.0.0 - liftTyped :: Quote m => t -> m (TExp t) + liftTyped :: Quote m => t -> Code m t -- If you add any instances here, consider updating test th/TH_Lift instance Lift Integer where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL x)) instance Lift Int where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) -- | @since 2.16.0.0 instance Lift Int# where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntPrimL (fromIntegral (I# x)))) instance Lift Int8 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Int16 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Int32 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Int64 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) -- | @since 2.16.0.0 instance Lift Word# where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (WordPrimL (fromIntegral (W# x)))) instance Lift Word where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Word8 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Word16 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Word32 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Word64 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Natural where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Integral a => Lift (Ratio a) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (RationalL (toRational x))) instance Lift Float where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (RationalL (toRational x))) -- | @since 2.16.0.0 instance Lift Float# where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (FloatPrimL (toRational (F# x)))) instance Lift Double where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (RationalL (toRational x))) -- | @since 2.16.0.0 instance Lift Double# where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (DoublePrimL (toRational (D# x)))) instance Lift Char where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (CharL x)) -- | @since 2.16.0.0 instance Lift Char# where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (CharPrimL (C# x))) instance Lift Bool where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift True = return (ConE trueName) lift False = return (ConE falseName) @@ -837,24 +894,24 @@ instance Lift Bool where -- -- @since 2.16.0.0 instance Lift Addr# where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (StringPrimL (map (fromIntegral . ord) (unpackCString# x)))) instance Lift a => Lift (Maybe a) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift Nothing = return (ConE nothingName) lift (Just x) = liftM (ConE justName `AppE`) (lift x) instance (Lift a, Lift b) => Lift (Either a b) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (Left x) = liftM (ConE leftName `AppE`) (lift x) lift (Right y) = liftM (ConE rightName `AppE`) (lift y) instance Lift a => Lift [a] where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift xs = do { xs' <- mapM lift xs; return (ListE xs') } liftString :: Quote m => String -> m Exp @@ -863,7 +920,7 @@ liftString s = return (LitE (StringL s)) -- | @since 2.15.0.0 instance Lift a => Lift (NonEmpty a) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (x :| xs) = do x' <- lift x @@ -872,77 +929,77 @@ instance Lift a => Lift (NonEmpty a) where -- | @since 2.15.0.0 instance Lift Void where - liftTyped = pure . absurd + liftTyped = liftCode . absurd lift = pure . absurd instance Lift () where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift () = return (ConE (tupleDataName 0)) instance (Lift a, Lift b) => Lift (a, b) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (a, b) = liftM TupE $ sequence $ map (fmap Just) [lift a, lift b] instance (Lift a, Lift b, Lift c) => Lift (a, b, c) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (a, b, c) = liftM TupE $ sequence $ map (fmap Just) [lift a, lift b, lift c] instance (Lift a, Lift b, Lift c, Lift d) => Lift (a, b, c, d) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (a, b, c, d) = liftM TupE $ sequence $ map (fmap Just) [lift a, lift b, lift c, lift d] instance (Lift a, Lift b, Lift c, Lift d, Lift e) => Lift (a, b, c, d, e) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (a, b, c, d, e) = liftM TupE $ sequence $ map (fmap Just) [ lift a, lift b , lift c, lift d, lift e ] instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f) => Lift (a, b, c, d, e, f) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (a, b, c, d, e, f) = liftM TupE $ sequence $ map (fmap Just) [ lift a, lift b, lift c , lift d, lift e, lift f ] instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f, Lift g) => Lift (a, b, c, d, e, f, g) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (a, b, c, d, e, f, g) = liftM TupE $ sequence $ map (fmap Just) [ lift a, lift b, lift c , lift d, lift e, lift f, lift g ] -- | @since 2.16.0.0 instance Lift (# #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# #) = return (ConE (unboxedTupleTypeName 0)) -- | @since 2.16.0.0 instance (Lift a) => Lift (# a #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# a #) = liftM UnboxedTupE $ sequence $ map (fmap Just) [lift a] -- | @since 2.16.0.0 instance (Lift a, Lift b) => Lift (# a, b #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# a, b #) = liftM UnboxedTupE $ sequence $ map (fmap Just) [lift a, lift b] -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c) => Lift (# a, b, c #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# a, b, c #) = liftM UnboxedTupE $ sequence $ map (fmap Just) [lift a, lift b, lift c] -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d) => Lift (# a, b, c, d #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# a, b, c, d #) = liftM UnboxedTupE $ sequence $ map (fmap Just) [ lift a, lift b , lift c, lift d ] @@ -950,7 +1007,7 @@ instance (Lift a, Lift b, Lift c, Lift d) -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d, Lift e) => Lift (# a, b, c, d, e #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# a, b, c, d, e #) = liftM UnboxedTupE $ sequence $ map (fmap Just) [ lift a, lift b , lift c, lift d, lift e ] @@ -958,7 +1015,7 @@ instance (Lift a, Lift b, Lift c, Lift d, Lift e) -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f) => Lift (# a, b, c, d, e, f #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# a, b, c, d, e, f #) = liftM UnboxedTupE $ sequence $ map (fmap Just) [ lift a, lift b, lift c , lift d, lift e, lift f ] @@ -966,7 +1023,7 @@ instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f) -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f, Lift g) => Lift (# a, b, c, d, e, f, g #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# a, b, c, d, e, f, g #) = liftM UnboxedTupE $ sequence $ map (fmap Just) [ lift a, lift b, lift c , lift d, lift e, lift f @@ -974,7 +1031,7 @@ instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f, Lift g) -- | @since 2.16.0.0 instance (Lift a, Lift b) => Lift (# a | b #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = case x of (# y | #) -> UnboxedSumE <$> lift y <*> pure 1 <*> pure 2 @@ -983,7 +1040,7 @@ instance (Lift a, Lift b) => Lift (# a | b #) where -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c) => Lift (# a | b | c #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = case x of (# y | | #) -> UnboxedSumE <$> lift y <*> pure 1 <*> pure 3 @@ -993,7 +1050,7 @@ instance (Lift a, Lift b, Lift c) -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d) => Lift (# a | b | c | d #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = case x of (# y | | | #) -> UnboxedSumE <$> lift y <*> pure 1 <*> pure 4 @@ -1004,7 +1061,7 @@ instance (Lift a, Lift b, Lift c, Lift d) -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d, Lift e) => Lift (# a | b | c | d | e #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = case x of (# y | | | | #) -> UnboxedSumE <$> lift y <*> pure 1 <*> pure 5 @@ -1016,7 +1073,7 @@ instance (Lift a, Lift b, Lift c, Lift d, Lift e) -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f) => Lift (# a | b | c | d | e | f #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = case x of (# y | | | | | #) -> UnboxedSumE <$> lift y <*> pure 1 <*> pure 6 @@ -1029,7 +1086,7 @@ instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f) -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f, Lift g) => Lift (# a | b | c | d | e | f | g #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = case x of (# y | | | | | | #) -> UnboxedSumE <$> lift y <*> pure 1 <*> pure 7 ===================================== libraries/template-haskell/changelog.md ===================================== @@ -1,6 +1,9 @@ # Changelog for [`template-haskell` package](http://hackage.haskell.org/package/template-haskell) ## 2.17.0.0 + * Typed Quotations now return a value of type `Code m a` (GHC Proposal #195). + The main motiviation is to make writing instances easier and make it easier to + store `Code` values in type-indexed maps. * Implement Overloaded Quotations (GHC Proposal #246). This patch modifies a few fundamental things in the API. All the library combinators are generalised @@ -9,7 +12,7 @@ written in terms of `Q` are now disallowed. The types of `unsafeTExpCoerce` and `unTypeQ` are also generalised in terms of `Quote` rather than specific to `Q`. - + * Implement Explicit specificity in type variable binders (GHC Proposal #99). In `Language.Haskell.TH.Syntax`, `TyVarBndr` is now annotated with a `flag`, denoting the additional argument to its constructors `PlainTV` and `KindedTV`. ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -48,7 +48,7 @@ Library Language.Haskell.TH.Quote Language.Haskell.TH.Syntax Language.Haskell.TH.LanguageExtensions - + Language.Haskell.TH.CodeDo Language.Haskell.TH.Lib.Internal other-modules: ===================================== libraries/text ===================================== @@ -1 +1 @@ -Subproject commit a01843250166b5559936ba5eb81f7873e709587a +Subproject commit 74f835751b60b312d01dd600d516756d5325d514 ===================================== testsuite/tests/quotes/T17857.hs ===================================== @@ -7,4 +7,4 @@ import Language.Haskell.TH.Syntax data T = MkT deriving Data instance Lift T where lift = liftData - liftTyped = unsafeTExpCoerce . lift + liftTyped = unsafeCodeCoerce . lift ===================================== testsuite/tests/th/T10945.stderr ===================================== @@ -1,8 +1,8 @@ T10945.hs:7:4: error: - • Couldn't match type ‘[Dec]’ with ‘TExp DecsQ’ - Expected type: Q (TExp DecsQ) - Actual type: Q [Dec] + • Couldn't match type ‘[Dec]’ with ‘Q [Dec]’ + Expected type: Code Q DecsQ + Actual type: Code Q [Dec] • In the expression: return [SigD ===================================== testsuite/tests/th/T15471A.hs ===================================== @@ -6,9 +6,9 @@ import Language.Haskell.TH foo1 x = x -test_foo :: Q (TExp (a -> a)) +test_foo :: Code Q (a -> a) test_foo = [|| foo1 ||] -list_foo :: Q (TExp a) -> Q (TExp [a]) +list_foo :: Code Q a -> Code Q [a] list_foo x = [|| [ $$x, $$x ] ||] ===================================== testsuite/tests/th/T15843.hs ===================================== @@ -13,12 +13,12 @@ main = do mapM_ (\q -> runQ q >>= ppr_and_show) [first_of_2, second_of_2, empty_2, full_2, third_of_3] - mapM_ (\q -> runQ (fmap unType q) >>= ppr_and_show) + mapM_ (\q -> (runQ (unTypeCode q)) >>= ppr_and_show) [first_of_2_T, second_of_2_T] - runQ (fmap unType empty_2_T) >>= ppr_and_show - runQ (fmap unType full_2_T) >>= ppr_and_show - runQ (fmap unType third_of_3_T) >>= ppr_and_show + runQ (unTypeCode empty_2_T) >>= ppr_and_show + runQ (unTypeCode full_2_T) >>= ppr_and_show + runQ (unTypeCode third_of_3_T) >>= ppr_and_show print $ "(909,) applied to 'c' should be (909, 'c') ===> " ++ (show $ (909, 'c') == ($first_of_2 'c')) ===================================== testsuite/tests/th/T16195A.hs ===================================== @@ -3,11 +3,11 @@ module T16195A where import Language.Haskell.TH -foo :: Q (TExp (IO ())) +foo :: Code Q (IO ()) foo = [|| return () ||] -showC :: Q (TExp (() -> String)) +showC :: Code Q (() -> String) showC = [|| show ||] -unitC :: Q (TExp ()) +unitC :: Code Q () unitC = [|| () ||] ===================================== testsuite/tests/th/T18121.hs ===================================== @@ -3,5 +3,5 @@ module Bug where import Language.Haskell.TH -sapply :: Q (TExp (a -> b)) -> Q (TExp a) -> Q (TExp b) +sapply :: Quote m => Code m (a -> b) -> Code m a -> Code m b sapply cf cx = [|| $$cf $$cx ||] ===================================== testsuite/tests/th/T8577.stderr ===================================== @@ -1,8 +1,8 @@ T8577.hs:9:11: error: • Couldn't match type ‘Int’ with ‘Bool’ - Expected type: Q (TExp (A Bool)) - Actual type: Q (TExp (A Int)) + Expected type: Code Q (A Bool) + Actual type: Code Q (A Int) • In the expression: y In the Template Haskell splice $$(y) In the expression: $$(y) ===================================== testsuite/tests/th/T8577a.hs ===================================== @@ -4,8 +4,8 @@ import Language.Haskell.TH data A a = A -x :: Q (TExp (A a)) +x :: Code Q (A a) x = [|| A ||] -y :: Q (TExp (A Int)) +y :: Code Q (A Int) y = x ===================================== testsuite/tests/th/TH_StringLift.hs ===================================== @@ -3,7 +3,7 @@ module TH_StringLift where import Language.Haskell.TH.Syntax -foo :: Quote m => String -> m (TExp String) +foo :: Quote m => String -> Code m String foo x = [|| x ||] foo2 :: Quote m => String -> m Exp ===================================== testsuite/tests/th/TH_reifyLocalDefs.hs ===================================== @@ -29,8 +29,8 @@ main = print (f 1 "", g 'a' 2, h True 3) ) , xg :: Char ) - h xh y = ( $$(do printTypeOf("xh") - [|| y :: Int ||] + h xh y = ( $$(liftCode $ do printTypeOf("xh") + examineCode [|| y :: Int ||] ) , xh :: Bool ) ===================================== testsuite/tests/th/overloaded/T17839.hs ===================================== @@ -16,7 +16,7 @@ import Data.Functor.Identity type LetT m a = WriterT [Locus] m a -type Code m a = m (TExp a) +type MCode m a = m (TExp a) type LetCode m a = LetT m (TExp a) @@ -29,7 +29,7 @@ instance (Monoid w, Quote m) => Quote (StateT w m) where newName x = W.lift (newName x) -locus :: (Locus -> LetCode m a) -> Code m a +locus :: (Locus -> LetCode m a) -> MCode m a locus = undefined newTypedName :: Quote m => m (TExp a) @@ -38,15 +38,15 @@ newTypedName = do return (TExp (VarE n)) -gen :: Quote m => Locus -> (Code Identity (a -> b) -> LetCode m a -> LetCode m b) -> LetCode m (a -> b) +gen :: Quote m => Locus -> (MCode Identity (a -> b) -> LetCode m a -> LetCode m b) -> LetCode m (a -> b) gen l f = do n <- newTypedName - [|| \a -> $$(f (Identity n) [|| a ||]) ||] + examineCode [|| \a -> $$(liftCode $ f (Identity n) (examineCode [|| a ||])) ||] mrfix :: forall a b m r . (Monad m, Ord a, Quote m) - => (forall m . (a -> Code m (b -> r)) -> (a -> Code m b -> Code m r)) - -> (a -> Code m (b -> r)) + => (forall m . (a -> MCode m (b -> r)) -> (a -> MCode m b -> MCode m r)) + -> (a -> MCode m (b -> r)) mrfix f x = flip evalStateT Map.empty $ locus $ \locus -> do ===================================== testsuite/tests/th/overloaded/TH_overloaded_constraints.hs ===================================== @@ -22,11 +22,11 @@ dq = [| 5 |] top_level :: (C m, D m, Quote m) => m Exp top_level = [| $cq + $dq |] -cqt :: (C m, Quote m) => m (TExp Int) +cqt :: (C m, Quote m) => Code m Int cqt = [|| 5 ||] -dqt :: (D m, Quote m) => m (TExp Int) +dqt :: (D m, Quote m) => Code m Int dqt = [|| 5 ||] -top_level_t :: (C m, D m, Quote m) => m (TExp Int) +top_level_t :: (C m, D m, Quote m) => Code m Int top_level_t = [|| $$cqt + $$dqt ||] ===================================== testsuite/tests/th/overloaded/TH_overloaded_csp.hs ===================================== @@ -14,5 +14,5 @@ instance Quote Identity where main = do print $ runIdentity ((\x -> [| x |]) ()) - print $ unType $ runIdentity ((\x -> [|| x ||]) ()) + print $ runIdentity $ unTypeCode ((\x -> [|| x ||]) ()) ===================================== testsuite/tests/th/overloaded/TH_overloaded_extract.hs ===================================== @@ -19,5 +19,5 @@ main = do print $ runIdentity [d| data Foo = Foo |] print $ runIdentity [p| () |] print $ runIdentity [t| [Int] |] - print $ unType $ runIdentity [|| (+1) ||] + print $ runIdentity $ unTypeCode [|| (+1) ||] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/87d883e185cd247d36db7fc348adfc76bd576dac -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/87d883e185cd247d36db7fc348adfc76bd576dac You're receiving 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 27 10:41:14 2020 From: gitlab at gitlab.haskell.org (Matthew Pickering) Date: Wed, 27 May 2020 06:41:14 -0400 Subject: [Git][ghc/ghc][wip/proposal-195] Use a newtype `Code` for the return type of typed quotations (Proposal #195) Message-ID: <5ece43cad56_6e263f9ed476cd9018473a1@gitlab.haskell.org.mail> Matthew Pickering pushed to branch wip/proposal-195 at Glasgow Haskell Compiler / GHC Commits: 227e82c4 by Matthew Pickering at 2020-05-27T11:40:53+01:00 Use a newtype `Code` for the return type of typed quotations (Proposal #195) There are three problems with the current API: 1. It is hard to properly write instances for ``Quote m => m (TExp a)`` as the type is the composition of two type constructors. Doing so in your program involves making your own newtype and doing a lot of wrapping/unwrapping. For example, if I want to create a language which I can either run immediately or generate code from I could write the following with the new API. :: class Lang r where _int :: Int -> r Int _if :: r Bool -> r a -> r a -> r a instance Lang Identity where _int = Identity _if (Identity b) (Identity t) (Identity f) = Identity (if b then t else f) instance Quote m => Lang (Code m) where _int = liftTyped _if cb ct cf = [|| if $$cb then $$ct else $$cf ||] 2. When doing code generation it is common to want to store code fragments in a map. When doing typed code generation, these code fragments contain a type index so it is desirable to store them in one of the parameterised map data types such as ``DMap`` from ``dependent-map`` or ``MapF`` from ``parameterized-utils``. :: compiler :: Env -> AST a -> Code Q a data AST a where ... data Ident a = ... type Env = MapF Ident (Code Q) newtype Code m a = Code (m (TExp a)) In this example, the ``MapF`` maps an ``Ident String`` directly to a ``Code Q String``. Using one of these map types currently requires creating your own newtype and constantly wrapping every quotation and unwrapping it when using a splice. Achievable, but it creates even more syntactic noise than normal metaprogramming. 3. ``m (TExp a)`` is ugly to read and write, understanding ``Code m a`` is easier. This is a weak reason but one everyone can surely agree with. - - - - - 27 changed files: - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Gen/Splice.hs - docs/users_guide/exts/deriving_extra.rst - docs/users_guide/exts/template_haskell.rst - libraries/template-haskell/Language/Haskell/TH.hs - + libraries/template-haskell/Language/Haskell/TH/CodeDo.hs - libraries/template-haskell/Language/Haskell/TH/Lib.hs - libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/changelog.md - libraries/template-haskell/template-haskell.cabal.in - libraries/text - testsuite/tests/quotes/T17857.hs - testsuite/tests/th/T10945.stderr - testsuite/tests/th/T15471A.hs - testsuite/tests/th/T15843.hs - testsuite/tests/th/T16195A.hs - testsuite/tests/th/T18121.hs - testsuite/tests/th/T8577.stderr - testsuite/tests/th/T8577a.hs - testsuite/tests/th/TH_StringLift.hs - testsuite/tests/th/TH_reifyLocalDefs.hs - testsuite/tests/th/overloaded/T17839.hs - testsuite/tests/th/overloaded/TH_overloaded_constraints.hs - testsuite/tests/th/overloaded/TH_overloaded_csp.hs - testsuite/tests/th/overloaded/TH_overloaded_extract.hs Changes: ===================================== compiler/GHC/Builtin/Names/TH.hs ===================================== @@ -31,9 +31,8 @@ templateHaskellNames = [ mkNameName, mkNameG_vName, mkNameG_dName, mkNameG_tcName, mkNameLName, mkNameSName, liftStringName, - unTypeName, - unTypeQName, - unsafeTExpCoerceName, + unTypeName, unTypeCodeName, + unsafeCodeCoerceName, -- Lit charLName, stringLName, integerLName, intPrimLName, wordPrimLName, @@ -134,8 +133,6 @@ templateHaskellNames = [ -- DerivStrategy stockStrategyName, anyclassStrategyName, newtypeStrategyName, viaStrategyName, - -- TExp - tExpDataConName, -- RuleBndr ruleVarName, typedRuleVarName, -- FunDep @@ -158,7 +155,7 @@ templateHaskellNames = [ typeTyConName, tyVarBndrUnitTyConName, tyVarBndrSpecTyConName, clauseTyConName, patQTyConName, funDepTyConName, decsQTyConName, ruleBndrTyConName, tySynEqnTyConName, - roleTyConName, tExpTyConName, injAnnTyConName, kindTyConName, + roleTyConName, codeTyConName, injAnnTyConName, kindTyConName, overlapTyConName, derivClauseTyConName, derivStrategyTyConName, -- Quasiquoting @@ -191,7 +188,7 @@ quoteClassName = thCls (fsLit "Quote") quoteClassKey qTyConName, nameTyConName, fieldExpTyConName, patTyConName, fieldPatTyConName, expTyConName, decTyConName, typeTyConName, matchTyConName, clauseTyConName, funDepTyConName, predTyConName, - tExpTyConName, injAnnTyConName, overlapTyConName, decsTyConName :: Name + codeTyConName, injAnnTyConName, overlapTyConName, decsTyConName :: Name qTyConName = thTc (fsLit "Q") qTyConKey nameTyConName = thTc (fsLit "Name") nameTyConKey fieldExpTyConName = thTc (fsLit "FieldExp") fieldExpTyConKey @@ -205,14 +202,14 @@ matchTyConName = thTc (fsLit "Match") matchTyConKey clauseTyConName = thTc (fsLit "Clause") clauseTyConKey funDepTyConName = thTc (fsLit "FunDep") funDepTyConKey predTyConName = thTc (fsLit "Pred") predTyConKey -tExpTyConName = thTc (fsLit "TExp") tExpTyConKey +codeTyConName = thTc (fsLit "Code") codeTyConKey injAnnTyConName = thTc (fsLit "InjectivityAnn") injAnnTyConKey overlapTyConName = thTc (fsLit "Overlap") overlapTyConKey returnQName, bindQName, sequenceQName, newNameName, liftName, mkNameName, mkNameG_vName, mkNameG_dName, mkNameG_tcName, - mkNameLName, mkNameSName, liftStringName, unTypeName, unTypeQName, - unsafeTExpCoerceName, liftTypedName :: Name + mkNameLName, mkNameSName, liftStringName, unTypeName, unTypeCodeName, + unsafeCodeCoerceName, liftTypedName :: Name returnQName = thFun (fsLit "returnQ") returnQIdKey bindQName = thFun (fsLit "bindQ") bindQIdKey sequenceQName = thFun (fsLit "sequenceQ") sequenceQIdKey @@ -226,8 +223,8 @@ mkNameG_tcName = thFun (fsLit "mkNameG_tc") mkNameG_tcIdKey mkNameLName = thFun (fsLit "mkNameL") mkNameLIdKey mkNameSName = thFun (fsLit "mkNameS") mkNameSIdKey unTypeName = thFun (fsLit "unType") unTypeIdKey -unTypeQName = thFun (fsLit "unTypeQ") unTypeQIdKey -unsafeTExpCoerceName = thFun (fsLit "unsafeTExpCoerce") unsafeTExpCoerceIdKey +unTypeCodeName = thFun (fsLit "unTypeCode") unTypeCodeIdKey +unsafeCodeCoerceName = thFun (fsLit "unsafeCodeCoerce") unsafeCodeCoerceIdKey liftTypedName = thFun (fsLit "liftTyped") liftTypedIdKey @@ -519,10 +516,6 @@ unsafeName = libFun (fsLit "unsafe") unsafeIdKey safeName = libFun (fsLit "safe") safeIdKey interruptibleName = libFun (fsLit "interruptible") interruptibleIdKey --- newtype TExp a = ... -tExpDataConName :: Name -tExpDataConName = thCon (fsLit "TExp") tExpDataConKey - -- data RuleBndr = ... ruleVarName, typedRuleVarName :: Name ruleVarName = libFun (fsLit ("ruleVar")) ruleVarIdKey @@ -647,7 +640,7 @@ expTyConKey, matchTyConKey, clauseTyConKey, qTyConKey, expQTyConKey, fieldExpTyConKey, fieldPatTyConKey, nameTyConKey, patQTyConKey, funDepTyConKey, predTyConKey, predQTyConKey, decsQTyConKey, ruleBndrTyConKey, tySynEqnTyConKey, - roleTyConKey, tExpTyConKey, injAnnTyConKey, kindTyConKey, + roleTyConKey, tExpTyConKey, codeTyConKey, injAnnTyConKey, kindTyConKey, overlapTyConKey, derivClauseTyConKey, derivStrategyTyConKey, decsTyConKey :: Unique expTyConKey = mkPreludeTyConUnique 200 @@ -671,7 +664,6 @@ funDepTyConKey = mkPreludeTyConUnique 222 predTyConKey = mkPreludeTyConUnique 223 predQTyConKey = mkPreludeTyConUnique 224 tyVarBndrUnitTyConKey = mkPreludeTyConUnique 225 -tyVarBndrSpecTyConKey = mkPreludeTyConUnique 237 decsQTyConKey = mkPreludeTyConUnique 226 ruleBndrTyConKey = mkPreludeTyConUnique 227 tySynEqnTyConKey = mkPreludeTyConUnique 228 @@ -683,6 +675,8 @@ overlapTyConKey = mkPreludeTyConUnique 233 derivClauseTyConKey = mkPreludeTyConUnique 234 derivStrategyTyConKey = mkPreludeTyConUnique 235 decsTyConKey = mkPreludeTyConUnique 236 +tyVarBndrSpecTyConKey = mkPreludeTyConUnique 237 +codeTyConKey = mkPreludeTyConUnique 238 {- ********************************************************************* * * @@ -710,10 +704,6 @@ allPhasesDataConKey = mkPreludeDataConUnique 205 fromPhaseDataConKey = mkPreludeDataConUnique 206 beforePhaseDataConKey = mkPreludeDataConUnique 207 --- newtype TExp a = ... -tExpDataConKey :: Unique -tExpDataConKey = mkPreludeDataConUnique 208 - -- data Overlap = .. overlappableDataConKey, overlappingDataConKey, @@ -735,8 +725,8 @@ incoherentDataConKey = mkPreludeDataConUnique 212 returnQIdKey, bindQIdKey, sequenceQIdKey, liftIdKey, newNameIdKey, mkNameIdKey, mkNameG_vIdKey, mkNameG_dIdKey, mkNameG_tcIdKey, - mkNameLIdKey, mkNameSIdKey, unTypeIdKey, unTypeQIdKey, - unsafeTExpCoerceIdKey, liftTypedIdKey :: Unique + mkNameLIdKey, mkNameSIdKey, unTypeIdKey, unTypeCodeIdKey, + liftTypedIdKey, unsafeCodeCoerceIdKey :: Unique returnQIdKey = mkPreludeMiscIdUnique 200 bindQIdKey = mkPreludeMiscIdUnique 201 sequenceQIdKey = mkPreludeMiscIdUnique 202 @@ -749,9 +739,9 @@ mkNameG_tcIdKey = mkPreludeMiscIdUnique 208 mkNameLIdKey = mkPreludeMiscIdUnique 209 mkNameSIdKey = mkPreludeMiscIdUnique 210 unTypeIdKey = mkPreludeMiscIdUnique 211 -unTypeQIdKey = mkPreludeMiscIdUnique 212 -unsafeTExpCoerceIdKey = mkPreludeMiscIdUnique 213 +unTypeCodeIdKey = mkPreludeMiscIdUnique 212 liftTypedIdKey = mkPreludeMiscIdUnique 214 +unsafeCodeCoerceIdKey = mkPreludeMiscIdUnique 215 -- data Lit = ... @@ -1093,9 +1083,10 @@ inferredSpecKey = mkPreludeMiscIdUnique 499 ************************************************************************ -} -lift_RDR, liftTyped_RDR, mkNameG_dRDR, mkNameG_vRDR :: RdrName +lift_RDR, liftTyped_RDR, mkNameG_dRDR, mkNameG_vRDR, unsafeCodeCoerce_RDR :: RdrName lift_RDR = nameRdrName liftName liftTyped_RDR = nameRdrName liftTypedName +unsafeCodeCoerce_RDR = nameRdrName unsafeCodeCoerceName mkNameG_dRDR = nameRdrName mkNameG_dName mkNameG_vRDR = nameRdrName mkNameG_vName ===================================== compiler/GHC/Tc/Deriv/Generate.hs ===================================== @@ -1576,7 +1576,7 @@ gen_Lift_binds loc tycon = (listToBag [lift_bind, liftTyped_bind], emptyBag) where lift_bind = mkFunBindEC 1 loc lift_RDR (nlHsApp pure_Expr) (map (pats_etc mk_exp) data_cons) - liftTyped_bind = mkFunBindEC 1 loc liftTyped_RDR (nlHsApp pure_Expr) + liftTyped_bind = mkFunBindEC 1 loc liftTyped_RDR (nlHsApp unsafeCodeCoerce_Expr . nlHsApp pure_Expr) (map (pats_etc mk_texp) data_cons) mk_exp = ExpBr noExtField @@ -2352,17 +2352,18 @@ bs_RDRs = [ mkVarUnqual (mkFastString ("b"++show i)) | i <- [(1::Int) .. cs_RDRs = [ mkVarUnqual (mkFastString ("c"++show i)) | i <- [(1::Int) .. ] ] a_Expr, b_Expr, c_Expr, z_Expr, ltTag_Expr, eqTag_Expr, gtTag_Expr, false_Expr, - true_Expr, pure_Expr :: LHsExpr GhcPs -a_Expr = nlHsVar a_RDR -b_Expr = nlHsVar b_RDR -c_Expr = nlHsVar c_RDR -z_Expr = nlHsVar z_RDR -ltTag_Expr = nlHsVar ltTag_RDR -eqTag_Expr = nlHsVar eqTag_RDR -gtTag_Expr = nlHsVar gtTag_RDR -false_Expr = nlHsVar false_RDR -true_Expr = nlHsVar true_RDR -pure_Expr = nlHsVar pure_RDR + true_Expr, pure_Expr, unsafeCodeCoerce_Expr :: LHsExpr GhcPs +a_Expr = nlHsVar a_RDR +b_Expr = nlHsVar b_RDR +c_Expr = nlHsVar c_RDR +z_Expr = nlHsVar z_RDR +ltTag_Expr = nlHsVar ltTag_RDR +eqTag_Expr = nlHsVar eqTag_RDR +gtTag_Expr = nlHsVar gtTag_RDR +false_Expr = nlHsVar false_RDR +true_Expr = nlHsVar true_RDR +pure_Expr = nlHsVar pure_RDR +unsafeCodeCoerce_Expr = nlHsVar unsafeCodeCoerce_RDR a_Pat, b_Pat, c_Pat, d_Pat, k_Pat, z_Pat :: LPat GhcPs a_Pat = nlVarPat a_RDR ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -196,7 +196,7 @@ tcTypedBracket rn_expr brack@(TExpBr _ expr) res_ty ; let rep = getRuntimeRep expr_ty ; meta_ty <- tcTExpTy m_var expr_ty ; ps' <- readMutVar ps_ref - ; texpco <- tcLookupId unsafeTExpCoerceName + ; texpco <- tcLookupId unsafeCodeCoerceName ; tcWrapResultO (Shouldn'tHappenOrigin "TExpBr") rn_expr (unLoc (mkHsApp (mkLHsWrap (applyQuoteWrapper wrapper) @@ -302,9 +302,9 @@ tcPendingSplice m_var (PendingRnSplice flavour splice_name expr) tcTExpTy :: TcType -> TcType -> TcM TcType tcTExpTy m_ty exp_ty = do { unless (isTauTy exp_ty) $ addErr (err_msg exp_ty) - ; texp <- tcLookupTyCon tExpTyConName + ; codeCon <- tcLookupTyCon codeTyConName ; let rep = getRuntimeRep exp_ty - ; return (mkAppTy m_ty (mkTyConApp texp [rep, exp_ty])) } + ; return (mkTyConApp codeCon [rep, m_ty, exp_ty]) } where err_msg ty = vcat [ text "Illegal polytype:" <+> ppr ty @@ -619,10 +619,10 @@ tcNestedSplice pop_stage (TcPending ps_var lie_var q@(QuoteWrapper _ m_var)) spl ; expr' <- setStage pop_stage $ setConstraintVar lie_var $ tcLExpr expr (mkCheckExpType meta_exp_ty) - ; untypeq <- tcLookupId unTypeQName + ; untypeCode <- tcLookupId unTypeCodeName ; let expr'' = mkHsApp (mkLHsWrap (applyQuoteWrapper q) - (nlHsTyApp untypeq [rep, res_ty])) expr' + (nlHsTyApp untypeCode [rep, res_ty])) expr' ; ps <- readMutVar ps_var ; writeMutVar ps_var (PendingTcSplice splice_name expr'' : ps) ===================================== docs/users_guide/exts/deriving_extra.rst ===================================== @@ -528,7 +528,7 @@ Deriving ``Lift`` instances The class ``Lift``, unlike other derivable classes, lives in ``template-haskell`` instead of ``base``. Having a data type be an instance of ``Lift`` permits its values to be promoted to Template Haskell expressions (of -type ``ExpQ`` and ``TExpQ a``), which can then be spliced into Haskell source +type ``ExpQ`` and ``Code Q a``), which can then be spliced into Haskell source code. Here is an example of how one can derive ``Lift``: ===================================== docs/users_guide/exts/template_haskell.rst ===================================== @@ -133,15 +133,15 @@ The :extension:`TemplateHaskellQuotes` extension is considered safe under is an arbitrary expression. A top-level typed expression splice can occur in place of an expression; the - spliced expression must have type ``Q (TExp a)`` + spliced expression must have type ``Code Q a`` - A *typed* expression quotation is written as ``[|| ... ||]``, or ``[e|| ... ||]``, where the "..." is an expression; if the "..." expression has type ``a``, then the quotation has type - ``Quote m => m (TExp a)``. + ``Quote m => Code m a``. - Values of type ``TExp a`` may be converted to values of type ``Exp`` - using the function ``unType :: TExp a -> Exp``. + It is possible to extract a value of type ``m Exp`` from ``Code m a`` + using the ``unTypeCode :: Code m a -> m Exp`` function. - A quasi-quotation can appear in a pattern, type, expression, or declaration context and is also written in Oxford brackets: @@ -202,7 +202,7 @@ The :extension:`TemplateHaskellQuotes` extension is considered safe under class Lift t where lift :: Quote m => t -> m Exp - liftTyped :: Quote m => t -> m (TExp t) + liftTyped :: Quote m => t -> Code m t In general, if GHC sees an expression within Oxford brackets (e.g., ``[| foo bar |]``, then GHC looks up each name within the brackets. If a name ===================================== libraries/template-haskell/Language/Haskell/TH.hs ===================================== @@ -50,6 +50,7 @@ module Language.Haskell.TH( -- * Typed expressions TExp, unType, + Code(..), unTypeCode, unsafeCodeCoerce, hoistCode, -- * Names Name, NameSpace, -- Abstract ===================================== libraries/template-haskell/Language/Haskell/TH/CodeDo.hs ===================================== @@ -0,0 +1,20 @@ +-- | This module exists to work nicely with the QualifiedDo +-- extension. +-- @ +-- import qualified Language.Haskell.TH.CodeDo as Code +-- myExample :: Monad m => Code m a -> Code m a -> Code m a +-- myExample opt1 opt2 = +-- Code.do +-- x <- someSideEffect -- This one is of type `M Bool` +-- if x then opt1 else opt2 +-- @ +module Language.Haskell.TH.CodeDo((>>=), (>>)) where + +import Language.Haskell.TH.Syntax +import Prelude(Monad) + +-- | Module over monad operator for 'Code' +(>>=) :: Monad m => m a -> (a -> Code m b) -> Code m b +(>>=) = bindCode +(>>) :: Monad m => m a -> Code m b -> Code m b +(>>) = bindCode_ ===================================== libraries/template-haskell/Language/Haskell/TH/Lib.hs ===================================== @@ -18,7 +18,7 @@ module Language.Haskell.TH.Lib ( -- * Library functions -- ** Abbreviations - InfoQ, ExpQ, TExpQ, DecQ, DecsQ, ConQ, TypeQ, KindQ, + InfoQ, ExpQ, TExpQ, CodeQ, DecQ, DecsQ, ConQ, TypeQ, KindQ, TyLitQ, CxtQ, PredQ, DerivClauseQ, MatchQ, ClauseQ, BodyQ, GuardQ, StmtQ, RangeQ, SourceStrictnessQ, SourceUnpackednessQ, BangQ, BangTypeQ, VarBangTypeQ, StrictTypeQ, VarStrictTypeQ, FieldExpQ, PatQ, ===================================== libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs ===================================== @@ -31,6 +31,7 @@ type PatQ = Q Pat type FieldPatQ = Q FieldPat type ExpQ = Q Exp type TExpQ a = Q (TExp a) +type CodeQ = Code Q type DecQ = Q Dec type DecsQ = Q [Dec] type Decs = [Dec] -- Defined as it is more convenient to wire-in ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -343,6 +343,63 @@ be inferred (#8459). Consider The splice will evaluate to (MkAge 3) and you can't add that to 4::Int. So you can't coerce a (TExp Age) to a (TExp Int). -} +-- Code constructor + +type role Code representational nominal -- See Note [Role of TExp] +newtype Code m (a :: TYPE (r :: RuntimeRep)) = Code + { examineCode :: m (TExp a) -- ^ Underlying monadic value + } + +-- | Unsafely convert an untyped code representation into a typed code +-- representation. +unsafeCodeCoerce :: forall (r :: RuntimeRep) (a :: TYPE r) m . + Quote m => m Exp -> Code m a +unsafeCodeCoerce m = Code (unsafeTExpCoerce m) + +-- | Lift a monadic action producing code into the typed 'Code' +-- representation +liftCode :: forall (r :: RuntimeRep) (a :: TYPE r) m . m (TExp a) -> Code m a +liftCode = Code + +-- | Extract the untyped representation from the typed representation +unTypeCode :: forall (r :: RuntimeRep) (a :: TYPE r) m . Quote m + => Code m a -> m Exp +unTypeCode = unTypeQ . examineCode + +-- | Modify the ambient monad used during code generation. For example, you +-- can use `hoistCode` to handle a state effect: +-- @ +-- handleState :: Code (StateT Int Q) a -> Code Q a +-- handleState = hoistCode (flip runState 0) +-- @ +hoistCode :: forall m n (r :: RuntimeRep) (a :: TYPE r) . Monad m + => (forall x . m x -> n x) -> Code m a -> Code n a +hoistCode f (Code a) = Code (f a) + + +-- | Variant of (>>=) which allows effectful computations to be injected +-- into code generation. +bindCode :: forall m a (r :: RuntimeRep) (b :: TYPE r) . Monad m + => m a -> (a -> Code m b) -> Code m b +bindCode q k = liftCode (q >>= examineCode . k) + +-- | Variant of (>>) which allows effectful computations to be injected +-- into code generation. +bindCode_ :: forall m a (r :: RuntimeRep) (b :: TYPE r) . Monad m + => m a -> Code m b -> Code m b +bindCode_ q c = liftCode ( q >> examineCode c) + +-- | A useful combinator for embedding monadic actions into 'Code' +-- @ +-- myCode :: ... => Code m a +-- myCode = joinCode $ do +-- x <- someSideEffect +-- return (makeCodeWith x) +-- @ +joinCode :: forall m (r :: RuntimeRep) (a :: TYPE r) . Monad m + => m (Code m a) -> Code m a +joinCode = flip bindCode id + ---------------------------------------------------- -- Packaged versions for the programmer, hiding the Quasi-ness @@ -727,107 +784,107 @@ class Lift (t :: TYPE r) where -- a splice. lift :: Quote m => t -> m Exp default lift :: (r ~ 'LiftedRep, Quote m) => t -> m Exp - lift = unTypeQ . liftTyped + lift = unTypeCode . liftTyped -- | Turn a value into a Template Haskell typed expression, suitable for use -- in a typed splice. -- -- @since 2.16.0.0 - liftTyped :: Quote m => t -> m (TExp t) + liftTyped :: Quote m => t -> Code m t -- If you add any instances here, consider updating test th/TH_Lift instance Lift Integer where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL x)) instance Lift Int where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) -- | @since 2.16.0.0 instance Lift Int# where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntPrimL (fromIntegral (I# x)))) instance Lift Int8 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Int16 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Int32 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Int64 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) -- | @since 2.16.0.0 instance Lift Word# where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (WordPrimL (fromIntegral (W# x)))) instance Lift Word where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Word8 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Word16 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Word32 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Word64 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Natural where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Integral a => Lift (Ratio a) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (RationalL (toRational x))) instance Lift Float where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (RationalL (toRational x))) -- | @since 2.16.0.0 instance Lift Float# where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (FloatPrimL (toRational (F# x)))) instance Lift Double where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (RationalL (toRational x))) -- | @since 2.16.0.0 instance Lift Double# where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (DoublePrimL (toRational (D# x)))) instance Lift Char where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (CharL x)) -- | @since 2.16.0.0 instance Lift Char# where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (CharPrimL (C# x))) instance Lift Bool where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift True = return (ConE trueName) lift False = return (ConE falseName) @@ -837,24 +894,24 @@ instance Lift Bool where -- -- @since 2.16.0.0 instance Lift Addr# where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (StringPrimL (map (fromIntegral . ord) (unpackCString# x)))) instance Lift a => Lift (Maybe a) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift Nothing = return (ConE nothingName) lift (Just x) = liftM (ConE justName `AppE`) (lift x) instance (Lift a, Lift b) => Lift (Either a b) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (Left x) = liftM (ConE leftName `AppE`) (lift x) lift (Right y) = liftM (ConE rightName `AppE`) (lift y) instance Lift a => Lift [a] where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift xs = do { xs' <- mapM lift xs; return (ListE xs') } liftString :: Quote m => String -> m Exp @@ -863,7 +920,7 @@ liftString s = return (LitE (StringL s)) -- | @since 2.15.0.0 instance Lift a => Lift (NonEmpty a) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (x :| xs) = do x' <- lift x @@ -872,77 +929,77 @@ instance Lift a => Lift (NonEmpty a) where -- | @since 2.15.0.0 instance Lift Void where - liftTyped = pure . absurd + liftTyped = liftCode . absurd lift = pure . absurd instance Lift () where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift () = return (ConE (tupleDataName 0)) instance (Lift a, Lift b) => Lift (a, b) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (a, b) = liftM TupE $ sequence $ map (fmap Just) [lift a, lift b] instance (Lift a, Lift b, Lift c) => Lift (a, b, c) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (a, b, c) = liftM TupE $ sequence $ map (fmap Just) [lift a, lift b, lift c] instance (Lift a, Lift b, Lift c, Lift d) => Lift (a, b, c, d) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (a, b, c, d) = liftM TupE $ sequence $ map (fmap Just) [lift a, lift b, lift c, lift d] instance (Lift a, Lift b, Lift c, Lift d, Lift e) => Lift (a, b, c, d, e) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (a, b, c, d, e) = liftM TupE $ sequence $ map (fmap Just) [ lift a, lift b , lift c, lift d, lift e ] instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f) => Lift (a, b, c, d, e, f) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (a, b, c, d, e, f) = liftM TupE $ sequence $ map (fmap Just) [ lift a, lift b, lift c , lift d, lift e, lift f ] instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f, Lift g) => Lift (a, b, c, d, e, f, g) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (a, b, c, d, e, f, g) = liftM TupE $ sequence $ map (fmap Just) [ lift a, lift b, lift c , lift d, lift e, lift f, lift g ] -- | @since 2.16.0.0 instance Lift (# #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# #) = return (ConE (unboxedTupleTypeName 0)) -- | @since 2.16.0.0 instance (Lift a) => Lift (# a #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# a #) = liftM UnboxedTupE $ sequence $ map (fmap Just) [lift a] -- | @since 2.16.0.0 instance (Lift a, Lift b) => Lift (# a, b #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# a, b #) = liftM UnboxedTupE $ sequence $ map (fmap Just) [lift a, lift b] -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c) => Lift (# a, b, c #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# a, b, c #) = liftM UnboxedTupE $ sequence $ map (fmap Just) [lift a, lift b, lift c] -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d) => Lift (# a, b, c, d #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# a, b, c, d #) = liftM UnboxedTupE $ sequence $ map (fmap Just) [ lift a, lift b , lift c, lift d ] @@ -950,7 +1007,7 @@ instance (Lift a, Lift b, Lift c, Lift d) -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d, Lift e) => Lift (# a, b, c, d, e #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# a, b, c, d, e #) = liftM UnboxedTupE $ sequence $ map (fmap Just) [ lift a, lift b , lift c, lift d, lift e ] @@ -958,7 +1015,7 @@ instance (Lift a, Lift b, Lift c, Lift d, Lift e) -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f) => Lift (# a, b, c, d, e, f #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# a, b, c, d, e, f #) = liftM UnboxedTupE $ sequence $ map (fmap Just) [ lift a, lift b, lift c , lift d, lift e, lift f ] @@ -966,7 +1023,7 @@ instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f) -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f, Lift g) => Lift (# a, b, c, d, e, f, g #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# a, b, c, d, e, f, g #) = liftM UnboxedTupE $ sequence $ map (fmap Just) [ lift a, lift b, lift c , lift d, lift e, lift f @@ -974,7 +1031,7 @@ instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f, Lift g) -- | @since 2.16.0.0 instance (Lift a, Lift b) => Lift (# a | b #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = case x of (# y | #) -> UnboxedSumE <$> lift y <*> pure 1 <*> pure 2 @@ -983,7 +1040,7 @@ instance (Lift a, Lift b) => Lift (# a | b #) where -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c) => Lift (# a | b | c #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = case x of (# y | | #) -> UnboxedSumE <$> lift y <*> pure 1 <*> pure 3 @@ -993,7 +1050,7 @@ instance (Lift a, Lift b, Lift c) -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d) => Lift (# a | b | c | d #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = case x of (# y | | | #) -> UnboxedSumE <$> lift y <*> pure 1 <*> pure 4 @@ -1004,7 +1061,7 @@ instance (Lift a, Lift b, Lift c, Lift d) -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d, Lift e) => Lift (# a | b | c | d | e #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = case x of (# y | | | | #) -> UnboxedSumE <$> lift y <*> pure 1 <*> pure 5 @@ -1016,7 +1073,7 @@ instance (Lift a, Lift b, Lift c, Lift d, Lift e) -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f) => Lift (# a | b | c | d | e | f #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = case x of (# y | | | | | #) -> UnboxedSumE <$> lift y <*> pure 1 <*> pure 6 @@ -1029,7 +1086,7 @@ instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f) -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f, Lift g) => Lift (# a | b | c | d | e | f | g #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = case x of (# y | | | | | | #) -> UnboxedSumE <$> lift y <*> pure 1 <*> pure 7 ===================================== libraries/template-haskell/changelog.md ===================================== @@ -1,6 +1,9 @@ # Changelog for [`template-haskell` package](http://hackage.haskell.org/package/template-haskell) ## 2.17.0.0 + * Typed Quotations now return a value of type `Code m a` (GHC Proposal #195). + The main motiviation is to make writing instances easier and make it easier to + store `Code` values in type-indexed maps. * Implement Overloaded Quotations (GHC Proposal #246). This patch modifies a few fundamental things in the API. All the library combinators are generalised @@ -9,7 +12,7 @@ written in terms of `Q` are now disallowed. The types of `unsafeTExpCoerce` and `unTypeQ` are also generalised in terms of `Quote` rather than specific to `Q`. - + * Implement Explicit specificity in type variable binders (GHC Proposal #99). In `Language.Haskell.TH.Syntax`, `TyVarBndr` is now annotated with a `flag`, denoting the additional argument to its constructors `PlainTV` and `KindedTV`. ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -48,7 +48,7 @@ Library Language.Haskell.TH.Quote Language.Haskell.TH.Syntax Language.Haskell.TH.LanguageExtensions - + Language.Haskell.TH.CodeDo Language.Haskell.TH.Lib.Internal other-modules: ===================================== libraries/text ===================================== @@ -1 +1 @@ -Subproject commit a01843250166b5559936ba5eb81f7873e709587a +Subproject commit 74f835751b60b312d01dd600d516756d5325d514 ===================================== testsuite/tests/quotes/T17857.hs ===================================== @@ -7,4 +7,4 @@ import Language.Haskell.TH.Syntax data T = MkT deriving Data instance Lift T where lift = liftData - liftTyped = unsafeTExpCoerce . lift + liftTyped = unsafeCodeCoerce . lift ===================================== testsuite/tests/th/T10945.stderr ===================================== @@ -1,8 +1,8 @@ T10945.hs:7:4: error: - • Couldn't match type ‘[Dec]’ with ‘TExp DecsQ’ - Expected type: Q (TExp DecsQ) - Actual type: Q [Dec] + • Couldn't match type ‘[Dec]’ with ‘Q [Dec]’ + Expected type: Code Q DecsQ + Actual type: Code Q [Dec] • In the expression: return [SigD ===================================== testsuite/tests/th/T15471A.hs ===================================== @@ -6,9 +6,9 @@ import Language.Haskell.TH foo1 x = x -test_foo :: Q (TExp (a -> a)) +test_foo :: Code Q (a -> a) test_foo = [|| foo1 ||] -list_foo :: Q (TExp a) -> Q (TExp [a]) +list_foo :: Code Q a -> Code Q [a] list_foo x = [|| [ $$x, $$x ] ||] ===================================== testsuite/tests/th/T15843.hs ===================================== @@ -13,12 +13,12 @@ main = do mapM_ (\q -> runQ q >>= ppr_and_show) [first_of_2, second_of_2, empty_2, full_2, third_of_3] - mapM_ (\q -> runQ (fmap unType q) >>= ppr_and_show) + mapM_ (\q -> (runQ (unTypeCode q)) >>= ppr_and_show) [first_of_2_T, second_of_2_T] - runQ (fmap unType empty_2_T) >>= ppr_and_show - runQ (fmap unType full_2_T) >>= ppr_and_show - runQ (fmap unType third_of_3_T) >>= ppr_and_show + runQ (unTypeCode empty_2_T) >>= ppr_and_show + runQ (unTypeCode full_2_T) >>= ppr_and_show + runQ (unTypeCode third_of_3_T) >>= ppr_and_show print $ "(909,) applied to 'c' should be (909, 'c') ===> " ++ (show $ (909, 'c') == ($first_of_2 'c')) ===================================== testsuite/tests/th/T16195A.hs ===================================== @@ -3,11 +3,11 @@ module T16195A where import Language.Haskell.TH -foo :: Q (TExp (IO ())) +foo :: Code Q (IO ()) foo = [|| return () ||] -showC :: Q (TExp (() -> String)) +showC :: Code Q (() -> String) showC = [|| show ||] -unitC :: Q (TExp ()) +unitC :: Code Q () unitC = [|| () ||] ===================================== testsuite/tests/th/T18121.hs ===================================== @@ -3,5 +3,5 @@ module Bug where import Language.Haskell.TH -sapply :: Q (TExp (a -> b)) -> Q (TExp a) -> Q (TExp b) +sapply :: Quote m => Code m (a -> b) -> Code m a -> Code m b sapply cf cx = [|| $$cf $$cx ||] ===================================== testsuite/tests/th/T8577.stderr ===================================== @@ -1,8 +1,8 @@ T8577.hs:9:11: error: • Couldn't match type ‘Int’ with ‘Bool’ - Expected type: Q (TExp (A Bool)) - Actual type: Q (TExp (A Int)) + Expected type: Code Q (A Bool) + Actual type: Code Q (A Int) • In the expression: y In the Template Haskell splice $$(y) In the expression: $$(y) ===================================== testsuite/tests/th/T8577a.hs ===================================== @@ -4,8 +4,8 @@ import Language.Haskell.TH data A a = A -x :: Q (TExp (A a)) +x :: Code Q (A a) x = [|| A ||] -y :: Q (TExp (A Int)) +y :: Code Q (A Int) y = x ===================================== testsuite/tests/th/TH_StringLift.hs ===================================== @@ -3,7 +3,7 @@ module TH_StringLift where import Language.Haskell.TH.Syntax -foo :: Quote m => String -> m (TExp String) +foo :: Quote m => String -> Code m String foo x = [|| x ||] foo2 :: Quote m => String -> m Exp ===================================== testsuite/tests/th/TH_reifyLocalDefs.hs ===================================== @@ -29,8 +29,8 @@ main = print (f 1 "", g 'a' 2, h True 3) ) , xg :: Char ) - h xh y = ( $$(do printTypeOf("xh") - [|| y :: Int ||] + h xh y = ( $$(liftCode $ do printTypeOf("xh") + examineCode [|| y :: Int ||] ) , xh :: Bool ) ===================================== testsuite/tests/th/overloaded/T17839.hs ===================================== @@ -16,7 +16,7 @@ import Data.Functor.Identity type LetT m a = WriterT [Locus] m a -type Code m a = m (TExp a) +type MCode m a = m (TExp a) type LetCode m a = LetT m (TExp a) @@ -29,7 +29,7 @@ instance (Monoid w, Quote m) => Quote (StateT w m) where newName x = W.lift (newName x) -locus :: (Locus -> LetCode m a) -> Code m a +locus :: (Locus -> LetCode m a) -> MCode m a locus = undefined newTypedName :: Quote m => m (TExp a) @@ -38,15 +38,15 @@ newTypedName = do return (TExp (VarE n)) -gen :: Quote m => Locus -> (Code Identity (a -> b) -> LetCode m a -> LetCode m b) -> LetCode m (a -> b) +gen :: Quote m => Locus -> (MCode Identity (a -> b) -> LetCode m a -> LetCode m b) -> LetCode m (a -> b) gen l f = do n <- newTypedName - [|| \a -> $$(f (Identity n) [|| a ||]) ||] + examineCode [|| \a -> $$(liftCode $ f (Identity n) (examineCode [|| a ||])) ||] mrfix :: forall a b m r . (Monad m, Ord a, Quote m) - => (forall m . (a -> Code m (b -> r)) -> (a -> Code m b -> Code m r)) - -> (a -> Code m (b -> r)) + => (forall m . (a -> MCode m (b -> r)) -> (a -> MCode m b -> MCode m r)) + -> (a -> MCode m (b -> r)) mrfix f x = flip evalStateT Map.empty $ locus $ \locus -> do ===================================== testsuite/tests/th/overloaded/TH_overloaded_constraints.hs ===================================== @@ -22,11 +22,11 @@ dq = [| 5 |] top_level :: (C m, D m, Quote m) => m Exp top_level = [| $cq + $dq |] -cqt :: (C m, Quote m) => m (TExp Int) +cqt :: (C m, Quote m) => Code m Int cqt = [|| 5 ||] -dqt :: (D m, Quote m) => m (TExp Int) +dqt :: (D m, Quote m) => Code m Int dqt = [|| 5 ||] -top_level_t :: (C m, D m, Quote m) => m (TExp Int) +top_level_t :: (C m, D m, Quote m) => Code m Int top_level_t = [|| $$cqt + $$dqt ||] ===================================== testsuite/tests/th/overloaded/TH_overloaded_csp.hs ===================================== @@ -14,5 +14,5 @@ instance Quote Identity where main = do print $ runIdentity ((\x -> [| x |]) ()) - print $ unType $ runIdentity ((\x -> [|| x ||]) ()) + print $ runIdentity $ unTypeCode ((\x -> [|| x ||]) ()) ===================================== testsuite/tests/th/overloaded/TH_overloaded_extract.hs ===================================== @@ -19,5 +19,5 @@ main = do print $ runIdentity [d| data Foo = Foo |] print $ runIdentity [p| () |] print $ runIdentity [t| [Int] |] - print $ unType $ runIdentity [|| (+1) ||] + print $ runIdentity $ unTypeCode [|| (+1) ||] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/227e82c48b6f672a5d76ce4bb665ac44a75f882a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/227e82c48b6f672a5d76ce4bb665ac44a75f882a You're receiving 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 27 11:03:17 2020 From: gitlab at gitlab.haskell.org (Matthew Pickering) Date: Wed, 27 May 2020 07:03:17 -0400 Subject: [Git][ghc/ghc][wip/proposal-195] Use a newtype `Code` for the return type of typed quotations (Proposal #195) Message-ID: <5ece48f56122f_6e263f9f083f2a6418636c5@gitlab.haskell.org.mail> Matthew Pickering pushed to branch wip/proposal-195 at Glasgow Haskell Compiler / GHC Commits: 74a756df by Matthew Pickering at 2020-05-27T12:02:59+01:00 Use a newtype `Code` for the return type of typed quotations (Proposal #195) There are three problems with the current API: 1. It is hard to properly write instances for ``Quote m => m (TExp a)`` as the type is the composition of two type constructors. Doing so in your program involves making your own newtype and doing a lot of wrapping/unwrapping. For example, if I want to create a language which I can either run immediately or generate code from I could write the following with the new API. :: class Lang r where _int :: Int -> r Int _if :: r Bool -> r a -> r a -> r a instance Lang Identity where _int = Identity _if (Identity b) (Identity t) (Identity f) = Identity (if b then t else f) instance Quote m => Lang (Code m) where _int = liftTyped _if cb ct cf = [|| if $$cb then $$ct else $$cf ||] 2. When doing code generation it is common to want to store code fragments in a map. When doing typed code generation, these code fragments contain a type index so it is desirable to store them in one of the parameterised map data types such as ``DMap`` from ``dependent-map`` or ``MapF`` from ``parameterized-utils``. :: compiler :: Env -> AST a -> Code Q a data AST a where ... data Ident a = ... type Env = MapF Ident (Code Q) newtype Code m a = Code (m (TExp a)) In this example, the ``MapF`` maps an ``Ident String`` directly to a ``Code Q String``. Using one of these map types currently requires creating your own newtype and constantly wrapping every quotation and unwrapping it when using a splice. Achievable, but it creates even more syntactic noise than normal metaprogramming. 3. ``m (TExp a)`` is ugly to read and write, understanding ``Code m a`` is easier. This is a weak reason but one everyone can surely agree with. - - - - - 27 changed files: - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Gen/Splice.hs - docs/users_guide/exts/deriving_extra.rst - docs/users_guide/exts/template_haskell.rst - libraries/template-haskell/Language/Haskell/TH.hs - + libraries/template-haskell/Language/Haskell/TH/CodeDo.hs - libraries/template-haskell/Language/Haskell/TH/Lib.hs - libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/changelog.md - libraries/template-haskell/template-haskell.cabal.in - libraries/text - testsuite/tests/quotes/T17857.hs - testsuite/tests/th/T10945.stderr - testsuite/tests/th/T15471A.hs - testsuite/tests/th/T15843.hs - testsuite/tests/th/T16195A.hs - testsuite/tests/th/T18121.hs - testsuite/tests/th/T8577.stderr - testsuite/tests/th/T8577a.hs - testsuite/tests/th/TH_StringLift.hs - testsuite/tests/th/TH_reifyLocalDefs.hs - testsuite/tests/th/overloaded/T17839.hs - testsuite/tests/th/overloaded/TH_overloaded_constraints.hs - testsuite/tests/th/overloaded/TH_overloaded_csp.hs - testsuite/tests/th/overloaded/TH_overloaded_extract.hs Changes: ===================================== compiler/GHC/Builtin/Names/TH.hs ===================================== @@ -31,9 +31,8 @@ templateHaskellNames = [ mkNameName, mkNameG_vName, mkNameG_dName, mkNameG_tcName, mkNameLName, mkNameSName, liftStringName, - unTypeName, - unTypeQName, - unsafeTExpCoerceName, + unTypeName, unTypeCodeName, + unsafeCodeCoerceName, -- Lit charLName, stringLName, integerLName, intPrimLName, wordPrimLName, @@ -134,8 +133,6 @@ templateHaskellNames = [ -- DerivStrategy stockStrategyName, anyclassStrategyName, newtypeStrategyName, viaStrategyName, - -- TExp - tExpDataConName, -- RuleBndr ruleVarName, typedRuleVarName, -- FunDep @@ -158,7 +155,7 @@ templateHaskellNames = [ typeTyConName, tyVarBndrUnitTyConName, tyVarBndrSpecTyConName, clauseTyConName, patQTyConName, funDepTyConName, decsQTyConName, ruleBndrTyConName, tySynEqnTyConName, - roleTyConName, tExpTyConName, injAnnTyConName, kindTyConName, + roleTyConName, codeTyConName, injAnnTyConName, kindTyConName, overlapTyConName, derivClauseTyConName, derivStrategyTyConName, -- Quasiquoting @@ -191,7 +188,7 @@ quoteClassName = thCls (fsLit "Quote") quoteClassKey qTyConName, nameTyConName, fieldExpTyConName, patTyConName, fieldPatTyConName, expTyConName, decTyConName, typeTyConName, matchTyConName, clauseTyConName, funDepTyConName, predTyConName, - tExpTyConName, injAnnTyConName, overlapTyConName, decsTyConName :: Name + codeTyConName, injAnnTyConName, overlapTyConName, decsTyConName :: Name qTyConName = thTc (fsLit "Q") qTyConKey nameTyConName = thTc (fsLit "Name") nameTyConKey fieldExpTyConName = thTc (fsLit "FieldExp") fieldExpTyConKey @@ -205,14 +202,14 @@ matchTyConName = thTc (fsLit "Match") matchTyConKey clauseTyConName = thTc (fsLit "Clause") clauseTyConKey funDepTyConName = thTc (fsLit "FunDep") funDepTyConKey predTyConName = thTc (fsLit "Pred") predTyConKey -tExpTyConName = thTc (fsLit "TExp") tExpTyConKey +codeTyConName = thTc (fsLit "Code") codeTyConKey injAnnTyConName = thTc (fsLit "InjectivityAnn") injAnnTyConKey overlapTyConName = thTc (fsLit "Overlap") overlapTyConKey returnQName, bindQName, sequenceQName, newNameName, liftName, mkNameName, mkNameG_vName, mkNameG_dName, mkNameG_tcName, - mkNameLName, mkNameSName, liftStringName, unTypeName, unTypeQName, - unsafeTExpCoerceName, liftTypedName :: Name + mkNameLName, mkNameSName, liftStringName, unTypeName, unTypeCodeName, + unsafeCodeCoerceName, liftTypedName :: Name returnQName = thFun (fsLit "returnQ") returnQIdKey bindQName = thFun (fsLit "bindQ") bindQIdKey sequenceQName = thFun (fsLit "sequenceQ") sequenceQIdKey @@ -226,8 +223,8 @@ mkNameG_tcName = thFun (fsLit "mkNameG_tc") mkNameG_tcIdKey mkNameLName = thFun (fsLit "mkNameL") mkNameLIdKey mkNameSName = thFun (fsLit "mkNameS") mkNameSIdKey unTypeName = thFun (fsLit "unType") unTypeIdKey -unTypeQName = thFun (fsLit "unTypeQ") unTypeQIdKey -unsafeTExpCoerceName = thFun (fsLit "unsafeTExpCoerce") unsafeTExpCoerceIdKey +unTypeCodeName = thFun (fsLit "unTypeCode") unTypeCodeIdKey +unsafeCodeCoerceName = thFun (fsLit "unsafeCodeCoerce") unsafeCodeCoerceIdKey liftTypedName = thFun (fsLit "liftTyped") liftTypedIdKey @@ -519,10 +516,6 @@ unsafeName = libFun (fsLit "unsafe") unsafeIdKey safeName = libFun (fsLit "safe") safeIdKey interruptibleName = libFun (fsLit "interruptible") interruptibleIdKey --- newtype TExp a = ... -tExpDataConName :: Name -tExpDataConName = thCon (fsLit "TExp") tExpDataConKey - -- data RuleBndr = ... ruleVarName, typedRuleVarName :: Name ruleVarName = libFun (fsLit ("ruleVar")) ruleVarIdKey @@ -647,7 +640,7 @@ expTyConKey, matchTyConKey, clauseTyConKey, qTyConKey, expQTyConKey, fieldExpTyConKey, fieldPatTyConKey, nameTyConKey, patQTyConKey, funDepTyConKey, predTyConKey, predQTyConKey, decsQTyConKey, ruleBndrTyConKey, tySynEqnTyConKey, - roleTyConKey, tExpTyConKey, injAnnTyConKey, kindTyConKey, + roleTyConKey, tExpTyConKey, codeTyConKey, injAnnTyConKey, kindTyConKey, overlapTyConKey, derivClauseTyConKey, derivStrategyTyConKey, decsTyConKey :: Unique expTyConKey = mkPreludeTyConUnique 200 @@ -671,7 +664,6 @@ funDepTyConKey = mkPreludeTyConUnique 222 predTyConKey = mkPreludeTyConUnique 223 predQTyConKey = mkPreludeTyConUnique 224 tyVarBndrUnitTyConKey = mkPreludeTyConUnique 225 -tyVarBndrSpecTyConKey = mkPreludeTyConUnique 237 decsQTyConKey = mkPreludeTyConUnique 226 ruleBndrTyConKey = mkPreludeTyConUnique 227 tySynEqnTyConKey = mkPreludeTyConUnique 228 @@ -683,6 +675,8 @@ overlapTyConKey = mkPreludeTyConUnique 233 derivClauseTyConKey = mkPreludeTyConUnique 234 derivStrategyTyConKey = mkPreludeTyConUnique 235 decsTyConKey = mkPreludeTyConUnique 236 +tyVarBndrSpecTyConKey = mkPreludeTyConUnique 237 +codeTyConKey = mkPreludeTyConUnique 238 {- ********************************************************************* * * @@ -710,10 +704,6 @@ allPhasesDataConKey = mkPreludeDataConUnique 205 fromPhaseDataConKey = mkPreludeDataConUnique 206 beforePhaseDataConKey = mkPreludeDataConUnique 207 --- newtype TExp a = ... -tExpDataConKey :: Unique -tExpDataConKey = mkPreludeDataConUnique 208 - -- data Overlap = .. overlappableDataConKey, overlappingDataConKey, @@ -735,8 +725,8 @@ incoherentDataConKey = mkPreludeDataConUnique 212 returnQIdKey, bindQIdKey, sequenceQIdKey, liftIdKey, newNameIdKey, mkNameIdKey, mkNameG_vIdKey, mkNameG_dIdKey, mkNameG_tcIdKey, - mkNameLIdKey, mkNameSIdKey, unTypeIdKey, unTypeQIdKey, - unsafeTExpCoerceIdKey, liftTypedIdKey :: Unique + mkNameLIdKey, mkNameSIdKey, unTypeIdKey, unTypeCodeIdKey, + liftTypedIdKey, unsafeCodeCoerceIdKey :: Unique returnQIdKey = mkPreludeMiscIdUnique 200 bindQIdKey = mkPreludeMiscIdUnique 201 sequenceQIdKey = mkPreludeMiscIdUnique 202 @@ -749,9 +739,9 @@ mkNameG_tcIdKey = mkPreludeMiscIdUnique 208 mkNameLIdKey = mkPreludeMiscIdUnique 209 mkNameSIdKey = mkPreludeMiscIdUnique 210 unTypeIdKey = mkPreludeMiscIdUnique 211 -unTypeQIdKey = mkPreludeMiscIdUnique 212 -unsafeTExpCoerceIdKey = mkPreludeMiscIdUnique 213 +unTypeCodeIdKey = mkPreludeMiscIdUnique 212 liftTypedIdKey = mkPreludeMiscIdUnique 214 +unsafeCodeCoerceIdKey = mkPreludeMiscIdUnique 215 -- data Lit = ... @@ -1093,9 +1083,10 @@ inferredSpecKey = mkPreludeMiscIdUnique 499 ************************************************************************ -} -lift_RDR, liftTyped_RDR, mkNameG_dRDR, mkNameG_vRDR :: RdrName +lift_RDR, liftTyped_RDR, mkNameG_dRDR, mkNameG_vRDR, unsafeCodeCoerce_RDR :: RdrName lift_RDR = nameRdrName liftName liftTyped_RDR = nameRdrName liftTypedName +unsafeCodeCoerce_RDR = nameRdrName unsafeCodeCoerceName mkNameG_dRDR = nameRdrName mkNameG_dName mkNameG_vRDR = nameRdrName mkNameG_vName ===================================== compiler/GHC/Tc/Deriv/Generate.hs ===================================== @@ -1576,7 +1576,7 @@ gen_Lift_binds loc tycon = (listToBag [lift_bind, liftTyped_bind], emptyBag) where lift_bind = mkFunBindEC 1 loc lift_RDR (nlHsApp pure_Expr) (map (pats_etc mk_exp) data_cons) - liftTyped_bind = mkFunBindEC 1 loc liftTyped_RDR (nlHsApp pure_Expr) + liftTyped_bind = mkFunBindEC 1 loc liftTyped_RDR (nlHsApp unsafeCodeCoerce_Expr . nlHsApp pure_Expr) (map (pats_etc mk_texp) data_cons) mk_exp = ExpBr noExtField @@ -2352,17 +2352,18 @@ bs_RDRs = [ mkVarUnqual (mkFastString ("b"++show i)) | i <- [(1::Int) .. cs_RDRs = [ mkVarUnqual (mkFastString ("c"++show i)) | i <- [(1::Int) .. ] ] a_Expr, b_Expr, c_Expr, z_Expr, ltTag_Expr, eqTag_Expr, gtTag_Expr, false_Expr, - true_Expr, pure_Expr :: LHsExpr GhcPs -a_Expr = nlHsVar a_RDR -b_Expr = nlHsVar b_RDR -c_Expr = nlHsVar c_RDR -z_Expr = nlHsVar z_RDR -ltTag_Expr = nlHsVar ltTag_RDR -eqTag_Expr = nlHsVar eqTag_RDR -gtTag_Expr = nlHsVar gtTag_RDR -false_Expr = nlHsVar false_RDR -true_Expr = nlHsVar true_RDR -pure_Expr = nlHsVar pure_RDR + true_Expr, pure_Expr, unsafeCodeCoerce_Expr :: LHsExpr GhcPs +a_Expr = nlHsVar a_RDR +b_Expr = nlHsVar b_RDR +c_Expr = nlHsVar c_RDR +z_Expr = nlHsVar z_RDR +ltTag_Expr = nlHsVar ltTag_RDR +eqTag_Expr = nlHsVar eqTag_RDR +gtTag_Expr = nlHsVar gtTag_RDR +false_Expr = nlHsVar false_RDR +true_Expr = nlHsVar true_RDR +pure_Expr = nlHsVar pure_RDR +unsafeCodeCoerce_Expr = nlHsVar unsafeCodeCoerce_RDR a_Pat, b_Pat, c_Pat, d_Pat, k_Pat, z_Pat :: LPat GhcPs a_Pat = nlVarPat a_RDR ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -196,7 +196,7 @@ tcTypedBracket rn_expr brack@(TExpBr _ expr) res_ty ; let rep = getRuntimeRep expr_ty ; meta_ty <- tcTExpTy m_var expr_ty ; ps' <- readMutVar ps_ref - ; texpco <- tcLookupId unsafeTExpCoerceName + ; texpco <- tcLookupId unsafeCodeCoerceName ; tcWrapResultO (Shouldn'tHappenOrigin "TExpBr") rn_expr (unLoc (mkHsApp (mkLHsWrap (applyQuoteWrapper wrapper) @@ -302,9 +302,9 @@ tcPendingSplice m_var (PendingRnSplice flavour splice_name expr) tcTExpTy :: TcType -> TcType -> TcM TcType tcTExpTy m_ty exp_ty = do { unless (isTauTy exp_ty) $ addErr (err_msg exp_ty) - ; texp <- tcLookupTyCon tExpTyConName + ; codeCon <- tcLookupTyCon codeTyConName ; let rep = getRuntimeRep exp_ty - ; return (mkAppTy m_ty (mkTyConApp texp [rep, exp_ty])) } + ; return (mkTyConApp codeCon [rep, m_ty, exp_ty]) } where err_msg ty = vcat [ text "Illegal polytype:" <+> ppr ty @@ -619,10 +619,10 @@ tcNestedSplice pop_stage (TcPending ps_var lie_var q@(QuoteWrapper _ m_var)) spl ; expr' <- setStage pop_stage $ setConstraintVar lie_var $ tcLExpr expr (mkCheckExpType meta_exp_ty) - ; untypeq <- tcLookupId unTypeQName + ; untypeCode <- tcLookupId unTypeCodeName ; let expr'' = mkHsApp (mkLHsWrap (applyQuoteWrapper q) - (nlHsTyApp untypeq [rep, res_ty])) expr' + (nlHsTyApp untypeCode [rep, res_ty])) expr' ; ps <- readMutVar ps_var ; writeMutVar ps_var (PendingTcSplice splice_name expr'' : ps) ===================================== docs/users_guide/exts/deriving_extra.rst ===================================== @@ -528,7 +528,7 @@ Deriving ``Lift`` instances The class ``Lift``, unlike other derivable classes, lives in ``template-haskell`` instead of ``base``. Having a data type be an instance of ``Lift`` permits its values to be promoted to Template Haskell expressions (of -type ``ExpQ`` and ``TExpQ a``), which can then be spliced into Haskell source +type ``ExpQ`` and ``Code Q a``), which can then be spliced into Haskell source code. Here is an example of how one can derive ``Lift``: ===================================== docs/users_guide/exts/template_haskell.rst ===================================== @@ -133,15 +133,15 @@ The :extension:`TemplateHaskellQuotes` extension is considered safe under is an arbitrary expression. A top-level typed expression splice can occur in place of an expression; the - spliced expression must have type ``Q (TExp a)`` + spliced expression must have type ``Code Q a`` - A *typed* expression quotation is written as ``[|| ... ||]``, or ``[e|| ... ||]``, where the "..." is an expression; if the "..." expression has type ``a``, then the quotation has type - ``Quote m => m (TExp a)``. + ``Quote m => Code m a``. - Values of type ``TExp a`` may be converted to values of type ``Exp`` - using the function ``unType :: TExp a -> Exp``. + It is possible to extract a value of type ``m Exp`` from ``Code m a`` + using the ``unTypeCode :: Code m a -> m Exp`` function. - A quasi-quotation can appear in a pattern, type, expression, or declaration context and is also written in Oxford brackets: @@ -202,7 +202,7 @@ The :extension:`TemplateHaskellQuotes` extension is considered safe under class Lift t where lift :: Quote m => t -> m Exp - liftTyped :: Quote m => t -> m (TExp t) + liftTyped :: Quote m => t -> Code m t In general, if GHC sees an expression within Oxford brackets (e.g., ``[| foo bar |]``, then GHC looks up each name within the brackets. If a name ===================================== libraries/template-haskell/Language/Haskell/TH.hs ===================================== @@ -50,6 +50,8 @@ module Language.Haskell.TH( -- * Typed expressions TExp, unType, + Code(..), unTypeCode, unsafeCodeCoerce, hoistCode, bindCode, + bindCode_, joinCode, liftCode, -- * Names Name, NameSpace, -- Abstract ===================================== libraries/template-haskell/Language/Haskell/TH/CodeDo.hs ===================================== @@ -0,0 +1,20 @@ +-- | This module exists to work nicely with the QualifiedDo +-- extension. +-- @ +-- import qualified Language.Haskell.TH.CodeDo as Code +-- myExample :: Monad m => Code m a -> Code m a -> Code m a +-- myExample opt1 opt2 = +-- Code.do +-- x <- someSideEffect -- This one is of type `M Bool` +-- if x then opt1 else opt2 +-- @ +module Language.Haskell.TH.CodeDo((>>=), (>>)) where + +import Language.Haskell.TH.Syntax +import Prelude(Monad) + +-- | Module over monad operator for 'Code' +(>>=) :: Monad m => m a -> (a -> Code m b) -> Code m b +(>>=) = bindCode +(>>) :: Monad m => m a -> Code m b -> Code m b +(>>) = bindCode_ ===================================== libraries/template-haskell/Language/Haskell/TH/Lib.hs ===================================== @@ -18,7 +18,7 @@ module Language.Haskell.TH.Lib ( -- * Library functions -- ** Abbreviations - InfoQ, ExpQ, TExpQ, DecQ, DecsQ, ConQ, TypeQ, KindQ, + InfoQ, ExpQ, TExpQ, CodeQ, DecQ, DecsQ, ConQ, TypeQ, KindQ, TyLitQ, CxtQ, PredQ, DerivClauseQ, MatchQ, ClauseQ, BodyQ, GuardQ, StmtQ, RangeQ, SourceStrictnessQ, SourceUnpackednessQ, BangQ, BangTypeQ, VarBangTypeQ, StrictTypeQ, VarStrictTypeQ, FieldExpQ, PatQ, ===================================== libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs ===================================== @@ -31,6 +31,7 @@ type PatQ = Q Pat type FieldPatQ = Q FieldPat type ExpQ = Q Exp type TExpQ a = Q (TExp a) +type CodeQ = Code Q type DecQ = Q Dec type DecsQ = Q [Dec] type Decs = [Dec] -- Defined as it is more convenient to wire-in ===================================== libraries/template-haskell/Language/Haskell/TH/Syntax.hs ===================================== @@ -343,6 +343,63 @@ be inferred (#8459). Consider The splice will evaluate to (MkAge 3) and you can't add that to 4::Int. So you can't coerce a (TExp Age) to a (TExp Int). -} +-- Code constructor + +type role Code representational nominal -- See Note [Role of TExp] +newtype Code m (a :: TYPE (r :: RuntimeRep)) = Code + { examineCode :: m (TExp a) -- ^ Underlying monadic value + } + +-- | Unsafely convert an untyped code representation into a typed code +-- representation. +unsafeCodeCoerce :: forall (r :: RuntimeRep) (a :: TYPE r) m . + Quote m => m Exp -> Code m a +unsafeCodeCoerce m = Code (unsafeTExpCoerce m) + +-- | Lift a monadic action producing code into the typed 'Code' +-- representation +liftCode :: forall (r :: RuntimeRep) (a :: TYPE r) m . m (TExp a) -> Code m a +liftCode = Code + +-- | Extract the untyped representation from the typed representation +unTypeCode :: forall (r :: RuntimeRep) (a :: TYPE r) m . Quote m + => Code m a -> m Exp +unTypeCode = unTypeQ . examineCode + +-- | Modify the ambient monad used during code generation. For example, you +-- can use `hoistCode` to handle a state effect: +-- @ +-- handleState :: Code (StateT Int Q) a -> Code Q a +-- handleState = hoistCode (flip runState 0) +-- @ +hoistCode :: forall m n (r :: RuntimeRep) (a :: TYPE r) . Monad m + => (forall x . m x -> n x) -> Code m a -> Code n a +hoistCode f (Code a) = Code (f a) + + +-- | Variant of (>>=) which allows effectful computations to be injected +-- into code generation. +bindCode :: forall m a (r :: RuntimeRep) (b :: TYPE r) . Monad m + => m a -> (a -> Code m b) -> Code m b +bindCode q k = liftCode (q >>= examineCode . k) + +-- | Variant of (>>) which allows effectful computations to be injected +-- into code generation. +bindCode_ :: forall m a (r :: RuntimeRep) (b :: TYPE r) . Monad m + => m a -> Code m b -> Code m b +bindCode_ q c = liftCode ( q >> examineCode c) + +-- | A useful combinator for embedding monadic actions into 'Code' +-- @ +-- myCode :: ... => Code m a +-- myCode = joinCode $ do +-- x <- someSideEffect +-- return (makeCodeWith x) +-- @ +joinCode :: forall m (r :: RuntimeRep) (a :: TYPE r) . Monad m + => m (Code m a) -> Code m a +joinCode = flip bindCode id + ---------------------------------------------------- -- Packaged versions for the programmer, hiding the Quasi-ness @@ -727,107 +784,107 @@ class Lift (t :: TYPE r) where -- a splice. lift :: Quote m => t -> m Exp default lift :: (r ~ 'LiftedRep, Quote m) => t -> m Exp - lift = unTypeQ . liftTyped + lift = unTypeCode . liftTyped -- | Turn a value into a Template Haskell typed expression, suitable for use -- in a typed splice. -- -- @since 2.16.0.0 - liftTyped :: Quote m => t -> m (TExp t) + liftTyped :: Quote m => t -> Code m t -- If you add any instances here, consider updating test th/TH_Lift instance Lift Integer where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL x)) instance Lift Int where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) -- | @since 2.16.0.0 instance Lift Int# where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntPrimL (fromIntegral (I# x)))) instance Lift Int8 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Int16 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Int32 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Int64 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) -- | @since 2.16.0.0 instance Lift Word# where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (WordPrimL (fromIntegral (W# x)))) instance Lift Word where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Word8 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Word16 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Word32 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Word64 where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Lift Natural where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (IntegerL (fromIntegral x))) instance Integral a => Lift (Ratio a) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (RationalL (toRational x))) instance Lift Float where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (RationalL (toRational x))) -- | @since 2.16.0.0 instance Lift Float# where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (FloatPrimL (toRational (F# x)))) instance Lift Double where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (RationalL (toRational x))) -- | @since 2.16.0.0 instance Lift Double# where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (DoublePrimL (toRational (D# x)))) instance Lift Char where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (CharL x)) -- | @since 2.16.0.0 instance Lift Char# where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (CharPrimL (C# x))) instance Lift Bool where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift True = return (ConE trueName) lift False = return (ConE falseName) @@ -837,24 +894,24 @@ instance Lift Bool where -- -- @since 2.16.0.0 instance Lift Addr# where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = return (LitE (StringPrimL (map (fromIntegral . ord) (unpackCString# x)))) instance Lift a => Lift (Maybe a) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift Nothing = return (ConE nothingName) lift (Just x) = liftM (ConE justName `AppE`) (lift x) instance (Lift a, Lift b) => Lift (Either a b) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (Left x) = liftM (ConE leftName `AppE`) (lift x) lift (Right y) = liftM (ConE rightName `AppE`) (lift y) instance Lift a => Lift [a] where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift xs = do { xs' <- mapM lift xs; return (ListE xs') } liftString :: Quote m => String -> m Exp @@ -863,7 +920,7 @@ liftString s = return (LitE (StringL s)) -- | @since 2.15.0.0 instance Lift a => Lift (NonEmpty a) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (x :| xs) = do x' <- lift x @@ -872,77 +929,77 @@ instance Lift a => Lift (NonEmpty a) where -- | @since 2.15.0.0 instance Lift Void where - liftTyped = pure . absurd + liftTyped = liftCode . absurd lift = pure . absurd instance Lift () where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift () = return (ConE (tupleDataName 0)) instance (Lift a, Lift b) => Lift (a, b) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (a, b) = liftM TupE $ sequence $ map (fmap Just) [lift a, lift b] instance (Lift a, Lift b, Lift c) => Lift (a, b, c) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (a, b, c) = liftM TupE $ sequence $ map (fmap Just) [lift a, lift b, lift c] instance (Lift a, Lift b, Lift c, Lift d) => Lift (a, b, c, d) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (a, b, c, d) = liftM TupE $ sequence $ map (fmap Just) [lift a, lift b, lift c, lift d] instance (Lift a, Lift b, Lift c, Lift d, Lift e) => Lift (a, b, c, d, e) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (a, b, c, d, e) = liftM TupE $ sequence $ map (fmap Just) [ lift a, lift b , lift c, lift d, lift e ] instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f) => Lift (a, b, c, d, e, f) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (a, b, c, d, e, f) = liftM TupE $ sequence $ map (fmap Just) [ lift a, lift b, lift c , lift d, lift e, lift f ] instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f, Lift g) => Lift (a, b, c, d, e, f, g) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (a, b, c, d, e, f, g) = liftM TupE $ sequence $ map (fmap Just) [ lift a, lift b, lift c , lift d, lift e, lift f, lift g ] -- | @since 2.16.0.0 instance Lift (# #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# #) = return (ConE (unboxedTupleTypeName 0)) -- | @since 2.16.0.0 instance (Lift a) => Lift (# a #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# a #) = liftM UnboxedTupE $ sequence $ map (fmap Just) [lift a] -- | @since 2.16.0.0 instance (Lift a, Lift b) => Lift (# a, b #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# a, b #) = liftM UnboxedTupE $ sequence $ map (fmap Just) [lift a, lift b] -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c) => Lift (# a, b, c #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# a, b, c #) = liftM UnboxedTupE $ sequence $ map (fmap Just) [lift a, lift b, lift c] -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d) => Lift (# a, b, c, d #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# a, b, c, d #) = liftM UnboxedTupE $ sequence $ map (fmap Just) [ lift a, lift b , lift c, lift d ] @@ -950,7 +1007,7 @@ instance (Lift a, Lift b, Lift c, Lift d) -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d, Lift e) => Lift (# a, b, c, d, e #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# a, b, c, d, e #) = liftM UnboxedTupE $ sequence $ map (fmap Just) [ lift a, lift b , lift c, lift d, lift e ] @@ -958,7 +1015,7 @@ instance (Lift a, Lift b, Lift c, Lift d, Lift e) -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f) => Lift (# a, b, c, d, e, f #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# a, b, c, d, e, f #) = liftM UnboxedTupE $ sequence $ map (fmap Just) [ lift a, lift b, lift c , lift d, lift e, lift f ] @@ -966,7 +1023,7 @@ instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f) -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f, Lift g) => Lift (# a, b, c, d, e, f, g #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift (# a, b, c, d, e, f, g #) = liftM UnboxedTupE $ sequence $ map (fmap Just) [ lift a, lift b, lift c , lift d, lift e, lift f @@ -974,7 +1031,7 @@ instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f, Lift g) -- | @since 2.16.0.0 instance (Lift a, Lift b) => Lift (# a | b #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = case x of (# y | #) -> UnboxedSumE <$> lift y <*> pure 1 <*> pure 2 @@ -983,7 +1040,7 @@ instance (Lift a, Lift b) => Lift (# a | b #) where -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c) => Lift (# a | b | c #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = case x of (# y | | #) -> UnboxedSumE <$> lift y <*> pure 1 <*> pure 3 @@ -993,7 +1050,7 @@ instance (Lift a, Lift b, Lift c) -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d) => Lift (# a | b | c | d #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = case x of (# y | | | #) -> UnboxedSumE <$> lift y <*> pure 1 <*> pure 4 @@ -1004,7 +1061,7 @@ instance (Lift a, Lift b, Lift c, Lift d) -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d, Lift e) => Lift (# a | b | c | d | e #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = case x of (# y | | | | #) -> UnboxedSumE <$> lift y <*> pure 1 <*> pure 5 @@ -1016,7 +1073,7 @@ instance (Lift a, Lift b, Lift c, Lift d, Lift e) -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f) => Lift (# a | b | c | d | e | f #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = case x of (# y | | | | | #) -> UnboxedSumE <$> lift y <*> pure 1 <*> pure 6 @@ -1029,7 +1086,7 @@ instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f) -- | @since 2.16.0.0 instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f, Lift g) => Lift (# a | b | c | d | e | f | g #) where - liftTyped x = unsafeTExpCoerce (lift x) + liftTyped x = unsafeCodeCoerce (lift x) lift x = case x of (# y | | | | | | #) -> UnboxedSumE <$> lift y <*> pure 1 <*> pure 7 ===================================== libraries/template-haskell/changelog.md ===================================== @@ -1,6 +1,9 @@ # Changelog for [`template-haskell` package](http://hackage.haskell.org/package/template-haskell) ## 2.17.0.0 + * Typed Quotations now return a value of type `Code m a` (GHC Proposal #195). + The main motiviation is to make writing instances easier and make it easier to + store `Code` values in type-indexed maps. * Implement Overloaded Quotations (GHC Proposal #246). This patch modifies a few fundamental things in the API. All the library combinators are generalised @@ -9,7 +12,7 @@ written in terms of `Q` are now disallowed. The types of `unsafeTExpCoerce` and `unTypeQ` are also generalised in terms of `Quote` rather than specific to `Q`. - + * Implement Explicit specificity in type variable binders (GHC Proposal #99). In `Language.Haskell.TH.Syntax`, `TyVarBndr` is now annotated with a `flag`, denoting the additional argument to its constructors `PlainTV` and `KindedTV`. ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -48,7 +48,7 @@ Library Language.Haskell.TH.Quote Language.Haskell.TH.Syntax Language.Haskell.TH.LanguageExtensions - + Language.Haskell.TH.CodeDo Language.Haskell.TH.Lib.Internal other-modules: ===================================== libraries/text ===================================== @@ -1 +1 @@ -Subproject commit a01843250166b5559936ba5eb81f7873e709587a +Subproject commit 74f835751b60b312d01dd600d516756d5325d514 ===================================== testsuite/tests/quotes/T17857.hs ===================================== @@ -7,4 +7,4 @@ import Language.Haskell.TH.Syntax data T = MkT deriving Data instance Lift T where lift = liftData - liftTyped = unsafeTExpCoerce . lift + liftTyped = unsafeCodeCoerce . lift ===================================== testsuite/tests/th/T10945.stderr ===================================== @@ -1,8 +1,8 @@ T10945.hs:7:4: error: - • Couldn't match type ‘[Dec]’ with ‘TExp DecsQ’ - Expected type: Q (TExp DecsQ) - Actual type: Q [Dec] + • Couldn't match type ‘[Dec]’ with ‘Q [Dec]’ + Expected type: Code Q DecsQ + Actual type: Code Q [Dec] • In the expression: return [SigD ===================================== testsuite/tests/th/T15471A.hs ===================================== @@ -6,9 +6,9 @@ import Language.Haskell.TH foo1 x = x -test_foo :: Q (TExp (a -> a)) +test_foo :: Code Q (a -> a) test_foo = [|| foo1 ||] -list_foo :: Q (TExp a) -> Q (TExp [a]) +list_foo :: Code Q a -> Code Q [a] list_foo x = [|| [ $$x, $$x ] ||] ===================================== testsuite/tests/th/T15843.hs ===================================== @@ -13,12 +13,12 @@ main = do mapM_ (\q -> runQ q >>= ppr_and_show) [first_of_2, second_of_2, empty_2, full_2, third_of_3] - mapM_ (\q -> runQ (fmap unType q) >>= ppr_and_show) + mapM_ (\q -> (runQ (unTypeCode q)) >>= ppr_and_show) [first_of_2_T, second_of_2_T] - runQ (fmap unType empty_2_T) >>= ppr_and_show - runQ (fmap unType full_2_T) >>= ppr_and_show - runQ (fmap unType third_of_3_T) >>= ppr_and_show + runQ (unTypeCode empty_2_T) >>= ppr_and_show + runQ (unTypeCode full_2_T) >>= ppr_and_show + runQ (unTypeCode third_of_3_T) >>= ppr_and_show print $ "(909,) applied to 'c' should be (909, 'c') ===> " ++ (show $ (909, 'c') == ($first_of_2 'c')) ===================================== testsuite/tests/th/T16195A.hs ===================================== @@ -3,11 +3,11 @@ module T16195A where import Language.Haskell.TH -foo :: Q (TExp (IO ())) +foo :: Code Q (IO ()) foo = [|| return () ||] -showC :: Q (TExp (() -> String)) +showC :: Code Q (() -> String) showC = [|| show ||] -unitC :: Q (TExp ()) +unitC :: Code Q () unitC = [|| () ||] ===================================== testsuite/tests/th/T18121.hs ===================================== @@ -3,5 +3,5 @@ module Bug where import Language.Haskell.TH -sapply :: Q (TExp (a -> b)) -> Q (TExp a) -> Q (TExp b) +sapply :: Quote m => Code m (a -> b) -> Code m a -> Code m b sapply cf cx = [|| $$cf $$cx ||] ===================================== testsuite/tests/th/T8577.stderr ===================================== @@ -1,8 +1,8 @@ T8577.hs:9:11: error: • Couldn't match type ‘Int’ with ‘Bool’ - Expected type: Q (TExp (A Bool)) - Actual type: Q (TExp (A Int)) + Expected type: Code Q (A Bool) + Actual type: Code Q (A Int) • In the expression: y In the Template Haskell splice $$(y) In the expression: $$(y) ===================================== testsuite/tests/th/T8577a.hs ===================================== @@ -4,8 +4,8 @@ import Language.Haskell.TH data A a = A -x :: Q (TExp (A a)) +x :: Code Q (A a) x = [|| A ||] -y :: Q (TExp (A Int)) +y :: Code Q (A Int) y = x ===================================== testsuite/tests/th/TH_StringLift.hs ===================================== @@ -3,7 +3,7 @@ module TH_StringLift where import Language.Haskell.TH.Syntax -foo :: Quote m => String -> m (TExp String) +foo :: Quote m => String -> Code m String foo x = [|| x ||] foo2 :: Quote m => String -> m Exp ===================================== testsuite/tests/th/TH_reifyLocalDefs.hs ===================================== @@ -29,8 +29,8 @@ main = print (f 1 "", g 'a' 2, h True 3) ) , xg :: Char ) - h xh y = ( $$(do printTypeOf("xh") - [|| y :: Int ||] + h xh y = ( $$(liftCode $ do printTypeOf("xh") + examineCode [|| y :: Int ||] ) , xh :: Bool ) ===================================== testsuite/tests/th/overloaded/T17839.hs ===================================== @@ -16,7 +16,7 @@ import Data.Functor.Identity type LetT m a = WriterT [Locus] m a -type Code m a = m (TExp a) +type MCode m a = m (TExp a) type LetCode m a = LetT m (TExp a) @@ -29,7 +29,7 @@ instance (Monoid w, Quote m) => Quote (StateT w m) where newName x = W.lift (newName x) -locus :: (Locus -> LetCode m a) -> Code m a +locus :: (Locus -> LetCode m a) -> MCode m a locus = undefined newTypedName :: Quote m => m (TExp a) @@ -38,15 +38,15 @@ newTypedName = do return (TExp (VarE n)) -gen :: Quote m => Locus -> (Code Identity (a -> b) -> LetCode m a -> LetCode m b) -> LetCode m (a -> b) +gen :: Quote m => Locus -> (MCode Identity (a -> b) -> LetCode m a -> LetCode m b) -> LetCode m (a -> b) gen l f = do n <- newTypedName - [|| \a -> $$(f (Identity n) [|| a ||]) ||] + examineCode [|| \a -> $$(liftCode $ f (Identity n) (examineCode [|| a ||])) ||] mrfix :: forall a b m r . (Monad m, Ord a, Quote m) - => (forall m . (a -> Code m (b -> r)) -> (a -> Code m b -> Code m r)) - -> (a -> Code m (b -> r)) + => (forall m . (a -> MCode m (b -> r)) -> (a -> MCode m b -> MCode m r)) + -> (a -> MCode m (b -> r)) mrfix f x = flip evalStateT Map.empty $ locus $ \locus -> do ===================================== testsuite/tests/th/overloaded/TH_overloaded_constraints.hs ===================================== @@ -22,11 +22,11 @@ dq = [| 5 |] top_level :: (C m, D m, Quote m) => m Exp top_level = [| $cq + $dq |] -cqt :: (C m, Quote m) => m (TExp Int) +cqt :: (C m, Quote m) => Code m Int cqt = [|| 5 ||] -dqt :: (D m, Quote m) => m (TExp Int) +dqt :: (D m, Quote m) => Code m Int dqt = [|| 5 ||] -top_level_t :: (C m, D m, Quote m) => m (TExp Int) +top_level_t :: (C m, D m, Quote m) => Code m Int top_level_t = [|| $$cqt + $$dqt ||] ===================================== testsuite/tests/th/overloaded/TH_overloaded_csp.hs ===================================== @@ -14,5 +14,5 @@ instance Quote Identity where main = do print $ runIdentity ((\x -> [| x |]) ()) - print $ unType $ runIdentity ((\x -> [|| x ||]) ()) + print $ runIdentity $ unTypeCode ((\x -> [|| x ||]) ()) ===================================== testsuite/tests/th/overloaded/TH_overloaded_extract.hs ===================================== @@ -19,5 +19,5 @@ main = do print $ runIdentity [d| data Foo = Foo |] print $ runIdentity [p| () |] print $ runIdentity [t| [Int] |] - print $ unType $ runIdentity [|| (+1) ||] + print $ runIdentity $ unTypeCode [|| (+1) ||] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/74a756df27f5e5ae9b4486bfbabaf1eac2d188f0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/74a756df27f5e5ae9b4486bfbabaf1eac2d188f0 You're receiving 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 27 12:18:32 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Wed, 27 May 2020 08:18:32 -0400 Subject: [Git][ghc/ghc][wip/always-use-rnImplicitBndrs] Always use rnImplicitBndrs to bring implicit tyvars into scope Message-ID: <5ece5a9881824_6e263f9eef640398189321b@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/always-use-rnImplicitBndrs at Glasgow Haskell Compiler / GHC Commits: 285f2817 by Ryan Scott at 2020-05-27T08:16:59-04:00 Always use rnImplicitBndrs to bring implicit tyvars into scope This implements a first step towards #16762 by changing the renamer to always use `rnImplicitBndrs` to bring implicitly bound type variables into scope. The main change is in `rnFamInstEqn` and `bindHsQTyVars`, which previously used _ad hoc_ methods of binding their implicit tyvars. There are a number of knock-on consequences: * One of the reasons that `rnFamInstEqn` used an _ad hoc_ binding mechanism was to give more precise source locations in `-Wunused-type-patterns` warnings. (See https://gitlab.haskell.org/ghc/ghc/issues/16762#note_273343 for an example of this.) However, these warnings are actually a little _too_ precise, since implicitly bound type variables don't have exact binding sites like explicitly bound type variables do. A similar problem existed for "`Different names for the same type variable`" errors involving implicit tyvars bound by `bindHsQTyVars`. Therefore, we simply accept the less precise (but more accurate) source locations from `rnImplicitBndrs` in `rnFamInstEqn` and `bindHsQTyVars`. See `Note [Source locations for implicitly bound type variables]` in `GHC.Rename.HsType` for the full story. * In order for `rnImplicitBndrs` to work in `rnFamInstEqn`, it needs to be able to look up names from the parent class (in the event that we are renaming an associated type family instance). As a result, `rnImplicitBndrs` now takes an argument of type `Maybe assoc`, which is `Just` in the event that a type family instance is associated with a class. * Previously, GHC kept track of three type synonyms for free type variables in the renamer: `FreeKiTyVars`, `FreeKiTyVarsDups` (which are allowed to contain duplicates)`, and `FreeKiTyVarsNoDups` (which contain no duplicates). However, making is a distinction between `-Dups` and `-NoDups` is now pointless, as all code that returns `FreeKiTyVars{,Dups,NoDups}` will eventually end up being passed to `rnImplicitBndrs`, which removes duplicates. As a result, I decided to just get rid of `FreeKiTyVarsDups` and `FreeKiTyVarsNoDups`, leaving only `FreeKiTyVars`. * The `bindLRdrNames` and `deleteBys` functions are now dead code, so I took the liberty of removing them. - - - - - 15 changed files: - compiler/GHC/Data/List/SetOps.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Tc/Gen/Splice.hs - testsuite/tests/indexed-types/should_compile/ExplicitForAllFams2.stderr - testsuite/tests/indexed-types/should_compile/T16356_Compile2.stderr - testsuite/tests/indexed-types/should_compile/T16632.stderr - testsuite/tests/indexed-types/should_compile/UnusedTyVarWarnings.stderr - testsuite/tests/indexed-types/should_compile/UnusedTyVarWarningsNamedWCs.stderr - testsuite/tests/indexed-types/should_fail/T17008a.stderr - testsuite/tests/indexed-types/should_fail/T7536.stderr - testsuite/tests/polykinds/T11203.stderr - testsuite/tests/polykinds/T11821a.stderr - testsuite/tests/typecheck/should_fail/T17566b.stderr - testsuite/tests/typecheck/should_fail/T17566c.stderr Changes: ===================================== compiler/GHC/Data/List/SetOps.hs ===================================== @@ -10,7 +10,7 @@ -- -- Avoid using them as much as possible module GHC.Data.List.SetOps ( - unionLists, minusList, deleteBys, + unionLists, minusList, -- Association lists Assoc, assoc, assocMaybe, assocUsing, assocDefault, assocDefaultUsing, @@ -39,11 +39,6 @@ getNth :: Outputable a => [a] -> Int -> a getNth xs n = ASSERT2( xs `lengthExceeds` n, ppr n $$ ppr xs ) xs !! n -deleteBys :: (a -> a -> Bool) -> [a] -> [a] -> [a] --- (deleteBys eq xs ys) returns xs-ys, using the given equality function --- Just like 'Data.List.delete' but with an equality function -deleteBys eq xs ys = foldl' (flip (L.deleteBy eq)) xs ys - {- ************************************************************************ * * ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -24,11 +24,11 @@ module GHC.Rename.HsType ( -- Binding related stuff bindLHsTyVarBndr, bindLHsTyVarBndrs, rnImplicitBndrs, - bindSigTyVarsFV, bindHsQTyVars, bindLRdrNames, + bindSigTyVarsFV, bindHsQTyVars, + FreeKiTyVars, extractHsTyRdrTyVars, extractHsTyRdrTyVarsKindVars, - extractHsTysRdrTyVarsDups, - extractRdrKindSigVars, extractDataDefnKindVars, - extractHsTvBndrs, extractHsTyArgRdrKiTyVarsDup, + extractHsTysRdrTyVars, extractRdrKindSigVars, extractDataDefnKindVars, + extractHsTvBndrs, extractHsTyArgRdrKiTyVars, forAllOrNothing, nubL ) where @@ -56,7 +56,6 @@ import GHC.Types.Name.Set import GHC.Types.FieldLabel import GHC.Utils.Misc -import GHC.Data.List.SetOps ( deleteBys ) import GHC.Types.Basic ( compareFixity, funTyFixity, negateFixity , Fixity(..), FixityDirection(..), LexicalFixity(..) , TypeOrKind(..) ) @@ -164,14 +163,14 @@ rn_hs_sig_wc_type :: HsSigWcTypeScoping -> HsDocContext -> Maybe SDoc -> RnM (a, FreeVars) rn_hs_sig_wc_type scoping ctxt inf_err hs_ty thing_inside = do { check_inferred_vars ctxt inf_err hs_ty - ; free_vars <- filterInScopeM (extractHsTyRdrTyVarsDups hs_ty) + ; free_vars <- filterInScopeM (extractHsTyRdrTyVars hs_ty) ; (nwc_rdrs', tv_rdrs) <- partition_nwcs free_vars ; let nwc_rdrs = nubL nwc_rdrs' ; implicit_bndrs <- case scoping of AlwaysBind -> pure tv_rdrs BindUnlessForall -> forAllOrNothing (isLHsForAllTy hs_ty) tv_rdrs NeverBind -> pure [] - ; rnImplicitBndrs implicit_bndrs $ \ vars -> + ; rnImplicitBndrs Nothing implicit_bndrs $ \ vars -> do { (wcs, hs_ty', fvs1) <- rnWcBody ctxt nwc_rdrs hs_ty ; (res, fvs2) <- thing_inside wcs vars hs_ty' ; return (res, fvs1 `plusFV` fvs2) } } @@ -179,7 +178,8 @@ rn_hs_sig_wc_type scoping ctxt inf_err hs_ty thing_inside rnHsWcType :: HsDocContext -> LHsWcType GhcPs -> RnM (LHsWcType GhcRn, FreeVars) rnHsWcType ctxt (HsWC { hswc_body = hs_ty }) = do { free_vars <- filterInScopeM (extractHsTyRdrTyVars hs_ty) - ; (nwc_rdrs, _) <- partition_nwcs free_vars + ; (nwc_rdrs', _) <- partition_nwcs free_vars + ; let nwc_rdrs = nubL nwc_rdrs' ; (wcs, hs_ty', fvs) <- rnWcBody ctxt nwc_rdrs hs_ty ; let sig_ty' = HsWC { hswc_ext = wcs, hswc_body = hs_ty' } ; return (sig_ty', fvs) } @@ -328,8 +328,8 @@ rnHsSigType ctx level inf_err (HsIB { hsib_body = hs_ty }) ; check_inferred_vars ctx inf_err hs_ty ; vars0 <- forAllOrNothing (isLHsForAllTy hs_ty) $ filterInScope rdr_env - $ extractHsTyRdrTyVarsDups hs_ty - ; rnImplicitBndrs vars0 $ \ vars -> + $ extractHsTyRdrTyVars hs_ty + ; rnImplicitBndrs Nothing vars0 $ \ vars -> do { (body', fvs) <- rnLHsTyKi (mkTyKiEnv ctx level RnTypeBody) hs_ty ; return ( HsIB { hsib_ext = vars @@ -357,9 +357,9 @@ forAllOrNothing :: Bool -- we do not want to bring 'b' into scope, hence True -- But f :: a -> b -- we want to bring both 'a' and 'b' into scope, hence False - -> FreeKiTyVarsWithDups + -> FreeKiTyVars -- ^ Free vars of the type - -> RnM FreeKiTyVarsWithDups + -> RnM FreeKiTyVars forAllOrNothing has_outer_forall fvs = case has_outer_forall of True -> do traceRn "forAllOrNothing" $ text "has explicit outer forall" @@ -368,24 +368,50 @@ forAllOrNothing has_outer_forall fvs = case has_outer_forall of traceRn "forAllOrNothing" $ text "no explicit forall. implicit binders:" <+> ppr fvs pure fvs -rnImplicitBndrs :: FreeKiTyVarsWithDups +rnImplicitBndrs :: Maybe assoc + -- ^ @'Just' _@ => an associated type decl + -> FreeKiTyVars -- ^ Surface-syntax free vars that we will implicitly bind. - -- May have duplicates, which is checked here + -- May have duplicates, which are removed here. -> ([Name] -> RnM (a, FreeVars)) -> RnM (a, FreeVars) -rnImplicitBndrs implicit_vs_with_dups - thing_inside +rnImplicitBndrs mb_assoc implicit_vs_with_dups thing_inside = do { let implicit_vs = nubL implicit_vs_with_dups ; traceRn "rnImplicitBndrs" $ vcat [ ppr implicit_vs_with_dups, ppr implicit_vs ] + -- Use the currently set SrcSpan as the new source location for each Name. + -- See Note [Source locations for implicitly bound type variables]. ; loc <- getSrcSpanM - ; vars <- mapM (newLocalBndrRn . L loc . unLoc) implicit_vs + ; vars <- mapM (newTyVarNameRn mb_assoc . L loc . unLoc) implicit_vs ; bindLocalNamesFV vars $ thing_inside vars } +{- +Note [Source locations for implicitly bound type variables] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When bringing implicitly bound type variables into scope (in rnImplicitBndrs), +we do something peculiar: we drop the original SrcSpan attached to each +variable and replace it with the currently set SrcSpan. Moreover, this new +SrcSpan is usually /less/ precise than the original one, and that's OK. To see +why this is done, consider the following example: + + f :: a -> b -> a + +Suppose that a warning or error message needs to point to the SrcSpans of the +binding sites for `a` and `b`. But where /are/ they bound, anyway? Technically, +they're bound by an unwritten `forall` at the front of the type signature, but +there is no SrcSpan for that. We could point to the first occurrence of `a` as +the binding site for `a`, but that would make the first occurrence of `a` +special. Moreover, we don't want IDEs to confuse binding sites and occurrences. + +As a result, we make the `SrcSpan`s for `a` and `b` span the entirety of the +type signature, since the type signature implicitly carries their binding +sites. This is less precise, but more accurate. +-} + check_inferred_vars :: HsDocContext -> Maybe SDoc -- ^ The error msg if the signature is not allowed to contain @@ -831,24 +857,13 @@ bindSigTyVarsFV tvs thing_inside else bindLocalNamesFV tvs thing_inside } --- | Simply bring a bunch of RdrNames into scope. No checking for --- validity, at all. The binding location is taken from the location --- on each name. -bindLRdrNames :: [Located RdrName] - -> ([Name] -> RnM (a, FreeVars)) - -> RnM (a, FreeVars) -bindLRdrNames rdrs thing_inside - = do { var_names <- mapM (newTyVarNameRn Nothing) rdrs - ; bindLocalNamesFV var_names $ - thing_inside var_names } - --------------- bindHsQTyVars :: forall a b. HsDocContext -> Maybe SDoc -- Just d => check for unused tvs -- d is a phrase like "in the type ..." -> Maybe a -- Just _ => an associated type decl - -> [Located RdrName] -- Kind variables from scope, no dups + -> FreeKiTyVars -- Kind variables from scope -> (LHsQTyVars GhcPs) -> (LHsQTyVars GhcRn -> Bool -> RnM (b, FreeVars)) -- The Bool is True <=> all kind variables used in the @@ -871,10 +886,10 @@ bindHsQTyVars doc mb_in_doc mb_assoc body_kv_occs hsq_bndrs thing_inside -- all these various things are doing bndrs, implicit_kvs :: [Located RdrName] bndrs = map hsLTyVarLocName hs_tv_bndrs - implicit_kvs = nubL $ filterFreeVarsToBind bndrs $ + implicit_kvs = filterFreeVarsToBind bndrs $ bndr_kv_occs ++ body_kv_occs - del = deleteBys eqLocated - body_remaining = (body_kv_occs `del` bndrs) `del` bndr_kv_occs + body_remaining = filterFreeVarsToBind bndr_kv_occs $ + filterFreeVarsToBind bndrs body_kv_occs all_bound_on_lhs = null body_remaining ; traceRn "checkMixedVars3" $ @@ -885,9 +900,7 @@ bindHsQTyVars doc mb_in_doc mb_assoc body_kv_occs hsq_bndrs thing_inside , text "body_remaining" <+> ppr body_remaining ] - ; implicit_kv_nms <- mapM (newTyVarNameRn mb_assoc) implicit_kvs - - ; bindLocalNamesFV implicit_kv_nms $ + ; rnImplicitBndrs mb_assoc implicit_kvs $ \ implicit_kv_nms -> bindLHsTyVarBndrs doc mb_in_doc mb_assoc hs_tv_bndrs $ \ rn_bndrs -> do { traceRn "bindHsQTyVars" (ppr hsq_bndrs $$ ppr implicit_kv_nms $$ ppr rn_bndrs) ; thing_inside (HsQTvs { hsq_ext = implicit_kv_nms @@ -909,12 +922,12 @@ Then: body_kv_occs = [k2,k1], kind variables free in the result kind signature - implicit_kvs = [k1,k2], kind variables free in kind signatures - of hs_tv_bndrs, and not bound by bndrs + implicit_kvs = [k1,k2,k1], kind variables free in kind signatures + of hs_tv_bndrs, and not bound by bndrs * We want to quantify add implicit bindings for implicit_kvs -* If implicit_body_kvs is non-empty, then there is a kind variable +* If body_kv_occs is non-empty, then there is a kind variable mentioned in the kind signature that is not bound "on the left". That's one of the rules for a CUSK, so we pass that info on as the second argument to thing_inside. @@ -922,6 +935,9 @@ Then: * Order is not important in these lists. All we are doing is bring Names into scope. +* bndr_kv_occs, body_kv_occs, and implicit_kvs can contain duplicates. All + duplicate occurrences are removed when we bind them with rnImplicitBndrs. + Finally, you may wonder why filterFreeVarsToBind removes in-scope variables from bndr/body_kv_occs. How can anything be in scope? Answer: HsQTyVars is /also/ used (slightly oddly) for Haskell-98 syntax @@ -1040,14 +1056,15 @@ bindLHsTyVarBndr doc mb_assoc (L loc (KindedTyVar x fl lrdr@(L lv _) kind)) $ thing_inside (L loc (KindedTyVar x fl (L lv tv_nm) kind')) ; return (b, fvs1 `plusFV` fvs2) } -newTyVarNameRn :: Maybe a -> Located RdrName -> RnM Name -newTyVarNameRn mb_assoc (L loc rdr) +newTyVarNameRn :: Maybe a -- associated class + -> Located RdrName -> RnM Name +newTyVarNameRn mb_assoc lrdr@(L _ rdr) = do { rdr_env <- getLocalRdrEnv ; case (mb_assoc, lookupLocalRdrEnv rdr_env rdr) of (Just _, Just n) -> return n -- Use the same Name as the parent class decl - _ -> newLocalBndrRn (L loc rdr) } + _ -> newLocalBndrRn lrdr } {- ********************************************************* * * @@ -1504,7 +1521,10 @@ To do that, we need to walk over a type and find its free type/kind variables. We preserve the left-to-right order of each variable occurrence. See Note [Ordering of implicit variables]. -Clients of this code can remove duplicates with nubL. +It is common for lists of free type variables to contain duplicates. For +example, in `f :: a -> a`, the free type variable list is [a, a]. When these +implicitly bound variables are brought into scope (with rnImplicitBndrs), +duplicates are removed with nubL. Note [Ordering of implicit variables] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1533,9 +1553,8 @@ the a in the code. Thus, GHC does ScopedSort on the variables. See Note [ScopedSort] in GHC.Core.Type. Implicitly bound variables are collected by any function which returns a -FreeKiTyVars, FreeKiTyVarsWithDups, or FreeKiTyVarsNoDups, which notably -includes the `extract-` family of functions (extractHsTysRdrTyVarsDups, -extractHsTyVarBndrsKVs, etc.). +FreeKiTyVars, which notably includes the `extract-` family of functions +(extractHsTysRdrTyVars, extractHsTyVarBndrsKVs, etc.). These functions thus promise to keep left-to-right ordering. Note [Implicit quantification in type synonyms] @@ -1621,18 +1640,13 @@ type checking. While viable, this would mean we'd end up accepting this: -} +-- A list of free type/kind variables, which can contain duplicates. -- See Note [Kind and type-variable binders] -- These lists are guaranteed to preserve left-to-right ordering of -- the types the variables were extracted from. See also -- Note [Ordering of implicit variables]. type FreeKiTyVars = [Located RdrName] --- | A 'FreeKiTyVars' list that is allowed to have duplicate variables. -type FreeKiTyVarsWithDups = FreeKiTyVars - --- | A 'FreeKiTyVars' list that contains no duplicate variables. -type FreeKiTyVarsNoDups = FreeKiTyVars - -- | Filter out any type and kind variables that are already in scope in the -- the supplied LocalRdrEnv. Note that this includes named wildcards, which -- look like perfectly ordinary type variables at this point. @@ -1650,46 +1664,32 @@ filterInScopeM vars inScope :: LocalRdrEnv -> RdrName -> Bool inScope rdr_env rdr = rdr `elemLocalRdrEnv` rdr_env -extract_tyarg :: LHsTypeArg GhcPs -> FreeKiTyVarsWithDups -> FreeKiTyVarsWithDups +extract_tyarg :: LHsTypeArg GhcPs -> FreeKiTyVars -> FreeKiTyVars extract_tyarg (HsValArg ty) acc = extract_lty ty acc extract_tyarg (HsTypeArg _ ki) acc = extract_lty ki acc extract_tyarg (HsArgPar _) acc = acc -extract_tyargs :: [LHsTypeArg GhcPs] -> FreeKiTyVarsWithDups -> FreeKiTyVarsWithDups +extract_tyargs :: [LHsTypeArg GhcPs] -> FreeKiTyVars -> FreeKiTyVars extract_tyargs args acc = foldr extract_tyarg acc args -extractHsTyArgRdrKiTyVarsDup :: [LHsTypeArg GhcPs] -> FreeKiTyVarsWithDups -extractHsTyArgRdrKiTyVarsDup args +extractHsTyArgRdrKiTyVars :: [LHsTypeArg GhcPs] -> FreeKiTyVars +extractHsTyArgRdrKiTyVars args = extract_tyargs args [] -- | 'extractHsTyRdrTyVars' finds the type/kind variables -- of a HsType/HsKind. -- It's used when making the @forall at s explicit. --- When the same name occurs multiple times in the types, only the first --- occurrence is returned. -- See Note [Kind and type-variable binders] -extractHsTyRdrTyVars :: LHsType GhcPs -> FreeKiTyVarsNoDups -extractHsTyRdrTyVars ty - = nubL (extractHsTyRdrTyVarsDups ty) - --- | 'extractHsTyRdrTyVarsDups' finds the type/kind variables --- of a HsType/HsKind. --- It's used when making the @forall at s explicit. --- When the same name occurs multiple times in the types, all occurrences --- are returned. -extractHsTyRdrTyVarsDups :: LHsType GhcPs -> FreeKiTyVarsWithDups -extractHsTyRdrTyVarsDups ty - = extract_lty ty [] +extractHsTyRdrTyVars :: LHsType GhcPs -> FreeKiTyVars +extractHsTyRdrTyVars ty = extract_lty ty [] -- | Extracts the free type/kind variables from the kind signature of a HsType. -- This is used to implicitly quantify over @k@ in @type T = Nothing :: Maybe k at . --- When the same name occurs multiple times in the type, only the first --- occurrence is returned, and the left-to-right order of variables is --- preserved. +-- The left-to-right order of variables is preserved. -- See Note [Kind and type-variable binders] and -- Note [Ordering of implicit variables] and -- Note [Implicit quantification in type synonyms]. -extractHsTyRdrTyVarsKindVars :: LHsType GhcPs -> FreeKiTyVarsNoDups +extractHsTyRdrTyVarsKindVars :: LHsType GhcPs -> FreeKiTyVars extractHsTyRdrTyVarsKindVars (L _ ty) = case ty of HsParTy _ ty -> extractHsTyRdrTyVarsKindVars ty @@ -1699,51 +1699,45 @@ extractHsTyRdrTyVarsKindVars (L _ ty) = -- | Extracts free type and kind variables from types in a list. -- When the same name occurs multiple times in the types, all occurrences -- are returned. -extractHsTysRdrTyVarsDups :: [LHsType GhcPs] -> FreeKiTyVarsWithDups -extractHsTysRdrTyVarsDups tys - = extract_ltys tys [] +extractHsTysRdrTyVars :: [LHsType GhcPs] -> FreeKiTyVars +extractHsTysRdrTyVars tys = extract_ltys tys [] -- Returns the free kind variables of any explicitly-kinded binders, returning -- variable occurrences in left-to-right order. -- See Note [Ordering of implicit variables]. -- NB: Does /not/ delete the binders themselves. --- However duplicates are removed -- E.g. given [k1, a:k1, b:k2] -- the function returns [k1,k2], even though k1 is bound here -extractHsTyVarBndrsKVs :: [LHsTyVarBndr flag GhcPs] -> FreeKiTyVarsNoDups -extractHsTyVarBndrsKVs tv_bndrs - = nubL (extract_hs_tv_bndrs_kvs tv_bndrs) +extractHsTyVarBndrsKVs :: [LHsTyVarBndr flag GhcPs] -> FreeKiTyVars +extractHsTyVarBndrsKVs tv_bndrs = extract_hs_tv_bndrs_kvs tv_bndrs -- Returns the free kind variables in a type family result signature, returning -- variable occurrences in left-to-right order. -- See Note [Ordering of implicit variables]. -extractRdrKindSigVars :: LFamilyResultSig GhcPs -> [Located RdrName] +extractRdrKindSigVars :: LFamilyResultSig GhcPs -> FreeKiTyVars extractRdrKindSigVars (L _ resultSig) = case resultSig of KindSig _ k -> extractHsTyRdrTyVars k TyVarSig _ (L _ (KindedTyVar _ _ _ k)) -> extractHsTyRdrTyVars k _ -> [] -- | Get type/kind variables mentioned in the kind signature, preserving --- left-to-right order and without duplicates: +-- left-to-right order: -- -- * data T a (b :: k1) :: k2 -> k1 -> k2 -> Type -- result: [k2,k1] -- * data T a (b :: k1) -- result: [] -- -- See Note [Ordering of implicit variables]. -extractDataDefnKindVars :: HsDataDefn GhcPs -> FreeKiTyVarsNoDups +extractDataDefnKindVars :: HsDataDefn GhcPs -> FreeKiTyVars extractDataDefnKindVars (HsDataDefn { dd_kindSig = ksig }) = maybe [] extractHsTyRdrTyVars ksig -extract_lctxt :: LHsContext GhcPs - -> FreeKiTyVarsWithDups -> FreeKiTyVarsWithDups +extract_lctxt :: LHsContext GhcPs -> FreeKiTyVars -> FreeKiTyVars extract_lctxt ctxt = extract_ltys (unLoc ctxt) -extract_ltys :: [LHsType GhcPs] - -> FreeKiTyVarsWithDups -> FreeKiTyVarsWithDups +extract_ltys :: [LHsType GhcPs] -> FreeKiTyVars -> FreeKiTyVars extract_ltys tys acc = foldr extract_lty acc tys -extract_lty :: LHsType GhcPs - -> FreeKiTyVarsWithDups -> FreeKiTyVarsWithDups +extract_lty :: LHsType GhcPs -> FreeKiTyVars -> FreeKiTyVars extract_lty (L _ ty) acc = case ty of HsTyVar _ _ ltv -> extract_tv ltv acc @@ -1784,15 +1778,15 @@ extract_lty (L _ ty) acc HsWildCardTy {} -> acc extractHsTvBndrs :: [LHsTyVarBndr flag GhcPs] - -> FreeKiTyVarsWithDups -- Free in body - -> FreeKiTyVarsWithDups -- Free in result + -> FreeKiTyVars -- Free in body + -> FreeKiTyVars -- Free in result extractHsTvBndrs tv_bndrs body_fvs = extract_hs_tv_bndrs tv_bndrs [] body_fvs extract_hs_tv_bndrs :: [LHsTyVarBndr flag GhcPs] - -> FreeKiTyVarsWithDups -- Accumulator - -> FreeKiTyVarsWithDups -- Free in body - -> FreeKiTyVarsWithDups + -> FreeKiTyVars -- Accumulator + -> FreeKiTyVars -- Free in body + -> FreeKiTyVars -- In (forall (a :: Maybe e). a -> b) we have -- 'a' is bound by the forall -- 'b' is a free type variable @@ -1807,24 +1801,28 @@ extract_hs_tv_bndrs tv_bndrs acc_vars body_vars = new_vars ++ acc_vars bndr_vars = extract_hs_tv_bndrs_kvs tv_bndrs tv_bndr_rdrs = map hsLTyVarLocName tv_bndrs -extract_hs_tv_bndrs_kvs :: [LHsTyVarBndr flag GhcPs] -> FreeKiTyVarsWithDups +extract_hs_tv_bndrs_kvs :: [LHsTyVarBndr flag GhcPs] -> FreeKiTyVars -- Returns the free kind variables of any explicitly-kinded binders, returning -- variable occurrences in left-to-right order. -- See Note [Ordering of implicit variables]. -- NB: Does /not/ delete the binders themselves. --- Duplicates are /not/ removed -- E.g. given [k1, a:k1, b:k2] -- the function returns [k1,k2], even though k1 is bound here extract_hs_tv_bndrs_kvs tv_bndrs = foldr extract_lty [] [k | L _ (KindedTyVar _ _ _ k) <- tv_bndrs] -extract_tv :: Located RdrName - -> [Located RdrName] -> [Located RdrName] +extract_tv :: Located RdrName -> FreeKiTyVars -> FreeKiTyVars extract_tv tv acc = if isRdrTyVar (unLoc tv) then tv:acc else acc --- Deletes duplicates in a list of Located things. +-- Deletes duplicates in a list of Located things. This is used to: +-- +-- * Delete duplicate occurrences of implicitly bound type/kind variables when +-- bringing them into scope (in rnImplicitBndrs). +-- +-- * Delete duplicate occurrences of named wildcards (in rn_hs_sig_wc_type and +-- rnHsWcType). -- -- Importantly, this function is stable with respect to the original ordering -- of things in the list. This is important, as it is a property that GHC @@ -1838,9 +1836,9 @@ nubL = nubBy eqLocated -- already in scope, or are explicitly bound in the binder. filterFreeVarsToBind :: FreeKiTyVars -- ^ Explicitly bound here - -> FreeKiTyVarsWithDups + -> FreeKiTyVars -- ^ Potential implicit binders - -> FreeKiTyVarsWithDups + -> FreeKiTyVars -- ^ Final implicit binders filterFreeVarsToBind bndrs = filterOut is_in_scope -- Make sure to list the binder kvs before the body kvs, as mandated by ===================================== compiler/GHC/Rename/Module.hs ===================================== @@ -664,7 +664,7 @@ rnClsInstDecl (ClsInstDecl { cid_poly_ty = inst_ty, cid_binds = mbinds rnFamInstEqn :: HsDocContext -> AssocTyFamInfo - -> [Located RdrName] + -> FreeKiTyVars -- ^ Kind variables from the equation's RHS to be implicitly bound -- if no explicit forall. -> FamInstEqn GhcPs rhs @@ -681,9 +681,10 @@ rnFamInstEqn doc atfi rhs_kvars AssocTyFamDeflt cls -> Just cls AssocTyFamInst cls _ -> Just cls ; tycon' <- lookupFamInstName mb_cls tycon - ; let pat_kity_vars_with_dups = extractHsTyArgRdrKiTyVarsDup pats - -- Use the "...Dups" form because it's needed - -- below to report unused binder on the LHS + ; let pat_kity_vars_with_dups = extractHsTyArgRdrKiTyVars pats + -- It is crucial that extractHsTyArgRdrKiTyVars return + -- duplicate occurrences, since they're needed below to help + -- determine unused binders on the LHS. ; let bndrs = fromMaybe [] mb_bndrs @@ -713,48 +714,42 @@ rnFamInstEqn doc atfi rhs_kvars -- No need to filter out explicit binders (the 'mb_bndrs = Just -- explicit_bndrs' case) because there must be none if we're going -- to implicitly bind anything, per the previous comment. - nubL $ pat_kity_vars_with_dups ++ rhs_kvars - ; all_imp_var_names <- mapM (newTyVarNameRn mb_cls) all_imp_vars - - -- All the free vars of the family patterns - -- with a sensible binding location - ; ((bndrs', pats', payload'), fvs) - <- bindLocalNamesFV all_imp_var_names $ - bindLHsTyVarBndrs doc (Just $ inHsDocContext doc) - Nothing bndrs $ \bndrs' -> - -- Note: If we pass mb_cls instead of Nothing here, - -- bindLHsTyVarBndrs will use class variables for any names - -- the user meant to bring in scope here. This is an explicit - -- forall, so we want fresh names, not class variables. - -- Thus: always pass Nothing - do { (pats', pat_fvs) <- rnLHsTypeArgs (FamPatCtx tycon) pats - ; (payload', rhs_fvs) <- rn_payload doc payload - - -- Report unused binders on the LHS - -- See Note [Unused type variables in family instances] - ; let groups :: [NonEmpty (Located RdrName)] - groups = equivClasses cmpLocated $ - pat_kity_vars_with_dups - ; nms_dups <- mapM (lookupOccRn . unLoc) $ - [ tv | (tv :| (_:_)) <- groups ] - -- Add to the used variables - -- a) any variables that appear *more than once* on the LHS - -- e.g. F a Int a = Bool - -- b) for associated instances, the variables - -- of the instance decl. See - -- Note [Unused type variables in family instances] - ; let nms_used = extendNameSetList rhs_fvs $ - inst_tvs ++ nms_dups - inst_tvs = case atfi of - NonAssocTyFamEqn -> [] - AssocTyFamDeflt _ -> [] - AssocTyFamInst _ inst_tvs -> inst_tvs - all_nms = all_imp_var_names ++ hsLTyVarNames bndrs' - ; warnUnusedTypePatterns all_nms nms_used - - ; return ((bndrs', pats', payload'), rhs_fvs `plusFV` pat_fvs) } - - ; let all_fvs = fvs `addOneFV` unLoc tycon' + pat_kity_vars_with_dups ++ rhs_kvars + + ; rnImplicitBndrs mb_cls all_imp_vars $ \all_imp_var_names -> + bindLHsTyVarBndrs doc (Just $ inHsDocContext doc) + Nothing bndrs $ \bndrs' -> + -- Note: If we pass mb_cls instead of Nothing here, + -- bindLHsTyVarBndrs will use class variables for any names + -- the user meant to bring in scope here. This is an explicit + -- forall, so we want fresh names, not class variables. + -- Thus: always pass Nothing + do { (pats', pat_fvs) <- rnLHsTypeArgs (FamPatCtx tycon) pats + ; (payload', rhs_fvs) <- rn_payload doc payload + + -- Report unused binders on the LHS + -- See Note [Unused type variables in family instances] + ; let groups :: [NonEmpty (Located RdrName)] + groups = equivClasses cmpLocated $ + pat_kity_vars_with_dups + ; nms_dups <- mapM (lookupOccRn . unLoc) $ + [ tv | (tv :| (_:_)) <- groups ] + -- Add to the used variables + -- a) any variables that appear *more than once* on the LHS + -- e.g. F a Int a = Bool + -- b) for associated instances, the variables + -- of the instance decl. See + -- Note [Unused type variables in family instances] + ; let nms_used = extendNameSetList rhs_fvs $ + inst_tvs ++ nms_dups + inst_tvs = case atfi of + NonAssocTyFamEqn -> [] + AssocTyFamDeflt _ -> [] + AssocTyFamInst _ inst_tvs -> inst_tvs + all_nms = all_imp_var_names ++ hsLTyVarNames bndrs' + ; warnUnusedTypePatterns all_nms nms_used + + ; let all_fvs = (rhs_fvs `plusFV` pat_fvs) `addOneFV` unLoc tycon' -- type instance => use, hence addOneFV ; return (HsIB { hsib_ext = all_imp_var_names -- Note [Wildcards in family instances] @@ -765,7 +760,7 @@ rnFamInstEqn doc atfi rhs_kvars , feqn_pats = pats' , feqn_fixity = fixity , feqn_rhs = payload' } }, - all_fvs) } + all_fvs) } } rnTyFamInstDecl :: AssocTyFamInfo -> TyFamInstDecl GhcPs @@ -2116,12 +2111,12 @@ rnConDecl decl@(ConDeclGADT { con_names = names -- See #14808. ; implicit_bndrs <- forAllOrNothing explicit_forall $ extractHsTvBndrs explicit_tkvs - $ extractHsTysRdrTyVarsDups (theta ++ arg_tys ++ [res_ty]) + $ extractHsTysRdrTyVars (theta ++ arg_tys ++ [res_ty]) ; let ctxt = ConDeclCtx new_names mb_ctxt = Just (inHsDocContext ctxt) - ; rnImplicitBndrs implicit_bndrs $ \ implicit_tkvs -> + ; rnImplicitBndrs Nothing implicit_bndrs $ \ implicit_tkvs -> bindLHsTyVarBndrs ctxt mb_ctxt Nothing explicit_tkvs $ \ explicit_tkvs -> do { (new_cxt, fvs1) <- rnMbContext ctxt mcxt ; (new_args, fvs2) <- rnConDeclDetails (unLoc (head new_names)) ctxt args ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -1431,7 +1431,7 @@ reifyInstances th_nm th_tys -- must error before proceeding to typecheck the -- renamed type, as that will result in GHC -- internal errors (#13837). - bindLRdrNames tv_rdrs $ \ tv_names -> + rnImplicitBndrs Nothing tv_rdrs $ \ tv_names -> do { (rn_ty, fvs) <- rnLHsType doc rdr_ty ; return ((tv_names, rn_ty), fvs) } ; (_tvs, ty) ===================================== testsuite/tests/indexed-types/should_compile/ExplicitForAllFams2.stderr ===================================== @@ -5,8 +5,8 @@ ExplicitForAllFams2.hs:34:10: warning: [-Wunused-type-patterns] ExplicitForAllFams2.hs:35:10: warning: [-Wunused-type-patterns] Defined but not used on the right hand side: type variable ‘a’ -ExplicitForAllFams2.hs:38:7: warning: [-Wunused-type-patterns] +ExplicitForAllFams2.hs:38:3: warning: [-Wunused-type-patterns] Defined but not used on the right hand side: type variable ‘t’ -ExplicitForAllFams2.hs:39:6: warning: [-Wunused-type-patterns] +ExplicitForAllFams2.hs:39:3: warning: [-Wunused-type-patterns] Defined but not used on the right hand side: type variable ‘a’ ===================================== testsuite/tests/indexed-types/should_compile/T16356_Compile2.stderr ===================================== @@ -1,8 +1,8 @@ -T16356_Compile2.hs:10:12: warning: [-Wunused-type-patterns] +T16356_Compile2.hs:10:3: warning: [-Wunused-type-patterns] Defined but not used on the right hand side: type variable ‘j’ -T16356_Compile2.hs:10:17: warning: [-Wunused-type-patterns] +T16356_Compile2.hs:10:3: warning: [-Wunused-type-patterns] Defined but not used on the right hand side: type variable ‘a’ T16356_Compile2.hs:13:15: warning: [-Wunused-type-patterns] ===================================== testsuite/tests/indexed-types/should_compile/T16632.stderr ===================================== @@ -1,6 +1,6 @@ -T16632.hs:5:22: warning: [-Wunused-type-patterns] +T16632.hs:5:1: warning: [-Wunused-type-patterns] Defined but not used on the right hand side: type variable ‘b’ | 5 | type instance F Char b Int = () - | ^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ===================================== testsuite/tests/indexed-types/should_compile/UnusedTyVarWarnings.stderr ===================================== @@ -1,12 +1,12 @@ -UnusedTyVarWarnings.hs:8:7: warning: [-Wunused-type-patterns] +UnusedTyVarWarnings.hs:8:3: warning: [-Wunused-type-patterns] Defined but not used on the right hand side: type variable ‘b’ -UnusedTyVarWarnings.hs:11:20: warning: [-Wunused-type-patterns] +UnusedTyVarWarnings.hs:11:1: warning: [-Wunused-type-patterns] Defined but not used on the right hand side: type variable ‘b’ -UnusedTyVarWarnings.hs:27:5: warning: [-Wunused-type-patterns] +UnusedTyVarWarnings.hs:27:3: warning: [-Wunused-type-patterns] Defined but not used on the right hand side: type variable ‘a’ -UnusedTyVarWarnings.hs:33:19: warning: [-Wunused-type-patterns] +UnusedTyVarWarnings.hs:33:1: warning: [-Wunused-type-patterns] Defined but not used on the right hand side: type variable ‘b’ ===================================== testsuite/tests/indexed-types/should_compile/UnusedTyVarWarningsNamedWCs.stderr ===================================== @@ -1,12 +1,12 @@ -UnusedTyVarWarningsNamedWCs.hs:8:7: warning: [-Wunused-type-patterns] +UnusedTyVarWarningsNamedWCs.hs:8:3: warning: [-Wunused-type-patterns] Defined but not used on the right hand side: type variable ‘b’ -UnusedTyVarWarningsNamedWCs.hs:11:20: warning: [-Wunused-type-patterns] +UnusedTyVarWarningsNamedWCs.hs:11:1: warning: [-Wunused-type-patterns] Defined but not used on the right hand side: type variable ‘b’ -UnusedTyVarWarningsNamedWCs.hs:27:5: warning: [-Wunused-type-patterns] +UnusedTyVarWarningsNamedWCs.hs:27:3: warning: [-Wunused-type-patterns] Defined but not used on the right hand side: type variable ‘a’ -UnusedTyVarWarningsNamedWCs.hs:33:19: warning: [-Wunused-type-patterns] +UnusedTyVarWarningsNamedWCs.hs:33:1: warning: [-Wunused-type-patterns] Defined but not used on the right hand side: type variable ‘b’ ===================================== testsuite/tests/indexed-types/should_fail/T17008a.stderr ===================================== @@ -1,5 +1,5 @@ -T17008a.hs:11:21: error: +T17008a.hs:11:3: error: • Type variable ‘a1’ is mentioned in the RHS, but not bound on the LHS of the family instance The real LHS (expanding synonyms) is: F @a2 x ===================================== testsuite/tests/indexed-types/should_fail/T7536.stderr ===================================== @@ -1,5 +1,5 @@ -T7536.hs:8:21: error: +T7536.hs:8:1: error: • Type variable ‘a’ is mentioned in the RHS, but not bound on the LHS of the family instance The real LHS (expanding synonyms) is: TF Int ===================================== testsuite/tests/polykinds/T11203.stderr ===================================== @@ -1,4 +1,4 @@ -T11203.hs:7:24: error: +T11203.hs:7:1: error: • Different names for the same type variable: ‘k1’ and ‘k2’ • In the data declaration for ‘Q’ ===================================== testsuite/tests/polykinds/T11821a.stderr ===================================== @@ -1,4 +1,4 @@ -T11821a.hs:4:31: error: +T11821a.hs:4:1: error: • Different names for the same type variable: ‘k1’ and ‘k2’ • In the type declaration for ‘SameKind’ ===================================== testsuite/tests/typecheck/should_fail/T17566b.stderr ===================================== @@ -1,4 +1,4 @@ -T17566b.hs:7:17: error: +T17566b.hs:7:3: error: • Different names for the same type variable: ‘k1’ and ‘k2’ • In the class declaration for ‘C’ ===================================== testsuite/tests/typecheck/should_fail/T17566c.stderr ===================================== @@ -1,6 +1,6 @@ -T17566c.hs:11:23: error: +T17566c.hs:11:3: error: • Different names for the same type variable: - ‘k’ bound at T17566c.hs:10:17 - ‘k’ bound at T17566c.hs:11:23 + ‘k’ bound at T17566c.hs:10:3 + ‘k’ bound at T17566c.hs:11:3 • In the class declaration for ‘C2’ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/285f281743865ea1657cd734527c7c3fc64bd0f7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/285f281743865ea1657cd734527c7c3fc64bd0f7 You're receiving 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 27 12:21:10 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Wed, 27 May 2020 08:21:10 -0400 Subject: [Git][ghc/ghc][wip/T18078] 35 commits: docs: fix formatting and add some links Message-ID: <5ece5b3649242_6e263f9ed77c97f419000cf@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T18078 at Glasgow Haskell Compiler / GHC Commits: d830bbc9 by Adam Sandberg Ericsson at 2020-05-23T13:36:20-04:00 docs: fix formatting and add some links [skip ci] - - - - - 49301ad6 by Andrew Martin at 2020-05-23T13:37:01-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. - - - - - dcd6bdcc by Ben Gamari at 2020-05-23T13:37:48-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. - - - - - 82cb8913 by John Ericson at 2020-05-23T13:38:32-04:00 Fix #18145 and also avoid needless work with implicit vars - `forAllOrNothing` now is monadic, so we can trace whether we bind an explicit `forall` or not. - #18145 arose because the free vars calculation was needlessly complex. It is now greatly simplified. - Replaced some other implicit var code with `filterFreeVarsToBind`. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - a60dc835 by Ben Gamari at 2020-05-23T13:39:12-04:00 Bump process submodule Fixes #17926. - - - - - 856adf54 by Ben Gamari at 2020-05-23T13:40:21-04:00 users-guide: Clarify meaning of -haddock flag Fixes #18206. - - - - - 7ae57afd by Ben Gamari at 2020-05-23T13:41:03-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 - - - - - 63d30e60 by jneira at 2020-05-24T01:54:42-04:00 Add hie-bios script for windows systems It is a direct translation of the sh script - - - - - 59182b88 by jneira at 2020-05-24T01:54:42-04:00 Honour previous values for CABAL and CABFLAGS The immediate goal is let the hie-bios.bat script set CABFLAGS with `-v0` and remove all cabal output except the compiler arguments - - - - - 932dc54e by jneira at 2020-05-24T01:54:42-04:00 Add specific configuration for windows in hie.yaml - - - - - e0eda070 by jneira at 2020-05-24T01:54:42-04:00 Remove not needed hie-bios output - - - - - a0ea59d6 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Move Config module into GHC.Settings - - - - - 37430251 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Core.Arity into GHC.Core.Opt.Arity - - - - - a426abb9 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Hs.Types into GHC.Hs.Type See discussion in https://gitlab.haskell.org/ghc/ghc/issues/13009#note_268610 - - - - - 1c91a7a0 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Bump haddock submodule - - - - - 66bd24d1 by Ryan Scott at 2020-05-24T01:56:03-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. - - - - - 01c43634 by Matthew Pickering at 2020-05-24T01:56:42-04:00 Remove unused hs-boot file - - - - - 7a07aa71 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix cross-compiler build (#16051) - - - - - 15ccca16 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix distDir per stage - - - - - b420fb24 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix hp2ps error during cross-compilation Fixed by @alp (see https://gitlab.haskell.org/ghc/ghc/issues/16051#note_274265) - - - - - cd339ef0 by Joshua Price at 2020-05-24T15:22:56-04:00 Make Unicode brackets opening/closing tokens (#18225) The tokens `[|`, `|]`, `(|`, and `|)` are opening/closing tokens as described in GHC Proposal #229. This commit makes the unicode variants (`⟦`, `⟧`, `⦇`, and `⦈`) act the same as their ASCII counterparts. - - - - - 013d7120 by Ben Gamari at 2020-05-25T09:48:17-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. - - - - - 4c4312ed by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Drop redundant ad-hoc boot module check To determine whether the module is a boot module Coverage.addTicksToBinds was checking for a `boot` suffix in the module source filename. This is quite ad-hoc and shouldn't be necessary; the callsite in `deSugar` already checks that the module isn't a boot module. - - - - - 1abf3c84 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make tickBoxCount strict This could otherwise easily cause a leak of (+) thunks. - - - - - b2813750 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make ccIndices strict This just seems like a good idea. - - - - - 02e278eb by Ben Gamari at 2020-05-25T09:48:53-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. - - - - - b8c014ce by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Factor out addMixEntry - - - - - 53814a64 by Zubin Duggal at 2020-05-26T03:03:24-04:00 Add info about typeclass evidence to .hie files See `testsuite/tests/hiefile/should_run/HieQueries.hs` and `testsuite/tests/hiefile/should_run/HieQueries.stdout` for an example of this We add two new fields, `EvidenceVarBind` and `EvidenceVarUse` to the `ContextInfo` associated with an Identifier. These are associated with the appropriate identifiers for the evidence variables collected when we come across `HsWrappers`, `TcEvBinds` and `IPBinds` while traversing the AST. Instance dictionary and superclass selector dictionaries from `tcg_insts` and classes defined in `tcg_tcs` are also recorded in the AST as originating from their definition span This allows us to save a complete picture of the evidence constructed by the constraint solver, and will let us report this to the user, enabling features like going to the instance definition from the invocation of a class method(or any other method taking a constraint) and finding all usages of a particular instance. Additionally, - Mark NodeInfo with an origin so we can differentiate between bindings origininating in the source vs those in ghc - Along with typeclass evidence info, also include information on Implicit Parameters - Add a few utility functions to HieUtils in order to query the new info Updates haddock submodule - - - - - 6604906c by Sebastian Graf at 2020-05-26T03:04:04-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. - - - - - cf772f19 by Sylvain Henry at 2020-05-26T03:04:45-04:00 Enhance Note [About units] for Backpack - - - - - ede24126 by Takenobu Tani at 2020-05-27T00:13:55-04:00 core-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Core.hs <= coreSyn/CoreSyn.hs * GHC/Core/Coercion.hs <= types/Coercion.hs * GHC/Core/Coercion/Axiom.hs <= types/CoAxiom.hs * GHC/Core/Coercion/Opt.hs <= types/OptCoercion.hs * GHC/Core/DataCon.hs <= basicTypes/DataCon.hs * GHC/Core/FamInstEnv.hs <= types/FamInstEnv.hs * GHC/Core/Lint.hs <= coreSyn/CoreLint.hs * GHC/Core/Subst.hs <= coreSyn/CoreSubst.hs * GHC/Core/TyCo/Rep.hs <= types/TyCoRep.hs * GHC/Core/TyCon.hs <= types/TyCon.hs * GHC/Core/Type.hs <= types/Type.hs * GHC/Core/Unify.hs <= types/Unify.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/Var.hs <= basicTypes/Var.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [skip ci] - - - - - 04750304 by Ben Gamari at 2020-05-27T00:14:33-04:00 eventlog: Fix racy flushing Previously no attempt was made to avoid multiple threads writing their capability-local eventlog buffers to the eventlog writer simultaneously. This could result in multiple eventlog streams being interleaved. Fix this by documenting that the EventLogWriter's write() and flush() functions may be called reentrantly and fix the default writer to protect its FILE* by a mutex. Fixes #18210. - - - - - d6203f24 by Joshua Price at 2020-05-27T00:15:17-04:00 Make `identifier` parse unparenthesized `->` (#18060) - - - - - 138df1cf by Simon Peyton Jones at 2020-05-27T12:52:40+01:00 Optimisation in Unique.Supply This patch switches on -fno-state-hack in GHC.Types.Unique.Supply. It turned out that my fixes for #18078 (coercion floating) changed the optimisation pathway for mkSplitUniqSupply in such a way that we had an extra allocation inside the inner loop. Adding -fno-state-hack fixed that -- and indeed the loop in mkSplitUniqSupply is a classic example of the way in which -fno-state-hack can be bad; see #18238. Moreover, the new code is better than the old. They allocate the same, but the old code ends up with a partial application. The net effect is that the test perf/should_run/UniqLoop runs 20% faster! From 2.5s down to 2.0s. The allocation numbers are the same -- but elapsed time falls. Good! The bad thing about this is that it's terribly delicate. But at least it's a good example of such delicacy in action. There is a long Note [Optimising the unique supply] which now explains all this. - - - - - 23646100 by Simon Peyton Jones at 2020-05-27T13:20:27+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 also discovered that unsafeCoerce wasn't being inlined if the context was boring. So (\x. f (unsafeCoerce x)) would create a thunk -- yikes! I fixed that by making inlineBoringOK a bit cleverer: see Note [Inline unsafeCoerce] in GHC.Core.Unfold. I also found that unsafeCoerceName was unused, so I removed it. 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: - + .git-ignore-revs - compiler/GHC/Builtin/Names.hs - − compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Types.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Arity.hs → compiler/GHC/Core/Opt/Arity.hs - compiler/GHC/Core/Opt/CSE.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/Driver.hs - compiler/GHC/Core/Opt/FloatOut.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/Rules.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fe99560e3942c64dc5e397ec9c3c8e8423b626aa...23646100be8f0ecbd22b500b18952478f56bc9da -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/fe99560e3942c64dc5e397ec9c3c8e8423b626aa...23646100be8f0ecbd22b500b18952478f56bc9da You're receiving 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 27 12:30:11 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 27 May 2020 08:30:11 -0400 Subject: [Git][ghc/ghc][wip/bump-base] base: Bump to 4.15.0.0 Message-ID: <5ece5d53c1ead_6e263f9ee3e9af901907851@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/bump-base at Glasgow Haskell Compiler / GHC Commits: c1a8577c by Ben Gamari at 2020-05-27T12:29:21+00:00 base: Bump to 4.15.0.0 - - - - - 30 changed files: - compiler/ghc.cabal.in - libraries/array - libraries/base/base.cabal - libraries/deepseq - libraries/directory - libraries/filepath - libraries/ghc-boot-th/ghc-boot-th.cabal.in - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghc-compact/ghc-compact.cabal - libraries/ghci/ghci.cabal.in - libraries/haskeline - libraries/hpc - libraries/parsec - libraries/process - libraries/stm - libraries/template-haskell/template-haskell.cabal.in - libraries/terminfo - libraries/unix - testsuite/tests/dependent/should_compile/T14729.stderr - testsuite/tests/dependent/should_compile/T15743.stderr - testsuite/tests/dependent/should_compile/T15743e.stderr - testsuite/tests/indexed-types/should_compile/T15711.stderr - testsuite/tests/indexed-types/should_compile/T15852.stderr - testsuite/tests/polykinds/T15592.stderr - testsuite/tests/polykinds/T15592b.stderr - testsuite/tests/printer/T18052a.stderr - testsuite/tests/typecheck/should_compile/T12763.stderr - testsuite/tests/typecheck/should_compile/subsumption_sort_hole_fits.stderr - utils/haddock - utils/hsc2hs Changes: ===================================== compiler/ghc.cabal.in ===================================== @@ -59,7 +59,7 @@ Library Default-Language: Haskell2010 Exposed: False - Build-Depends: base >= 4.11 && < 4.15, + Build-Depends: base >= 4.11 && < 4.16, deepseq >= 1.4 && < 1.5, directory >= 1 && < 1.4, process >= 1 && < 1.7, ===================================== libraries/array ===================================== @@ -1 +1 @@ -Subproject commit f73f681e52546b1e35cb9e8a62fe49c33f259d98 +Subproject commit ab535173d7885ebfc2005d8da2765f0f52c923ce ===================================== 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 ===================================== libraries/deepseq ===================================== @@ -1 +1 @@ -Subproject commit da0eda33f540786b6823c6f542ab59cf9d1b71d9 +Subproject commit 13c1c84415da727ab56e9fa33aca5046b6683848 ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit 36bd1921258b759724a95ce56c5e880edf0972a2 +Subproject commit 0dcb228388a6e306c11f419c7c5575eaa6af40b3 ===================================== libraries/filepath ===================================== @@ -1 +1 @@ -Subproject commit 023eedaeb142d47b7b5a41fe4cc4150da0bd0042 +Subproject commit 7cb3dc285cd595a7b6cf0b74a58b6583fb67772e ===================================== libraries/ghc-boot-th/ghc-boot-th.cabal.in ===================================== @@ -36,4 +36,4 @@ Library GHC.ForeignSrcLang.Type GHC.Lexeme - build-depends: base >= 4.7 && < 4.15 + build-depends: base >= 4.7 && < 4.16 ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -55,7 +55,7 @@ Library -- GHC.Version -- GHC.Platform.Host - build-depends: base >= 4.7 && < 4.15, + build-depends: base >= 4.7 && < 4.16, binary == 0.8.*, bytestring == 0.10.*, containers >= 0.5 && < 0.7, ===================================== libraries/ghc-compact/ghc-compact.cabal ===================================== @@ -37,7 +37,7 @@ library CPP build-depends: ghc-prim >= 0.5.3 && < 0.7, - base >= 4.9.0 && < 4.15, + base >= 4.9.0 && < 4.16, bytestring >= 0.10.6.0 ghc-options: -Wall ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -72,7 +72,7 @@ library Build-Depends: array == 0.5.*, - base >= 4.8 && < 4.15, + base >= 4.8 && < 4.16, binary == 0.8.*, bytestring == 0.10.*, containers >= 0.5 && < 0.7, ===================================== libraries/haskeline ===================================== @@ -1 +1 @@ -Subproject commit 463fc49d17bfab846cceba48bccc02ef285e6cba +Subproject commit 0382e3acdb8433e1d9c33ca5947784e78134f838 ===================================== libraries/hpc ===================================== @@ -1 +1 @@ -Subproject commit f73c482db30a40cfa12074de51335b70a0974931 +Subproject commit 43bb9061a748aee6a95a9f1db33a2b1e5f770634 ===================================== libraries/parsec ===================================== @@ -1 +1 @@ -Subproject commit ce416997e15438ca616667995660e123ef7e219d +Subproject commit 190492494fe92e8dd42165190b7ac112be1f7389 ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit 1afc36ecd38c069251a836e1c1c8b3a3043ddc01 +Subproject commit 8f4ecebb6578a179a6c04074cb06600683e2e50c ===================================== libraries/stm ===================================== @@ -1 +1 @@ -Subproject commit faf9904137044e35a589c7c1579e1bfa03789c84 +Subproject commit 444f672416a354c3cfde9d94ec237a36be46ef59 ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -55,7 +55,7 @@ Library Language.Haskell.TH.Lib.Map build-depends: - base >= 4.11 && < 4.15, + base >= 4.11 && < 4.16, ghc-boot-th == @ProjectVersionMunged@, ghc-prim, pretty == 1.1.* ===================================== libraries/terminfo ===================================== @@ -1 +1 @@ -Subproject commit 27e694688d2d6eee69959a8b6a128c584c84aa72 +Subproject commit 3ebb36f4a2c42b74ec4e35efccc2be34c198a830 ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 1a993b89c570e03ba74f196f5d065a0ebe624010 +Subproject commit ea13d990580273a883368793dfbb826cab5a22d4 ===================================== testsuite/tests/dependent/should_compile/T14729.stderr ===================================== @@ -11,5 +11,5 @@ COERCION AXIOMS FAMILY INSTANCES type instance F Int = Bool -- Defined at T14729.hs:10:15 Dependent modules: [] -Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, - integer-gmp-1.0.2.0] +Dependent packages: [base-4.15.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] ===================================== testsuite/tests/dependent/should_compile/T15743.stderr ===================================== @@ -3,5 +3,5 @@ TYPE CONSTRUCTORS forall {k1} k2 (k3 :: k2). Proxy k3 -> k1 -> k2 -> * roles nominal nominal nominal phantom phantom phantom Dependent modules: [] -Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, - integer-gmp-1.0.2.0] +Dependent packages: [base-4.15.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] ===================================== testsuite/tests/dependent/should_compile/T15743e.stderr ===================================== @@ -52,5 +52,5 @@ DATA CONSTRUCTORS (d :: Proxy k5) (e :: Proxy k7). f c -> T k8 a b f c d e Dependent modules: [] -Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, - integer-gmp-1.0.2.0] +Dependent packages: [base-4.15.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] ===================================== testsuite/tests/indexed-types/should_compile/T15711.stderr ===================================== @@ -3,5 +3,5 @@ TYPE CONSTRUCTORS associated type family F{2} :: forall a. Maybe a -> * roles nominal nominal Dependent modules: [] -Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, - integer-gmp-1.0.2.0] +Dependent packages: [base-4.15.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] ===================================== testsuite/tests/indexed-types/should_compile/T15852.stderr ===================================== @@ -9,5 +9,5 @@ FAMILY INSTANCES data instance forall {k1} {k2} {j :: k1} {c :: k2}. DF (Proxy c) -- Defined at T15852.hs:10:15 Dependent modules: [] -Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, - integer-gmp-1.0.2.0] +Dependent packages: [base-4.15.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] ===================================== testsuite/tests/polykinds/T15592.stderr ===================================== @@ -5,5 +5,5 @@ DATA CONSTRUCTORS MkT :: forall {k} k1 (f :: k1 -> k -> *) (a :: k1) (b :: k). f a b -> T f a b -> T f a b Dependent modules: [] -Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, - integer-gmp-1.0.2.0] +Dependent packages: [base-4.15.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] ===================================== testsuite/tests/polykinds/T15592b.stderr ===================================== @@ -4,5 +4,5 @@ TYPE CONSTRUCTORS forall k (f :: k -> *) (a :: k). f a -> * roles nominal nominal nominal nominal Dependent modules: [] -Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, - integer-gmp-1.0.2.0] +Dependent packages: [base-4.15.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] ===================================== testsuite/tests/printer/T18052a.stderr ===================================== @@ -6,7 +6,7 @@ TYPE CONSTRUCTORS PATTERN SYNONYMS (:||:) :: forall {a} {b}. a -> b -> (a, b) Dependent modules: [] -Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, +Dependent packages: [base-4.15.0.0, ghc-prim-0.6.1, integer-gmp-1.0.3.0] ==================== Tidy Core ==================== ===================================== testsuite/tests/typecheck/should_compile/T12763.stderr ===================================== @@ -8,5 +8,5 @@ COERCION AXIOMS CLASS INSTANCES instance C Int -- Defined at T12763.hs:9:10 Dependent modules: [] -Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, - integer-gmp-1.0.2.0] +Dependent packages: [base-4.15.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] ===================================== testsuite/tests/typecheck/should_compile/subsumption_sort_hole_fits.stderr ===================================== @@ -9,10 +9,10 @@ subsumption_sort_hole_fits.hs:2:5: warning: [-Wtyped-holes (in -Wdefault)] Valid hole fits include lines :: String -> [String] (imported from ‘Prelude’ at subsumption_sort_hole_fits.hs:1:1 - (and originally defined in ‘base-4.14.0.0:Data.OldList’)) + (and originally defined in ‘base-4.15.0.0:Data.OldList’)) words :: String -> [String] (imported from ‘Prelude’ at subsumption_sort_hole_fits.hs:1:1 - (and originally defined in ‘base-4.14.0.0:Data.OldList’)) + (and originally defined in ‘base-4.15.0.0:Data.OldList’)) read :: forall a. Read a => String -> a with read @[String] (imported from ‘Prelude’ at subsumption_sort_hole_fits.hs:1:1 ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 8f340aef12df5f5df02d49ab5c6c5d7cccfa398b +Subproject commit be2dfbd166f6bb0790ad94f0b4b9a90f02849d84 ===================================== utils/hsc2hs ===================================== @@ -1 +1 @@ -Subproject commit 24100ea521596922d3edc8370b3d9f7b845ae4cf +Subproject commit e792dd8e5589d42a4d416f78df8efb70995f95e3 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c1a8577c1f18bfedc6a67197c80fd206286d1f87 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c1a8577c1f18bfedc6a67197c80fd206286d1f87 You're receiving 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 27 12:34:37 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Wed, 27 May 2020 08:34:37 -0400 Subject: [Git][ghc/ghc][wip/T18078] Implement cast worker/wrapper properly Message-ID: <5ece5e5dc26b3_6e263f9ed77c97f419093b1@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T18078 at Glasgow Haskell Compiler / GHC Commits: ec08c16c by Simon Peyton Jones at 2020-05-27T13:33:51+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 also discovered that unsafeCoerce wasn't being inlined if the context was boring. So (\x. f (unsafeCoerce x)) would create a thunk -- yikes! I fixed that by making inlineBoringOK a bit cleverer: see Note [Inline unsafeCoerce] in GHC.Core.Unfold. I also found that unsafeCoerceName was unused, so I removed it. 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/Builtin/Names.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Opt/CSE.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/Driver.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/SimpleOpt.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/Id/Make.hs - compiler/GHC/Types/Var.hs - compiler/GHC/Utils/Binary.hs - libraries/base/Unsafe/Coerce.hs - testsuite/tests/codeGen/should_compile/debug.stdout - testsuite/tests/deSugar/should_compile/T2431.stderr - testsuite/tests/perf/compiler/T16473.stdout - testsuite/tests/simplCore/should_compile/T13143.stderr - + testsuite/tests/simplCore/should_compile/T17673.hs - + testsuite/tests/simplCore/should_compile/T17673.stderr - + testsuite/tests/simplCore/should_compile/T18078.hs - + testsuite/tests/simplCore/should_compile/T18078.stderr - testsuite/tests/simplCore/should_compile/T3772.stdout - testsuite/tests/simplCore/should_compile/T7360.stderr - testsuite/tests/simplCore/should_compile/T7865.stdout The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ec08c16ca01c0b0ec6df018fdf0f22903ff25e50 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ec08c16ca01c0b0ec6df018fdf0f22903ff25e50 You're receiving 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 27 12:34:53 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 27 May 2020 08:34:53 -0400 Subject: [Git][ghc/ghc][wip/T18234] hi Message-ID: <5ece5e6dad2ee_6e263f9eef640398190996f@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18234 at Glasgow Haskell Compiler / GHC Commits: 8c629407 by Ben Gamari at 2020-05-27T08:34:37-04:00 hi - - - - - 1 changed file: - .gitlab-ci.yml Changes: ===================================== .gitlab-ci.yml ===================================== @@ -649,7 +649,8 @@ release-x86_64-linux-deb10: extends: .build-x86_64-linux-deb10 nightly-x86_64-linux-deb10-cross-aarch64: - <<: *nightly + #<<: *nightly + stage: build extends: .build-x86_64-linux-deb10 variables: CROSS_TARGET: "aarch64-linux-gnu" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8c62940791622f2da7750401603d5c3d81268147 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8c62940791622f2da7750401603d5c3d81268147 You're receiving 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 27 12:42:19 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Wed, 27 May 2020 08:42:19 -0400 Subject: [Git][ghc/ghc][wip/T18235] Use HsForAllTelescope to avoid inferred, visible foralls Message-ID: <5ece602b5594f_6e268f30ef01913162@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T18235 at Glasgow Haskell Compiler / GHC Commits: 51c51fcc by Ryan Scott at 2020-05-27T08:42:01-04:00 Use HsForAllTelescope to avoid inferred, visible foralls Currently, `HsForAllTy` permits the combination of `ForallVis` and `Inferred`, but you can't actually typecheck code that uses it (e.g., `forall {a} ->`). This patch refactors `HsForAllTy` to use a new `HsForAllTelescope` data type that makes a type-level distinction between visible and invisible `forall`s such that visible `forall`s do not track `Specificity`. That part of the patch is actually quite small; the rest is simply changing consumers of `HsType` to accommodate this new type. Fixes #18235. Bumps the `haddock` submodule. - - - - - 30 changed files: - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Extension.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Tc/Deriv.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Types/Var.hs - testsuite/tests/ghc-api/annotations/T10278.stdout - testsuite/tests/ghc-api/annotations/T10399.stdout - testsuite/tests/ghc-api/annotations/T11018.stdout - testsuite/tests/ghc-api/annotations/T16230.stdout - testsuite/tests/ghc-api/annotations/T17519.stdout - testsuite/tests/parser/should_compile/DumpRenamedAst.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/51c51fcc04912c36b5e628da1b7f5dfe69f491a4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/51c51fcc04912c36b5e628da1b7f5dfe69f491a4 You're receiving 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 27 13:32:08 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Wed, 27 May 2020 09:32:08 -0400 Subject: [Git][ghc/ghc][wip/andreask/elem_rule_fix] Fix "build/elem" RULE. Message-ID: <5ece6bd8eeffc_6e263f9f0c69d6ac19293a3@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/elem_rule_fix at Glasgow Haskell Compiler / GHC Commits: 912f944b by Andreas Klebinger at 2020-05-27T15:31:21+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/Builtin/Names.hs - compiler/GHC/Core/Opt/ConstantFold.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/Builtin/Names.hs ===================================== @@ -347,8 +347,8 @@ basicKnownKeyNames groupWithName, -- Strings and lists - unpackCStringName, - unpackCStringFoldrName, unpackCStringUtf8Name, + unpackCStringName, unpackCStringUtf8Name, + unpackCStringFoldrName, unpackCStringFoldrUtf8Name, cstringLengthName, -- Overloaded lists @@ -717,11 +717,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 @@ -1011,12 +1012,14 @@ modIntName = varQual gHC_CLASSES (fsLit "modInt#") modIntIdKey -- Base strings Strings unpackCStringName, unpackCStringFoldrName, - unpackCStringUtf8Name, eqStringName, cstringLengthName :: Name + unpackCStringUtf8Name, unpackCStringFoldrUtf8Name, + eqStringName, cstringLengthName :: Name unpackCStringName = varQual gHC_CSTRING (fsLit "unpackCString#") unpackCStringIdKey unpackCStringFoldrName = varQual gHC_CSTRING (fsLit "unpackFoldrCString#") unpackCStringFoldrIdKey unpackCStringUtf8Name = varQual gHC_CSTRING (fsLit "unpackCStringUtf8#") unpackCStringUtf8IdKey cstringLengthName = varQual gHC_CSTRING (fsLit "cstringLength#") cstringLengthIdKey eqStringName = varQual gHC_BASE (fsLit "eqString") eqStringIdKey +unpackCStringFoldrUtf8Name = varQual gHC_CSTRING (fsLit "unpackFoldrCStringUtf8#") unpackCStringFoldrUtf8IdKey -- The 'inline' function inlineIdName :: Name @@ -2093,7 +2096,8 @@ wildCardKey, absentErrorIdKey, augmentIdKey, appendIdKey, runtimeErrorIdKey, patErrorIdKey, voidPrimIdKey, realWorldPrimIdKey, recConErrorIdKey, unpackCStringUtf8IdKey, unpackCStringAppendIdKey, - unpackCStringFoldrIdKey, unpackCStringIdKey, + unpackCStringFoldrIdKey, unpackCStringFoldrUtf8IdKey, + unpackCStringIdKey, typeErrorIdKey, divIntIdKey, modIntIdKey, absentSumFieldErrorIdKey, cstringLengthIdKey :: Unique @@ -2117,12 +2121,14 @@ 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 -cstringLengthIdKey = mkPreludeMiscIdUnique 25 +unpackCStringFoldrUtf8IdKey = mkPreludeMiscIdUnique 21 +voidPrimIdKey = mkPreludeMiscIdUnique 22 +typeErrorIdKey = mkPreludeMiscIdUnique 23 +divIntIdKey = mkPreludeMiscIdUnique 24 +modIntIdKey = mkPreludeMiscIdUnique 25 +cstringLengthIdKey = mkPreludeMiscIdUnique 26 concatIdKey, filterIdKey, zipIdKey, bindIOIdKey, returnIOIdKey, newStablePtrIdKey, ===================================== compiler/GHC/Core/Opt/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 GHC.Builtin.Names import GHC.Data.Maybe ( orElse ) @@ -1255,7 +1258,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 "CStringLength", ru_fn = cstringLengthName, @@ -1433,11 +1439,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 @@ -1450,12 +1467,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 @@ -1463,17 +1481,23 @@ 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) ===================================== 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 --- There's a built-in rule (in GHC.Core.Opt.ConstantFold) for +"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 ===================================== @@ -15,7 +15,14 @@ `ConcFlags`, `DebugFlags`, `CCFlags`, `DoHeapProfile`, `ProfFlags`, `DoTrace`, `TraceFlags`, `TickyFlags`, `ParFlags`, `RTSFlags`, `RTSStats`, `GCStats`, `ByteOrder`, `GeneralCategory`, `SrcLoc` - + + * 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 ===================================== @@ -16,13 +16,78 @@ ----------------------------------------------------------------------------- module GHC.CString ( + -- * Ascii variants unpackCString#, unpackAppendCString#, unpackFoldrCString#, - unpackCStringUtf8#, unpackNBytes#, cstringLength# + cstringLength#, + + -- * 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 ----------------------------------------------------------------------------- @@ -70,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: @@ -88,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] @@ -110,28 +198,19 @@ 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.Opt.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 +-- Usually the unpack-list rule turns unpackFoldrCString# into unpackCString#. +-- See Note [String literals in GHC] for more details. +-- 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. @@ -139,22 +218,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# @@ -187,3 +287,61 @@ foreign import ccall unsafe "strlen" c_strlen :: Addr# -> Int# cstringLength# :: Addr# -> Int# {-# INLINE[0] cstringLength# #-} cstringLength# = c_strlen + + +------------------------------ +--- 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 ===================================== @@ -5,6 +5,17 @@ - Add known-key `cstringLength#` to `GHC.CString`. This is just the C function `strlen`, but a built-in rewrite rule allows GHC to compute the result at compile time when the argument is known. + +- 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) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/912f944b3a12307a0cc295a4d67c9f3adfbe9232 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/912f944b3a12307a0cc295a4d67c9f3adfbe9232 You're receiving 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 27 13:38:25 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 27 May 2020 09:38:25 -0400 Subject: [Git][ghc/ghc][wip/T18078] A few improvements Message-ID: <5ece6d51cce0d_6e263f9f0bdc5750193760@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/T18078 at Glasgow Haskell Compiler / GHC Commits: a36eb7d5 by Sebastian Graf at 2020-05-27T15:29:40+02:00 A few improvements - Inline `finalPhase` - Remove `isFinalPhase` and use `== FinalPhase` instead - A few comment improvements - - - - - 5 changed files: - compiler/GHC/Core/Opt/Driver.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap.hs - compiler/GHC/Types/Basic.hs Changes: ===================================== compiler/GHC/Core/Opt/Driver.hs ===================================== @@ -165,7 +165,7 @@ getCoreToDo dflags -- Run GHC's internal simplification phase, after all rules have run. -- See Note [Compiler phases] in GHC.Types.Basic - simplify name = simpl_phase finalPhase name max_iter + simplify name = simpl_phase FinalPhase name max_iter -- initial simplify: mk specialiser happy: minimum effort please simpl_gently = CoreDoSimplify max_iter @@ -205,7 +205,7 @@ getCoreToDo dflags if opt_level == 0 then [ static_ptrs_float_outwards, CoreDoSimplify max_iter - (base_mode { sm_phase = finalPhase + (base_mode { sm_phase = FinalPhase , sm_names = ["Non-opt simplification"] }) ] @@ -306,7 +306,7 @@ getCoreToDo dflags runWhen do_float_in CoreDoFloatInwards, - maybe_rule_check finalPhase, + maybe_rule_check FinalPhase, -- Case-liberation for -O2. This should be after -- strictness analysis and the simplification which follows it. @@ -319,7 +319,7 @@ getCoreToDo dflags runWhen spec_constr CoreDoSpecConstr, - maybe_rule_check finalPhase, + maybe_rule_check FinalPhase, runWhen late_specialise (CoreDoPasses [ CoreDoSpecialising @@ -345,7 +345,7 @@ getCoreToDo dflags -- can become /exponentially/ more expensive. See #11731, #12996. runWhen (strictness || late_dmd_anal) CoreDoDemand, - maybe_rule_check finalPhase + maybe_rule_check FinalPhase ] -- Remove 'CoreDoNothing' and flatten 'CoreDoPasses' for clarity. ===================================== compiler/GHC/Core/Opt/Simplify/Utils.hs ===================================== @@ -1093,7 +1093,7 @@ seems to be to do a callSiteInline based on the fact that there is something interesting about the call site (it's strict). Hmm. That seems a bit fragile. -Conclusion: inline top level things gaily until finalPhase (the last +Conclusion: inline top level things gaily until FinalPhase (the last phase), at which point don't. Note [pre/postInlineUnconditionally in gentle mode] @@ -1216,7 +1216,7 @@ preInlineUnconditionally env top_lvl bndr rhs rhs_env -- not ticks. Counting ticks cannot be duplicated, and non-counting -- ticks around a Lam will disappear anyway. - early_phase = not (isFinalPhase (sm_phase mode)) + early_phase = sm_phase mode /= FinalPhase -- If we don't have this early_phase test, consider -- x = length [1,2,3] -- The full laziness pass carefully floats all the cons cells to ===================================== compiler/GHC/Core/Opt/SpecConstr.hs ===================================== @@ -1760,8 +1760,8 @@ Note [Transfer activation] In which phase should the specialise-constructor rules be active? Originally I made them always-active, but Manuel found that this defeated some clever user-written rules. Then I made them active only -in finalPhase; after all, currently, the specConstr transformation is -only run after the simplifier has reached finalPhase, but that meant +in FinalPhase; after all, currently, the specConstr transformation is +only run after the simplifier has reached FinalPhase, but that meant that specialisations didn't fire inside wrappers; see test simplCore/should_compile/spec-inline. ===================================== compiler/GHC/Core/Opt/WorkWrap.hs ===================================== @@ -435,9 +435,9 @@ Conclusion: phase 0, the last user-visible phase. That means that all rules will have had a chance to fire. - What phase is after phase 0? Answer: finalPhase, phase (-1). - That's the reason finalPhase exists. NB: user's can't write - INLINE[-1] f; it's syntactically illegal. + What phase is after phase 0? Answer: FinalPhase, that's the reason it + exists. NB: Similar to InitialPhase, users can't write INLINE[Final] f; + it's syntactically illegal. - Otherwise inline wrapper in phase 2. That allows the 'gentle' simplification pass to apply specialisation rules ===================================== compiler/GHC/Types/Basic.hs ===================================== @@ -83,7 +83,6 @@ module GHC.Types.Basic ( Activation(..), isActive, competesWith, isNeverActive, isAlwaysActive, activeInFinalPhase, activateAfterInitial, activateDuringFinal, - finalPhase, isFinalPhase, RuleMatchInfo(..), isConLike, isFunLike, InlineSpec(..), noUserInlineSpec, @@ -1332,7 +1331,8 @@ type PhaseNum = Int -- Compilation phase data CompilerPhase = InitialPhase -- The first phase -- number = infinity! | Phase PhaseNum -- User-specificable phases - | FinalPhase + | FinalPhase -- The last phase -- number = -infinity! + deriving Eq instance Outputable CompilerPhase where ppr (Phase n) = int n @@ -1360,13 +1360,6 @@ activateDuringFinal :: Activation -- Active in the final simplification phase (which is repeated) activateDuringFinal = FinalActive -finalPhase :: CompilerPhase -finalPhase = FinalPhase - -isFinalPhase :: CompilerPhase -> Bool -isFinalPhase FinalPhase = True -isFinalPhase _ = False - isActive :: CompilerPhase -> Activation -> Bool isActive InitialPhase act = activeInInitialPhase act isActive (Phase p) act = activeInPhase p act View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a36eb7d5e727b72d550adae7cb473c73947d6e13 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a36eb7d5e727b72d550adae7cb473c73947d6e13 You're receiving 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 27 13:39:05 2020 From: gitlab at gitlab.haskell.org (Matthew Pickering) Date: Wed, 27 May 2020 09:39:05 -0400 Subject: [Git][ghc/ghc][wip/proposal-195] Use a newtype `Code` for the return type of typed quotations (Proposal #195) Message-ID: <5ece6d795af42_6e26ec1fbfc194061@gitlab.haskell.org.mail> Matthew Pickering pushed to branch wip/proposal-195 at Glasgow Haskell Compiler / GHC Commits: 3db7cff9 by Matthew Pickering at 2020-05-27T14:38:43+01:00 Use a newtype `Code` for the return type of typed quotations (Proposal #195) There are three problems with the current API: 1. It is hard to properly write instances for ``Quote m => m (TExp a)`` as the type is the composition of two type constructors. Doing so in your program involves making your own newtype and doing a lot of wrapping/unwrapping. For example, if I want to create a language which I can either run immediately or generate code from I could write the following with the new API. :: class Lang r where _int :: Int -> r Int _if :: r Bool -> r a -> r a -> r a instance Lang Identity where _int = Identity _if (Identity b) (Identity t) (Identity f) = Identity (if b then t else f) instance Quote m => Lang (Code m) where _int = liftTyped _if cb ct cf = [|| if $$cb then $$ct else $$cf ||] 2. When doing code generation it is common to want to store code fragments in a map. When doing typed code generation, these code fragments contain a type index so it is desirable to store them in one of the parameterised map data types such as ``DMap`` from ``dependent-map`` or ``MapF`` from ``parameterized-utils``. :: compiler :: Env -> AST a -> Code Q a data AST a where ... data Ident a = ... type Env = MapF Ident (Code Q) newtype Code m a = Code (m (TExp a)) In this example, the ``MapF`` maps an ``Ident String`` directly to a ``Code Q String``. Using one of these map types currently requires creating your own newtype and constantly wrapping every quotation and unwrapping it when using a splice. Achievable, but it creates even more syntactic noise than normal metaprogramming. 3. ``m (TExp a)`` is ugly to read and write, understanding ``Code m a`` is easier. This is a weak reason but one everyone can surely agree with. - - - - - 30 changed files: - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Gen/Splice.hs - docs/users_guide/exts/deriving_extra.rst - docs/users_guide/exts/template_haskell.rst - libraries/template-haskell/Language/Haskell/TH.hs - + libraries/template-haskell/Language/Haskell/TH/CodeDo.hs - libraries/template-haskell/Language/Haskell/TH/Lib.hs - libraries/template-haskell/Language/Haskell/TH/Lib/Internal.hs - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/changelog.md - libraries/template-haskell/template-haskell.cabal.in - libraries/text - testsuite/tests/deriving/should_compile/drv-empty-data.stderr - testsuite/tests/parser/should_compile/Proposal229f_instances.hs - testsuite/tests/partial-sigs/should_compile/TypedSplice.hs - testsuite/tests/partial-sigs/should_compile/TypedSplice.stderr - testsuite/tests/quotes/T17857.hs - testsuite/tests/th/T10945.stderr - testsuite/tests/th/T15471A.hs - testsuite/tests/th/T15843.hs - testsuite/tests/th/T16195A.hs - testsuite/tests/th/T18121.hs - testsuite/tests/th/T8577.stderr - testsuite/tests/th/T8577a.hs - testsuite/tests/th/TH_StringLift.hs - testsuite/tests/th/TH_reifyLocalDefs.hs - testsuite/tests/th/overloaded/T17839.hs - testsuite/tests/th/overloaded/TH_overloaded_constraints.hs - testsuite/tests/th/overloaded/TH_overloaded_csp.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3db7cff992ec13f4cbeb355e3b623fd6c87949a8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3db7cff992ec13f4cbeb355e3b623fd6c87949a8 You're receiving 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 27 15:27:41 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 27 May 2020 11:27:41 -0400 Subject: [Git][ghc/ghc][wip/T18234] Update ci-images commit Message-ID: <5ece86edbc769_6e26b45071c1983693@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18234 at Glasgow Haskell Compiler / GHC Commits: 03a84b67 by Ben Gamari at 2020-05-27T11:27:35-04:00 Update ci-images commit - - - - - 1 changed file: - .gitlab-ci.yml 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: 35d6418c6ee0297352e6ea5f93a8ede0f2c2f931 + DOCKER_REV: ba119705df5222fe74208a85019cb980e2c4318f # Sequential version number capturing the versions of all tools fetched by # .gitlab/ci.sh. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/03a84b671c83a514c84bfe629e3dcb90c48c1d98 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/03a84b671c83a514c84bfe629e3dcb90c48c1d98 You're receiving 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 27 15:31:10 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Wed, 27 May 2020 11:31:10 -0400 Subject: [Git][ghc/ghc][wip/andreask/inlineable_mapAccumLM] Optimize GHC.Utils.Monad. Message-ID: <5ece87beb6e67_6e26a9948141987510@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/inlineable_mapAccumLM at Glasgow Haskell Compiler / GHC Commits: 8339d4aa by Andreas Klebinger at 2020-05-27T17:29:50+02:00 Optimize GHC.Utils.Monad. Many functions in this module are recursive and as such are marked loop breakers. Which means they are unlikely to get an unfolding. This is *bad*. We always want to specialize them to specific Monads. Which requires a visible unfolding at the use site. I rewrote the recursive ones from: foo f x = ... foo x' ... to foo f x = go x where go x = ... As well as giving some pragmas to make all of them available for specialization. The end result is a reduction of allocations of about -1.4% for nofib/spectral/simple/Main.hs when compiled with `-O`. - - - - - 1 changed file: - compiler/GHC/Utils/Monad.hs Changes: ===================================== compiler/GHC/Utils/Monad.hs ===================================== @@ -138,22 +138,32 @@ mapAndUnzip5M :: Monad m => (a -> m (b,c,d,e,f)) -> [a] -> m ([b],[c],[d],[e],[f -- See Note [Inline @mapAndUnzipNM@ functions] above. mapAndUnzip5M f xs = unzip5 <$> traverse f xs +-- TODO: mapAccumLM is used in many places. Surely most of +-- these don't actually want to be lazy. We should add a strict +-- variant and use it where appropriate. + -- | Monadic version of mapAccumL +{-# INLINEABLE mapAccumLM #-} mapAccumLM :: Monad m => (acc -> x -> m (acc, y)) -- ^ combining function -> acc -- ^ initial state -> [x] -- ^ inputs -> m (acc, [y]) -- ^ final state, outputs -mapAccumLM _ s [] = return (s, []) -mapAccumLM f s (x:xs) = do - (s1, x') <- f s x - (s2, xs') <- mapAccumLM f s1 xs - return (s2, x' : xs') +mapAccumLM f s xs = + go s xs + where + go s (x:xs) = do + (s1, x') <- f s x + (s2, xs') <- go s1 xs + return (s2, x' : xs') + go s [] = return (s, []) -- | Monadic version of mapSnd mapSndM :: Monad m => (b -> m c) -> [(a,b)] -> m [(a,c)] -mapSndM _ [] = return [] -mapSndM f ((a,b):xs) = do { c <- f b; rs <- mapSndM f xs; return ((a,c):rs) } +mapSndM f xs = go xs + where + go [] = return [] + go ((a,b):xs) = do { c <- f b; rs <- go xs; return ((a,c):rs) } -- | Monadic version of concatMap concatMapM :: Monad m => (a -> m [b]) -> [a] -> m [b] @@ -176,15 +186,19 @@ fmapEitherM _ fr (Right b) = fr b >>= (return . Right) -- | Monadic version of 'any', aborts the computation at the first @True@ value anyM :: Monad m => (a -> m Bool) -> [a] -> m Bool -anyM _ [] = return False -anyM f (x:xs) = do b <- f x +anyM f xs = go xs + where + go [] = return False + go (x:xs) = do b <- f x if b then return True - else anyM f xs + else go xs -- | Monad version of 'all', aborts the computation at the first @False@ value allM :: Monad m => (a -> m Bool) -> [a] -> m Bool -allM _ [] = return True -allM f (b:bs) = (f b) >>= (\bv -> if bv then allM f bs else return False) +allM f bs = go bs + where + go [] = return True + go (b:bs) = (f b) >>= (\bv -> if bv then go bs else return False) -- | Monadic version of or orM :: Monad m => m Bool -> m Bool -> m Bool View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8339d4aa2ffb46e5b6d3d04e52c9b012352bb444 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8339d4aa2ffb46e5b6d3d04e52c9b012352bb444 You're receiving 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 27 15:31:52 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Wed, 27 May 2020 11:31:52 -0400 Subject: [Git][ghc/ghc][wip/andreask/inlineable_mapAccumLM] Optimize GHC.Utils.Monad. Message-ID: <5ece87e8473b9_6e263f9f0ba3613419878c0@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/inlineable_mapAccumLM at Glasgow Haskell Compiler / GHC Commits: 6a0cafae by Andreas Klebinger at 2020-05-27T17:31:35+02:00 Optimize GHC.Utils.Monad. Many functions in this module are recursive and as such are marked loop breakers. Which means they are unlikely to get an unfolding. This is *bad*. We always want to specialize them to specific Monads. Which requires a visible unfolding at the use site. I rewrote the recursive ones from: foo f x = ... foo x' ... to foo f x = go x where go x = ... As well as giving some pragmas to make all of them available for specialization. The end result is a reduction of allocations of about -1.4% for nofib/spectral/simple/Main.hs when compiled with `-O`. - - - - - 1 changed file: - compiler/GHC/Utils/Monad.hs Changes: ===================================== compiler/GHC/Utils/Monad.hs ===================================== @@ -138,22 +138,31 @@ mapAndUnzip5M :: Monad m => (a -> m (b,c,d,e,f)) -> [a] -> m ([b],[c],[d],[e],[f -- See Note [Inline @mapAndUnzipNM@ functions] above. mapAndUnzip5M f xs = unzip5 <$> traverse f xs +-- TODO: mapAccumLM is used in many places. Surely most of +-- these don't actually want to be lazy. We should add a strict +-- variant and use it where appropriate. + -- | Monadic version of mapAccumL mapAccumLM :: Monad m => (acc -> x -> m (acc, y)) -- ^ combining function -> acc -- ^ initial state -> [x] -- ^ inputs -> m (acc, [y]) -- ^ final state, outputs -mapAccumLM _ s [] = return (s, []) -mapAccumLM f s (x:xs) = do - (s1, x') <- f s x - (s2, xs') <- mapAccumLM f s1 xs - return (s2, x' : xs') +mapAccumLM f s xs = + go s xs + where + go s (x:xs) = do + (s1, x') <- f s x + (s2, xs') <- go s1 xs + return (s2, x' : xs') + go s [] = return (s, []) -- | Monadic version of mapSnd mapSndM :: Monad m => (b -> m c) -> [(a,b)] -> m [(a,c)] -mapSndM _ [] = return [] -mapSndM f ((a,b):xs) = do { c <- f b; rs <- mapSndM f xs; return ((a,c):rs) } +mapSndM f xs = go xs + where + go [] = return [] + go ((a,b):xs) = do { c <- f b; rs <- go xs; return ((a,c):rs) } -- | Monadic version of concatMap concatMapM :: Monad m => (a -> m [b]) -> [a] -> m [b] @@ -176,15 +185,19 @@ fmapEitherM _ fr (Right b) = fr b >>= (return . Right) -- | Monadic version of 'any', aborts the computation at the first @True@ value anyM :: Monad m => (a -> m Bool) -> [a] -> m Bool -anyM _ [] = return False -anyM f (x:xs) = do b <- f x +anyM f xs = go xs + where + go [] = return False + go (x:xs) = do b <- f x if b then return True - else anyM f xs + else go xs -- | Monad version of 'all', aborts the computation at the first @False@ value allM :: Monad m => (a -> m Bool) -> [a] -> m Bool -allM _ [] = return True -allM f (b:bs) = (f b) >>= (\bv -> if bv then allM f bs else return False) +allM f bs = go bs + where + go [] = return True + go (b:bs) = (f b) >>= (\bv -> if bv then go bs else return False) -- | Monadic version of or orM :: Monad m => m Bool -> m Bool -> m Bool View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6a0cafae95b5ace1e85fdab997634bf71492c2c6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6a0cafae95b5ace1e85fdab997634bf71492c2c6 You're receiving 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 27 15:32:13 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 27 May 2020 11:32:13 -0400 Subject: [Git][ghc/ghc][wip/T18078] Implement cast worker/wrapper properly Message-ID: <5ece87fd33cea_6e263f9ed652f4cc19881c8@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18078 at Glasgow Haskell Compiler / GHC Commits: ca7ff81c by Simon Peyton Jones at 2020-05-27T11:31:39-04: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 also discovered that unsafeCoerce wasn't being inlined if the context was boring. So (\x. f (unsafeCoerce x)) would create a thunk -- yikes! I fixed that by making inlineBoringOK a bit cleverer: see Note [Inline unsafeCoerce] in GHC.Core.Unfold. I also found that unsafeCoerceName was unused, so I removed it. 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% Metric Decrease: T15164 - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Opt/CSE.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/Driver.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/SimpleOpt.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/Id/Make.hs - compiler/GHC/Types/Var.hs - compiler/GHC/Utils/Binary.hs - libraries/base/Unsafe/Coerce.hs - testsuite/tests/codeGen/should_compile/debug.stdout - testsuite/tests/deSugar/should_compile/T2431.stderr - testsuite/tests/perf/compiler/T16473.stdout - testsuite/tests/simplCore/should_compile/T13143.stderr - + testsuite/tests/simplCore/should_compile/T17673.hs - + testsuite/tests/simplCore/should_compile/T17673.stderr - + testsuite/tests/simplCore/should_compile/T18078.hs - + testsuite/tests/simplCore/should_compile/T18078.stderr - testsuite/tests/simplCore/should_compile/T3772.stdout - testsuite/tests/simplCore/should_compile/T7360.stderr - testsuite/tests/simplCore/should_compile/T7865.stdout The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ca7ff81c4b8b9888f6d415b9f7cbdd4e6b16e05e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/ca7ff81c4b8b9888f6d415b9f7cbdd4e6b16e05e You're receiving 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 27 15:37:58 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Wed, 27 May 2020 11:37:58 -0400 Subject: [Git][ghc/ghc][wip/T18235] Use HsForAllTelescope to avoid inferred, visible foralls Message-ID: <5ece8956e4cf3_6e2612d6bb6019929d7@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T18235 at Glasgow Haskell Compiler / GHC Commits: cc398811 by Ryan Scott at 2020-05-27T11:33:55-04:00 Use HsForAllTelescope to avoid inferred, visible foralls Currently, `HsForAllTy` permits the combination of `ForallVis` and `Inferred`, but you can't actually typecheck code that uses it (e.g., `forall {a} ->`). This patch refactors `HsForAllTy` to use a new `HsForAllTelescope` data type that makes a type-level distinction between visible and invisible `forall`s such that visible `forall`s do not track `Specificity`. That part of the patch is actually quite small; the rest is simply changing consumers of `HsType` to accommodate this new type. Fixes #18235. Bumps the `haddock` submodule. - - - - - 25 changed files: - compiler/GHC/Core/TyCo/Rep.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Extension.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/Docs.hs - compiler/GHC/HsToCore/Quote.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Parser.y - compiler/GHC/Rename/HsType.hs - compiler/GHC/Tc/Deriv.hs - compiler/GHC/Tc/Gen/HsType.hs - compiler/GHC/Tc/Gen/Sig.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/Tc/Module.hs - compiler/GHC/Tc/Utils/TcMType.hs - compiler/GHC/Tc/Utils/TcType.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Types/Var.hs - testsuite/tests/parser/should_compile/DumpRenamedAst.stderr - testsuite/tests/typecheck/should_fail/ExplicitSpecificity8.stderr - utils/haddock Changes: ===================================== compiler/GHC/Core/TyCo/Rep.hs ===================================== @@ -34,7 +34,7 @@ module GHC.Core.TyCo.Rep ( KindOrType, Kind, KnotTied, PredType, ThetaType, -- Synonyms - ArgFlag(..), AnonArgFlag(..), ForallVisFlag(..), + ArgFlag(..), AnonArgFlag(..), -- * Coercions Coercion(..), ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -15,7 +15,7 @@ module GHC.Core.Type ( -- $type_classification -- $representation_types - TyThing(..), Type, ArgFlag(..), AnonArgFlag(..), ForallVisFlag(..), + TyThing(..), Type, ArgFlag(..), AnonArgFlag(..), Specificity(..), KindOrType, PredType, ThetaType, Var, TyVar, isTyVar, TyCoVar, TyCoBinder, TyCoVarBinder, TyVarBinder, @@ -44,7 +44,8 @@ module GHC.Core.Type ( mkSpecForAllTy, mkSpecForAllTys, mkVisForAllTys, mkTyCoInvForAllTy, mkInfForAllTy, mkInfForAllTys, - splitForAllTys, splitForAllTysSameVis, + splitForAllTys, splitSomeForAllTys, + splitForAllTysReq, splitForAllTysInvis, splitForAllVarBndrs, splitForAllTy_maybe, splitForAllTy, splitForAllTy_ty_maybe, splitForAllTy_co_maybe, @@ -271,7 +272,7 @@ import GHC.Data.List.SetOps import GHC.Types.Unique ( nonDetCmpUnique ) import GHC.Data.Maybe ( orElse ) -import Data.Maybe ( isJust ) +import Data.Maybe ( isJust, mapMaybe ) import Control.Monad ( guard ) -- $type_classification @@ -1598,19 +1599,47 @@ splitForAllTys ty = split ty ty [] split _ (ForAllTy (Bndr tv _) ty) tvs = split ty ty (tv:tvs) split orig_ty _ tvs = (reverse tvs, orig_ty) --- | Like 'splitForAllTys', but only splits a 'ForAllTy' if --- @'sameVis' argf supplied_argf@ is 'True', where @argf@ is the visibility --- of the @ForAllTy@'s binder and @supplied_argf@ is the visibility provided --- as an argument to this function. --- Furthermore, each returned tyvar is annotated with its argf. -splitForAllTysSameVis :: ArgFlag -> Type -> ([TyCoVarBinder], Type) -splitForAllTysSameVis supplied_argf ty = split ty ty [] +-- | Like 'splitForAllTys', but only splits a 'ForAllTy' if @argf_pred argf@ +-- is 'True', where @argf@ is the visibility of the @ForAllTy@'s binder and +-- @argf_pred@ is a predicate over visibilities provided as an argument to this +-- function. Furthermore, each returned tyvar is annotated with its @argf at . +splitSomeForAllTys :: (ArgFlag -> Bool) -> Type -> ([TyCoVarBinder], Type) +splitSomeForAllTys argf_pred ty = split ty ty [] where split orig_ty ty tvs | Just ty' <- coreView ty = split orig_ty ty' tvs - split _ (ForAllTy (Bndr tv argf) ty) tvs - | argf `sameVis` supplied_argf = split ty ty ((Bndr tv argf):tvs) + split _ (ForAllTy tvb@(Bndr _ argf) ty) tvs + | argf_pred argf = split ty ty (tvb:tvs) split orig_ty _ tvs = (reverse tvs, orig_ty) +-- | Like 'splitForAllTys', but only splits 'ForAllTy's with 'Required' type +-- variable binders. Furthermore, each returned tyvar is annotated with '()'. +splitForAllTysReq :: Type -> ([ReqTVBinder], Type) +splitForAllTysReq ty = + let (all_bndrs, body) = splitSomeForAllTys isVisibleArgFlag ty + req_bndrs = mapMaybe mk_req_bndr_maybe all_bndrs in + ASSERT( req_bndrs `equalLength` all_bndrs ) + (req_bndrs, body) + where + mk_req_bndr_maybe :: TyCoVarBinder -> Maybe ReqTVBinder + mk_req_bndr_maybe (Bndr tv argf) = case argf of + Required -> Just $ Bndr tv () + Invisible _ -> Nothing + +-- | Like 'splitForAllTys', but only splits 'ForAllTy's with 'Invisible' type +-- variable binders. Furthermore, each returned tyvar is annotated with its +-- 'Specificity'. +splitForAllTysInvis :: Type -> ([InvisTVBinder], Type) +splitForAllTysInvis ty = + let (all_bndrs, body) = splitSomeForAllTys isInvisibleArgFlag ty + inv_bndrs = mapMaybe mk_inv_bndr_maybe all_bndrs in + ASSERT( inv_bndrs `equalLength` all_bndrs ) + (inv_bndrs, body) + where + mk_inv_bndr_maybe :: TyCoVarBinder -> Maybe InvisTVBinder + mk_inv_bndr_maybe (Bndr tv argf) = case argf of + Invisible s -> Just $ Bndr tv s + Required -> Nothing + -- | Like splitForAllTys, but split only for tyvars. -- This always succeeds, even if it returns only an empty list. Note that the -- result type returned may have free variables that were bound by a forall. ===================================== compiler/GHC/Hs/Decls.hs ===================================== @@ -1533,7 +1533,9 @@ pprConDecl (ConDeclH98 { con_name = L _ con , con_mb_cxt = mcxt , con_args = args , con_doc = doc }) - = sep [ppr_mbDoc doc, pprHsForAll ForallInvis ex_tvs cxt, ppr_details args] + = sep [ ppr_mbDoc doc + , pprHsForAll (mkHsForAllInvisTele ex_tvs) cxt + , ppr_details args ] where ppr_details (InfixCon t1 t2) = hsep [ppr t1, pprInfixOcc con, ppr t2] ppr_details (PrefixCon tys) = hsep (pprPrefixOcc con @@ -1546,7 +1548,7 @@ pprConDecl (ConDeclGADT { con_names = cons, con_qvars = qvars , con_mb_cxt = mcxt, con_args = args , con_res_ty = res_ty, con_doc = doc }) = ppr_mbDoc doc <+> ppr_con_names cons <+> dcolon - <+> (sep [pprHsForAll ForallInvis qvars cxt, + <+> (sep [pprHsForAll (mkHsForAllInvisTele qvars) cxt, ppr_arrow_chain (get_args args ++ [ppr res_ty]) ]) where get_args (PrefixCon args) = map ppr args @@ -1822,7 +1824,7 @@ pprHsFamInstLHS :: (OutputableBndrId p) -> LHsContext (GhcPass p) -> SDoc pprHsFamInstLHS thing bndrs typats fixity mb_ctxt - = hsep [ pprHsExplicitForAll ForallInvis bndrs + = hsep [ pprHsExplicitForAll bndrs , pprLHsContext mb_ctxt , pp_pats typats ] where ===================================== compiler/GHC/Hs/Extension.hs ===================================== @@ -716,6 +716,12 @@ type family XXType x -- --------------------------------------------------------------------- +type family XHsForAllVis x +type family XHsForAllInvis x +type family XXHsForAllTelescope x + +-- --------------------------------------------------------------------- + type family XUserTyVar x type family XKindedTyVar x type family XXTyVarBndr x ===================================== compiler/GHC/Hs/Instances.hs ===================================== @@ -391,6 +391,11 @@ deriving instance Data (HsPatSigType GhcPs) deriving instance Data (HsPatSigType GhcRn) deriving instance Data (HsPatSigType GhcTc) +-- deriving instance (DataIdLR p p) => Data (HsForAllTelescope p) +deriving instance Data (HsForAllTelescope GhcPs) +deriving instance Data (HsForAllTelescope GhcRn) +deriving instance Data (HsForAllTelescope GhcTc) + -- deriving instance (DataIdLR p p) => Data (HsTyVarBndr p) deriving instance (Data flag) => Data (HsTyVarBndr flag GhcPs) deriving instance (Data flag) => Data (HsTyVarBndr flag GhcRn) ===================================== compiler/GHC/Hs/Type.hs ===================================== @@ -9,6 +9,7 @@ GHC.Hs.Type: Abstract syntax: user-defined types {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow] @@ -19,7 +20,7 @@ GHC.Hs.Type: Abstract syntax: user-defined types module GHC.Hs.Type ( HsType(..), NewHsTypeX(..), LHsType, HsKind, LHsKind, - HsTyVarBndr(..), LHsTyVarBndr, ForallVisFlag(..), + HsForAllTelescope(..), HsTyVarBndr(..), LHsTyVarBndr, LHsQTyVars(..), HsImplicitBndrs(..), HsWildCardBndrs(..), @@ -51,6 +52,7 @@ module GHC.Hs.Type ( mkHsImplicitBndrs, mkHsWildCardBndrs, mkHsPatSigType, hsImplicitBody, mkEmptyImplicitBndrs, mkEmptyWildCardBndrs, + mkHsForAllVisTele, mkHsForAllInvisTele, mkHsQTvs, hsQTvExplicit, emptyLHsQTvs, isHsKindedTyVar, hsTvbAllKinded, isLHsForAllTy, hsScopedTvs, hsWcScopedTvs, dropWildCards, @@ -162,7 +164,7 @@ is a bit complicated. Here's how it works. These constructors represent what the user wrote, no more and no less. -* The ForallVisFlag field of HsForAllTy represents whether a forall is +* The ForAllTelescope field of HsForAllTy represents whether a forall is invisible (e.g., forall a b. {...}, with a dot) or visible (e.g., forall a b -> {...}, with an arrow). @@ -328,6 +330,28 @@ type LHsKind pass = Located (HsKind pass) -- LHsQTyVars -- The explicitly-quantified binders in a data/type declaration +-- | The type variable binders in an 'HsForAllTy'. +-- See also @Note [Variable Specificity and Forall Visibility]@ in +-- "GHC.Tc.Gen.HsType". +data HsForAllTelescope pass + = HsForAllVis -- ^ A visible @forall@ (e.g., @forall a -> {...}@). + -- These do not have any notion of specificity, so we use + -- '()' as a placeholder value. + { hsf_xvis :: XHsForAllVis pass + , hsf_vis_bndrs :: [LHsTyVarBndr () pass] + } + | HsForAllInvis -- ^ An invisible @forall@ (e.g., @forall a {b} c -> {...}@), + -- where each binder has a 'Specificity'. + { hsf_xinvis :: XHsForAllInvis pass + , hsf_invis_bndrs :: [LHsTyVarBndr Specificity pass] + } + | XHsForAllTelescope !(XXHsForAllTelescope pass) + +type instance XHsForAllVis (GhcPass _) = NoExtField +type instance XHsForAllInvis (GhcPass _) = NoExtField + +type instance XXHsForAllTelescope (GhcPass _) = NoExtCon + -- | Located Haskell Type Variable Binder type LHsTyVarBndr flag pass = Located (HsTyVarBndr flag pass) -- See Note [HsType binders] @@ -351,6 +375,16 @@ type instance XHsQTvs GhcTc = HsQTvsRn type instance XXLHsQTyVars (GhcPass _) = NoExtCon +mkHsForAllVisTele :: + [LHsTyVarBndr () (GhcPass p)] -> HsForAllTelescope (GhcPass p) +mkHsForAllVisTele vis_bndrs = + HsForAllVis { hsf_xvis = noExtField, hsf_vis_bndrs = vis_bndrs } + +mkHsForAllInvisTele :: + [LHsTyVarBndr Specificity (GhcPass p)] -> HsForAllTelescope (GhcPass p) +mkHsForAllInvisTele invis_bndrs = + HsForAllInvis { hsf_xinvis = noExtField, hsf_invis_bndrs = invis_bndrs } + mkHsQTvs :: [LHsTyVarBndr () GhcPs] -> LHsQTyVars GhcPs mkHsQTvs tvs = HsQTvs { hsq_ext = noExtField, hsq_explicit = tvs } @@ -474,7 +508,7 @@ E.g. For a signature like f :: forall (a::k). blah we get HsIB { hsib_vars = [k] - , hsib_body = HsForAllTy { hst_bndrs = [(a::*)] + , hsib_body = HsForAllTy { hst_tele = HsForAllInvis [(a::*)] , hst_body = blah } The implicit kind variable 'k' is bound by the HsIB; the explicitly forall'd tyvar 'a' is bound by the HsForAllTy @@ -641,30 +675,12 @@ instance NamedThing (HsTyVarBndr flag GhcRn) where getName (UserTyVar _ _ v) = unLoc v getName (KindedTyVar _ _ v _) = unLoc v -{- Note [Specificity in HsForAllTy] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -All type variables in a `HsForAllTy` type are annotated with their -`Specificity`. The meaning of this `Specificity` depends on the visibility of -the binder `hst_fvf`: - -* In an invisible forall type, the `Specificity` denotes whether type variables - are `Specified` (`forall a. ...`) or `Inferred` (`forall {a}. ...`). For more - information, see Note [VarBndrs, TyCoVarBinders, TyConBinders, and visibility] - in GHC.Core.TyCo.Rep. - -* In a visible forall type, the `Specificity` has no particular meaning. We - uphold the convention that all visible forall types use `Specified` binders. --} - -- | Haskell Type data HsType pass = HsForAllTy -- See Note [HsType binders] { hst_xforall :: XForAllTy pass - , hst_fvf :: ForallVisFlag -- Is this `forall a -> {...}` or - -- `forall a. {...}`? - , hst_bndrs :: [LHsTyVarBndr Specificity pass] + , hst_tele :: HsForAllTelescope pass -- Explicit, user-supplied 'forall a {b} c' - -- see Note [Specificity in HsForAllTy] , hst_body :: LHsType pass -- body type } -- ^ - 'ApiAnnotation.AnnKeywordId' : 'ApiAnnotation.AnnForall', @@ -1074,8 +1090,8 @@ hsWcScopedTvs sig_ty , HsIB { hsib_ext = vars , hsib_body = sig_ty2 } <- sig_ty1 = case sig_ty2 of - L _ (HsForAllTy { hst_fvf = ForallInvis -- See Note [hsScopedTvs vis_flag] - , hst_bndrs = tvs }) -> + L _ (HsForAllTy { hst_tele = HsForAllInvis { hsf_invis_bndrs = tvs }}) -> + -- See Note [hsScopedTvs vis_flag] vars ++ nwcs ++ hsLTyVarNames tvs _ -> nwcs @@ -1084,8 +1100,8 @@ hsScopedTvs :: LHsSigType GhcRn -> [Name] hsScopedTvs sig_ty | HsIB { hsib_ext = vars , hsib_body = sig_ty2 } <- sig_ty - , L _ (HsForAllTy { hst_fvf = ForallInvis -- See Note [hsScopedTvs vis_flag] - , hst_bndrs = tvs }) <- sig_ty2 + , L _ (HsForAllTy { hst_tele = HsForAllInvis { hsf_invis_bndrs = tvs }}) + <- sig_ty2 -- See Note [hsScopedTvs vis_flag] = vars ++ hsLTyVarNames tvs | otherwise = [] @@ -1132,9 +1148,10 @@ The conclusion of these discussions can be summarized as follows: > vfn :: forall x y -> tau(x,y) > vfn x y = \a b -> ... -- bad! -We cement this design by pattern-matching on ForallInvis in hsScopedTvs: +We cement this design by pattern-matching on HsForAllInvis in hsScopedTvs: - hsScopedTvs (HsForAllTy { hst_fvf = ForallInvis, ... }) = ... + hsScopedTvs (HsForAllTy { hst_tele = HsForAllInvis { hst_bndrs = ... } + , ... }) = ... At the moment, GHC does not support visible 'forall' in terms. Nevertheless, it is still possible to write erroneous programs that use visible 'forall's in @@ -1143,12 +1160,12 @@ terms, such as this example: x :: forall a -> a -> a x = x -If we do not pattern-match on ForallInvis in hsScopedTvs, then `a` would +If we do not pattern-match on HsForAllInvis in hsScopedTvs, then `a` would erroneously be brought into scope over the body of `x` when renaming it. Although the typechecker would later reject this (see `GHC.Tc.Validity.vdqAllowed`), it is still possible for this to wreak havoc in the renamer before it gets to that point (see #17687 for an example of this). -Bottom line: nip problems in the bud by matching on ForallInvis from the start. +Bottom line: nip problems in the bud by matching on HsForAllInvis from the start. -} --------------------- @@ -1364,8 +1381,8 @@ splitLHsForAllTyInvis :: LHsType pass -> ([LHsTyVarBndr Specificity pass], LHsTy splitLHsForAllTyInvis lty@(L _ ty) = case ty of HsParTy _ ty' -> splitLHsForAllTyInvis ty' - HsForAllTy { hst_fvf = fvf', hst_bndrs = tvs', hst_body = body' } - | fvf' == ForallInvis + HsForAllTy { hst_tele = HsForAllInvis { hsf_invis_bndrs = tvs' } + , hst_body = body' } -> (tvs', body') _ -> ([], lty) @@ -1531,6 +1548,13 @@ instance OutputableBndrId p => Outputable (LHsQTyVars (GhcPass p)) where ppr (HsQTvs { hsq_explicit = tvs }) = interppSP tvs +instance OutputableBndrId p + => Outputable (HsForAllTelescope (GhcPass p)) where + ppr (HsForAllVis { hsf_vis_bndrs = bndrs }) = + text "HsForAllVis:" <+> ppr bndrs + ppr (HsForAllInvis { hsf_invis_bndrs = bndrs }) = + text "HsForAllInvis:" <+> ppr bndrs + instance (OutputableBndrId p, OutputableBndrFlag flag) => Outputable (HsTyVarBndr flag (GhcPass p)) where ppr = pprTyVarBndr @@ -1552,8 +1576,8 @@ pprAnonWildCard = char '_' -- | Prints a forall; When passed an empty list, prints @forall .@/@forall ->@ -- only when @-dppr-debug@ is enabled. -pprHsForAll :: (OutputableBndrId p, OutputableBndrFlag flag) - => ForallVisFlag -> [LHsTyVarBndr flag (GhcPass p)] +pprHsForAll :: OutputableBndrId p + => HsForAllTelescope (GhcPass p) -> LHsContext (GhcPass p) -> SDoc pprHsForAll = pprHsForAllExtra Nothing @@ -1564,32 +1588,30 @@ pprHsForAll = pprHsForAllExtra Nothing -- function for this is needed, as the extra-constraints wildcard is removed -- from the actual context and type, and stored in a separate field, thus just -- printing the type will not print the extra-constraints wildcard. -pprHsForAllExtra :: (OutputableBndrId p, OutputableBndrFlag flag) - => Maybe SrcSpan -> ForallVisFlag - -> [LHsTyVarBndr flag (GhcPass p)] +pprHsForAllExtra :: forall p. OutputableBndrId p + => Maybe SrcSpan + -> HsForAllTelescope (GhcPass p) -> LHsContext (GhcPass p) -> SDoc -pprHsForAllExtra extra fvf qtvs cxt - = pp_forall <+> pprLHsContextExtra (isJust extra) cxt +pprHsForAllExtra extra tele cxt + = pp_tele tele <+> pprLHsContextExtra (isJust extra) cxt where - pp_forall | null qtvs = whenPprDebug (forAllLit <> separator) - | otherwise = forAllLit <+> interppSP qtvs <> separator + pp_tele :: HsForAllTelescope (GhcPass p) -> SDoc + pp_tele tele = case tele of + HsForAllVis { hsf_vis_bndrs = qtvs } -> pp_forall (space <> arrow) qtvs + HsForAllInvis { hsf_invis_bndrs = qtvs } -> pp_forall dot qtvs - separator = ppr_forall_separator fvf + pp_forall :: forall flag. OutputableBndrFlag flag => + SDoc -> [LHsTyVarBndr flag (GhcPass p)] -> SDoc + pp_forall separator qtvs + | null qtvs = whenPprDebug (forAllLit <> separator) + | otherwise = forAllLit <+> interppSP qtvs <> separator -- | Version of 'pprHsForAll' or 'pprHsForAllExtra' that will always print -- @forall.@ when passed @Just []@. Prints nothing if passed 'Nothing' pprHsExplicitForAll :: (OutputableBndrId p) - => ForallVisFlag - -> Maybe [LHsTyVarBndr () (GhcPass p)] -> SDoc -pprHsExplicitForAll fvf (Just qtvs) = forAllLit <+> interppSP qtvs - <> ppr_forall_separator fvf -pprHsExplicitForAll _ Nothing = empty - --- | Prints an arrow for visible @forall at s (e.g., @forall a ->@) and a dot for --- invisible @forall at s (e.g., @forall a.@). -ppr_forall_separator :: ForallVisFlag -> SDoc -ppr_forall_separator ForallVis = space <> arrow -ppr_forall_separator ForallInvis = dot + => Maybe [LHsTyVarBndr () (GhcPass p)] -> SDoc +pprHsExplicitForAll (Just qtvs) = forAllLit <+> interppSP qtvs <> dot +pprHsExplicitForAll Nothing = empty pprLHsContext :: (OutputableBndrId p) => LHsContext (GhcPass p) -> SDoc @@ -1649,8 +1671,8 @@ ppr_mono_lty :: (OutputableBndrId p) => LHsType (GhcPass p) -> SDoc ppr_mono_lty ty = ppr_mono_ty (unLoc ty) ppr_mono_ty :: (OutputableBndrId p) => HsType (GhcPass p) -> SDoc -ppr_mono_ty (HsForAllTy { hst_fvf = fvf, hst_bndrs = tvs, hst_body = ty }) - = sep [pprHsForAll fvf tvs noLHsContext, ppr_mono_lty ty] +ppr_mono_ty (HsForAllTy { hst_tele = tele, hst_body = ty }) + = sep [pprHsForAll tele noLHsContext, ppr_mono_lty ty] ppr_mono_ty (HsQualTy { hst_ctxt = ctxt, hst_body = ty }) = sep [pprLHsContextAlways ctxt, ppr_mono_lty ty] ===================================== compiler/GHC/Hs/Utils.hs ===================================== @@ -694,11 +694,17 @@ typeToLHsType ty , hst_body = go tau }) go ty@(ForAllTy (Bndr _ argf) _) - | (tvs, tau) <- tcSplitForAllTysSameVis argf ty - = noLoc (HsForAllTy { hst_fvf = argToForallVisFlag argf - , hst_bndrs = map go_tv tvs + = noLoc (HsForAllTy { hst_tele = tele , hst_xforall = noExtField , hst_body = go tau }) + where + (tele, tau) + | isVisibleArgFlag argf + = let (req_tvbs, tau') = tcSplitForAllTysReq ty in + (mkHsForAllVisTele (map go_tv req_tvbs), tau') + | otherwise + = let (inv_tvbs, tau') = tcSplitForAllTysInvis ty in + (mkHsForAllInvisTele (map go_tv inv_tvbs), tau') go (TyVarTy tv) = nlHsTyVar (getRdrName tv) go (LitTy (NumTyLit n)) = noLoc $ HsTyLit noExtField (HsNumTy NoSourceText n) @@ -723,7 +729,7 @@ typeToLHsType ty args :: [Type] (head, args) = splitAppTys ty go (CastTy ty _) = go ty - go (CoercionTy co) = pprPanic "toLHsSigWcType" (ppr co) + go (CoercionTy co) = pprPanic "typeToLHsType" (ppr co) -- Source-language types have _invisible_ kind arguments, -- so we must remove them here (#8563) @@ -743,14 +749,9 @@ typeToLHsType ty Required -> f `nlHsAppTy` arg') head (zip args arg_flags) - argf_to_spec :: ArgFlag -> Specificity - argf_to_spec Required = SpecifiedSpec - -- see Note [Specificity in HsForAllTy] in GHC.Hs.Type - argf_to_spec (Invisible s) = s - - go_tv :: TyVarBinder -> LHsTyVarBndr Specificity GhcPs - go_tv (Bndr tv argf) = noLoc $ KindedTyVar noExtField - (argf_to_spec argf) + go_tv :: VarBndr TyVar flag -> LHsTyVarBndr flag GhcPs + go_tv (Bndr tv flag) = noLoc $ KindedTyVar noExtField + flag (noLoc (getRdrName tv)) (go (tyVarKind tv)) ===================================== compiler/GHC/HsToCore/Docs.hs ===================================== @@ -200,7 +200,7 @@ subordinates instMap decl = case decl of extract_deriv_ty (L l ty) = case ty of -- deriving (forall a. C a {- ^ Doc comment -}) - HsForAllTy{ hst_fvf = ForallInvis + HsForAllTy{ hst_tele = HsForAllInvis{} , hst_body = L _ (HsDocTy _ _ doc) } -> Just (l, doc) -- deriving (C a {- ^ Doc comment -}) ===================================== compiler/GHC/HsToCore/Quote.hs ===================================== @@ -1265,7 +1265,7 @@ repLTy ty = repTy (unLoc ty) -- Desugar a type headed by an invisible forall (e.g., @forall a. a@) or -- a context (e.g., @Show a => a@) into a ForallT from L.H.TH.Syntax. -- In other words, the argument to this function is always an --- @HsForAllTy ForallInvis@ or @HsQualTy at . +-- @HsForAllTy HsForAllInvis{}@ or @HsQualTy at . -- Types headed by visible foralls (which are desugared to ForallVisT) are -- handled separately in repTy. repForallT :: HsType GhcRn -> MetaM (Core (M TH.Type)) @@ -1278,14 +1278,13 @@ repForallT ty } repTy :: HsType GhcRn -> MetaM (Core (M TH.Type)) -repTy ty@(HsForAllTy { hst_fvf = fvf, hst_bndrs = tvs, hst_body = body }) = - case fvf of - ForallInvis -> repForallT ty - ForallVis -> let tvs' = map ((<$>) (setHsTyVarBndrFlag ())) tvs - -- see Note [Specificity in HsForAllTy] in GHC.Hs.Type - in addHsTyVarBinds tvs' $ \bndrs -> - do body1 <- repLTy body - repTForallVis bndrs body1 +repTy ty@(HsForAllTy { hst_tele = tele, hst_body = body }) = + case tele of + HsForAllInvis{} -> repForallT ty + HsForAllVis { hsf_vis_bndrs = tvs } -> + addHsTyVarBinds tvs $ \bndrs -> + do body1 <- repLTy body + repTForallVis bndrs body1 repTy ty@(HsQualTy {}) = repForallT ty repTy (HsTyVar _ _ (L _ n)) ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -1706,8 +1706,13 @@ instance ToHie (LHsType GhcRn) where instance ToHie (TScoped (LHsType GhcRn)) where toHie (TS tsc (L span t)) = concatM $ makeNode t span : case t of - HsForAllTy _ _ bndrs body -> - [ toHie $ tvScopes tsc (mkScope $ getLoc body) bndrs + HsForAllTy _ tele body -> + let scope = mkScope $ getLoc body in + [ case tele of + HsForAllVis { hsf_vis_bndrs = bndrs } -> + toHie $ tvScopes tsc scope bndrs + HsForAllInvis { hsf_invis_bndrs = bndrs } -> + toHie $ tvScopes tsc scope bndrs , toHie body ] HsQualTy _ ctx body -> ===================================== compiler/GHC/Iface/Type.hs ===================================== @@ -31,8 +31,7 @@ module GHC.Iface.Type ( IfaceContext, IfaceBndr(..), IfaceOneShot(..), IfaceLamBndr, IfaceTvBndr, IfaceIdBndr, IfaceTyConBinder, IfaceForAllSpecBndr, - IfaceForAllBndr, ArgFlag(..), AnonArgFlag(..), - ForallVisFlag(..), ShowForAllFlag(..), + IfaceForAllBndr, ArgFlag(..), AnonArgFlag(..), ShowForAllFlag(..), mkIfaceForAllTvBndr, mkIfaceTyConKind, ifaceForAllSpecToBndrs, ifaceForAllSpecToBndr, ===================================== compiler/GHC/Parser.y ===================================== @@ -1888,9 +1888,16 @@ unpackedness :: { Located ([AddAnn], SourceText, SrcUnpackedness) } : '{-# UNPACK' '#-}' { sLL $1 $> ([mo $1, mc $2], getUNPACK_PRAGs $1, SrcUnpack) } | '{-# NOUNPACK' '#-}' { sLL $1 $> ([mo $1, mc $2], getNOUNPACK_PRAGs $1, SrcNoUnpack) } -forall_vis_flag :: { (AddAnn, ForallVisFlag) } - : '.' { (mj AnnDot $1, ForallInvis) } - | '->' { (mu AnnRarrow $1, ForallVis) } +forall_telescope :: { Located ([AddAnn], HsForAllTelescope GhcPs) } + : 'forall' tv_bndrs '.' {% do { hintExplicitForall $1 + ; pure $ sLL $1 $> + ( [mu AnnForall $1, mu AnnDot $3] + , mkHsForAllInvisTele $2 ) }} + | 'forall' tv_bndrs '->' {% do { hintExplicitForall $1 + ; req_tvbs <- fromSpecTyVarBndrs $2 + ; pure $ sLL $1 $> $ + ( [mu AnnForall $1, mu AnnRarrow $3] + , mkHsForAllVisTele req_tvbs ) }} -- A ktype/ktypedoc is a ctype/ctypedoc, possibly with a kind annotation ktype :: { LHsType GhcPs } @@ -1905,15 +1912,12 @@ ktypedoc :: { LHsType GhcPs } -- A ctype is a for-all type ctype :: { LHsType GhcPs } - : 'forall' tv_bndrs forall_vis_flag ctype - {% let (fv_ann, fv_flag) = $3 in - hintExplicitForall $1 *> - ams (sLL $1 $> $ - HsForAllTy { hst_fvf = fv_flag - , hst_bndrs = $2 - , hst_xforall = noExtField - , hst_body = $4 }) - [mu AnnForall $1,fv_ann] } + : forall_telescope ctype {% let (forall_anns, forall_tele) = unLoc $1 in + ams (sLL $1 $> $ + HsForAllTy { hst_tele = forall_tele + , hst_xforall = noExtField + , hst_body = $2 }) + forall_anns } | context '=>' ctype {% addAnnotation (gl $1) (toUnicodeAnn AnnDarrow $2) (gl $2) >> return (sLL $1 $> $ HsQualTy { hst_ctxt = $1 @@ -1935,15 +1939,12 @@ ctype :: { LHsType GhcPs } -- to 'field' or to 'Int'. So we must use `ctype` to describe the type. ctypedoc :: { LHsType GhcPs } - : 'forall' tv_bndrs forall_vis_flag ctypedoc - {% let (fv_ann, fv_flag) = $3 in - hintExplicitForall $1 *> - ams (sLL $1 $> $ - HsForAllTy { hst_fvf = fv_flag - , hst_bndrs = $2 - , hst_xforall = noExtField - , hst_body = $4 }) - [mu AnnForall $1,fv_ann] } + : forall_telescope ctypedoc {% let (forall_anns, forall_tele) = unLoc $1 in + ams (sLL $1 $> $ + HsForAllTy { hst_tele = forall_tele + , hst_xforall = noExtField + , hst_body = $2 }) + forall_anns } | context '=>' ctypedoc {% addAnnotation (gl $1) (toUnicodeAnn AnnDarrow $2) (gl $2) >> return (sLL $1 $> $ HsQualTy { hst_ctxt = $1 ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -23,6 +23,7 @@ module GHC.Rename.HsType ( checkPrecMatch, checkSectionPrec, -- Binding related stuff + bindHsForAllTelescope, bindLHsTyVarBndr, bindLHsTyVarBndrs, rnImplicitBndrs, bindSigTyVarsFV, bindHsQTyVars, bindLRdrNames, extractHsTyRdrTyVars, extractHsTyRdrTyVarsKindVars, @@ -203,12 +204,11 @@ rnWcBody ctxt nwc_rdrs hs_ty rn_ty :: RnTyKiEnv -> HsType GhcPs -> RnM (HsType GhcRn, FreeVars) -- A lot of faff just to allow the extra-constraints wildcard to appear - rn_ty env hs_ty@(HsForAllTy { hst_fvf = fvf, hst_bndrs = tvs - , hst_body = hs_body }) - = bindLHsTyVarBndrs (rtke_ctxt env) (Just $ inTypeDoc hs_ty) Nothing tvs $ \ tvs' -> + rn_ty env hs_ty@(HsForAllTy { hst_tele = tele, hst_body = hs_body }) + = bindHsForAllTelescope (rtke_ctxt env) (Just $ inTypeDoc hs_ty) tele $ \ tele' -> do { (hs_body', fvs) <- rn_lty env hs_body - ; return (HsForAllTy { hst_fvf = fvf, hst_xforall = noExtField - , hst_bndrs = tvs', hst_body = hs_body' } + ; return (HsForAllTy { hst_xforall = noExtField + , hst_tele = tele', hst_body = hs_body' } , fvs) } rn_ty env (HsQualTy { hst_ctxt = L cx hs_ctxt @@ -401,9 +401,10 @@ check_inferred_vars ctxt (Just msg) ty = where forallty_bndrs :: LHsType GhcPs -> [HsTyVarBndr Specificity GhcPs] forallty_bndrs (L _ ty) = case ty of - HsParTy _ ty' -> forallty_bndrs ty' - HsForAllTy { hst_bndrs = tvs } -> map unLoc tvs - _ -> [] + HsParTy _ ty' -> forallty_bndrs ty' + HsForAllTy { hst_tele = HsForAllInvis { hsf_invis_bndrs = tvs }} + -> map unLoc tvs + _ -> [] {- ****************************************************** * * @@ -531,14 +532,13 @@ rnLHsTyKi env (L loc ty) rnHsTyKi :: RnTyKiEnv -> HsType GhcPs -> RnM (HsType GhcRn, FreeVars) -rnHsTyKi env ty@(HsForAllTy { hst_fvf = fvf, hst_bndrs = tyvars - , hst_body = tau }) +rnHsTyKi env ty@(HsForAllTy { hst_tele = tele, hst_body = tau }) = do { checkPolyKinds env ty - ; bindLHsTyVarBndrs (rtke_ctxt env) (Just $ inTypeDoc ty) - Nothing tyvars $ \ tyvars' -> + ; bindHsForAllTelescope (rtke_ctxt env) (Just $ inTypeDoc ty) + tele $ \ tele' -> do { (tau', fvs) <- rnLHsTyKi env tau - ; return ( HsForAllTy { hst_fvf = fvf, hst_xforall = noExtField - , hst_bndrs = tyvars' , hst_body = tau' } + ; return ( HsForAllTy { hst_xforall = noExtField + , hst_tele = tele' , hst_body = tau' } , fvs) } } rnHsTyKi env ty@(HsQualTy { hst_ctxt = lctxt, hst_body = tau }) @@ -992,6 +992,21 @@ So tvs is {k,a} and kvs is {k}. NB: we do this only at the binding site of 'tvs'. -} +bindHsForAllTelescope :: HsDocContext + -> Maybe SDoc -- Just d => check for unused tvs + -- d is a phrase like "in the type ..." + -> HsForAllTelescope GhcPs + -> (HsForAllTelescope GhcRn -> RnM (a, FreeVars)) + -> RnM (a, FreeVars) +bindHsForAllTelescope doc mb_in_doc tele thing_inside = + case tele of + HsForAllVis { hsf_vis_bndrs = bndrs } -> + bindLHsTyVarBndrs doc mb_in_doc Nothing bndrs $ \bndrs' -> + thing_inside $ mkHsForAllVisTele bndrs' + HsForAllInvis { hsf_invis_bndrs = bndrs } -> + bindLHsTyVarBndrs doc mb_in_doc Nothing bndrs $ \bndrs' -> + thing_inside $ mkHsForAllInvisTele bndrs' + bindLHsTyVarBndrs :: (OutputableBndrFlag flag) => HsDocContext -> Maybe SDoc -- Just d => check for unused tvs @@ -1773,8 +1788,8 @@ extract_lty (L _ ty) acc HsStarTy _ _ -> acc HsKindSig _ ty ki -> extract_lty ty $ extract_lty ki acc - HsForAllTy { hst_bndrs = tvs, hst_body = ty } - -> extract_hs_tv_bndrs tvs acc $ + HsForAllTy { hst_tele = tele, hst_body = ty } + -> extract_hs_for_all_telescope tele acc $ extract_lty ty [] HsQualTy { hst_ctxt = ctxt, hst_body = ty } -> extract_lctxt ctxt $ @@ -1783,6 +1798,17 @@ extract_lty (L _ ty) acc -- We deal with these separately in rnLHsTypeWithWildCards HsWildCardTy {} -> acc +extract_hs_for_all_telescope :: HsForAllTelescope GhcPs + -> FreeKiTyVarsWithDups -- Accumulator + -> FreeKiTyVarsWithDups -- Free in body + -> FreeKiTyVarsWithDups +extract_hs_for_all_telescope tele acc_vars body_fvs = + case tele of + HsForAllVis { hsf_vis_bndrs = bndrs } -> + extract_hs_tv_bndrs bndrs acc_vars body_fvs + HsForAllInvis { hsf_invis_bndrs = bndrs } -> + extract_hs_tv_bndrs bndrs acc_vars body_fvs + extractHsTvBndrs :: [LHsTyVarBndr flag GhcPs] -> FreeKiTyVarsWithDups -- Free in body -> FreeKiTyVarsWithDups -- Free in result ===================================== compiler/GHC/Tc/Deriv.hs ===================================== @@ -722,8 +722,7 @@ tcStandaloneDerivInstType ctxt HsIB { hsib_ext = vars , hsib_body = L (getLoc deriv_ty_body) $ - HsForAllTy { hst_fvf = ForallInvis - , hst_bndrs = tvs + HsForAllTy { hst_tele = mkHsForAllInvisTele tvs , hst_xforall = noExtField , hst_body = rho }} let (tvs, _theta, cls, inst_tys) = tcSplitDFunTy dfun_ty ===================================== compiler/GHC/Tc/Gen/HsType.hs ===================================== @@ -715,37 +715,31 @@ tc_hs_type mode (HsOpTy _ ty1 (L _ op) ty2) exp_kind = tc_fun_type mode ty1 ty2 exp_kind --------- Foralls -tc_hs_type mode forall@(HsForAllTy { hst_fvf = fvf, hst_bndrs = hs_tvs - , hst_body = ty }) exp_kind - = do { (tclvl, wanted, (inv_tv_bndrs, ty')) +tc_hs_type mode forall@(HsForAllTy { hst_tele = tele, hst_body = ty }) exp_kind + = do { (tclvl, wanted, (tv_bndrs, ty')) <- pushLevelAndCaptureConstraints $ - bindExplicitTKBndrs_Skol hs_tvs $ + bindExplicitTKTele_Skol tele $ tc_lhs_type mode ty exp_kind -- Do not kind-generalise here! See Note [Kind generalisation] -- Why exp_kind? See Note [Body kind of HsForAllTy] ; let skol_info = ForAllSkol (ppr forall) - m_telescope = Just (sep (map ppr hs_tvs)) + m_telescope = Just $ sep $ case tele of + HsForAllVis { hsf_vis_bndrs = hs_tvs } -> + map ppr hs_tvs + HsForAllInvis { hsf_invis_bndrs = hs_tvs } -> + map ppr hs_tvs + tv_bndrs' = construct_bndrs tv_bndrs - ; tv_bndrs <- mapM construct_bndr inv_tv_bndrs + ; emitResidualTvConstraint skol_info m_telescope (binderVars tv_bndrs') tclvl wanted - ; emitResidualTvConstraint skol_info m_telescope (binderVars tv_bndrs) tclvl wanted - - ; return (mkForAllTys tv_bndrs ty') } + ; return (mkForAllTys tv_bndrs' ty') } where - construct_bndr :: TcInvisTVBinder -> TcM TcTyVarBinder - construct_bndr (Bndr tv spec) = do { argf <- spec_to_argf spec - ; return $ mkTyVarBinder argf tv } - - -- See Note [Variable Specificity and Forall Visibility] - spec_to_argf :: Specificity -> TcM ArgFlag - spec_to_argf SpecifiedSpec = case fvf of - ForallVis -> return Required - ForallInvis -> return Specified - spec_to_argf InferredSpec = case fvf of - ForallVis -> do { addErrTc (hang (text "Unexpected inferred variable in visible forall binder:") - 2 (ppr forall)) - ; return Required } - ForallInvis -> return Inferred + construct_bndrs :: Either [TcReqTVBinder] [TcInvisTVBinder] + -> [TcTyVarBinder] + construct_bndrs (Left req_tv_bndrs) = + map (mkTyVarBinder Required . binderVar) req_tv_bndrs + construct_bndrs (Right inv_tv_bndrs) = + map tyVarSpecToBinder inv_tv_bndrs tc_hs_type mode (HsQualTy { hst_ctxt = ctxt, hst_body = rn_ty }) exp_kind | null (unLoc ctxt) @@ -880,21 +874,21 @@ tc_hs_type _ wc@(HsWildCardTy _) ek = tcAnonWildCardOcc wc ek {- Note [Variable Specificity and Forall Visibility] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -A HsForAllTy contains a ForAllVisFlag to denote the visibility of the forall -binder. Furthermore, each bound variable also has a Specificity. Together these -determine the variable binders (ArgFlag) for each variable in the generated -ForAllTy type. +A HsForAllTy contains an HsForAllTelescope to denote the visibility of the forall +binder. Furthermore, each invisible type variable binder also has a +Specificity. Together, these determine the variable binders (ArgFlag) for each +variable in the generated ForAllTy type. This table summarises this relation: --------------------------------------------------------------------------- -| User-written type ForAllVisFlag Specificity ArgFlag -|------------------------------------------------------------------------- -| f :: forall a. type ForallInvis SpecifiedSpec Specified -| f :: forall {a}. type ForallInvis InferredSpec Inferred -| f :: forall a -> type ForallVis SpecifiedSpec Required -| f :: forall {a} -> type ForallVis InferredSpec / +---------------------------------------------------------------------------- +| User-written type HsForAllTelescope Specificity ArgFlag +|--------------------------------------------------------------------------- +| f :: forall a. type HsForAllInvis SpecifiedSpec Specified +| f :: forall {a}. type HsForAllInvis InferredSpec Inferred +| f :: forall a -> type HsForAllVis SpecifiedSpec Required +| f :: forall {a} -> type HsForAllVis InferredSpec / | This last form is non-sensical and is thus rejected. --------------------------------------------------------------------------- +---------------------------------------------------------------------------- For more information regarding the interpretation of the resulting ArgFlag, see Note [VarBndrs, TyCoVarBinders, TyConBinders, and visibility] in TyCoRep. @@ -2697,6 +2691,20 @@ cloneFlexiKindedTyVarTyVar = newFlexiKindedTyVar cloneTyVarTyVar -- Explicit binders -------------------------------------- +-- | Skolemise the 'HsTyVarBndr's in an 'LHsForAllTelescope. +-- Returns 'Left' for visible @forall at s and 'Right' for invisible @forall at s. +bindExplicitTKTele_Skol + :: HsForAllTelescope GhcRn + -> TcM a + -> TcM (Either [TcReqTVBinder] [TcInvisTVBinder], a) +bindExplicitTKTele_Skol tele thing_inside = case tele of + HsForAllVis { hsf_vis_bndrs = bndrs } -> do + (req_tv_bndrs, thing) <- bindExplicitTKBndrs_Skol bndrs thing_inside + pure (Left req_tv_bndrs, thing) + HsForAllInvis { hsf_invis_bndrs = bndrs } -> do + (inv_tv_bndrs, thing) <- bindExplicitTKBndrs_Skol bndrs thing_inside + pure (Right inv_tv_bndrs, thing) + bindExplicitTKBndrs_Skol, bindExplicitTKBndrs_Tv :: (OutputableBndrFlag flag) => [LHsTyVarBndr flag GhcRn] ===================================== compiler/GHC/Tc/Gen/Sig.hs ===================================== @@ -279,8 +279,8 @@ no_anon_wc lty = go lty HsRecTy _ flds -> gos $ map (cd_fld_type . unLoc) flds HsExplicitListTy _ _ tys -> gos tys HsExplicitTupleTy _ tys -> gos tys - HsForAllTy { hst_bndrs = bndrs - , hst_body = ty } -> no_anon_wc_bndrs bndrs + HsForAllTy { hst_tele = tele + , hst_body = ty } -> no_anon_wc_tele tele && go ty HsQualTy { hst_ctxt = L _ ctxt , hst_body = ty } -> gos ctxt && go ty @@ -293,8 +293,10 @@ no_anon_wc lty = go lty gos = all go -no_anon_wc_bndrs :: [LHsTyVarBndr flag GhcRn] -> Bool -no_anon_wc_bndrs ltvs = all (go . unLoc) ltvs +no_anon_wc_tele :: HsForAllTelescope GhcRn -> Bool +no_anon_wc_tele tele = case tele of + HsForAllVis { hsf_vis_bndrs = ltvs } -> all (go . unLoc) ltvs + HsForAllInvis { hsf_invis_bndrs = ltvs } -> all (go . unLoc) ltvs where go (UserTyVar _ _ _) = True go (KindedTyVar _ _ _ ki) = no_anon_wc ki ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -2123,19 +2123,19 @@ reifyType ty@(CoercionTy {})= noTH (sLit "coercions in types") (ppr ty) reify_for_all :: TyCoRep.ArgFlag -> TyCoRep.Type -> TcM TH.Type -- Arg of reify_for_all is always ForAllTy or a predicate FunTy -reify_for_all argf ty = do - tvbndrs' <- reifyTyVarBndrs tvbndrs - case argToForallVisFlag argf of - ForallVis -> do phi' <- reifyType phi - let tvs = map (() <$) tvbndrs' - -- see Note [Specificity in HsForAllTy] in GHC.Hs.Type - pure $ TH.ForallVisT tvs phi' - ForallInvis -> do let (cxt, tau) = tcSplitPhiTy phi - cxt' <- reifyCxt cxt - tau' <- reifyType tau - pure $ TH.ForallT tvbndrs' cxt' tau' - where - (tvbndrs, phi) = tcSplitForAllTysSameVis argf ty +reify_for_all argf ty + | isVisibleArgFlag argf + = do let (req_bndrs, phi) = tcSplitForAllTysReq ty + tvbndrs' <- reifyTyVarBndrs req_bndrs + phi' <- reifyType phi + pure $ TH.ForallVisT tvbndrs' phi' + | otherwise + = do let (inv_bndrs, phi) = tcSplitForAllTysInvis ty + tvbndrs' <- reifyTyVarBndrs inv_bndrs + let (cxt, tau) = tcSplitPhiTy phi + cxt' <- reifyCxt cxt + tau' <- reifyType tau + pure $ TH.ForallT tvbndrs' cxt' tau' reifyTyLit :: TyCoRep.TyLit -> TcM TH.TyLit reifyTyLit (NumTyLit n) = return (TH.NumTyLit n) @@ -2177,10 +2177,6 @@ instance ReifyFlag Specificity TH.Specificity where reifyFlag SpecifiedSpec = TH.SpecifiedSpec reifyFlag InferredSpec = TH.InferredSpec -instance ReifyFlag ArgFlag TH.Specificity where - reifyFlag Required = TH.SpecifiedSpec - reifyFlag (Invisible s) = reifyFlag s - reifyTyVars :: [TyVar] -> TcM [TH.TyVarBndr ()] reifyTyVars = reifyTyVarBndrs . map mk_bndr where ===================================== compiler/GHC/Tc/Module.hs ===================================== @@ -2443,8 +2443,8 @@ getGhciStepIO = do ioM = nlHsAppTy (nlHsTyVar ioTyConName) (nlHsTyVar a_tv) step_ty = noLoc $ HsForAllTy - { hst_fvf = ForallInvis - , hst_bndrs = [noLoc $ UserTyVar noExtField SpecifiedSpec (noLoc a_tv)] + { hst_tele = mkHsForAllInvisTele + [noLoc $ UserTyVar noExtField SpecifiedSpec (noLoc a_tv)] , hst_xforall = noExtField , hst_body = nlHsFunTy ghciM ioM } ===================================== compiler/GHC/Tc/Utils/TcMType.hs ===================================== @@ -548,14 +548,8 @@ tcInstTypeBndrs :: ([VarBndr TyVar Specificity] -> TcM (TCvSubst, [VarBndr TcTyV -> TcM ([(Name, VarBndr TcTyVar Specificity)], TcThetaType, TcType) -- ^ Result -- (type vars, preds (incl equalities), rho) tcInstTypeBndrs inst_tyvars id = - let (tyvars, rho) = splitForAllVarBndrs (idType id) - tyvars' = map argf_to_spec tyvars - in tc_inst_internal inst_tyvars tyvars' rho - where - argf_to_spec :: VarBndr TyCoVar ArgFlag -> VarBndr TyCoVar Specificity - argf_to_spec (Bndr tv Required) = Bndr tv SpecifiedSpec - -- see Note [Specificity in HsForAllTy] in GHC.Hs.Type - argf_to_spec (Bndr tv (Invisible s)) = Bndr tv s + let (tyvars, rho) = splitForAllTysInvis (idType id) + in tc_inst_internal inst_tyvars tyvars rho tcSkolDFunType :: DFunId -> TcM ([TcTyVar], TcThetaType, TcType) -- Instantiate a type signature with skolem constants. ===================================== compiler/GHC/Tc/Utils/TcType.hs ===================================== @@ -21,8 +21,8 @@ module GHC.Tc.Utils.TcType ( -- Types TcType, TcSigmaType, TcRhoType, TcTauType, TcPredType, TcThetaType, TcTyVar, TcTyVarSet, TcDTyVarSet, TcTyCoVarSet, TcDTyCoVarSet, - TcKind, TcCoVar, TcTyCoVar, TcTyVarBinder, TcInvisTVBinder, TcTyCon, - KnotTied, + TcKind, TcCoVar, TcTyCoVar, TcTyVarBinder, TcInvisTVBinder, TcReqTVBinder, + TcTyCon, KnotTied, ExpType(..), InferResult(..), ExpSigmaType, ExpRhoType, mkCheckExpType, @@ -57,7 +57,8 @@ module GHC.Tc.Utils.TcType ( -- These are important because they do not look through newtypes getTyVar, tcSplitForAllTy_maybe, - tcSplitForAllTys, tcSplitForAllTysSameVis, + tcSplitForAllTys, tcSplitSomeForAllTys, + tcSplitForAllTysReq, tcSplitForAllTysInvis, tcSplitPiTys, tcSplitPiTy_maybe, tcSplitForAllVarBndrs, tcSplitPhiTy, tcSplitPredFunTy_maybe, tcSplitFunTy_maybe, tcSplitFunTys, tcFunArgTy, tcFunResultTy, tcFunResultTyN, @@ -128,7 +129,7 @@ module GHC.Tc.Utils.TcType ( -------------------------------- -- Reexported from Type Type, PredType, ThetaType, TyCoBinder, - ArgFlag(..), AnonArgFlag(..), ForallVisFlag(..), + ArgFlag(..), AnonArgFlag(..), mkForAllTy, mkForAllTys, mkInvisForAllTys, mkTyCoInvForAllTys, mkSpecForAllTys, mkTyCoInvForAllTy, @@ -340,6 +341,7 @@ type TcTyCoVar = Var -- Either a TcTyVar or a CoVar type TcTyVarBinder = TyVarBinder type TcInvisTVBinder = InvisTVBinder +type TcReqTVBinder = ReqTVBinder type TcTyCon = TyCon -- these can be the TcTyCon constructor -- These types do not have boxy type variables in them @@ -1211,14 +1213,25 @@ tcSplitForAllTys ty = ASSERT( all isTyVar (fst sty) ) sty where sty = splitForAllTys ty --- | Like 'tcSplitForAllTys', but only splits a 'ForAllTy' if --- @'sameVis' argf supplied_argf@ is 'True', where @argf@ is the visibility --- of the @ForAllTy@'s binder and @supplied_argf@ is the visibility provided --- as an argument to this function. --- All split tyvars are annotated with their argf. -tcSplitForAllTysSameVis :: ArgFlag -> Type -> ([TyVarBinder], Type) -tcSplitForAllTysSameVis supplied_argf ty = ASSERT( all (isTyVar . binderVar) (fst sty) ) sty - where sty = splitForAllTysSameVis supplied_argf ty +-- | Like 'tcSplitForAllTys', but only splits a 'ForAllTy' if @argf_pred argf@ +-- is 'True', where @argf@ is the visibility of the @ForAllTy@'s binder and +-- @argf_pred@ is a predicate over visibilities provided as an argument to this +-- function. All split tyvars are annotated with their @argf at . +tcSplitSomeForAllTys :: (ArgFlag -> Bool) -> Type -> ([TyCoVarBinder], Type) +tcSplitSomeForAllTys argf_pred ty = ASSERT( all (isTyVar . binderVar) (fst sty) ) sty + where sty = splitSomeForAllTys argf_pred ty + +-- | Like 'tcSplitForAllTys', but only splits 'ForAllTy's with 'Required' type +-- variable binders. All split tyvars are annotated with '()'. +tcSplitForAllTysReq :: Type -> ([TcReqTVBinder], Type) +tcSplitForAllTysReq ty = ASSERT( all (isTyVar . binderVar) (fst sty) ) sty + where sty = splitForAllTysReq ty + +-- | Like 'tcSplitForAllTys', but only splits 'ForAllTy's with 'Invisible' type +-- variable binders. All split tyvars are annotated with their 'Specificity'. +tcSplitForAllTysInvis :: Type -> ([TcInvisTVBinder], Type) +tcSplitForAllTysInvis ty = ASSERT( all (isTyVar . binderVar) (fst sty) ) sty + where sty = splitForAllTysInvis ty -- | Like 'tcSplitForAllTys', but splits off only named binders. tcSplitForAllVarBndrs :: Type -> ([TyVarBinder], Type) ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -1474,19 +1474,19 @@ cvtTypeKind ty_str ty ; cxt' <- cvtContext funPrec cxt ; ty' <- cvtType ty ; loc <- getL - ; let hs_ty = mkHsForAllTy loc ForallInvis tvs' rho_ty + ; let tele = mkHsForAllInvisTele tvs' + hs_ty = mkHsForAllTy loc tele rho_ty rho_ty = mkHsQualTy cxt loc cxt' ty' ; return hs_ty } ForallVisT tvs ty | null tys' - -> do { let tvs_spec = map (TH.SpecifiedSpec <$) tvs - -- see Note [Specificity in HsForAllTy] in GHC.Hs.Type - ; tvs_spec' <- cvtTvs tvs_spec - ; ty' <- cvtType ty - ; loc <- getL - ; pure $ mkHsForAllTy loc ForallVis tvs_spec' ty' } + -> do { tvs' <- cvtTvs tvs + ; ty' <- cvtType ty + ; loc <- getL + ; let tele = mkHsForAllVisTele tvs' + ; pure $ mkHsForAllTy loc tele ty' } SigT ty ki -> do { ty' <- cvtType ty @@ -1726,8 +1726,7 @@ cvtPatSynSigTy (ForallT univs reqs (ForallT exis provs ty)) ; univs' <- cvtTvs univs ; ty' <- cvtType (ForallT exis provs ty) ; let forTy = HsForAllTy - { hst_fvf = ForallInvis - , hst_bndrs = univs' + { hst_tele = mkHsForAllInvisTele univs' , hst_xforall = noExtField , hst_body = L l cxtTy } cxtTy = HsQualTy { hst_ctxt = L l [] @@ -1779,21 +1778,21 @@ unboxedSumChecks alt arity mkHsForAllTy :: SrcSpan -- ^ The location of the returned 'LHsType' if it needs an -- explicit forall - -> ForallVisFlag - -- ^ Whether this is @forall@ is visible (e.g., @forall a ->@) - -- or invisible (e.g., @forall a.@) - -> [LHsTyVarBndr Hs.Specificity GhcPs] + -> HsForAllTelescope GhcPs -- ^ The converted type variable binders -> LHsType GhcPs -- ^ The converted rho type -> LHsType GhcPs -- ^ The complete type, quantified with a forall if necessary -mkHsForAllTy loc fvf tvs rho_ty - | null tvs = rho_ty - | otherwise = L loc $ HsForAllTy { hst_fvf = fvf - , hst_bndrs = tvs +mkHsForAllTy loc tele rho_ty + | no_tvs = rho_ty + | otherwise = L loc $ HsForAllTy { hst_tele = tele , hst_xforall = noExtField , hst_body = rho_ty } + where + no_tvs = case tele of + HsForAllVis { hsf_vis_bndrs = bndrs } -> null bndrs + HsForAllInvis { hsf_invis_bndrs = bndrs } -> null bndrs -- | If passed an empty 'TH.Cxt', this simply returns the third argument -- (an 'LHsType'). Otherwise, return an 'HsQualTy' using the provided ===================================== compiler/GHC/Types/Var.hs ===================================== @@ -65,11 +65,10 @@ module GHC.Types.Var ( -- * ArgFlags ArgFlag(Invisible,Required,Specified,Inferred), isVisibleArgFlag, isInvisibleArgFlag, sameVis, - AnonArgFlag(..), ForallVisFlag(..), argToForallVisFlag, - Specificity(..), + AnonArgFlag(..), Specificity(..), -- * TyVar's - VarBndr(..), TyCoVarBinder, TyVarBinder, InvisTVBinder, + VarBndr(..), TyCoVarBinder, TyVarBinder, InvisTVBinder, ReqTVBinder, binderVar, binderVars, binderArgFlag, binderType, mkTyCoVarBinder, mkTyCoVarBinders, mkTyVarBinder, mkTyVarBinders, @@ -405,7 +404,6 @@ data ArgFlag = Invisible Specificity -- (<) on ArgFlag means "is less visible than" -- | Whether an 'Invisible' argument may appear in source Haskell. --- see Note [Specificity in HsForAllTy] in GHC.Hs.Type data Specificity = InferredSpec -- ^ the argument may not appear in source Haskell, it is -- only inferred. @@ -469,7 +467,6 @@ instance Binary ArgFlag where -- Appears here partly so that it's together with its friend ArgFlag, -- but also because it is used in IfaceType, rather early in the -- compilation chain --- See Note [AnonArgFlag vs. ForallVisFlag] data AnonArgFlag = VisArg -- ^ Used for @(->)@: an ordinary non-dependent arrow. -- The argument is visible in source code. @@ -491,47 +488,6 @@ instance Binary AnonArgFlag where 0 -> return VisArg _ -> return InvisArg --- | Is a @forall@ invisible (e.g., @forall a b. {...}@, with a dot) or visible --- (e.g., @forall a b -> {...}@, with an arrow)? - --- See Note [AnonArgFlag vs. ForallVisFlag] -data ForallVisFlag - = ForallVis -- ^ A visible @forall@ (with an arrow) - | ForallInvis -- ^ An invisible @forall@ (with a dot) - deriving (Eq, Ord, Data) - -instance Outputable ForallVisFlag where - ppr f = text $ case f of - ForallVis -> "ForallVis" - ForallInvis -> "ForallInvis" - --- | Convert an 'ArgFlag' to its corresponding 'ForallVisFlag'. -argToForallVisFlag :: ArgFlag -> ForallVisFlag -argToForallVisFlag Required = ForallVis -argToForallVisFlag Specified = ForallInvis -argToForallVisFlag Inferred = ForallInvis - -{- -Note [AnonArgFlag vs. ForallVisFlag] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The AnonArgFlag and ForallVisFlag data types are quite similar at a first -glance: - - data AnonArgFlag = VisArg | InvisArg - data ForallVisFlag = ForallVis | ForallInvis - -Both data types keep track of visibility of some sort. AnonArgFlag tracks -whether a FunTy has a visible argument (->) or an invisible predicate argument -(=>). ForallVisFlag tracks whether a `forall` quantifier is visible -(forall a -> {...}) or invisible (forall a. {...}). - -Given their similarities, it's tempting to want to combine these two data types -into one, but they actually represent distinct concepts. AnonArgFlag reflects a -property of *Core* types, whereas ForallVisFlag reflects a property of the GHC -AST. In other words, AnonArgFlag is all about internals, whereas ForallVisFlag -is all about surface syntax. Therefore, they are kept as separate data types. --} - {- ********************************************************************* * * * VarBndr, TyCoVarBinder @@ -541,13 +497,16 @@ is all about surface syntax. Therefore, they are kept as separate data types. -- Variable Binder -- -- VarBndr is polymorphic in both var and visibility fields. --- Currently there are six different uses of 'VarBndr': +-- Currently there are nine different uses of 'VarBndr': -- * Var.TyVarBinder = VarBndr TyVar ArgFlag -- * Var.TyCoVarBinder = VarBndr TyCoVar ArgFlag +-- * Var.InvisTVBinder = VarBndr TyVar Specificity +-- * Var.ReqTVBinder = VarBndr TyVar () -- * TyCon.TyConBinder = VarBndr TyVar TyConBndrVis -- * TyCon.TyConTyCoBinder = VarBndr TyCoVar TyConBndrVis --- * IfaceType.IfaceForAllBndr = VarBndr IfaceBndr ArgFlag --- * IfaceType.IfaceTyConBinder = VarBndr IfaceBndr TyConBndrVis +-- * IfaceType.IfaceForAllBndr = VarBndr IfaceBndr ArgFlag +-- * IfaceType.IfaceTyConBinder = VarBndr IfaceBndr TyConBndrVis +-- * IfaceType.IfaceForAllSpecBndr = VarBndr IfaceBndr Specificity data VarBndr var argf = Bndr var argf deriving( Data ) @@ -561,6 +520,7 @@ data VarBndr var argf = Bndr var argf type TyCoVarBinder = VarBndr TyCoVar ArgFlag type TyVarBinder = VarBndr TyVar ArgFlag type InvisTVBinder = VarBndr TyVar Specificity +type ReqTVBinder = VarBndr TyVar () tyVarSpecToBinders :: [VarBndr a Specificity] -> [VarBndr a ArgFlag] tyVarSpecToBinders = map tyVarSpecToBinder ===================================== testsuite/tests/parser/should_compile/DumpRenamedAst.stderr ===================================== @@ -368,13 +368,14 @@ ({ DumpRenamedAst.hs:19:11-33 } (HsForAllTy (NoExtField) - (ForallInvis) - [({ DumpRenamedAst.hs:19:18-19 } - (UserTyVar - (NoExtField) - (SpecifiedSpec) - ({ DumpRenamedAst.hs:19:18-19 } - {Name: xx})))] + (HsForAllInvis + (NoExtField) + [({ DumpRenamedAst.hs:19:18-19 } + (UserTyVar + (NoExtField) + (SpecifiedSpec) + ({ DumpRenamedAst.hs:19:18-19 } + {Name: xx})))]) ({ DumpRenamedAst.hs:19:22-33 } (HsFunTy (NoExtField) ===================================== testsuite/tests/typecheck/should_fail/ExplicitSpecificity8.stderr ===================================== @@ -1,6 +1,3 @@ -ExplicitSpecificity8.hs:9:12: error: - • Unexpected inferred variable in visible forall binder: - forall {k} -> k -> Type - • In the kind ‘forall {k} -> k -> Type’ - In the data type declaration for ‘T2’ +ExplicitSpecificity8.hs:9:19: error: + Inferred type variables are not allowed here ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 8134a3be2c01ab5f1b88fed86c4ad7cc2f417f0a +Subproject commit d16264da6c8ff97b55a523040eb3f82f759998d3 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cc398811621cb26700ec7a4390f9e8d4a8702f19 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cc398811621cb26700ec7a4390f9e8d4a8702f19 You're receiving 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 27 15:45:03 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 27 May 2020 11:45:03 -0400 Subject: [Git][ghc/ghc][wip/T17775] Simple subsumption Message-ID: <5ece8aff18d77_6e263f9eeb6d00f0199875a@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: d224b07b by Simon Peyton Jones at 2020-05-27T11:43:58-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 Updates Cabal submodule. Metric Increase: T12150 - - - - - 20 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/Type.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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d224b07b450d50089bad13dc0860b7c9d863f904 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d224b07b450d50089bad13dc0860b7c9d863f904 You're receiving 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 27 16:30:08 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 27 May 2020 12:30:08 -0400 Subject: [Git][ghc/ghc][wip/nested-cpr-2019] 33 commits: core-spec: Modify file paths according to new module hierarchy Message-ID: <5ece95908b3ce_6e2612d6bb6020189e4@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/nested-cpr-2019 at Glasgow Haskell Compiler / GHC Commits: ede24126 by Takenobu Tani at 2020-05-27T00:13:55-04:00 core-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Core.hs <= coreSyn/CoreSyn.hs * GHC/Core/Coercion.hs <= types/Coercion.hs * GHC/Core/Coercion/Axiom.hs <= types/CoAxiom.hs * GHC/Core/Coercion/Opt.hs <= types/OptCoercion.hs * GHC/Core/DataCon.hs <= basicTypes/DataCon.hs * GHC/Core/FamInstEnv.hs <= types/FamInstEnv.hs * GHC/Core/Lint.hs <= coreSyn/CoreLint.hs * GHC/Core/Subst.hs <= coreSyn/CoreSubst.hs * GHC/Core/TyCo/Rep.hs <= types/TyCoRep.hs * GHC/Core/TyCon.hs <= types/TyCon.hs * GHC/Core/Type.hs <= types/Type.hs * GHC/Core/Unify.hs <= types/Unify.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/Var.hs <= basicTypes/Var.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [skip ci] - - - - - 04750304 by Ben Gamari at 2020-05-27T00:14:33-04:00 eventlog: Fix racy flushing Previously no attempt was made to avoid multiple threads writing their capability-local eventlog buffers to the eventlog writer simultaneously. This could result in multiple eventlog streams being interleaved. Fix this by documenting that the EventLogWriter's write() and flush() functions may be called reentrantly and fix the default writer to protect its FILE* by a mutex. Fixes #18210. - - - - - d6203f24 by Joshua Price at 2020-05-27T00:15:17-04:00 Make `identifier` parse unparenthesized `->` (#18060) - - - - - 2eabe61c by Sebastian Graf at 2020-05-27T18:29:58+02:00 Nested CPR - - - - - f69d654e by Sebastian Graf at 2020-05-27T18:29:58+02:00 Move tests from stranal to cpranal - - - - - f6f67aa7 by Sebastian Graf at 2020-05-27T18:29:58+02:00 Accept FacState - - - - - 8f37b25c by Sebastian Graf at 2020-05-27T18:29:58+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. - - - - - a29e5b3f by Sebastian Graf at 2020-05-27T18:29:58+02:00 Consider unboxing effects of WW better and get rid of hack - - - - - 9373a877 by Sebastian Graf at 2020-05-27T18:29:58+02:00 stuff - - - - - 503b3fc0 by Sebastian Graf at 2020-05-27T18:29:58+02:00 Debug output - - - - - 4b2145d2 by Sebastian Graf at 2020-05-27T18:29:58+02:00 A slew of testsuite changes - - - - - f9e60261 by Sebastian Graf at 2020-05-27T18:29:58+02:00 Fix T1600 - - - - - aece58ba by Sebastian Graf at 2020-05-27T18:29:58+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. - - - - - 772ef520 by Sebastian Graf at 2020-05-27T18:29:58+02:00 Fix primop termination - - - - - 7c883ae9 by Sebastian Graf at 2020-05-27T18:29:58+02:00 Test for DataCon wrapper CPR - - - - - 10f52230 by Sebastian Graf at 2020-05-27T18:29:58+02:00 Fix CPR of bottoming functions/primops - - - - - d6171905 by Sebastian Graf at 2020-05-27T18:29:58+02:00 Fix DataConWrapperCpr and accept other test outputs - - - - - aa4568f9 by Sebastian Graf at 2020-05-27T18:29:58+02:00 Accept two more changed test outputs - - - - - 50f84626 by Sebastian Graf at 2020-05-27T18:29:58+02:00 Update CaseBinderCPR with a new function - - - - - ea7ec31c by Sebastian Graf at 2020-05-27T18:29:58+02:00 Don't give the case binder the CPR property - - - - - 8d214ac7 by Sebastian Graf at 2020-05-27T18:29:58+02:00 Prune CPR sigs to constant depth on all bindings - - - - - fcd805a1 by Sebastian Graf at 2020-05-27T18:29:58+02:00 Use variable length coding for ConTags - - - - - 943c365e by Sebastian Graf at 2020-05-27T18:29:58+02:00 Accept testuite output - - - - - e2c34b5d by Sebastian Graf at 2020-05-27T18:29:58+02:00 Don't attach CPR sigs to expandable bindings; transform their unfoldings instead - - - - - 4d593ea4 by Sebastian Graf at 2020-05-27T18:29:58+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`. - - - - - 4d1b3a93 by Sebastian Graf at 2020-05-27T18:29:58+02:00 A more modular and configurable approach to optimistic case binder CPR - - - - - 101c4954 by Sebastian Graf at 2020-05-27T18:29:58+02:00 Fix T9291 - - - - - 50bb0d16 by Sebastian Graf at 2020-05-27T18:29:58+02:00 Document -fcase-binder-cpr-depth in the user's guide - - - - - 2f47a43a by Sebastian Graf at 2020-05-27T18:29:58+02:00 Rebase woes - - - - - ae2fb002 by Sebastian Graf at 2020-05-27T18:29:58+02:00 Testsuite changes - - - - - 06182f53 by Sebastian Graf at 2020-05-27T18:29:58+02:00 Refactoring around cprAnalBind - - - - - d4711127 by Sebastian Graf at 2020-05-27T18:29:58+02:00 Fix case binder CPR by not looking into unfoldings of case binders - - - - - 22b55364 by Sebastian Graf at 2020-05-27T18:29:58+02:00 Regard all arity 0 bindings (incl. DataCon apps) as thunks - - - - - 30 changed files: - compiler/GHC/Core/Make.hs - compiler/GHC/Core/Opt/Arity.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/WorkWrap.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/CoreToIface.hs - compiler/GHC/Data/Maybe.hs - compiler/GHC/Driver/Flags.hs - compiler/GHC/Driver/Session.hs - compiler/GHC/Iface/Syntax.hs - compiler/GHC/Iface/Tidy.hs - compiler/GHC/Parser.y - compiler/GHC/Types/Cpr.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id/Info.hs - compiler/GHC/Types/Id/Make.hs - docs/core-spec/CoreLint.ott - docs/core-spec/CoreSyn.ott - docs/core-spec/README - docs/core-spec/core-spec.mng - docs/core-spec/core-spec.pdf - docs/users_guide/runtime_control.rst - docs/users_guide/using-optimisation.rst - includes/rts/EventLogWriter.h - libraries/integer-gmp/src/GHC/Integer/Type.hs - rts/eventlog/EventLogWriter.c - testsuite/tests/stranal/sigs/CaseBinderCPR.hs → testsuite/tests/cpranal/sigs/CaseBinderCPR.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a324360bdcc55e8825f04425969fd2d4b1c501df...22b553642c0b8aabfa62096fd9851073f38416b2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a324360bdcc55e8825f04425969fd2d4b1c501df...22b553642c0b8aabfa62096fd9851073f38416b2 You're receiving 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 27 16:43:45 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 27 May 2020 12:43:45 -0400 Subject: [Git][ghc/ghc][wip/tyconapp-opts] hi Message-ID: <5ece98c1f2692_6e2612d6bb60203473f@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/tyconapp-opts at Glasgow Haskell Compiler / GHC Commits: 8811b5e9 by Ben Gamari at 2020-05-27T12:43:32-04:00 hi Metric Decrease: T13035 Metric Increase: T9872c - - - - - 4 changed files: - testsuite/tests/deriving/should_compile/T14578.stderr - testsuite/tests/printer/T18052a.stderr - testsuite/tests/simplCore/should_compile/T18013.stderr - testsuite/tests/simplCore/should_compile/T7360.stderr Changes: ===================================== testsuite/tests/deriving/should_compile/T14578.stderr ===================================== @@ -13,27 +13,27 @@ 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 @GHC.Types.Type @GHC.Types.Type f g) a + -> T14578.App (Data.Functor.Compose.Compose @GHC.Types.Type @GHC.Types.Type f g) a + -> T14578.App (Data.Functor.Compose.Compose @GHC.Types.Type @GHC.Types.Type 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)) + @(T14578.App (Data.Functor.Compose.Compose @GHC.Types.Type @GHC.Types.Type 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 @GHC.Types.Type @GHC.Types.Type f g) a) + -> T14578.App (Data.Functor.Compose.Compose @GHC.Types.Type @GHC.Types.Type 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 @GHC.Types.Type @GHC.Types.Type 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 @GHC.Types.Type @GHC.Types.Type f g) a + -> T14578.App (Data.Functor.Compose.Compose @GHC.Types.Type @GHC.Types.Type 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 @GHC.Types.Type @GHC.Types.Type f g) a)) instance GHC.Base.Functor f => GHC.Base.Functor (T14578.App f) where ===================================== testsuite/tests/printer/T18052a.stderr ===================================== @@ -11,7 +11,7 @@ Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, ==================== Tidy Core ==================== Result size of Tidy Core - = {terms: 18, types: 53, coercions: 0, joins: 0/0} + = {terms: 18, types: 46, coercions: 0, joins: 0/0} -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T18052a.$b:||: :: forall {a} {b}. a -> b -> (a, b) @@ -23,7 +23,7 @@ T18052a.$b:||: = GHC.Tuple.(,) [GblId] (+++) = (++) --- RHS size: {terms: 13, types: 20, coercions: 0, joins: 0/0} +-- RHS size: {terms: 13, types: 18, coercions: 0, joins: 0/0} T18052a.$m:||: :: forall {rep :: GHC.Types.RuntimeRep} {r :: TYPE rep} {a} {b}. (a, b) -> (a -> b -> r) -> (GHC.Prim.Void# -> r) -> r ===================================== testsuite/tests/simplCore/should_compile/T18013.stderr ===================================== @@ -129,9 +129,9 @@ Rule fired: Class op fmap (BUILTIN) ==================== Tidy Core ==================== Result size of Tidy Core - = {terms: 52, types: 106, coercions: 15, joins: 0/1} + = {terms: 52, types: 101, coercions: 15, joins: 0/1} --- RHS size: {terms: 37, types: 87, coercions: 15, joins: 0/1} +-- RHS size: {terms: 37, types: 84, coercions: 15, joins: 0/1} mapMaybeRule :: forall a b. Rule IO a b -> Rule IO (Maybe a) (Maybe b) [GblId, ===================================== testsuite/tests/simplCore/should_compile/T7360.stderr ===================================== @@ -1,7 +1,7 @@ ==================== Tidy Core ==================== Result size of Tidy Core - = {terms: 114, types: 51, coercions: 0, joins: 0/0} + = {terms: 106, types: 45, coercions: 0, joins: 0/0} -- RHS size: {terms: 6, types: 3, coercions: 0, joins: 0/0} T7360.$WFoo3 [InlPrag=INLINE[0] CONLIKE] :: Int -> Foo @@ -31,15 +31,7 @@ T7360.fun4 :: () WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 20 0}] T7360.fun4 = fun1 T7360.Foo1 --- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} -T7360.fun4 :: Int -[GblId, - Cpr=m1, - Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, - WorkFree=True, Expandable=True, Guidance=IF_ARGS [] 10 20}] -T7360.fun4 = GHC.Types.I# 0# - --- RHS size: {terms: 16, types: 12, coercions: 0, joins: 0/0} +-- RHS size: {terms: 11, types: 7, coercions: 0, joins: 0/0} fun2 :: forall {a}. [a] -> ((), Int) [GblId, Arity=1, @@ -57,13 +49,9 @@ fun2 :: forall {a}. [a] -> ((), Int) })}] fun2 = \ (@a) (x :: [a]) -> - (T7360.fun5, - case x of wild { - [] -> T7360.fun4; - : ds ds1 -> - case GHC.List.$wlenAcc @a wild 0# of ww2 { __DEFAULT -> - GHC.Types.I# ww2 - } + (T7360.fun4, + case GHC.List.$wlenAcc @a x 0# of ww2 { __DEFAULT -> + GHC.Types.I# ww2 }) -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} @@ -97,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 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8811b5e918718923de9f33d74f6b4ef56b3f3d83 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8811b5e918718923de9f33d74f6b4ef56b3f3d83 You're receiving 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 27 17:00:31 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 27 May 2020 13:00:31 -0400 Subject: [Git][ghc/ghc][wip/T18151] 15 commits: Revert "Specify kind variables for inferred kinds in base." Message-ID: <5ece9caf2196f_6e2612d6bb602037273@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18151 at Glasgow Haskell Compiler / GHC Commits: 013d7120 by Ben Gamari at 2020-05-25T09:48:17-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. - - - - - 4c4312ed by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Drop redundant ad-hoc boot module check To determine whether the module is a boot module Coverage.addTicksToBinds was checking for a `boot` suffix in the module source filename. This is quite ad-hoc and shouldn't be necessary; the callsite in `deSugar` already checks that the module isn't a boot module. - - - - - 1abf3c84 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make tickBoxCount strict This could otherwise easily cause a leak of (+) thunks. - - - - - b2813750 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make ccIndices strict This just seems like a good idea. - - - - - 02e278eb by Ben Gamari at 2020-05-25T09:48:53-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. - - - - - b8c014ce by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Factor out addMixEntry - - - - - 53814a64 by Zubin Duggal at 2020-05-26T03:03:24-04:00 Add info about typeclass evidence to .hie files See `testsuite/tests/hiefile/should_run/HieQueries.hs` and `testsuite/tests/hiefile/should_run/HieQueries.stdout` for an example of this We add two new fields, `EvidenceVarBind` and `EvidenceVarUse` to the `ContextInfo` associated with an Identifier. These are associated with the appropriate identifiers for the evidence variables collected when we come across `HsWrappers`, `TcEvBinds` and `IPBinds` while traversing the AST. Instance dictionary and superclass selector dictionaries from `tcg_insts` and classes defined in `tcg_tcs` are also recorded in the AST as originating from their definition span This allows us to save a complete picture of the evidence constructed by the constraint solver, and will let us report this to the user, enabling features like going to the instance definition from the invocation of a class method(or any other method taking a constraint) and finding all usages of a particular instance. Additionally, - Mark NodeInfo with an origin so we can differentiate between bindings origininating in the source vs those in ghc - Along with typeclass evidence info, also include information on Implicit Parameters - Add a few utility functions to HieUtils in order to query the new info Updates haddock submodule - - - - - 6604906c by Sebastian Graf at 2020-05-26T03:04:04-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. - - - - - cf772f19 by Sylvain Henry at 2020-05-26T03:04:45-04:00 Enhance Note [About units] for Backpack - - - - - ede24126 by Takenobu Tani at 2020-05-27T00:13:55-04:00 core-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Core.hs <= coreSyn/CoreSyn.hs * GHC/Core/Coercion.hs <= types/Coercion.hs * GHC/Core/Coercion/Axiom.hs <= types/CoAxiom.hs * GHC/Core/Coercion/Opt.hs <= types/OptCoercion.hs * GHC/Core/DataCon.hs <= basicTypes/DataCon.hs * GHC/Core/FamInstEnv.hs <= types/FamInstEnv.hs * GHC/Core/Lint.hs <= coreSyn/CoreLint.hs * GHC/Core/Subst.hs <= coreSyn/CoreSubst.hs * GHC/Core/TyCo/Rep.hs <= types/TyCoRep.hs * GHC/Core/TyCon.hs <= types/TyCon.hs * GHC/Core/Type.hs <= types/Type.hs * GHC/Core/Unify.hs <= types/Unify.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/Var.hs <= basicTypes/Var.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [skip ci] - - - - - 04750304 by Ben Gamari at 2020-05-27T00:14:33-04:00 eventlog: Fix racy flushing Previously no attempt was made to avoid multiple threads writing their capability-local eventlog buffers to the eventlog writer simultaneously. This could result in multiple eventlog streams being interleaved. Fix this by documenting that the EventLogWriter's write() and flush() functions may be called reentrantly and fix the default writer to protect its FILE* by a mutex. Fixes #18210. - - - - - d6203f24 by Joshua Price at 2020-05-27T00:15:17-04:00 Make `identifier` parse unparenthesized `->` (#18060) - - - - - bd9f5589 by Ben Gamari at 2020-05-27T12:44:10-04:00 testsuite: Add test for #18151 - - - - - 95a9eb73 by Ben Gamari at 2020-05-27T12:44:10-04:00 testsuite: Add test for desugaring of PostfixOperators - - - - - b1dbd625 by Ben Gamari at 2020-05-27T13:00:23-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. - - - - - 30 changed files: - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/HsToCore/Coverage.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Debug.hs - compiler/GHC/Iface/Ext/Types.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Parser.y - compiler/GHC/Unit.hs - docs/core-spec/CoreLint.ott - docs/core-spec/CoreSyn.ott - docs/core-spec/README - docs/core-spec/core-spec.mng - docs/core-spec/core-spec.pdf - docs/users_guide/runtime_control.rst - docs/users_guide/using-optimisation.rst - includes/rts/EventLogWriter.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/Product.hs - libraries/base/Data/Functor/Sum.hs - libraries/base/Data/Type/Coercion.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cca6673d4771eba253c8c0b15707059e098983d4...b1dbd625493ae1bf984cf51177011baf9c677c0a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cca6673d4771eba253c8c0b15707059e098983d4...b1dbd625493ae1bf984cf51177011baf9c677c0a You're receiving 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 27 17:07:31 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 27 May 2020 13:07:31 -0400 Subject: [Git][ghc/ghc][wip/T14781] 97 commits: Fix unboxed-sums GC ptr-slot rubbish value (#17791) Message-ID: <5ece9e5384f2d_6e2612d6bb60203809a@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T14781 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. - - - - - 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. - - - - - 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] - - - - - 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 - - - - - 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 - - - - - 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. - - - - - 78c6523c by Ben Gamari at 2020-05-21T12:13:01-04:00 nonmoving: Optimise the write barrier - - - - - 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). - - - - - 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 - - - - - b7a6b2f4 by Gleb Popov at 2020-05-21T12:15:26-04:00 gitlab-ci: Set locale to C.UTF-8. - - - - - 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. - - - - - 0004ccb8 by Tuan Le at 2020-05-21T12:16:46-04:00 llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 - - - - - 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 - - - - - 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 - - - - - 2b363ebb by Richard Eisenberg at 2020-05-21T12:18:45-04:00 MR template should ask for key part - - - - - a95bbd0b by Sebastian Graf at 2020-05-21T12:19:37-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. - - - - - d3d055b8 by Galen Huntington at 2020-05-21T12:20:18-04:00 Clarify pitfalls of NegativeLiterals; see #18022. - - - - - 1b508a9e by Alexey Kuleshevich at 2020-05-21T12:21:02-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" - - - - - 4ca0c8a1 by Andreas Klebinger at 2020-05-21T12:21: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. - - - - - a1275081 by Krzysztof Gogolewski at 2020-05-21T12:22:35-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 - - - - - 8a816e5f by Krzysztof Gogolewski at 2020-05-21T12:23:55-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. - - - - - 566cc73f by Sylvain Henry at 2020-05-21T12:24:45-04:00 Move isDynLinkName into GHC.Types.Name It doesn't belong into GHC.Unit.State - - - - - d830bbc9 by Adam Sandberg Ericsson at 2020-05-23T13:36:20-04:00 docs: fix formatting and add some links [skip ci] - - - - - 49301ad6 by Andrew Martin at 2020-05-23T13:37:01-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. - - - - - dcd6bdcc by Ben Gamari at 2020-05-23T13:37:48-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. - - - - - 82cb8913 by John Ericson at 2020-05-23T13:38:32-04:00 Fix #18145 and also avoid needless work with implicit vars - `forAllOrNothing` now is monadic, so we can trace whether we bind an explicit `forall` or not. - #18145 arose because the free vars calculation was needlessly complex. It is now greatly simplified. - Replaced some other implicit var code with `filterFreeVarsToBind`. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - a60dc835 by Ben Gamari at 2020-05-23T13:39:12-04:00 Bump process submodule Fixes #17926. - - - - - 856adf54 by Ben Gamari at 2020-05-23T13:40:21-04:00 users-guide: Clarify meaning of -haddock flag Fixes #18206. - - - - - 7ae57afd by Ben Gamari at 2020-05-23T13:41:03-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 - - - - - 63d30e60 by jneira at 2020-05-24T01:54:42-04:00 Add hie-bios script for windows systems It is a direct translation of the sh script - - - - - 59182b88 by jneira at 2020-05-24T01:54:42-04:00 Honour previous values for CABAL and CABFLAGS The immediate goal is let the hie-bios.bat script set CABFLAGS with `-v0` and remove all cabal output except the compiler arguments - - - - - 932dc54e by jneira at 2020-05-24T01:54:42-04:00 Add specific configuration for windows in hie.yaml - - - - - e0eda070 by jneira at 2020-05-24T01:54:42-04:00 Remove not needed hie-bios output - - - - - a0ea59d6 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Move Config module into GHC.Settings - - - - - 37430251 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Core.Arity into GHC.Core.Opt.Arity - - - - - a426abb9 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Hs.Types into GHC.Hs.Type See discussion in https://gitlab.haskell.org/ghc/ghc/issues/13009#note_268610 - - - - - 1c91a7a0 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Bump haddock submodule - - - - - 66bd24d1 by Ryan Scott at 2020-05-24T01:56:03-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. - - - - - 01c43634 by Matthew Pickering at 2020-05-24T01:56:42-04:00 Remove unused hs-boot file - - - - - 7a07aa71 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix cross-compiler build (#16051) - - - - - 15ccca16 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix distDir per stage - - - - - b420fb24 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix hp2ps error during cross-compilation Fixed by @alp (see https://gitlab.haskell.org/ghc/ghc/issues/16051#note_274265) - - - - - cd339ef0 by Joshua Price at 2020-05-24T15:22:56-04:00 Make Unicode brackets opening/closing tokens (#18225) The tokens `[|`, `|]`, `(|`, and `|)` are opening/closing tokens as described in GHC Proposal #229. This commit makes the unicode variants (`⟦`, `⟧`, `⦇`, and `⦈`) act the same as their ASCII counterparts. - - - - - 013d7120 by Ben Gamari at 2020-05-25T09:48:17-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. - - - - - 4c4312ed by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Drop redundant ad-hoc boot module check To determine whether the module is a boot module Coverage.addTicksToBinds was checking for a `boot` suffix in the module source filename. This is quite ad-hoc and shouldn't be necessary; the callsite in `deSugar` already checks that the module isn't a boot module. - - - - - 1abf3c84 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make tickBoxCount strict This could otherwise easily cause a leak of (+) thunks. - - - - - b2813750 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make ccIndices strict This just seems like a good idea. - - - - - 02e278eb by Ben Gamari at 2020-05-25T09:48:53-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. - - - - - b8c014ce by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Factor out addMixEntry - - - - - 53814a64 by Zubin Duggal at 2020-05-26T03:03:24-04:00 Add info about typeclass evidence to .hie files See `testsuite/tests/hiefile/should_run/HieQueries.hs` and `testsuite/tests/hiefile/should_run/HieQueries.stdout` for an example of this We add two new fields, `EvidenceVarBind` and `EvidenceVarUse` to the `ContextInfo` associated with an Identifier. These are associated with the appropriate identifiers for the evidence variables collected when we come across `HsWrappers`, `TcEvBinds` and `IPBinds` while traversing the AST. Instance dictionary and superclass selector dictionaries from `tcg_insts` and classes defined in `tcg_tcs` are also recorded in the AST as originating from their definition span This allows us to save a complete picture of the evidence constructed by the constraint solver, and will let us report this to the user, enabling features like going to the instance definition from the invocation of a class method(or any other method taking a constraint) and finding all usages of a particular instance. Additionally, - Mark NodeInfo with an origin so we can differentiate between bindings origininating in the source vs those in ghc - Along with typeclass evidence info, also include information on Implicit Parameters - Add a few utility functions to HieUtils in order to query the new info Updates haddock submodule - - - - - 6604906c by Sebastian Graf at 2020-05-26T03:04:04-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. - - - - - cf772f19 by Sylvain Henry at 2020-05-26T03:04:45-04:00 Enhance Note [About units] for Backpack - - - - - ede24126 by Takenobu Tani at 2020-05-27T00:13:55-04:00 core-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Core.hs <= coreSyn/CoreSyn.hs * GHC/Core/Coercion.hs <= types/Coercion.hs * GHC/Core/Coercion/Axiom.hs <= types/CoAxiom.hs * GHC/Core/Coercion/Opt.hs <= types/OptCoercion.hs * GHC/Core/DataCon.hs <= basicTypes/DataCon.hs * GHC/Core/FamInstEnv.hs <= types/FamInstEnv.hs * GHC/Core/Lint.hs <= coreSyn/CoreLint.hs * GHC/Core/Subst.hs <= coreSyn/CoreSubst.hs * GHC/Core/TyCo/Rep.hs <= types/TyCoRep.hs * GHC/Core/TyCon.hs <= types/TyCon.hs * GHC/Core/Type.hs <= types/Type.hs * GHC/Core/Unify.hs <= types/Unify.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/Var.hs <= basicTypes/Var.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [skip ci] - - - - - 04750304 by Ben Gamari at 2020-05-27T00:14:33-04:00 eventlog: Fix racy flushing Previously no attempt was made to avoid multiple threads writing their capability-local eventlog buffers to the eventlog writer simultaneously. This could result in multiple eventlog streams being interleaved. Fix this by documenting that the EventLogWriter's write() and flush() functions may be called reentrantly and fix the default writer to protect its FILE* by a mutex. Fixes #18210. - - - - - d6203f24 by Joshua Price at 2020-05-27T00:15:17-04:00 Make `identifier` parse unparenthesized `->` (#18060) - - - - - 79103928 by Ben Gamari at 2020-05-27T13:01:33-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. - - - - - 6aae8923 by Ben Gamari at 2020-05-27T13:01:33-04:00 rts: Drop compatibility shims for Windows Vista We can now assume that the thread and processor group interfaces are available. - - - - - 876285e7 by Ben Gamari at 2020-05-27T13:06:55-04:00 users-guide: Note change in getNumProcessors in users guide - - - - - 30 changed files: - + .git-ignore-revs - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/merge_request_templates/merge-request.md - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - − compiler/GHC/Builtin/Names.hs-boot - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Reg/Graph/SpillClean.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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ce8bca8d5388bfb92e6765d3703c20e62d37781c...876285e76dd44039bc37bd1c8a8b24f8c86b6f83 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ce8bca8d5388bfb92e6765d3703c20e62d37781c...876285e76dd44039bc37bd1c8a8b24f8c86b6f83 You're receiving 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 27 17:16:16 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 27 May 2020 13:16:16 -0400 Subject: [Git][ghc/ghc][wip/primop-traits] 338 commits: Fix #17021 by checking more return kinds Message-ID: <5ecea060a3daf_6e26b45071c20387d6@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/primop-traits at Glasgow Haskell Compiler / GHC Commits: 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. - - - - - 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] - - - - - 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 - - - - - 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 - - - - - 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. - - - - - 78c6523c by Ben Gamari at 2020-05-21T12:13:01-04:00 nonmoving: Optimise the write barrier - - - - - 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). - - - - - 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 - - - - - b7a6b2f4 by Gleb Popov at 2020-05-21T12:15:26-04:00 gitlab-ci: Set locale to C.UTF-8. - - - - - 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. - - - - - 0004ccb8 by Tuan Le at 2020-05-21T12:16:46-04:00 llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 - - - - - 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 - - - - - 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 - - - - - 2b363ebb by Richard Eisenberg at 2020-05-21T12:18:45-04:00 MR template should ask for key part - - - - - a95bbd0b by Sebastian Graf at 2020-05-21T12:19:37-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. - - - - - d3d055b8 by Galen Huntington at 2020-05-21T12:20:18-04:00 Clarify pitfalls of NegativeLiterals; see #18022. - - - - - 1b508a9e by Alexey Kuleshevich at 2020-05-21T12:21:02-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" - - - - - 4ca0c8a1 by Andreas Klebinger at 2020-05-21T12:21: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. - - - - - a1275081 by Krzysztof Gogolewski at 2020-05-21T12:22:35-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 - - - - - 8a816e5f by Krzysztof Gogolewski at 2020-05-21T12:23:55-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. - - - - - 566cc73f by Sylvain Henry at 2020-05-21T12:24:45-04:00 Move isDynLinkName into GHC.Types.Name It doesn't belong into GHC.Unit.State - - - - - d830bbc9 by Adam Sandberg Ericsson at 2020-05-23T13:36:20-04:00 docs: fix formatting and add some links [skip ci] - - - - - 49301ad6 by Andrew Martin at 2020-05-23T13:37:01-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. - - - - - dcd6bdcc by Ben Gamari at 2020-05-23T13:37:48-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. - - - - - 82cb8913 by John Ericson at 2020-05-23T13:38:32-04:00 Fix #18145 and also avoid needless work with implicit vars - `forAllOrNothing` now is monadic, so we can trace whether we bind an explicit `forall` or not. - #18145 arose because the free vars calculation was needlessly complex. It is now greatly simplified. - Replaced some other implicit var code with `filterFreeVarsToBind`. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - a60dc835 by Ben Gamari at 2020-05-23T13:39:12-04:00 Bump process submodule Fixes #17926. - - - - - 856adf54 by Ben Gamari at 2020-05-23T13:40:21-04:00 users-guide: Clarify meaning of -haddock flag Fixes #18206. - - - - - 7ae57afd by Ben Gamari at 2020-05-23T13:41:03-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 - - - - - 63d30e60 by jneira at 2020-05-24T01:54:42-04:00 Add hie-bios script for windows systems It is a direct translation of the sh script - - - - - 59182b88 by jneira at 2020-05-24T01:54:42-04:00 Honour previous values for CABAL and CABFLAGS The immediate goal is let the hie-bios.bat script set CABFLAGS with `-v0` and remove all cabal output except the compiler arguments - - - - - 932dc54e by jneira at 2020-05-24T01:54:42-04:00 Add specific configuration for windows in hie.yaml - - - - - e0eda070 by jneira at 2020-05-24T01:54:42-04:00 Remove not needed hie-bios output - - - - - a0ea59d6 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Move Config module into GHC.Settings - - - - - 37430251 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Core.Arity into GHC.Core.Opt.Arity - - - - - a426abb9 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Hs.Types into GHC.Hs.Type See discussion in https://gitlab.haskell.org/ghc/ghc/issues/13009#note_268610 - - - - - 1c91a7a0 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Bump haddock submodule - - - - - 66bd24d1 by Ryan Scott at 2020-05-24T01:56:03-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. - - - - - 01c43634 by Matthew Pickering at 2020-05-24T01:56:42-04:00 Remove unused hs-boot file - - - - - 7a07aa71 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix cross-compiler build (#16051) - - - - - 15ccca16 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix distDir per stage - - - - - b420fb24 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix hp2ps error during cross-compilation Fixed by @alp (see https://gitlab.haskell.org/ghc/ghc/issues/16051#note_274265) - - - - - cd339ef0 by Joshua Price at 2020-05-24T15:22:56-04:00 Make Unicode brackets opening/closing tokens (#18225) The tokens `[|`, `|]`, `(|`, and `|)` are opening/closing tokens as described in GHC Proposal #229. This commit makes the unicode variants (`⟦`, `⟧`, `⦇`, and `⦈`) act the same as their ASCII counterparts. - - - - - 013d7120 by Ben Gamari at 2020-05-25T09:48:17-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. - - - - - 4c4312ed by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Drop redundant ad-hoc boot module check To determine whether the module is a boot module Coverage.addTicksToBinds was checking for a `boot` suffix in the module source filename. This is quite ad-hoc and shouldn't be necessary; the callsite in `deSugar` already checks that the module isn't a boot module. - - - - - 1abf3c84 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make tickBoxCount strict This could otherwise easily cause a leak of (+) thunks. - - - - - b2813750 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make ccIndices strict This just seems like a good idea. - - - - - 02e278eb by Ben Gamari at 2020-05-25T09:48:53-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. - - - - - b8c014ce by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Factor out addMixEntry - - - - - 53814a64 by Zubin Duggal at 2020-05-26T03:03:24-04:00 Add info about typeclass evidence to .hie files See `testsuite/tests/hiefile/should_run/HieQueries.hs` and `testsuite/tests/hiefile/should_run/HieQueries.stdout` for an example of this We add two new fields, `EvidenceVarBind` and `EvidenceVarUse` to the `ContextInfo` associated with an Identifier. These are associated with the appropriate identifiers for the evidence variables collected when we come across `HsWrappers`, `TcEvBinds` and `IPBinds` while traversing the AST. Instance dictionary and superclass selector dictionaries from `tcg_insts` and classes defined in `tcg_tcs` are also recorded in the AST as originating from their definition span This allows us to save a complete picture of the evidence constructed by the constraint solver, and will let us report this to the user, enabling features like going to the instance definition from the invocation of a class method(or any other method taking a constraint) and finding all usages of a particular instance. Additionally, - Mark NodeInfo with an origin so we can differentiate between bindings origininating in the source vs those in ghc - Along with typeclass evidence info, also include information on Implicit Parameters - Add a few utility functions to HieUtils in order to query the new info Updates haddock submodule - - - - - 6604906c by Sebastian Graf at 2020-05-26T03:04:04-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. - - - - - cf772f19 by Sylvain Henry at 2020-05-26T03:04:45-04:00 Enhance Note [About units] for Backpack - - - - - ede24126 by Takenobu Tani at 2020-05-27T00:13:55-04:00 core-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Core.hs <= coreSyn/CoreSyn.hs * GHC/Core/Coercion.hs <= types/Coercion.hs * GHC/Core/Coercion/Axiom.hs <= types/CoAxiom.hs * GHC/Core/Coercion/Opt.hs <= types/OptCoercion.hs * GHC/Core/DataCon.hs <= basicTypes/DataCon.hs * GHC/Core/FamInstEnv.hs <= types/FamInstEnv.hs * GHC/Core/Lint.hs <= coreSyn/CoreLint.hs * GHC/Core/Subst.hs <= coreSyn/CoreSubst.hs * GHC/Core/TyCo/Rep.hs <= types/TyCoRep.hs * GHC/Core/TyCon.hs <= types/TyCon.hs * GHC/Core/Type.hs <= types/Type.hs * GHC/Core/Unify.hs <= types/Unify.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/Var.hs <= basicTypes/Var.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [skip ci] - - - - - 04750304 by Ben Gamari at 2020-05-27T00:14:33-04:00 eventlog: Fix racy flushing Previously no attempt was made to avoid multiple threads writing their capability-local eventlog buffers to the eventlog writer simultaneously. This could result in multiple eventlog streams being interleaved. Fix this by documenting that the EventLogWriter's write() and flush() functions may be called reentrantly and fix the default writer to protect its FILE* by a mutex. Fixes #18210. - - - - - d6203f24 by Joshua Price at 2020-05-27T00:15:17-04:00 Make `identifier` parse unparenthesized `->` (#18060) - - - - - 2bf09071 by Sebastian Graf at 2020-05-27T19:13:57+02:00 Clear up PrimOp effect semantics Previously we classified PrimOps with two boolean flags, `can_fail` and `has_side_effects`. Although there is quite a slew of documentation surrounding them, see `Note [PrimOp can_fail and has_side_effects]` and `Note [Transformations affected by can_fail and has_side_effects]`, I found it quite hard to understand and also was confused of conservative misclassifications for some read-only primops like `readMutVar#` (which is marked as `has_side_effect`, although it actually shouldn't per semantics of `has_side_effect`, see #3207), but not for others (`indexIntArr#`, which is just `can_fail`). This patch defines a total order of 4 different `PrimOpEffect`s: - `NoEffect`: A pure primop - `ThrowsImprecise`: Possibly throws an imprecise exception (and may perform read effects) - `WriteEffect`: May write to a mutable ref cell, array or the world (or read from them or throw an imprecise exception) - `ThrowsPrecise`: May throw a precise exception, or do any of the aforementioned effects. Each effect is strictly "stronger" than its predecessor in this list wrt. to program transformation that are sound to apply to it. For example, we may speculatively execute read effects (as long as their data dependencies such as the state token are satisfied), but we may not speculate division (for fear of imprecise division-by-zero errors). Which `PrimOpEffect` inhibits which transformation, including examples, is spelled out in the rewritten `Note [Transformations affected by PrimOpEffect]`. Fixes #17900. - - - - - 348a0d87 by Sebastian Graf at 2020-05-27T19:16:00+02:00 Modify primops.txt.pp to declare PrimOpEffects - - - - - 30 changed files: - + .git-ignore-revs - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/linters/check-cpp.py - .gitlab/merge_request_templates/merge-request.md - CODEOWNERS - compiler/GHC.hs - compiler/prelude/PrelNames.hs → compiler/GHC/Builtin/Names.hs - 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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bbd20a71a1f27bc03cb8e59acf5ccb6516a2de37...348a0d8744fe500a48f1159990cc0a5d5f1b900c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/bbd20a71a1f27bc03cb8e59acf5ccb6516a2de37...348a0d8744fe500a48f1159990cc0a5d5f1b900c You're receiving 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 27 17:28:06 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 27 May 2020 13:28:06 -0400 Subject: [Git][ghc/ghc][wip/primop-traits] 2 commits: Clear up PrimOp effect semantics Message-ID: <5ecea3268d97d_6e263f9ecd30d120204404b@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/primop-traits at Glasgow Haskell Compiler / GHC Commits: 5ece157f by Sebastian Graf at 2020-05-27T19:27:59+02:00 Clear up PrimOp effect semantics Previously we classified PrimOps with two boolean flags, `can_fail` and `has_side_effects`. Although there is quite a slew of documentation surrounding them, see `Note [PrimOp can_fail and has_side_effects]` and `Note [Transformations affected by can_fail and has_side_effects]`, I found it quite hard to understand and also was confused of conservative misclassifications for some read-only primops like `readMutVar#` (which is marked as `has_side_effect`, although it actually shouldn't per semantics of `has_side_effect`, see #3207), but not for others (`indexIntArr#`, which is just `can_fail`). This patch defines a total order of 4 different `PrimOpEffect`s: - `NoEffect`: A pure primop - `ThrowsImprecise`: Possibly throws an imprecise exception (and may perform read effects) - `WriteEffect`: May write to a mutable ref cell, array or the world (or read from them or throw an imprecise exception) - `ThrowsPrecise`: May throw a precise exception, or do any of the aforementioned effects. Each effect is strictly "stronger" than its predecessor in this list wrt. to program transformation that are sound to apply to it. For example, we may speculatively execute read effects (as long as their data dependencies such as the state token are satisfied), but we may not speculate division (for fear of imprecise division-by-zero errors). Which `PrimOpEffect` inhibits which transformation, including examples, is spelled out in the rewritten `Note [Transformations affected by PrimOpEffect]`. Fixes #17900. - - - - - 80544f09 by Sebastian Graf at 2020-05-27T19:27:59+02:00 Modify primops.txt.pp to declare PrimOpEffects - - - - - 7 changed files: - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/ghc.mk - distrib/hc-build - hadrian/src/Rules/Generate.hs - hadrian/src/Settings/Builders/GenPrimopCode.hs - utils/genprimopcode/Main.hs Changes: ===================================== compiler/GHC/Builtin/PrimOps.hs ===================================== @@ -312,158 +312,190 @@ perform a heap check or they block. primOpOutOfLine :: PrimOp -> Bool #include "primop-out-of-line.hs-incl" + {- ************************************************************************ * * Failure and side effects * * ************************************************************************ +-} -Note [Checking versus non-checking primops] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - In GHC primops break down into two classes: - - a. Checking primops behave, for instance, like division. In this - case the primop may throw an exception (e.g. division-by-zero) - and is consequently is marked with the can_fail flag described below. - The ability to fail comes at the expense of precluding some optimizations. - - b. Non-checking primops behavior, for instance, like addition. While - addition can overflow it does not produce an exception. So can_fail is - set to False, and we get more optimisation opportunities. But we must - never throw an exception, so we cannot rewrite to a call to error. - - It is important that a non-checking primop never be transformed in a way that - would cause it to bottom. Doing so would violate Core's let/app invariant - (see Note [Core let/app invariant] in GHC.Core) which is critical to - the simplifier's ability to float without fear of changing program meaning. - - -Note [PrimOp can_fail and has_side_effects] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Both can_fail and has_side_effects mean that the primop has -some effect that is not captured entirely by its result value. - ----------- has_side_effects --------------------- -A primop "has_side_effects" if it has some *write* effect, visible -elsewhere - - writing to the world (I/O) - - writing to a mutable data structure (writeIORef) - - throwing a synchronous Haskell exception - -Often such primops have a type like - State -> input -> (State, output) -so the state token guarantees ordering. In general we rely *only* on -data dependencies of the state token to enforce write-effect ordering - - * NB1: if you inline unsafePerformIO, you may end up with - side-effecting ops whose 'state' output is discarded. - And programmers may do that by hand; see #9390. - That is why we (conservatively) do not discard write-effecting - primops even if both their state and result is discarded. - - * NB2: We consider primops, such as raiseIO#, that can raise a - (Haskell) synchronous exception to "have_side_effects" but not - "can_fail". We must be careful about not discarding such things; - see the paper "A semantics for imprecise exceptions". - - * NB3: *Read* effects (like reading an IORef) don't count here, - because it doesn't matter if we don't do them, or do them more than - once. *Sequencing* is maintained by the data dependency of the state - token. - ----------- can_fail ---------------------------- -A primop "can_fail" if it can fail with an *unchecked* exception on -some elements of its input domain. Main examples: - division (fails on zero denominator) - array indexing (fails if the index is out of bounds) - -An "unchecked exception" is one that is an outright error, (not -turned into a Haskell exception,) such as seg-fault or -divide-by-zero error. Such can_fail primops are ALWAYS surrounded -with a test that checks for the bad cases, but we need to be -very careful about code motion that might move it out of -the scope of the test. - -Note [Transformations affected by can_fail and has_side_effects] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The can_fail and has_side_effects properties have the following effect -on program transformations. Summary table is followed by details. - - can_fail has_side_effects -Discard YES NO -Float in YES YES -Float out NO NO -Duplicate YES NO +-- | A classification of primops by triggered side effects. +-- See Note [Classification by PrimOpEffect]. +-- The total 'Ord' instance is significant (and hence the order of constructors +-- is). A "stronger" effect means less transformations are sound to apply to +-- them. +data PrimOpEffect + = NoEffect + -- ^ Triggers no side-effects. + | ThrowsImprecise + -- ^ May throw an /imprecise/ exception. + -- See Note [Precise vs imprecise exceptions] in GHC.Types.Demand. + | WriteEffect + -- ^ May perform a write effect, such as writing out to a file or a mutable + -- ref cell. (Or any of the weaker effects.) + | ThrowsPrecise + -- ^ May throw a /precise/ exception. (Or any of the weaker effects.) + -- See Note [Precise vs imprecise exceptions] in GHC.Types.Demand. + deriving (Eq, Ord) + +-- | Can we discard a call to the primop, i.e. @case a `op` b of _ -> rhs@? +-- This is a question that i.e. the Simplifier asks before dropping the @case at . +-- See Note [Transformations affected by can_fail and has_side_effects]. +isDiscardablePrimOpEffect :: PrimOpEffect -> Bool +isDiscardablePrimOpEffect eff = eff <= ThrowsImprecise + +-- | Can we duplicate a call to the primop? +-- This is a question that i.e. the Simplifier asks when inlining definitions +-- involving primops with multiple syntactic occurrences. +-- See Note [Transformations affected by can_fail and has_side_effects]. +isDupablePrimOpEffect :: PrimOpEffect -> Bool +-- isDupablePrimOpEffect eff = True -- #3207, see the Note +isDupablePrimOpEffect eff = eff <= ThrowsImprecise + +-- | Can we perform other actions first before entering the primop? +-- This is the question that i.e. @FloatIn@ asks. +-- See Note [Transformations affected by can_fail and has_side_effects]. +isDeferrablePrimOpEffect :: PrimOpEffect -> Bool +isDeferrablePrimOpEffect eff = eff <= WriteEffect + +-- | Can we speculatively execute this primop, before performing other actions +-- that should come first according to evaluation strategy? +-- This is the question that i.e. @FloatOut@ (of a @case@) asks. +-- See Note [Transformations affected by can_fail and has_side_effects]. +isSpeculatablePrimOpEffect :: PrimOpEffect -> Bool +isSpeculatablePrimOpEffect eff = eff <= NoEffect + +{- Note [Classification by PrimOpEffect] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Some primops have effects that are not captured entirely by their result value. +We distinguish these cases: + + * NoEffect: Pure primop, like `plusInt#`. + * ThrowsImprecise: Possibly throws an *imprecise* exception, like + division-by-zero or a segfault arising from an out of bounds array access. + An imprecise exception is an outright error and transformations may play + fast and loose by turning one imprecise exception into another, or bottom. + See Note [Precise vs imprecise exceptions] in GHC.Types.Demand. + * WriteEffect: A write side-effect, either writing to the RealWorld (IO) or + to a mutable variable (`writeMutVar#`). + * ThrowsPrecise: Possibly throws a *precise* exception. `raiseIO#` is the + only primop that does that. + See Note [Precise vs imprecise exceptions] in GHC.Types.Demand. + +Why is this classification necessary? Because the kind of effect a primop +performs influences the transformations we are allowed to apply to it. +For example let binding a division-by-zero (which `ThrowsImprecise`) might +violate Core's let/app invariant (see Note [Core let/app invariant] in +GHC.Core) which is critical to the simplifier's ability to float without fear +of changing program meaning. + +See Note [Transformations affected by PrimOpEffect]. + +Note [Transformations affected by PrimOpEffect] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The PrimOpEffect of a primop affects applicability of program transformations +in the following way. +Summary table is followed by details. + +Tranform. | Example | NoEffect | ThrowsImprecise | WriteEffect | ThrowsPrecise +----------+----------+----------+-----------------+-------------+-------------- +Defer | FloatIn | YES | YES | YES | NO +Discard | DeadCode | YES | YES | NO | NO +Dupe | Inlining | YES | YES | NO | NO +Speculate | FloatOut | YES | NO | NO | NO + +Note how there is a total order on effects in terms of which program +tranformations they inhibit. A "stronger" effect means less transformations +are sound to apply to it. NoEffect means any tranformation is sound; +ThrowsPrecise means none of the following is. +Whether or not a primop is cheap to evaluate is an orthogonal concern. * Discarding. case (a `op` b) of _ -> rhs ===> rhs - You should not discard a has_side_effects primop; e.g. - case (writeIntArray# a i v s of (# _, _ #) -> True - Arguably you should be able to discard this, since the - returned stat token is not used, but that relies on NEVER - inlining unsafePerformIO, and programmers sometimes write - this kind of stuff by hand (#9390). So we (conservatively) - never discard a has_side_effects primop. - - However, it's fine to discard a can_fail primop. For example - case (indexIntArray# a i) of _ -> True - We can discard indexIntArray#; it has can_fail, but not - has_side_effects; see #5658 which was all about this. - Notice that indexIntArray# is (in a more general handling of - effects) read effect, but we don't care about that here, and - treat read effects as *not* has_side_effects. - - Similarly (a `/#` b) can be discarded. It can seg-fault or - cause a hardware exception, but not a synchronous Haskell + You should not discard a WriteEffect primop; e.g. + case (writeIntArray# a i v s of (# _, _ #) -> True + Arguably you should be able to discard this, since the returned state token + is not used, but that relies on NEVER inlining unsafePerformIO, and + programmers sometimes write this kind of stuff by hand (#9390). So we + (conservatively) never discard such a primop. + The situation with (stronger) ThrowsPrecise primops such as raiseIO# is even + more restrictive: We may never discard a side effect throwing a precise exception. - - - Synchronous Haskell exceptions, e.g. from raiseIO#, are treated - as has_side_effects and hence are not discarded. - -* Float in. You can float a can_fail or has_side_effects primop - *inwards*, but not inside a lambda (see Duplication below). - -* Float out. You must not float a can_fail primop *outwards* lest - you escape the dynamic scope of the test. Example: - case d ># 0# of - True -> case x /# d of r -> r +# 1 - False -> 0 - Here we must not float the case outwards to give - case x/# d of r -> - case d ># 0# of - True -> r +# 1 - False -> 0 - - Nor can you float out a has_side_effects primop. For example: - if blah then case writeMutVar# v True s0 of (# s1 #) -> s1 - else s0 - Notice that s0 is mentioned in both branches of the 'if', but - only one of these two will actually be consumed. But if we - float out to - case writeMutVar# v True s0 of (# s1 #) -> - if blah then s1 else s0 - the writeMutVar will be performed in both branches, which is - utterly wrong. - -* Duplication. You cannot duplicate a has_side_effect primop. You - might wonder how this can occur given the state token threading, but - just look at Control.Monad.ST.Lazy.Imp.strictToLazy! We get - something like this - p = case readMutVar# s v of - (# s', r #) -> (S# s', r) - s' = case p of (s', r) -> s' - r = case p of (s', r) -> r - + However, it's fine to discard a ThrowsImprecise primop. For example + case (indexIntArray# a i) of _ -> True + We can discard indexIntArray#; it might throw an imprecise segmentation + fault, but no precise exception, so we are OK with not observing it. + See #5658 which was all about this. + Similarly (a `/#` b) can be discarded. It can seg-fault or cause a hardware + exception, but not a precise Haskell exception. + It's obviously fine to discard a NoEffect if its result aren't used. + +* Duplication. Example: The Simplifier inlines a (multi occ) binding. + You cannot duplicate any effectful primop participating in state token + threading. Not even what is actually a read-only effect like `readMutVar#`, + see #3207. + You might wonder how that can be problematic, but just look at + Control.Monad.ST.Lazy.Imp.strictToLazy! We get something like this + p = case readMutVar# s v of + (# s', r #) -> (S# s', r) + s' = case p of (s', r) -> s' + r = case p of (s', r) -> r (All these bindings are boxed.) If we inline p at its two call sites, we get a catastrophe: because the read is performed once when s' is demanded, and once when 'r' is demanded, which may be much - later. Utterly wrong. #3207 is real example of this happening. - - However, it's fine to duplicate a can_fail primop. That is really - the only difference between can_fail and has_side_effects. + later. Utterly wrong. #3207 is a real example of this happening. + + If it wasn't for working around state token threading + (see https://gitlab.haskell.org/ghc/ghc/issues/3207#note_257470 for other + approaches), then duplication wouldn't be an issue at all, soundness-wise. + But for the time being, we mark primops that participate in state token + threading such as `readMutVar#` (which has NoEffect at heart) and + `readArray#` (ThrowsImprecise) as WriteEffect and say that we may not + duplicate WriteEffect. + +* Deferring (Float In). Example, here inside a single-alt case: + case (a `op` b) of (# s, x #) -> case e of p -> rhs + ==> + case e of p -> case (a `op` b) of (# s, x #) -> rhs + Note that e might diverge (or throw an imprecise exception) and thus the + side-effect we would observe by evaluating op might not happen if we defer it + after e. + + That is a problem if op ThrowsPrecise: If e diverges, the user can catch + the precise exception /before/ FloatIn, but not afterwards. Hence we may not + float in a ThrowsPrecise primop like raiseIO#. + + But since e can never throw an imprecise exception, there is no + non-imprecise-exceptional control flow in which it is possible to observe + that a WriteEffect (and anything "weaker") didn't happen. So it's OK to + defer (every weaker than or equal to) write effects. So you can float a + WriteEffect *inwards*, but not inside a lambda (see Duplication below [SG: It + isn't obvious to me how that explains why we shouldn't float inside a lambda + at all]). + +* Speculating (Float out). + You must not float a ThrowsImprecise primop *outwards* lest you escape the + dynamic scope of the test. Example: + case d ># 0# of + True -> case x /# d of r -> r +# 1 + False -> 0 + Here we must not float the division outwards to give + case x/# d of r -> + case d ># 0# of + True -> r +# 1 + False -> 0 + Now the potential division by zero will be performed in both branches. + + Similarly you can't float out a (stronger) WriteEffect primop. For example: + if blah then case writeMutVar# v True s0 of (# s1 #) -> s1 + else s0 + Notice that s0 is mentioned in both branches of the 'if', but only one of + these two will actually be consumed. But if we float out to + case writeMutVar# v True s0 of (# s1 #) -> + if blah then s1 else s0 + the writeMutVar will be performed in both branches, which is utterly wrong. Note [Implementation: how can_fail/has_side_effects affect transformations] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -488,11 +520,16 @@ Two main predicates on primpops test these flags: has_side_effects things (very very very) not-cheap! -} -primOpHasSideEffects :: PrimOp -> Bool -#include "primop-has-side-effects.hs-incl" +primOpEffect :: PrimOp -> PrimOpEffect +#include "primop-effect.hs-incl" + +primOpOkForSideEffects :: PrimOp -> Bool +-- This is exactly @isDupablePrimOpEffect (primOpEffect op)@ +primOpOkForSideEffects op = primOpEffect op < WriteEffect primOpCanFail :: PrimOp -> Bool -#include "primop-can-fail.hs-incl" +-- This is exactly @isSpeculatablePrimOpEffect (primOpEffect op)@ +primOpCanFail op = primOpEffect op < ThrowsImprecise primOpOkForSpeculation :: PrimOp -> Bool -- See Note [PrimOp can_fail and has_side_effects] ===================================== compiler/GHC/Builtin/primops.txt.pp ===================================== The diff for this file was not included because it is too large. ===================================== compiler/ghc.mk ===================================== @@ -108,11 +108,10 @@ $(eval $(call compilerConfig,2)) PRIMOP_BITS_NAMES = primop-data-decl.hs-incl \ primop-tag.hs-incl \ primop-list.hs-incl \ - primop-has-side-effects.hs-incl \ + primop-effect.hs-incl \ primop-out-of-line.hs-incl \ primop-commutable.hs-incl \ primop-code-size.hs-incl \ - primop-can-fail.hs-incl \ primop-strictness.hs-incl \ primop-fixity.hs-incl \ primop-primop-info.hs-incl \ @@ -143,16 +142,14 @@ compiler/stage$1/build/primop-tag.hs-incl: compiler/stage$1/build/primops.txt $$ "$$(genprimopcode_INPLACE)" --primop-tag < $$< > $$@ compiler/stage$1/build/primop-list.hs-incl: compiler/stage$1/build/primops.txt $$$$(genprimopcode_INPLACE) "$$(genprimopcode_INPLACE)" --primop-list < $$< > $$@ -compiler/stage$1/build/primop-has-side-effects.hs-incl: compiler/stage$1/build/primops.txt $$$$(genprimopcode_INPLACE) - "$$(genprimopcode_INPLACE)" --has-side-effects < $$< > $$@ +compiler/stage$1/build/primop-effect.hs-incl: compiler/stage$1/build/primops.txt $$$$(genprimopcode_INPLACE) + "$$(genprimopcode_INPLACE)" --effect < $$< > $$@ compiler/stage$1/build/primop-out-of-line.hs-incl: compiler/stage$1/build/primops.txt $$$$(genprimopcode_INPLACE) "$$(genprimopcode_INPLACE)" --out-of-line < $$< > $$@ compiler/stage$1/build/primop-commutable.hs-incl: compiler/stage$1/build/primops.txt $$$$(genprimopcode_INPLACE) "$$(genprimopcode_INPLACE)" --commutable < $$< > $$@ compiler/stage$1/build/primop-code-size.hs-incl: compiler/stage$1/build/primops.txt $$$$(genprimopcode_INPLACE) "$$(genprimopcode_INPLACE)" --code-size < $$< > $$@ -compiler/stage$1/build/primop-can-fail.hs-incl: compiler/stage$1/build/primops.txt $$$$(genprimopcode_INPLACE) - "$$(genprimopcode_INPLACE)" --can-fail < $$< > $$@ compiler/stage$1/build/primop-strictness.hs-incl: compiler/stage$1/build/primops.txt $$$$(genprimopcode_INPLACE) "$$(genprimopcode_INPLACE)" --strictness < $$< > $$@ compiler/stage$1/build/primop-fixity.hs-incl: compiler/stage$1/build/primops.txt $$$$(genprimopcode_INPLACE) ===================================== distrib/hc-build ===================================== @@ -73,11 +73,10 @@ HappyCmd="$PWD/distrib/fake-happy" ./configure --with-ghc="$PWD/compiler/ghc-inp PRIMOP_BITS="primop-data-decl.hs-incl \ primop-tag.hs-incl \ primop-list.hs-incl \ - primop-has-side-effects.hs-incl \ + primop-effect.hs-incl \ primop-out-of-line.hs-incl \ primop-commutable.hs-incl \ primop-needs-wrapper.hs-incl \ - primop-can-fail.hs-incl \ primop-strictness.hs-incl \ primop-usage.hs-incl \ primop-primop-info.hs-incl" ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -59,12 +59,11 @@ compilerDependencies = do , notStage0 ? isGmp ? return [gmpPath -/- "include/ghc-gmp.h"] , notStage0 ? return ((rtsPath -/-) <$> libffiHeaderFiles) , return $ fmap (ghcPath -/-) - [ "primop-can-fail.hs-incl" - , "primop-code-size.hs-incl" + [ "primop-code-size.hs-incl" , "primop-commutable.hs-incl" , "primop-data-decl.hs-incl" + , "primop-effect.hs-incl" , "primop-fixity.hs-incl" - , "primop-has-side-effects.hs-incl" , "primop-list.hs-incl" , "primop-out-of-line.hs-incl" , "primop-primop-info.hs-incl" ===================================== hadrian/src/Settings/Builders/GenPrimopCode.hs ===================================== @@ -9,11 +9,10 @@ genPrimopCodeBuilderArgs = builder GenPrimopCode ? mconcat , output "//primop-data-decl.hs-incl" ? arg "--data-decl" , output "//primop-tag.hs-incl" ? arg "--primop-tag" , output "//primop-list.hs-incl" ? arg "--primop-list" - , output "//primop-has-side-effects.hs-incl" ? arg "--has-side-effects" + , output "//primop-effect.hs-incl" ? arg "--effect" , output "//primop-out-of-line.hs-incl" ? arg "--out-of-line" , output "//primop-commutable.hs-incl" ? arg "--commutable" , output "//primop-code-size.hs-incl" ? arg "--code-size" - , output "//primop-can-fail.hs-incl" ? arg "--can-fail" , output "//primop-strictness.hs-incl" ? arg "--strictness" , output "//primop-fixity.hs-incl" ? arg "--fixity" , output "//primop-primop-info.hs-incl" ? arg "--primop-primop-info" ===================================== utils/genprimopcode/Main.hs ===================================== @@ -124,10 +124,10 @@ main = getArgs >>= \args -> "--data-decl" -> putStr (gen_data_decl p_o_specs) - "--has-side-effects" + "--effect" -> putStr (gen_switch_from_attribs - "has_side_effects" - "primOpHasSideEffects" p_o_specs) + "effect" + "primOpEffect" p_o_specs) "--out-of-line" -> putStr (gen_switch_from_attribs @@ -144,11 +144,6 @@ main = getArgs >>= \args -> "code_size" "primOpCodeSize" p_o_specs) - "--can-fail" - -> putStr (gen_switch_from_attribs - "can_fail" - "primOpCanFail" p_o_specs) - "--strictness" -> putStr (gen_switch_from_attribs "strictness" @@ -514,20 +509,25 @@ gen_latex_doc (Info defaults entries) mk_options o = "\\primoptions{" - ++ mk_has_side_effects o ++ "}{" + ++ mk_effect o ++ "}{" ++ mk_out_of_line o ++ "}{" ++ mk_commutable o ++ "}{" ++ mk_needs_wrapper o ++ "}{" - ++ mk_can_fail o ++ "}{" ++ mk_fixity o ++ "}{" ++ latex_encode (mk_strictness o) ++ "}{" ++ "}" - mk_has_side_effects o = mk_bool_opt o "has_side_effects" "Has side effects." "Has no side effects." + mk_effect o = case lookup_attrib "effect" o of + Just "NoEffect" -> "" + Just "ThrowsImprecise" -> "May throw an imprecise exception." + Just "WriteEffect" -> "May throw an imprecise exception or perform a write effect." + Just "ThrowsPrecise" -> "May throw a precise exception (or any other effect)." + Just v -> error "Wrong value for effect: '" ++ show v ++ "'" + Nothing -> "" + mk_out_of_line o = mk_bool_opt o "out_of_line" "Implemented out of line." "Implemented in line." mk_commutable o = mk_bool_opt o "commutable" "Commutable." "Not commutable." mk_needs_wrapper o = mk_bool_opt o "needs_wrapper" "Needs wrapper." "Needs no wrapper." - mk_can_fail o = mk_bool_opt o "can_fail" "Can fail." "Cannot fail." mk_bool_opt o opt_name if_true if_false = case lookup_attrib opt_name o of @@ -774,6 +774,7 @@ gen_switch_from_attribs attrib_name fn_name (Info defaults entries) getAltRhs (OptionString _ s) = s getAltRhs (OptionVector _) = "True" getAltRhs (OptionFixity mf) = show mf + getAltRhs (OptionEffect eff) = show eff mkAlt po = case lookup_attrib attrib_name (opts po) of View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/348a0d8744fe500a48f1159990cc0a5d5f1b900c...80544f093969dc264d2f01de87056e2d0489e750 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/348a0d8744fe500a48f1159990cc0a5d5f1b900c...80544f093969dc264d2f01de87056e2d0489e750 You're receiving 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 27 17:31:33 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 27 May 2020 13:31:33 -0400 Subject: [Git][ghc/ghc][wip/primop-traits] 2 commits: Clear up PrimOp effect semantics Message-ID: <5ecea3f5b606e_6e26a99481420446af@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/primop-traits at Glasgow Haskell Compiler / GHC Commits: 9616d2d1 by Sebastian Graf at 2020-05-27T19:31:24+02:00 Clear up PrimOp effect semantics Previously we classified PrimOps with two boolean flags, `can_fail` and `has_side_effects`. Although there is quite a slew of documentation surrounding them, see `Note [PrimOp can_fail and has_side_effects]` and `Note [Transformations affected by can_fail and has_side_effects]`, I found it quite hard to understand and also was confused of conservative misclassifications for some read-only primops like `readMutVar#` (which is marked as `has_side_effect`, although it actually shouldn't per semantics of `has_side_effect`, see #3207), but not for others (`indexIntArr#`, which is just `can_fail`). This patch defines a total order of 4 different `PrimOpEffect`s: - `NoEffect`: A pure primop - `ThrowsImprecise`: Possibly throws an imprecise exception (and may perform read effects) - `WriteEffect`: May write to a mutable ref cell, array or the world (or read from them or throw an imprecise exception) - `ThrowsPrecise`: May throw a precise exception, or do any of the aforementioned effects. Each effect is strictly "stronger" than its predecessor in this list wrt. to program transformation that are sound to apply to it. For example, we may speculatively execute read effects (as long as their data dependencies such as the state token are satisfied), but we may not speculate division (for fear of imprecise division-by-zero errors). Which `PrimOpEffect` inhibits which transformation, including examples, is spelled out in the rewritten `Note [Transformations affected by PrimOpEffect]`. Fixes #17900. - - - - - 6f871bba by Sebastian Graf at 2020-05-27T19:31:24+02:00 Modify primops.txt.pp to declare PrimOpEffects - - - - - 7 changed files: - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/ghc.mk - distrib/hc-build - hadrian/src/Rules/Generate.hs - hadrian/src/Settings/Builders/GenPrimopCode.hs - utils/genprimopcode/Main.hs Changes: ===================================== compiler/GHC/Builtin/PrimOps.hs ===================================== @@ -312,158 +312,190 @@ perform a heap check or they block. primOpOutOfLine :: PrimOp -> Bool #include "primop-out-of-line.hs-incl" + {- ************************************************************************ * * Failure and side effects * * ************************************************************************ +-} -Note [Checking versus non-checking primops] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - In GHC primops break down into two classes: - - a. Checking primops behave, for instance, like division. In this - case the primop may throw an exception (e.g. division-by-zero) - and is consequently is marked with the can_fail flag described below. - The ability to fail comes at the expense of precluding some optimizations. - - b. Non-checking primops behavior, for instance, like addition. While - addition can overflow it does not produce an exception. So can_fail is - set to False, and we get more optimisation opportunities. But we must - never throw an exception, so we cannot rewrite to a call to error. - - It is important that a non-checking primop never be transformed in a way that - would cause it to bottom. Doing so would violate Core's let/app invariant - (see Note [Core let/app invariant] in GHC.Core) which is critical to - the simplifier's ability to float without fear of changing program meaning. - - -Note [PrimOp can_fail and has_side_effects] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Both can_fail and has_side_effects mean that the primop has -some effect that is not captured entirely by its result value. - ----------- has_side_effects --------------------- -A primop "has_side_effects" if it has some *write* effect, visible -elsewhere - - writing to the world (I/O) - - writing to a mutable data structure (writeIORef) - - throwing a synchronous Haskell exception - -Often such primops have a type like - State -> input -> (State, output) -so the state token guarantees ordering. In general we rely *only* on -data dependencies of the state token to enforce write-effect ordering - - * NB1: if you inline unsafePerformIO, you may end up with - side-effecting ops whose 'state' output is discarded. - And programmers may do that by hand; see #9390. - That is why we (conservatively) do not discard write-effecting - primops even if both their state and result is discarded. - - * NB2: We consider primops, such as raiseIO#, that can raise a - (Haskell) synchronous exception to "have_side_effects" but not - "can_fail". We must be careful about not discarding such things; - see the paper "A semantics for imprecise exceptions". - - * NB3: *Read* effects (like reading an IORef) don't count here, - because it doesn't matter if we don't do them, or do them more than - once. *Sequencing* is maintained by the data dependency of the state - token. - ----------- can_fail ---------------------------- -A primop "can_fail" if it can fail with an *unchecked* exception on -some elements of its input domain. Main examples: - division (fails on zero denominator) - array indexing (fails if the index is out of bounds) - -An "unchecked exception" is one that is an outright error, (not -turned into a Haskell exception,) such as seg-fault or -divide-by-zero error. Such can_fail primops are ALWAYS surrounded -with a test that checks for the bad cases, but we need to be -very careful about code motion that might move it out of -the scope of the test. - -Note [Transformations affected by can_fail and has_side_effects] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The can_fail and has_side_effects properties have the following effect -on program transformations. Summary table is followed by details. - - can_fail has_side_effects -Discard YES NO -Float in YES YES -Float out NO NO -Duplicate YES NO +-- | A classification of primops by triggered side effects. +-- See Note [Classification by PrimOpEffect]. +-- The total 'Ord' instance is significant (and hence the order of constructors +-- is). A "stronger" effect means less transformations are sound to apply to +-- them. +data PrimOpEffect + = NoEffect + -- ^ Triggers no side-effects. + | ThrowsImprecise + -- ^ May throw an /imprecise/ exception. + -- See Note [Precise vs imprecise exceptions] in GHC.Types.Demand. + | WriteEffect + -- ^ May perform a write effect, such as writing out to a file or a mutable + -- ref cell. (Or any of the weaker effects.) + | ThrowsPrecise + -- ^ May throw a /precise/ exception. (Or any of the weaker effects.) + -- See Note [Precise vs imprecise exceptions] in GHC.Types.Demand. + deriving (Eq, Ord) + +-- | Can we discard a call to the primop, i.e. @case a `op` b of _ -> rhs@? +-- This is a question that i.e. the Simplifier asks before dropping the @case at . +-- See Note [Transformations affected by can_fail and has_side_effects]. +isDiscardablePrimOpEffect :: PrimOpEffect -> Bool +isDiscardablePrimOpEffect eff = eff <= ThrowsImprecise + +-- | Can we duplicate a call to the primop? +-- This is a question that i.e. the Simplifier asks when inlining definitions +-- involving primops with multiple syntactic occurrences. +-- See Note [Transformations affected by can_fail and has_side_effects]. +isDupablePrimOpEffect :: PrimOpEffect -> Bool +-- isDupablePrimOpEffect eff = True -- #3207, see the Note +isDupablePrimOpEffect eff = eff <= ThrowsImprecise + +-- | Can we perform other actions first before entering the primop? +-- This is the question that i.e. @FloatIn@ asks. +-- See Note [Transformations affected by can_fail and has_side_effects]. +isDeferrablePrimOpEffect :: PrimOpEffect -> Bool +isDeferrablePrimOpEffect eff = eff <= WriteEffect + +-- | Can we speculatively execute this primop, before performing other actions +-- that should come first according to evaluation strategy? +-- This is the question that i.e. @FloatOut@ (of a @case@) asks. +-- See Note [Transformations affected by can_fail and has_side_effects]. +isSpeculatablePrimOpEffect :: PrimOpEffect -> Bool +isSpeculatablePrimOpEffect eff = eff <= NoEffect + +{- Note [Classification by PrimOpEffect] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Some primops have effects that are not captured entirely by their result value. +We distinguish these cases: + + * NoEffect: Pure primop, like `plusInt#`. + * ThrowsImprecise: Possibly throws an *imprecise* exception, like + division-by-zero or a segfault arising from an out of bounds array access. + An imprecise exception is an outright error and transformations may play + fast and loose by turning one imprecise exception into another, or bottom. + See Note [Precise vs imprecise exceptions] in GHC.Types.Demand. + * WriteEffect: A write side-effect, either writing to the RealWorld (IO) or + to a mutable variable (`writeMutVar#`). + * ThrowsPrecise: Possibly throws a *precise* exception. `raiseIO#` is the + only primop that does that. + See Note [Precise vs imprecise exceptions] in GHC.Types.Demand. + +Why is this classification necessary? Because the kind of effect a primop +performs influences the transformations we are allowed to apply to it. +For example let binding a division-by-zero (which `ThrowsImprecise`) might +violate Core's let/app invariant (see Note [Core let/app invariant] in +GHC.Core) which is critical to the simplifier's ability to float without fear +of changing program meaning. + +See Note [Transformations affected by PrimOpEffect]. + +Note [Transformations affected by PrimOpEffect] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The PrimOpEffect of a primop affects applicability of program transformations +in the following way. +Summary table is followed by details. + +Tranform. | Example | NoEffect | ThrowsImprecise | WriteEffect | ThrowsPrecise +----------+----------+----------+-----------------+-------------+-------------- +Defer | FloatIn | YES | YES | YES | NO +Discard | DeadCode | YES | YES | NO | NO +Dupe | Inlining | YES | YES | NO | NO +Speculate | FloatOut | YES | NO | NO | NO + +Note how there is a total order on effects in terms of which program +tranformations they inhibit. A "stronger" effect means less transformations +are sound to apply to it. NoEffect means any tranformation is sound; +ThrowsPrecise means none of the following is. +Whether or not a primop is cheap to evaluate is an orthogonal concern. * Discarding. case (a `op` b) of _ -> rhs ===> rhs - You should not discard a has_side_effects primop; e.g. - case (writeIntArray# a i v s of (# _, _ #) -> True - Arguably you should be able to discard this, since the - returned stat token is not used, but that relies on NEVER - inlining unsafePerformIO, and programmers sometimes write - this kind of stuff by hand (#9390). So we (conservatively) - never discard a has_side_effects primop. - - However, it's fine to discard a can_fail primop. For example - case (indexIntArray# a i) of _ -> True - We can discard indexIntArray#; it has can_fail, but not - has_side_effects; see #5658 which was all about this. - Notice that indexIntArray# is (in a more general handling of - effects) read effect, but we don't care about that here, and - treat read effects as *not* has_side_effects. - - Similarly (a `/#` b) can be discarded. It can seg-fault or - cause a hardware exception, but not a synchronous Haskell + You should not discard a WriteEffect primop; e.g. + case (writeIntArray# a i v s of (# _, _ #) -> True + Arguably you should be able to discard this, since the returned state token + is not used, but that relies on NEVER inlining unsafePerformIO, and + programmers sometimes write this kind of stuff by hand (#9390). So we + (conservatively) never discard such a primop. + The situation with (stronger) ThrowsPrecise primops such as raiseIO# is even + more restrictive: We may never discard a side effect throwing a precise exception. - - - Synchronous Haskell exceptions, e.g. from raiseIO#, are treated - as has_side_effects and hence are not discarded. - -* Float in. You can float a can_fail or has_side_effects primop - *inwards*, but not inside a lambda (see Duplication below). - -* Float out. You must not float a can_fail primop *outwards* lest - you escape the dynamic scope of the test. Example: - case d ># 0# of - True -> case x /# d of r -> r +# 1 - False -> 0 - Here we must not float the case outwards to give - case x/# d of r -> - case d ># 0# of - True -> r +# 1 - False -> 0 - - Nor can you float out a has_side_effects primop. For example: - if blah then case writeMutVar# v True s0 of (# s1 #) -> s1 - else s0 - Notice that s0 is mentioned in both branches of the 'if', but - only one of these two will actually be consumed. But if we - float out to - case writeMutVar# v True s0 of (# s1 #) -> - if blah then s1 else s0 - the writeMutVar will be performed in both branches, which is - utterly wrong. - -* Duplication. You cannot duplicate a has_side_effect primop. You - might wonder how this can occur given the state token threading, but - just look at Control.Monad.ST.Lazy.Imp.strictToLazy! We get - something like this - p = case readMutVar# s v of - (# s', r #) -> (S# s', r) - s' = case p of (s', r) -> s' - r = case p of (s', r) -> r - + However, it's fine to discard a ThrowsImprecise primop. For example + case (indexIntArray# a i) of _ -> True + We can discard indexIntArray#; it might throw an imprecise segmentation + fault, but no precise exception, so we are OK with not observing it. + See #5658 which was all about this. + Similarly (a `/#` b) can be discarded. It can seg-fault or cause a hardware + exception, but not a precise Haskell exception. + It's obviously fine to discard a NoEffect if its result aren't used. + +* Duplication. Example: The Simplifier inlines a (multi occ) binding. + You cannot duplicate any effectful primop participating in state token + threading. Not even what is actually a read-only effect like `readMutVar#`, + see #3207. + You might wonder how that can be problematic, but just look at + Control.Monad.ST.Lazy.Imp.strictToLazy! We get something like this + p = case readMutVar# s v of + (# s', r #) -> (S# s', r) + s' = case p of (s', r) -> s' + r = case p of (s', r) -> r (All these bindings are boxed.) If we inline p at its two call sites, we get a catastrophe: because the read is performed once when s' is demanded, and once when 'r' is demanded, which may be much - later. Utterly wrong. #3207 is real example of this happening. - - However, it's fine to duplicate a can_fail primop. That is really - the only difference between can_fail and has_side_effects. + later. Utterly wrong. #3207 is a real example of this happening. + + If it wasn't for working around state token threading + (see https://gitlab.haskell.org/ghc/ghc/issues/3207#note_257470 for other + approaches), then duplication wouldn't be an issue at all, soundness-wise. + But for the time being, we mark primops that participate in state token + threading such as `readMutVar#` (which has NoEffect at heart) and + `readArray#` (ThrowsImprecise) as WriteEffect and say that we may not + duplicate WriteEffect. + +* Deferring (Float In). Example, here inside a single-alt case: + case (a `op` b) of (# s, x #) -> case e of p -> rhs + ==> + case e of p -> case (a `op` b) of (# s, x #) -> rhs + Note that e might diverge (or throw an imprecise exception) and thus the + side-effect we would observe by evaluating op might not happen if we defer it + after e. + + That is a problem if op ThrowsPrecise: If e diverges, the user can catch + the precise exception /before/ FloatIn, but not afterwards. Hence we may not + float in a ThrowsPrecise primop like raiseIO#. + + But since e can never throw an imprecise exception, there is no + non-imprecise-exceptional control flow in which it is possible to observe + that a WriteEffect (and anything "weaker") didn't happen. So it's OK to + defer (every weaker than or equal to) write effects. So you can float a + WriteEffect *inwards*, but not inside a lambda (see Duplication below [SG: It + isn't obvious to me how that explains why we shouldn't float inside a lambda + at all]). + +* Speculating (Float out). + You must not float a ThrowsImprecise primop *outwards* lest you escape the + dynamic scope of the test. Example: + case d ># 0# of + True -> case x /# d of r -> r +# 1 + False -> 0 + Here we must not float the division outwards to give + case x/# d of r -> + case d ># 0# of + True -> r +# 1 + False -> 0 + Now the potential division by zero will be performed in both branches. + + Similarly you can't float out a (stronger) WriteEffect primop. For example: + if blah then case writeMutVar# v True s0 of (# s1 #) -> s1 + else s0 + Notice that s0 is mentioned in both branches of the 'if', but only one of + these two will actually be consumed. But if we float out to + case writeMutVar# v True s0 of (# s1 #) -> + if blah then s1 else s0 + the writeMutVar will be performed in both branches, which is utterly wrong. Note [Implementation: how can_fail/has_side_effects affect transformations] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -488,11 +520,16 @@ Two main predicates on primpops test these flags: has_side_effects things (very very very) not-cheap! -} -primOpHasSideEffects :: PrimOp -> Bool -#include "primop-has-side-effects.hs-incl" +primOpEffect :: PrimOp -> PrimOpEffect +#include "primop-effect.hs-incl" + +primOpOkForSideEffects :: PrimOp -> Bool +-- This is exactly @isDupablePrimOpEffect (primOpEffect op)@ +primOpOkForSideEffects op = primOpEffect op < WriteEffect primOpCanFail :: PrimOp -> Bool -#include "primop-can-fail.hs-incl" +-- This is exactly @isSpeculatablePrimOpEffect (primOpEffect op)@ +primOpCanFail op = primOpEffect op < ThrowsImprecise primOpOkForSpeculation :: PrimOp -> Bool -- See Note [PrimOp can_fail and has_side_effects] ===================================== compiler/GHC/Builtin/primops.txt.pp ===================================== The diff for this file was not included because it is too large. ===================================== compiler/ghc.mk ===================================== @@ -108,11 +108,10 @@ $(eval $(call compilerConfig,2)) PRIMOP_BITS_NAMES = primop-data-decl.hs-incl \ primop-tag.hs-incl \ primop-list.hs-incl \ - primop-has-side-effects.hs-incl \ + primop-effect.hs-incl \ primop-out-of-line.hs-incl \ primop-commutable.hs-incl \ primop-code-size.hs-incl \ - primop-can-fail.hs-incl \ primop-strictness.hs-incl \ primop-fixity.hs-incl \ primop-primop-info.hs-incl \ @@ -143,16 +142,14 @@ compiler/stage$1/build/primop-tag.hs-incl: compiler/stage$1/build/primops.txt $$ "$$(genprimopcode_INPLACE)" --primop-tag < $$< > $$@ compiler/stage$1/build/primop-list.hs-incl: compiler/stage$1/build/primops.txt $$$$(genprimopcode_INPLACE) "$$(genprimopcode_INPLACE)" --primop-list < $$< > $$@ -compiler/stage$1/build/primop-has-side-effects.hs-incl: compiler/stage$1/build/primops.txt $$$$(genprimopcode_INPLACE) - "$$(genprimopcode_INPLACE)" --has-side-effects < $$< > $$@ +compiler/stage$1/build/primop-effect.hs-incl: compiler/stage$1/build/primops.txt $$$$(genprimopcode_INPLACE) + "$$(genprimopcode_INPLACE)" --effect < $$< > $$@ compiler/stage$1/build/primop-out-of-line.hs-incl: compiler/stage$1/build/primops.txt $$$$(genprimopcode_INPLACE) "$$(genprimopcode_INPLACE)" --out-of-line < $$< > $$@ compiler/stage$1/build/primop-commutable.hs-incl: compiler/stage$1/build/primops.txt $$$$(genprimopcode_INPLACE) "$$(genprimopcode_INPLACE)" --commutable < $$< > $$@ compiler/stage$1/build/primop-code-size.hs-incl: compiler/stage$1/build/primops.txt $$$$(genprimopcode_INPLACE) "$$(genprimopcode_INPLACE)" --code-size < $$< > $$@ -compiler/stage$1/build/primop-can-fail.hs-incl: compiler/stage$1/build/primops.txt $$$$(genprimopcode_INPLACE) - "$$(genprimopcode_INPLACE)" --can-fail < $$< > $$@ compiler/stage$1/build/primop-strictness.hs-incl: compiler/stage$1/build/primops.txt $$$$(genprimopcode_INPLACE) "$$(genprimopcode_INPLACE)" --strictness < $$< > $$@ compiler/stage$1/build/primop-fixity.hs-incl: compiler/stage$1/build/primops.txt $$$$(genprimopcode_INPLACE) ===================================== distrib/hc-build ===================================== @@ -73,11 +73,10 @@ HappyCmd="$PWD/distrib/fake-happy" ./configure --with-ghc="$PWD/compiler/ghc-inp PRIMOP_BITS="primop-data-decl.hs-incl \ primop-tag.hs-incl \ primop-list.hs-incl \ - primop-has-side-effects.hs-incl \ + primop-effect.hs-incl \ primop-out-of-line.hs-incl \ primop-commutable.hs-incl \ primop-needs-wrapper.hs-incl \ - primop-can-fail.hs-incl \ primop-strictness.hs-incl \ primop-usage.hs-incl \ primop-primop-info.hs-incl" ===================================== hadrian/src/Rules/Generate.hs ===================================== @@ -59,12 +59,11 @@ compilerDependencies = do , notStage0 ? isGmp ? return [gmpPath -/- "include/ghc-gmp.h"] , notStage0 ? return ((rtsPath -/-) <$> libffiHeaderFiles) , return $ fmap (ghcPath -/-) - [ "primop-can-fail.hs-incl" - , "primop-code-size.hs-incl" + [ "primop-code-size.hs-incl" , "primop-commutable.hs-incl" , "primop-data-decl.hs-incl" + , "primop-effect.hs-incl" , "primop-fixity.hs-incl" - , "primop-has-side-effects.hs-incl" , "primop-list.hs-incl" , "primop-out-of-line.hs-incl" , "primop-primop-info.hs-incl" ===================================== hadrian/src/Settings/Builders/GenPrimopCode.hs ===================================== @@ -9,11 +9,10 @@ genPrimopCodeBuilderArgs = builder GenPrimopCode ? mconcat , output "//primop-data-decl.hs-incl" ? arg "--data-decl" , output "//primop-tag.hs-incl" ? arg "--primop-tag" , output "//primop-list.hs-incl" ? arg "--primop-list" - , output "//primop-has-side-effects.hs-incl" ? arg "--has-side-effects" + , output "//primop-effect.hs-incl" ? arg "--effect" , output "//primop-out-of-line.hs-incl" ? arg "--out-of-line" , output "//primop-commutable.hs-incl" ? arg "--commutable" , output "//primop-code-size.hs-incl" ? arg "--code-size" - , output "//primop-can-fail.hs-incl" ? arg "--can-fail" , output "//primop-strictness.hs-incl" ? arg "--strictness" , output "//primop-fixity.hs-incl" ? arg "--fixity" , output "//primop-primop-info.hs-incl" ? arg "--primop-primop-info" ===================================== utils/genprimopcode/Main.hs ===================================== @@ -124,10 +124,10 @@ main = getArgs >>= \args -> "--data-decl" -> putStr (gen_data_decl p_o_specs) - "--has-side-effects" + "--effect" -> putStr (gen_switch_from_attribs - "has_side_effects" - "primOpHasSideEffects" p_o_specs) + "effect" + "primOpEffect" p_o_specs) "--out-of-line" -> putStr (gen_switch_from_attribs @@ -144,11 +144,6 @@ main = getArgs >>= \args -> "code_size" "primOpCodeSize" p_o_specs) - "--can-fail" - -> putStr (gen_switch_from_attribs - "can_fail" - "primOpCanFail" p_o_specs) - "--strictness" -> putStr (gen_switch_from_attribs "strictness" @@ -514,20 +509,25 @@ gen_latex_doc (Info defaults entries) mk_options o = "\\primoptions{" - ++ mk_has_side_effects o ++ "}{" + ++ mk_effect o ++ "}{" ++ mk_out_of_line o ++ "}{" ++ mk_commutable o ++ "}{" ++ mk_needs_wrapper o ++ "}{" - ++ mk_can_fail o ++ "}{" ++ mk_fixity o ++ "}{" ++ latex_encode (mk_strictness o) ++ "}{" ++ "}" - mk_has_side_effects o = mk_bool_opt o "has_side_effects" "Has side effects." "Has no side effects." + mk_effect o = case lookup_attrib "effect" o of + Just (OptionString _ "NoEffect") -> "" + Just (OptionString _ "ThrowsImprecise") -> "May throw an imprecise exception." + Just (OptionString _ "WriteEffect") -> "May throw an imprecise exception or perform a write effect." + Just (OptionString _ "ThrowsPrecise") -> "May throw a precise exception (or any other effect)." + Just v -> error "Wrong value for effect: '" ++ show v ++ "'" + Nothing -> "" + mk_out_of_line o = mk_bool_opt o "out_of_line" "Implemented out of line." "Implemented in line." mk_commutable o = mk_bool_opt o "commutable" "Commutable." "Not commutable." mk_needs_wrapper o = mk_bool_opt o "needs_wrapper" "Needs wrapper." "Needs no wrapper." - mk_can_fail o = mk_bool_opt o "can_fail" "Can fail." "Cannot fail." mk_bool_opt o opt_name if_true if_false = case lookup_attrib opt_name o of @@ -774,6 +774,7 @@ gen_switch_from_attribs attrib_name fn_name (Info defaults entries) getAltRhs (OptionString _ s) = s getAltRhs (OptionVector _) = "True" getAltRhs (OptionFixity mf) = show mf + getAltRhs (OptionEffect eff) = show eff mkAlt po = case lookup_attrib attrib_name (opts po) of View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/80544f093969dc264d2f01de87056e2d0489e750...6f871bba28298024524ee7708b855aa0667a59da -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/80544f093969dc264d2f01de87056e2d0489e750...6f871bba28298024524ee7708b855aa0667a59da You're receiving 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 27 17:48:04 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 27 May 2020 13:48:04 -0400 Subject: [Git][ghc/ghc][wip/gc/opt-log2-ceil] 68 commits: IdInfo: Add reference to bitfield-packing ticket Message-ID: <5ecea7d448eb2_6e263f9e9e7046b8205203c@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/gc/opt-log2-ceil 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 - - - - - 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. - - - - - 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] - - - - - 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 - - - - - 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 - - - - - 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. - - - - - 78c6523c by Ben Gamari at 2020-05-21T12:13:01-04:00 nonmoving: Optimise the write barrier - - - - - 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). - - - - - 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 - - - - - b7a6b2f4 by Gleb Popov at 2020-05-21T12:15:26-04:00 gitlab-ci: Set locale to C.UTF-8. - - - - - 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. - - - - - 0004ccb8 by Tuan Le at 2020-05-21T12:16:46-04:00 llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 - - - - - 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 - - - - - 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 - - - - - 2b363ebb by Richard Eisenberg at 2020-05-21T12:18:45-04:00 MR template should ask for key part - - - - - a95bbd0b by Sebastian Graf at 2020-05-21T12:19:37-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. - - - - - d3d055b8 by Galen Huntington at 2020-05-21T12:20:18-04:00 Clarify pitfalls of NegativeLiterals; see #18022. - - - - - 1b508a9e by Alexey Kuleshevich at 2020-05-21T12:21:02-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" - - - - - 4ca0c8a1 by Andreas Klebinger at 2020-05-21T12:21: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. - - - - - a1275081 by Krzysztof Gogolewski at 2020-05-21T12:22:35-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 - - - - - 8a816e5f by Krzysztof Gogolewski at 2020-05-21T12:23:55-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. - - - - - 566cc73f by Sylvain Henry at 2020-05-21T12:24:45-04:00 Move isDynLinkName into GHC.Types.Name It doesn't belong into GHC.Unit.State - - - - - d830bbc9 by Adam Sandberg Ericsson at 2020-05-23T13:36:20-04:00 docs: fix formatting and add some links [skip ci] - - - - - 49301ad6 by Andrew Martin at 2020-05-23T13:37:01-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. - - - - - dcd6bdcc by Ben Gamari at 2020-05-23T13:37:48-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. - - - - - 82cb8913 by John Ericson at 2020-05-23T13:38:32-04:00 Fix #18145 and also avoid needless work with implicit vars - `forAllOrNothing` now is monadic, so we can trace whether we bind an explicit `forall` or not. - #18145 arose because the free vars calculation was needlessly complex. It is now greatly simplified. - Replaced some other implicit var code with `filterFreeVarsToBind`. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - a60dc835 by Ben Gamari at 2020-05-23T13:39:12-04:00 Bump process submodule Fixes #17926. - - - - - 856adf54 by Ben Gamari at 2020-05-23T13:40:21-04:00 users-guide: Clarify meaning of -haddock flag Fixes #18206. - - - - - 7ae57afd by Ben Gamari at 2020-05-23T13:41:03-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 - - - - - 63d30e60 by jneira at 2020-05-24T01:54:42-04:00 Add hie-bios script for windows systems It is a direct translation of the sh script - - - - - 59182b88 by jneira at 2020-05-24T01:54:42-04:00 Honour previous values for CABAL and CABFLAGS The immediate goal is let the hie-bios.bat script set CABFLAGS with `-v0` and remove all cabal output except the compiler arguments - - - - - 932dc54e by jneira at 2020-05-24T01:54:42-04:00 Add specific configuration for windows in hie.yaml - - - - - e0eda070 by jneira at 2020-05-24T01:54:42-04:00 Remove not needed hie-bios output - - - - - a0ea59d6 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Move Config module into GHC.Settings - - - - - 37430251 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Core.Arity into GHC.Core.Opt.Arity - - - - - a426abb9 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Hs.Types into GHC.Hs.Type See discussion in https://gitlab.haskell.org/ghc/ghc/issues/13009#note_268610 - - - - - 1c91a7a0 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Bump haddock submodule - - - - - 66bd24d1 by Ryan Scott at 2020-05-24T01:56:03-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. - - - - - 01c43634 by Matthew Pickering at 2020-05-24T01:56:42-04:00 Remove unused hs-boot file - - - - - 7a07aa71 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix cross-compiler build (#16051) - - - - - 15ccca16 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix distDir per stage - - - - - b420fb24 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix hp2ps error during cross-compilation Fixed by @alp (see https://gitlab.haskell.org/ghc/ghc/issues/16051#note_274265) - - - - - cd339ef0 by Joshua Price at 2020-05-24T15:22:56-04:00 Make Unicode brackets opening/closing tokens (#18225) The tokens `[|`, `|]`, `(|`, and `|)` are opening/closing tokens as described in GHC Proposal #229. This commit makes the unicode variants (`⟦`, `⟧`, `⦇`, and `⦈`) act the same as their ASCII counterparts. - - - - - 013d7120 by Ben Gamari at 2020-05-25T09:48:17-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. - - - - - 4c4312ed by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Drop redundant ad-hoc boot module check To determine whether the module is a boot module Coverage.addTicksToBinds was checking for a `boot` suffix in the module source filename. This is quite ad-hoc and shouldn't be necessary; the callsite in `deSugar` already checks that the module isn't a boot module. - - - - - 1abf3c84 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make tickBoxCount strict This could otherwise easily cause a leak of (+) thunks. - - - - - b2813750 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make ccIndices strict This just seems like a good idea. - - - - - 02e278eb by Ben Gamari at 2020-05-25T09:48:53-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. - - - - - b8c014ce by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Factor out addMixEntry - - - - - 53814a64 by Zubin Duggal at 2020-05-26T03:03:24-04:00 Add info about typeclass evidence to .hie files See `testsuite/tests/hiefile/should_run/HieQueries.hs` and `testsuite/tests/hiefile/should_run/HieQueries.stdout` for an example of this We add two new fields, `EvidenceVarBind` and `EvidenceVarUse` to the `ContextInfo` associated with an Identifier. These are associated with the appropriate identifiers for the evidence variables collected when we come across `HsWrappers`, `TcEvBinds` and `IPBinds` while traversing the AST. Instance dictionary and superclass selector dictionaries from `tcg_insts` and classes defined in `tcg_tcs` are also recorded in the AST as originating from their definition span This allows us to save a complete picture of the evidence constructed by the constraint solver, and will let us report this to the user, enabling features like going to the instance definition from the invocation of a class method(or any other method taking a constraint) and finding all usages of a particular instance. Additionally, - Mark NodeInfo with an origin so we can differentiate between bindings origininating in the source vs those in ghc - Along with typeclass evidence info, also include information on Implicit Parameters - Add a few utility functions to HieUtils in order to query the new info Updates haddock submodule - - - - - 6604906c by Sebastian Graf at 2020-05-26T03:04:04-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. - - - - - cf772f19 by Sylvain Henry at 2020-05-26T03:04:45-04:00 Enhance Note [About units] for Backpack - - - - - ede24126 by Takenobu Tani at 2020-05-27T00:13:55-04:00 core-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Core.hs <= coreSyn/CoreSyn.hs * GHC/Core/Coercion.hs <= types/Coercion.hs * GHC/Core/Coercion/Axiom.hs <= types/CoAxiom.hs * GHC/Core/Coercion/Opt.hs <= types/OptCoercion.hs * GHC/Core/DataCon.hs <= basicTypes/DataCon.hs * GHC/Core/FamInstEnv.hs <= types/FamInstEnv.hs * GHC/Core/Lint.hs <= coreSyn/CoreLint.hs * GHC/Core/Subst.hs <= coreSyn/CoreSubst.hs * GHC/Core/TyCo/Rep.hs <= types/TyCoRep.hs * GHC/Core/TyCon.hs <= types/TyCon.hs * GHC/Core/Type.hs <= types/Type.hs * GHC/Core/Unify.hs <= types/Unify.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/Var.hs <= basicTypes/Var.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [skip ci] - - - - - 04750304 by Ben Gamari at 2020-05-27T00:14:33-04:00 eventlog: Fix racy flushing Previously no attempt was made to avoid multiple threads writing their capability-local eventlog buffers to the eventlog writer simultaneously. This could result in multiple eventlog streams being interleaved. Fix this by documenting that the EventLogWriter's write() and flush() functions may be called reentrantly and fix the default writer to protect its FILE* by a mutex. Fixes #18210. - - - - - d6203f24 by Joshua Price at 2020-05-27T00:15:17-04:00 Make `identifier` parse unparenthesized `->` (#18060) - - - - - d0c7ac14 by Ben Gamari at 2020-05-27T13:48:01-04:00 nonmoving: Optimise log2_ceil - - - - - 30 changed files: - + .git-ignore-revs - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/merge_request_templates/merge-request.md - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - − compiler/GHC/Builtin/Names.hs-boot - 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/Cmm/Opt.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/Dwarf.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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5f69016115414d0dd921e72f3edcd0b365966141...d0c7ac1412b13c8f77bcd4b4188d8c8f34b9c547 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/5f69016115414d0dd921e72f3edcd0b365966141...d0c7ac1412b13c8f77bcd4b4188d8c8f34b9c547 You're receiving 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 27 17:53:52 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 27 May 2020 13:53:52 -0400 Subject: [Git][ghc/ghc][wip/primop-traits] fixups Message-ID: <5ecea9308e82f_6e263f9e9e7046b8205244b@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/primop-traits at Glasgow Haskell Compiler / GHC Commits: 3f6056a5 by Sebastian Graf at 2020-05-27T19:53:37+02:00 fixups - - - - - 3 changed files: - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/primops.txt.pp - utils/genprimopcode/Main.hs Changes: ===================================== compiler/GHC/Builtin/PrimOps.hs ===================================== @@ -340,32 +340,32 @@ data PrimOpEffect -- See Note [Precise vs imprecise exceptions] in GHC.Types.Demand. deriving (Eq, Ord) --- | Can we discard a call to the primop, i.e. @case a `op` b of _ -> rhs@? --- This is a question that i.e. the Simplifier asks before dropping the @case at . --- See Note [Transformations affected by can_fail and has_side_effects]. -isDiscardablePrimOpEffect :: PrimOpEffect -> Bool -isDiscardablePrimOpEffect eff = eff <= ThrowsImprecise - --- | Can we duplicate a call to the primop? --- This is a question that i.e. the Simplifier asks when inlining definitions --- involving primops with multiple syntactic occurrences. --- See Note [Transformations affected by can_fail and has_side_effects]. -isDupablePrimOpEffect :: PrimOpEffect -> Bool --- isDupablePrimOpEffect eff = True -- #3207, see the Note -isDupablePrimOpEffect eff = eff <= ThrowsImprecise - --- | Can we perform other actions first before entering the primop? --- This is the question that i.e. @FloatIn@ asks. --- See Note [Transformations affected by can_fail and has_side_effects]. -isDeferrablePrimOpEffect :: PrimOpEffect -> Bool -isDeferrablePrimOpEffect eff = eff <= WriteEffect - --- | Can we speculatively execute this primop, before performing other actions --- that should come first according to evaluation strategy? --- This is the question that i.e. @FloatOut@ (of a @case@) asks. --- See Note [Transformations affected by can_fail and has_side_effects]. -isSpeculatablePrimOpEffect :: PrimOpEffect -> Bool -isSpeculatablePrimOpEffect eff = eff <= NoEffect +-- -- | Can we discard a call to the primop, i.e. @case a `op` b of _ -> rhs@? +-- -- This is a question that i.e. the Simplifier asks before dropping the @case at . +-- -- See Note [Transformations affected by can_fail and has_side_effects]. +-- isDiscardablePrimOpEffect :: PrimOpEffect -> Bool +-- isDiscardablePrimOpEffect eff = eff <= ThrowsImprecise +-- +-- -- | Can we duplicate a call to the primop? +-- -- This is a question that i.e. the Simplifier asks when inlining definitions +-- -- involving primops with multiple syntactic occurrences. +-- -- See Note [Transformations affected by can_fail and has_side_effects]. +-- isDupablePrimOpEffect :: PrimOpEffect -> Bool +-- -- isDupablePrimOpEffect eff = True -- #3207, see the Note +-- isDupablePrimOpEffect eff = eff <= ThrowsImprecise +-- +-- -- | Can we perform other actions first before entering the primop? +-- -- This is the question that i.e. @FloatIn@ asks. +-- -- See Note [Transformations affected by can_fail and has_side_effects]. +-- isDeferrablePrimOpEffect :: PrimOpEffect -> Bool +-- isDeferrablePrimOpEffect eff = eff <= WriteEffect +-- +-- -- | Can we speculatively execute this primop, before performing other actions +-- -- that should come first according to evaluation strategy? +-- -- This is the question that i.e. @FloatOut@ (of a @case@) asks. +-- -- See Note [Transformations affected by can_fail and has_side_effects]. +-- isSpeculatablePrimOpEffect :: PrimOpEffect -> Bool +-- isSpeculatablePrimOpEffect eff = eff <= NoEffect {- Note [Classification by PrimOpEffect] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -523,13 +523,11 @@ Two main predicates on primpops test these flags: primOpEffect :: PrimOp -> PrimOpEffect #include "primop-effect.hs-incl" -primOpOkForSideEffects :: PrimOp -> Bool --- This is exactly @isDupablePrimOpEffect (primOpEffect op)@ -primOpOkForSideEffects op = primOpEffect op < WriteEffect +primOpHasSideEffects :: PrimOp -> Bool +primOpHasSideEffects op = primOpEffect op >= WriteEffect primOpCanFail :: PrimOp -> Bool --- This is exactly @isSpeculatablePrimOpEffect (primOpEffect op)@ -primOpCanFail op = primOpEffect op < ThrowsImprecise +primOpCanFail op = primOpEffect op >= ThrowsImprecise primOpOkForSpeculation :: PrimOp -> Bool -- See Note [PrimOp can_fail and has_side_effects] ===================================== compiler/GHC/Builtin/primops.txt.pp ===================================== @@ -67,7 +67,7 @@ -- #). defaults - effect = NoEffect -- See Note [Classification by PrimOpEffect] in PrimOp.hs + effect = { NoEffect } -- See Note [Classification by PrimOpEffect] in PrimOp.hs out_of_line = False -- See Note [When do out-of-line primops go in primops.txt.pp] commutable = False code_size = { primOpCodeSizeDefault } @@ -99,7 +99,7 @@ defaults -- - No polymorphism in type -- - `strictness = ` -- - `can_fail = False` --- - `effect = WriteEffect` +-- - `effect = { WriteEffect }` -- -- https://gitlab.haskell.org/ghc/ghc/issues/16929 tracks this issue, -- and has a table of which external-only primops are blocked by which @@ -253,15 +253,15 @@ primop Int8MulOp "timesInt8#" Dyadic Int8# -> Int8# -> Int8# primop Int8QuotOp "quotInt8#" Dyadic Int8# -> Int8# -> Int8# with - effect = ThrowsImprecise + effect = { ThrowsImprecise } primop Int8RemOp "remInt8#" Dyadic Int8# -> Int8# -> Int8# with - effect = ThrowsImprecise + effect = { ThrowsImprecise } primop Int8QuotRemOp "quotRemInt8#" GenPrimOp Int8# -> Int8# -> (# Int8#, Int8# #) with - effect = ThrowsImprecise + effect = { ThrowsImprecise } primop Int8EqOp "eqInt8#" Compare Int8# -> Int8# -> Int# primop Int8GeOp "geInt8#" Compare Int8# -> Int8# -> Int# @@ -294,15 +294,15 @@ primop Word8MulOp "timesWord8#" Dyadic Word8# -> Word8# -> Word8# primop Word8QuotOp "quotWord8#" Dyadic Word8# -> Word8# -> Word8# with - effect = ThrowsImprecise + effect = { ThrowsImprecise } primop Word8RemOp "remWord8#" Dyadic Word8# -> Word8# -> Word8# with - effect = ThrowsImprecise + effect = { ThrowsImprecise } primop Word8QuotRemOp "quotRemWord8#" GenPrimOp Word8# -> Word8# -> (# Word8#, Word8# #) with - effect = ThrowsImprecise + effect = { ThrowsImprecise } primop Word8EqOp "eqWord8#" Compare Word8# -> Word8# -> Int# primop Word8GeOp "geWord8#" Compare Word8# -> Word8# -> Int# @@ -335,15 +335,15 @@ primop Int16MulOp "timesInt16#" Dyadic Int16# -> Int16# -> Int16# primop Int16QuotOp "quotInt16#" Dyadic Int16# -> Int16# -> Int16# with - effect = ThrowsImprecise + effect = { ThrowsImprecise } primop Int16RemOp "remInt16#" Dyadic Int16# -> Int16# -> Int16# with - effect = ThrowsImprecise + effect = { ThrowsImprecise } primop Int16QuotRemOp "quotRemInt16#" GenPrimOp Int16# -> Int16# -> (# Int16#, Int16# #) with - effect = ThrowsImprecise + effect = { ThrowsImprecise } primop Int16EqOp "eqInt16#" Compare Int16# -> Int16# -> Int# primop Int16GeOp "geInt16#" Compare Int16# -> Int16# -> Int# @@ -376,15 +376,15 @@ primop Word16MulOp "timesWord16#" Dyadic Word16# -> Word16# -> Word16# primop Word16QuotOp "quotWord16#" Dyadic Word16# -> Word16# -> Word16# with - effect = ThrowsImprecise + effect = { ThrowsImprecise } primop Word16RemOp "remWord16#" Dyadic Word16# -> Word16# -> Word16# with - effect = ThrowsImprecise + effect = { ThrowsImprecise } primop Word16QuotRemOp "quotRemWord16#" GenPrimOp Word16# -> Word16# -> (# Word16#, Word16# #) with - effect = ThrowsImprecise + effect = { ThrowsImprecise } primop Word16EqOp "eqWord16#" Compare Word16# -> Word16# -> Int# primop Word16GeOp "geWord16#" Compare Word16# -> Word16# -> Int# @@ -471,19 +471,19 @@ primop IntQuotOp "quotInt#" Dyadic {Rounds towards zero. The behavior is undefined if the second argument is zero. } - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IntRemOp "remInt#" Dyadic Int# -> Int# -> Int# {Satisfies \texttt{(quotInt\# x y) *\# y +\# (remInt\# x y) == x}. The behavior is undefined if the second argument is zero. } - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IntQuotRemOp "quotRemInt#" GenPrimOp Int# -> Int# -> (# Int#, Int# #) {Rounds towards zero.} - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop AndIOp "andI#" Dyadic Int# -> Int# -> Int# {Bitwise "and".} @@ -608,20 +608,20 @@ primop WordMul2Op "timesWord2#" GenPrimOp with commutable = True primop WordQuotOp "quotWord#" Dyadic Word# -> Word# -> Word# - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop WordRemOp "remWord#" Dyadic Word# -> Word# -> Word# - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop WordQuotRemOp "quotRemWord#" GenPrimOp Word# -> Word# -> (# Word#, Word# #) - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop WordQuotRem2Op "quotRemWord2#" GenPrimOp Word# -> Word# -> Word# -> (# Word#, Word# #) { Takes high word of dividend, then low word of dividend, then divisor. Requires that high word < divisor.} - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop AndOp "and#" Dyadic Word# -> Word# -> Word# with commutable = True @@ -782,7 +782,7 @@ primop DoubleMulOp "*##" Dyadic primop DoubleDivOp "/##" Dyadic Double# -> Double# -> Double# - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } fixity = infixl 7 primop DoubleNegOp "negateDouble#" Monadic Double# -> Double# @@ -810,13 +810,13 @@ primop DoubleLogOp "logDouble#" Monadic Double# -> Double# with code_size = { primOpCodeSizeForeignCall } - effect = ThrowsImprecise + effect = { ThrowsImprecise } primop DoubleLog1POp "log1pDouble#" Monadic Double# -> Double# with code_size = { primOpCodeSizeForeignCall } - effect = ThrowsImprecise + effect = { ThrowsImprecise } primop DoubleSqrtOp "sqrtDouble#" Monadic Double# -> Double# @@ -842,13 +842,13 @@ primop DoubleAsinOp "asinDouble#" Monadic Double# -> Double# with code_size = { primOpCodeSizeForeignCall } - effect = ThrowsImprecise + effect = { ThrowsImprecise } primop DoubleAcosOp "acosDouble#" Monadic Double# -> Double# with code_size = { primOpCodeSizeForeignCall } - effect = ThrowsImprecise + effect = { ThrowsImprecise } primop DoubleAtanOp "atanDouble#" Monadic Double# -> Double# @@ -937,7 +937,7 @@ primop FloatMulOp "timesFloat#" Dyadic primop FloatDivOp "divideFloat#" Dyadic Float# -> Float# -> Float# - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop FloatNegOp "negateFloat#" Monadic Float# -> Float# @@ -962,13 +962,13 @@ primop FloatLogOp "logFloat#" Monadic Float# -> Float# with code_size = { primOpCodeSizeForeignCall } - effect = ThrowsImprecise + effect = { ThrowsImprecise } primop FloatLog1POp "log1pFloat#" Monadic Float# -> Float# with code_size = { primOpCodeSizeForeignCall } - effect = ThrowsImprecise + effect = { ThrowsImprecise } primop FloatSqrtOp "sqrtFloat#" Monadic Float# -> Float# @@ -994,13 +994,13 @@ primop FloatAsinOp "asinFloat#" Monadic Float# -> Float# with code_size = { primOpCodeSizeForeignCall } - effect = ThrowsImprecise + effect = { ThrowsImprecise } primop FloatAcosOp "acosFloat#" Monadic Float# -> Float# with code_size = { primOpCodeSizeForeignCall } - effect = ThrowsImprecise + effect = { ThrowsImprecise } primop FloatAtanOp "atanFloat#" Monadic Float# -> Float# @@ -1066,8 +1066,8 @@ primop NewArrayOp "newArray#" GenPrimOp with each element containing the specified initial value.} with out_of_line = True - -- effect = NoEffect -- #3207 - effect = WriteEffect + -- effect = { NoEffect } -- #3207 + effect = { WriteEffect } primop SameMutableArrayOp "sameMutableArray#" GenPrimOp MutableArray# s a -> MutableArray# s a -> Int# @@ -1076,14 +1076,14 @@ primop ReadArrayOp "readArray#" GenPrimOp MutableArray# s a -> Int# -> State# s -> (# State# s, a #) {Read from specified index of mutable array. Result is not yet evaluated.} with - -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop WriteArrayOp "writeArray#" GenPrimOp MutableArray# s a -> Int# -> a -> State# s -> State# s {Write to specified index of mutable array.} with - effect = WriteEffect + effect = { WriteEffect } code_size = 2 -- card update too primop SizeofArrayOp "sizeofArray#" GenPrimOp @@ -1104,20 +1104,20 @@ primop IndexArrayOp "indexArray#" GenPrimOp heap. Avoiding these thunks, in turn, reduces references to the argument array, allowing it to be garbage collected more promptly.} with - effect = ThrowsImprecise + effect = { ThrowsImprecise } primop UnsafeFreezeArrayOp "unsafeFreezeArray#" GenPrimOp MutableArray# s a -> State# s -> (# State# s, Array# a #) {Make a mutable array immutable, without copying.} with - effect = WriteEffect + effect = { WriteEffect } primop UnsafeThawArrayOp "unsafeThawArray#" GenPrimOp Array# a -> State# s -> (# State# s, MutableArray# s a #) {Make an immutable array mutable, without copying.} with out_of_line = True - effect = WriteEffect + effect = { WriteEffect } primop CopyArrayOp "copyArray#" GenPrimOp Array# a -> Int# -> MutableArray# s a -> Int# -> Int# -> State# s -> State# s @@ -1130,7 +1130,7 @@ primop CopyArrayOp "copyArray#" GenPrimOp either.} with out_of_line = True - effect = WriteEffect + effect = { WriteEffect } primop CopyMutableArrayOp "copyMutableArray#" GenPrimOp MutableArray# s a -> Int# -> MutableArray# s a -> Int# -> Int# -> State# s -> State# s @@ -1143,7 +1143,7 @@ primop CopyMutableArrayOp "copyMutableArray#" GenPrimOp destination regions may overlap.} with out_of_line = True - effect = WriteEffect + effect = { WriteEffect } primop CloneArrayOp "cloneArray#" GenPrimOp Array# a -> Int# -> Int# -> Array# a @@ -1153,7 +1153,7 @@ primop CloneArrayOp "cloneArray#" GenPrimOp range, but this is not checked.} with out_of_line = True - effect = WriteEffect + effect = { WriteEffect } primop CloneMutableArrayOp "cloneMutableArray#" GenPrimOp MutableArray# s a -> Int# -> Int# -> State# s -> (# State# s, MutableArray# s a #) @@ -1163,7 +1163,7 @@ primop CloneMutableArrayOp "cloneMutableArray#" GenPrimOp range, but this is not checked.} with out_of_line = True - effect = WriteEffect + effect = { WriteEffect } primop FreezeArrayOp "freezeArray#" GenPrimOp MutableArray# s a -> Int# -> Int# -> State# s -> (# State# s, Array# a #) @@ -1173,8 +1173,8 @@ primop FreezeArrayOp "freezeArray#" GenPrimOp range, but this is not checked.} with out_of_line = True - -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ThawArrayOp "thawArray#" GenPrimOp Array# a -> Int# -> Int# -> State# s -> (# State# s, MutableArray# s a #) @@ -1184,8 +1184,8 @@ primop ThawArrayOp "thawArray#" GenPrimOp range, but this is not checked.} with out_of_line = True - -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop CasArrayOp "casArray#" GenPrimOp MutableArray# s a -> Int# -> a -> a -> State# s -> (# State# s, Int#, a #) @@ -1203,7 +1203,7 @@ primop CasArrayOp "casArray#" GenPrimOp } with out_of_line = True - effect = WriteEffect + effect = { WriteEffect } ------------------------------------------------------------------------ @@ -1240,8 +1240,8 @@ primop NewSmallArrayOp "newSmallArray#" GenPrimOp with each element containing the specified initial value.} with out_of_line = True - -- effect = NoEffect -- #3207 - effect = WriteEffect + -- effect = { NoEffect } -- #3207 + effect = { WriteEffect } primop SameSmallMutableArrayOp "sameSmallMutableArray#" GenPrimOp SmallMutableArray# s a -> SmallMutableArray# s a -> Int# @@ -1252,20 +1252,20 @@ primop ShrinkSmallMutableArrayOp_Char "shrinkSmallMutableArray#" GenPrimOp the specified state thread. The new size argument must be less than or equal to the current size as reported by {\tt getSizeofSmallMutableArray\#}.} with out_of_line = True - effect = WriteEffect + effect = { WriteEffect } primop ReadSmallArrayOp "readSmallArray#" GenPrimOp SmallMutableArray# s a -> Int# -> State# s -> (# State# s, a #) {Read from specified index of mutable array. Result is not yet evaluated.} with - -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop WriteSmallArrayOp "writeSmallArray#" GenPrimOp SmallMutableArray# s a -> Int# -> a -> State# s -> State# s {Write to specified index of mutable array.} with - effect = WriteEffect + effect = { WriteEffect } primop SizeofSmallArrayOp "sizeofSmallArray#" GenPrimOp SmallArray# a -> Int# @@ -1287,20 +1287,20 @@ primop IndexSmallArrayOp "indexSmallArray#" GenPrimOp {Read from specified index of immutable array. Result is packaged into an unboxed singleton; the result itself is not yet evaluated.} with - effect = ThrowsImprecise + effect = { ThrowsImprecise } primop UnsafeFreezeSmallArrayOp "unsafeFreezeSmallArray#" GenPrimOp SmallMutableArray# s a -> State# s -> (# State# s, SmallArray# a #) {Make a mutable array immutable, without copying.} with - effect = WriteEffect + effect = { WriteEffect } primop UnsafeThawSmallArrayOp "unsafeThawSmallArray#" GenPrimOp SmallArray# a -> State# s -> (# State# s, SmallMutableArray# s a #) {Make an immutable array mutable, without copying.} with out_of_line = True - effect = WriteEffect + effect = { WriteEffect } -- The code_size is only correct for the case when the copy family of -- primops aren't inlined. It would be nice to keep track of both. @@ -1316,7 +1316,7 @@ primop CopySmallArrayOp "copySmallArray#" GenPrimOp either.} with out_of_line = True - effect = WriteEffect + effect = { WriteEffect } primop CopySmallMutableArrayOp "copySmallMutableArray#" GenPrimOp SmallMutableArray# s a -> Int# -> SmallMutableArray# s a -> Int# -> Int# -> State# s -> State# s @@ -1330,7 +1330,7 @@ primop CopySmallMutableArrayOp "copySmallMutableArray#" GenPrimOp array is provided as both the source and the destination. } with out_of_line = True - effect = WriteEffect + effect = { WriteEffect } primop CloneSmallArrayOp "cloneSmallArray#" GenPrimOp SmallArray# a -> Int# -> Int# -> SmallArray# a @@ -1340,7 +1340,7 @@ primop CloneSmallArrayOp "cloneSmallArray#" GenPrimOp range, but this is not checked.} with out_of_line = True - effect = ThrowsImprecise + effect = { ThrowsImprecise } primop CloneSmallMutableArrayOp "cloneSmallMutableArray#" GenPrimOp SmallMutableArray# s a -> Int# -> Int# -> State# s -> (# State# s, SmallMutableArray# s a #) @@ -1350,8 +1350,8 @@ primop CloneSmallMutableArrayOp "cloneSmallMutableArray#" GenPrimOp range, but this is not checked.} with out_of_line = True - -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop FreezeSmallArrayOp "freezeSmallArray#" GenPrimOp SmallMutableArray# s a -> Int# -> Int# -> State# s -> (# State# s, SmallArray# a #) @@ -1361,8 +1361,8 @@ primop FreezeSmallArrayOp "freezeSmallArray#" GenPrimOp range, but this is not checked.} with out_of_line = True - -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ThawSmallArrayOp "thawSmallArray#" GenPrimOp SmallArray# a -> Int# -> Int# -> State# s -> (# State# s, SmallMutableArray# s a #) @@ -1372,8 +1372,8 @@ primop ThawSmallArrayOp "thawSmallArray#" GenPrimOp range, but this is not checked.} with out_of_line = True - -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop CasSmallArrayOp "casSmallArray#" GenPrimOp SmallMutableArray# s a -> Int# -> a -> a -> State# s -> (# State# s, Int#, a #) @@ -1381,7 +1381,7 @@ primop CasSmallArrayOp "casSmallArray#" GenPrimOp See the documentation of {\tt casArray\#}.} with out_of_line = True - effect = WriteEffect + effect = { WriteEffect } ------------------------------------------------------------------------ section "Byte Arrays" @@ -1408,21 +1408,21 @@ primop NewByteArrayOp_Char "newByteArray#" GenPrimOp the specified state thread.} with out_of_line = True -- effect = NoEffec --#3207 - effect = WriteEffect + effect = { WriteEffect } primop NewPinnedByteArrayOp_Char "newPinnedByteArray#" GenPrimOp Int# -> State# s -> (# State# s, MutableByteArray# s #) {Create a mutable byte array that the GC guarantees not to move.} with out_of_line = True -- effect = NoEffec --#3207 - effect = WriteEffect + effect = { WriteEffect } 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.} with out_of_line = True -- effect = NoEffec --#3207 - effect = WriteEffect + effect = { WriteEffect } primop MutableByteArrayIsPinnedOp "isMutableByteArrayPinned#" GenPrimOp MutableByteArray# s -> Int# @@ -1448,7 +1448,7 @@ primop ShrinkMutableByteArrayOp_Char "shrinkMutableByteArray#" GenPrimOp the specified state thread. The new size argument must be less than or equal to the current size as reported by {\tt getSizeofMutableByteArray\#}.} with out_of_line = True - effect = WriteEffect + effect = { WriteEffect } primop ResizeMutableByteArrayOp_Char "resizeMutableByteArray#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s,MutableByteArray# s #) @@ -1464,13 +1464,13 @@ primop ResizeMutableByteArrayOp_Char "resizeMutableByteArray#" GenPrimOp to allow garbage collection of the original {\tt MutableByteArray\#} in case a new {\tt MutableByteArray\#} had to be allocated.} with out_of_line = True - effect = WriteEffect + effect = { WriteEffect } primop UnsafeFreezeByteArrayOp "unsafeFreezeByteArray#" GenPrimOp MutableByteArray# s -> State# s -> (# State# s, ByteArray# #) {Make a mutable byte array immutable, without copying.} with - effect = WriteEffect + effect = { WriteEffect } primop SizeofByteArrayOp "sizeofByteArray#" GenPrimOp ByteArray# -> Int# @@ -1490,452 +1490,421 @@ primop GetSizeofMutableByteArrayOp "getSizeofMutableByteArray#" GenPrimOp primop IndexByteArrayOp_Char "indexCharArray#" GenPrimOp ByteArray# -> Int# -> Char# {Read 8-bit character; offset in bytes.} - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexByteArrayOp_WideChar "indexWideCharArray#" GenPrimOp ByteArray# -> Int# -> Char# {Read 31-bit character; offset in 4-byte words.} - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexByteArrayOp_Int "indexIntArray#" GenPrimOp ByteArray# -> Int# -> Int# - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexByteArrayOp_Word "indexWordArray#" GenPrimOp ByteArray# -> Int# -> Word# - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexByteArrayOp_Addr "indexAddrArray#" GenPrimOp ByteArray# -> Int# -> Addr# - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexByteArrayOp_Float "indexFloatArray#" GenPrimOp ByteArray# -> Int# -> Float# - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexByteArrayOp_Double "indexDoubleArray#" GenPrimOp ByteArray# -> Int# -> Double# - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexByteArrayOp_StablePtr "indexStablePtrArray#" GenPrimOp ByteArray# -> Int# -> StablePtr# a - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexByteArrayOp_Int8 "indexInt8Array#" GenPrimOp ByteArray# -> Int# -> Int# {Read 8-bit integer; offset in bytes.} - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexByteArrayOp_Int16 "indexInt16Array#" GenPrimOp ByteArray# -> Int# -> Int# {Read 16-bit integer; offset in 16-bit words.} - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexByteArrayOp_Int32 "indexInt32Array#" GenPrimOp ByteArray# -> Int# -> INT32 {Read 32-bit integer; offset in 32-bit words.} - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexByteArrayOp_Int64 "indexInt64Array#" GenPrimOp ByteArray# -> Int# -> INT64 {Read 64-bit integer; offset in 64-bit words.} - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexByteArrayOp_Word8 "indexWord8Array#" GenPrimOp ByteArray# -> Int# -> Word# {Read 8-bit word; offset in bytes.} - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexByteArrayOp_Word16 "indexWord16Array#" GenPrimOp ByteArray# -> Int# -> Word# {Read 16-bit word; offset in 16-bit words.} - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexByteArrayOp_Word32 "indexWord32Array#" GenPrimOp ByteArray# -> Int# -> WORD32 {Read 32-bit word; offset in 32-bit words.} - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexByteArrayOp_Word64 "indexWord64Array#" GenPrimOp ByteArray# -> Int# -> WORD64 {Read 64-bit word; offset in 64-bit words.} - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexByteArrayOp_Word8AsChar "indexWord8ArrayAsChar#" GenPrimOp ByteArray# -> Int# -> Char# {Read 8-bit character; offset in bytes.} - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexByteArrayOp_Word8AsWideChar "indexWord8ArrayAsWideChar#" GenPrimOp ByteArray# -> Int# -> Char# {Read 31-bit character; offset in bytes.} - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexByteArrayOp_Word8AsAddr "indexWord8ArrayAsAddr#" GenPrimOp ByteArray# -> Int# -> Addr# {Read address; offset in bytes.} - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexByteArrayOp_Word8AsFloat "indexWord8ArrayAsFloat#" GenPrimOp ByteArray# -> Int# -> Float# {Read float; offset in bytes.} - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexByteArrayOp_Word8AsDouble "indexWord8ArrayAsDouble#" GenPrimOp ByteArray# -> Int# -> Double# {Read double; offset in bytes.} - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexByteArrayOp_Word8AsStablePtr "indexWord8ArrayAsStablePtr#" GenPrimOp ByteArray# -> Int# -> StablePtr# a {Read stable pointer; offset in bytes.} - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexByteArrayOp_Word8AsInt16 "indexWord8ArrayAsInt16#" GenPrimOp ByteArray# -> Int# -> Int# {Read 16-bit int; offset in bytes.} - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexByteArrayOp_Word8AsInt32 "indexWord8ArrayAsInt32#" GenPrimOp ByteArray# -> Int# -> INT32 {Read 32-bit int; offset in bytes.} - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexByteArrayOp_Word8AsInt64 "indexWord8ArrayAsInt64#" GenPrimOp ByteArray# -> Int# -> INT64 {Read 64-bit int; offset in bytes.} - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexByteArrayOp_Word8AsInt "indexWord8ArrayAsInt#" GenPrimOp ByteArray# -> Int# -> Int# {Read int; offset in bytes.} - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexByteArrayOp_Word8AsWord16 "indexWord8ArrayAsWord16#" GenPrimOp ByteArray# -> Int# -> Word# {Read 16-bit word; offset in bytes.} - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexByteArrayOp_Word8AsWord32 "indexWord8ArrayAsWord32#" GenPrimOp ByteArray# -> Int# -> WORD32 {Read 32-bit word; offset in bytes.} - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexByteArrayOp_Word8AsWord64 "indexWord8ArrayAsWord64#" GenPrimOp ByteArray# -> Int# -> WORD64 {Read 64-bit word; offset in bytes.} - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexByteArrayOp_Word8AsWord "indexWord8ArrayAsWord#" GenPrimOp ByteArray# -> Int# -> Word# {Read word; offset in bytes.} - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop ReadByteArrayOp_Char "readCharArray#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, Char# #) {Read 8-bit character; offset in bytes.} - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadByteArrayOp_WideChar "readWideCharArray#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, Char# #) {Read 31-bit character; offset in 4-byte words.} - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadByteArrayOp_Int "readIntArray#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #) {Read integer; offset in machine words.} - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadByteArrayOp_Word "readWordArray#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, Word# #) {Read word; offset in machine words.} - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadByteArrayOp_Addr "readAddrArray#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, Addr# #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadByteArrayOp_Float "readFloatArray#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, Float# #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadByteArrayOp_Double "readDoubleArray#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, Double# #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadByteArrayOp_StablePtr "readStablePtrArray#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, StablePtr# a #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadByteArrayOp_Int8 "readInt8Array#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadByteArrayOp_Int16 "readInt16Array#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadByteArrayOp_Int32 "readInt32Array#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, INT32 #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadByteArrayOp_Int64 "readInt64Array#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, INT64 #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadByteArrayOp_Word8 "readWord8Array#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, Word# #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadByteArrayOp_Word16 "readWord16Array#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, Word# #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadByteArrayOp_Word32 "readWord32Array#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, WORD32 #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadByteArrayOp_Word64 "readWord64Array#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, WORD64 #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadByteArrayOp_Word8AsChar "readWord8ArrayAsChar#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, Char# #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadByteArrayOp_Word8AsWideChar "readWord8ArrayAsWideChar#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, Char# #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadByteArrayOp_Word8AsAddr "readWord8ArrayAsAddr#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, Addr# #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadByteArrayOp_Word8AsFloat "readWord8ArrayAsFloat#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, Float# #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadByteArrayOp_Word8AsDouble "readWord8ArrayAsDouble#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, Double# #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadByteArrayOp_Word8AsStablePtr "readWord8ArrayAsStablePtr#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, StablePtr# a #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadByteArrayOp_Word8AsInt16 "readWord8ArrayAsInt16#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadByteArrayOp_Word8AsInt32 "readWord8ArrayAsInt32#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, INT32 #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadByteArrayOp_Word8AsInt64 "readWord8ArrayAsInt64#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, INT64 #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadByteArrayOp_Word8AsInt "readWord8ArrayAsInt#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadByteArrayOp_Word8AsWord16 "readWord8ArrayAsWord16#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, Word# #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadByteArrayOp_Word8AsWord32 "readWord8ArrayAsWord32#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, WORD32 #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadByteArrayOp_Word8AsWord64 "readWord8ArrayAsWord64#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, WORD64 #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadByteArrayOp_Word8AsWord "readWord8ArrayAsWord#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, Word# #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_Char "writeCharArray#" GenPrimOp MutableByteArray# s -> Int# -> Char# -> State# s -> State# s {Write 8-bit character; offset in bytes.} - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_WideChar "writeWideCharArray#" GenPrimOp MutableByteArray# s -> Int# -> Char# -> State# s -> State# s {Write 31-bit character; offset in 4-byte words.} - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_Int "writeIntArray#" GenPrimOp MutableByteArray# s -> Int# -> Int# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_Word "writeWordArray#" GenPrimOp MutableByteArray# s -> Int# -> Word# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_Addr "writeAddrArray#" GenPrimOp MutableByteArray# s -> Int# -> Addr# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_Float "writeFloatArray#" GenPrimOp MutableByteArray# s -> Int# -> Float# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_Double "writeDoubleArray#" GenPrimOp MutableByteArray# s -> Int# -> Double# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_StablePtr "writeStablePtrArray#" GenPrimOp MutableByteArray# s -> Int# -> StablePtr# a -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_Int8 "writeInt8Array#" GenPrimOp MutableByteArray# s -> Int# -> Int# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_Int16 "writeInt16Array#" GenPrimOp MutableByteArray# s -> Int# -> Int# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_Int32 "writeInt32Array#" GenPrimOp MutableByteArray# s -> Int# -> INT32 -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_Int64 "writeInt64Array#" GenPrimOp MutableByteArray# s -> Int# -> INT64 -> State# s -> State# s - with effect = ThrowsImprecise - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_Word8 "writeWord8Array#" GenPrimOp MutableByteArray# s -> Int# -> Word# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_Word16 "writeWord16Array#" GenPrimOp MutableByteArray# s -> Int# -> Word# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_Word32 "writeWord32Array#" GenPrimOp MutableByteArray# s -> Int# -> WORD32 -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_Word64 "writeWord64Array#" GenPrimOp MutableByteArray# s -> Int# -> WORD64 -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_Word8AsChar "writeWord8ArrayAsChar#" GenPrimOp MutableByteArray# s -> Int# -> Char# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_Word8AsWideChar "writeWord8ArrayAsWideChar#" GenPrimOp MutableByteArray# s -> Int# -> Char# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_Word8AsAddr "writeWord8ArrayAsAddr#" GenPrimOp MutableByteArray# s -> Int# -> Addr# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_Word8AsFloat "writeWord8ArrayAsFloat#" GenPrimOp MutableByteArray# s -> Int# -> Float# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_Word8AsDouble "writeWord8ArrayAsDouble#" GenPrimOp MutableByteArray# s -> Int# -> Double# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_Word8AsStablePtr "writeWord8ArrayAsStablePtr#" GenPrimOp MutableByteArray# s -> Int# -> StablePtr# a -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_Word8AsInt16 "writeWord8ArrayAsInt16#" GenPrimOp MutableByteArray# s -> Int# -> Int# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_Word8AsInt32 "writeWord8ArrayAsInt32#" GenPrimOp MutableByteArray# s -> Int# -> INT32 -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_Word8AsInt64 "writeWord8ArrayAsInt64#" GenPrimOp MutableByteArray# s -> Int# -> INT64 -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_Word8AsInt "writeWord8ArrayAsInt#" GenPrimOp MutableByteArray# s -> Int# -> Int# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_Word8AsWord16 "writeWord8ArrayAsWord16#" GenPrimOp MutableByteArray# s -> Int# -> Word# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_Word8AsWord32 "writeWord8ArrayAsWord32#" GenPrimOp MutableByteArray# s -> Int# -> WORD32 -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_Word8AsWord64 "writeWord8ArrayAsWord64#" GenPrimOp MutableByteArray# s -> Int# -> WORD64 -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop WriteByteArrayOp_Word8AsWord "writeWord8ArrayAsWord#" GenPrimOp MutableByteArray# s -> Int# -> Word# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with effect = { WriteEffect } primop CompareByteArraysOp "compareByteArrays#" GenPrimOp ByteArray# -> Int# -> ByteArray# -> Int# -> Int# -> Int# @@ -1949,7 +1918,7 @@ primop CompareByteArraysOp "compareByteArrays#" GenPrimOp respectively, to be byte-wise lexicographically less than, to match, or be greater than the second range.} with - effect = ThrowsImprecise + effect = { ThrowsImprecise } primop CopyByteArrayOp "copyByteArray#" GenPrimOp ByteArray# -> Int# -> MutableByteArray# s -> Int# -> Int# -> State# s -> State# s @@ -1961,8 +1930,8 @@ primop CopyByteArrayOp "copyByteArray#" GenPrimOp not be the same array in different states, but this is not checked either.} with - -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } code_size = { primOpCodeSizeForeignCall + 4} primop CopyMutableByteArrayOp "copyMutableByteArray#" GenPrimOp @@ -1972,8 +1941,8 @@ primop CopyMutableByteArrayOp "copyMutableByteArray#" GenPrimOp allowed to overlap, although this is only possible when the same array is provided as both the source and the destination.} with - -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } code_size = { primOpCodeSizeForeignCall + 4 } primop CopyByteArrayToAddrOp "copyByteArrayToAddr#" GenPrimOp @@ -1984,8 +1953,8 @@ primop CopyByteArrayToAddrOp "copyByteArrayToAddr#" GenPrimOp ByteArray\# (e.g. if the ByteArray\# were pinned), but this is not checked either.} with - -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } code_size = { primOpCodeSizeForeignCall + 4} primop CopyMutableByteArrayToAddrOp "copyMutableByteArrayToAddr#" GenPrimOp @@ -1996,8 +1965,8 @@ primop CopyMutableByteArrayToAddrOp "copyMutableByteArrayToAddr#" GenPrimOp point into the MutableByteArray\# (e.g. if the MutableByteArray\# were pinned), but this is not checked either.} with - -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } code_size = { primOpCodeSizeForeignCall + 4} primop CopyAddrToByteArrayOp "copyAddrToByteArray#" GenPrimOp @@ -2008,8 +1977,8 @@ primop CopyAddrToByteArrayOp "copyAddrToByteArray#" GenPrimOp point into the MutableByteArray\# (e.g. if the MutableByteArray\# were pinned), but this is not checked either.} with - -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } code_size = { primOpCodeSizeForeignCall + 4} primop SetByteArrayOp "setByteArray#" GenPrimOp @@ -2017,8 +1986,8 @@ primop SetByteArrayOp "setByteArray#" GenPrimOp {{\tt setByteArray# ba off len c} sets the byte range {\tt [off, off+len]} of the {\tt MutableByteArray#} to the byte {\tt c}.} with - -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } code_size = { primOpCodeSizeForeignCall + 4 } -- Atomic operations @@ -2027,15 +1996,15 @@ primop AtomicReadByteArrayOp_Int "atomicReadIntArray#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, Int# #) {Given an array and an offset in machine words, read an element. The index is assumed to be in bounds. Implies a full memory barrier.} - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop AtomicWriteByteArrayOp_Int "atomicWriteIntArray#" GenPrimOp MutableByteArray# s -> Int# -> Int# -> State# s -> State# s {Given an array and an offset in machine words, write an element. The index is assumed to be in bounds. Implies a full memory barrier.} - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop CasByteArrayOp_Int "casIntArray#" GenPrimOp MutableByteArray# s -> Int# -> Int# -> Int# -> State# s -> (# State# s, Int# #) @@ -2044,56 +2013,56 @@ primop CasByteArrayOp_Int "casIntArray#" GenPrimOp value if the current value matches the provided old value. Returns the value of the element before the operation. Implies a full memory barrier.} - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop FetchAddByteArrayOp_Int "fetchAddIntArray#" GenPrimOp MutableByteArray# s -> Int# -> Int# -> State# s -> (# State# s, Int# #) {Given an array, and offset in machine words, and a value to add, atomically add the value to the element. Returns the value of the element before the operation. Implies a full memory barrier.} - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop FetchSubByteArrayOp_Int "fetchSubIntArray#" GenPrimOp MutableByteArray# s -> Int# -> Int# -> State# s -> (# State# s, Int# #) {Given an array, and offset in machine words, and a value to subtract, atomically subtract the value to the element. Returns the value of the element before the operation. Implies a full memory barrier.} - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop FetchAndByteArrayOp_Int "fetchAndIntArray#" GenPrimOp MutableByteArray# s -> Int# -> Int# -> State# s -> (# State# s, Int# #) {Given an array, and offset in machine words, and a value to AND, atomically AND the value to the element. Returns the value of the element before the operation. Implies a full memory barrier.} - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop FetchNandByteArrayOp_Int "fetchNandIntArray#" GenPrimOp MutableByteArray# s -> Int# -> Int# -> State# s -> (# State# s, Int# #) {Given an array, and offset in machine words, and a value to NAND, atomically NAND the value to the element. Returns the value of the element before the operation. Implies a full memory barrier.} - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop FetchOrByteArrayOp_Int "fetchOrIntArray#" GenPrimOp MutableByteArray# s -> Int# -> Int# -> State# s -> (# State# s, Int# #) {Given an array, and offset in machine words, and a value to OR, atomically OR the value to the element. Returns the value of the element before the operation. Implies a full memory barrier.} - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop FetchXorByteArrayOp_Int "fetchXorIntArray#" GenPrimOp MutableByteArray# s -> Int# -> Int# -> State# s -> (# State# s, Int# #) {Given an array, and offset in machine words, and a value to XOR, atomically XOR the value to the element. Returns the value of the element before the operation. Implies a full memory barrier.} - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } ------------------------------------------------------------------------ @@ -2116,8 +2085,8 @@ primop NewArrayArrayOp "newArrayArray#" GenPrimOp newly created array.} with out_of_line = True - -- effect = NoEffect -- #3207 - effect = WriteEffect + -- effect = { NoEffect } -- #3207 + effect = { WriteEffect } primop SameMutableArrayArrayOp "sameMutableArrayArray#" GenPrimOp MutableArrayArray# s -> MutableArrayArray# s -> Int# @@ -2126,7 +2095,7 @@ primop UnsafeFreezeArrayArrayOp "unsafeFreezeArrayArray#" GenPrimOp MutableArrayArray# s -> State# s -> (# State# s, ArrayArray# #) {Make a mutable array of arrays immutable, without copying.} with - effect = WriteEffect + effect = { WriteEffect } primop SizeofArrayArrayOp "sizeofArrayArray#" GenPrimOp ArrayArray# -> Int# @@ -2138,51 +2107,51 @@ primop SizeofMutableArrayArrayOp "sizeofMutableArrayArray#" GenPrimOp primop IndexArrayArrayOp_ByteArray "indexByteArrayArray#" GenPrimOp ArrayArray# -> Int# -> ByteArray# - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexArrayArrayOp_ArrayArray "indexArrayArrayArray#" GenPrimOp ArrayArray# -> Int# -> ArrayArray# - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop ReadArrayArrayOp_ByteArray "readByteArrayArray#" GenPrimOp MutableArrayArray# s -> Int# -> State# s -> (# State# s, ByteArray# #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadArrayArrayOp_MutableByteArray "readMutableByteArrayArray#" GenPrimOp MutableArrayArray# s -> Int# -> State# s -> (# State# s, MutableByteArray# s #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadArrayArrayOp_ArrayArray "readArrayArrayArray#" GenPrimOp MutableArrayArray# s -> Int# -> State# s -> (# State# s, ArrayArray# #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadArrayArrayOp_MutableArrayArray "readMutableArrayArrayArray#" GenPrimOp MutableArrayArray# s -> Int# -> State# s -> (# State# s, MutableArrayArray# s #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop WriteArrayArrayOp_ByteArray "writeByteArrayArray#" GenPrimOp MutableArrayArray# s -> Int# -> ByteArray# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop WriteArrayArrayOp_MutableByteArray "writeMutableByteArrayArray#" GenPrimOp MutableArrayArray# s -> Int# -> MutableByteArray# s -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop WriteArrayArrayOp_ArrayArray "writeArrayArrayArray#" GenPrimOp MutableArrayArray# s -> Int# -> ArrayArray# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop WriteArrayArrayOp_MutableArrayArray "writeMutableArrayArrayArray#" GenPrimOp MutableArrayArray# s -> Int# -> MutableArrayArray# s -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop CopyArrayArrayOp "copyArrayArray#" GenPrimOp ArrayArray# -> Int# -> MutableArrayArray# s -> Int# -> Int# -> State# s -> State# s @@ -2191,8 +2160,8 @@ primop CopyArrayArrayOp "copyArrayArray#" GenPrimOp The two arrays must not be the same array in different states, but this is not checked either.} with out_of_line = True - -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop CopyMutableArrayArrayOp "copyMutableArrayArray#" GenPrimOp MutableArrayArray# s -> Int# -> MutableArrayArray# s -> Int# -> Int# -> State# s -> State# s @@ -2204,8 +2173,8 @@ primop CopyMutableArrayArrayOp "copyMutableArrayArray#" GenPrimOp } with out_of_line = True - -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } ------------------------------------------------------------------------ section "Addr#" @@ -2244,230 +2213,230 @@ primop AddrLeOp "leAddr#" Compare Addr# -> Addr# -> Int# primop IndexOffAddrOp_Char "indexCharOffAddr#" GenPrimOp Addr# -> Int# -> Char# {Reads 8-bit character; offset in bytes.} - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexOffAddrOp_WideChar "indexWideCharOffAddr#" GenPrimOp Addr# -> Int# -> Char# {Reads 31-bit character; offset in 4-byte words.} - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexOffAddrOp_Int "indexIntOffAddr#" GenPrimOp Addr# -> Int# -> Int# - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexOffAddrOp_Word "indexWordOffAddr#" GenPrimOp Addr# -> Int# -> Word# - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexOffAddrOp_Addr "indexAddrOffAddr#" GenPrimOp Addr# -> Int# -> Addr# - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexOffAddrOp_Float "indexFloatOffAddr#" GenPrimOp Addr# -> Int# -> Float# - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexOffAddrOp_Double "indexDoubleOffAddr#" GenPrimOp Addr# -> Int# -> Double# - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexOffAddrOp_StablePtr "indexStablePtrOffAddr#" GenPrimOp Addr# -> Int# -> StablePtr# a - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexOffAddrOp_Int8 "indexInt8OffAddr#" GenPrimOp Addr# -> Int# -> Int# - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexOffAddrOp_Int16 "indexInt16OffAddr#" GenPrimOp Addr# -> Int# -> Int# - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexOffAddrOp_Int32 "indexInt32OffAddr#" GenPrimOp Addr# -> Int# -> INT32 - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexOffAddrOp_Int64 "indexInt64OffAddr#" GenPrimOp Addr# -> Int# -> INT64 - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexOffAddrOp_Word8 "indexWord8OffAddr#" GenPrimOp Addr# -> Int# -> Word# - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexOffAddrOp_Word16 "indexWord16OffAddr#" GenPrimOp Addr# -> Int# -> Word# - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexOffAddrOp_Word32 "indexWord32OffAddr#" GenPrimOp Addr# -> Int# -> WORD32 - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop IndexOffAddrOp_Word64 "indexWord64OffAddr#" GenPrimOp Addr# -> Int# -> WORD64 - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } primop ReadOffAddrOp_Char "readCharOffAddr#" GenPrimOp Addr# -> Int# -> State# s -> (# State# s, Char# #) {Reads 8-bit character; offset in bytes.} - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadOffAddrOp_WideChar "readWideCharOffAddr#" GenPrimOp Addr# -> Int# -> State# s -> (# State# s, Char# #) {Reads 31-bit character; offset in 4-byte words.} - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadOffAddrOp_Int "readIntOffAddr#" GenPrimOp Addr# -> Int# -> State# s -> (# State# s, Int# #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadOffAddrOp_Word "readWordOffAddr#" GenPrimOp Addr# -> Int# -> State# s -> (# State# s, Word# #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadOffAddrOp_Addr "readAddrOffAddr#" GenPrimOp Addr# -> Int# -> State# s -> (# State# s, Addr# #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadOffAddrOp_Float "readFloatOffAddr#" GenPrimOp Addr# -> Int# -> State# s -> (# State# s, Float# #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadOffAddrOp_Double "readDoubleOffAddr#" GenPrimOp Addr# -> Int# -> State# s -> (# State# s, Double# #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadOffAddrOp_StablePtr "readStablePtrOffAddr#" GenPrimOp Addr# -> Int# -> State# s -> (# State# s, StablePtr# a #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadOffAddrOp_Int8 "readInt8OffAddr#" GenPrimOp Addr# -> Int# -> State# s -> (# State# s, Int# #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadOffAddrOp_Int16 "readInt16OffAddr#" GenPrimOp Addr# -> Int# -> State# s -> (# State# s, Int# #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadOffAddrOp_Int32 "readInt32OffAddr#" GenPrimOp Addr# -> Int# -> State# s -> (# State# s, INT32 #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadOffAddrOp_Int64 "readInt64OffAddr#" GenPrimOp Addr# -> Int# -> State# s -> (# State# s, INT64 #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadOffAddrOp_Word8 "readWord8OffAddr#" GenPrimOp Addr# -> Int# -> State# s -> (# State# s, Word# #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadOffAddrOp_Word16 "readWord16OffAddr#" GenPrimOp Addr# -> Int# -> State# s -> (# State# s, Word# #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadOffAddrOp_Word32 "readWord32OffAddr#" GenPrimOp Addr# -> Int# -> State# s -> (# State# s, WORD32 #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop ReadOffAddrOp_Word64 "readWord64OffAddr#" GenPrimOp Addr# -> Int# -> State# s -> (# State# s, WORD64 #) - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop WriteOffAddrOp_Char "writeCharOffAddr#" GenPrimOp Addr# -> Int# -> Char# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop WriteOffAddrOp_WideChar "writeWideCharOffAddr#" GenPrimOp Addr# -> Int# -> Char# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop WriteOffAddrOp_Int "writeIntOffAddr#" GenPrimOp Addr# -> Int# -> Int# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop WriteOffAddrOp_Word "writeWordOffAddr#" GenPrimOp Addr# -> Int# -> Word# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop WriteOffAddrOp_Addr "writeAddrOffAddr#" GenPrimOp Addr# -> Int# -> Addr# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop WriteOffAddrOp_Float "writeFloatOffAddr#" GenPrimOp Addr# -> Int# -> Float# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop WriteOffAddrOp_Double "writeDoubleOffAddr#" GenPrimOp Addr# -> Int# -> Double# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop WriteOffAddrOp_StablePtr "writeStablePtrOffAddr#" GenPrimOp Addr# -> Int# -> StablePtr# a -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop WriteOffAddrOp_Int8 "writeInt8OffAddr#" GenPrimOp Addr# -> Int# -> Int# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop WriteOffAddrOp_Int16 "writeInt16OffAddr#" GenPrimOp Addr# -> Int# -> Int# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop WriteOffAddrOp_Int32 "writeInt32OffAddr#" GenPrimOp Addr# -> Int# -> INT32 -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop WriteOffAddrOp_Int64 "writeInt64OffAddr#" GenPrimOp Addr# -> Int# -> INT64 -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop WriteOffAddrOp_Word8 "writeWord8OffAddr#" GenPrimOp Addr# -> Int# -> Word# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop WriteOffAddrOp_Word16 "writeWord16OffAddr#" GenPrimOp Addr# -> Int# -> Word# -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop WriteOffAddrOp_Word32 "writeWord32OffAddr#" GenPrimOp Addr# -> Int# -> WORD32 -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } primop WriteOffAddrOp_Word64 "writeWord64OffAddr#" GenPrimOp Addr# -> Int# -> WORD64 -> State# s -> State# s - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } ------------------------------------------------------------------------ section "Mutable variables" @@ -2482,21 +2451,21 @@ primop NewMutVarOp "newMutVar#" GenPrimOp {Create {\tt MutVar\#} with specified initial value in specified state thread.} with out_of_line = True - -- effect = NoEffect -- #3207 - effect = WriteEffect + -- effect = { NoEffect } -- #3207 + effect = { WriteEffect } primop ReadMutVarOp "readMutVar#" GenPrimOp MutVar# s a -> State# s -> (# State# s, a #) {Read contents of {\tt MutVar\#}. Result is not yet evaluated.} with - -- effect = NoEffect -- #3207 - effect = WriteEffect + -- effect = { NoEffect } -- #3207 + effect = { WriteEffect } primop WriteMutVarOp "writeMutVar#" GenPrimOp MutVar# s a -> a -> State# s -> State# s {Write contents of {\tt MutVar\#}.} with - effect = WriteEffect + effect = { WriteEffect } code_size = { primOpCodeSizeForeignCall } -- for the write barrier primop SameMutVarOp "sameMutVar#" GenPrimOp @@ -2525,7 +2494,7 @@ primop AtomicModifyMutVar2Op "atomicModifyMutVar2#" GenPrimOp but we don't know about pairs here. } with out_of_line = True - effect = WriteEffect + effect = { WriteEffect } primop AtomicModifyMutVar_Op "atomicModifyMutVar_#" GenPrimOp MutVar# s a -> (a -> a) -> State# s -> (# State# s, a, a #) @@ -2534,13 +2503,13 @@ primop AtomicModifyMutVar_Op "atomicModifyMutVar_#" GenPrimOp previous contents. } with out_of_line = True - effect = WriteEffect + effect = { WriteEffect } primop CasMutVarOp "casMutVar#" GenPrimOp MutVar# s a -> a -> a -> State# s -> (# State# s, Int#, a #) with out_of_line = True - effect = WriteEffect + effect = { WriteEffect } ------------------------------------------------------------------------ section "Exceptions" @@ -2570,7 +2539,7 @@ primop CatchOp "catch#" GenPrimOp , topDmd] topDiv } -- See Note [Strictness for mask/unmask/catch] out_of_line = True - effect = WriteEffect + effect = { WriteEffect } primop RaiseOp "raise#" GenPrimOp b -> o @@ -2585,7 +2554,7 @@ primop RaiseOp "raise#" GenPrimOp -- See Note [PrimOp can_fail and has_side_effects] in PrimOp.hs. strictness = { \ _arity -> mkClosedStrictSig [topDmd] botDiv } out_of_line = True - effect = ThrowsImprecise + effect = { ThrowsImprecise } -- Note [Arithmetic exception primops] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -2608,7 +2577,7 @@ primop RaiseDivZeroOp "raiseDivZero#" GenPrimOp with strictness = { \ _arity -> mkClosedStrictSig [topDmd] botDiv } out_of_line = True - effect = ThrowsImprecise + effect = { ThrowsImprecise } primop RaiseUnderflowOp "raiseUnderflow#" GenPrimOp Void# -> o @@ -2618,7 +2587,7 @@ primop RaiseUnderflowOp "raiseUnderflow#" GenPrimOp with strictness = { \ _arity -> mkClosedStrictSig [topDmd] botDiv } out_of_line = True - effect = ThrowsImprecise + effect = { ThrowsImprecise } primop RaiseOverflowOp "raiseOverflow#" GenPrimOp Void# -> o @@ -2628,7 +2597,7 @@ primop RaiseOverflowOp "raiseOverflow#" GenPrimOp with strictness = { \ _arity -> mkClosedStrictSig [topDmd] botDiv } out_of_line = True - effect = ThrowsImprecise + effect = { ThrowsImprecise } -- See Note [Precise vs. imprecise exceptions] in GHC.Types.Demand. -- This is the only way to throw a precise exception, hence a primop separate @@ -2640,7 +2609,7 @@ primop RaiseIOOp "raiseIO#" GenPrimOp -- for why this is the *only* primop that has 'exnDiv' strictness = { \ _arity -> mkClosedStrictSig [topDmd, topDmd] exnDiv } out_of_line = True - effect = ThrowsPrecise + effect = { ThrowsPrecise } primop MaskAsyncExceptionsOp "maskAsyncExceptions#" GenPrimOp (State# RealWorld -> (# State# RealWorld, a #)) @@ -2649,7 +2618,7 @@ primop MaskAsyncExceptionsOp "maskAsyncExceptions#" GenPrimOp strictness = { \ _arity -> mkClosedStrictSig [strictApply1Dmd,topDmd] topDiv } -- See Note [Strictness for mask/unmask/catch] out_of_line = True - effect = WriteEffect + effect = { WriteEffect } primop MaskUninterruptibleOp "maskUninterruptible#" GenPrimOp (State# RealWorld -> (# State# RealWorld, a #)) @@ -2657,7 +2626,7 @@ primop MaskUninterruptibleOp "maskUninterruptible#" GenPrimOp with strictness = { \ _arity -> mkClosedStrictSig [strictApply1Dmd,topDmd] topDiv } out_of_line = True - effect = WriteEffect + effect = { WriteEffect } primop UnmaskAsyncExceptionsOp "unmaskAsyncExceptions#" GenPrimOp (State# RealWorld -> (# State# RealWorld, a #)) @@ -2666,13 +2635,13 @@ primop UnmaskAsyncExceptionsOp "unmaskAsyncExceptions#" GenPrimOp strictness = { \ _arity -> mkClosedStrictSig [strictApply1Dmd,topDmd] topDiv } -- See Note [Strictness for mask/unmask/catch] out_of_line = True - effect = WriteEffect + effect = { WriteEffect } primop MaskStatus "getMaskingState#" GenPrimOp State# RealWorld -> (# State# RealWorld, Int# #) with out_of_line = True - effect = WriteEffect + effect = { WriteEffect } ------------------------------------------------------------------------ section "STM-accessible Mutable Variables" @@ -2687,7 +2656,7 @@ primop AtomicallyOp "atomically#" GenPrimOp strictness = { \ _arity -> mkClosedStrictSig [strictApply1Dmd,topDmd] topDiv } -- See Note [Strictness for mask/unmask/catch] out_of_line = True - effect = WriteEffect + effect = { WriteEffect } -- NB: retry#'s strictness information specifies it to diverge. -- This lets the compiler perform some extra simplifications, since retry# @@ -2704,7 +2673,7 @@ primop RetryOp "retry#" GenPrimOp with strictness = { \ _arity -> mkClosedStrictSig [topDmd] botDiv } out_of_line = True - effect = WriteEffect + effect = { WriteEffect } primop CatchRetryOp "catchRetry#" GenPrimOp (State# RealWorld -> (# State# RealWorld, a #) ) @@ -2716,7 +2685,7 @@ primop CatchRetryOp "catchRetry#" GenPrimOp , topDmd ] topDiv } -- See Note [Strictness for mask/unmask/catch] out_of_line = True - effect = WriteEffect + effect = { WriteEffect } primop CatchSTMOp "catchSTM#" GenPrimOp (State# RealWorld -> (# State# RealWorld, a #) ) @@ -2728,7 +2697,7 @@ primop CatchSTMOp "catchSTM#" GenPrimOp , topDmd ] topDiv } -- See Note [Strictness for mask/unmask/catch] out_of_line = True - effect = WriteEffect + effect = { WriteEffect } primop NewTVarOp "newTVar#" GenPrimOp a @@ -2736,8 +2705,8 @@ primop NewTVarOp "newTVar#" GenPrimOp {Create a new {\tt TVar\#} holding a specified initial value.} with out_of_line = True - -- effect = NoEffect -- #3207 - effect = WriteEffect + -- effect = { NoEffect } -- #3207 + effect = { WriteEffect } primop ReadTVarOp "readTVar#" GenPrimOp TVar# s a @@ -2745,8 +2714,8 @@ primop ReadTVarOp "readTVar#" GenPrimOp {Read contents of {\tt TVar\#}. Result is not yet evaluated.} with out_of_line = True - -- effect = NoEffect -- #3207 - effect = WriteEffect + -- effect = { NoEffect } -- #3207 + effect = { WriteEffect } primop ReadTVarIOOp "readTVarIO#" GenPrimOp TVar# s a @@ -2754,8 +2723,8 @@ primop ReadTVarIOOp "readTVarIO#" GenPrimOp {Read contents of {\tt TVar\#} outside an STM transaction} with out_of_line = True - -- effect = NoEffect -- #3207 - effect = WriteEffect + -- effect = { NoEffect } -- #3207 + effect = { WriteEffect } primop WriteTVarOp "writeTVar#" GenPrimOp TVar# s a @@ -2764,7 +2733,7 @@ primop WriteTVarOp "writeTVar#" GenPrimOp {Write contents of {\tt TVar\#}.} with out_of_line = True - effect = WriteEffect + effect = { WriteEffect } primop SameTVarOp "sameTVar#" GenPrimOp TVar# s a -> TVar# s a -> Int# @@ -2785,8 +2754,8 @@ primop NewMVarOp "newMVar#" GenPrimOp {Create new {\tt MVar\#}; initially empty.} with out_of_line = True - -- effect = NoEffect -- #3207 - effect = WriteEffect + -- effect = { NoEffect } -- #3207 + effect = { WriteEffect } primop TakeMVarOp "takeMVar#" GenPrimOp MVar# s a -> State# s -> (# State# s, a #) @@ -2794,7 +2763,7 @@ primop TakeMVarOp "takeMVar#" GenPrimOp Then remove and return its contents, and set it empty.} with out_of_line = True - effect = WriteEffect -- because it may block! + effect = { WriteEffect } -- because it may block! primop TryTakeMVarOp "tryTakeMVar#" GenPrimOp MVar# s a -> State# s -> (# State# s, Int#, a #) @@ -2802,7 +2771,7 @@ primop TryTakeMVarOp "tryTakeMVar#" GenPrimOp Otherwise, return with integer 1 and contents of {\tt MVar\#}, and set {\tt MVar\#} empty.} with out_of_line = True - effect = WriteEffect + effect = { WriteEffect } primop PutMVarOp "putMVar#" GenPrimOp MVar# s a -> a -> State# s -> State# s @@ -2810,7 +2779,7 @@ primop PutMVarOp "putMVar#" GenPrimOp Then store value arg as its new contents.} with out_of_line = True - effect = WriteEffect + effect = { WriteEffect } primop TryPutMVarOp "tryPutMVar#" GenPrimOp MVar# s a -> a -> State# s -> (# State# s, Int# #) @@ -2818,7 +2787,7 @@ primop TryPutMVarOp "tryPutMVar#" GenPrimOp Otherwise, store value arg as {\tt MVar\#}'s new contents, and return with integer 1.} with out_of_line = True - effect = WriteEffect + effect = { WriteEffect } primop ReadMVarOp "readMVar#" GenPrimOp MVar# s a -> State# s -> (# State# s, a #) @@ -2827,7 +2796,7 @@ primop ReadMVarOp "readMVar#" GenPrimOp of intervention from other threads.} with out_of_line = True - effect = WriteEffect -- because it may block! + effect = { WriteEffect } -- because it may block! primop TryReadMVarOp "tryReadMVar#" GenPrimOp MVar# s a -> State# s -> (# State# s, Int#, a #) @@ -2835,7 +2804,7 @@ primop TryReadMVarOp "tryReadMVar#" GenPrimOp Otherwise, return with integer 1 and contents of {\tt MVar\#}.} with out_of_line = True - effect = WriteEffect + effect = { WriteEffect } primop SameMVarOp "sameMVar#" GenPrimOp MVar# s a -> MVar# s a -> Int# @@ -2845,8 +2814,8 @@ primop IsEmptyMVarOp "isEmptyMVar#" GenPrimOp {Return 1 if {\tt MVar\#} is empty; 0 otherwise.} with out_of_line = True - -- effect = NoEffect -- #3207 - effect = WriteEffect + -- effect = { NoEffect } -- #3207 + effect = { WriteEffect } ------------------------------------------------------------------------ section "Delay/wait operations" @@ -2856,21 +2825,21 @@ primop DelayOp "delay#" GenPrimOp Int# -> State# s -> State# s {Sleep specified number of microseconds.} with - effect = WriteEffect + effect = { WriteEffect } out_of_line = True primop WaitReadOp "waitRead#" GenPrimOp Int# -> State# s -> State# s {Block until input is available on specified file descriptor.} with - effect = WriteEffect + effect = { WriteEffect } out_of_line = True primop WaitWriteOp "waitWrite#" GenPrimOp Int# -> State# s -> State# s {Block until output is possible on specified file descriptor.} with - effect = WriteEffect + effect = { WriteEffect } out_of_line = True ------------------------------------------------------------------------ @@ -2897,58 +2866,58 @@ primtype ThreadId# primop ForkOp "fork#" GenPrimOp a -> State# RealWorld -> (# State# RealWorld, ThreadId# #) with - effect = WriteEffect + effect = { WriteEffect } out_of_line = True primop ForkOnOp "forkOn#" GenPrimOp Int# -> a -> State# RealWorld -> (# State# RealWorld, ThreadId# #) with - effect = WriteEffect + effect = { WriteEffect } out_of_line = True primop KillThreadOp "killThread#" GenPrimOp ThreadId# -> a -> State# RealWorld -> State# RealWorld with - effect = WriteEffect + effect = { WriteEffect } out_of_line = True primop YieldOp "yield#" GenPrimOp State# RealWorld -> State# RealWorld with - effect = WriteEffect + effect = { WriteEffect } out_of_line = True primop MyThreadIdOp "myThreadId#" GenPrimOp State# RealWorld -> (# State# RealWorld, ThreadId# #) with - -- effect = NoEffect -- #3207 - effect = WriteEffect + -- effect = { NoEffect } -- #3207 + effect = { WriteEffect } primop LabelThreadOp "labelThread#" GenPrimOp ThreadId# -> Addr# -> State# RealWorld -> State# RealWorld with - effect = WriteEffect + effect = { WriteEffect } out_of_line = True primop IsCurrentThreadBoundOp "isCurrentThreadBound#" GenPrimOp State# RealWorld -> (# State# RealWorld, Int# #) with out_of_line = True - -- effect = NoEffect -- #3207 - effect = WriteEffect + -- effect = { NoEffect } -- #3207 + effect = { WriteEffect } primop NoDuplicateOp "noDuplicate#" GenPrimOp State# s -> State# s with out_of_line = True - effect = WriteEffect -- See Note [Classification by PrimOpEffect] in PrimOp + effect = { WriteEffect } -- See Note [Classification by PrimOpEffect] in PrimOp primop ThreadStatusOp "threadStatus#" GenPrimOp ThreadId# -> State# RealWorld -> (# State# RealWorld, Int#, Int#, Int# #) with out_of_line = True - -- effect = NoEffect -- #3207 - effect = WriteEffect + -- effect = { NoEffect } -- #3207 + effect = { WriteEffect } ------------------------------------------------------------------------ section "Weak pointers" @@ -2967,13 +2936,13 @@ primop MkWeakOp "mkWeak#" GenPrimOp the type of {\tt k} must be represented by a pointer (i.e. of kind {\tt TYPE 'LiftedRep} or {\tt TYPE 'UnliftedRep}). } with - effect = WriteEffect -- better be safe + effect = { WriteEffect } -- better be safe out_of_line = True primop MkWeakNoFinalizerOp "mkWeakNoFinalizer#" GenPrimOp o -> b -> State# RealWorld -> (# State# RealWorld, Weak# b #) with - effect = WriteEffect + effect = { WriteEffect } out_of_line = True primop AddCFinalizerToWeakOp "addCFinalizerToWeak#" GenPrimOp @@ -2986,13 +2955,13 @@ primop AddCFinalizerToWeakOp "addCFinalizerToWeak#" GenPrimOp {\tt eptr} and {\tt ptr}. {\tt addCFinalizerToWeak#} returns 1 on success, or 0 if {\tt w} is already dead. } with - effect = WriteEffect + effect = { WriteEffect } out_of_line = True primop DeRefWeakOp "deRefWeak#" GenPrimOp Weak# a -> State# RealWorld -> (# State# RealWorld, Int#, a #) with - effect = WriteEffect + effect = { WriteEffect } out_of_line = True primop FinalizeWeakOp "finalizeWeak#" GenPrimOp @@ -3004,14 +2973,14 @@ primop FinalizeWeakOp "finalizeWeak#" GenPrimOp action. An {\tt Int#} of {\tt 1} indicates that the finalizer is valid. The return value {\tt b} from the finalizer should be ignored. } with - effect = WriteEffect + effect = { WriteEffect } out_of_line = True primop TouchOp "touch#" GenPrimOp o -> State# RealWorld -> State# RealWorld with code_size = { 0 } - effect = WriteEffect + effect = { WriteEffect } ------------------------------------------------------------------------ section "Stable pointers and names" @@ -3024,24 +2993,24 @@ primtype StableName# a primop MakeStablePtrOp "makeStablePtr#" GenPrimOp a -> State# RealWorld -> (# State# RealWorld, StablePtr# a #) with - effect = WriteEffect + effect = { WriteEffect } out_of_line = True primop DeRefStablePtrOp "deRefStablePtr#" GenPrimOp StablePtr# a -> State# RealWorld -> (# State# RealWorld, a #) with - effect = WriteEffect + effect = { WriteEffect } out_of_line = True primop EqStablePtrOp "eqStablePtr#" GenPrimOp StablePtr# a -> StablePtr# a -> Int# with - effect = WriteEffect + effect = { WriteEffect } primop MakeStableNameOp "makeStableName#" GenPrimOp a -> State# RealWorld -> (# State# RealWorld, StableName# a #) with - effect = WriteEffect + effect = { WriteEffect } out_of_line = True primop EqStableNameOp "eqStableName#" GenPrimOp @@ -3076,8 +3045,8 @@ primop CompactNewOp "compactNew#" GenPrimOp The capacity is rounded up to a multiple of the allocator block size and is capped to one mega block. } with - -- effect = NoEffect -- #3207 - effect = WriteEffect + -- effect = { NoEffect } -- #3207 + effect = { WriteEffect } out_of_line = True primop CompactResizeOp "compactResize#" GenPrimOp @@ -3087,23 +3056,23 @@ primop CompactResizeOp "compactResize#" GenPrimOp determines the capacity of each compact block in the CNF. It does not retroactively affect existing compact blocks in the CNF. } with - effect = WriteEffect + effect = { WriteEffect } out_of_line = True primop CompactContainsOp "compactContains#" GenPrimOp Compact# -> a -> State# RealWorld -> (# State# RealWorld, Int# #) { Returns 1\# if the object is contained in the CNF, 0\# otherwise. } with - -- effect = NoEffect -- #3207 - effect = WriteEffect + -- effect = { NoEffect } -- #3207 + effect = { WriteEffect } out_of_line = True primop CompactContainsAnyOp "compactContainsAny#" GenPrimOp a -> State# RealWorld -> (# State# RealWorld, Int# #) { Returns 1\# if the object is in any CNF at all, 0\# otherwise. } with - -- effect = NoEffect -- #3207 - effect = WriteEffect + -- effect = { NoEffect } -- #3207 + effect = { WriteEffect } out_of_line = True primop CompactGetFirstBlockOp "compactGetFirstBlock#" GenPrimOp @@ -3111,8 +3080,8 @@ primop CompactGetFirstBlockOp "compactGetFirstBlock#" GenPrimOp { Returns the address and the utilized size (in bytes) of the first compact block of a CNF.} with - -- effect = NoEffect -- #3207 - effect = WriteEffect + -- effect = { NoEffect } -- #3207 + effect = { WriteEffect } out_of_line = True primop CompactGetNextBlockOp "compactGetNextBlock#" GenPrimOp @@ -3121,8 +3090,8 @@ primop CompactGetNextBlockOp "compactGetNextBlock#" GenPrimOp next compact block and its utilized size, or {\tt nullAddr\#} if the argument was the last compact block in the CNF. } with - -- effect = NoEffect -- #3207 - effect = WriteEffect + -- effect = { NoEffect } -- #3207 + effect = { WriteEffect } out_of_line = True primop CompactAllocateBlockOp "compactAllocateBlock#" GenPrimOp @@ -3137,7 +3106,7 @@ primop CompactAllocateBlockOp "compactAllocateBlock#" GenPrimOp so that the address does not escape or memory will be leaked. } with - effect = WriteEffect + effect = { WriteEffect } out_of_line = True primop CompactFixupPointersOp "compactFixupPointers#" GenPrimOp @@ -3150,7 +3119,7 @@ primop CompactFixupPointersOp "compactFixupPointers#" GenPrimOp a serialized CNF. It returns the new CNF and the new adjusted root address. } with - effect = WriteEffect + effect = { WriteEffect } out_of_line = True primop CompactAdd "compactAdd#" GenPrimOp @@ -3163,7 +3132,7 @@ primop CompactAdd "compactAdd#" GenPrimOp enforce any mutual exclusion; the caller is expected to arrange this. } with - effect = WriteEffect + effect = { WriteEffect } out_of_line = True primop CompactAddWithSharing "compactAddWithSharing#" GenPrimOp @@ -3171,7 +3140,7 @@ primop CompactAddWithSharing "compactAddWithSharing#" GenPrimOp { Like {\texttt compactAdd\#}, but retains sharing and cycles during compaction. } with - effect = WriteEffect + effect = { WriteEffect } out_of_line = True primop CompactSize "compactSize#" GenPrimOp @@ -3179,8 +3148,8 @@ primop CompactSize "compactSize#" GenPrimOp { Return the total capacity (in bytes) of all the compact blocks in the CNF. } with - -- effect = NoEffect -- #3207 - effect = WriteEffect + -- effect = { NoEffect } -- #3207 + effect = { WriteEffect } out_of_line = True ------------------------------------------------------------------------ @@ -3192,7 +3161,7 @@ primop ReallyUnsafePtrEqualityOp "reallyUnsafePtrEquality#" GenPrimOp a -> a -> Int# { Returns {\texttt 1\#} if the given pointers are equal and {\texttt 0\#} otherwise. } with - effect = ThrowsImprecise -- See Note [reallyUnsafePtrEquality#] + effect = { ThrowsImprecise } -- See Note [reallyUnsafePtrEquality#] -- Note [reallyUnsafePtrEquality#] @@ -3233,14 +3202,14 @@ primop ParOp "par#" GenPrimOp with -- Note that Par is lazy to avoid that the sparked thing -- gets evaluated strictly, which it should *not* be - effect = WriteEffect + effect = { WriteEffect } code_size = { primOpCodeSizeForeignCall } deprecated_msg = { Use 'spark#' instead } primop SparkOp "spark#" GenPrimOp a -> State# s -> (# State# s, a #) with - effect = WriteEffect + effect = { WriteEffect } code_size = { primOpCodeSizeForeignCall } primop SeqOp "seq#" GenPrimOp @@ -3250,16 +3219,16 @@ primop SeqOp "seq#" GenPrimOp primop GetSparkOp "getSpark#" GenPrimOp State# s -> (# State# s, Int#, a #) with - -- effect = NoEffect -- #3207 - effect = WriteEffect + -- effect = { NoEffect } -- #3207 + effect = { WriteEffect } out_of_line = True primop NumSparks "numSparks#" GenPrimOp State# s -> (# State# s, Int# #) { Returns the number of sparks in the local spark pool. } with - -- effect = NoEffect -- #3207 - effect = WriteEffect + -- effect = { NoEffect } -- #3207 + effect = { WriteEffect } out_of_line = True ------------------------------------------------------------------------ @@ -3324,7 +3293,7 @@ primop NewBCOOp "newBCO#" GenPrimOp encoded in {\tt instrs}, and a static reference table usage bitmap given by {\tt bitmap}. } with - effect = WriteEffect + effect = { WriteEffect } out_of_line = True primop UnpackClosureOp "unpackClosure#" GenPrimOp @@ -3441,7 +3410,7 @@ pseudoop "unsafeCoerce#" to, use {\tt Any}, which is not an algebraic data type. } - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } -- NB. It is tempting to think that casting a value to a type that it doesn't have is safe -- as long as you don't "do anything" with the value in its cast form, such as seq on it. This @@ -3458,7 +3427,7 @@ primop TraceEventOp "traceEvent#" GenPrimOp argument. The event will be emitted either to the {\tt .eventlog} file, or to stderr, depending on the runtime RTS flags. } with - effect = WriteEffect + effect = { WriteEffect } out_of_line = True primop TraceEventBinaryOp "traceBinaryEvent#" GenPrimOp @@ -3468,7 +3437,7 @@ primop TraceEventBinaryOp "traceBinaryEvent#" GenPrimOp the the given length passed as the second argument. The event will be emitted to the {\tt .eventlog} file. } with - effect = WriteEffect + effect = { WriteEffect } out_of_line = True primop TraceMarkerOp "traceMarker#" GenPrimOp @@ -3478,14 +3447,14 @@ primop TraceMarkerOp "traceMarker#" GenPrimOp argument. The event will be emitted either to the {\tt .eventlog} file, or to stderr, depending on the runtime RTS flags. } with - effect = WriteEffect + effect = { WriteEffect } out_of_line = True primop SetThreadAllocationCounter "setThreadAllocationCounter#" GenPrimOp INT64 -> State# RealWorld -> State# RealWorld { Sets the allocation counter for the current thread to the given value. } with - effect = WriteEffect + effect = { WriteEffect } out_of_line = True ------------------------------------------------------------------------ @@ -3569,7 +3538,7 @@ primop VecUnpackOp "unpack#" GenPrimOp primop VecInsertOp "insert#" GenPrimOp VECTOR -> SCALAR -> Int# -> VECTOR { Insert a scalar at the given position in a vector. } - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } llvm_only = True vector = ALL_VECTOR_TYPES @@ -3596,21 +3565,21 @@ primop VecMulOp "times#" Dyadic primop VecDivOp "divide#" Dyadic VECTOR -> VECTOR -> VECTOR { Divide two vectors element-wise. } - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } llvm_only = True vector = FLOAT_VECTOR_TYPES primop VecQuotOp "quot#" Dyadic VECTOR -> VECTOR -> VECTOR { Rounds towards zero element-wise. } - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } llvm_only = True vector = INT_VECTOR_TYPES primop VecRemOp "rem#" Dyadic VECTOR -> VECTOR -> VECTOR { Satisfies \texttt{(quot\# x y) times\# y plus\# (rem\# x y) == x}. } - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } llvm_only = True vector = INT_VECTOR_TYPES @@ -3623,44 +3592,44 @@ primop VecNegOp "negate#" Monadic primop VecIndexByteArrayOp "indexArray#" GenPrimOp ByteArray# -> Int# -> VECTOR { Read a vector from specified index of immutable array. } - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } llvm_only = True vector = ALL_VECTOR_TYPES primop VecReadByteArrayOp "readArray#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, VECTOR #) { Read a vector from specified index of mutable array. } - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } llvm_only = True vector = ALL_VECTOR_TYPES primop VecWriteByteArrayOp "writeArray#" GenPrimOp MutableByteArray# s -> Int# -> VECTOR -> State# s -> State# s { Write a vector to specified index of mutable array. } - with effect = WriteEffect + with effect = { WriteEffect } llvm_only = True vector = ALL_VECTOR_TYPES primop VecIndexOffAddrOp "indexOffAddr#" GenPrimOp Addr# -> Int# -> VECTOR { Reads vector; offset in bytes. } - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } llvm_only = True vector = ALL_VECTOR_TYPES primop VecReadOffAddrOp "readOffAddr#" GenPrimOp Addr# -> Int# -> State# s -> (# State# s, VECTOR #) { Reads vector; offset in bytes. } - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } llvm_only = True vector = ALL_VECTOR_TYPES primop VecWriteOffAddrOp "writeOffAddr#" GenPrimOp Addr# -> Int# -> VECTOR -> State# s -> State# s { Write vector; offset in bytes. } - with effect = WriteEffect + with effect = { WriteEffect } llvm_only = True vector = ALL_VECTOR_TYPES @@ -3668,44 +3637,44 @@ primop VecWriteOffAddrOp "writeOffAddr#" GenPrimOp primop VecIndexScalarByteArrayOp "indexArrayAs#" GenPrimOp ByteArray# -> Int# -> VECTOR { Read a vector from specified index of immutable array of scalars; offset is in scalar elements. } - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } llvm_only = True vector = ALL_VECTOR_TYPES primop VecReadScalarByteArrayOp "readArrayAs#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> (# State# s, VECTOR #) { Read a vector from specified index of mutable array of scalars; offset is in scalar elements. } - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } llvm_only = True vector = ALL_VECTOR_TYPES primop VecWriteScalarByteArrayOp "writeArrayAs#" GenPrimOp MutableByteArray# s -> Int# -> VECTOR -> State# s -> State# s { Write a vector to specified index of mutable array of scalars; offset is in scalar elements. } - with effect = WriteEffect + with effect = { WriteEffect } llvm_only = True vector = ALL_VECTOR_TYPES primop VecIndexScalarOffAddrOp "indexOffAddrAs#" GenPrimOp Addr# -> Int# -> VECTOR { Reads vector; offset in scalar elements. } - with effect = ThrowsImprecise + with effect = { ThrowsImprecise } llvm_only = True vector = ALL_VECTOR_TYPES primop VecReadScalarOffAddrOp "readOffAddrAs#" GenPrimOp Addr# -> Int# -> State# s -> (# State# s, VECTOR #) { Reads vector; offset in scalar elements. } - with -- effect = ThrowsImprecise -- #3207 - effect = WriteEffect + with -- effect = { ThrowsImprecise } -- #3207 + effect = { WriteEffect } llvm_only = True vector = ALL_VECTOR_TYPES primop VecWriteScalarOffAddrOp "writeOffAddrAs#" GenPrimOp Addr# -> Int# -> VECTOR -> State# s -> State# s { Write vector; offset in scalar elements. } - with effect = WriteEffect + with effect = { WriteEffect } llvm_only = True vector = ALL_VECTOR_TYPES @@ -3754,7 +3723,7 @@ section "Prefetch" It is important to note that while the prefetch operations will never change the answer to a pure computation, They CAN change the memory locations resident in a CPU cache and that may change the performance and timing characteristics - of an application. The prefetch operations are marked effect = WriteEffect + of an application. The prefetch operations are marked effect = { WriteEffect } to reflect that these operations have side effects with respect to the runtime performance characteristics of the resulting code. Additionally, if the prefetchValue operations did not have this attribute, GHC does a float out transformation that @@ -3771,77 +3740,72 @@ section "Prefetch" --- primop PrefetchByteArrayOp3 "prefetchByteArray3#" GenPrimOp ByteArray# -> Int# -> State# s -> State# s - with effect = WriteEffect + with effect = { WriteEffect } primop PrefetchMutableByteArrayOp3 "prefetchMutableByteArray3#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> State# s - with effect = WriteEffect + with effect = { WriteEffect } primop PrefetchAddrOp3 "prefetchAddr3#" GenPrimOp Addr# -> Int# -> State# s -> State# s - with effect = WriteEffect + with effect = { WriteEffect } primop PrefetchValueOp3 "prefetchValue3#" GenPrimOp a -> State# s -> State# s with strictness = { \ _arity -> mkClosedStrictSig [botDmd, topDmd] topDiv } - effect = WriteEffect + effect = { WriteEffect } ---- primop PrefetchByteArrayOp2 "prefetchByteArray2#" GenPrimOp ByteArray# -> Int# -> State# s -> State# s - with effect = WriteEffect + with effect = { WriteEffect } primop PrefetchMutableByteArrayOp2 "prefetchMutableByteArray2#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> State# s - with effect = WriteEffect + with effect = { WriteEffect } primop PrefetchAddrOp2 "prefetchAddr2#" GenPrimOp Addr# -> Int# -> State# s -> State# s - with effect = WriteEffect + with effect = { WriteEffect } primop PrefetchValueOp2 "prefetchValue2#" GenPrimOp a -> State# s -> State# s with strictness = { \ _arity -> mkClosedStrictSig [botDmd, topDmd] topDiv } - effect = WriteEffect + effect = { WriteEffect } ---- primop PrefetchByteArrayOp1 "prefetchByteArray1#" GenPrimOp ByteArray# -> Int# -> State# s -> State# s - with effect = WriteEffect + with effect = { WriteEffect } primop PrefetchMutableByteArrayOp1 "prefetchMutableByteArray1#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> State# s - with effect = WriteEffect + with effect = { WriteEffect } primop PrefetchAddrOp1 "prefetchAddr1#" GenPrimOp Addr# -> Int# -> State# s -> State# s - with effect = WriteEffect + with effect = { WriteEffect } primop PrefetchValueOp1 "prefetchValue1#" GenPrimOp a -> State# s -> State# s with strictness = { \ _arity -> mkClosedStrictSig [botDmd, topDmd] topDiv } - effect = WriteEffect + effect = { WriteEffect } ---- primop PrefetchByteArrayOp0 "prefetchByteArray0#" GenPrimOp ByteArray# -> Int# -> State# s -> State# s - with effect = WriteEffect + with effect = { WriteEffect } primop PrefetchMutableByteArrayOp0 "prefetchMutableByteArray0#" GenPrimOp MutableByteArray# s -> Int# -> State# s -> State# s - with effect = WriteEffect + with effect = { WriteEffect } primop PrefetchAddrOp0 "prefetchAddr0#" GenPrimOp Addr# -> Int# -> State# s -> State# s - with effect = WriteEffect + with effect = { WriteEffect } primop PrefetchValueOp0 "prefetchValue0#" GenPrimOp a -> State# s -> State# s with strictness = { \ _arity -> mkClosedStrictSig [botDmd, topDmd] topDiv } - effect = WriteEffect - ------------------------------------------------------------------------- ---- --- ------------------------------------------------------------------------- thats_all_folks ===================================== utils/genprimopcode/Main.hs ===================================== @@ -193,11 +193,10 @@ main = getArgs >>= \args -> known_args :: [String] known_args = [ "--data-decl", - "--has-side-effects", + "--effect", "--out-of-line", "--commutable", "--code-size", - "--can-fail", "--strictness", "--fixity", "--primop-primop-info", @@ -774,7 +773,6 @@ gen_switch_from_attribs attrib_name fn_name (Info defaults entries) getAltRhs (OptionString _ s) = s getAltRhs (OptionVector _) = "True" getAltRhs (OptionFixity mf) = show mf - getAltRhs (OptionEffect eff) = show eff mkAlt po = case lookup_attrib attrib_name (opts po) of View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3f6056a57dc8a9476c42c170941afdeb8ac8cd8f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3f6056a57dc8a9476c42c170941afdeb8ac8cd8f You're receiving 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 27 18:48:51 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 27 May 2020 14:48:51 -0400 Subject: [Git][ghc/ghc][wip/testsuite-fixes] 202 commits: Mark T12010 fragile on 32-bit Message-ID: <5eceb613e6c95_6e261275eeac206505a@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/testsuite-fixes at Glasgow Haskell Compiler / GHC Commits: 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. - - - - - 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] - - - - - 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 - - - - - 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 - - - - - 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. - - - - - 78c6523c by Ben Gamari at 2020-05-21T12:13:01-04:00 nonmoving: Optimise the write barrier - - - - - 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). - - - - - 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 - - - - - b7a6b2f4 by Gleb Popov at 2020-05-21T12:15:26-04:00 gitlab-ci: Set locale to C.UTF-8. - - - - - 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. - - - - - 0004ccb8 by Tuan Le at 2020-05-21T12:16:46-04:00 llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 - - - - - 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 - - - - - 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 - - - - - 2b363ebb by Richard Eisenberg at 2020-05-21T12:18:45-04:00 MR template should ask for key part - - - - - a95bbd0b by Sebastian Graf at 2020-05-21T12:19:37-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. - - - - - d3d055b8 by Galen Huntington at 2020-05-21T12:20:18-04:00 Clarify pitfalls of NegativeLiterals; see #18022. - - - - - 1b508a9e by Alexey Kuleshevich at 2020-05-21T12:21:02-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" - - - - - 4ca0c8a1 by Andreas Klebinger at 2020-05-21T12:21: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. - - - - - a1275081 by Krzysztof Gogolewski at 2020-05-21T12:22:35-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 - - - - - 8a816e5f by Krzysztof Gogolewski at 2020-05-21T12:23:55-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. - - - - - 566cc73f by Sylvain Henry at 2020-05-21T12:24:45-04:00 Move isDynLinkName into GHC.Types.Name It doesn't belong into GHC.Unit.State - - - - - d830bbc9 by Adam Sandberg Ericsson at 2020-05-23T13:36:20-04:00 docs: fix formatting and add some links [skip ci] - - - - - 49301ad6 by Andrew Martin at 2020-05-23T13:37:01-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. - - - - - dcd6bdcc by Ben Gamari at 2020-05-23T13:37:48-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. - - - - - 82cb8913 by John Ericson at 2020-05-23T13:38:32-04:00 Fix #18145 and also avoid needless work with implicit vars - `forAllOrNothing` now is monadic, so we can trace whether we bind an explicit `forall` or not. - #18145 arose because the free vars calculation was needlessly complex. It is now greatly simplified. - Replaced some other implicit var code with `filterFreeVarsToBind`. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - a60dc835 by Ben Gamari at 2020-05-23T13:39:12-04:00 Bump process submodule Fixes #17926. - - - - - 856adf54 by Ben Gamari at 2020-05-23T13:40:21-04:00 users-guide: Clarify meaning of -haddock flag Fixes #18206. - - - - - 7ae57afd by Ben Gamari at 2020-05-23T13:41:03-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 - - - - - 63d30e60 by jneira at 2020-05-24T01:54:42-04:00 Add hie-bios script for windows systems It is a direct translation of the sh script - - - - - 59182b88 by jneira at 2020-05-24T01:54:42-04:00 Honour previous values for CABAL and CABFLAGS The immediate goal is let the hie-bios.bat script set CABFLAGS with `-v0` and remove all cabal output except the compiler arguments - - - - - 932dc54e by jneira at 2020-05-24T01:54:42-04:00 Add specific configuration for windows in hie.yaml - - - - - e0eda070 by jneira at 2020-05-24T01:54:42-04:00 Remove not needed hie-bios output - - - - - a0ea59d6 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Move Config module into GHC.Settings - - - - - 37430251 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Core.Arity into GHC.Core.Opt.Arity - - - - - a426abb9 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Hs.Types into GHC.Hs.Type See discussion in https://gitlab.haskell.org/ghc/ghc/issues/13009#note_268610 - - - - - 1c91a7a0 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Bump haddock submodule - - - - - 66bd24d1 by Ryan Scott at 2020-05-24T01:56:03-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. - - - - - 01c43634 by Matthew Pickering at 2020-05-24T01:56:42-04:00 Remove unused hs-boot file - - - - - 7a07aa71 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix cross-compiler build (#16051) - - - - - 15ccca16 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix distDir per stage - - - - - b420fb24 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix hp2ps error during cross-compilation Fixed by @alp (see https://gitlab.haskell.org/ghc/ghc/issues/16051#note_274265) - - - - - cd339ef0 by Joshua Price at 2020-05-24T15:22:56-04:00 Make Unicode brackets opening/closing tokens (#18225) The tokens `[|`, `|]`, `(|`, and `|)` are opening/closing tokens as described in GHC Proposal #229. This commit makes the unicode variants (`⟦`, `⟧`, `⦇`, and `⦈`) act the same as their ASCII counterparts. - - - - - 013d7120 by Ben Gamari at 2020-05-25T09:48:17-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. - - - - - 4c4312ed by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Drop redundant ad-hoc boot module check To determine whether the module is a boot module Coverage.addTicksToBinds was checking for a `boot` suffix in the module source filename. This is quite ad-hoc and shouldn't be necessary; the callsite in `deSugar` already checks that the module isn't a boot module. - - - - - 1abf3c84 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make tickBoxCount strict This could otherwise easily cause a leak of (+) thunks. - - - - - b2813750 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make ccIndices strict This just seems like a good idea. - - - - - 02e278eb by Ben Gamari at 2020-05-25T09:48:53-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. - - - - - b8c014ce by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Factor out addMixEntry - - - - - 53814a64 by Zubin Duggal at 2020-05-26T03:03:24-04:00 Add info about typeclass evidence to .hie files See `testsuite/tests/hiefile/should_run/HieQueries.hs` and `testsuite/tests/hiefile/should_run/HieQueries.stdout` for an example of this We add two new fields, `EvidenceVarBind` and `EvidenceVarUse` to the `ContextInfo` associated with an Identifier. These are associated with the appropriate identifiers for the evidence variables collected when we come across `HsWrappers`, `TcEvBinds` and `IPBinds` while traversing the AST. Instance dictionary and superclass selector dictionaries from `tcg_insts` and classes defined in `tcg_tcs` are also recorded in the AST as originating from their definition span This allows us to save a complete picture of the evidence constructed by the constraint solver, and will let us report this to the user, enabling features like going to the instance definition from the invocation of a class method(or any other method taking a constraint) and finding all usages of a particular instance. Additionally, - Mark NodeInfo with an origin so we can differentiate between bindings origininating in the source vs those in ghc - Along with typeclass evidence info, also include information on Implicit Parameters - Add a few utility functions to HieUtils in order to query the new info Updates haddock submodule - - - - - 6604906c by Sebastian Graf at 2020-05-26T03:04:04-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. - - - - - cf772f19 by Sylvain Henry at 2020-05-26T03:04:45-04:00 Enhance Note [About units] for Backpack - - - - - ede24126 by Takenobu Tani at 2020-05-27T00:13:55-04:00 core-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Core.hs <= coreSyn/CoreSyn.hs * GHC/Core/Coercion.hs <= types/Coercion.hs * GHC/Core/Coercion/Axiom.hs <= types/CoAxiom.hs * GHC/Core/Coercion/Opt.hs <= types/OptCoercion.hs * GHC/Core/DataCon.hs <= basicTypes/DataCon.hs * GHC/Core/FamInstEnv.hs <= types/FamInstEnv.hs * GHC/Core/Lint.hs <= coreSyn/CoreLint.hs * GHC/Core/Subst.hs <= coreSyn/CoreSubst.hs * GHC/Core/TyCo/Rep.hs <= types/TyCoRep.hs * GHC/Core/TyCon.hs <= types/TyCon.hs * GHC/Core/Type.hs <= types/Type.hs * GHC/Core/Unify.hs <= types/Unify.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/Var.hs <= basicTypes/Var.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [skip ci] - - - - - 04750304 by Ben Gamari at 2020-05-27T00:14:33-04:00 eventlog: Fix racy flushing Previously no attempt was made to avoid multiple threads writing their capability-local eventlog buffers to the eventlog writer simultaneously. This could result in multiple eventlog streams being interleaved. Fix this by documenting that the EventLogWriter's write() and flush() functions may be called reentrantly and fix the default writer to protect its FILE* by a mutex. Fixes #18210. - - - - - d6203f24 by Joshua Price at 2020-05-27T00:15:17-04:00 Make `identifier` parse unparenthesized `->` (#18060) - - - - - bd9f5589 by Ben Gamari at 2020-05-27T12:44:10-04:00 testsuite: Add test for #18151 - - - - - 95a9eb73 by Ben Gamari at 2020-05-27T12:44:10-04:00 testsuite: Add test for desugaring of PostfixOperators - - - - - b1dbd625 by Ben Gamari at 2020-05-27T13:00:23-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. - - - - - d60270c1 by Ben Gamari at 2020-05-27T14:47:47-04:00 testsuite: Don't fail if we can't unlink __symlink_test Afterall, it's possible we were unable to create it due to lack of symlink permission. - - - - - 30 changed files: - + .git-ignore-revs - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/merge_request_templates/merge-request.md - 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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/262b205849ae03b73534f4195b0d41cef8a2ceb9...d60270c120ad060218bd3336c529753d09a9464d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/262b205849ae03b73534f4195b0d41cef8a2ceb9...d60270c120ad060218bd3336c529753d09a9464d You're receiving 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 27 19:12:33 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 27 May 2020 15:12:33 -0400 Subject: [Git][ghc/ghc][wip/testsuite-fixes] 3 commits: testsuite: Refactor ghostscript detection Message-ID: <5ecebba1255c0_6e263f9eefac1d2c206965e@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/testsuite-fixes at Glasgow Haskell Compiler / GHC Commits: 71504a8d by Ben Gamari at 2020-05-27T15:07:47-04:00 testsuite: Refactor ghostscript detection Tamar reported that he saw crashes due to unhandled exceptions. - - - - - 8d5f51ec by Ben Gamari at 2020-05-27T15:10:52-04:00 testsuite/perf_notes: Fix ill-typed assignments - - - - - ad599da0 by Ben Gamari at 2020-05-27T15:12:12-04:00 testsuite/testutil: Fix bytes/str mismatch - - - - - 4 changed files: - testsuite/driver/perf_notes.py - testsuite/driver/testglobals.py - testsuite/driver/testlib.py - testsuite/driver/testutil.py Changes: ===================================== testsuite/driver/perf_notes.py ===================================== @@ -126,10 +126,11 @@ def get_perf_stats(commit: Union[GitRef, GitHash]=GitRef('HEAD'), except subprocess.CalledProcessError: return [] - log = log.strip('\n').split('\n') - log = list(filter(None, log)) - log = [parse_perf_stat(stat_str) for stat_str in log] - return log + return \ + [ parse_perf_stat(stat_str) + for stat_str in log.strip('\n').split('\n') + if stat_str != '' + ] # Check if a str is in a 40 character git commit hash. _commit_hash_re = re.compile('[0-9a-f]' * 40) ===================================== testsuite/driver/testglobals.py ===================================== @@ -43,7 +43,7 @@ class TestConfig: self.summary_file = '' # Path to Ghostscript - self.gs = '' + self.gs = None # type: Optional[Path] # Run tests requiring Haddock self.haddock = False ===================================== testsuite/driver/testlib.py ===================================== @@ -22,7 +22,7 @@ from testglobals import config, ghc_env, default_testopts, brokens, t, \ TestRun, TestResult, TestOptions, PerfMetric from testutil import strip_quotes, lndir, link_or_copy_file, passed, \ failBecause, testing_metrics, \ - PassFail + PassFail, memoize from term_color import Color, colored import testutil from cpu_features import have_cpu_feature @@ -1895,7 +1895,7 @@ def check_hp_ok(name: TestName) -> bool: if hp2psResult == 0: if actual_ps_path.exists(): - if gs_working: + if does_ghostscript_work(): gsResult = runCmd(genGSCmd(actual_ps_path)) if (gsResult == 0): return True @@ -2335,31 +2335,38 @@ def runCmd(cmd: str, # ----------------------------------------------------------------------------- # checking if ghostscript is available for checking the output of hp2ps - def genGSCmd(psfile: Path) -> str: return '{{gs}} -dNODISPLAY -dBATCH -dQUIET -dNOPAUSE "{0}"'.format(psfile) -def gsNotWorking() -> None: - global gs_working - print("GhostScript not available for hp2ps tests") - -global gs_working -gs_working = False -if config.have_profiling: - if config.gs != '': - resultGood = runCmd(genGSCmd(config.top + '/config/good.ps')); - if resultGood == 0: - resultBad = runCmd(genGSCmd(config.top + '/config/bad.ps') + - ' >/dev/null 2>&1') - if resultBad != 0: - print("GhostScript available for hp2ps tests") - gs_working = True - else: - gsNotWorking(); - else: - gsNotWorking(); - else: - gsNotWorking(); + at memoize +def does_ghostscript_work() -> bool: + """ + Detect whether Ghostscript is functional. + """ + def gsNotWorking(reason: str) -> None: + print("GhostScript not available for hp2ps tests:", reason) + + if config.gs is None: + return False + + try: + if runCmd(genGSCmd(config.top / 'config' / 'good.ps')) != 0: + gsNotWorking("gs can't process good input") + return False + except Exception as e: + gsNotWorking('error invoking gs on bad input: %s' % e) + return False + + try: + cmd = genGSCmd(config.top / 'config' / 'bad.ps') + ' >/dev/null 2>&1' + if runCmd(cmd) == 0: + gsNotWorking('gs accepts bad input') + return False + except Exception as e: + gsNotWorking('error invoking gs on bad input: %s' % e) + return False + + return True def add_suffix( name: Union[str, Path], suffix: str ) -> Path: if suffix == '': ===================================== testsuite/driver/testutil.py ===================================== @@ -55,7 +55,7 @@ def getStdout(cmd_and_args: List[str]): if r != 0: raise Exception("Command failed: " + str(cmd_and_args)) if stderr: - raise Exception("stderr from command: %s\nOutput:\n%s\n" % (cmd_and_args, stderr)) + raise Exception("stderr from command: %s\nOutput:\n%s\n" % (cmd_and_args, stderr.decode('utf-8'))) return stdout.decode('utf-8') def lndir(srcdir: Path, dstdir: Path): @@ -131,3 +131,16 @@ class Watcher(object): if self.pool <= 0: self.evt.set() self.sync_lock.release() + +def memoize(f): + """ + A decorator to memoize a nullary function. + """ + def cached(): + if cached._cache is None: + cached._cache = f() + + return cached._cache + + cached._cache = None + return cached View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d60270c120ad060218bd3336c529753d09a9464d...ad599da053fae69172ba44710e560abebc0e6b4d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d60270c120ad060218bd3336c529753d09a9464d...ad599da053fae69172ba44710e560abebc0e6b4d You're receiving 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 27 19:14:40 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 27 May 2020 15:14:40 -0400 Subject: [Git][ghc/ghc][wip/testsuite-fixes] testsuite: Work around spurious mypy failure Message-ID: <5ecebc2082e90_6e263f9eeb6d00f0207005d@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/testsuite-fixes at Glasgow Haskell Compiler / GHC Commits: 18255827 by Ben Gamari at 2020-05-27T15:14:30-04:00 testsuite: Work around spurious mypy failure - - - - - 1 changed file: - testsuite/driver/my_typing.py Changes: ===================================== testsuite/driver/my_typing.py ===================================== @@ -26,7 +26,7 @@ except: # TextIO is missing on some older Pythons. if 'TextIO' not in globals(): try: - TextIO = typing.TextIO + from typing import TextIO except ImportError: TextIO = None # type: ignore else: View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/182558274d9d83ce972a306a645beebaa18fd5f8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/182558274d9d83ce972a306a645beebaa18fd5f8 You're receiving 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 27 19:15:05 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 27 May 2020 15:15:05 -0400 Subject: [Git][ghc/ghc][wip/testsuite-fixes] 5 commits: testsuite: Don't fail if we can't unlink __symlink_test Message-ID: <5ecebc397740a_6e263f9ecd30d12020704fe@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/testsuite-fixes at Glasgow Haskell Compiler / GHC Commits: 937a2415 by Ben Gamari at 2020-05-27T15:15:00-04:00 testsuite: Don't fail if we can't unlink __symlink_test Afterall, it's possible we were unable to create it due to lack of symlink permission. - - - - - 17a1c97e by Ben Gamari at 2020-05-27T15:15:00-04:00 testsuite: Refactor ghostscript detection Tamar reported that he saw crashes due to unhandled exceptions. - - - - - e41176a5 by Ben Gamari at 2020-05-27T15:15:00-04:00 testsuite/perf_notes: Fix ill-typed assignments - - - - - 4b3f6582 by Ben Gamari at 2020-05-27T15:15:00-04:00 testsuite/testutil: Fix bytes/str mismatch - - - - - 8afa32b8 by Ben Gamari at 2020-05-27T15:15:00-04:00 testsuite: Work around spurious mypy failure - - - - - 5 changed files: - testsuite/driver/my_typing.py - testsuite/driver/perf_notes.py - testsuite/driver/testglobals.py - testsuite/driver/testlib.py - testsuite/driver/testutil.py Changes: ===================================== testsuite/driver/my_typing.py ===================================== @@ -26,7 +26,7 @@ except: # TextIO is missing on some older Pythons. if 'TextIO' not in globals(): try: - TextIO = typing.TextIO + from typing import TextIO except ImportError: TextIO = None # type: ignore else: ===================================== testsuite/driver/perf_notes.py ===================================== @@ -126,10 +126,11 @@ def get_perf_stats(commit: Union[GitRef, GitHash]=GitRef('HEAD'), except subprocess.CalledProcessError: return [] - log = log.strip('\n').split('\n') - log = list(filter(None, log)) - log = [parse_perf_stat(stat_str) for stat_str in log] - return log + return \ + [ parse_perf_stat(stat_str) + for stat_str in log.strip('\n').split('\n') + if stat_str != '' + ] # Check if a str is in a 40 character git commit hash. _commit_hash_re = re.compile('[0-9a-f]' * 40) ===================================== testsuite/driver/testglobals.py ===================================== @@ -43,7 +43,7 @@ class TestConfig: self.summary_file = '' # Path to Ghostscript - self.gs = '' + self.gs = None # type: Optional[Path] # Run tests requiring Haddock self.haddock = False ===================================== testsuite/driver/testlib.py ===================================== @@ -22,7 +22,7 @@ from testglobals import config, ghc_env, default_testopts, brokens, t, \ TestRun, TestResult, TestOptions, PerfMetric from testutil import strip_quotes, lndir, link_or_copy_file, passed, \ failBecause, testing_metrics, \ - PassFail + PassFail, memoize from term_color import Color, colored import testutil from cpu_features import have_cpu_feature @@ -1895,7 +1895,7 @@ def check_hp_ok(name: TestName) -> bool: if hp2psResult == 0: if actual_ps_path.exists(): - if gs_working: + if does_ghostscript_work(): gsResult = runCmd(genGSCmd(actual_ps_path)) if (gsResult == 0): return True @@ -2335,31 +2335,38 @@ def runCmd(cmd: str, # ----------------------------------------------------------------------------- # checking if ghostscript is available for checking the output of hp2ps - def genGSCmd(psfile: Path) -> str: return '{{gs}} -dNODISPLAY -dBATCH -dQUIET -dNOPAUSE "{0}"'.format(psfile) -def gsNotWorking() -> None: - global gs_working - print("GhostScript not available for hp2ps tests") - -global gs_working -gs_working = False -if config.have_profiling: - if config.gs != '': - resultGood = runCmd(genGSCmd(config.top + '/config/good.ps')); - if resultGood == 0: - resultBad = runCmd(genGSCmd(config.top + '/config/bad.ps') + - ' >/dev/null 2>&1') - if resultBad != 0: - print("GhostScript available for hp2ps tests") - gs_working = True - else: - gsNotWorking(); - else: - gsNotWorking(); - else: - gsNotWorking(); + at memoize +def does_ghostscript_work() -> bool: + """ + Detect whether Ghostscript is functional. + """ + def gsNotWorking(reason: str) -> None: + print("GhostScript not available for hp2ps tests:", reason) + + if config.gs is None: + return False + + try: + if runCmd(genGSCmd(config.top / 'config' / 'good.ps')) != 0: + gsNotWorking("gs can't process good input") + return False + except Exception as e: + gsNotWorking('error invoking gs on bad input: %s' % e) + return False + + try: + cmd = genGSCmd(config.top / 'config' / 'bad.ps') + ' >/dev/null 2>&1' + if runCmd(cmd) == 0: + gsNotWorking('gs accepts bad input') + return False + except Exception as e: + gsNotWorking('error invoking gs on bad input: %s' % e) + return False + + return True def add_suffix( name: Union[str, Path], suffix: str ) -> Path: if suffix == '': ===================================== testsuite/driver/testutil.py ===================================== @@ -55,7 +55,7 @@ def getStdout(cmd_and_args: List[str]): if r != 0: raise Exception("Command failed: " + str(cmd_and_args)) if stderr: - raise Exception("stderr from command: %s\nOutput:\n%s\n" % (cmd_and_args, stderr)) + raise Exception("stderr from command: %s\nOutput:\n%s\n" % (cmd_and_args, stderr.decode('utf-8'))) return stdout.decode('utf-8') def lndir(srcdir: Path, dstdir: Path): @@ -98,7 +98,10 @@ def symlinks_work() -> bool: except OSError as e: print('Saw {} during symlink test; assuming symlinks do not work.'.format(e)) finally: - os.unlink('__symlink-test') + try: + os.unlink('__symlink-test') + except: + pass return works else: @@ -128,3 +131,16 @@ class Watcher(object): if self.pool <= 0: self.evt.set() self.sync_lock.release() + +def memoize(f): + """ + A decorator to memoize a nullary function. + """ + def cached(): + if cached._cache is None: + cached._cache = f() + + return cached._cache + + cached._cache = None + return cached View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/182558274d9d83ce972a306a645beebaa18fd5f8...8afa32b87cfad193d25183bd0b95127733ae7504 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/182558274d9d83ce972a306a645beebaa18fd5f8...8afa32b87cfad193d25183bd0b95127733ae7504 You're receiving 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 27 19:25:04 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Wed, 27 May 2020 15:25:04 -0400 Subject: [Git][ghc/ghc][wip/nested-cpr-2019] Regard all arity 0 bindings (incl. DataCon apps) as thunks Message-ID: <5ecebe902744f_6e261275eeac2072749@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/nested-cpr-2019 at Glasgow Haskell Compiler / GHC Commits: a98c6510 by Sebastian Graf at 2020-05-27T21:24:56+02:00 Regard all arity 0 bindings (incl. DataCon apps) as thunks - - - - - 1 changed file: - compiler/GHC/Core/Opt/CprAnal.hs Changes: ===================================== compiler/GHC/Core/Opt/CprAnal.hs ===================================== @@ -357,7 +357,7 @@ cprAnalBind top_lvl env widening args id rhs -- See Note [CPR for thunks] stays_thunk = is_thunk && not_strict - is_thunk = not (exprIsHNF rhs) && not (isJoinId id) + is_thunk = idArity id == 0 && not (isJoinId id) not_strict = not (isStrictDmd (idDemandInfo id)) -- See Note [CPR for sum types] (_, ret_ty) = splitPiTys (idType id) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a98c6510929219df22abe30f686e653040133e75 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a98c6510929219df22abe30f686e653040133e75 You're receiving 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 27 19:35:17 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 27 May 2020 15:35:17 -0400 Subject: [Git][ghc/ghc][wip/T18234] 9 commits: Add info about typeclass evidence to .hie files Message-ID: <5ecec0f5933c8_6e263f9f0bed5050207566e@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18234 at Glasgow Haskell Compiler / GHC Commits: 53814a64 by Zubin Duggal at 2020-05-26T03:03:24-04:00 Add info about typeclass evidence to .hie files See `testsuite/tests/hiefile/should_run/HieQueries.hs` and `testsuite/tests/hiefile/should_run/HieQueries.stdout` for an example of this We add two new fields, `EvidenceVarBind` and `EvidenceVarUse` to the `ContextInfo` associated with an Identifier. These are associated with the appropriate identifiers for the evidence variables collected when we come across `HsWrappers`, `TcEvBinds` and `IPBinds` while traversing the AST. Instance dictionary and superclass selector dictionaries from `tcg_insts` and classes defined in `tcg_tcs` are also recorded in the AST as originating from their definition span This allows us to save a complete picture of the evidence constructed by the constraint solver, and will let us report this to the user, enabling features like going to the instance definition from the invocation of a class method(or any other method taking a constraint) and finding all usages of a particular instance. Additionally, - Mark NodeInfo with an origin so we can differentiate between bindings origininating in the source vs those in ghc - Along with typeclass evidence info, also include information on Implicit Parameters - Add a few utility functions to HieUtils in order to query the new info Updates haddock submodule - - - - - 6604906c by Sebastian Graf at 2020-05-26T03:04:04-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. - - - - - cf772f19 by Sylvain Henry at 2020-05-26T03:04:45-04:00 Enhance Note [About units] for Backpack - - - - - ede24126 by Takenobu Tani at 2020-05-27T00:13:55-04:00 core-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Core.hs <= coreSyn/CoreSyn.hs * GHC/Core/Coercion.hs <= types/Coercion.hs * GHC/Core/Coercion/Axiom.hs <= types/CoAxiom.hs * GHC/Core/Coercion/Opt.hs <= types/OptCoercion.hs * GHC/Core/DataCon.hs <= basicTypes/DataCon.hs * GHC/Core/FamInstEnv.hs <= types/FamInstEnv.hs * GHC/Core/Lint.hs <= coreSyn/CoreLint.hs * GHC/Core/Subst.hs <= coreSyn/CoreSubst.hs * GHC/Core/TyCo/Rep.hs <= types/TyCoRep.hs * GHC/Core/TyCon.hs <= types/TyCon.hs * GHC/Core/Type.hs <= types/Type.hs * GHC/Core/Unify.hs <= types/Unify.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/Var.hs <= basicTypes/Var.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [skip ci] - - - - - 04750304 by Ben Gamari at 2020-05-27T00:14:33-04:00 eventlog: Fix racy flushing Previously no attempt was made to avoid multiple threads writing their capability-local eventlog buffers to the eventlog writer simultaneously. This could result in multiple eventlog streams being interleaved. Fix this by documenting that the EventLogWriter's write() and flush() functions may be called reentrantly and fix the default writer to protect its FILE* by a mutex. Fixes #18210. - - - - - d6203f24 by Joshua Price at 2020-05-27T00:15:17-04:00 Make `identifier` parse unparenthesized `->` (#18060) - - - - - b20d8fc9 by Ben Gamari at 2020-05-27T15:28:29-04:00 gitlab-ci: Add usage message to ci.sh - - - - - 65c75d5d by Ben Gamari at 2020-05-27T15:34:26-04:00 gitlab-ci: Make names more consistent - - - - - e5a0d8a5 by Ben Gamari at 2020-05-27T15:34:58-04:00 gitlab-ci: Introduce a nightly cross-compilation job This adds a job to test cross-compilation from x86-64 to AArch64 with Hadrian. Fixes #18234. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Debug.hs - compiler/GHC/Iface/Ext/Types.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Parser.y - compiler/GHC/Unit.hs - docs/core-spec/CoreLint.ott - docs/core-spec/CoreSyn.ott - docs/core-spec/README - docs/core-spec/core-spec.mng - docs/core-spec/core-spec.pdf - docs/users_guide/runtime_control.rst - docs/users_guide/using-optimisation.rst - includes/rts/EventLogWriter.h - rts/eventlog/EventLogWriter.c - + testsuite/tests/ghci/T18060/T18060.script - + testsuite/tests/ghci/T18060/T18060.stdout - + testsuite/tests/ghci/T18060/all.T - testsuite/tests/hiefile/should_compile/Scopes.hs - + testsuite/tests/hiefile/should_run/HieQueries.hs - + testsuite/tests/hiefile/should_run/HieQueries.stdout - testsuite/tests/hiefile/should_run/PatTypes.hs - testsuite/tests/hiefile/should_run/all.T - + testsuite/tests/stranal/should_compile/T18122.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/03a84b671c83a514c84bfe629e3dcb90c48c1d98...e5a0d8a5536c0db649642044a33c0d73e6c28e62 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/03a84b671c83a514c84bfe629e3dcb90c48c1d98...e5a0d8a5536c0db649642044a33c0d73e6c28e62 You're receiving 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 27 20:24:36 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Wed, 27 May 2020 16:24:36 -0400 Subject: [Git][ghc/ghc][wip/always-use-rnImplicitBndrs] Always use rnImplicitBndrs to bring implicit tyvars into scope Message-ID: <5ececc84c2763_6e263f9e9e7046b82077224@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/always-use-rnImplicitBndrs at Glasgow Haskell Compiler / GHC Commits: 5d45579f by Ryan Scott at 2020-05-27T16:24:10-04:00 Always use rnImplicitBndrs to bring implicit tyvars into scope This implements a first step towards #16762 by changing the renamer to always use `rnImplicitBndrs` to bring implicitly bound type variables into scope. The main change is in `rnFamInstEqn` and `bindHsQTyVars`, which previously used _ad hoc_ methods of binding their implicit tyvars. There are a number of knock-on consequences: * One of the reasons that `rnFamInstEqn` used an _ad hoc_ binding mechanism was to give more precise source locations in `-Wunused-type-patterns` warnings. (See https://gitlab.haskell.org/ghc/ghc/issues/16762#note_273343 for an example of this.) However, these warnings are actually a little _too_ precise, since implicitly bound type variables don't have exact binding sites like explicitly bound type variables do. A similar problem existed for "`Different names for the same type variable`" errors involving implicit tyvars bound by `bindHsQTyVars`. Therefore, we simply accept the less precise (but more accurate) source locations from `rnImplicitBndrs` in `rnFamInstEqn` and `bindHsQTyVars`. See `Note [Source locations for implicitly bound type variables]` in `GHC.Rename.HsType` for the full story. * In order for `rnImplicitBndrs` to work in `rnFamInstEqn`, it needs to be able to look up names from the parent class (in the event that we are renaming an associated type family instance). As a result, `rnImplicitBndrs` now takes an argument of type `Maybe assoc`, which is `Just` in the event that a type family instance is associated with a class. * Previously, GHC kept track of three type synonyms for free type variables in the renamer: `FreeKiTyVars`, `FreeKiTyVarsDups` (which are allowed to contain duplicates)`, and `FreeKiTyVarsNoDups` (which contain no duplicates). However, making is a distinction between `-Dups` and `-NoDups` is now pointless, as all code that returns `FreeKiTyVars{,Dups,NoDups}` will eventually end up being passed to `rnImplicitBndrs`, which removes duplicates. As a result, I decided to just get rid of `FreeKiTyVarsDups` and `FreeKiTyVarsNoDups`, leaving only `FreeKiTyVars`. * The `bindLRdrNames` and `deleteBys` functions are now dead code, so I took the liberty of removing them. - - - - - 16 changed files: - compiler/GHC/Data/List/SetOps.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Tc/Gen/Splice.hs - testsuite/tests/indexed-types/should_compile/ExplicitForAllFams2.stderr - testsuite/tests/indexed-types/should_compile/T16356_Compile2.stderr - testsuite/tests/indexed-types/should_compile/T16632.stderr - testsuite/tests/indexed-types/should_compile/UnusedTyVarWarnings.stderr - testsuite/tests/indexed-types/should_compile/UnusedTyVarWarningsNamedWCs.stderr - testsuite/tests/indexed-types/should_fail/T17008a.stderr - testsuite/tests/indexed-types/should_fail/T7536.stderr - testsuite/tests/polykinds/T11203.stderr - testsuite/tests/polykinds/T11821a.stderr - testsuite/tests/typecheck/should_fail/T17566b.stderr - testsuite/tests/typecheck/should_fail/T17566c.stderr Changes: ===================================== compiler/GHC/Data/List/SetOps.hs ===================================== @@ -10,7 +10,7 @@ -- -- Avoid using them as much as possible module GHC.Data.List.SetOps ( - unionLists, minusList, deleteBys, + unionLists, minusList, -- Association lists Assoc, assoc, assocMaybe, assocUsing, assocDefault, assocDefaultUsing, @@ -39,11 +39,6 @@ getNth :: Outputable a => [a] -> Int -> a getNth xs n = ASSERT2( xs `lengthExceeds` n, ppr n $$ ppr xs ) xs !! n -deleteBys :: (a -> a -> Bool) -> [a] -> [a] -> [a] --- (deleteBys eq xs ys) returns xs-ys, using the given equality function --- Just like 'Data.List.delete' but with an equality function -deleteBys eq xs ys = foldl' (flip (L.deleteBy eq)) xs ys - {- ************************************************************************ * * ===================================== compiler/GHC/Hs/Type.hs ===================================== @@ -30,7 +30,7 @@ module GHC.Hs.Type ( HsTyLit(..), HsIPName(..), hsIPNameFS, HsArg(..), numVisibleArgs, - LHsTypeArg, + LHsTypeArg, lhsTypeArgSrcSpan, OutputableBndrFlag, LBangType, BangType, @@ -1287,6 +1287,13 @@ numVisibleArgs = count is_vis -- type level equivalent type LHsTypeArg p = HsArg (LHsType p) (LHsKind p) +-- | Compute the 'SrcSpan' associated with an 'LHsTypeArg'. +lhsTypeArgSrcSpan :: LHsTypeArg pass -> SrcSpan +lhsTypeArgSrcSpan arg = case arg of + HsValArg tm -> getLoc tm + HsTypeArg at ty -> at `combineSrcSpans` getLoc ty + HsArgPar sp -> sp + instance (Outputable tm, Outputable ty) => Outputable (HsArg tm ty) where ppr (HsValArg tm) = ppr tm ppr (HsTypeArg _ ty) = char '@' <> ppr ty ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -24,11 +24,11 @@ module GHC.Rename.HsType ( -- Binding related stuff bindLHsTyVarBndr, bindLHsTyVarBndrs, rnImplicitBndrs, - bindSigTyVarsFV, bindHsQTyVars, bindLRdrNames, + bindSigTyVarsFV, bindHsQTyVars, + FreeKiTyVars, extractHsTyRdrTyVars, extractHsTyRdrTyVarsKindVars, - extractHsTysRdrTyVarsDups, - extractRdrKindSigVars, extractDataDefnKindVars, - extractHsTvBndrs, extractHsTyArgRdrKiTyVarsDup, + extractHsTysRdrTyVars, extractRdrKindSigVars, extractDataDefnKindVars, + extractHsTvBndrs, extractHsTyArgRdrKiTyVars, forAllOrNothing, nubL ) where @@ -56,7 +56,6 @@ import GHC.Types.Name.Set import GHC.Types.FieldLabel import GHC.Utils.Misc -import GHC.Data.List.SetOps ( deleteBys ) import GHC.Types.Basic ( compareFixity, funTyFixity, negateFixity , Fixity(..), FixityDirection(..), LexicalFixity(..) , TypeOrKind(..) ) @@ -164,14 +163,14 @@ rn_hs_sig_wc_type :: HsSigWcTypeScoping -> HsDocContext -> Maybe SDoc -> RnM (a, FreeVars) rn_hs_sig_wc_type scoping ctxt inf_err hs_ty thing_inside = do { check_inferred_vars ctxt inf_err hs_ty - ; free_vars <- filterInScopeM (extractHsTyRdrTyVarsDups hs_ty) + ; free_vars <- filterInScopeM (extractHsTyRdrTyVars hs_ty) ; (nwc_rdrs', tv_rdrs) <- partition_nwcs free_vars ; let nwc_rdrs = nubL nwc_rdrs' ; implicit_bndrs <- case scoping of AlwaysBind -> pure tv_rdrs BindUnlessForall -> forAllOrNothing (isLHsForAllTy hs_ty) tv_rdrs NeverBind -> pure [] - ; rnImplicitBndrs implicit_bndrs $ \ vars -> + ; rnImplicitBndrs Nothing implicit_bndrs $ \ vars -> do { (wcs, hs_ty', fvs1) <- rnWcBody ctxt nwc_rdrs hs_ty ; (res, fvs2) <- thing_inside wcs vars hs_ty' ; return (res, fvs1 `plusFV` fvs2) } } @@ -179,7 +178,8 @@ rn_hs_sig_wc_type scoping ctxt inf_err hs_ty thing_inside rnHsWcType :: HsDocContext -> LHsWcType GhcPs -> RnM (LHsWcType GhcRn, FreeVars) rnHsWcType ctxt (HsWC { hswc_body = hs_ty }) = do { free_vars <- filterInScopeM (extractHsTyRdrTyVars hs_ty) - ; (nwc_rdrs, _) <- partition_nwcs free_vars + ; (nwc_rdrs', _) <- partition_nwcs free_vars + ; let nwc_rdrs = nubL nwc_rdrs' ; (wcs, hs_ty', fvs) <- rnWcBody ctxt nwc_rdrs hs_ty ; let sig_ty' = HsWC { hswc_ext = wcs, hswc_body = hs_ty' } ; return (sig_ty', fvs) } @@ -328,8 +328,8 @@ rnHsSigType ctx level inf_err (HsIB { hsib_body = hs_ty }) ; check_inferred_vars ctx inf_err hs_ty ; vars0 <- forAllOrNothing (isLHsForAllTy hs_ty) $ filterInScope rdr_env - $ extractHsTyRdrTyVarsDups hs_ty - ; rnImplicitBndrs vars0 $ \ vars -> + $ extractHsTyRdrTyVars hs_ty + ; rnImplicitBndrs Nothing vars0 $ \ vars -> do { (body', fvs) <- rnLHsTyKi (mkTyKiEnv ctx level RnTypeBody) hs_ty ; return ( HsIB { hsib_ext = vars @@ -357,9 +357,9 @@ forAllOrNothing :: Bool -- we do not want to bring 'b' into scope, hence True -- But f :: a -> b -- we want to bring both 'a' and 'b' into scope, hence False - -> FreeKiTyVarsWithDups + -> FreeKiTyVars -- ^ Free vars of the type - -> RnM FreeKiTyVarsWithDups + -> RnM FreeKiTyVars forAllOrNothing has_outer_forall fvs = case has_outer_forall of True -> do traceRn "forAllOrNothing" $ text "has explicit outer forall" @@ -368,24 +368,50 @@ forAllOrNothing has_outer_forall fvs = case has_outer_forall of traceRn "forAllOrNothing" $ text "no explicit forall. implicit binders:" <+> ppr fvs pure fvs -rnImplicitBndrs :: FreeKiTyVarsWithDups +rnImplicitBndrs :: Maybe assoc + -- ^ @'Just' _@ => an associated type decl + -> FreeKiTyVars -- ^ Surface-syntax free vars that we will implicitly bind. - -- May have duplicates, which is checked here + -- May have duplicates, which are removed here. -> ([Name] -> RnM (a, FreeVars)) -> RnM (a, FreeVars) -rnImplicitBndrs implicit_vs_with_dups - thing_inside +rnImplicitBndrs mb_assoc implicit_vs_with_dups thing_inside = do { let implicit_vs = nubL implicit_vs_with_dups ; traceRn "rnImplicitBndrs" $ vcat [ ppr implicit_vs_with_dups, ppr implicit_vs ] + -- Use the currently set SrcSpan as the new source location for each Name. + -- See Note [Source locations for implicitly bound type variables]. ; loc <- getSrcSpanM - ; vars <- mapM (newLocalBndrRn . L loc . unLoc) implicit_vs + ; vars <- mapM (newTyVarNameRn mb_assoc . L loc . unLoc) implicit_vs ; bindLocalNamesFV vars $ thing_inside vars } +{- +Note [Source locations for implicitly bound type variables] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +When bringing implicitly bound type variables into scope (in rnImplicitBndrs), +we do something peculiar: we drop the original SrcSpan attached to each +variable and replace it with the currently set SrcSpan. Moreover, this new +SrcSpan is usually /less/ precise than the original one, and that's OK. To see +why this is done, consider the following example: + + f :: a -> b -> a + +Suppose that a warning or error message needs to point to the SrcSpans of the +binding sites for `a` and `b`. But where /are/ they bound, anyway? Technically, +they're bound by an unwritten `forall` at the front of the type signature, but +there is no SrcSpan for that. We could point to the first occurrence of `a` as +the binding site for `a`, but that would make the first occurrence of `a` +special. Moreover, we don't want IDEs to confuse binding sites and occurrences. + +As a result, we make the `SrcSpan`s for `a` and `b` span the entirety of the +type signature, since the type signature implicitly carries their binding +sites. This is less precise, but more accurate. +-} + check_inferred_vars :: HsDocContext -> Maybe SDoc -- ^ The error msg if the signature is not allowed to contain @@ -831,24 +857,13 @@ bindSigTyVarsFV tvs thing_inside else bindLocalNamesFV tvs thing_inside } --- | Simply bring a bunch of RdrNames into scope. No checking for --- validity, at all. The binding location is taken from the location --- on each name. -bindLRdrNames :: [Located RdrName] - -> ([Name] -> RnM (a, FreeVars)) - -> RnM (a, FreeVars) -bindLRdrNames rdrs thing_inside - = do { var_names <- mapM (newTyVarNameRn Nothing) rdrs - ; bindLocalNamesFV var_names $ - thing_inside var_names } - --------------- bindHsQTyVars :: forall a b. HsDocContext -> Maybe SDoc -- Just d => check for unused tvs -- d is a phrase like "in the type ..." -> Maybe a -- Just _ => an associated type decl - -> [Located RdrName] -- Kind variables from scope, no dups + -> FreeKiTyVars -- Kind variables from scope -> (LHsQTyVars GhcPs) -> (LHsQTyVars GhcRn -> Bool -> RnM (b, FreeVars)) -- The Bool is True <=> all kind variables used in the @@ -871,10 +886,10 @@ bindHsQTyVars doc mb_in_doc mb_assoc body_kv_occs hsq_bndrs thing_inside -- all these various things are doing bndrs, implicit_kvs :: [Located RdrName] bndrs = map hsLTyVarLocName hs_tv_bndrs - implicit_kvs = nubL $ filterFreeVarsToBind bndrs $ + implicit_kvs = filterFreeVarsToBind bndrs $ bndr_kv_occs ++ body_kv_occs - del = deleteBys eqLocated - body_remaining = (body_kv_occs `del` bndrs) `del` bndr_kv_occs + body_remaining = filterFreeVarsToBind bndr_kv_occs $ + filterFreeVarsToBind bndrs body_kv_occs all_bound_on_lhs = null body_remaining ; traceRn "checkMixedVars3" $ @@ -885,9 +900,7 @@ bindHsQTyVars doc mb_in_doc mb_assoc body_kv_occs hsq_bndrs thing_inside , text "body_remaining" <+> ppr body_remaining ] - ; implicit_kv_nms <- mapM (newTyVarNameRn mb_assoc) implicit_kvs - - ; bindLocalNamesFV implicit_kv_nms $ + ; rnImplicitBndrs mb_assoc implicit_kvs $ \ implicit_kv_nms -> bindLHsTyVarBndrs doc mb_in_doc mb_assoc hs_tv_bndrs $ \ rn_bndrs -> do { traceRn "bindHsQTyVars" (ppr hsq_bndrs $$ ppr implicit_kv_nms $$ ppr rn_bndrs) ; thing_inside (HsQTvs { hsq_ext = implicit_kv_nms @@ -909,12 +922,12 @@ Then: body_kv_occs = [k2,k1], kind variables free in the result kind signature - implicit_kvs = [k1,k2], kind variables free in kind signatures - of hs_tv_bndrs, and not bound by bndrs + implicit_kvs = [k1,k2,k1], kind variables free in kind signatures + of hs_tv_bndrs, and not bound by bndrs * We want to quantify add implicit bindings for implicit_kvs -* If implicit_body_kvs is non-empty, then there is a kind variable +* If body_kv_occs is non-empty, then there is a kind variable mentioned in the kind signature that is not bound "on the left". That's one of the rules for a CUSK, so we pass that info on as the second argument to thing_inside. @@ -922,6 +935,9 @@ Then: * Order is not important in these lists. All we are doing is bring Names into scope. +* bndr_kv_occs, body_kv_occs, and implicit_kvs can contain duplicates. All + duplicate occurrences are removed when we bind them with rnImplicitBndrs. + Finally, you may wonder why filterFreeVarsToBind removes in-scope variables from bndr/body_kv_occs. How can anything be in scope? Answer: HsQTyVars is /also/ used (slightly oddly) for Haskell-98 syntax @@ -1040,14 +1056,15 @@ bindLHsTyVarBndr doc mb_assoc (L loc (KindedTyVar x fl lrdr@(L lv _) kind)) $ thing_inside (L loc (KindedTyVar x fl (L lv tv_nm) kind')) ; return (b, fvs1 `plusFV` fvs2) } -newTyVarNameRn :: Maybe a -> Located RdrName -> RnM Name -newTyVarNameRn mb_assoc (L loc rdr) +newTyVarNameRn :: Maybe a -- associated class + -> Located RdrName -> RnM Name +newTyVarNameRn mb_assoc lrdr@(L _ rdr) = do { rdr_env <- getLocalRdrEnv ; case (mb_assoc, lookupLocalRdrEnv rdr_env rdr) of (Just _, Just n) -> return n -- Use the same Name as the parent class decl - _ -> newLocalBndrRn (L loc rdr) } + _ -> newLocalBndrRn lrdr } {- ********************************************************* * * @@ -1504,7 +1521,10 @@ To do that, we need to walk over a type and find its free type/kind variables. We preserve the left-to-right order of each variable occurrence. See Note [Ordering of implicit variables]. -Clients of this code can remove duplicates with nubL. +It is common for lists of free type variables to contain duplicates. For +example, in `f :: a -> a`, the free type variable list is [a, a]. When these +implicitly bound variables are brought into scope (with rnImplicitBndrs), +duplicates are removed with nubL. Note [Ordering of implicit variables] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1533,9 +1553,8 @@ the a in the code. Thus, GHC does ScopedSort on the variables. See Note [ScopedSort] in GHC.Core.Type. Implicitly bound variables are collected by any function which returns a -FreeKiTyVars, FreeKiTyVarsWithDups, or FreeKiTyVarsNoDups, which notably -includes the `extract-` family of functions (extractHsTysRdrTyVarsDups, -extractHsTyVarBndrsKVs, etc.). +FreeKiTyVars, which notably includes the `extract-` family of functions +(extractHsTysRdrTyVars, extractHsTyVarBndrsKVs, etc.). These functions thus promise to keep left-to-right ordering. Note [Implicit quantification in type synonyms] @@ -1621,18 +1640,13 @@ type checking. While viable, this would mean we'd end up accepting this: -} +-- A list of free type/kind variables, which can contain duplicates. -- See Note [Kind and type-variable binders] -- These lists are guaranteed to preserve left-to-right ordering of -- the types the variables were extracted from. See also -- Note [Ordering of implicit variables]. type FreeKiTyVars = [Located RdrName] --- | A 'FreeKiTyVars' list that is allowed to have duplicate variables. -type FreeKiTyVarsWithDups = FreeKiTyVars - --- | A 'FreeKiTyVars' list that contains no duplicate variables. -type FreeKiTyVarsNoDups = FreeKiTyVars - -- | Filter out any type and kind variables that are already in scope in the -- the supplied LocalRdrEnv. Note that this includes named wildcards, which -- look like perfectly ordinary type variables at this point. @@ -1650,46 +1664,32 @@ filterInScopeM vars inScope :: LocalRdrEnv -> RdrName -> Bool inScope rdr_env rdr = rdr `elemLocalRdrEnv` rdr_env -extract_tyarg :: LHsTypeArg GhcPs -> FreeKiTyVarsWithDups -> FreeKiTyVarsWithDups +extract_tyarg :: LHsTypeArg GhcPs -> FreeKiTyVars -> FreeKiTyVars extract_tyarg (HsValArg ty) acc = extract_lty ty acc extract_tyarg (HsTypeArg _ ki) acc = extract_lty ki acc extract_tyarg (HsArgPar _) acc = acc -extract_tyargs :: [LHsTypeArg GhcPs] -> FreeKiTyVarsWithDups -> FreeKiTyVarsWithDups +extract_tyargs :: [LHsTypeArg GhcPs] -> FreeKiTyVars -> FreeKiTyVars extract_tyargs args acc = foldr extract_tyarg acc args -extractHsTyArgRdrKiTyVarsDup :: [LHsTypeArg GhcPs] -> FreeKiTyVarsWithDups -extractHsTyArgRdrKiTyVarsDup args +extractHsTyArgRdrKiTyVars :: [LHsTypeArg GhcPs] -> FreeKiTyVars +extractHsTyArgRdrKiTyVars args = extract_tyargs args [] -- | 'extractHsTyRdrTyVars' finds the type/kind variables -- of a HsType/HsKind. -- It's used when making the @forall at s explicit. --- When the same name occurs multiple times in the types, only the first --- occurrence is returned. -- See Note [Kind and type-variable binders] -extractHsTyRdrTyVars :: LHsType GhcPs -> FreeKiTyVarsNoDups -extractHsTyRdrTyVars ty - = nubL (extractHsTyRdrTyVarsDups ty) - --- | 'extractHsTyRdrTyVarsDups' finds the type/kind variables --- of a HsType/HsKind. --- It's used when making the @forall at s explicit. --- When the same name occurs multiple times in the types, all occurrences --- are returned. -extractHsTyRdrTyVarsDups :: LHsType GhcPs -> FreeKiTyVarsWithDups -extractHsTyRdrTyVarsDups ty - = extract_lty ty [] +extractHsTyRdrTyVars :: LHsType GhcPs -> FreeKiTyVars +extractHsTyRdrTyVars ty = extract_lty ty [] -- | Extracts the free type/kind variables from the kind signature of a HsType. -- This is used to implicitly quantify over @k@ in @type T = Nothing :: Maybe k at . --- When the same name occurs multiple times in the type, only the first --- occurrence is returned, and the left-to-right order of variables is --- preserved. +-- The left-to-right order of variables is preserved. -- See Note [Kind and type-variable binders] and -- Note [Ordering of implicit variables] and -- Note [Implicit quantification in type synonyms]. -extractHsTyRdrTyVarsKindVars :: LHsType GhcPs -> FreeKiTyVarsNoDups +extractHsTyRdrTyVarsKindVars :: LHsType GhcPs -> FreeKiTyVars extractHsTyRdrTyVarsKindVars (L _ ty) = case ty of HsParTy _ ty -> extractHsTyRdrTyVarsKindVars ty @@ -1699,51 +1699,45 @@ extractHsTyRdrTyVarsKindVars (L _ ty) = -- | Extracts free type and kind variables from types in a list. -- When the same name occurs multiple times in the types, all occurrences -- are returned. -extractHsTysRdrTyVarsDups :: [LHsType GhcPs] -> FreeKiTyVarsWithDups -extractHsTysRdrTyVarsDups tys - = extract_ltys tys [] +extractHsTysRdrTyVars :: [LHsType GhcPs] -> FreeKiTyVars +extractHsTysRdrTyVars tys = extract_ltys tys [] -- Returns the free kind variables of any explicitly-kinded binders, returning -- variable occurrences in left-to-right order. -- See Note [Ordering of implicit variables]. -- NB: Does /not/ delete the binders themselves. --- However duplicates are removed -- E.g. given [k1, a:k1, b:k2] -- the function returns [k1,k2], even though k1 is bound here -extractHsTyVarBndrsKVs :: [LHsTyVarBndr flag GhcPs] -> FreeKiTyVarsNoDups -extractHsTyVarBndrsKVs tv_bndrs - = nubL (extract_hs_tv_bndrs_kvs tv_bndrs) +extractHsTyVarBndrsKVs :: [LHsTyVarBndr flag GhcPs] -> FreeKiTyVars +extractHsTyVarBndrsKVs tv_bndrs = extract_hs_tv_bndrs_kvs tv_bndrs -- Returns the free kind variables in a type family result signature, returning -- variable occurrences in left-to-right order. -- See Note [Ordering of implicit variables]. -extractRdrKindSigVars :: LFamilyResultSig GhcPs -> [Located RdrName] +extractRdrKindSigVars :: LFamilyResultSig GhcPs -> FreeKiTyVars extractRdrKindSigVars (L _ resultSig) = case resultSig of KindSig _ k -> extractHsTyRdrTyVars k TyVarSig _ (L _ (KindedTyVar _ _ _ k)) -> extractHsTyRdrTyVars k _ -> [] -- | Get type/kind variables mentioned in the kind signature, preserving --- left-to-right order and without duplicates: +-- left-to-right order: -- -- * data T a (b :: k1) :: k2 -> k1 -> k2 -> Type -- result: [k2,k1] -- * data T a (b :: k1) -- result: [] -- -- See Note [Ordering of implicit variables]. -extractDataDefnKindVars :: HsDataDefn GhcPs -> FreeKiTyVarsNoDups +extractDataDefnKindVars :: HsDataDefn GhcPs -> FreeKiTyVars extractDataDefnKindVars (HsDataDefn { dd_kindSig = ksig }) = maybe [] extractHsTyRdrTyVars ksig -extract_lctxt :: LHsContext GhcPs - -> FreeKiTyVarsWithDups -> FreeKiTyVarsWithDups +extract_lctxt :: LHsContext GhcPs -> FreeKiTyVars -> FreeKiTyVars extract_lctxt ctxt = extract_ltys (unLoc ctxt) -extract_ltys :: [LHsType GhcPs] - -> FreeKiTyVarsWithDups -> FreeKiTyVarsWithDups +extract_ltys :: [LHsType GhcPs] -> FreeKiTyVars -> FreeKiTyVars extract_ltys tys acc = foldr extract_lty acc tys -extract_lty :: LHsType GhcPs - -> FreeKiTyVarsWithDups -> FreeKiTyVarsWithDups +extract_lty :: LHsType GhcPs -> FreeKiTyVars -> FreeKiTyVars extract_lty (L _ ty) acc = case ty of HsTyVar _ _ ltv -> extract_tv ltv acc @@ -1784,15 +1778,15 @@ extract_lty (L _ ty) acc HsWildCardTy {} -> acc extractHsTvBndrs :: [LHsTyVarBndr flag GhcPs] - -> FreeKiTyVarsWithDups -- Free in body - -> FreeKiTyVarsWithDups -- Free in result + -> FreeKiTyVars -- Free in body + -> FreeKiTyVars -- Free in result extractHsTvBndrs tv_bndrs body_fvs = extract_hs_tv_bndrs tv_bndrs [] body_fvs extract_hs_tv_bndrs :: [LHsTyVarBndr flag GhcPs] - -> FreeKiTyVarsWithDups -- Accumulator - -> FreeKiTyVarsWithDups -- Free in body - -> FreeKiTyVarsWithDups + -> FreeKiTyVars -- Accumulator + -> FreeKiTyVars -- Free in body + -> FreeKiTyVars -- In (forall (a :: Maybe e). a -> b) we have -- 'a' is bound by the forall -- 'b' is a free type variable @@ -1807,24 +1801,28 @@ extract_hs_tv_bndrs tv_bndrs acc_vars body_vars = new_vars ++ acc_vars bndr_vars = extract_hs_tv_bndrs_kvs tv_bndrs tv_bndr_rdrs = map hsLTyVarLocName tv_bndrs -extract_hs_tv_bndrs_kvs :: [LHsTyVarBndr flag GhcPs] -> FreeKiTyVarsWithDups +extract_hs_tv_bndrs_kvs :: [LHsTyVarBndr flag GhcPs] -> FreeKiTyVars -- Returns the free kind variables of any explicitly-kinded binders, returning -- variable occurrences in left-to-right order. -- See Note [Ordering of implicit variables]. -- NB: Does /not/ delete the binders themselves. --- Duplicates are /not/ removed -- E.g. given [k1, a:k1, b:k2] -- the function returns [k1,k2], even though k1 is bound here extract_hs_tv_bndrs_kvs tv_bndrs = foldr extract_lty [] [k | L _ (KindedTyVar _ _ _ k) <- tv_bndrs] -extract_tv :: Located RdrName - -> [Located RdrName] -> [Located RdrName] +extract_tv :: Located RdrName -> FreeKiTyVars -> FreeKiTyVars extract_tv tv acc = if isRdrTyVar (unLoc tv) then tv:acc else acc --- Deletes duplicates in a list of Located things. +-- Deletes duplicates in a list of Located things. This is used to: +-- +-- * Delete duplicate occurrences of implicitly bound type/kind variables when +-- bringing them into scope (in rnImplicitBndrs). +-- +-- * Delete duplicate occurrences of named wildcards (in rn_hs_sig_wc_type and +-- rnHsWcType). -- -- Importantly, this function is stable with respect to the original ordering -- of things in the list. This is important, as it is a property that GHC @@ -1838,9 +1836,9 @@ nubL = nubBy eqLocated -- already in scope, or are explicitly bound in the binder. filterFreeVarsToBind :: FreeKiTyVars -- ^ Explicitly bound here - -> FreeKiTyVarsWithDups + -> FreeKiTyVars -- ^ Potential implicit binders - -> FreeKiTyVarsWithDups + -> FreeKiTyVars -- ^ Final implicit binders filterFreeVarsToBind bndrs = filterOut is_in_scope -- Make sure to list the binder kvs before the body kvs, as mandated by ===================================== compiler/GHC/Rename/Module.hs ===================================== @@ -664,7 +664,7 @@ rnClsInstDecl (ClsInstDecl { cid_poly_ty = inst_ty, cid_binds = mbinds rnFamInstEqn :: HsDocContext -> AssocTyFamInfo - -> [Located RdrName] + -> FreeKiTyVars -- ^ Kind variables from the equation's RHS to be implicitly bound -- if no explicit forall. -> FamInstEqn GhcPs rhs @@ -676,16 +676,7 @@ rnFamInstEqn doc atfi rhs_kvars , feqn_pats = pats , feqn_fixity = fixity , feqn_rhs = payload }}) rn_payload - = do { let mb_cls = case atfi of - NonAssocTyFamEqn -> Nothing - AssocTyFamDeflt cls -> Just cls - AssocTyFamInst cls _ -> Just cls - ; tycon' <- lookupFamInstName mb_cls tycon - ; let pat_kity_vars_with_dups = extractHsTyArgRdrKiTyVarsDup pats - -- Use the "...Dups" form because it's needed - -- below to report unused binder on the LHS - - ; let bndrs = fromMaybe [] mb_bndrs + = do { tycon' <- lookupFamInstName mb_cls tycon -- all_imp_vars represent the implicitly bound type variables. This is -- empty if we have an explicit `forall` (see @@ -713,48 +704,45 @@ rnFamInstEqn doc atfi rhs_kvars -- No need to filter out explicit binders (the 'mb_bndrs = Just -- explicit_bndrs' case) because there must be none if we're going -- to implicitly bind anything, per the previous comment. - nubL $ pat_kity_vars_with_dups ++ rhs_kvars - ; all_imp_var_names <- mapM (newTyVarNameRn mb_cls) all_imp_vars - - -- All the free vars of the family patterns - -- with a sensible binding location - ; ((bndrs', pats', payload'), fvs) - <- bindLocalNamesFV all_imp_var_names $ - bindLHsTyVarBndrs doc (Just $ inHsDocContext doc) - Nothing bndrs $ \bndrs' -> - -- Note: If we pass mb_cls instead of Nothing here, - -- bindLHsTyVarBndrs will use class variables for any names - -- the user meant to bring in scope here. This is an explicit - -- forall, so we want fresh names, not class variables. - -- Thus: always pass Nothing - do { (pats', pat_fvs) <- rnLHsTypeArgs (FamPatCtx tycon) pats - ; (payload', rhs_fvs) <- rn_payload doc payload - - -- Report unused binders on the LHS - -- See Note [Unused type variables in family instances] - ; let groups :: [NonEmpty (Located RdrName)] - groups = equivClasses cmpLocated $ - pat_kity_vars_with_dups - ; nms_dups <- mapM (lookupOccRn . unLoc) $ - [ tv | (tv :| (_:_)) <- groups ] - -- Add to the used variables - -- a) any variables that appear *more than once* on the LHS - -- e.g. F a Int a = Bool - -- b) for associated instances, the variables - -- of the instance decl. See - -- Note [Unused type variables in family instances] - ; let nms_used = extendNameSetList rhs_fvs $ - inst_tvs ++ nms_dups - inst_tvs = case atfi of - NonAssocTyFamEqn -> [] - AssocTyFamDeflt _ -> [] - AssocTyFamInst _ inst_tvs -> inst_tvs - all_nms = all_imp_var_names ++ hsLTyVarNames bndrs' - ; warnUnusedTypePatterns all_nms nms_used - - ; return ((bndrs', pats', payload'), rhs_fvs `plusFV` pat_fvs) } - - ; let all_fvs = fvs `addOneFV` unLoc tycon' + pat_kity_vars_with_dups ++ rhs_kvars + + ; rnImplicitBndrs mb_cls all_imp_vars $ \all_imp_var_names' -> + bindLHsTyVarBndrs doc (Just $ inHsDocContext doc) + Nothing (fromMaybe [] mb_bndrs) $ \bndrs' -> + -- Note: If we pass mb_cls instead of Nothing here, + -- bindLHsTyVarBndrs will use class variables for any names + -- the user meant to bring in scope here. This is an explicit + -- forall, so we want fresh names, not class variables. + -- Thus: always pass Nothing + do { (pats', pat_fvs) <- rnLHsTypeArgs (FamPatCtx tycon) pats + ; (payload', rhs_fvs) <- rn_payload doc payload + + -- Report unused binders on the LHS + -- See Note [Unused type variables in family instances] + ; let -- The SrcSpan that rnImplicitBndrs will attach to each Name will + -- span the entire type family instance, which will be reflected in + -- -Wunused-type-patterns warnings. We can be a little more precise + -- than that by pointing to the LHS of the instance instead, which + -- is what lhs_loc corresponds to. + all_imp_var_names = map (`setNameLoc` lhs_loc) all_imp_var_names' + + groups :: [NonEmpty (Located RdrName)] + groups = equivClasses cmpLocated $ + pat_kity_vars_with_dups + ; nms_dups <- mapM (lookupOccRn . unLoc) $ + [ tv | (tv :| (_:_)) <- groups ] + -- Add to the used variables + -- a) any variables that appear *more than once* on the LHS + -- e.g. F a Int a = Bool + -- b) for associated instances, the variables + -- of the instance decl. See + -- Note [Unused type variables in family instances] + ; let nms_used = extendNameSetList rhs_fvs $ + inst_tvs ++ nms_dups + all_nms = all_imp_var_names ++ hsLTyVarNames bndrs' + ; warnUnusedTypePatterns all_nms nms_used + + ; let all_fvs = (rhs_fvs `plusFV` pat_fvs) `addOneFV` unLoc tycon' -- type instance => use, hence addOneFV ; return (HsIB { hsib_ext = all_imp_var_names -- Note [Wildcards in family instances] @@ -765,7 +753,33 @@ rnFamInstEqn doc atfi rhs_kvars , feqn_pats = pats' , feqn_fixity = fixity , feqn_rhs = payload' } }, - all_fvs) } + all_fvs) } } + where + -- The parent class, if we are dealing with an associated type family + -- instance. + mb_cls = case atfi of + NonAssocTyFamEqn -> Nothing + AssocTyFamDeflt cls -> Just cls + AssocTyFamInst cls _ -> Just cls + + -- The type variables from the instance head, if we are dealing with an + -- associated type family instance. + inst_tvs = case atfi of + NonAssocTyFamEqn -> [] + AssocTyFamDeflt _ -> [] + AssocTyFamInst _ inst_tvs -> inst_tvs + + pat_kity_vars_with_dups = extractHsTyArgRdrKiTyVars pats + -- It is crucial that extractHsTyArgRdrKiTyVars return + -- duplicate occurrences, since they're needed to help + -- determine unused binders on the LHS. + + -- The SrcSpan of the LHS of the instance. For example, lhs_loc would be + -- the highlighted part in the example below: + -- + -- type instance F a b c = Either a b + -- ^^^^^^^ + lhs_loc = foldr combineSrcSpans (getLoc tycon) (map lhsTypeArgSrcSpan pats) rnTyFamInstDecl :: AssocTyFamInfo -> TyFamInstDecl GhcPs @@ -2116,12 +2130,12 @@ rnConDecl decl@(ConDeclGADT { con_names = names -- See #14808. ; implicit_bndrs <- forAllOrNothing explicit_forall $ extractHsTvBndrs explicit_tkvs - $ extractHsTysRdrTyVarsDups (theta ++ arg_tys ++ [res_ty]) + $ extractHsTysRdrTyVars (theta ++ arg_tys ++ [res_ty]) ; let ctxt = ConDeclCtx new_names mb_ctxt = Just (inHsDocContext ctxt) - ; rnImplicitBndrs implicit_bndrs $ \ implicit_tkvs -> + ; rnImplicitBndrs Nothing implicit_bndrs $ \ implicit_tkvs -> bindLHsTyVarBndrs ctxt mb_ctxt Nothing explicit_tkvs $ \ explicit_tkvs -> do { (new_cxt, fvs1) <- rnMbContext ctxt mcxt ; (new_args, fvs2) <- rnConDeclDetails (unLoc (head new_names)) ctxt args ===================================== compiler/GHC/Tc/Gen/Splice.hs ===================================== @@ -1431,7 +1431,7 @@ reifyInstances th_nm th_tys -- must error before proceeding to typecheck the -- renamed type, as that will result in GHC -- internal errors (#13837). - bindLRdrNames tv_rdrs $ \ tv_names -> + rnImplicitBndrs Nothing tv_rdrs $ \ tv_names -> do { (rn_ty, fvs) <- rnLHsType doc rdr_ty ; return ((tv_names, rn_ty), fvs) } ; (_tvs, ty) ===================================== testsuite/tests/indexed-types/should_compile/ExplicitForAllFams2.stderr ===================================== @@ -5,8 +5,8 @@ ExplicitForAllFams2.hs:34:10: warning: [-Wunused-type-patterns] ExplicitForAllFams2.hs:35:10: warning: [-Wunused-type-patterns] Defined but not used on the right hand side: type variable ‘a’ -ExplicitForAllFams2.hs:38:7: warning: [-Wunused-type-patterns] +ExplicitForAllFams2.hs:38:3: warning: [-Wunused-type-patterns] Defined but not used on the right hand side: type variable ‘t’ -ExplicitForAllFams2.hs:39:6: warning: [-Wunused-type-patterns] +ExplicitForAllFams2.hs:39:3: warning: [-Wunused-type-patterns] Defined but not used on the right hand side: type variable ‘a’ ===================================== testsuite/tests/indexed-types/should_compile/T16356_Compile2.stderr ===================================== @@ -1,8 +1,8 @@ -T16356_Compile2.hs:10:12: warning: [-Wunused-type-patterns] +T16356_Compile2.hs:10:8: warning: [-Wunused-type-patterns] Defined but not used on the right hand side: type variable ‘j’ -T16356_Compile2.hs:10:17: warning: [-Wunused-type-patterns] +T16356_Compile2.hs:10:8: warning: [-Wunused-type-patterns] Defined but not used on the right hand side: type variable ‘a’ T16356_Compile2.hs:13:15: warning: [-Wunused-type-patterns] ===================================== testsuite/tests/indexed-types/should_compile/T16632.stderr ===================================== @@ -1,6 +1,6 @@ -T16632.hs:5:22: warning: [-Wunused-type-patterns] +T16632.hs:5:15: warning: [-Wunused-type-patterns] Defined but not used on the right hand side: type variable ‘b’ | 5 | type instance F Char b Int = () - | ^ + | ^^^^^^^^^^^^ ===================================== testsuite/tests/indexed-types/should_compile/UnusedTyVarWarnings.stderr ===================================== @@ -1,12 +1,12 @@ -UnusedTyVarWarnings.hs:8:7: warning: [-Wunused-type-patterns] +UnusedTyVarWarnings.hs:8:3: warning: [-Wunused-type-patterns] Defined but not used on the right hand side: type variable ‘b’ -UnusedTyVarWarnings.hs:11:20: warning: [-Wunused-type-patterns] +UnusedTyVarWarnings.hs:11:15: warning: [-Wunused-type-patterns] Defined but not used on the right hand side: type variable ‘b’ -UnusedTyVarWarnings.hs:27:5: warning: [-Wunused-type-patterns] +UnusedTyVarWarnings.hs:27:3: warning: [-Wunused-type-patterns] Defined but not used on the right hand side: type variable ‘a’ -UnusedTyVarWarnings.hs:33:19: warning: [-Wunused-type-patterns] +UnusedTyVarWarnings.hs:33:15: warning: [-Wunused-type-patterns] Defined but not used on the right hand side: type variable ‘b’ ===================================== testsuite/tests/indexed-types/should_compile/UnusedTyVarWarningsNamedWCs.stderr ===================================== @@ -1,12 +1,12 @@ -UnusedTyVarWarningsNamedWCs.hs:8:7: warning: [-Wunused-type-patterns] +UnusedTyVarWarningsNamedWCs.hs:8:3: warning: [-Wunused-type-patterns] Defined but not used on the right hand side: type variable ‘b’ -UnusedTyVarWarningsNamedWCs.hs:11:20: warning: [-Wunused-type-patterns] +UnusedTyVarWarningsNamedWCs.hs:11:15: warning: [-Wunused-type-patterns] Defined but not used on the right hand side: type variable ‘b’ -UnusedTyVarWarningsNamedWCs.hs:27:5: warning: [-Wunused-type-patterns] +UnusedTyVarWarningsNamedWCs.hs:27:3: warning: [-Wunused-type-patterns] Defined but not used on the right hand side: type variable ‘a’ -UnusedTyVarWarningsNamedWCs.hs:33:19: warning: [-Wunused-type-patterns] +UnusedTyVarWarningsNamedWCs.hs:33:15: warning: [-Wunused-type-patterns] Defined but not used on the right hand side: type variable ‘b’ ===================================== testsuite/tests/indexed-types/should_fail/T17008a.stderr ===================================== @@ -1,5 +1,5 @@ -T17008a.hs:11:21: error: +T17008a.hs:11:3: error: • Type variable ‘a1’ is mentioned in the RHS, but not bound on the LHS of the family instance The real LHS (expanding synonyms) is: F @a2 x ===================================== testsuite/tests/indexed-types/should_fail/T7536.stderr ===================================== @@ -1,5 +1,5 @@ -T7536.hs:8:21: error: +T7536.hs:8:15: error: • Type variable ‘a’ is mentioned in the RHS, but not bound on the LHS of the family instance The real LHS (expanding synonyms) is: TF Int ===================================== testsuite/tests/polykinds/T11203.stderr ===================================== @@ -1,4 +1,4 @@ -T11203.hs:7:24: error: +T11203.hs:7:1: error: • Different names for the same type variable: ‘k1’ and ‘k2’ • In the data declaration for ‘Q’ ===================================== testsuite/tests/polykinds/T11821a.stderr ===================================== @@ -1,4 +1,4 @@ -T11821a.hs:4:31: error: +T11821a.hs:4:1: error: • Different names for the same type variable: ‘k1’ and ‘k2’ • In the type declaration for ‘SameKind’ ===================================== testsuite/tests/typecheck/should_fail/T17566b.stderr ===================================== @@ -1,4 +1,4 @@ -T17566b.hs:7:17: error: +T17566b.hs:7:3: error: • Different names for the same type variable: ‘k1’ and ‘k2’ • In the class declaration for ‘C’ ===================================== testsuite/tests/typecheck/should_fail/T17566c.stderr ===================================== @@ -1,6 +1,6 @@ -T17566c.hs:11:23: error: +T17566c.hs:11:3: error: • Different names for the same type variable: - ‘k’ bound at T17566c.hs:10:17 - ‘k’ bound at T17566c.hs:11:23 + ‘k’ bound at T17566c.hs:10:3 + ‘k’ bound at T17566c.hs:11:3 • In the class declaration for ‘C2’ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5d45579fa1258a7626c554313d672f0367ed63d6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5d45579fa1258a7626c554313d672f0367ed63d6 You're receiving 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 27 22:07:56 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 27 May 2020 18:07:56 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/bump-win32-tarballs Message-ID: <5ecee4bc3a503_6e263f9ecd30d12021006b4@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/bump-win32-tarballs at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/bump-win32-tarballs You're receiving 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 27 22:08:24 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 27 May 2020 18:08:24 -0400 Subject: [Git][ghc/ghc][wip/bump-win32-tarballs] Windows: Bump Windows toolchain to 0.2 Message-ID: <5ecee4d88d1c8_6e263f9ed652f4cc21010d5@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/bump-win32-tarballs at Glasgow Haskell Compiler / GHC Commits: 47732f5a by Ben Gamari at 2020-05-27T18:08:21-04:00 Windows: Bump Windows toolchain to 0.2 - - - - - 1 changed file: - mk/get-win32-tarballs.py Changes: ===================================== mk/get-win32-tarballs.py ===================================== @@ -7,7 +7,7 @@ import subprocess import argparse from sys import stderr -TARBALL_VERSION = '0.1' +TARBALL_VERSION = '0.2' BASE_URL = "https://downloads.haskell.org/ghc/mingw/{}".format(TARBALL_VERSION) DEST = Path('ghc-tarballs/mingw-w64') ARCHS = ['i686', 'x86_64', 'sources'] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/47732f5a8d9b6af2a759a8ed0426e666804858f4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/47732f5a8d9b6af2a759a8ed0426e666804858f4 You're receiving 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 27 22:12:34 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 27 May 2020 18:12:34 -0400 Subject: [Git][ghc/ghc][wip/T18234] 2 commits: gitlab-ci: Make names more consistent Message-ID: <5ecee5d2cfa4e_6e263f9ed652f4cc2102984@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18234 at Glasgow Haskell Compiler / GHC Commits: c5ce6d56 by Ben Gamari at 2020-05-27T18:12:22-04:00 gitlab-ci: Make names more consistent - - - - - 17d0b228 by Ben Gamari at 2020-05-27T18:12:25-04:00 gitlab-ci: Introduce a nightly cross-compilation job This adds a job to test cross-compilation from x86-64 to AArch64 with Hadrian. Fixes #18234. - - - - - 2 changed files: - .gitlab-ci.yml - .gitlab/ci.sh 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: 6223fe0b5942f4fa35bdec92c74566cf195bfb42 + DOCKER_REV: ba119705df5222fe74208a85019cb980e2c4318f # Sequential version number capturing the versions of all tools fetched by # .gitlab/ci.sh. @@ -178,7 +178,7 @@ lint-release-changelogs: # Validation via Pipelines (hadrian) ############################################################ -.validate-hadrian: +.build-hadrian: variables: FLAVOUR: "validate" script: @@ -198,11 +198,8 @@ lint-release-changelogs: - ghc.tar.xz - junit.xml -.validate-linux-hadrian: - extends: .validate-hadrian - image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV" - variables: - TEST_ENV: "x86_64-linux-deb9-hadrian" +.build-linux-hadrian: + extends: .build-hadrian before_script: # workaround for docker permissions - sudo chown ghc:ghc -R . @@ -212,20 +209,53 @@ lint-release-changelogs: - "git fetch https://gitlab.haskell.org/ghc/ghc-performance-notes.git refs/notes/perf:refs/notes/perf || true" after_script: - .gitlab/ci.sh clean + +.build-x86_64-linux-deb9-hadrian: + extends: .build-linux-hadrian + image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV" tags: - x86_64-linux validate-x86_64-linux-deb9-hadrian: - extends: .validate-linux-hadrian + extends: .build-x86_64-linux-deb9-hadrian stage: build + variables: + TEST_ENV: "x86_64-linux-deb9-hadrian" validate-x86_64-linux-deb9-unreg-hadrian: - extends: .validate-linux-hadrian + extends: .build-x86_64-linux-deb9-hadrian stage: full-build variables: CONFIGURE_ARGS: --enable-unregisterised TEST_ENV: "x86_64-linux-deb9-unreg-hadrian" +.build-x86_64-linux-deb10-hadrian: + extends: .build-hadrian + image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV" + before_script: + # workaround for docker permissions + - sudo chown ghc:ghc -R . + - git submodule sync --recursive + - git submodule update --init --recursive + - git checkout .gitmodules + - "git fetch https://gitlab.haskell.org/ghc/ghc-performance-notes.git refs/notes/perf:refs/notes/perf || true" + after_script: + - .gitlab/ci.sh clean + tags: + - x86_64-linux + +nightly-x86_64-linux-deb10-hadrian-cross-aarch64: + #<<: *nightly + stage: build + extends: .build-x86_64-linux-deb10-hadrian + variables: + CROSS_TARGET: "aarch64-linux-gnu" + + +############################################################ +# GHC-in-GHCi (Hadrian) +############################################################ + hadrian-ghc-in-ghci: stage: quick-build image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV" @@ -327,7 +357,7 @@ release-x86_64-freebsd: stage: full-build .build-x86_64-freebsd-hadrian: - extends: .validate-hadrian + extends: .build-hadrian stage: full-build tags: - x86_64-freebsd @@ -678,7 +708,7 @@ release-x86_64-linux-deb8: ################################# .build-x86_64-linux-alpine-hadrian: - extends: .validate-linux-hadrian + extends: .build-linux-hadrian stage: full-build image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-alpine:$DOCKER_REV" # There are currently a few failing tests ===================================== .gitlab/ci.sh ===================================== @@ -80,6 +80,7 @@ Modes: Environment variables: + CROSS_TARGET Triple of cross-compilation target. MSYSTEM (Windows-only) Which platform to build form (MINGW64 or MINGW32). Environment variables determining build configuration of Make system: @@ -114,11 +115,11 @@ EOF function mingw_init() { case "$MSYSTEM" in MINGW32) - triple="i386-unknown-mingw32" + target_triple="i386-unknown-mingw32" boot_triple="i386-unknown-mingw32" # triple of bootstrap GHC ;; MINGW64) - triple="x86_64-unknown-mingw32" + target_triple="x86_64-unknown-mingw32" boot_triple="x86_64-unknown-mingw32" # triple of bootstrap GHC ;; *) @@ -375,8 +376,8 @@ function configure() { end_section "booting" local target_args="" - if [[ -n "$triple" ]]; then - target_args="--target=$triple" + if [[ -n "$target_triple" ]]; then + target_args="--target=$target_triple" fi start_section "configuring" @@ -415,6 +416,11 @@ function push_perf_notes() { } function test_make() { + if [ -n "$CROSS_TARGET" ]; then + info "Can't test cross-compiled build." + return + fi + run "$MAKE" test_bindist TEST_PREP=YES run "$MAKE" V=0 test \ THREADS="$cores" \ @@ -432,6 +438,11 @@ function build_hadrian() { } function test_hadrian() { + if [ -n "$CROSS_TARGET" ]; then + info "Can't test cross-compiled build." + return + fi + cd _build/bindist/ghc-*/ run ./configure --prefix="$TOP"/_build/install run "$MAKE" install @@ -486,6 +497,11 @@ case "$(uname)" in *) fail "uname $(uname) is not supported" ;; esac +if [ -n "$CROSS_TARGET" ]; then + info "Cross-compiling for $CROSS_TARGET..." + target_triple="$CROSS_TARGET" +fi + set_toolchain_paths case $1 in View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e5a0d8a5536c0db649642044a33c0d73e6c28e62...17d0b228d440439aa03a02dae708ae5b559510fd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e5a0d8a5536c0db649642044a33c0d73e6c28e62...17d0b228d440439aa03a02dae708ae5b559510fd You're receiving 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 27 22:28:06 2020 From: gitlab at gitlab.haskell.org (Alan Zimmerman) Date: Wed, 27 May 2020 18:28:06 -0400 Subject: [Git][ghc/ghc][wip/az/exactprint] 2 commits: Proof of Concept implementation of in-tree API Annotations Message-ID: <5ecee976ae59b_6e263f9e9e7046b821080b3@gitlab.haskell.org.mail> Alan Zimmerman pushed to branch wip/az/exactprint at Glasgow Haskell Compiler / GHC Commits: 24f83adc by Alan Zimmerman at 2020-05-25T22:27:33+01:00 Proof of Concept implementation of in-tree API Annotations This MR introduces a possible machinery to introduce API Annotations into the TTG extension points. It is intended to be a concrete example for discussion. It still needs to process comments. ---- Work in progress, adding more TTG extensions for annotations. And fixing ppr round-trip tests by being able to blank out in-tree annotations, as done with SrcSpans. This is needed for the case of class Foo a where for which current ppr does not print the "where". Rename AA to AddApiAnn and AA to AddAnn Add XConPatIn and XConPatOut Rebase ---- First pass at bringing in LocatedA for API anns in locations Treatment of ECP in parsing is provisional at this stage, leads to some horribly stuff in Parser.y and RdrHsSyn. It is an extensive but not invasive change. I think (AZ). Locally it reports some parsing tests using less memory. Add ApiAnns to the HsExpr data structure. rebase. Change HsMatchContext and HsStmtContext to use an id, not a GhcPass parameter. Add ApiAnns to Hs/Types Rebase Rebased 2020-03-25 WIP on in-tree annotations Includes updating HsModule Imports LocateA ImportDecl so we can hang AnnSemi off it A whole bunch of stuff more InjectivityAnn and FamEqn now have annotations in them Add annotations to context srcspan ---- In-tree annotations: LHsDecl and LHsBind LocatedA ---- WIP on in-tree annotations ---- in-tree annotations: LHsType is now LocatedA ---- FunDeps is now also a HS data type ---- WIP. Added LocatedA to Pat, Expr, Decl And worked some more through Parser.y ---- LStmt now Located ---- Finished working through Parser.y, tests seem ok failures relate to annotations. Adding test infrastructure for check-exact Like check-ppr, but checking for an exact reproduction of the parsed source file. Starting to work on actual exact printer - - - - - fe6c414e by Alan Zimmerman at 2020-05-27T23:26:52+01:00 Bring in ApiAnnName As an alternative for LocatedA, to be used for names only. Carrying extra name adornments, such as locations of backticks, parens, etc. - - - - - 19 changed files: - compiler/GHC/Data/BooleanFormula.hs - compiler/GHC/Data/OrdList.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Hs.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Dump.hs - + compiler/GHC/Hs/Exact.hs - compiler/GHC/Hs/Expr.hs - compiler/GHC/Hs/Expr.hs-boot - compiler/GHC/Hs/Extension.hs - compiler/GHC/Hs/ImpExp.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Pat.hs - compiler/GHC/Hs/Stats.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/095800f7d9237d48dbcdaa90b92e8d07789b3d57...fe6c414e21eaa1ba7f0887c542e61f9c05f09565 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/095800f7d9237d48dbcdaa90b92e8d07789b3d57...fe6c414e21eaa1ba7f0887c542e61f9c05f09565 You're receiving 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 27 22:29:34 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 27 May 2020 18:29:34 -0400 Subject: [Git][ghc/ghc][wip/T14781] 2 commits: users-guide: Note change in getNumProcessors in users guide Message-ID: <5ecee9ced003f_6e263f9ed652f4cc21086b4@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T14781 at Glasgow Haskell Compiler / GHC Commits: c5028dd0 by Ben Gamari at 2020-05-27T18:28:04-04:00 users-guide: Note change in getNumProcessors in users guide - - - - - c0f4bcc0 by Ben Gamari at 2020-05-27T18:29:24-04:00 rts: Drop compatibility shims for Windows Vista We can now assume that the thread and processor group interfaces are available. - - - - - 5 changed files: - docs/users_guide/8.12.1-notes.rst - docs/users_guide/using-concurrent.rst - hadrian/src/Settings/Packages.hs - rts/ghc.mk - rts/win32/OSThreads.c Changes: ===================================== docs/users_guide/8.12.1-notes.rst ===================================== @@ -17,7 +17,7 @@ Highlights digit improvements in runtime for inner loops. In the mean this improved runtime by about 0.8%. For details - see ticket #17823. + see ticket :ghc-ticket:`17823`. Full details ------------ @@ -95,7 +95,7 @@ Language effectively allows users to choose which variables can or can't be instantiated through visible type application. More information can be found here: :ref:`Manually-defining-inferred-variables`. - + Compiler ~~~~~~~~ @@ -105,11 +105,18 @@ 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) + escaping spaces in file names with a backslash. (:ghc-ticket:`18027`) Runtime system ~~~~~~~~~~~~~~ +- :rts-flag:`-N` without a count now tries to respect the number of processors + in the process's affinity mask, making GHC's behavior more predictable in + containerized settings (:ghc-ticket:`14781`). + +- Support for Windows Vista has been dropped. GHC-compiled programs now require + Windows 7 or later. + Template Haskell ~~~~~~~~~~~~~~~~ ===================================== docs/users_guide/using-concurrent.rst ===================================== @@ -111,6 +111,7 @@ There are two ways to run a program on multiple processors: call use the RTS :rts-flag:`-N ⟨x⟩` options. .. rts-flag:: -N ⟨x⟩ + -N -maxN ⟨x⟩ Use ⟨x⟩ simultaneous threads when running the program. ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -442,4 +442,4 @@ rtsWarnings = mconcat -- and also centralizes the versioning. -- | Minimum supported Windows version. windowsVersion :: String -windowsVersion = "0x06000100" +windowsVersion = "0x06010000" ===================================== rts/ghc.mk ===================================== @@ -25,7 +25,7 @@ rts_VERSION = 1.0 # If we're compiling on windows, enforce that we only support Vista SP1+ # Adding this here means it doesn't have to be done in individual .c files # and also centralizes the versioning. -rts_WINVER = 0x06000100 +rts_WINVER = 0x06010000 # merge GhcLibWays and GhcRTSWays but strip out duplicates rts_WAYS = $(GhcLibWays) $(filter-out $(GhcLibWays),$(GhcRTSWays)) ===================================== 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)); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/876285e76dd44039bc37bd1c8a8b24f8c86b6f83...c0f4bcc07d887fd932e10bff91b372b7142b7050 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/876285e76dd44039bc37bd1c8a8b24f8c86b6f83...c0f4bcc07d887fd932e10bff91b372b7142b7050 You're receiving 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 27 22:32:37 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Wed, 27 May 2020 18:32:37 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 12 commits: core-spec: Modify file paths according to new module hierarchy Message-ID: <5eceea85eb134_6e263f9ecd30d12021116b3@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: ede24126 by Takenobu Tani at 2020-05-27T00:13:55-04:00 core-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Core.hs <= coreSyn/CoreSyn.hs * GHC/Core/Coercion.hs <= types/Coercion.hs * GHC/Core/Coercion/Axiom.hs <= types/CoAxiom.hs * GHC/Core/Coercion/Opt.hs <= types/OptCoercion.hs * GHC/Core/DataCon.hs <= basicTypes/DataCon.hs * GHC/Core/FamInstEnv.hs <= types/FamInstEnv.hs * GHC/Core/Lint.hs <= coreSyn/CoreLint.hs * GHC/Core/Subst.hs <= coreSyn/CoreSubst.hs * GHC/Core/TyCo/Rep.hs <= types/TyCoRep.hs * GHC/Core/TyCon.hs <= types/TyCon.hs * GHC/Core/Type.hs <= types/Type.hs * GHC/Core/Unify.hs <= types/Unify.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/Var.hs <= basicTypes/Var.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [skip ci] - - - - - 04750304 by Ben Gamari at 2020-05-27T00:14:33-04:00 eventlog: Fix racy flushing Previously no attempt was made to avoid multiple threads writing their capability-local eventlog buffers to the eventlog writer simultaneously. This could result in multiple eventlog streams being interleaved. Fix this by documenting that the EventLogWriter's write() and flush() functions may be called reentrantly and fix the default writer to protect its FILE* by a mutex. Fixes #18210. - - - - - d6203f24 by Joshua Price at 2020-05-27T00:15:17-04:00 Make `identifier` parse unparenthesized `->` (#18060) - - - - - f7338dd8 by Ben Gamari at 2020-05-27T18:32:19-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 - - - - - 2c422a8b by Ben Gamari at 2020-05-27T18:32:19-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 haddock.Cabal haddock.base haddock.compiler - - - - - 836bd057 by Vladislav Zavialov at 2020-05-27T18:32:19-04:00 Add Semigroup/Monoid for Q (#18123) - - - - - 3f5b09a1 by Xavier Denis at 2020-05-27T18:32:26-04:00 Fix #18071 Run the core linter on candidate instances to ensure they are well-kinded. Better handle quantified constraints by using a CtWanted to avoid having unsolved constraints thrown away at the end by the solver. - - - - - 87a87ad9 by Sebastian Graf at 2020-05-27T18:32:27-04:00 FloatOut: Only eta-expand dead-end RHS if arity will increase (#18231) Otherwise we risk turning trivial RHS into non-trivial RHS, introducing unnecessary bindings in the next Simplifier run, resulting in more churn. Fixes #18231. - - - - - 993c66a6 by Sebastian Graf at 2020-05-27T18:32:27-04:00 DmdAnal: Recognise precise exceptions from case alternatives (#18086) Consider ```hs m :: IO () m = do putStrLn "foo" error "bar" ``` `m` (from #18086) always throws a (precise or imprecise) exception or diverges. Yet demand analysis infers `<L,A>` as demand signature instead of `<L,A>x` for it. That's because the demand analyser sees `putStrLn` occuring in a case scrutinee and decides that it has to `deferAfterPreciseException`, because `putStrLn` throws a precise exception on some control flow paths. This will mask the `botDiv` `Divergence`of the single case alt containing `error` to `topDiv`. Since `putStrLn` has `topDiv` itself, the final `Divergence` is `topDiv`. This is easily fixed: `deferAfterPreciseException` works by `lub`ing with the demand type of a virtual case branch denoting the precise exceptional control flow. We used `nopDmdType` before, but we can be more precise and use `exnDmdType`, which is `nopDmdType` with `exnDiv`. Now the `Divergence` from the case alt will degrade `botDiv` to `exnDiv` instead of `topDiv`, which combines with the result from the scrutinee to `exnDiv`, and all is well. Fixes #18086. - - - - - b6c76ea9 by Ben Gamari at 2020-05-27T18:32:27-04:00 Ticky-ticky: Record DataCon name in ticker name This makes it significantly easier to spot the nature of allocations regressions and comes at a reasonably low cost. - - - - - 752f9d02 by Ben Gamari at 2020-05-27T18:32:28-04:00 hadrian: Don't track GHC's verbosity argument Teach hadrian to ignore GHC's -v argument in its recompilation check, thus fixing #18131. - - - - - de24f092 by Ben Gamari at 2020-05-27T18:32:29-04:00 Rip out CmmStackInfo(updfr_space) As noted in #18232, this field is currently completely unused and moreover doesn't have a clear meaning. - - - - - 30 changed files: - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/LayoutStack.hs - compiler/GHC/Cmm/Ppr.hs - compiler/GHC/Cmm/ProcPoint.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify/Monad.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/Parser.y - compiler/GHC/Runtime/Eval.hs - compiler/GHC/StgToCmm/Bind.hs - compiler/GHC/StgToCmm/Monad.hs - compiler/GHC/StgToCmm/Ticky.hs - compiler/GHC/Tc/Solver/Flatten.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Utils/Error.hs - docs/core-spec/CoreLint.ott - docs/core-spec/CoreSyn.ott - docs/core-spec/README - docs/core-spec/core-spec.mng - docs/core-spec/core-spec.pdf - docs/users_guide/runtime_control.rst - hadrian/src/Target.hs - includes/rts/EventLogWriter.h - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/changelog.md - rts/eventlog/EventLogWriter.c The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1ecba71ee3ca880032d87e6e5dc89eb4a60d6ecc...de24f09226e05e5d8fbfea12bc7edd7513b368e6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1ecba71ee3ca880032d87e6e5dc89eb4a60d6ecc...de24f09226e05e5d8fbfea12bc7edd7513b368e6 You're receiving 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 28 00:58:47 2020 From: gitlab at gitlab.haskell.org (Vilem-Benjamin Liepelt) Date: Wed, 27 May 2020 20:58:47 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/buggymcbugfix/array-prim Message-ID: <5ecf0cc78a7f6_6e26115ac9702137150@gitlab.haskell.org.mail> Vilem-Benjamin Liepelt pushed new branch wip/buggymcbugfix/array-prim at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/buggymcbugfix/array-prim You're receiving 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 28 01:57:13 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 27 May 2020 21:57:13 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/backports-8.8 Message-ID: <5ecf1a79b06dd_6e263f9eefac1d2c21577af@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/backports-8.8 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/backports-8.8 You're receiving 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 28 02:13:22 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 27 May 2020 22:13:22 -0400 Subject: [Git][ghc/ghc][wip/backports-8.8] 3 commits: Rts: show errno on failure (#18033) Message-ID: <5ecf1e4220736_6e261275eeac21628b6@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/backports-8.8 at Glasgow Haskell Compiler / GHC Commits: 66c1cf35 by Sylvain Henry at 2020-05-27T22:05:33-04:00 Rts: show errno on failure (#18033) (cherry picked from commit 4875d419ba066e479f7ac07f8b39ebe10c855859) - - - - - 2efbf38f by Ben Gamari at 2020-05-27T22:05:58-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) - - - - - df9671ef by Sylvain Henry at 2020-05-27T22:06:55-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 (cherry picked from commit 12789d3ac30dd90f77593e99ef51e54b14fbf556) - - - - - 2 changed files: - rts/linker/PEi386.c - rts/posix/itimer/Pthread.c Changes: ===================================== rts/linker/PEi386.c ===================================== @@ -769,12 +769,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,22 +109,30 @@ 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 while (!exited) { if (USE_TIMERFD_FOR_ITIMER) { - if (read(timerfd, &nticks, sizeof(nticks)) != sizeof(nticks)) { - if (errno != EINTR) { - barf("Itimer: read(timerfd) failed"); - } + ssize_t r = read(timerfd, &nticks, sizeof(nticks)); + if ((r == 0) && (errno == 0)) { + /* r == 0 is expected only for non-blocking fd (in which case + * errno should be EAGAIN) but we use a blocking fd. + * + * Due to a kernel bug (cf https://lkml.org/lkml/2019/8/16/335) + * on some platforms we could see r == 0 and errno == 0. + */ + IF_DEBUG(scheduler, debugBelch("read(timerfd) returned 0 with errno=0. This is a known kernel bug. We just ignore it.")); + } + else if (r != sizeof(nticks) && errno != EINTR) { + barf("Itimer: read(timerfd) failed with %s and returned %zd", strerror(errno), r); } } else { if (usleep(TimeToUS(itimer_interval)) != 0 && errno != EINTR) { @@ -169,7 +177,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 +211,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); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/aa3fb803cccc0c235dfe8b7c9925d63b73134577...df9671ef7999ad84f1707c8fd54bd236d5d17dac -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/aa3fb803cccc0c235dfe8b7c9925d63b73134577...df9671ef7999ad84f1707c8fd54bd236d5d17dac You're receiving 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 28 02:29:49 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 27 May 2020 22:29:49 -0400 Subject: [Git][ghc/ghc][wip/backports-8.8] 9 commits: Set RELEASE=NO Message-ID: <5ecf221da5e3_6e263f9ed652f4cc21632c9@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/backports-8.8 at Glasgow Haskell Compiler / GHC Commits: ebc670a2 by Ben Gamari at 2020-05-27T22:29:40-04:00 Set RELEASE=NO - - - - - daf20c1a by Alp Mestanogullari at 2020-05-27T22:29:40-04:00 Hadrian: track mingw, ship it in bindists, more robust install script (cherry picked from commit 22c2713bcc30cea9da7d8b95f3ea99357d1551f7) - - - - - df71d20b by Ben Gamari at 2020-05-27T22:29:40-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. (cherry picked from commit f684a7d505f19bd78f178e01bbd8e4467aaa00ea) - - - - - 0bfe8342 by Alexis King at 2020-05-27T22:29:40-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. (cherry picked from commit eaed0a3289e4c24ff1a70c6fc4b7f8bae6cd2dd3) - - - - - c8b1be72 by Ben Gamari at 2020-05-27T22:29:40-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. (cherry picked from commit 2290eb02cf95e9cfffcb15fc9c593d5ef79c75d9) - - - - - 85e191e9 by Ben Gamari at 2020-05-27T22:29:40-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. (cherry picked from commit eba58110538686d8fe57d5dd372624b50f1fa2b7) - - - - - adb716fd by Sylvain Henry at 2020-05-27T22:29:41-04:00 Rts: show errno on failure (#18033) (cherry picked from commit 4875d419ba066e479f7ac07f8b39ebe10c855859) - - - - - 1c77f9a8 by Ben Gamari at 2020-05-27T22:29:41-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) - - - - - 39af414c by Sylvain Henry at 2020-05-27T22:29:41-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 (cherry picked from commit 12789d3ac30dd90f77593e99ef51e54b14fbf556) - - - - - 13 changed files: - compiler/deSugar/Coverage.hs - compiler/simplCore/OccurAnal.hs - configure.ac - hadrian/src/Base.hs - hadrian/src/Builder.hs - hadrian/src/Rules/BinaryDist.hs - hadrian/src/Rules/Program.hs - hadrian/src/Settings/Builders/Cabal.hs - hadrian/src/Settings/Packages.hs - libraries/Cabal - rts/linker/PEi386.c - rts/posix/itimer/Pthread.c - utils/iserv/ghc.mk Changes: ===================================== compiler/deSugar/Coverage.hs ===================================== @@ -111,7 +111,7 @@ addTicksToBinds hsc_env mod mod_loc exports tyCons binds dumpIfSet_dyn dflags Opt_D_dump_ticked "HPC" (pprLHsBinds binds1) - return (binds1, HpcInfo tickCount hashNo, Just modBreaks) + return (binds1, HpcInfo tickCount hashNo, modBreaks) | otherwise = return (binds, emptyHpcInfo False, Nothing) @@ -128,23 +128,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_] @@ -1038,7 +1038,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 $ @@ -1046,6 +1046,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. ===================================== compiler/simplCore/OccurAnal.hs ===================================== @@ -808,7 +808,7 @@ occAnalNonRecBind env lvl imp_rule_edges binder rhs body_usage occAnalRecBind :: OccEnv -> TopLevelFlag -> ImpRuleEdges -> [(Var,CoreExpr)] -> UsageDetails -> (UsageDetails, [CoreBind]) occAnalRecBind env lvl imp_rule_edges pairs body_usage - = foldr (occAnalRec env lvl) (body_usage, []) sccs + = foldr (occAnalRec rhs_env lvl) (body_usage, []) sccs -- For a recursive group, we -- * occ-analyse all the RHSs -- * compute strongly-connected components @@ -821,9 +821,11 @@ occAnalRecBind env lvl imp_rule_edges pairs body_usage nodes :: [LetrecNode] nodes = {-# SCC "occAnalBind.assoc" #-} - map (makeNode env imp_rule_edges bndr_set) pairs + map (makeNode rhs_env imp_rule_edges bndr_set) pairs - bndr_set = mkVarSet (map fst pairs) + bndrs = map fst pairs + bndr_set = mkVarSet bndrs + rhs_env = env `addInScope` bndrs {- Note [Unfoldings and join points] ===================================== configure.ac ===================================== @@ -16,7 +16,7 @@ dnl AC_INIT([The Glorious Glasgow Haskell Compilation System], [8.8.3], [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 ===================================== hadrian/src/Base.hs ===================================== @@ -25,7 +25,7 @@ module Base ( hadrianPath, configPath, configFile, sourcePath, shakeFilesDir, generatedDir, generatedPath, stageBinPath, stageLibPath, templateHscPath, ghcDeps, haddockDeps, relativePackageDbPath, packageDbPath, packageDbStamp, - ghcSplitPath + mingwStamp, ghcSplitPath ) where import Control.Applicative @@ -137,3 +137,9 @@ templateHscPath stage = stageLibPath stage <&> (-/- "template-hsc.h") -- to the build root under which we will copy @ghc-split at . ghcSplitPath :: Stage -> FilePath ghcSplitPath stage = stageString stage -/- "bin" -/- "ghc-split" + +-- | We use this stamp file to track whether we've moved the mingw toolchain +-- under the build root (to make it accessible to the GHCs we build on +-- Windows). See "Rules.Program". +mingwStamp :: FilePath +mingwStamp = "mingw" -/- ".stamp" ===================================== hadrian/src/Builder.hs ===================================== @@ -184,6 +184,10 @@ instance H.Builder Builder where , unlitPath ] ++ ghcdeps ++ [ touchyPath | win ] + ++ [ root -/- mingwStamp | win ] + -- proxy for the entire mingw toolchain that + -- we have in inplace/mingw initially, and then at + -- root -/- mingw. Hsc2Hs stage -> (\p -> [p]) <$> templateHscPath stage Make dir -> return [dir -/- "Makefile"] ===================================== hadrian/src/Rules/BinaryDist.hs ===================================== @@ -100,6 +100,7 @@ bindistRules = do targetPlatform <- setting TargetPlatformFull distDir <- Context.distDir rtsDir <- pkgIdentifier rts + windows <- windowsHost let ghcBuildDir = root -/- stageString Stage1 bindistFilesDir = root -/- "bindist" -/- ghcVersionPretty @@ -115,6 +116,12 @@ bindistRules = do copyDirectory (rtsIncludeDir) bindistFilesDir need ["docs"] copyDirectory (root -/- "docs") bindistFilesDir + when windows $ do + copyDirectory (root -/- "mingw") bindistFilesDir + -- we use that opportunity to delete the .stamp file that we use + -- as a proxy for the whole mingw toolchain, there's no point in + -- shipping it + removeFile (bindistFilesDir -/- mingwStamp) -- We copy the binary (/stage1/bin/haddock) to -- the bindist's bindir (/bindist/ghc-.../bin/). @@ -132,7 +139,8 @@ bindistRules = do , "runghc"] -- Finally, we create the archive /bindist/ghc-X.Y.Z-platform.tar.xz - command [Cwd $ root -/- "bindist"] "tar" + tarPath <- builderPath (Tar Create) + cmd [Cwd $ root -/- "bindist"] tarPath [ "-c", "--xz", "-f" , ghcVersionPretty <.> "tar.xz" , ghcVersionPretty ] @@ -224,19 +232,19 @@ bindistMakefile = unlines , "# to it. This implementation is a bit hacky and depends on consistency" , "# of program names. For hadrian build this will work as programs have a" , "# consistent naming procedure." - , "\trm -f $2" - , "\t$(CREATE_SCRIPT) $2" - , "\t at echo \"#!$(SHELL)\" >> $2" - , "\t at echo \"exedir=\\\"$4\\\"\" >> $2" - , "\t at echo \"exeprog=\\\"$1\\\"\" >> $2" - , "\t at echo \"executablename=\\\"$5\\\"\" >> $2" - , "\t at echo \"bindir=\\\"$3\\\"\" >> $2" - , "\t at echo \"libdir=\\\"$6\\\"\" >> $2" - , "\t at echo \"docdir=\\\"$7\\\"\" >> $2" - , "\t at echo \"includedir=\\\"$8\\\"\" >> $2" - , "\t at echo \"\" >> $2 " - , "\tcat wrappers/$1 >> $2" - , "\t$(EXECUTABLE_FILE) $2 ;" + , "\trm -f '$2'" + , "\t$(CREATE_SCRIPT) '$2'" + , "\t at echo \"#!$(SHELL)\" >> '$2'" + , "\t at echo \"exedir=\\\"$4\\\"\" >> '$2'" + , "\t at echo \"exeprog=\\\"$1\\\"\" >> '$2'" + , "\t at echo \"executablename=\\\"$5\\\"\" >> '$2'" + , "\t at echo \"bindir=\\\"$3\\\"\" >> '$2'" + , "\t at echo \"libdir=\\\"$6\\\"\" >> '$2'" + , "\t at echo \"docdir=\\\"$7\\\"\" >> '$2'" + , "\t at echo \"includedir=\\\"$8\\\"\" >> '$2'" + , "\t at echo \"\" >> '$2'" + , "\tcat wrappers/$1 >> '$2'" + , "\t$(EXECUTABLE_FILE) '$2' ;" , "endef" , "" , "# Hacky function to patch up the 'haddock-interfaces' and 'haddock-html'" @@ -245,10 +253,10 @@ bindistMakefile = unlines , "# $1 = package name (ex: 'bytestring')" , "# $2 = path to .conf file" , "# $3 = Docs Directory" - , "\tcat $2 | sed 's|haddock-interfaces.*|haddock-interfaces: $3/html/libraries/$1/$1.haddock|' \\" - , "\t | sed 's|haddock-html.*|haddock-html: $3/html/libraries/$1|' \\" - , "\t > $2.copy" - , "\tmv $2.copy $2" + , "\tcat '$2' | sed 's|haddock-interfaces.*|haddock-interfaces: $3/html/libraries/$1/$1.haddock|' \\" + , "\t | sed 's|haddock-html.*|haddock-html: $3/html/libraries/$1|' \\" + , "\t > '$2.copy'" + , "\tmv '$2.copy' '$2'" , "endef" , "" , "# QUESTION : should we use shell commands?" @@ -257,7 +265,7 @@ bindistMakefile = unlines , ".PHONY: install" , "install: install_lib install_bin install_includes" , "install: install_docs install_wrappers install_ghci" - , "install: update_package_db" + , "install: install_mingw update_package_db" , "" , "ActualBinsDir=${ghclibdir}/bin" , "WrapperBinsDir=${bindir}" @@ -273,10 +281,10 @@ bindistMakefile = unlines , "" , "install_ghci:" , "\t at echo \"Copying and installing ghci\"" - , "\t$(CREATE_SCRIPT) $(WrapperBinsDir)/ghci" - , "\t at echo \"#!$(SHELL)\" >> $(WrapperBinsDir)/ghci" - , "\tcat wrappers/ghci-script >> $(WrapperBinsDir)/ghci" - , "\t$(EXECUTABLE_FILE) $(WrapperBinsDir)/ghci" + , "\t$(CREATE_SCRIPT) '$(WrapperBinsDir)/ghci'" + , "\t at echo \"#!$(SHELL)\" >> '$(WrapperBinsDir)/ghci'" + , "\tcat wrappers/ghci-script >> '$(WrapperBinsDir)/ghci'" + , "\t$(EXECUTABLE_FILE) '$(WrapperBinsDir)/ghci'" , "" , "LIBRARIES = $(wildcard ./lib/*)" , "install_lib:" @@ -302,7 +310,7 @@ bindistMakefile = unlines , "\t\tcp -R $$i \"$(docdir)/\"; \\" , "\tdone" , "" - , "BINARY_NAMES=$(shell ls ./bin/)" + , "BINARY_NAMES=$(shell ls ./wrappers/)" , "install_wrappers:" , "\t at echo \"Installing Wrapper scripts\"" , "\t$(INSTALL_DIR) \"$(WrapperBinsDir)\"" @@ -318,8 +326,16 @@ bindistMakefile = unlines , "\t\t$(call patchpackageconf," ++ "$(shell echo $(notdir $p) | sed 's/-\\([0-9]*[0-9]\\.\\)*conf//g')," ++ "$p,$(docdir)))" - , "\t$(WrapperBinsDir)/ghc-pkg recache" + , "\t'$(WrapperBinsDir)/ghc-pkg' recache" , "" + , "# The 'foreach' that copies the mingw directory will only trigger a copy" + , "# when the wildcard matches, therefore only on Windows." + , "MINGW = $(wildcard ./mingw)" + , "install_mingw:" + , "\t at echo \"Installing MingGW\"" + , "\t$(INSTALL_DIR) \"$(prefix)/mingw\"" + , "\t$(foreach d, $(MINGW),\\" + , "\t\tcp -R ./mingw \"$(prefix)\")" , "# END INSTALL" , "# ----------------------------------------------------------------------" ] @@ -385,3 +401,19 @@ ghciScriptWrapper = unlines [ "DIR=`dirname \"$0\"`" , "executable=\"$DIR/ghc\"" , "exec $executable --interactive \"$@\"" ] + +-- | When not on Windows, we want to ship the 3 flavours of the iserv program +-- in binary distributions. This isn't easily achievable by just asking for +-- the package to be built, since here we're generating 3 different +-- executables out of just one package, so we need to specify all 3 contexts +-- explicitly and 'need' the result of building them. +needIservBins :: Action () +needIservBins = do + windows <- windowsHost + when (not windows) $ do + rtsways <- interpretInContext (vanillaContext Stage1 ghc) getRtsWays + need =<< traverse programPath + [ Context Stage1 iserv w + | w <- [vanilla, profiling, dynamic] + , w `elem` rtsways + ] ===================================== hadrian/src/Rules/Program.hs ===================================== @@ -8,6 +8,7 @@ import Context import Expression hiding (stage, way) import Oracles.Flag import Oracles.ModuleFiles +import Oracles.Setting (topDirectory) import Packages import Settings import Settings.Default @@ -19,6 +20,18 @@ import Flavour buildProgramRules :: [(Resource, Int)] -> Rules () buildProgramRules rs = do root <- buildRootRules + + -- Proxy rule for the whole mingw toolchain on Windows. + -- We 'need' configure because that's when the inplace/mingw + -- folder gets filled with the toolchain. This "proxy" rule + -- is listed as a runtime dependency for stage >= 1 GHCs. + root -/- mingwStamp %> \stampPath -> do + top <- topDirectory + need [ top -/- "configure" ] + copyDirectory (top -/- "inplace" -/- "mingw") root + writeFile' stampPath "OK" + + -- Rules for programs that are actually built by hadrian. forM_ [Stage0 ..] $ \stage -> [ root -/- stageString stage -/- "bin" -/- "*" , root -/- stageString stage -/- "lib/bin" -/- "*" ] |%> \bin -> do ===================================== hadrian/src/Settings/Builders/Cabal.hs ===================================== @@ -16,6 +16,8 @@ cabalBuilderArgs = builder (Cabal Setup) ? do pkg <- getPackage path <- getContextPath stage <- getStage + windows <- expr windowsHost + let prefix = "${pkgroot}" ++ (if windows then "" else "/..") mconcat [ arg "configure" -- Don't strip libraries when cross compiling. -- TODO: We need to set @--with-strip=(stripCmdPath :: Action FilePath)@, @@ -32,7 +34,7 @@ cabalBuilderArgs = builder (Cabal Setup) ? do , arg "--ipid" , arg "$pkg-$version" , arg "--prefix" - , arg "${pkgroot}/.." + , arg prefix -- NB: this is valid only because Hadrian puts the @docs@ and -- @libraries@ folders in the same relative position: ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -119,6 +119,14 @@ packageArgs = do [ notStage0 ? builder (Cabal Flags) ? arg "ghci" , flag CrossCompiling ? stage0 ? builder (Cabal Flags) ? arg "ghci" ] + --------------------------------- iserv -------------------------------- + -- Add -Wl,--export-dynamic enables GHCi to load dynamic objects that + -- refer to the RTS. This is harmless if you don't use it (adds a bit + -- of overhead to startup and increases the binary sizes) but if you + -- need it there's no alternative. + , package iserv ? mconcat + [ builder (Ghc LinkHs) ? arg "-optl-Wl,--export-dynamic" ] + -------------------------------- haddock ------------------------------- , package haddock ? builder (Cabal Flags) ? arg "in-ghc-tree" ===================================== libraries/Cabal ===================================== @@ -1 +1 @@ -Subproject commit 8199c3f838a15fb9b7c8d3527603084b2474d877 +Subproject commit 78f9ec2907b458bcfa7975ed2b92e3bed0aba949 ===================================== rts/linker/PEi386.c ===================================== @@ -769,12 +769,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,22 +109,30 @@ 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 while (!exited) { if (USE_TIMERFD_FOR_ITIMER) { - if (read(timerfd, &nticks, sizeof(nticks)) != sizeof(nticks)) { - if (errno != EINTR) { - barf("Itimer: read(timerfd) failed"); - } + ssize_t r = read(timerfd, &nticks, sizeof(nticks)); + if ((r == 0) && (errno == 0)) { + /* r == 0 is expected only for non-blocking fd (in which case + * errno should be EAGAIN) but we use a blocking fd. + * + * Due to a kernel bug (cf https://lkml.org/lkml/2019/8/16/335) + * on some platforms we could see r == 0 and errno == 0. + */ + IF_DEBUG(scheduler, debugBelch("read(timerfd) returned 0 with errno=0. This is a known kernel bug. We just ignore it.")); + } + else if (r != sizeof(nticks) && errno != EINTR) { + barf("Itimer: read(timerfd) failed with %s and returned %zd", strerror(errno), r); } } else { if (usleep(TimeToUS(itimer_interval)) != 0 && errno != EINTR) { @@ -169,7 +177,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 +211,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); ===================================== utils/iserv/ghc.mk ===================================== @@ -30,8 +30,9 @@ endif # refer to the RTS. This is harmless if you don't use it (adds a bit # of overhead to startup and increases the binary sizes) but if you # need it there's no alternative. +# Don't do this on FreeBSD to work around #17962. ifeq "$(TargetElf)" "YES" -ifneq "$(TargetOS_CPP)" "solaris2" +ifeq "$(findstring $(TargetOS_CPP), solaris2 freebsd)" "" # The Solaris linker does not support --export-dynamic option. It also # does not need it since it exports all dynamic symbols by default utils/iserv_stage2_MORE_HC_OPTS += -optl-Wl,--export-dynamic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/df9671ef7999ad84f1707c8fd54bd236d5d17dac...39af414c1c860aa27eda7232ba7c03e13592edb0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/df9671ef7999ad84f1707c8fd54bd236d5d17dac...39af414c1c860aa27eda7232ba7c03e13592edb0 You're receiving 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 28 02:47:19 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 27 May 2020 22:47:19 -0400 Subject: [Git][ghc/ghc][wip/backports-8.8] 8 commits: Hadrian: track mingw, ship it in bindists, more robust install script Message-ID: <5ecf2637672a_6e26113fea24216388e@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/backports-8.8 at Glasgow Haskell Compiler / GHC Commits: 37c0dd8f by Alp Mestanogullari at 2020-05-27T22:47:06-04:00 Hadrian: track mingw, ship it in bindists, more robust install script (cherry picked from commit 22c2713bcc30cea9da7d8b95f3ea99357d1551f7) - - - - - 53b6bdee by Ben Gamari at 2020-05-27T22:47:11-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. (cherry picked from commit f684a7d505f19bd78f178e01bbd8e4467aaa00ea) - - - - - 78ca6b13 by Alexis King at 2020-05-27T22:47:11-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. (cherry picked from commit eaed0a3289e4c24ff1a70c6fc4b7f8bae6cd2dd3) - - - - - 8b162b13 by Ben Gamari at 2020-05-27T22:47:11-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. (cherry picked from commit 2290eb02cf95e9cfffcb15fc9c593d5ef79c75d9) - - - - - 6cedf4b8 by Ben Gamari at 2020-05-27T22:47:11-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. (cherry picked from commit eba58110538686d8fe57d5dd372624b50f1fa2b7) - - - - - 95e92052 by Sylvain Henry at 2020-05-27T22:47:11-04:00 Rts: show errno on failure (#18033) (cherry picked from commit 4875d419ba066e479f7ac07f8b39ebe10c855859) - - - - - 56f10712 by Ben Gamari at 2020-05-27T22:47:11-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) - - - - - d6bc1fef by Sylvain Henry at 2020-05-27T22:47:11-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 (cherry picked from commit 12789d3ac30dd90f77593e99ef51e54b14fbf556) - - - - - 11 changed files: - compiler/deSugar/Coverage.hs - compiler/simplCore/OccurAnal.hs - hadrian/src/Base.hs - hadrian/src/Builder.hs - hadrian/src/Rules/BinaryDist.hs - hadrian/src/Rules/Program.hs - hadrian/src/Settings/Builders/Cabal.hs - hadrian/src/Settings/Packages.hs - rts/linker/PEi386.c - rts/posix/itimer/Pthread.c - utils/iserv/ghc.mk Changes: ===================================== compiler/deSugar/Coverage.hs ===================================== @@ -111,7 +111,7 @@ addTicksToBinds hsc_env mod mod_loc exports tyCons binds dumpIfSet_dyn dflags Opt_D_dump_ticked "HPC" (pprLHsBinds binds1) - return (binds1, HpcInfo tickCount hashNo, Just modBreaks) + return (binds1, HpcInfo tickCount hashNo, modBreaks) | otherwise = return (binds, emptyHpcInfo False, Nothing) @@ -128,23 +128,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_] @@ -1038,7 +1038,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 $ @@ -1046,6 +1046,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. ===================================== compiler/simplCore/OccurAnal.hs ===================================== @@ -808,7 +808,7 @@ occAnalNonRecBind env lvl imp_rule_edges binder rhs body_usage occAnalRecBind :: OccEnv -> TopLevelFlag -> ImpRuleEdges -> [(Var,CoreExpr)] -> UsageDetails -> (UsageDetails, [CoreBind]) occAnalRecBind env lvl imp_rule_edges pairs body_usage - = foldr (occAnalRec env lvl) (body_usage, []) sccs + = foldr (occAnalRec rhs_env lvl) (body_usage, []) sccs -- For a recursive group, we -- * occ-analyse all the RHSs -- * compute strongly-connected components @@ -821,9 +821,11 @@ occAnalRecBind env lvl imp_rule_edges pairs body_usage nodes :: [LetrecNode] nodes = {-# SCC "occAnalBind.assoc" #-} - map (makeNode env imp_rule_edges bndr_set) pairs + map (makeNode rhs_env imp_rule_edges bndr_set) pairs - bndr_set = mkVarSet (map fst pairs) + bndrs = map fst pairs + bndr_set = mkVarSet bndrs + rhs_env = env `addInScope` bndrs {- Note [Unfoldings and join points] ===================================== hadrian/src/Base.hs ===================================== @@ -25,7 +25,7 @@ module Base ( hadrianPath, configPath, configFile, sourcePath, shakeFilesDir, generatedDir, generatedPath, stageBinPath, stageLibPath, templateHscPath, ghcDeps, haddockDeps, relativePackageDbPath, packageDbPath, packageDbStamp, - ghcSplitPath + mingwStamp, ghcSplitPath ) where import Control.Applicative @@ -137,3 +137,9 @@ templateHscPath stage = stageLibPath stage <&> (-/- "template-hsc.h") -- to the build root under which we will copy @ghc-split at . ghcSplitPath :: Stage -> FilePath ghcSplitPath stage = stageString stage -/- "bin" -/- "ghc-split" + +-- | We use this stamp file to track whether we've moved the mingw toolchain +-- under the build root (to make it accessible to the GHCs we build on +-- Windows). See "Rules.Program". +mingwStamp :: FilePath +mingwStamp = "mingw" -/- ".stamp" ===================================== hadrian/src/Builder.hs ===================================== @@ -184,6 +184,10 @@ instance H.Builder Builder where , unlitPath ] ++ ghcdeps ++ [ touchyPath | win ] + ++ [ root -/- mingwStamp | win ] + -- proxy for the entire mingw toolchain that + -- we have in inplace/mingw initially, and then at + -- root -/- mingw. Hsc2Hs stage -> (\p -> [p]) <$> templateHscPath stage Make dir -> return [dir -/- "Makefile"] ===================================== hadrian/src/Rules/BinaryDist.hs ===================================== @@ -100,6 +100,7 @@ bindistRules = do targetPlatform <- setting TargetPlatformFull distDir <- Context.distDir rtsDir <- pkgIdentifier rts + windows <- windowsHost let ghcBuildDir = root -/- stageString Stage1 bindistFilesDir = root -/- "bindist" -/- ghcVersionPretty @@ -115,6 +116,12 @@ bindistRules = do copyDirectory (rtsIncludeDir) bindistFilesDir need ["docs"] copyDirectory (root -/- "docs") bindistFilesDir + when windows $ do + copyDirectory (root -/- "mingw") bindistFilesDir + -- we use that opportunity to delete the .stamp file that we use + -- as a proxy for the whole mingw toolchain, there's no point in + -- shipping it + removeFile (bindistFilesDir -/- mingwStamp) -- We copy the binary (/stage1/bin/haddock) to -- the bindist's bindir (/bindist/ghc-.../bin/). @@ -132,7 +139,8 @@ bindistRules = do , "runghc"] -- Finally, we create the archive /bindist/ghc-X.Y.Z-platform.tar.xz - command [Cwd $ root -/- "bindist"] "tar" + tarPath <- builderPath (Tar Create) + cmd [Cwd $ root -/- "bindist"] tarPath [ "-c", "--xz", "-f" , ghcVersionPretty <.> "tar.xz" , ghcVersionPretty ] @@ -224,19 +232,19 @@ bindistMakefile = unlines , "# to it. This implementation is a bit hacky and depends on consistency" , "# of program names. For hadrian build this will work as programs have a" , "# consistent naming procedure." - , "\trm -f $2" - , "\t$(CREATE_SCRIPT) $2" - , "\t at echo \"#!$(SHELL)\" >> $2" - , "\t at echo \"exedir=\\\"$4\\\"\" >> $2" - , "\t at echo \"exeprog=\\\"$1\\\"\" >> $2" - , "\t at echo \"executablename=\\\"$5\\\"\" >> $2" - , "\t at echo \"bindir=\\\"$3\\\"\" >> $2" - , "\t at echo \"libdir=\\\"$6\\\"\" >> $2" - , "\t at echo \"docdir=\\\"$7\\\"\" >> $2" - , "\t at echo \"includedir=\\\"$8\\\"\" >> $2" - , "\t at echo \"\" >> $2 " - , "\tcat wrappers/$1 >> $2" - , "\t$(EXECUTABLE_FILE) $2 ;" + , "\trm -f '$2'" + , "\t$(CREATE_SCRIPT) '$2'" + , "\t at echo \"#!$(SHELL)\" >> '$2'" + , "\t at echo \"exedir=\\\"$4\\\"\" >> '$2'" + , "\t at echo \"exeprog=\\\"$1\\\"\" >> '$2'" + , "\t at echo \"executablename=\\\"$5\\\"\" >> '$2'" + , "\t at echo \"bindir=\\\"$3\\\"\" >> '$2'" + , "\t at echo \"libdir=\\\"$6\\\"\" >> '$2'" + , "\t at echo \"docdir=\\\"$7\\\"\" >> '$2'" + , "\t at echo \"includedir=\\\"$8\\\"\" >> '$2'" + , "\t at echo \"\" >> '$2'" + , "\tcat wrappers/$1 >> '$2'" + , "\t$(EXECUTABLE_FILE) '$2' ;" , "endef" , "" , "# Hacky function to patch up the 'haddock-interfaces' and 'haddock-html'" @@ -245,10 +253,10 @@ bindistMakefile = unlines , "# $1 = package name (ex: 'bytestring')" , "# $2 = path to .conf file" , "# $3 = Docs Directory" - , "\tcat $2 | sed 's|haddock-interfaces.*|haddock-interfaces: $3/html/libraries/$1/$1.haddock|' \\" - , "\t | sed 's|haddock-html.*|haddock-html: $3/html/libraries/$1|' \\" - , "\t > $2.copy" - , "\tmv $2.copy $2" + , "\tcat '$2' | sed 's|haddock-interfaces.*|haddock-interfaces: $3/html/libraries/$1/$1.haddock|' \\" + , "\t | sed 's|haddock-html.*|haddock-html: $3/html/libraries/$1|' \\" + , "\t > '$2.copy'" + , "\tmv '$2.copy' '$2'" , "endef" , "" , "# QUESTION : should we use shell commands?" @@ -257,7 +265,7 @@ bindistMakefile = unlines , ".PHONY: install" , "install: install_lib install_bin install_includes" , "install: install_docs install_wrappers install_ghci" - , "install: update_package_db" + , "install: install_mingw update_package_db" , "" , "ActualBinsDir=${ghclibdir}/bin" , "WrapperBinsDir=${bindir}" @@ -273,10 +281,10 @@ bindistMakefile = unlines , "" , "install_ghci:" , "\t at echo \"Copying and installing ghci\"" - , "\t$(CREATE_SCRIPT) $(WrapperBinsDir)/ghci" - , "\t at echo \"#!$(SHELL)\" >> $(WrapperBinsDir)/ghci" - , "\tcat wrappers/ghci-script >> $(WrapperBinsDir)/ghci" - , "\t$(EXECUTABLE_FILE) $(WrapperBinsDir)/ghci" + , "\t$(CREATE_SCRIPT) '$(WrapperBinsDir)/ghci'" + , "\t at echo \"#!$(SHELL)\" >> '$(WrapperBinsDir)/ghci'" + , "\tcat wrappers/ghci-script >> '$(WrapperBinsDir)/ghci'" + , "\t$(EXECUTABLE_FILE) '$(WrapperBinsDir)/ghci'" , "" , "LIBRARIES = $(wildcard ./lib/*)" , "install_lib:" @@ -302,7 +310,7 @@ bindistMakefile = unlines , "\t\tcp -R $$i \"$(docdir)/\"; \\" , "\tdone" , "" - , "BINARY_NAMES=$(shell ls ./bin/)" + , "BINARY_NAMES=$(shell ls ./wrappers/)" , "install_wrappers:" , "\t at echo \"Installing Wrapper scripts\"" , "\t$(INSTALL_DIR) \"$(WrapperBinsDir)\"" @@ -318,8 +326,16 @@ bindistMakefile = unlines , "\t\t$(call patchpackageconf," ++ "$(shell echo $(notdir $p) | sed 's/-\\([0-9]*[0-9]\\.\\)*conf//g')," ++ "$p,$(docdir)))" - , "\t$(WrapperBinsDir)/ghc-pkg recache" + , "\t'$(WrapperBinsDir)/ghc-pkg' recache" , "" + , "# The 'foreach' that copies the mingw directory will only trigger a copy" + , "# when the wildcard matches, therefore only on Windows." + , "MINGW = $(wildcard ./mingw)" + , "install_mingw:" + , "\t at echo \"Installing MingGW\"" + , "\t$(INSTALL_DIR) \"$(prefix)/mingw\"" + , "\t$(foreach d, $(MINGW),\\" + , "\t\tcp -R ./mingw \"$(prefix)\")" , "# END INSTALL" , "# ----------------------------------------------------------------------" ] @@ -385,3 +401,19 @@ ghciScriptWrapper = unlines [ "DIR=`dirname \"$0\"`" , "executable=\"$DIR/ghc\"" , "exec $executable --interactive \"$@\"" ] + +-- | When not on Windows, we want to ship the 3 flavours of the iserv program +-- in binary distributions. This isn't easily achievable by just asking for +-- the package to be built, since here we're generating 3 different +-- executables out of just one package, so we need to specify all 3 contexts +-- explicitly and 'need' the result of building them. +needIservBins :: Action () +needIservBins = do + windows <- windowsHost + when (not windows) $ do + rtsways <- interpretInContext (vanillaContext Stage1 ghc) getRtsWays + need =<< traverse programPath + [ Context Stage1 iserv w + | w <- [vanilla, profiling, dynamic] + , w `elem` rtsways + ] ===================================== hadrian/src/Rules/Program.hs ===================================== @@ -8,6 +8,7 @@ import Context import Expression hiding (stage, way) import Oracles.Flag import Oracles.ModuleFiles +import Oracles.Setting (topDirectory) import Packages import Settings import Settings.Default @@ -19,6 +20,18 @@ import Flavour buildProgramRules :: [(Resource, Int)] -> Rules () buildProgramRules rs = do root <- buildRootRules + + -- Proxy rule for the whole mingw toolchain on Windows. + -- We 'need' configure because that's when the inplace/mingw + -- folder gets filled with the toolchain. This "proxy" rule + -- is listed as a runtime dependency for stage >= 1 GHCs. + root -/- mingwStamp %> \stampPath -> do + top <- topDirectory + need [ top -/- "configure" ] + copyDirectory (top -/- "inplace" -/- "mingw") root + writeFile' stampPath "OK" + + -- Rules for programs that are actually built by hadrian. forM_ [Stage0 ..] $ \stage -> [ root -/- stageString stage -/- "bin" -/- "*" , root -/- stageString stage -/- "lib/bin" -/- "*" ] |%> \bin -> do ===================================== hadrian/src/Settings/Builders/Cabal.hs ===================================== @@ -16,6 +16,8 @@ cabalBuilderArgs = builder (Cabal Setup) ? do pkg <- getPackage path <- getContextPath stage <- getStage + windows <- expr windowsHost + let prefix = "${pkgroot}" ++ (if windows then "" else "/..") mconcat [ arg "configure" -- Don't strip libraries when cross compiling. -- TODO: We need to set @--with-strip=(stripCmdPath :: Action FilePath)@, @@ -32,7 +34,7 @@ cabalBuilderArgs = builder (Cabal Setup) ? do , arg "--ipid" , arg "$pkg-$version" , arg "--prefix" - , arg "${pkgroot}/.." + , arg prefix -- NB: this is valid only because Hadrian puts the @docs@ and -- @libraries@ folders in the same relative position: ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -119,6 +119,14 @@ packageArgs = do [ notStage0 ? builder (Cabal Flags) ? arg "ghci" , flag CrossCompiling ? stage0 ? builder (Cabal Flags) ? arg "ghci" ] + --------------------------------- iserv -------------------------------- + -- Add -Wl,--export-dynamic enables GHCi to load dynamic objects that + -- refer to the RTS. This is harmless if you don't use it (adds a bit + -- of overhead to startup and increases the binary sizes) but if you + -- need it there's no alternative. + , package iserv ? mconcat + [ builder (Ghc LinkHs) ? arg "-optl-Wl,--export-dynamic" ] + -------------------------------- haddock ------------------------------- , package haddock ? builder (Cabal Flags) ? arg "in-ghc-tree" ===================================== rts/linker/PEi386.c ===================================== @@ -769,12 +769,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,22 +109,30 @@ 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 while (!exited) { if (USE_TIMERFD_FOR_ITIMER) { - if (read(timerfd, &nticks, sizeof(nticks)) != sizeof(nticks)) { - if (errno != EINTR) { - barf("Itimer: read(timerfd) failed"); - } + ssize_t r = read(timerfd, &nticks, sizeof(nticks)); + if ((r == 0) && (errno == 0)) { + /* r == 0 is expected only for non-blocking fd (in which case + * errno should be EAGAIN) but we use a blocking fd. + * + * Due to a kernel bug (cf https://lkml.org/lkml/2019/8/16/335) + * on some platforms we could see r == 0 and errno == 0. + */ + IF_DEBUG(scheduler, debugBelch("read(timerfd) returned 0 with errno=0. This is a known kernel bug. We just ignore it.")); + } + else if (r != sizeof(nticks) && errno != EINTR) { + barf("Itimer: read(timerfd) failed with %s and returned %zd", strerror(errno), r); } } else { if (usleep(TimeToUS(itimer_interval)) != 0 && errno != EINTR) { @@ -169,7 +177,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 +211,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); ===================================== utils/iserv/ghc.mk ===================================== @@ -30,8 +30,9 @@ endif # refer to the RTS. This is harmless if you don't use it (adds a bit # of overhead to startup and increases the binary sizes) but if you # need it there's no alternative. +# Don't do this on FreeBSD to work around #17962. ifeq "$(TargetElf)" "YES" -ifneq "$(TargetOS_CPP)" "solaris2" +ifeq "$(findstring $(TargetOS_CPP), solaris2 freebsd)" "" # The Solaris linker does not support --export-dynamic option. It also # does not need it since it exports all dynamic symbols by default utils/iserv_stage2_MORE_HC_OPTS += -optl-Wl,--export-dynamic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/39af414c1c860aa27eda7232ba7c03e13592edb0...d6bc1fef6a8c55b5237bccdbc5f2d902979443bb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/39af414c1c860aa27eda7232ba7c03e13592edb0...d6bc1fef6a8c55b5237bccdbc5f2d902979443bb You're receiving 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 28 03:14:34 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Wed, 27 May 2020 23:14:34 -0400 Subject: [Git][ghc/ghc][wip/backports-8.8] 5 commits: iserv: Don't pass --export-dynamic on FreeBSD Message-ID: <5ecf2c9a84033_6e26115ac9702164287@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/backports-8.8 at Glasgow Haskell Compiler / GHC Commits: 5133f5c2 by Ben Gamari at 2020-05-27T23:14:28-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. (cherry picked from commit 2290eb02cf95e9cfffcb15fc9c593d5ef79c75d9) - - - - - 66de4d07 by Ben Gamari at 2020-05-27T23:14:28-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. (cherry picked from commit eba58110538686d8fe57d5dd372624b50f1fa2b7) - - - - - 6507c2bf by Sylvain Henry at 2020-05-27T23:14:28-04:00 Rts: show errno on failure (#18033) (cherry picked from commit 4875d419ba066e479f7ac07f8b39ebe10c855859) - - - - - 286cf192 by Ben Gamari at 2020-05-27T23:14:28-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) - - - - - 9037a2b6 by Sylvain Henry at 2020-05-27T23:14:28-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 (cherry picked from commit 12789d3ac30dd90f77593e99ef51e54b14fbf556) - - - - - 4 changed files: - hadrian/src/Settings/Packages.hs - rts/linker/PEi386.c - rts/posix/itimer/Pthread.c - utils/iserv/ghc.mk Changes: ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -119,6 +119,14 @@ packageArgs = do [ notStage0 ? builder (Cabal Flags) ? arg "ghci" , flag CrossCompiling ? stage0 ? builder (Cabal Flags) ? arg "ghci" ] + --------------------------------- iserv -------------------------------- + -- Add -Wl,--export-dynamic enables GHCi to load dynamic objects that + -- refer to the RTS. This is harmless if you don't use it (adds a bit + -- of overhead to startup and increases the binary sizes) but if you + -- need it there's no alternative. + , package iserv ? mconcat + [ builder (Ghc LinkHs) ? arg "-optl-Wl,--export-dynamic" ] + -------------------------------- haddock ------------------------------- , package haddock ? builder (Cabal Flags) ? arg "in-ghc-tree" ===================================== rts/linker/PEi386.c ===================================== @@ -769,12 +769,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,22 +109,30 @@ 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 while (!exited) { if (USE_TIMERFD_FOR_ITIMER) { - if (read(timerfd, &nticks, sizeof(nticks)) != sizeof(nticks)) { - if (errno != EINTR) { - barf("Itimer: read(timerfd) failed"); - } + ssize_t r = read(timerfd, &nticks, sizeof(nticks)); + if ((r == 0) && (errno == 0)) { + /* r == 0 is expected only for non-blocking fd (in which case + * errno should be EAGAIN) but we use a blocking fd. + * + * Due to a kernel bug (cf https://lkml.org/lkml/2019/8/16/335) + * on some platforms we could see r == 0 and errno == 0. + */ + IF_DEBUG(scheduler, debugBelch("read(timerfd) returned 0 with errno=0. This is a known kernel bug. We just ignore it.")); + } + else if (r != sizeof(nticks) && errno != EINTR) { + barf("Itimer: read(timerfd) failed with %s and returned %zd", strerror(errno), r); } } else { if (usleep(TimeToUS(itimer_interval)) != 0 && errno != EINTR) { @@ -169,7 +177,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 +211,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); ===================================== utils/iserv/ghc.mk ===================================== @@ -30,8 +30,9 @@ endif # refer to the RTS. This is harmless if you don't use it (adds a bit # of overhead to startup and increases the binary sizes) but if you # need it there's no alternative. +# Don't do this on FreeBSD to work around #17962. ifeq "$(TargetElf)" "YES" -ifneq "$(TargetOS_CPP)" "solaris2" +ifeq "$(findstring $(TargetOS_CPP), solaris2 freebsd)" "" # The Solaris linker does not support --export-dynamic option. It also # does not need it since it exports all dynamic symbols by default utils/iserv_stage2_MORE_HC_OPTS += -optl-Wl,--export-dynamic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d6bc1fef6a8c55b5237bccdbc5f2d902979443bb...9037a2b64ec78cc6d6946aae118622517c8163e2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d6bc1fef6a8c55b5237bccdbc5f2d902979443bb...9037a2b64ec78cc6d6946aae118622517c8163e2 You're receiving 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 28 07:59:46 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Thu, 28 May 2020 03:59:46 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18126-deep Message-ID: <5ecf6f72337b1_6e263f9f0bed505021793aa@gitlab.haskell.org.mail> Simon Peyton Jones pushed new branch wip/T18126-deep at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18126-deep You're receiving 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 28 09:03:00 2020 From: gitlab at gitlab.haskell.org (Sebastian Graf) Date: Thu, 28 May 2020 05:03:00 -0400 Subject: [Git][ghc/ghc][wip/nested-cpr-2019] Regard all arity 0 bindings (incl. DataCon apps) as thunks Message-ID: <5ecf7e443229d_6e263f9ed652f4cc218431e@gitlab.haskell.org.mail> Sebastian Graf pushed to branch wip/nested-cpr-2019 at Glasgow Haskell Compiler / GHC Commits: 8790dbc7 by Sebastian Graf at 2020-05-28T11:02:52+02:00 Regard all arity 0 bindings (incl. DataCon apps) as thunks - - - - - 1 changed file: - compiler/GHC/Core/Opt/CprAnal.hs Changes: ===================================== compiler/GHC/Core/Opt/CprAnal.hs ===================================== @@ -25,7 +25,7 @@ import GHC.Types.Basic import GHC.Core.DataCon import GHC.Types.Id import GHC.Types.Id.Info -import GHC.Core.Utils ( exprIsHNF, dumpIdInfoOfProgram ) +import GHC.Core.Utils ( dumpIdInfoOfProgram ) import GHC.Core.TyCon import GHC.Core.Type import GHC.Core.FamInstEnv @@ -357,7 +357,7 @@ cprAnalBind top_lvl env widening args id rhs -- See Note [CPR for thunks] stays_thunk = is_thunk && not_strict - is_thunk = not (exprIsHNF rhs) && not (isJoinId id) + is_thunk = idArity id == 0 && not (isJoinId id) not_strict = not (isStrictDmd (idDemandInfo id)) -- See Note [CPR for sum types] (_, ret_ty) = splitPiTys (idType id) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8790dbc7d084d91f2bcbf9297e5ec3c2cf1ccf02 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8790dbc7d084d91f2bcbf9297e5ec3c2cf1ccf02 You're receiving 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 28 09:56:35 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Thu, 28 May 2020 05:56:35 -0400 Subject: [Git][ghc/ghc][wip/osa1/std_string_thunks] 162 commits: Define a Quote IO instance Message-ID: <5ecf8ad38b992_6e26115ac97021911af@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/std_string_thunks 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. - - - - - 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. - - - - - 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] - - - - - 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 - - - - - 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 - - - - - 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. - - - - - 78c6523c by Ben Gamari at 2020-05-21T12:13:01-04:00 nonmoving: Optimise the write barrier - - - - - 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). - - - - - 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 - - - - - b7a6b2f4 by Gleb Popov at 2020-05-21T12:15:26-04:00 gitlab-ci: Set locale to C.UTF-8. - - - - - 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. - - - - - 0004ccb8 by Tuan Le at 2020-05-21T12:16:46-04:00 llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 - - - - - 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 - - - - - 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 - - - - - 2b363ebb by Richard Eisenberg at 2020-05-21T12:18:45-04:00 MR template should ask for key part - - - - - a95bbd0b by Sebastian Graf at 2020-05-21T12:19:37-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. - - - - - d3d055b8 by Galen Huntington at 2020-05-21T12:20:18-04:00 Clarify pitfalls of NegativeLiterals; see #18022. - - - - - 1b508a9e by Alexey Kuleshevich at 2020-05-21T12:21:02-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" - - - - - 4ca0c8a1 by Andreas Klebinger at 2020-05-21T12:21: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. - - - - - a1275081 by Krzysztof Gogolewski at 2020-05-21T12:22:35-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 - - - - - 8a816e5f by Krzysztof Gogolewski at 2020-05-21T12:23:55-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. - - - - - 566cc73f by Sylvain Henry at 2020-05-21T12:24:45-04:00 Move isDynLinkName into GHC.Types.Name It doesn't belong into GHC.Unit.State - - - - - d830bbc9 by Adam Sandberg Ericsson at 2020-05-23T13:36:20-04:00 docs: fix formatting and add some links [skip ci] - - - - - 49301ad6 by Andrew Martin at 2020-05-23T13:37:01-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. - - - - - dcd6bdcc by Ben Gamari at 2020-05-23T13:37:48-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. - - - - - 82cb8913 by John Ericson at 2020-05-23T13:38:32-04:00 Fix #18145 and also avoid needless work with implicit vars - `forAllOrNothing` now is monadic, so we can trace whether we bind an explicit `forall` or not. - #18145 arose because the free vars calculation was needlessly complex. It is now greatly simplified. - Replaced some other implicit var code with `filterFreeVarsToBind`. Co-authored-by: Ryan Scott <ryan.gl.scott at gmail.com> - - - - - a60dc835 by Ben Gamari at 2020-05-23T13:39:12-04:00 Bump process submodule Fixes #17926. - - - - - 856adf54 by Ben Gamari at 2020-05-23T13:40:21-04:00 users-guide: Clarify meaning of -haddock flag Fixes #18206. - - - - - 7ae57afd by Ben Gamari at 2020-05-23T13:41:03-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 - - - - - 63d30e60 by jneira at 2020-05-24T01:54:42-04:00 Add hie-bios script for windows systems It is a direct translation of the sh script - - - - - 59182b88 by jneira at 2020-05-24T01:54:42-04:00 Honour previous values for CABAL and CABFLAGS The immediate goal is let the hie-bios.bat script set CABFLAGS with `-v0` and remove all cabal output except the compiler arguments - - - - - 932dc54e by jneira at 2020-05-24T01:54:42-04:00 Add specific configuration for windows in hie.yaml - - - - - e0eda070 by jneira at 2020-05-24T01:54:42-04:00 Remove not needed hie-bios output - - - - - a0ea59d6 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Move Config module into GHC.Settings - - - - - 37430251 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Core.Arity into GHC.Core.Opt.Arity - - - - - a426abb9 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Rename GHC.Hs.Types into GHC.Hs.Type See discussion in https://gitlab.haskell.org/ghc/ghc/issues/13009#note_268610 - - - - - 1c91a7a0 by Sylvain Henry at 2020-05-24T01:55:24-04:00 Bump haddock submodule - - - - - 66bd24d1 by Ryan Scott at 2020-05-24T01:56:03-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. - - - - - 01c43634 by Matthew Pickering at 2020-05-24T01:56:42-04:00 Remove unused hs-boot file - - - - - 7a07aa71 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix cross-compiler build (#16051) - - - - - 15ccca16 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix distDir per stage - - - - - b420fb24 by Sylvain Henry at 2020-05-24T15:22:17-04:00 Hadrian: fix hp2ps error during cross-compilation Fixed by @alp (see https://gitlab.haskell.org/ghc/ghc/issues/16051#note_274265) - - - - - cd339ef0 by Joshua Price at 2020-05-24T15:22:56-04:00 Make Unicode brackets opening/closing tokens (#18225) The tokens `[|`, `|]`, `(|`, and `|)` are opening/closing tokens as described in GHC Proposal #229. This commit makes the unicode variants (`⟦`, `⟧`, `⦇`, and `⦈`) act the same as their ASCII counterparts. - - - - - 013d7120 by Ben Gamari at 2020-05-25T09:48:17-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. - - - - - 4c4312ed by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Drop redundant ad-hoc boot module check To determine whether the module is a boot module Coverage.addTicksToBinds was checking for a `boot` suffix in the module source filename. This is quite ad-hoc and shouldn't be necessary; the callsite in `deSugar` already checks that the module isn't a boot module. - - - - - 1abf3c84 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make tickBoxCount strict This could otherwise easily cause a leak of (+) thunks. - - - - - b2813750 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make ccIndices strict This just seems like a good idea. - - - - - 02e278eb by Ben Gamari at 2020-05-25T09:48:53-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. - - - - - b8c014ce by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Factor out addMixEntry - - - - - 53814a64 by Zubin Duggal at 2020-05-26T03:03:24-04:00 Add info about typeclass evidence to .hie files See `testsuite/tests/hiefile/should_run/HieQueries.hs` and `testsuite/tests/hiefile/should_run/HieQueries.stdout` for an example of this We add two new fields, `EvidenceVarBind` and `EvidenceVarUse` to the `ContextInfo` associated with an Identifier. These are associated with the appropriate identifiers for the evidence variables collected when we come across `HsWrappers`, `TcEvBinds` and `IPBinds` while traversing the AST. Instance dictionary and superclass selector dictionaries from `tcg_insts` and classes defined in `tcg_tcs` are also recorded in the AST as originating from their definition span This allows us to save a complete picture of the evidence constructed by the constraint solver, and will let us report this to the user, enabling features like going to the instance definition from the invocation of a class method(or any other method taking a constraint) and finding all usages of a particular instance. Additionally, - Mark NodeInfo with an origin so we can differentiate between bindings origininating in the source vs those in ghc - Along with typeclass evidence info, also include information on Implicit Parameters - Add a few utility functions to HieUtils in order to query the new info Updates haddock submodule - - - - - 6604906c by Sebastian Graf at 2020-05-26T03:04:04-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. - - - - - cf772f19 by Sylvain Henry at 2020-05-26T03:04:45-04:00 Enhance Note [About units] for Backpack - - - - - ede24126 by Takenobu Tani at 2020-05-27T00:13:55-04:00 core-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Core.hs <= coreSyn/CoreSyn.hs * GHC/Core/Coercion.hs <= types/Coercion.hs * GHC/Core/Coercion/Axiom.hs <= types/CoAxiom.hs * GHC/Core/Coercion/Opt.hs <= types/OptCoercion.hs * GHC/Core/DataCon.hs <= basicTypes/DataCon.hs * GHC/Core/FamInstEnv.hs <= types/FamInstEnv.hs * GHC/Core/Lint.hs <= coreSyn/CoreLint.hs * GHC/Core/Subst.hs <= coreSyn/CoreSubst.hs * GHC/Core/TyCo/Rep.hs <= types/TyCoRep.hs * GHC/Core/TyCon.hs <= types/TyCon.hs * GHC/Core/Type.hs <= types/Type.hs * GHC/Core/Unify.hs <= types/Unify.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/Var.hs <= basicTypes/Var.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [skip ci] - - - - - 04750304 by Ben Gamari at 2020-05-27T00:14:33-04:00 eventlog: Fix racy flushing Previously no attempt was made to avoid multiple threads writing their capability-local eventlog buffers to the eventlog writer simultaneously. This could result in multiple eventlog streams being interleaved. Fix this by documenting that the EventLogWriter's write() and flush() functions may be called reentrantly and fix the default writer to protect its FILE* by a mutex. Fixes #18210. - - - - - d6203f24 by Joshua Price at 2020-05-27T00:15:17-04:00 Make `identifier` parse unparenthesized `->` (#18060) - - - - - afd1b7e6 by Ömer Sinan Ağacan at 2020-05-28T11:06:10+03:00 Introduce a standard thunk for allocating strings Currently for a top-level closure in the form hey = unpackCString# x we generate code like this: Main.hey_entry() // [R1] { info_tbls: [(c2T4, label: Main.hey_info rep: HeapRep static { Thunk } srt: Nothing)] stack_info: arg_space: 8 updfr_space: Just 8 } {offset c2T4: // global _rqm::P64 = R1; if ((Sp + 8) - 24 < SpLim) (likely: False) goto c2T5; else goto c2T6; c2T5: // global R1 = _rqm::P64; call (stg_gc_enter_1)(R1) args: 8, res: 0, upd: 8; c2T6: // global (_c2T1::I64) = call "ccall" arg hints: [PtrHint, PtrHint] result hints: [PtrHint] newCAF(BaseReg, _rqm::P64); if (_c2T1::I64 == 0) goto c2T3; else goto c2T2; c2T3: // global call (I64[_rqm::P64])() args: 8, res: 0, upd: 8; c2T2: // global I64[Sp - 16] = stg_bh_upd_frame_info; I64[Sp - 8] = _c2T1::I64; R2 = hey1_r2Gg_bytes; Sp = Sp - 16; call GHC.CString.unpackCString#_info(R2) args: 24, res: 0, upd: 24; } } This code is generated for every string literal. Only difference between top-level closures like this is the argument for the bytes of the string (hey1_r2Gg_bytes in the code above). With this patch we introduce a standard thunk in the RTS, called stg_MK_STRING_info, that does what `unpackCString# x` does, except it gets the bytes address from the payload. Using this, for the closure above, we generate this: Main.hey_closure" { Main.hey_closure: const stg_MK_STRING_info; const hey1_r1Gg_bytes; const 0; const 0; } This is much smaller in code. - - - - - dc57c656 by Ömer Sinan Ağacan at 2020-05-28T12:56:23+03:00 Fix entering newCAF result - - - - - 30 changed files: - + .git-ignore-revs - .gitlab-ci.yml - .gitlab/ci.sh - .gitlab/merge_request_templates/merge-request.md - 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/Types/Prim.hs - compiler/GHC/Builtin/Utils.hs - compiler/GHC/Builtin/primops.txt.pp - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/DebugBlock.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/Opt.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Pipeline.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm.hs - compiler/GHC/CmmToAsm/BlockLayout.hs - compiler/GHC/CmmToAsm/CFG.hs - compiler/GHC/CmmToAsm/Config.hs - compiler/GHC/CmmToAsm/Dwarf.hs - compiler/GHC/CmmToAsm/Instr.hs - compiler/GHC/CmmToAsm/Monad.hs - compiler/GHC/CmmToAsm/PIC.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3a39d53833746c0b025815b1a604c294c63ca385...dc57c656ae3f1d9575fd29b39bd06540d34a74f4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3a39d53833746c0b025815b1a604c294c63ca385...dc57c656ae3f1d9575fd29b39bd06540d34a74f4 You're receiving 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 28 10:01:02 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Thu, 28 May 2020 06:01:02 -0400 Subject: [Git][ghc/ghc][wip/osa1/std_string_thunks] Fix unpackCString# entry Message-ID: <5ecf8bdea5cc4_6e263f9eeb6d00f021919bb@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/std_string_thunks at Glasgow Haskell Compiler / GHC Commits: bbf1a076 by Ömer Sinan Ağacan at 2020-05-28T13:00:49+03:00 Fix unpackCString# entry - - - - - 1 changed file: - rts/StgStdThunks.cmm Changes: ===================================== rts/StgStdThunks.cmm ===================================== @@ -305,6 +305,6 @@ INFO_TABLE(stg_MK_STRING, 0, 1, THUNK_STATIC, "stg_MK_STRING", "stg_MK_STRING") Sp_adj(-2); Sp(1) = node; Sp(0) = stg_bh_upd_frame_info; - jump ghczmprim_GHCziCString_unpackCStringzh_info(StgThunk_payload(node,0)); + jump stg_ap_n_fast(ghczmprim_GHCziCString_unpackCStringzh_info, StgThunk_payload(node, 0)); } } View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bbf1a076789c01cdb10c916f431417d345257938 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bbf1a076789c01cdb10c916f431417d345257938 You're receiving 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 28 10:08:41 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Thu, 28 May 2020 06:08:41 -0400 Subject: [Git][ghc/ghc][wip/osa1/std_string_thunks] Implement stack check Message-ID: <5ecf8da94d154_6e263f9eeb6d00f02195059@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/std_string_thunks at Glasgow Haskell Compiler / GHC Commits: f1154530 by Ömer Sinan Ağacan at 2020-05-28T13:08:31+03:00 Implement stack check - - - - - 1 changed file: - rts/StgStdThunks.cmm Changes: ===================================== rts/StgStdThunks.cmm ===================================== @@ -296,12 +296,18 @@ INFO_TABLE(stg_MK_STRING, 0, 1, THUNK_STATIC, "stg_MK_STRING", "stg_MK_STRING") { W_ newCAF_ret; + // TODO (osa): Not sure why we do stack check before `newCAF`, but this is + // how `unpackCString# str` thunks are today. + if (Sp - WDS(2) < SpLim) { + jump stg_gc_enter_1(node); + } + (newCAF_ret) = ccall newCAF(BaseReg "ptr", node "ptr"); if (newCAF_ret == 0) { jump node(); } else { - // TODO: Stack checks? + // Stack check done above Sp_adj(-2); Sp(1) = node; Sp(0) = stg_bh_upd_frame_info; View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f11545306dc083e14b104d2c0d7ef749dd6cb15a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f11545306dc083e14b104d2c0d7ef749dd6cb15a You're receiving 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 28 10:39:15 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Thu, 28 May 2020 06:39:15 -0400 Subject: [Git][ghc/ghc][wip/andreask/inlineable_mapAccumLM] Optimize GHC.Utils.Monad. Message-ID: <5ecf94d37d763_6e261275eeac22094e0@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/inlineable_mapAccumLM at Glasgow Haskell Compiler / GHC Commits: e793b9f3 by Andreas Klebinger at 2020-05-28T12:38:52+02:00 Optimize GHC.Utils.Monad. Many functions in this module are recursive and as such are marked loop breakers. Which means they are unlikely to get an unfolding. This is *bad*. We always want to specialize them to specific Monads. Which requires a visible unfolding at the use site. I rewrote the recursive ones from: foo f x = ... foo x' ... to foo f x = go x where go x = ... As well as giving some pragmas to make all of them available for specialization. The end result is a reduction of allocations of about -1.4% for nofib/spectral/simple/Main.hs when compiled with `-O`. ------------------------- Metric Decrease: T14683 T5631 T9233 T9675 T9961 WWRec ------------------------- - - - - - 1 changed file: - compiler/GHC/Utils/Monad.hs Changes: ===================================== compiler/GHC/Utils/Monad.hs ===================================== @@ -138,22 +138,31 @@ mapAndUnzip5M :: Monad m => (a -> m (b,c,d,e,f)) -> [a] -> m ([b],[c],[d],[e],[f -- See Note [Inline @mapAndUnzipNM@ functions] above. mapAndUnzip5M f xs = unzip5 <$> traverse f xs +-- TODO: mapAccumLM is used in many places. Surely most of +-- these don't actually want to be lazy. We should add a strict +-- variant and use it where appropriate. + -- | Monadic version of mapAccumL mapAccumLM :: Monad m => (acc -> x -> m (acc, y)) -- ^ combining function -> acc -- ^ initial state -> [x] -- ^ inputs -> m (acc, [y]) -- ^ final state, outputs -mapAccumLM _ s [] = return (s, []) -mapAccumLM f s (x:xs) = do - (s1, x') <- f s x - (s2, xs') <- mapAccumLM f s1 xs - return (s2, x' : xs') +mapAccumLM f s xs = + go s xs + where + go s (x:xs) = do + (s1, x') <- f s x + (s2, xs') <- go s1 xs + return (s2, x' : xs') + go s [] = return (s, []) -- | Monadic version of mapSnd mapSndM :: Monad m => (b -> m c) -> [(a,b)] -> m [(a,c)] -mapSndM _ [] = return [] -mapSndM f ((a,b):xs) = do { c <- f b; rs <- mapSndM f xs; return ((a,c):rs) } +mapSndM f xs = go xs + where + go [] = return [] + go ((a,b):xs) = do { c <- f b; rs <- go xs; return ((a,c):rs) } -- | Monadic version of concatMap concatMapM :: Monad m => (a -> m [b]) -> [a] -> m [b] @@ -176,15 +185,19 @@ fmapEitherM _ fr (Right b) = fr b >>= (return . Right) -- | Monadic version of 'any', aborts the computation at the first @True@ value anyM :: Monad m => (a -> m Bool) -> [a] -> m Bool -anyM _ [] = return False -anyM f (x:xs) = do b <- f x +anyM f xs = go xs + where + go [] = return False + go (x:xs) = do b <- f x if b then return True - else anyM f xs + else go xs -- | Monad version of 'all', aborts the computation at the first @False@ value allM :: Monad m => (a -> m Bool) -> [a] -> m Bool -allM _ [] = return True -allM f (b:bs) = (f b) >>= (\bv -> if bv then allM f bs else return False) +allM f bs = go bs + where + go [] = return True + go (b:bs) = (f b) >>= (\bv -> if bv then go bs else return False) -- | Monadic version of or orM :: Monad m => m Bool -> m Bool -> m Bool View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e793b9f32c7a75d2aeca4f911b5caca1629aee5f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e793b9f32c7a75d2aeca4f911b5caca1629aee5f You're receiving 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 28 10:45:16 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Thu, 28 May 2020 06:45:16 -0400 Subject: [Git][ghc/ghc][wip/osa1/std_string_thunks] Introduce a standard thunk for allocating strings Message-ID: <5ecf963ca7755_6e263f9f0bed50502211547@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/std_string_thunks at Glasgow Haskell Compiler / GHC Commits: 6a1ac542 by Ömer Sinan Ağacan at 2020-05-28T13:44:54+03:00 Introduce a standard thunk for allocating strings Currently for a top-level closure in the form hey = unpackCString# x we generate code like this: Main.hey_entry() // [R1] { info_tbls: [(c2T4, label: Main.hey_info rep: HeapRep static { Thunk } srt: Nothing)] stack_info: arg_space: 8 updfr_space: Just 8 } {offset c2T4: // global _rqm::P64 = R1; if ((Sp + 8) - 24 < SpLim) (likely: False) goto c2T5; else goto c2T6; c2T5: // global R1 = _rqm::P64; call (stg_gc_enter_1)(R1) args: 8, res: 0, upd: 8; c2T6: // global (_c2T1::I64) = call "ccall" arg hints: [PtrHint, PtrHint] result hints: [PtrHint] newCAF(BaseReg, _rqm::P64); if (_c2T1::I64 == 0) goto c2T3; else goto c2T2; c2T3: // global call (I64[_rqm::P64])() args: 8, res: 0, upd: 8; c2T2: // global I64[Sp - 16] = stg_bh_upd_frame_info; I64[Sp - 8] = _c2T1::I64; R2 = hey1_r2Gg_bytes; Sp = Sp - 16; call GHC.CString.unpackCString#_info(R2) args: 24, res: 0, upd: 24; } } This code is generated for every string literal. Only difference between top-level closures like this is the argument for the bytes of the string (hey1_r2Gg_bytes in the code above). With this patch we introduce a standard thunk in the RTS, called stg_MK_STRING_info, that does what `unpackCString# x` does, except it gets the bytes address from the payload. Using this, for the closure above, we generate this: Main.hey_closure" { Main.hey_closure: const stg_MK_STRING_info; const hey1_r1Gg_bytes; const 0; const 0; } This is much smaller in code. - - - - - 5 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/StgToCmm/Bind.hs - includes/stg/MiscClosures.h - rts/RtsSymbols.c - rts/StgStdThunks.cmm Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -23,6 +23,7 @@ module GHC.Cmm.CLabel ( mkConInfoTableLabel, mkApEntryLabel, mkApInfoTableLabel, + mkMkStringInfoTableLabel, mkClosureTableLabel, mkBytesLabel, @@ -61,6 +62,7 @@ module GHC.Cmm.CLabel ( mkCAFBlackHoleInfoTableLabel, mkRtsPrimOpLabel, mkRtsSlowFastTickyCtrLabel, + mkRtsMkStringLabel, mkSelectorInfoLabel, mkSelectorEntryLabel, @@ -426,6 +428,8 @@ data RtsLabelInfo | RtsApInfoTable Bool{-updatable-} Int{-arity-} -- ^ AP thunks | RtsApEntry Bool{-updatable-} Int{-arity-} + | RtsMkStringInfoTable + | RtsPrimOp PrimOp | RtsApFast FastString -- ^ _fast versions of generic apply | RtsSlowFastTickyCtr String @@ -569,16 +573,16 @@ mkLocalBlockLabel u = LocalBlockLabel u mkRtsPrimOpLabel :: PrimOp -> CLabel mkRtsPrimOpLabel primop = RtsLabel (RtsPrimOp primop) -mkSelectorInfoLabel :: Bool -> Int -> CLabel -mkSelectorEntryLabel :: Bool -> Int -> CLabel +mkSelectorInfoLabel, mkSelectorEntryLabel :: Bool -> Int -> CLabel mkSelectorInfoLabel upd off = RtsLabel (RtsSelectorInfoTable upd off) mkSelectorEntryLabel upd off = RtsLabel (RtsSelectorEntry upd off) -mkApInfoTableLabel :: Bool -> Int -> CLabel -mkApEntryLabel :: Bool -> Int -> CLabel +mkApInfoTableLabel, mkApEntryLabel :: Bool -> Int -> CLabel mkApInfoTableLabel upd off = RtsLabel (RtsApInfoTable upd off) mkApEntryLabel upd off = RtsLabel (RtsApEntry upd off) +mkMkStringInfoTableLabel :: CLabel +mkMkStringInfoTableLabel = RtsLabel RtsMkStringInfoTable -- A call to some primitive hand written Cmm code mkPrimCallLabel :: PrimCall -> CLabel @@ -671,6 +675,8 @@ mkRtsApFastLabel str = RtsLabel (RtsApFast str) mkRtsSlowFastTickyCtrLabel :: String -> CLabel mkRtsSlowFastTickyCtrLabel pat = RtsLabel (RtsSlowFastTickyCtr pat) +mkRtsMkStringLabel :: CLabel +mkRtsMkStringLabel = RtsLabel RtsMkStringInfoTable -- Constructing Code Coverage Labels mkHpcTicksLabel :: Module -> CLabel @@ -1296,6 +1302,8 @@ pprCLbl dflags = \case (CCS_Label ccs) -> ppr ccs (HpcTicksLabel mod) -> text "_hpc_tickboxes_" <> ppr mod <> ptext (sLit "_hpc") + (RtsLabel RtsMkStringInfoTable) -> text "stg_MK_STRING_info" + (AsmTempLabel {}) -> panic "pprCLbl AsmTempLabel" (AsmTempDerivedLabel {}) -> panic "pprCLbl AsmTempDerivedLabel" (DynamicLinkerLabel {}) -> panic "pprCLbl DynamicLinkerLabel" ===================================== compiler/GHC/StgToCmm/Bind.hs ===================================== @@ -51,6 +51,8 @@ import GHC.Utils.Outputable import GHC.Data.FastString import GHC.Driver.Session +import GHC.Builtin.Names (unpackCStringName) + import Control.Monad ------------------------------------------------------------------------ @@ -76,6 +78,9 @@ cgTopRhsClosure dflags rec id ccs upd_flag args body = lf_info = mkClosureLFInfo platform id TopLevel [] upd_flag args in (cg_id_info, gen_code dflags lf_info closure_label) where + + gen_code :: DynFlags -> LambdaFormInfo -> CLabel -> FCode () + -- special case for a indirection (f = g). We create an IND_STATIC -- closure pointing directly to the indirectee. This is exactly -- what the CAF will eventually evaluate to anyway, we're just @@ -90,11 +95,34 @@ cgTopRhsClosure dflags rec id ccs upd_flag args body = -- concurrent/should_run/4030 fails, for instance. -- gen_code _ _ closure_label - | StgApp f [] <- body, null args, isNonRec rec + | StgApp f [] <- body + , null args + , isNonRec rec = do cg_info <- getCgIdInfo f emitDataCon closure_label indStaticInfoTable ccs [unLit (idInfoToAmode cg_info)] + gen_code _ _ closure_label + | StgApp f [arg] <- stripStgTicksTopE (not . tickishIsCode) body + , idName f == unpackCStringName + = do -- TODO: What to do with ticks? + pprTrace "unpackCString#" (ppr body) (return ()) + arg' <- getArgAmode (NonVoid arg) + case arg' of + CmmLit lit -> do + let payload = [lit] + let info = CmmInfoTable + { cit_lbl = mkRtsMkStringLabel + , cit_rep = HeapRep True 0 1 Thunk + , cit_prof = NoProfilingInfo + , cit_srt = Nothing + , cit_clo = Nothing + } + emitDecl (CmmData (Section Data closure_label) (CmmStatics closure_label info ccs payload)) + + _ -> panic "cgTopRhsClosure.gen_code" + + gen_code dflags lf_info _closure_label = do { let name = idName id ; mod_name <- getModuleName @@ -222,6 +250,34 @@ mkRhsClosure :: DynFlags -> Id -> CostCentreStack -> CgStgExpr -> FCode (CgIdInfo, FCode CmmAGraph) +{- + TODO: Consider handling this too. Not sure if it's going to save us much to + so this needs benchmarking. + +---------- unpackCString# -------------------- +mkRhsClosure dflags bndr _cc + [] -- No free variables, because this is top-level + Updatable -- Updatable thunk + [] -- A thunk + expr + + | let expr_no_ticks = stripStgTicksTopE (not . tickishIsCode) expr + , StgApp fn [arg] <- expr + , idName fn == unpackCStringName + = -- TODO: What to do with ticks? + -- A non-top-level unpackCString# closure. Most unpackCString# closures are + -- floted to the top-level, but sometimes we see simplifier-generated thunks + -- like: + -- + -- sat_sK0 [Occ=Once] :: [GHC.Types.Char] + -- [LclId] = + -- {} \u [] + -- GHC.CString.unpackCString# + -- "Oops! The program has entered an `absent' argument!\n"#; + -- + pprPanic "mkRhsClosure" (text "unpackCString# closure:" <+> ppr expr) +-} + {- mkRhsClosure looks for two special forms of the right-hand side: a) selector thunks b) AP thunks ===================================== includes/stg/MiscClosures.h ===================================== @@ -241,6 +241,9 @@ RTS_THUNK(stg_ap_5_upd); RTS_THUNK(stg_ap_6_upd); RTS_THUNK(stg_ap_7_upd); +// Standard entry for `unpackCString# str` thunks +RTS_ENTRY(stg_MK_STRING); + /* standard application routines (see also utils/genapply, * and GHC.StgToCmm.ArgRep). */ ===================================== rts/RtsSymbols.c ===================================== @@ -914,6 +914,7 @@ SymI_HasProto(stg_sel_13_noupd_info) \ SymI_HasProto(stg_sel_14_noupd_info) \ SymI_HasProto(stg_sel_15_noupd_info) \ + SymI_HasProto(stg_MK_STRING_info) \ SymI_HasProto(stg_upd_frame_info) \ SymI_HasProto(stg_bh_upd_frame_info) \ SymI_HasProto(suspendThread) \ ===================================== rts/StgStdThunks.cmm ===================================== @@ -13,6 +13,8 @@ #include "Cmm.h" #include "Updates.h" +import CLOSURE ghczmprim_GHCziCString_unpackCStringzh_info; + /* ----------------------------------------------------------------------------- The code for a thunk that simply extracts a field from a single-constructor datatype depends only on the offset of the field @@ -284,3 +286,31 @@ INFO_TABLE(stg_ap_7_upd,7,0,THUNK,"stg_ap_7_upd_info","stg_ap_7_upd_info") StgThunk_payload(node,6)); } } + +/* ----------------------------------------------------------------------------- + Making strings + -------------------------------------------------------------------------- */ + +INFO_TABLE(stg_MK_STRING, 0, 1, THUNK_STATIC, "stg_MK_STRING", "stg_MK_STRING") + (P_ node) +{ + W_ newCAF_ret; + + // TODO (osa): Not sure why we do stack check before `newCAF`, but this is + // how `unpackCString# str` thunks are today. + if (Sp - WDS(2) < SpLim) { + jump stg_gc_enter_1(node); + } + + (newCAF_ret) = ccall newCAF(BaseReg "ptr", node "ptr"); + + if (newCAF_ret == 0) { + jump node(); + } else { + // Stack check done above + Sp_adj(-2); + Sp(1) = node; + Sp(0) = stg_bh_upd_frame_info; + jump stg_ap_n_fast(ghczmprim_GHCziCString_unpackCStringzh_info, StgThunk_payload(node, 0)); + } +} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6a1ac542f52e86daf4992adcf30eef39ebeb8db3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6a1ac542f52e86daf4992adcf30eef39ebeb8db3 You're receiving 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 28 11:28:22 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Thu, 28 May 2020 07:28:22 -0400 Subject: [Git][ghc/ghc][wip/osa1/std_string_thunks] Introduce a standard thunk for allocating strings Message-ID: <5ecfa056a5b9b_6e263f9ed652f4cc2220438@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/std_string_thunks at Glasgow Haskell Compiler / GHC Commits: df2ece33 by Ömer Sinan Ağacan at 2020-05-28T14:27:55+03:00 Introduce a standard thunk for allocating strings Currently for a top-level closure in the form hey = unpackCString# x we generate code like this: Main.hey_entry() // [R1] { info_tbls: [(c2T4, label: Main.hey_info rep: HeapRep static { Thunk } srt: Nothing)] stack_info: arg_space: 8 updfr_space: Just 8 } {offset c2T4: // global _rqm::P64 = R1; if ((Sp + 8) - 24 < SpLim) (likely: False) goto c2T5; else goto c2T6; c2T5: // global R1 = _rqm::P64; call (stg_gc_enter_1)(R1) args: 8, res: 0, upd: 8; c2T6: // global (_c2T1::I64) = call "ccall" arg hints: [PtrHint, PtrHint] result hints: [PtrHint] newCAF(BaseReg, _rqm::P64); if (_c2T1::I64 == 0) goto c2T3; else goto c2T2; c2T3: // global call (I64[_rqm::P64])() args: 8, res: 0, upd: 8; c2T2: // global I64[Sp - 16] = stg_bh_upd_frame_info; I64[Sp - 8] = _c2T1::I64; R2 = hey1_r2Gg_bytes; Sp = Sp - 16; call GHC.CString.unpackCString#_info(R2) args: 24, res: 0, upd: 24; } } This code is generated for every string literal. Only difference between top-level closures like this is the argument for the bytes of the string (hey1_r2Gg_bytes in the code above). With this patch we introduce a standard thunk in the RTS, called stg_MK_STRING_info, that does what `unpackCString# x` does, except it gets the bytes address from the payload. Using this, for the closure above, we generate this: Main.hey_closure" { Main.hey_closure: const stg_MK_STRING_info; const hey1_r1Gg_bytes; const 0; const 0; } This is much smaller in code. - - - - - 5 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/StgToCmm/Bind.hs - includes/stg/MiscClosures.h - rts/RtsSymbols.c - rts/StgStdThunks.cmm Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -23,6 +23,7 @@ module GHC.Cmm.CLabel ( mkConInfoTableLabel, mkApEntryLabel, mkApInfoTableLabel, + mkMkStringInfoTableLabel, mkClosureTableLabel, mkBytesLabel, @@ -61,6 +62,7 @@ module GHC.Cmm.CLabel ( mkCAFBlackHoleInfoTableLabel, mkRtsPrimOpLabel, mkRtsSlowFastTickyCtrLabel, + mkRtsMkStringLabel, mkSelectorInfoLabel, mkSelectorEntryLabel, @@ -426,6 +428,8 @@ data RtsLabelInfo | RtsApInfoTable Bool{-updatable-} Int{-arity-} -- ^ AP thunks | RtsApEntry Bool{-updatable-} Int{-arity-} + | RtsMkStringInfoTable + | RtsPrimOp PrimOp | RtsApFast FastString -- ^ _fast versions of generic apply | RtsSlowFastTickyCtr String @@ -569,16 +573,16 @@ mkLocalBlockLabel u = LocalBlockLabel u mkRtsPrimOpLabel :: PrimOp -> CLabel mkRtsPrimOpLabel primop = RtsLabel (RtsPrimOp primop) -mkSelectorInfoLabel :: Bool -> Int -> CLabel -mkSelectorEntryLabel :: Bool -> Int -> CLabel +mkSelectorInfoLabel, mkSelectorEntryLabel :: Bool -> Int -> CLabel mkSelectorInfoLabel upd off = RtsLabel (RtsSelectorInfoTable upd off) mkSelectorEntryLabel upd off = RtsLabel (RtsSelectorEntry upd off) -mkApInfoTableLabel :: Bool -> Int -> CLabel -mkApEntryLabel :: Bool -> Int -> CLabel +mkApInfoTableLabel, mkApEntryLabel :: Bool -> Int -> CLabel mkApInfoTableLabel upd off = RtsLabel (RtsApInfoTable upd off) mkApEntryLabel upd off = RtsLabel (RtsApEntry upd off) +mkMkStringInfoTableLabel :: CLabel +mkMkStringInfoTableLabel = RtsLabel RtsMkStringInfoTable -- A call to some primitive hand written Cmm code mkPrimCallLabel :: PrimCall -> CLabel @@ -671,6 +675,8 @@ mkRtsApFastLabel str = RtsLabel (RtsApFast str) mkRtsSlowFastTickyCtrLabel :: String -> CLabel mkRtsSlowFastTickyCtrLabel pat = RtsLabel (RtsSlowFastTickyCtr pat) +mkRtsMkStringLabel :: CLabel +mkRtsMkStringLabel = RtsLabel RtsMkStringInfoTable -- Constructing Code Coverage Labels mkHpcTicksLabel :: Module -> CLabel @@ -1296,6 +1302,8 @@ pprCLbl dflags = \case (CCS_Label ccs) -> ppr ccs (HpcTicksLabel mod) -> text "_hpc_tickboxes_" <> ppr mod <> ptext (sLit "_hpc") + (RtsLabel RtsMkStringInfoTable) -> text "stg_MK_STRING_info" + (AsmTempLabel {}) -> panic "pprCLbl AsmTempLabel" (AsmTempDerivedLabel {}) -> panic "pprCLbl AsmTempDerivedLabel" (DynamicLinkerLabel {}) -> panic "pprCLbl DynamicLinkerLabel" ===================================== compiler/GHC/StgToCmm/Bind.hs ===================================== @@ -51,6 +51,8 @@ import GHC.Utils.Outputable import GHC.Data.FastString import GHC.Driver.Session +import GHC.Builtin.Names (unpackCStringName) + import Control.Monad ------------------------------------------------------------------------ @@ -76,6 +78,9 @@ cgTopRhsClosure dflags rec id ccs upd_flag args body = lf_info = mkClosureLFInfo platform id TopLevel [] upd_flag args in (cg_id_info, gen_code dflags lf_info closure_label) where + + gen_code :: DynFlags -> LambdaFormInfo -> CLabel -> FCode () + -- special case for a indirection (f = g). We create an IND_STATIC -- closure pointing directly to the indirectee. This is exactly -- what the CAF will eventually evaluate to anyway, we're just @@ -90,11 +95,34 @@ cgTopRhsClosure dflags rec id ccs upd_flag args body = -- concurrent/should_run/4030 fails, for instance. -- gen_code _ _ closure_label - | StgApp f [] <- body, null args, isNonRec rec + | StgApp f [] <- body + , null args + , isNonRec rec = do cg_info <- getCgIdInfo f emitDataCon closure_label indStaticInfoTable ccs [unLit (idInfoToAmode cg_info)] + gen_code _ _ closure_label + | StgApp f [arg] <- stripStgTicksTopE (not . tickishIsCode) body + , idName f == unpackCStringName + = do -- TODO: What to do with ticks? + pprTrace "unpackCString#" (ppr body) (return ()) + arg' <- getArgAmode (NonVoid arg) + case arg' of + CmmLit lit -> do + let payload = [lit] + let info = CmmInfoTable + { cit_lbl = mkRtsMkStringLabel + , cit_rep = HeapRep True 0 1 Thunk + , cit_prof = NoProfilingInfo + , cit_srt = Nothing + , cit_clo = Nothing + } + emitDecl (CmmData (Section Data closure_label) (CmmStatics closure_label info ccs payload)) + + _ -> panic "cgTopRhsClosure.gen_code" + + gen_code dflags lf_info _closure_label = do { let name = idName id ; mod_name <- getModuleName @@ -222,6 +250,34 @@ mkRhsClosure :: DynFlags -> Id -> CostCentreStack -> CgStgExpr -> FCode (CgIdInfo, FCode CmmAGraph) +{- + TODO: Consider handling this too. Not sure if it's going to save us much to + so this needs benchmarking. + +---------- unpackCString# -------------------- +mkRhsClosure dflags bndr _cc + [] -- No free variables, because this is top-level + Updatable -- Updatable thunk + [] -- A thunk + expr + + | let expr_no_ticks = stripStgTicksTopE (not . tickishIsCode) expr + , StgApp fn [arg] <- expr + , idName fn == unpackCStringName + = -- TODO: What to do with ticks? + -- A non-top-level unpackCString# closure. Most unpackCString# closures are + -- floted to the top-level, but sometimes we see simplifier-generated thunks + -- like: + -- + -- sat_sK0 [Occ=Once] :: [GHC.Types.Char] + -- [LclId] = + -- {} \u [] + -- GHC.CString.unpackCString# + -- "Oops! The program has entered an `absent' argument!\n"#; + -- + pprPanic "mkRhsClosure" (text "unpackCString# closure:" <+> ppr expr) +-} + {- mkRhsClosure looks for two special forms of the right-hand side: a) selector thunks b) AP thunks ===================================== includes/stg/MiscClosures.h ===================================== @@ -241,6 +241,9 @@ RTS_THUNK(stg_ap_5_upd); RTS_THUNK(stg_ap_6_upd); RTS_THUNK(stg_ap_7_upd); +// Standard entry for `unpackCString# str` thunks +RTS_ENTRY(stg_MK_STRING); + /* standard application routines (see also utils/genapply, * and GHC.StgToCmm.ArgRep). */ ===================================== rts/RtsSymbols.c ===================================== @@ -914,6 +914,7 @@ SymI_HasProto(stg_sel_13_noupd_info) \ SymI_HasProto(stg_sel_14_noupd_info) \ SymI_HasProto(stg_sel_15_noupd_info) \ + SymI_HasProto(stg_MK_STRING_info) \ SymI_HasProto(stg_upd_frame_info) \ SymI_HasProto(stg_bh_upd_frame_info) \ SymI_HasProto(suspendThread) \ ===================================== rts/StgStdThunks.cmm ===================================== @@ -13,6 +13,8 @@ #include "Cmm.h" #include "Updates.h" +import CLOSURE ghczmprim_GHCziCString_unpackCStringzh_info; + /* ----------------------------------------------------------------------------- The code for a thunk that simply extracts a field from a single-constructor datatype depends only on the offset of the field @@ -284,3 +286,29 @@ INFO_TABLE(stg_ap_7_upd,7,0,THUNK,"stg_ap_7_upd_info","stg_ap_7_upd_info") StgThunk_payload(node,6)); } } + +/* ----------------------------------------------------------------------------- + Making strings + -------------------------------------------------------------------------- */ + +INFO_TABLE(stg_MK_STRING, 0, 1, THUNK_STATIC, "stg_MK_STRING", "stg_MK_STRING") + (P_ node) +{ + W_ newCAF_ret; + + // TODO (osa): Not sure why we do stack check before `newCAF`, but this is + // how `unpackCString# str` thunks are today. + STK_CHK_ENTER(WDS(2), node); + + (newCAF_ret) = ccall newCAF(BaseReg "ptr", node "ptr"); + + if (newCAF_ret == 0) { + jump node(); + } else { + // Stack check done above + Sp_adj(-2); + Sp(1) = node; + Sp(0) = stg_bh_upd_frame_info; + jump stg_ap_n_fast(ghczmprim_GHCziCString_unpackCStringzh_info, StgThunk_payload(node, 0)); + } +} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/df2ece33892e4f38608bdb76ddb0278e61749f59 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/df2ece33892e4f38608bdb76ddb0278e61749f59 You're receiving 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 28 12:03:53 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Thu, 28 May 2020 08:03:53 -0400 Subject: [Git][ghc/ghc][wip/osa1/std_string_thunks] 2 commits: Introduce a standard thunk for allocating strings Message-ID: <5ecfa8a9da242_6e263f9f0bed505022338a4@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/std_string_thunks at Glasgow Haskell Compiler / GHC Commits: 0b9e8e8a by Ömer Sinan Ağacan at 2020-05-28T15:02:30+03:00 Introduce a standard thunk for allocating strings Currently for a top-level closure in the form hey = unpackCString# x we generate code like this: Main.hey_entry() // [R1] { info_tbls: [(c2T4, label: Main.hey_info rep: HeapRep static { Thunk } srt: Nothing)] stack_info: arg_space: 8 updfr_space: Just 8 } {offset c2T4: // global _rqm::P64 = R1; if ((Sp + 8) - 24 < SpLim) (likely: False) goto c2T5; else goto c2T6; c2T5: // global R1 = _rqm::P64; call (stg_gc_enter_1)(R1) args: 8, res: 0, upd: 8; c2T6: // global (_c2T1::I64) = call "ccall" arg hints: [PtrHint, PtrHint] result hints: [PtrHint] newCAF(BaseReg, _rqm::P64); if (_c2T1::I64 == 0) goto c2T3; else goto c2T2; c2T3: // global call (I64[_rqm::P64])() args: 8, res: 0, upd: 8; c2T2: // global I64[Sp - 16] = stg_bh_upd_frame_info; I64[Sp - 8] = _c2T1::I64; R2 = hey1_r2Gg_bytes; Sp = Sp - 16; call GHC.CString.unpackCString#_info(R2) args: 24, res: 0, upd: 24; } } This code is generated for every string literal. Only difference between top-level closures like this is the argument for the bytes of the string (hey1_r2Gg_bytes in the code above). With this patch we introduce a standard thunk in the RTS, called stg_MK_STRING_info, that does what `unpackCString# x` does, except it gets the bytes address from the payload. Using this, for the closure above, we generate this: Main.hey_closure" { Main.hey_closure: const stg_MK_STRING_info; const hey1_r1Gg_bytes; const 0; const 0; } This is much smaller in code. - - - - - 7cd6b4a2 by Ömer Sinan Ağacan at 2020-05-28T15:03:42+03:00 Trying to fix top-level thunk layouts - - - - - 5 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/StgToCmm/Bind.hs - includes/stg/MiscClosures.h - rts/RtsSymbols.c - rts/StgStdThunks.cmm Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -23,6 +23,7 @@ module GHC.Cmm.CLabel ( mkConInfoTableLabel, mkApEntryLabel, mkApInfoTableLabel, + mkMkStringInfoTableLabel, mkClosureTableLabel, mkBytesLabel, @@ -61,6 +62,7 @@ module GHC.Cmm.CLabel ( mkCAFBlackHoleInfoTableLabel, mkRtsPrimOpLabel, mkRtsSlowFastTickyCtrLabel, + mkRtsMkStringLabel, mkSelectorInfoLabel, mkSelectorEntryLabel, @@ -426,6 +428,8 @@ data RtsLabelInfo | RtsApInfoTable Bool{-updatable-} Int{-arity-} -- ^ AP thunks | RtsApEntry Bool{-updatable-} Int{-arity-} + | RtsMkStringInfoTable + | RtsPrimOp PrimOp | RtsApFast FastString -- ^ _fast versions of generic apply | RtsSlowFastTickyCtr String @@ -569,16 +573,16 @@ mkLocalBlockLabel u = LocalBlockLabel u mkRtsPrimOpLabel :: PrimOp -> CLabel mkRtsPrimOpLabel primop = RtsLabel (RtsPrimOp primop) -mkSelectorInfoLabel :: Bool -> Int -> CLabel -mkSelectorEntryLabel :: Bool -> Int -> CLabel +mkSelectorInfoLabel, mkSelectorEntryLabel :: Bool -> Int -> CLabel mkSelectorInfoLabel upd off = RtsLabel (RtsSelectorInfoTable upd off) mkSelectorEntryLabel upd off = RtsLabel (RtsSelectorEntry upd off) -mkApInfoTableLabel :: Bool -> Int -> CLabel -mkApEntryLabel :: Bool -> Int -> CLabel +mkApInfoTableLabel, mkApEntryLabel :: Bool -> Int -> CLabel mkApInfoTableLabel upd off = RtsLabel (RtsApInfoTable upd off) mkApEntryLabel upd off = RtsLabel (RtsApEntry upd off) +mkMkStringInfoTableLabel :: CLabel +mkMkStringInfoTableLabel = RtsLabel RtsMkStringInfoTable -- A call to some primitive hand written Cmm code mkPrimCallLabel :: PrimCall -> CLabel @@ -671,6 +675,8 @@ mkRtsApFastLabel str = RtsLabel (RtsApFast str) mkRtsSlowFastTickyCtrLabel :: String -> CLabel mkRtsSlowFastTickyCtrLabel pat = RtsLabel (RtsSlowFastTickyCtr pat) +mkRtsMkStringLabel :: CLabel +mkRtsMkStringLabel = RtsLabel RtsMkStringInfoTable -- Constructing Code Coverage Labels mkHpcTicksLabel :: Module -> CLabel @@ -1296,6 +1302,8 @@ pprCLbl dflags = \case (CCS_Label ccs) -> ppr ccs (HpcTicksLabel mod) -> text "_hpc_tickboxes_" <> ppr mod <> ptext (sLit "_hpc") + (RtsLabel RtsMkStringInfoTable) -> text "stg_MK_STRING_info" + (AsmTempLabel {}) -> panic "pprCLbl AsmTempLabel" (AsmTempDerivedLabel {}) -> panic "pprCLbl AsmTempDerivedLabel" (DynamicLinkerLabel {}) -> panic "pprCLbl DynamicLinkerLabel" ===================================== compiler/GHC/StgToCmm/Bind.hs ===================================== @@ -51,6 +51,8 @@ import GHC.Utils.Outputable import GHC.Data.FastString import GHC.Driver.Session +import GHC.Builtin.Names (unpackCStringName) + import Control.Monad ------------------------------------------------------------------------ @@ -76,6 +78,9 @@ cgTopRhsClosure dflags rec id ccs upd_flag args body = lf_info = mkClosureLFInfo platform id TopLevel [] upd_flag args in (cg_id_info, gen_code dflags lf_info closure_label) where + + gen_code :: DynFlags -> LambdaFormInfo -> CLabel -> FCode () + -- special case for a indirection (f = g). We create an IND_STATIC -- closure pointing directly to the indirectee. This is exactly -- what the CAF will eventually evaluate to anyway, we're just @@ -90,11 +95,43 @@ cgTopRhsClosure dflags rec id ccs upd_flag args body = -- concurrent/should_run/4030 fails, for instance. -- gen_code _ _ closure_label - | StgApp f [] <- body, null args, isNonRec rec + | StgApp f [] <- body + , null args + , isNonRec rec = do cg_info <- getCgIdInfo f emitDataCon closure_label indStaticInfoTable ccs [unLit (idInfoToAmode cg_info)] + gen_code _ _ closure_label + | StgApp f [arg] <- stripStgTicksTopE (not . tickishIsCode) body + , idName f == unpackCStringName + = do -- TODO: What to do with ticks? + pprTrace "unpackCString#" (ppr body) (return ()) + arg' <- getArgAmode (NonVoid arg) + case arg' of + CmmLit lit -> do + let info = CmmInfoTable + { cit_lbl = mkRtsMkStringLabel + , cit_rep = HeapRep True 0 1 Thunk + , cit_prof = NoProfilingInfo + , cit_srt = Nothing + , cit_clo = Nothing + } + emitDecl $ CmmData (Section Data closure_label) $ + -- CmmStatics closure_label info ccs payload + let platform = targetPlatform dflags + layout = + [ CmmLabel (cit_lbl info) -- info ptr + , mkIntCLit platform 0 -- padding for indirectee after update + , mkIntCLit platform 0 -- static link + , mkIntCLit platform 0 -- saved info + , lit -- the payload! TODO FIXME HACK: we have to put it here as we don't support payload in top-level closures!!!!! + ] + in CmmStaticsRaw closure_label (map CmmStaticLit layout) + + _ -> panic "cgTopRhsClosure.gen_code" + + gen_code dflags lf_info _closure_label = do { let name = idName id ; mod_name <- getModuleName @@ -222,6 +259,34 @@ mkRhsClosure :: DynFlags -> Id -> CostCentreStack -> CgStgExpr -> FCode (CgIdInfo, FCode CmmAGraph) +{- + TODO: Consider handling this too. Not sure if it's going to save us much to + so this needs benchmarking. + +---------- unpackCString# -------------------- +mkRhsClosure dflags bndr _cc + [] -- No free variables, because this is top-level + Updatable -- Updatable thunk + [] -- A thunk + expr + + | let expr_no_ticks = stripStgTicksTopE (not . tickishIsCode) expr + , StgApp fn [arg] <- expr + , idName fn == unpackCStringName + = -- TODO: What to do with ticks? + -- A non-top-level unpackCString# closure. Most unpackCString# closures are + -- floted to the top-level, but sometimes we see simplifier-generated thunks + -- like: + -- + -- sat_sK0 [Occ=Once] :: [GHC.Types.Char] + -- [LclId] = + -- {} \u [] + -- GHC.CString.unpackCString# + -- "Oops! The program has entered an `absent' argument!\n"#; + -- + pprPanic "mkRhsClosure" (text "unpackCString# closure:" <+> ppr expr) +-} + {- mkRhsClosure looks for two special forms of the right-hand side: a) selector thunks b) AP thunks ===================================== includes/stg/MiscClosures.h ===================================== @@ -241,6 +241,9 @@ RTS_THUNK(stg_ap_5_upd); RTS_THUNK(stg_ap_6_upd); RTS_THUNK(stg_ap_7_upd); +// Standard entry for `unpackCString# str` thunks +RTS_ENTRY(stg_MK_STRING); + /* standard application routines (see also utils/genapply, * and GHC.StgToCmm.ArgRep). */ ===================================== rts/RtsSymbols.c ===================================== @@ -914,6 +914,7 @@ SymI_HasProto(stg_sel_13_noupd_info) \ SymI_HasProto(stg_sel_14_noupd_info) \ SymI_HasProto(stg_sel_15_noupd_info) \ + SymI_HasProto(stg_MK_STRING_info) \ SymI_HasProto(stg_upd_frame_info) \ SymI_HasProto(stg_bh_upd_frame_info) \ SymI_HasProto(suspendThread) \ ===================================== rts/StgStdThunks.cmm ===================================== @@ -13,6 +13,8 @@ #include "Cmm.h" #include "Updates.h" +import CLOSURE ghczmprim_GHCziCString_unpackCStringzh_closure; + /* ----------------------------------------------------------------------------- The code for a thunk that simply extracts a field from a single-constructor datatype depends only on the offset of the field @@ -284,3 +286,38 @@ INFO_TABLE(stg_ap_7_upd,7,0,THUNK,"stg_ap_7_upd_info","stg_ap_7_upd_info") StgThunk_payload(node,6)); } } + +/* ----------------------------------------------------------------------------- + Making strings + -------------------------------------------------------------------------- */ + +// FIXME HACK: We use CONSTR_NOCAF with 4 nptrs as we don't support having +// payload in top-level thunks. Fields are: +// - Padding for indirectee -- this is part of the thunk header! So below we use +// index 2 for the payload +// - Static link +// - Saved info +// - The actual payload! +INFO_TABLE(stg_MK_STRING, 0, 4, CONSTR_NOCAF, "stg_MK_STRING", "stg_MK_STRING") + (P_ node) +{ + W_ newCAF_ret; + W_ str; + + // TODO (osa): Not sure why we do stack check before `newCAF`, but this is + // how `unpackCString# str` thunks are today. + STK_CHK_ENTER(WDS(2), node); + + (newCAF_ret) = ccall newCAF(BaseReg "ptr", node "ptr"); + + if (newCAF_ret == 0) { + jump node(); + } else { + // Stack check done above + Sp_adj(-2); + Sp(1) = node; + Sp(0) = stg_bh_upd_frame_info; + // TODO: Make this a direct call + jump stg_ap_n_fast(ghczmprim_GHCziCString_unpackCStringzh_closure, StgThunk_payload(node, 2)); + } +} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/df2ece33892e4f38608bdb76ddb0278e61749f59...7cd6b4a276677620b2859586ff8df693ded18565 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/df2ece33892e4f38608bdb76ddb0278e61749f59...7cd6b4a276677620b2859586ff8df693ded18565 You're receiving 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 28 16:05:02 2020 From: gitlab at gitlab.haskell.org (Andreas Klebinger) Date: Thu, 28 May 2020 12:05:02 -0400 Subject: [Git][ghc/ghc][wip/andreask/inlineable_mapAccumLM] Optimize GHC.Utils.Monad. Message-ID: <5ecfe12e88ef7_6e263f9ed652f4cc2329263@gitlab.haskell.org.mail> Andreas Klebinger pushed to branch wip/andreask/inlineable_mapAccumLM at Glasgow Haskell Compiler / GHC Commits: 57168fc0 by Andreas Klebinger at 2020-05-28T18:04:25+02:00 Optimize GHC.Utils.Monad. Many functions in this module are recursive and as such are marked loop breakers. Which means they are unlikely to get an unfolding. This is *bad*. We always want to specialize them to specific Monads. Which requires a visible unfolding at the use site. I rewrote the recursive ones from: foo f x = ... foo x' ... to foo f x = go x where go x = ... As well as giving some pragmas to make all of them available for specialization. The end result is a reduction of allocations of about -1.4% for nofib/spectral/simple/Main.hs when compiled with `-O`. ------------------------- Metric Decrease: T12425 T14683 T5631 T9233 T9675 T9961 WWRec ------------------------- - - - - - 1 changed file: - compiler/GHC/Utils/Monad.hs Changes: ===================================== compiler/GHC/Utils/Monad.hs ===================================== @@ -138,22 +138,31 @@ mapAndUnzip5M :: Monad m => (a -> m (b,c,d,e,f)) -> [a] -> m ([b],[c],[d],[e],[f -- See Note [Inline @mapAndUnzipNM@ functions] above. mapAndUnzip5M f xs = unzip5 <$> traverse f xs +-- TODO: mapAccumLM is used in many places. Surely most of +-- these don't actually want to be lazy. We should add a strict +-- variant and use it where appropriate. + -- | Monadic version of mapAccumL mapAccumLM :: Monad m => (acc -> x -> m (acc, y)) -- ^ combining function -> acc -- ^ initial state -> [x] -- ^ inputs -> m (acc, [y]) -- ^ final state, outputs -mapAccumLM _ s [] = return (s, []) -mapAccumLM f s (x:xs) = do - (s1, x') <- f s x - (s2, xs') <- mapAccumLM f s1 xs - return (s2, x' : xs') +mapAccumLM f s xs = + go s xs + where + go s (x:xs) = do + (s1, x') <- f s x + (s2, xs') <- go s1 xs + return (s2, x' : xs') + go s [] = return (s, []) -- | Monadic version of mapSnd mapSndM :: Monad m => (b -> m c) -> [(a,b)] -> m [(a,c)] -mapSndM _ [] = return [] -mapSndM f ((a,b):xs) = do { c <- f b; rs <- mapSndM f xs; return ((a,c):rs) } +mapSndM f xs = go xs + where + go [] = return [] + go ((a,b):xs) = do { c <- f b; rs <- go xs; return ((a,c):rs) } -- | Monadic version of concatMap concatMapM :: Monad m => (a -> m [b]) -> [a] -> m [b] @@ -176,15 +185,19 @@ fmapEitherM _ fr (Right b) = fr b >>= (return . Right) -- | Monadic version of 'any', aborts the computation at the first @True@ value anyM :: Monad m => (a -> m Bool) -> [a] -> m Bool -anyM _ [] = return False -anyM f (x:xs) = do b <- f x +anyM f xs = go xs + where + go [] = return False + go (x:xs) = do b <- f x if b then return True - else anyM f xs + else go xs -- | Monad version of 'all', aborts the computation at the first @False@ value allM :: Monad m => (a -> m Bool) -> [a] -> m Bool -allM _ [] = return True -allM f (b:bs) = (f b) >>= (\bv -> if bv then allM f bs else return False) +allM f bs = go bs + where + go [] = return True + go (b:bs) = (f b) >>= (\bv -> if bv then go bs else return False) -- | Monadic version of or orM :: Monad m => m Bool -> m Bool -> m Bool View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/57168fc00ce30671fc482d113dc13731b9f2265d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/57168fc00ce30671fc482d113dc13731b9f2265d You're receiving 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 28 16:35:23 2020 From: gitlab at gitlab.haskell.org (Peter Trommler) Date: Thu, 28 May 2020 12:35:23 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18250 Message-ID: <5ecfe84b6cab6_6e263f9f0ce68a6c233351f@gitlab.haskell.org.mail> Peter Trommler pushed new branch wip/T18250 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18250 You're receiving 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 28 16:49:14 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 28 May 2020 12:49:14 -0400 Subject: [Git][ghc/ghc][ghc-8.8] 8 commits: Set RELEASE=NO Message-ID: <5ecfeb8a528ab_6e263f9ed652f4cc2339028@gitlab.haskell.org.mail> Ben Gamari pushed to branch ghc-8.8 at Glasgow Haskell Compiler / GHC Commits: ebc670a2 by Ben Gamari at 2020-05-27T22:29:40-04:00 Set RELEASE=NO - - - - - 37c0dd8f by Alp Mestanogullari at 2020-05-27T22:47:06-04:00 Hadrian: track mingw, ship it in bindists, more robust install script (cherry picked from commit 22c2713bcc30cea9da7d8b95f3ea99357d1551f7) - - - - - 53b6bdee by Ben Gamari at 2020-05-27T22:47:11-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. (cherry picked from commit f684a7d505f19bd78f178e01bbd8e4467aaa00ea) - - - - - 5133f5c2 by Ben Gamari at 2020-05-27T23:14:28-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. (cherry picked from commit 2290eb02cf95e9cfffcb15fc9c593d5ef79c75d9) - - - - - 66de4d07 by Ben Gamari at 2020-05-27T23:14:28-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. (cherry picked from commit eba58110538686d8fe57d5dd372624b50f1fa2b7) - - - - - 6507c2bf by Sylvain Henry at 2020-05-27T23:14:28-04:00 Rts: show errno on failure (#18033) (cherry picked from commit 4875d419ba066e479f7ac07f8b39ebe10c855859) - - - - - 286cf192 by Ben Gamari at 2020-05-27T23:14:28-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) - - - - - 9037a2b6 by Sylvain Henry at 2020-05-27T23:14:28-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 (cherry picked from commit 12789d3ac30dd90f77593e99ef51e54b14fbf556) - - - - - 11 changed files: - compiler/deSugar/Coverage.hs - configure.ac - hadrian/src/Base.hs - hadrian/src/Builder.hs - hadrian/src/Rules/BinaryDist.hs - hadrian/src/Rules/Program.hs - hadrian/src/Settings/Builders/Cabal.hs - hadrian/src/Settings/Packages.hs - rts/linker/PEi386.c - rts/posix/itimer/Pthread.c - utils/iserv/ghc.mk Changes: ===================================== compiler/deSugar/Coverage.hs ===================================== @@ -111,7 +111,7 @@ addTicksToBinds hsc_env mod mod_loc exports tyCons binds dumpIfSet_dyn dflags Opt_D_dump_ticked "HPC" (pprLHsBinds binds1) - return (binds1, HpcInfo tickCount hashNo, Just modBreaks) + return (binds1, HpcInfo tickCount hashNo, modBreaks) | otherwise = return (binds, emptyHpcInfo False, Nothing) @@ -128,23 +128,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_] @@ -1038,7 +1038,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 $ @@ -1046,6 +1046,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. ===================================== configure.ac ===================================== @@ -16,7 +16,7 @@ dnl AC_INIT([The Glorious Glasgow Haskell Compilation System], [8.8.3], [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 ===================================== hadrian/src/Base.hs ===================================== @@ -25,7 +25,7 @@ module Base ( hadrianPath, configPath, configFile, sourcePath, shakeFilesDir, generatedDir, generatedPath, stageBinPath, stageLibPath, templateHscPath, ghcDeps, haddockDeps, relativePackageDbPath, packageDbPath, packageDbStamp, - ghcSplitPath + mingwStamp, ghcSplitPath ) where import Control.Applicative @@ -137,3 +137,9 @@ templateHscPath stage = stageLibPath stage <&> (-/- "template-hsc.h") -- to the build root under which we will copy @ghc-split at . ghcSplitPath :: Stage -> FilePath ghcSplitPath stage = stageString stage -/- "bin" -/- "ghc-split" + +-- | We use this stamp file to track whether we've moved the mingw toolchain +-- under the build root (to make it accessible to the GHCs we build on +-- Windows). See "Rules.Program". +mingwStamp :: FilePath +mingwStamp = "mingw" -/- ".stamp" ===================================== hadrian/src/Builder.hs ===================================== @@ -184,6 +184,10 @@ instance H.Builder Builder where , unlitPath ] ++ ghcdeps ++ [ touchyPath | win ] + ++ [ root -/- mingwStamp | win ] + -- proxy for the entire mingw toolchain that + -- we have in inplace/mingw initially, and then at + -- root -/- mingw. Hsc2Hs stage -> (\p -> [p]) <$> templateHscPath stage Make dir -> return [dir -/- "Makefile"] ===================================== hadrian/src/Rules/BinaryDist.hs ===================================== @@ -100,6 +100,7 @@ bindistRules = do targetPlatform <- setting TargetPlatformFull distDir <- Context.distDir rtsDir <- pkgIdentifier rts + windows <- windowsHost let ghcBuildDir = root -/- stageString Stage1 bindistFilesDir = root -/- "bindist" -/- ghcVersionPretty @@ -115,6 +116,12 @@ bindistRules = do copyDirectory (rtsIncludeDir) bindistFilesDir need ["docs"] copyDirectory (root -/- "docs") bindistFilesDir + when windows $ do + copyDirectory (root -/- "mingw") bindistFilesDir + -- we use that opportunity to delete the .stamp file that we use + -- as a proxy for the whole mingw toolchain, there's no point in + -- shipping it + removeFile (bindistFilesDir -/- mingwStamp) -- We copy the binary (/stage1/bin/haddock) to -- the bindist's bindir (/bindist/ghc-.../bin/). @@ -132,7 +139,8 @@ bindistRules = do , "runghc"] -- Finally, we create the archive /bindist/ghc-X.Y.Z-platform.tar.xz - command [Cwd $ root -/- "bindist"] "tar" + tarPath <- builderPath (Tar Create) + cmd [Cwd $ root -/- "bindist"] tarPath [ "-c", "--xz", "-f" , ghcVersionPretty <.> "tar.xz" , ghcVersionPretty ] @@ -224,19 +232,19 @@ bindistMakefile = unlines , "# to it. This implementation is a bit hacky and depends on consistency" , "# of program names. For hadrian build this will work as programs have a" , "# consistent naming procedure." - , "\trm -f $2" - , "\t$(CREATE_SCRIPT) $2" - , "\t at echo \"#!$(SHELL)\" >> $2" - , "\t at echo \"exedir=\\\"$4\\\"\" >> $2" - , "\t at echo \"exeprog=\\\"$1\\\"\" >> $2" - , "\t at echo \"executablename=\\\"$5\\\"\" >> $2" - , "\t at echo \"bindir=\\\"$3\\\"\" >> $2" - , "\t at echo \"libdir=\\\"$6\\\"\" >> $2" - , "\t at echo \"docdir=\\\"$7\\\"\" >> $2" - , "\t at echo \"includedir=\\\"$8\\\"\" >> $2" - , "\t at echo \"\" >> $2 " - , "\tcat wrappers/$1 >> $2" - , "\t$(EXECUTABLE_FILE) $2 ;" + , "\trm -f '$2'" + , "\t$(CREATE_SCRIPT) '$2'" + , "\t at echo \"#!$(SHELL)\" >> '$2'" + , "\t at echo \"exedir=\\\"$4\\\"\" >> '$2'" + , "\t at echo \"exeprog=\\\"$1\\\"\" >> '$2'" + , "\t at echo \"executablename=\\\"$5\\\"\" >> '$2'" + , "\t at echo \"bindir=\\\"$3\\\"\" >> '$2'" + , "\t at echo \"libdir=\\\"$6\\\"\" >> '$2'" + , "\t at echo \"docdir=\\\"$7\\\"\" >> '$2'" + , "\t at echo \"includedir=\\\"$8\\\"\" >> '$2'" + , "\t at echo \"\" >> '$2'" + , "\tcat wrappers/$1 >> '$2'" + , "\t$(EXECUTABLE_FILE) '$2' ;" , "endef" , "" , "# Hacky function to patch up the 'haddock-interfaces' and 'haddock-html'" @@ -245,10 +253,10 @@ bindistMakefile = unlines , "# $1 = package name (ex: 'bytestring')" , "# $2 = path to .conf file" , "# $3 = Docs Directory" - , "\tcat $2 | sed 's|haddock-interfaces.*|haddock-interfaces: $3/html/libraries/$1/$1.haddock|' \\" - , "\t | sed 's|haddock-html.*|haddock-html: $3/html/libraries/$1|' \\" - , "\t > $2.copy" - , "\tmv $2.copy $2" + , "\tcat '$2' | sed 's|haddock-interfaces.*|haddock-interfaces: $3/html/libraries/$1/$1.haddock|' \\" + , "\t | sed 's|haddock-html.*|haddock-html: $3/html/libraries/$1|' \\" + , "\t > '$2.copy'" + , "\tmv '$2.copy' '$2'" , "endef" , "" , "# QUESTION : should we use shell commands?" @@ -257,7 +265,7 @@ bindistMakefile = unlines , ".PHONY: install" , "install: install_lib install_bin install_includes" , "install: install_docs install_wrappers install_ghci" - , "install: update_package_db" + , "install: install_mingw update_package_db" , "" , "ActualBinsDir=${ghclibdir}/bin" , "WrapperBinsDir=${bindir}" @@ -273,10 +281,10 @@ bindistMakefile = unlines , "" , "install_ghci:" , "\t at echo \"Copying and installing ghci\"" - , "\t$(CREATE_SCRIPT) $(WrapperBinsDir)/ghci" - , "\t at echo \"#!$(SHELL)\" >> $(WrapperBinsDir)/ghci" - , "\tcat wrappers/ghci-script >> $(WrapperBinsDir)/ghci" - , "\t$(EXECUTABLE_FILE) $(WrapperBinsDir)/ghci" + , "\t$(CREATE_SCRIPT) '$(WrapperBinsDir)/ghci'" + , "\t at echo \"#!$(SHELL)\" >> '$(WrapperBinsDir)/ghci'" + , "\tcat wrappers/ghci-script >> '$(WrapperBinsDir)/ghci'" + , "\t$(EXECUTABLE_FILE) '$(WrapperBinsDir)/ghci'" , "" , "LIBRARIES = $(wildcard ./lib/*)" , "install_lib:" @@ -302,7 +310,7 @@ bindistMakefile = unlines , "\t\tcp -R $$i \"$(docdir)/\"; \\" , "\tdone" , "" - , "BINARY_NAMES=$(shell ls ./bin/)" + , "BINARY_NAMES=$(shell ls ./wrappers/)" , "install_wrappers:" , "\t at echo \"Installing Wrapper scripts\"" , "\t$(INSTALL_DIR) \"$(WrapperBinsDir)\"" @@ -318,8 +326,16 @@ bindistMakefile = unlines , "\t\t$(call patchpackageconf," ++ "$(shell echo $(notdir $p) | sed 's/-\\([0-9]*[0-9]\\.\\)*conf//g')," ++ "$p,$(docdir)))" - , "\t$(WrapperBinsDir)/ghc-pkg recache" + , "\t'$(WrapperBinsDir)/ghc-pkg' recache" , "" + , "# The 'foreach' that copies the mingw directory will only trigger a copy" + , "# when the wildcard matches, therefore only on Windows." + , "MINGW = $(wildcard ./mingw)" + , "install_mingw:" + , "\t at echo \"Installing MingGW\"" + , "\t$(INSTALL_DIR) \"$(prefix)/mingw\"" + , "\t$(foreach d, $(MINGW),\\" + , "\t\tcp -R ./mingw \"$(prefix)\")" , "# END INSTALL" , "# ----------------------------------------------------------------------" ] @@ -385,3 +401,19 @@ ghciScriptWrapper = unlines [ "DIR=`dirname \"$0\"`" , "executable=\"$DIR/ghc\"" , "exec $executable --interactive \"$@\"" ] + +-- | When not on Windows, we want to ship the 3 flavours of the iserv program +-- in binary distributions. This isn't easily achievable by just asking for +-- the package to be built, since here we're generating 3 different +-- executables out of just one package, so we need to specify all 3 contexts +-- explicitly and 'need' the result of building them. +needIservBins :: Action () +needIservBins = do + windows <- windowsHost + when (not windows) $ do + rtsways <- interpretInContext (vanillaContext Stage1 ghc) getRtsWays + need =<< traverse programPath + [ Context Stage1 iserv w + | w <- [vanilla, profiling, dynamic] + , w `elem` rtsways + ] ===================================== hadrian/src/Rules/Program.hs ===================================== @@ -8,6 +8,7 @@ import Context import Expression hiding (stage, way) import Oracles.Flag import Oracles.ModuleFiles +import Oracles.Setting (topDirectory) import Packages import Settings import Settings.Default @@ -19,6 +20,18 @@ import Flavour buildProgramRules :: [(Resource, Int)] -> Rules () buildProgramRules rs = do root <- buildRootRules + + -- Proxy rule for the whole mingw toolchain on Windows. + -- We 'need' configure because that's when the inplace/mingw + -- folder gets filled with the toolchain. This "proxy" rule + -- is listed as a runtime dependency for stage >= 1 GHCs. + root -/- mingwStamp %> \stampPath -> do + top <- topDirectory + need [ top -/- "configure" ] + copyDirectory (top -/- "inplace" -/- "mingw") root + writeFile' stampPath "OK" + + -- Rules for programs that are actually built by hadrian. forM_ [Stage0 ..] $ \stage -> [ root -/- stageString stage -/- "bin" -/- "*" , root -/- stageString stage -/- "lib/bin" -/- "*" ] |%> \bin -> do ===================================== hadrian/src/Settings/Builders/Cabal.hs ===================================== @@ -16,6 +16,8 @@ cabalBuilderArgs = builder (Cabal Setup) ? do pkg <- getPackage path <- getContextPath stage <- getStage + windows <- expr windowsHost + let prefix = "${pkgroot}" ++ (if windows then "" else "/..") mconcat [ arg "configure" -- Don't strip libraries when cross compiling. -- TODO: We need to set @--with-strip=(stripCmdPath :: Action FilePath)@, @@ -32,7 +34,7 @@ cabalBuilderArgs = builder (Cabal Setup) ? do , arg "--ipid" , arg "$pkg-$version" , arg "--prefix" - , arg "${pkgroot}/.." + , arg prefix -- NB: this is valid only because Hadrian puts the @docs@ and -- @libraries@ folders in the same relative position: ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -119,6 +119,14 @@ packageArgs = do [ notStage0 ? builder (Cabal Flags) ? arg "ghci" , flag CrossCompiling ? stage0 ? builder (Cabal Flags) ? arg "ghci" ] + --------------------------------- iserv -------------------------------- + -- Add -Wl,--export-dynamic enables GHCi to load dynamic objects that + -- refer to the RTS. This is harmless if you don't use it (adds a bit + -- of overhead to startup and increases the binary sizes) but if you + -- need it there's no alternative. + , package iserv ? mconcat + [ builder (Ghc LinkHs) ? arg "-optl-Wl,--export-dynamic" ] + -------------------------------- haddock ------------------------------- , package haddock ? builder (Cabal Flags) ? arg "in-ghc-tree" ===================================== rts/linker/PEi386.c ===================================== @@ -769,12 +769,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,22 +109,30 @@ 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 while (!exited) { if (USE_TIMERFD_FOR_ITIMER) { - if (read(timerfd, &nticks, sizeof(nticks)) != sizeof(nticks)) { - if (errno != EINTR) { - barf("Itimer: read(timerfd) failed"); - } + ssize_t r = read(timerfd, &nticks, sizeof(nticks)); + if ((r == 0) && (errno == 0)) { + /* r == 0 is expected only for non-blocking fd (in which case + * errno should be EAGAIN) but we use a blocking fd. + * + * Due to a kernel bug (cf https://lkml.org/lkml/2019/8/16/335) + * on some platforms we could see r == 0 and errno == 0. + */ + IF_DEBUG(scheduler, debugBelch("read(timerfd) returned 0 with errno=0. This is a known kernel bug. We just ignore it.")); + } + else if (r != sizeof(nticks) && errno != EINTR) { + barf("Itimer: read(timerfd) failed with %s and returned %zd", strerror(errno), r); } } else { if (usleep(TimeToUS(itimer_interval)) != 0 && errno != EINTR) { @@ -169,7 +177,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 +211,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); ===================================== utils/iserv/ghc.mk ===================================== @@ -30,8 +30,9 @@ endif # refer to the RTS. This is harmless if you don't use it (adds a bit # of overhead to startup and increases the binary sizes) but if you # need it there's no alternative. +# Don't do this on FreeBSD to work around #17962. ifeq "$(TargetElf)" "YES" -ifneq "$(TargetOS_CPP)" "solaris2" +ifeq "$(findstring $(TargetOS_CPP), solaris2 freebsd)" "" # The Solaris linker does not support --export-dynamic option. It also # does not need it since it exports all dynamic symbols by default utils/iserv_stage2_MORE_HC_OPTS += -optl-Wl,--export-dynamic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/dade73c7849d05bc50d35e4c8411e2fdbba75f2a...9037a2b64ec78cc6d6946aae118622517c8163e2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/dade73c7849d05bc50d35e4c8411e2fdbba75f2a...9037a2b64ec78cc6d6946aae118622517c8163e2 You're receiving 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 28 20:23:32 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 28 May 2020 16:23:32 -0400 Subject: [Git][ghc/ghc][master] 2 commits: GHC.Core.Unfold: Refactor traceInline Message-ID: <5ed01dc4ec50d_6e263f9eeae1d12424078c8@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 28deee28 by Ben Gamari at 2020-05-28T16:23:21-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 - - - - - 1f393e1e by Ben Gamari at 2020-05-28T16:23:21-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 haddock.Cabal haddock.base haddock.compiler - - - - - 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 ===================================== @@ -1277,16 +1277,23 @@ callSiteInline dflags id active_unfolding lone_variable arg_infos cont_info OtherCon {} -> Nothing DFunUnfolding {} -> Nothing -- Never unfold a DFun +-- | 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 - | Just prefix <- inlineCheck dflags - = if prefix `isPrefixOf` occNameString (getOccName inline_id) - then traceAction dflags str doc result - else result - | dopt Opt_D_dump_inlinings dflags && dopt Opt_D_verbose_core2core dflags - = traceAction dflags str doc result - | otherwise - = 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 + enable + | dopt Opt_D_dump_inlinings dflags && dopt Opt_D_verbose_core2core dflags + = 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/-/compare/d6203f24cf421749616a247c047a9b44192f963a...1f393e1e0a2998fe67cfd06501e35f495758b98f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d6203f24cf421749616a247c047a9b44192f963a...1f393e1e0a2998fe67cfd06501e35f495758b98f You're receiving 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 28 20:24:09 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 28 May 2020 16:24:09 -0400 Subject: [Git][ghc/ghc][master] Add Semigroup/Monoid for Q (#18123) Message-ID: <5ed01de939db8_6e263f9ee3c1eb54241219c@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 5f621a78 by Vladislav Zavialov at 2020-05-28T16:23:58-04:00 Add Semigroup/Monoid for Q (#18123) - - - - - 4 changed files: - libraries/template-haskell/Language/Haskell/TH/Syntax.hs - libraries/template-haskell/changelog.md - + testsuite/tests/th/T18123.hs - testsuite/tests/th/all.T Changes: ===================================== 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,14 @@ instance Applicative Q where Q f <*> Q x = Q (f <*> x) Q m *> Q n = Q (m *> n) +-- | @since 2.17.0.0 +instance Semigroup a => Semigroup (Q a) where + (<>) = liftA2 (<>) + +-- | @since 2.17.0.0 +instance Monoid a => Monoid (Q a) where + mempty = pure mempty + ----------------------------------------------------- -- -- The Quote class ===================================== libraries/template-haskell/changelog.md ===================================== @@ -22,6 +22,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 ===================================== 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 ===================================== @@ -507,3 +507,4 @@ 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/-/commit/5f621a78217237a4bdfb299b68827da6cc8f357e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5f621a78217237a4bdfb299b68827da6cc8f357e You're receiving 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 28 20:24:48 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 28 May 2020 16:24:48 -0400 Subject: [Git][ghc/ghc][master] Fix #18071 Message-ID: <5ed01e1065b_6e263f9ed663c68024165bb@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: dc5f004c by Xavier Denis at 2020-05-28T16:24:37-04:00 Fix #18071 Run the core linter on candidate instances to ensure they are well-kinded. Better handle quantified constraints by using a CtWanted to avoid having unsolved constraints thrown away at the end by the solver. - - - - - 5 changed files: - compiler/GHC/Runtime/Eval.hs - + testsuite/tests/ghci/T18071/T18071.hs - + testsuite/tests/ghci/T18071/T18071.script - + testsuite/tests/ghci/T18071/T18071.stdout - + testsuite/tests/ghci/T18071/all.T Changes: ===================================== compiler/GHC/Runtime/Eval.hs ===================================== @@ -64,6 +64,7 @@ import GHC.Core.FamInstEnv ( FamInst ) import GHC.Core.FVs ( orphNamesOfFamInst ) import GHC.Core.TyCon import GHC.Core.Type hiding( typeKind ) +import qualified GHC.Core.Type as Type import GHC.Types.RepType import GHC.Tc.Utils.TcType import GHC.Tc.Types.Constraint @@ -115,16 +116,14 @@ import Unsafe.Coerce ( unsafeCoerce ) import GHC.Tc.Module ( runTcInteractive, tcRnType, loadUnqualIfaces ) import GHC.Tc.Utils.Zonk ( ZonkFlexi (SkolemiseFlexi) ) - import GHC.Tc.Utils.Env (tcGetInstEnvs) - import GHC.Tc.Utils.Instantiate (instDFunType) import GHC.Tc.Solver (solveWanteds) import GHC.Tc.Utils.Monad import GHC.Tc.Types.Evidence import Data.Bifunctor (second) - import GHC.Tc.Solver.Monad (runTcS) +import GHC.Core.Class (classTyCon) -- ----------------------------------------------------------------------------- -- running a statement interactively @@ -1056,6 +1055,7 @@ getInstancesForType ty = withSession $ \hsc_env -> do -- Bring class and instances from unqualified modules into scope, this fixes #16793. loadUnqualIfaces hsc_env (hsc_IC hsc_env) matches <- findMatchingInstances ty + fmap catMaybes . forM matches $ uncurry checkForExistence -- Parse a type string and turn any holes into skolems @@ -1074,13 +1074,41 @@ getDictionaryBindings theta = do dictName <- newName (mkDictOcc (mkVarOcc "magic")) let dict_var = mkVanillaGlobal dictName theta loc <- getCtLocM (GivenOrigin UnkSkol) Nothing - let wCs = mkSimpleWC [CtDerived - { ctev_pred = varType dict_var - , ctev_loc = loc - }] + + -- Generate a wanted constraint here because at the end of constraint + -- solving, most derived constraints get thrown away, which in certain + -- cases, notably with quantified constraints makes it impossible to rule + -- out instances as invalid. (See #18071) + let wCs = mkSimpleWC [CtWanted { + ctev_pred = varType dict_var, + ctev_dest = EvVarDest dict_var, + ctev_nosh = WDeriv, + ctev_loc = loc + }] return wCs +-- Find instances where the head unifies with the provided type +findMatchingInstances :: Type -> TcM [(ClsInst, [DFunInstType])] +findMatchingInstances ty = do + ies@(InstEnvs {ie_global = ie_global, ie_local = ie_local}) <- tcGetInstEnvs + let allClasses = instEnvClasses ie_global ++ instEnvClasses ie_local + return $ concatMap (try_cls ies) allClasses + where + {- Check that a class instance is well-kinded. + Since `:instances` only works for unary classes, we're looking for instances of kind + k -> Constraint where k is the type of the queried type. + -} + try_cls ies cls + | Just (arg_kind, res_kind) <- splitFunTy_maybe (tyConKind $ classTyCon cls) + , tcIsConstraintKind res_kind + , Type.typeKind ty `eqType` arg_kind + , (matches, _, _) <- lookupInstEnv True ies cls [ty] + = matches + | otherwise + = [] + + {- When we've found an instance that a query matches against, we still need to check that all the instance's constraints are satisfiable. checkForExistence @@ -1105,19 +1133,28 @@ getDictionaryBindings theta = do -} checkForExistence :: ClsInst -> [DFunInstType] -> TcM (Maybe ClsInst) -checkForExistence res mb_inst_tys = do - (tys, thetas) <- instDFunType (is_dfun res) mb_inst_tys - - wanteds <- forM thetas getDictionaryBindings +checkForExistence clsInst mb_inst_tys = do + -- We want to force the solver to attempt to solve the constraints for clsInst. + -- Usually, this isn't a problem since there should only be a single instance + -- for a type. However, when we have overlapping instances, the solver will give up + -- since it can't decide which instance to use. To get around this restriction, instead + -- of asking the solver to solve a constraint for clsInst, we ask it to solve the + -- thetas of clsInst. + (tys, thetas) <- instDFunType (is_dfun clsInst) mb_inst_tys + wanteds <- mapM getDictionaryBindings thetas (residuals, _) <- second evBindMapBinds <$> runTcS (solveWanteds (unionsWC wanteds)) - let all_residual_constraints = bagToList $ wc_simple residuals - let preds = map ctPred all_residual_constraints - if all isSatisfiablePred preds && (null $ wc_impl residuals) - then return . Just $ substInstArgs tys preds res + let WC { wc_simple = simples, wc_impl = impls } = (dropDerivedWC residuals) + + let resPreds = mapBag ctPred simples + + if allBag isSatisfiablePred resPreds && solvedImplics impls + then return . Just $ substInstArgs tys (bagToList resPreds) clsInst else return Nothing where + solvedImplics :: Bag Implication -> Bool + solvedImplics impls = allBag (isSolvedStatus . ic_status) impls -- Stricter version of isTyVarClassPred that requires all TyConApps to have at least -- one argument or for the head to be a TyVar. The reason is that we want to ensure @@ -1129,7 +1166,7 @@ checkForExistence res mb_inst_tys = do Just (_, tys@(_:_)) -> all isTyVarTy tys _ -> isTyVarTy ty - empty_subst = mkEmptyTCvSubst (mkInScopeSet (tyCoVarsOfType (idType $ is_dfun res))) + empty_subst = mkEmptyTCvSubst (mkInScopeSet (tyCoVarsOfType (idType $ is_dfun clsInst))) {- Create a ClsInst with instantiated arguments and constraints. @@ -1149,16 +1186,6 @@ checkForExistence res mb_inst_tys = do where (dfun_tvs, _, cls, args) = instanceSig inst --- Find instances where the head unifies with the provided type -findMatchingInstances :: Type -> TcM [(ClsInst, [DFunInstType])] -findMatchingInstances ty = do - ies@(InstEnvs {ie_global = ie_global, ie_local = ie_local}) <- tcGetInstEnvs - let allClasses = instEnvClasses ie_global ++ instEnvClasses ie_local - - concatMapM (\cls -> do - let (matches, _, _) = lookupInstEnv True ies cls [ty] - return matches) allClasses - ----------------------------------------------------------------------------- -- Compile an expression, run it, and deliver the result ===================================== testsuite/tests/ghci/T18071/T18071.hs ===================================== @@ -0,0 +1,32 @@ +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE QuantifiedConstraints #-} +{-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE DataKinds #-} +module Bug where + +import Data.Kind +import Data.Proxy + +class MyShow a where + show :: a -> String + +class (forall (z :: k). MyShow (Proxy z)) => MyShowProxy (k :: Type) where +instance (forall (z :: k). MyShow (Proxy z)) => MyShowProxy (k :: Type) + +data T :: Type -> Type + +data U = A | B + +instance forall (z :: U). MyShow (Proxy (z :: U)) where + show _ = "U" + +data U2 = A2 | B2 + +instance MyShow (Proxy A2) where + show _ = "A2" + +instance MyShow (Proxy B2) where + show _ = "B2" + ===================================== testsuite/tests/ghci/T18071/T18071.script ===================================== @@ -0,0 +1,8 @@ +:set -Wno-simplifiable-class-constraints +:load T18071.hs +-- Should report no instances since it is ill-kinded for T +:instances T +-- U should report a match for ShowProxy +:instances U +-- U2 should not report a match for ShowProxy +:instances U2 ===================================== testsuite/tests/ghci/T18071/T18071.stdout ===================================== @@ -0,0 +1 @@ +instance [safe] MyShowProxy U -- Defined at T18071.hs:16:10 ===================================== testsuite/tests/ghci/T18071/all.T ===================================== @@ -0,0 +1 @@ +test('T18071', [extra_files(['T18071.hs'])], ghci_script, ['T18071.script']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dc5f004c4dc27d78d3415adc54e9b6694b865145 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/dc5f004c4dc27d78d3415adc54e9b6694b865145 You're receiving 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 28 20:25:26 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 28 May 2020 16:25:26 -0400 Subject: [Git][ghc/ghc][master] 2 commits: FloatOut: Only eta-expand dead-end RHS if arity will increase (#18231) Message-ID: <5ed01e36ea220_6e2681629e024215ce@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 10e6982c by Sebastian Graf at 2020-05-28T16:25:14-04:00 FloatOut: Only eta-expand dead-end RHS if arity will increase (#18231) Otherwise we risk turning trivial RHS into non-trivial RHS, introducing unnecessary bindings in the next Simplifier run, resulting in more churn. Fixes #18231. - - - - - 08dab5f7 by Sebastian Graf at 2020-05-28T16:25:14-04:00 DmdAnal: Recognise precise exceptions from case alternatives (#18086) Consider ```hs m :: IO () m = do putStrLn "foo" error "bar" ``` `m` (from #18086) always throws a (precise or imprecise) exception or diverges. Yet demand analysis infers `<L,A>` as demand signature instead of `<L,A>x` for it. That's because the demand analyser sees `putStrLn` occuring in a case scrutinee and decides that it has to `deferAfterPreciseException`, because `putStrLn` throws a precise exception on some control flow paths. This will mask the `botDiv` `Divergence`of the single case alt containing `error` to `topDiv`. Since `putStrLn` has `topDiv` itself, the final `Divergence` is `topDiv`. This is easily fixed: `deferAfterPreciseException` works by `lub`ing with the demand type of a virtual case branch denoting the precise exceptional control flow. We used `nopDmdType` before, but we can be more precise and use `exnDmdType`, which is `nopDmdType` with `exnDiv`. Now the `Divergence` from the case alt will degrade `botDiv` to `exnDiv` instead of `topDiv`, which combines with the result from the scrutinee to `exnDiv`, and all is well. Fixes #18086. - - - - - 9 changed files: - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Types/Demand.hs - + testsuite/tests/simplCore/should_compile/T18231.hs - + testsuite/tests/simplCore/should_compile/T18231.stderr - testsuite/tests/simplCore/should_compile/all.T - + testsuite/tests/stranal/sigs/T18086.hs - + testsuite/tests/stranal/sigs/T18086.stderr - testsuite/tests/stranal/sigs/all.T Changes: ===================================== compiler/GHC/Core/Opt/FloatOut.hs ===================================== @@ -15,7 +15,7 @@ import GHC.Prelude import GHC.Core import GHC.Core.Utils import GHC.Core.Make -import GHC.Core.Opt.Arity ( etaExpand ) +import GHC.Core.Opt.Arity ( exprArity, etaExpand ) import GHC.Core.Opt.Monad ( FloatOutSwitches(..) ) import GHC.Driver.Session @@ -221,8 +221,9 @@ floatBind (NonRec (TB var _) rhs) -- A tiresome hack: -- see Note [Bottoming floats: eta expansion] in GHC.Core.Opt.SetLevels - let rhs'' | isDeadEndId var = etaExpand (idArity var) rhs' - | otherwise = rhs' + let rhs'' | isDeadEndId var + , exprArity rhs' < idArity var = etaExpand (idArity var) rhs' + | otherwise = rhs' in (fs, rhs_floats, [NonRec var rhs'']) } ===================================== compiler/GHC/Core/Opt/SetLevels.hs ===================================== @@ -952,6 +952,9 @@ Tiresomely, though, the simplifier has an invariant that the manifest arity of the RHS should be the same as the arity; but we can't call etaExpand during GHC.Core.Opt.SetLevels because it works over a decorated form of CoreExpr. So we do the eta expansion later, in GHC.Core.Opt.FloatOut. +But we should only eta-expand if the RHS doesn't already have the right +exprArity, otherwise we get unnecessary top-level bindings if the RHS was +trivial after the next run of the Simplifier. Note [Case MFEs] ~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Types/Demand.hs ===================================== @@ -1055,11 +1055,19 @@ Is this strict in 'y'? Often not! If @foo x s@ might throw a precise exception (ultimately via raiseIO#), then we must not force 'y', which may fail to terminate or throw an imprecise exception, until we have performed @foo x s at . -So we have to 'Demand.deferAfterPreciseException' (which just 'lub's with -'nopDmdType' to model the exceptional control flow) when @foo x s@ -may throw a precise exception. Motivated by T13380{d,e,f}. +So we have to 'deferAfterPreciseException' (which 'lub's with 'exnDmdType' to +model the exceptional control flow) when @foo x s@ may throw a precise +exception. Motivated by T13380{d,e,f}. See Note [Which scrutinees may throw precise exceptions] in DmdAnal. +We have to be careful not to discard dead-end Divergence from case +alternatives, though (#18086): + + m = putStrLn "foo" >> error "bar" + +'m' should still have 'exnDiv', which is why it is not sufficient to lub with +'nopDmdType' (which has 'topDiv') in 'deferAfterPreciseException'. + Historical Note: This used to be called the "IO hack". But that term is rather a bad fit because 1. It's easily confused with the "State hack", which also affects IO. @@ -1261,6 +1269,11 @@ isTopDmdType :: DmdType -> Bool isTopDmdType (DmdType env args div) = div == topDiv && null args && isEmptyVarEnv env +-- | The demand type of an unspecified expression that is guaranteed to +-- throw a (precise or imprecise) exception or diverge. +exnDmdType :: DmdType +exnDmdType = DmdType emptyDmdEnv [] exnDiv + dmdTypeDepth :: DmdType -> Arity dmdTypeDepth (DmdType _ ds _) = length ds @@ -1303,13 +1316,17 @@ splitDmdTy (DmdType fv (dmd:dmds) res_ty) = (dmd, DmdType fv dmds res_ty) splitDmdTy ty@(DmdType _ [] res_ty) = (defaultArgDmd res_ty, ty) -- | When e is evaluated after executing an IO action that may throw a precise --- exception, and d is e's demand, then what of this demand should we consider? --- * We have to kill all strictness demands (i.e. lub with a lazy demand) --- * We can keep usage information (i.e. lub with an absent demand) --- * We have to kill definite divergence +-- exception, we act as if there is an additional control flow path that is +-- taken if e throws a precise exception. The demand type of this control flow +-- path +-- * is lazy and absent ('topDmd') in all free variables and arguments +-- * has 'exnDiv' 'Divergence' result +-- So we can simply take a variant of 'nopDmdType', 'exnDmdType'. +-- Why not 'nopDmdType'? Because then the result of 'e' can never be 'exnDiv'! +-- That means failure to drop dead-ends, see #18086. -- See Note [Precise exceptions and strictness analysis] deferAfterPreciseException :: DmdType -> DmdType -deferAfterPreciseException d = lubDmdType d nopDmdType +deferAfterPreciseException = lubDmdType exnDmdType strictenDmd :: Demand -> CleanDemand strictenDmd (JD { sd = s, ud = u}) ===================================== testsuite/tests/simplCore/should_compile/T18231.hs ===================================== @@ -0,0 +1,7 @@ +module T18231 where + +import Control.Monad (forever) +import Control.Monad.Trans.State.Strict + +m :: State Int () +m = forever $ modify' (+1) ===================================== testsuite/tests/simplCore/should_compile/T18231.stderr ===================================== @@ -0,0 +1,40 @@ + +==================== Tidy Core ==================== +Result size of Tidy Core = {terms: 30, types: 22, coercions: 5, joins: 0/0} + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T18231.$trModule4 :: GHC.Prim.Addr# +T18231.$trModule4 = "main"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T18231.$trModule3 :: GHC.Types.TrName +T18231.$trModule3 = GHC.Types.TrNameS T18231.$trModule4 + +-- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} +T18231.$trModule2 :: GHC.Prim.Addr# +T18231.$trModule2 = "T18231"# + +-- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} +T18231.$trModule1 :: GHC.Types.TrName +T18231.$trModule1 = GHC.Types.TrNameS T18231.$trModule2 + +-- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} +T18231.$trModule :: GHC.Types.Module +T18231.$trModule = GHC.Types.Module T18231.$trModule3 T18231.$trModule1 + +Rec { +-- RHS size: {terms: 6, types: 1, coercions: 0, joins: 0/0} +lvl :: GHC.Prim.Int# -> Data.Functor.Identity.Identity ((), Int) +lvl = \ (x :: GHC.Prim.Int#) -> T18231.m1 (GHC.Types.I# (GHC.Prim.+# x 1#)) + +-- RHS size: {terms: 6, types: 3, coercions: 0, joins: 0/0} +T18231.m1 :: Int -> Data.Functor.Identity.Identity ((), Int) +T18231.m1 = \ (s1 :: Int) -> case s1 of { GHC.Types.I# x -> lvl x } +end Rec } + +-- RHS size: {terms: 1, types: 0, coercions: 5, joins: 0/0} +m :: State Int () +m = T18231.m1 `cast` (Sym (Control.Monad.Trans.State.Strict.N:StateT[0] _N _R <()>_N) :: (Int -> Data.Functor.Identity.Identity ((), Int)) ~R# StateT Int Data.Functor.Identity.Identity ()) + + + ===================================== testsuite/tests/simplCore/should_compile/all.T ===================================== @@ -319,3 +319,8 @@ test('T17810', normal, multimod_compile, ['T17810', '-fspecialise-aggressively - test('T18013', normal, multimod_compile, ['T18013', '-v0 -O']) test('T18098', normal, compile, ['-dcore-lint -O2']) test('T18120', normal, compile, ['-dcore-lint -O']) + +# Verify that there are only two top-level functions (the rec group of m's cast +# WW worker m1). Ideally, it would be one, but we fail to inline dead-ending +# recursive groups due to Note [Bottoming floats]. +test('T18231', [ only_ways(['optasm']), grep_errmsg(r'^[\w\.]+ ::.*->.*') ], compile, ['-ddump-simpl -dsuppress-idinfo -dppr-cols=99999 -dsuppress-uniques']) ===================================== testsuite/tests/stranal/sigs/T18086.hs ===================================== @@ -0,0 +1,23 @@ +{-# OPTIONS_GHC -O2 -fforce-recomp #-} +module T18086 where + +import GHC.Stack +import GHC.Utils.Panic.Plain +import Control.Exception +import System.IO.Unsafe + +-- Should have strictness signature x, emphasis on the exceptional +-- divergence result. +m :: IO () +m = do + putStrLn "foo" + error "bar" + +-- Dito, just in a more complex scenario (the original reproducer of #18086) +panic :: String -> a +panic x = unsafeDupablePerformIO $ do + stack <- ccsToStrings =<< getCurrentCCS x + if null stack + then throw (PlainPanic x) + else throw (PlainPanic (x ++ '\n' : renderStack stack)) + ===================================== testsuite/tests/stranal/sigs/T18086.stderr ===================================== @@ -0,0 +1,21 @@ + +==================== Strictness signatures ==================== +T18086.$trModule: +T18086.m: x +T18086.panic: x + + + +==================== Cpr signatures ==================== +T18086.$trModule: +T18086.m: b +T18086.panic: + + + +==================== Strictness signatures ==================== +T18086.$trModule: +T18086.m: x +T18086.panic: x + + ===================================== testsuite/tests/stranal/sigs/all.T ===================================== @@ -22,3 +22,4 @@ test('T5075', normal, compile, ['']) test('T17932', normal, compile, ['']) test('T13380c', expect_broken('!3014'), compile, ['']) test('T13380f', normal, compile, ['']) +test('T18086', normal, compile, ['-package ghc']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/dc5f004c4dc27d78d3415adc54e9b6694b865145...08dab5f74e021ad054112cc5f6bb7e55d8796cd7 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/dc5f004c4dc27d78d3415adc54e9b6694b865145...08dab5f74e021ad054112cc5f6bb7e55d8796cd7 You're receiving 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 28 20:26:04 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 28 May 2020 16:26:04 -0400 Subject: [Git][ghc/ghc][master] Ticky-ticky: Record DataCon name in ticker name Message-ID: <5ed01e5cac61a_6e2681629e0242797f@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: aef95f11 by Ben Gamari at 2020-05-28T16:25:53-04:00 Ticky-ticky: Record DataCon name in ticker name This makes it significantly easier to spot the nature of allocations regressions and comes at a reasonably low cost. - - - - - 2 changed files: - compiler/GHC/StgToCmm/Bind.hs - compiler/GHC/StgToCmm/Ticky.hs Changes: ===================================== compiler/GHC/StgToCmm/Bind.hs ===================================== @@ -201,7 +201,7 @@ cgRhs :: Id ) cgRhs id (StgRhsCon cc con args) - = withNewTickyCounterCon (idName id) $ + = withNewTickyCounterCon (idName id) con $ buildDynCon id True cc con (assertNonVoidStgArgs args) -- con args are always non-void, -- see Note [Post-unarisation invariants] in GHC.Stg.Unarise ===================================== compiler/GHC/StgToCmm/Ticky.hs ===================================== @@ -128,6 +128,7 @@ import GHC.Driver.Session -- Turgid imports for showTypeCategory import GHC.Builtin.Names import GHC.Tc.Utils.TcType +import GHC.Core.DataCon import GHC.Core.TyCon import GHC.Core.Predicate @@ -145,6 +146,7 @@ data TickyClosureType = TickyFun Bool -- True <-> single entry | TickyCon + DataCon -- the allocated constructor | TickyThunk Bool -- True <-> updateable Bool -- True <-> standard thunk (AP or selector), has no entry counter @@ -188,13 +190,14 @@ withNewTickyCounterStdThunk isUpdatable name code = do withNewTickyCounterCon :: Name + -> DataCon -> FCode a -> FCode a -withNewTickyCounterCon name code = do +withNewTickyCounterCon name datacon code = do has_ctr <- thunkHasCounter False if not has_ctr then code - else withNewTickyCounter TickyCon name [] code + else withNewTickyCounter (TickyCon datacon) name [] code -- args does not include the void arguments withNewTickyCounter :: TickyClosureType -> Name -> [NonVoid Id] -> FCode a -> FCode a @@ -222,7 +225,7 @@ emitTickyCounter cloType name args ext = case cloType of TickyFun single_entry -> parens $ hcat $ punctuate comma $ [text "fun"] ++ [text "se"|single_entry] - TickyCon -> parens (text "con") + TickyCon datacon -> parens (text "con:" <+> ppr (dataConName datacon)) TickyThunk upd std -> parens $ hcat $ punctuate comma $ [text "thk"] ++ [text "se"|not upd] ++ [text "std"|std] TickyLNE | isInternalName name -> parens (text "LNE") View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/aef95f11f946f7d3f2c4c9b695d632cbfc4a993d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/aef95f11f946f7d3f2c4c9b695d632cbfc4a993d You're receiving 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 28 20:26:47 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 28 May 2020 16:26:47 -0400 Subject: [Git][ghc/ghc][master] hadrian: Don't track GHC's verbosity argument Message-ID: <5ed01e87dae26_6e263f9f0ce68a6c2432353@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 8f021b8c by Ben Gamari at 2020-05-28T16:26:34-04:00 hadrian: Don't track GHC's verbosity argument Teach hadrian to ignore GHC's -v argument in its recompilation check, thus fixing #18131. - - - - - 1 changed file: - hadrian/src/Target.hs Changes: ===================================== hadrian/src/Target.hs ===================================== @@ -20,7 +20,9 @@ type Target = H.Target Context Builder -- 'True' only if the argument needs to be tracked. trackArgument :: Target -> String -> Bool trackArgument target arg = case builder target of - (Make _) -> not $ threadArg arg - _ -> True + Make _ -> not $ threadArg arg + Ghc _ _ -> not $ verbosityArg arg + _ -> True where threadArg s = dropWhileEnd isDigit s `elem` ["-j", "MAKEFLAGS=-j", "THREADS="] + verbosityArg s = dropWhileEnd isDigit s == "-v" View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8f021b8c474f328441982c90c6a12f716b5607eb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8f021b8c474f328441982c90c6a12f716b5607eb You're receiving 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 28 20:27:31 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 28 May 2020 16:27:31 -0400 Subject: [Git][ghc/ghc][master] Rip out CmmStackInfo(updfr_space) Message-ID: <5ed01eb342bf9_6e2611db28542435026@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 13d9380b by Ben Gamari at 2020-05-28T16:27:20-04:00 Rip out CmmStackInfo(updfr_space) As noted in #18232, this field is currently completely unused and moreover doesn't have a clear meaning. - - - - - 5 changed files: - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/LayoutStack.hs - compiler/GHC/Cmm/Ppr.hs - compiler/GHC/Cmm/ProcPoint.hs - compiler/GHC/StgToCmm/Monad.hs Changes: ===================================== compiler/GHC/Cmm.hs ===================================== @@ -132,9 +132,6 @@ data CmmStackInfo -- number of bytes of arguments on the stack on entry to the -- the proc. This is filled in by GHC.StgToCmm.codeGen, and -- used by the stack allocator later. - updfr_space :: Maybe ByteOff, - -- XXX: this never contains anything useful, but it should. - -- See comment in GHC.Cmm.LayoutStack. do_layout :: Bool -- Do automatic stack layout for this proc. This is -- True for all code generated by the code generator, ===================================== compiler/GHC/Cmm/LayoutStack.hs ===================================== @@ -357,10 +357,9 @@ isGcJump _something_else = False -- This doesn't seem right somehow. We need to find out whether this -- proc will push some update frame material at some point, so that we --- can avoid using that area of the stack for spilling. The --- updfr_space field of the CmmProc *should* tell us, but it doesn't --- (I think maybe it gets filled in later when we do proc-point --- splitting). +-- can avoid using that area of the stack for spilling. Ideally we would +-- capture this information in the CmmProc (e.g. in CmmStackInfo; see #18232 +-- for details on one ill-fated attempt at this). -- -- So we'll just take the max of all the cml_ret_offs. This could be -- unnecessarily pessimistic, but probably not in the code we ===================================== compiler/GHC/Cmm/Ppr.hs ===================================== @@ -103,9 +103,8 @@ instance Outputable CmmGraph where -- Outputting types Cmm contains pprStackInfo :: CmmStackInfo -> SDoc -pprStackInfo (StackInfo {arg_space=arg_space, updfr_space=updfr_space}) = - text "arg_space: " <> ppr arg_space <+> - text "updfr_space: " <> ppr updfr_space +pprStackInfo (StackInfo {arg_space=arg_space}) = + text "arg_space: " <> ppr arg_space pprTopInfo :: CmmTopInfo -> SDoc pprTopInfo (TopInfo {info_tbls=info_tbl, stack_info=stack_info}) = ===================================== compiler/GHC/Cmm/ProcPoint.hs ===================================== @@ -356,7 +356,6 @@ splitAtProcPoints dflags entry_label callPPs procPoints procMap g' = replacePPIds g live = ppLiveness (g_entry g') stack_info = StackInfo { arg_space = 0 - , updfr_space = Nothing , do_layout = True } -- cannot use panic, this is printed by -ddump-cmm ===================================== compiler/GHC/StgToCmm/Monad.hs ===================================== @@ -762,8 +762,7 @@ emitProcWithConvention conv mb_info lbl args blocks emitProc :: Maybe CmmInfoTable -> CLabel -> [GlobalReg] -> CmmAGraphScoped -> Int -> Bool -> FCode () emitProc mb_info lbl live blocks offset do_layout - = do { platform <- getPlatform - ; l <- newBlockId + = do { l <- newBlockId ; let blks :: CmmGraph blks = labelAGraph l blocks @@ -772,7 +771,6 @@ emitProc mb_info lbl live blocks offset do_layout | otherwise = mapEmpty sinfo = StackInfo { arg_space = offset - , updfr_space = Just (initUpdFrameOff platform) , do_layout = do_layout } tinfo = TopInfo { info_tbls = infos View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/13d9380b1fc8b67057a9ad4fffe244040a7f9bc0 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/13d9380b1fc8b67057a9ad4fffe244040a7f9bc0 You're receiving 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 28 20:32:39 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 28 May 2020 16:32:39 -0400 Subject: [Git][ghc/ghc][wip/T18234] gitlab-ci: Introduce a nightly cross-compilation job Message-ID: <5ed01fe7691f8_6e263f9ee3c1eb542437042@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18234 at Glasgow Haskell Compiler / GHC Commits: 6d2b964c by Ben Gamari at 2020-05-28T16:32:30-04:00 gitlab-ci: Introduce a nightly cross-compilation job This adds a job to test cross-compilation from x86-64 to AArch64 with Hadrian. Fixes #18234. - - - - - 2 changed files: - .gitlab-ci.yml - .gitlab/ci.sh 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: 6223fe0b5942f4fa35bdec92c74566cf195bfb42 + DOCKER_REV: ba119705df5222fe74208a85019cb980e2c4318f # Sequential version number capturing the versions of all tools fetched by # .gitlab/ci.sh. @@ -244,6 +244,14 @@ validate-x86_64-linux-deb9-unreg-hadrian: tags: - x86_64-linux +nightly-x86_64-linux-deb10-hadrian-cross-aarch64: + #<<: *nightly + stage: build + extends: .build-x86_64-linux-deb10-hadrian + variables: + CONFIGURE_ARGS: --with-intree-gmp + CROSS_TARGET: "aarch64-linux-gnu" + ############################################################ # GHC-in-GHCi (Hadrian) ===================================== .gitlab/ci.sh ===================================== @@ -80,6 +80,7 @@ Modes: Environment variables: + CROSS_TARGET Triple of cross-compilation target. MSYSTEM (Windows-only) Which platform to build form (MINGW64 or MINGW32). Environment variables determining build configuration of Make system: @@ -114,11 +115,11 @@ EOF function mingw_init() { case "$MSYSTEM" in MINGW32) - triple="i386-unknown-mingw32" + target_triple="i386-unknown-mingw32" boot_triple="i386-unknown-mingw32" # triple of bootstrap GHC ;; MINGW64) - triple="x86_64-unknown-mingw32" + target_triple="x86_64-unknown-mingw32" boot_triple="x86_64-unknown-mingw32" # triple of bootstrap GHC ;; *) @@ -375,8 +376,8 @@ function configure() { end_section "booting" local target_args="" - if [[ -n "$triple" ]]; then - target_args="--target=$triple" + if [[ -n "$target_triple" ]]; then + target_args="--target=$target_triple" fi start_section "configuring" @@ -415,6 +416,11 @@ function push_perf_notes() { } function test_make() { + if [ -n "$CROSS_TARGET" ]; then + info "Can't test cross-compiled build." + return + fi + run "$MAKE" test_bindist TEST_PREP=YES run "$MAKE" V=0 test \ THREADS="$cores" \ @@ -432,6 +438,11 @@ function build_hadrian() { } function test_hadrian() { + if [ -n "$CROSS_TARGET" ]; then + info "Can't test cross-compiled build." + return + fi + cd _build/bindist/ghc-*/ run ./configure --prefix="$TOP"/_build/install run "$MAKE" install @@ -486,6 +497,11 @@ case "$(uname)" in *) fail "uname $(uname) is not supported" ;; esac +if [ -n "$CROSS_TARGET" ]; then + info "Cross-compiling for $CROSS_TARGET..." + target_triple="$CROSS_TARGET" +fi + set_toolchain_paths case $1 in View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6d2b964c01912b39d352b0e4421981ae449629a5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6d2b964c01912b39d352b0e4421981ae449629a5 You're receiving 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 28 20:58:39 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Thu, 28 May 2020 16:58:39 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 19 commits: GHC.Core.Unfold: Refactor traceInline Message-ID: <5ed025ff3f6ed_6e263f9ed663c680244419d@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 28deee28 by Ben Gamari at 2020-05-28T16:23:21-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 - - - - - 1f393e1e by Ben Gamari at 2020-05-28T16:23:21-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 haddock.Cabal haddock.base haddock.compiler - - - - - 5f621a78 by Vladislav Zavialov at 2020-05-28T16:23:58-04:00 Add Semigroup/Monoid for Q (#18123) - - - - - dc5f004c by Xavier Denis at 2020-05-28T16:24:37-04:00 Fix #18071 Run the core linter on candidate instances to ensure they are well-kinded. Better handle quantified constraints by using a CtWanted to avoid having unsolved constraints thrown away at the end by the solver. - - - - - 10e6982c by Sebastian Graf at 2020-05-28T16:25:14-04:00 FloatOut: Only eta-expand dead-end RHS if arity will increase (#18231) Otherwise we risk turning trivial RHS into non-trivial RHS, introducing unnecessary bindings in the next Simplifier run, resulting in more churn. Fixes #18231. - - - - - 08dab5f7 by Sebastian Graf at 2020-05-28T16:25:14-04:00 DmdAnal: Recognise precise exceptions from case alternatives (#18086) Consider ```hs m :: IO () m = do putStrLn "foo" error "bar" ``` `m` (from #18086) always throws a (precise or imprecise) exception or diverges. Yet demand analysis infers `<L,A>` as demand signature instead of `<L,A>x` for it. That's because the demand analyser sees `putStrLn` occuring in a case scrutinee and decides that it has to `deferAfterPreciseException`, because `putStrLn` throws a precise exception on some control flow paths. This will mask the `botDiv` `Divergence`of the single case alt containing `error` to `topDiv`. Since `putStrLn` has `topDiv` itself, the final `Divergence` is `topDiv`. This is easily fixed: `deferAfterPreciseException` works by `lub`ing with the demand type of a virtual case branch denoting the precise exceptional control flow. We used `nopDmdType` before, but we can be more precise and use `exnDmdType`, which is `nopDmdType` with `exnDiv`. Now the `Divergence` from the case alt will degrade `botDiv` to `exnDiv` instead of `topDiv`, which combines with the result from the scrutinee to `exnDiv`, and all is well. Fixes #18086. - - - - - aef95f11 by Ben Gamari at 2020-05-28T16:25:53-04:00 Ticky-ticky: Record DataCon name in ticker name This makes it significantly easier to spot the nature of allocations regressions and comes at a reasonably low cost. - - - - - 8f021b8c by Ben Gamari at 2020-05-28T16:26:34-04:00 hadrian: Don't track GHC's verbosity argument Teach hadrian to ignore GHC's -v argument in its recompilation check, thus fixing #18131. - - - - - 13d9380b by Ben Gamari at 2020-05-28T16:27:20-04:00 Rip out CmmStackInfo(updfr_space) As noted in #18232, this field is currently completely unused and moreover doesn't have a clear meaning. - - - - - a274e9f2 by Andreas Klebinger at 2020-05-28T16:58:15-04: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. - - - - - e46030f7 by Ben Gamari at 2020-05-28T16:58:16-04:00 CoreToStg: Add Outputable ArgInfo instance - - - - - 93d340d9 by Simon Peyton Jones at 2020-05-28T16:58:16-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. - - - - - 272fcd35 by Simon Peyton Jones at 2020-05-28T16:58:16-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. - - - - - d1ff5208 by Ben Gamari at 2020-05-28T16:58:16-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 Metric Decrease: ManyConstructors Co-Authored-By: Simon Peyton-Jone <simonpj at microsoft.com> - - - - - 331b005f by Ben Gamari at 2020-05-28T16:58:16-04:00 Eta expand un-saturated primops Now since we no longer try to predict CAFfyness we have no need for the solution to #16846. Eta expanding unsaturated primop applications is conceptually simpler, especially in the presence of levity polymorphism. This essentially reverts cac8dc9f51e31e4c0a6cd9bc302f7e1bc7c03beb, as suggested in #18079. Closes #18079. - - - - - 2d2ae348 by Simon Jakobi at 2020-05-28T16:58:17-04:00 base: Scrap deprecation plan for Data.Monoid.{First,Last} See the discussion on the libraries mailing list for context: https://mail.haskell.org/pipermail/libraries/2020-April/030357.html - - - - - a8a7666a by Jeremy Schlatter at 2020-05-28T16:58:19-04:00 Fix typo in documentation - - - - - 51dd29e3 by Gleb Popov at 2020-05-28T16:58:22-04:00 Always define USE_PTHREAD_FOR_ITIMER for FreeBSD. - - - - - 32d09881 by Alp Mestanogullari at 2020-05-28T16:58:29-04:00 hadrian: introduce 'install' target Its logic is very simple. It `need`s the `binary-dist-dir` target and runs suitable `configure` and `make install` commands for the user. A new `--prefix` command line argument is introduced to specify where GHC should be installed. - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/LayoutStack.hs - compiler/GHC/Cmm/Ppr.hs - compiler/GHC/Cmm/ProcPoint.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Monad.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/StgToCmm/Bind.hs - compiler/GHC/StgToCmm/Monad.hs - compiler/GHC/StgToCmm/Ticky.hs - compiler/GHC/Tc/Solver/Flatten.hs - compiler/GHC/Tc/Solver/Monad.hs - compiler/GHC/Tc/Utils/Monad.hs - compiler/GHC/Types/Demand.hs - compiler/GHC/Types/Id.hs - compiler/GHC/Utils/Error.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/de24f09226e05e5d8fbfea12bc7edd7513b368e6...32d09881327fbf23433922902bcac845090aa3a4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/de24f09226e05e5d8fbfea12bc7edd7513b368e6...32d09881327fbf23433922902bcac845090aa3a4 You're receiving 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 28 21:28:48 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 28 May 2020 17:28:48 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T14482 Message-ID: <5ed02d1062971_6e263f9f0ce68a6c245817d@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/T14482 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T14482 You're receiving 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 28 22:03:25 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Thu, 28 May 2020 18:03:25 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18254 Message-ID: <5ed0352d4c1a2_6e263f9f0bd9237824668f1@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/T18254 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18254 You're receiving 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 28 23:00:24 2020 From: gitlab at gitlab.haskell.org (Daneel S. Yaitskov) Date: Thu, 28 May 2020 19:00:24 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/thread-protected Message-ID: <5ed04288bd5cc_6e2681629e024752d0@gitlab.haskell.org.mail> Daneel S. Yaitskov pushed new branch wip/thread-protected at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/thread-protected You're receiving 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 29 03:22:59 2020 From: gitlab at gitlab.haskell.org (Daneel S. Yaitskov) Date: Thu, 28 May 2020 23:22:59 -0400 Subject: [Git][ghc/ghc][wip/T17949] Apply suggestion to libraries/base/Debug/Trace.hs Message-ID: <5ed080136a1c4_6e263f9ee299af3c24891c9@gitlab.haskell.org.mail> Daneel S. Yaitskov pushed to branch wip/T17949 at Glasgow Haskell Compiler / GHC Commits: 72bd17f3 by Daneel S. Yaitskov at 2020-05-28T23:22:58-04:00 Apply suggestion to libraries/base/Debug/Trace.hs - - - - - 1 changed file: - libraries/base/Debug/Trace.hs Changes: ===================================== libraries/base/Debug/Trace.hs ===================================== @@ -78,8 +78,8 @@ import Data.List (null, partition) foreign import ccall "&TRACE_user" traceUser :: Ptr CInt --- | The 'whenEventlog' function evals argument action --- if RTS eventlog (+RTS -l) is enabled. +-- | The 'whenEventlog' function runs the argument action +-- if eventlogging (+RTS -l) is enabled. -- -- @since 4.14.0.0 {-# INLINE whenEventlog #-} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/72bd17f332ab10315a78c6fa9d188144556e609e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/72bd17f332ab10315a78c6fa9d188144556e609e You're receiving 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 29 04:11:29 2020 From: gitlab at gitlab.haskell.org (Daneel S. Yaitskov) Date: Fri, 29 May 2020 00:11:29 -0400 Subject: [Git][ghc/ghc][wip/thread-protected] unusued import in Sync.hs Message-ID: <5ed08b718420a_6e263f9ed4e0fe4024909b8@gitlab.haskell.org.mail> Daneel S. Yaitskov pushed to branch wip/thread-protected at Glasgow Haskell Compiler / GHC Commits: b342aeb8 by Daneel S. Yaitskov at 2020-05-29T00:04:44-04:00 unusued import in Sync.hs - - - - - 1 changed file: - libraries/base/GHC/Conc/Sync.hs Changes: ===================================== libraries/base/GHC/Conc/Sync.hs ===================================== @@ -118,7 +118,6 @@ import GHC.Real ( fromIntegral ) import GHC.Show ( Show(..), showParen, showString ) import GHC.Stable ( StablePtr(..) ) import GHC.Weak -import GHC.Word import Unsafe.Coerce ( unsafeCoerce# ) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b342aeb87973ad72a14a68604348d1fe7ff75c6c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b342aeb87973ad72a14a68604348d1fe7ff75c6c You're receiving 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 29 04:24:58 2020 From: gitlab at gitlab.haskell.org (Daneel S. Yaitskov) Date: Fri, 29 May 2020 00:24:58 -0400 Subject: [Git][ghc/ghc][wip/T17949] T17949 try @maoe way Message-ID: <5ed08e9a5996d_6e2681629e0249136@gitlab.haskell.org.mail> Daneel S. Yaitskov pushed to branch wip/T17949 at Glasgow Haskell Compiler / GHC Commits: 480b208d by Daneel Yaitskov at 2020-05-28T21:16:26-07:00 T17949 try @maoe way - - - - - 4 changed files: - includes/Rts.h - libraries/base/Debug/Trace.hs - rts/Trace.c - rts/Trace.h Changes: ===================================== includes/Rts.h ===================================== @@ -57,10 +57,8 @@ extern "C" { // library. #if defined(HAS_VISIBILITY_HIDDEN) #define RTS_PRIVATE GNUC3_ATTRIBUTE(visibility("hidden")) -#define RTS_DEFAULT GNUC3_ATTRIBUTE(visibility("default")) #else #define RTS_PRIVATE /* disabled: RTS_PRIVATE */ -#define RTS_DEFAULT #endif #if __GNUC__ >= 4 ===================================== libraries/base/Debug/Trace.hs ===================================== @@ -46,14 +46,13 @@ module Debug.Trace ( import System.IO.Unsafe -import Foreign +import Control.Monad ((<$!>)) import Foreign.C.String -import Foreign.C.Types import GHC.Base import qualified GHC.Foreign import GHC.IO.Encoding import GHC.Ptr -import GHC.Real +import GHC.RTS.Flags import GHC.Show import GHC.Stack import Data.List (null, partition) @@ -76,7 +75,8 @@ import Data.List (null, partition) -- Some implementations of these functions may decorate the string that\'s -- output to indicate that you\'re tracing. -foreign import ccall "&TRACE_user" traceUser :: Ptr CInt +userTracingEnabled :: Bool +userTracingEnabled = unsafeDupablePerformIO $ user <$!> inline getTraceFlags -- | The 'whenEventlog' function runs the argument action -- if eventlogging (+RTS -l) is enabled. @@ -85,8 +85,7 @@ foreign import ccall "&TRACE_user" traceUser :: Ptr CInt {-# INLINE whenEventlog #-} whenEventlog :: IO () -> IO () whenEventlog logAction = do - ee <- peek traceUser - if 0 < (fromIntegral ee :: Int) + if userTracingEnabled then logAction else return () ===================================== rts/Trace.c ===================================== @@ -33,9 +33,7 @@ int TRACE_gc; int TRACE_nonmoving_gc; int TRACE_spark_sampled; int TRACE_spark_full; -#endif /* TRACING */ -RTS_DEFAULT int TRACE_user; // used in Debug.Trace -#if defined(TRACING) +int TRACE_user; int TRACE_cap; #if defined(THREADED_RTS) ===================================== rts/Trace.h ===================================== @@ -71,7 +71,7 @@ extern int TRACE_sched; extern int TRACE_gc; extern int TRACE_spark_sampled; extern int TRACE_spark_full; - +/* extern int TRACE_user; */ // only used in Trace.c extern int TRACE_cap; extern int TRACE_nonmoving_gc; View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/480b208d78de5e236bd7e4fc682c83f05077b270 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/480b208d78de5e236bd7e4fc682c83f05077b270 You're receiving 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 29 05:38:53 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 29 May 2020 01:38:53 -0400 Subject: [Git][ghc/ghc][master] Fix "build/elem" RULE. Message-ID: <5ed09fedc84e6_6e263f9ed4e0fe40250172f@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: f10d11fa by Andreas Klebinger at 2020-05-29T01:38:42-04: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/Builtin/Names.hs - compiler/GHC/Core/Opt/ConstantFold.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/Builtin/Names.hs ===================================== @@ -347,8 +347,8 @@ basicKnownKeyNames groupWithName, -- Strings and lists - unpackCStringName, - unpackCStringFoldrName, unpackCStringUtf8Name, + unpackCStringName, unpackCStringUtf8Name, + unpackCStringFoldrName, unpackCStringFoldrUtf8Name, cstringLengthName, -- Overloaded lists @@ -717,11 +717,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 @@ -1011,12 +1012,14 @@ modIntName = varQual gHC_CLASSES (fsLit "modInt#") modIntIdKey -- Base strings Strings unpackCStringName, unpackCStringFoldrName, - unpackCStringUtf8Name, eqStringName, cstringLengthName :: Name + unpackCStringUtf8Name, unpackCStringFoldrUtf8Name, + eqStringName, cstringLengthName :: Name unpackCStringName = varQual gHC_CSTRING (fsLit "unpackCString#") unpackCStringIdKey unpackCStringFoldrName = varQual gHC_CSTRING (fsLit "unpackFoldrCString#") unpackCStringFoldrIdKey unpackCStringUtf8Name = varQual gHC_CSTRING (fsLit "unpackCStringUtf8#") unpackCStringUtf8IdKey cstringLengthName = varQual gHC_CSTRING (fsLit "cstringLength#") cstringLengthIdKey eqStringName = varQual gHC_BASE (fsLit "eqString") eqStringIdKey +unpackCStringFoldrUtf8Name = varQual gHC_CSTRING (fsLit "unpackFoldrCStringUtf8#") unpackCStringFoldrUtf8IdKey -- The 'inline' function inlineIdName :: Name @@ -2093,7 +2096,8 @@ wildCardKey, absentErrorIdKey, augmentIdKey, appendIdKey, runtimeErrorIdKey, patErrorIdKey, voidPrimIdKey, realWorldPrimIdKey, recConErrorIdKey, unpackCStringUtf8IdKey, unpackCStringAppendIdKey, - unpackCStringFoldrIdKey, unpackCStringIdKey, + unpackCStringFoldrIdKey, unpackCStringFoldrUtf8IdKey, + unpackCStringIdKey, typeErrorIdKey, divIntIdKey, modIntIdKey, absentSumFieldErrorIdKey, cstringLengthIdKey :: Unique @@ -2117,12 +2121,14 @@ 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 -cstringLengthIdKey = mkPreludeMiscIdUnique 25 +unpackCStringFoldrUtf8IdKey = mkPreludeMiscIdUnique 21 +voidPrimIdKey = mkPreludeMiscIdUnique 22 +typeErrorIdKey = mkPreludeMiscIdUnique 23 +divIntIdKey = mkPreludeMiscIdUnique 24 +modIntIdKey = mkPreludeMiscIdUnique 25 +cstringLengthIdKey = mkPreludeMiscIdUnique 26 concatIdKey, filterIdKey, zipIdKey, bindIOIdKey, returnIOIdKey, newStablePtrIdKey, ===================================== compiler/GHC/Core/Opt/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 GHC.Builtin.Names import GHC.Data.Maybe ( orElse ) @@ -1255,7 +1258,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 "CStringLength", ru_fn = cstringLengthName, @@ -1433,11 +1439,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 @@ -1450,12 +1467,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 @@ -1463,17 +1481,23 @@ 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) ===================================== 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 --- There's a built-in rule (in GHC.Core.Opt.ConstantFold) for +"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 ===================================== @@ -15,7 +15,14 @@ `ConcFlags`, `DebugFlags`, `CCFlags`, `DoHeapProfile`, `ProfFlags`, `DoTrace`, `TraceFlags`, `TickyFlags`, `ParFlags`, `RTSFlags`, `RTSStats`, `GCStats`, `ByteOrder`, `GeneralCategory`, `SrcLoc` - + + * 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 ===================================== @@ -16,13 +16,78 @@ ----------------------------------------------------------------------------- module GHC.CString ( + -- * Ascii variants unpackCString#, unpackAppendCString#, unpackFoldrCString#, - unpackCStringUtf8#, unpackNBytes#, cstringLength# + cstringLength#, + + -- * 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 ----------------------------------------------------------------------------- @@ -70,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: @@ -88,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] @@ -110,28 +198,19 @@ 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.Opt.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 +-- Usually the unpack-list rule turns unpackFoldrCString# into unpackCString#. +-- See Note [String literals in GHC] for more details. +-- 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. @@ -139,22 +218,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# @@ -187,3 +287,61 @@ foreign import ccall unsafe "strlen" c_strlen :: Addr# -> Int# cstringLength# :: Addr# -> Int# {-# INLINE[0] cstringLength# #-} cstringLength# = c_strlen + + +------------------------------ +--- 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 ===================================== @@ -5,6 +5,17 @@ - Add known-key `cstringLength#` to `GHC.CString`. This is just the C function `strlen`, but a built-in rewrite rule allows GHC to compute the result at compile time when the argument is known. + +- 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) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f10d11fa49fa9a7a506c4fdbdf86521c2a8d3495 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f10d11fa49fa9a7a506c4fdbdf86521c2a8d3495 You're receiving 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 29 05:39:32 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 29 May 2020 01:39:32 -0400 Subject: [Git][ghc/ghc][master] 4 commits: CoreToStg: Add Outputable ArgInfo instance Message-ID: <5ed0a01469dfc_6e26121fd8b425063b0@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: bbeb2389 by Ben Gamari at 2020-05-29T01:39:19-04:00 CoreToStg: Add Outputable ArgInfo instance - - - - - 0e3361ca by Simon Peyton Jones at 2020-05-29T01:39:19-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. - - - - - c49f7df0 by Simon Peyton Jones at 2020-05-29T01:39:19-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. - - - - - 46720997 by Ben Gamari at 2020-05-29T01:39:19-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 Metric Decrease: ManyConstructors Co-Authored-By: Simon Peyton-Jone <simonpj at microsoft.com> - - - - - 7 changed files: - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/HsToCore/Utils.hs Changes: ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -462,7 +462,7 @@ lintCoreBindings dflags pass local_in_scope binds addLoc TopLevelBindings $ do { checkL (null dups) (dupVars dups) ; checkL (null ext_dups) (dupExtVars ext_dups) - ; lintRecBindings TopLevel all_pairs $ + ; lintRecBindings TopLevel all_pairs $ \_ -> return () } where all_pairs = flattenBinds binds @@ -573,11 +573,11 @@ Check a core binding, returning the list of variables bound. -} lintRecBindings :: TopLevelFlag -> [(Id, CoreExpr)] - -> LintM a -> LintM a + -> ([LintedId] -> LintM a) -> LintM a lintRecBindings top_lvl pairs thing_inside = lintIdBndrs top_lvl bndrs $ \ bndrs' -> do { zipWithM_ lint_pair bndrs' rhss - ; thing_inside } + ; thing_inside bndrs' } where (bndrs, rhss) = unzip pairs lint_pair bndr' rhs @@ -585,6 +585,12 @@ lintRecBindings top_lvl pairs thing_inside do { rhs_ty <- lintRhs bndr' rhs -- Check the rhs ; lintLetBind top_lvl Recursive bndr' rhs rhs_ty } +lintLetBody :: [LintedId] -> CoreExpr -> LintM LintedType +lintLetBody bndrs body + = do { body_ty <- addLoc (BodyOfLetRec bndrs) (lintCoreExpr body) + ; mapM_ (lintJoinBndrType body_ty) bndrs + ; return body_ty } + lintLetBind :: TopLevelFlag -> RecFlag -> LintedId -> CoreExpr -> LintedType -> LintM () -- Binder's type, and the RHS, have already been linted @@ -679,22 +685,9 @@ lintRhs :: Id -> CoreExpr -> LintM LintedType -- its OccInfo and join-pointer-hood lintRhs bndr rhs | Just arity <- isJoinId_maybe bndr - = lint_join_lams arity arity True rhs + = lintJoinLams arity (Just bndr) rhs | AlwaysTailCalled arity <- tailCallInfo (idOccInfo bndr) - = lint_join_lams arity arity False rhs - where - lint_join_lams 0 _ _ rhs - = lintCoreExpr rhs - - lint_join_lams n tot enforce (Lam var expr) - = lintLambda var $ lint_join_lams (n-1) tot enforce expr - - lint_join_lams n tot True _other - = failWithL $ mkBadJoinArityMsg bndr tot (tot-n) rhs - lint_join_lams _ _ False rhs - = markAllJoinsBad $ lintCoreExpr rhs - -- Future join point, not yet eta-expanded - -- Body is not a tail position + = lintJoinLams arity Nothing rhs -- Allow applications of the data constructor @StaticPtr@ at the top -- but produce errors otherwise. @@ -716,6 +709,22 @@ lintRhs _bndr rhs = fmap lf_check_static_ptrs getLintFlags >>= go binders0 go _ = markAllJoinsBad $ lintCoreExpr rhs +-- | Lint the RHS of a join point with expected join arity of @n@ (see Note +-- [Join points] in GHC.Core). +lintJoinLams :: JoinArity -> Maybe Id -> CoreExpr -> LintM LintedType +lintJoinLams join_arity enforce rhs + = go join_arity rhs + where + go 0 rhs = lintCoreExpr rhs + go n (Lam var expr) = lintLambda var $ go (n-1) expr + -- N.B. join points can be cast. e.g. we consider ((\x -> ...) `cast` ...) + -- to be a join point at join arity 1. + go n _other | Just bndr <- enforce -- Join point with too few RHS lambdas + = failWithL $ mkBadJoinArityMsg bndr join_arity n rhs + | otherwise -- Future join point, not yet eta-expanded + = markAllJoinsBad $ lintCoreExpr rhs + -- Body of lambda is not a tail position + lintIdUnfolding :: Id -> Type -> Unfolding -> LintM () lintIdUnfolding bndr bndr_ty uf | isStableUnfolding uf @@ -756,6 +765,40 @@ we will check any unfolding after it has been unfolded; checking the unfolding beforehand is merely an optimization, and one that actively hurts us here. +Note [Linting of runRW#] +~~~~~~~~~~~~~~~~~~~~~~~~ +runRW# has some very peculiar behavior (see Note [runRW magic] in +GHC.CoreToStg.Prep) which CoreLint must accommodate. + +As described in Note [Casts and lambdas] in +GHC.Core.Opt.Simplify.Utils, the simplifier pushes casts out of +lambdas. Concretely, the simplifier will transform + + runRW# @r @ty (\s -> expr `cast` co) + +into + + runRW# @r @ty ((\s -> expr) `cast` co) + +Consequently we need to handle the case that the continuation is a +cast of a lambda. See Note [Casts and lambdas] in +GHC.Core.Opt.Simplify.Utils. + +In the event that the continuation is headed by a lambda (which +will bind the State# token) we can safely allow calls to join +points since CorePrep is going to apply the continuation to +RealWorld. + +In the case that the continuation is not a lambda we lint the +continuation disallowing join points, to rule out things like, + + join j = ... + in runRW# @r @ty ( + let x = jump j + in x + ) + + ************************************************************************ * * \subsection[lintCoreExpr]{lintCoreExpr} @@ -770,6 +813,18 @@ type LintedCoercion = Coercion type LintedTyCoVar = TyCoVar type LintedId = Id +-- | Lint an expression cast through the given coercion, returning the type +-- resulting from the cast. +lintCastExpr :: CoreExpr -> LintedType -> Coercion -> LintM LintedType +lintCastExpr expr expr_ty co + = do { co' <- lintCoercion co + ; let (Pair from_ty to_ty, role) = coercionKindRole co' + ; checkValueType to_ty $ + text "target of cast" <+> quotes (ppr co') + ; lintRole co' Representational role + ; ensureEqTys from_ty expr_ty (mkCastErr expr co' from_ty expr_ty) + ; return to_ty } + lintCoreExpr :: CoreExpr -> LintM LintedType -- The returned type has the substitution from the monad -- already applied to it: @@ -787,14 +842,8 @@ lintCoreExpr (Lit lit) = return (literalType lit) lintCoreExpr (Cast expr co) - = do { expr_ty <- markAllJoinsBad $ lintCoreExpr expr - ; co' <- lintCoercion co - ; let (Pair from_ty to_ty, role) = coercionKindRole co' - ; checkValueType to_ty $ - text "target of cast" <+> quotes (ppr co') - ; lintRole co' Representational role - ; ensureEqTys from_ty expr_ty (mkCastErr expr co' from_ty expr_ty) - ; return to_ty } + = do expr_ty <- markAllJoinsBad $ lintCoreExpr expr + lintCastExpr expr expr_ty co lintCoreExpr (Tick tickish expr) = do case tickish of @@ -831,7 +880,7 @@ lintCoreExpr (Let (NonRec bndr rhs) body) -- Now lint the binder ; lintBinder LetBind bndr $ \bndr' -> do { lintLetBind NotTopLevel NonRecursive bndr' rhs rhs_ty - ; addLoc (BodyOfLetRec [bndr]) (lintCoreExpr body) } } + ; lintLetBody [bndr'] body } } | otherwise = failWithL (mkLetErr bndr rhs) -- Not quite accurate @@ -848,13 +897,37 @@ lintCoreExpr e@(Let (Rec pairs) body) ; checkL (all isJoinId bndrs || all (not . isJoinId) bndrs) $ mkInconsistentRecMsg bndrs - ; lintRecBindings NotTopLevel pairs $ - addLoc (BodyOfLetRec bndrs) $ - lintCoreExpr body } + ; lintRecBindings NotTopLevel pairs $ \ bndrs' -> + lintLetBody bndrs' body } where bndrs = map fst pairs lintCoreExpr e@(App _ _) + | Var fun <- fun + , fun `hasKey` runRWKey + -- N.B. we may have an over-saturated application of the form: + -- runRW (\s -> \x -> ...) y + , arg_ty1 : arg_ty2 : arg3 : rest <- args + = do { fun_ty1 <- lintCoreArg (idType fun) arg_ty1 + ; fun_ty2 <- lintCoreArg fun_ty1 arg_ty2 + -- See Note [Linting of runRW#] + ; let lintRunRWCont :: CoreArg -> LintM LintedType + lintRunRWCont (Cast expr co) = do + ty <- lintRunRWCont expr + lintCastExpr expr ty co + lintRunRWCont expr@(Lam _ _) = do + lintJoinLams 1 (Just fun) expr + lintRunRWCont other = markAllJoinsBad $ lintCoreExpr other + -- TODO: Look through ticks? + ; arg3_ty <- lintRunRWCont arg3 + ; app_ty <- lintValApp arg3 fun_ty2 arg3_ty + ; lintCoreArgs app_ty rest } + + | Var fun <- fun + , fun `hasKey` runRWKey + = failWithL (text "Invalid runRW# application") + + | otherwise = do { fun_ty <- lintCoreFun fun (length args) ; lintCoreArgs fun_ty args } where @@ -951,6 +1024,25 @@ checkDeadIdOcc id = return () ------------------ +lintJoinBndrType :: LintedType -- Type of the body + -> LintedId -- Possibly a join Id + -> LintM () +-- Checks that the return type of a join Id matches the body +-- E.g. join j x = rhs in body +-- The type of 'rhs' must be the same as the type of 'body' +lintJoinBndrType body_ty bndr + | Just arity <- isJoinId_maybe bndr + , let bndr_ty = idType bndr + , (bndrs, res) <- splitPiTys bndr_ty + = checkL (length bndrs >= arity + && body_ty `eqType` mkPiTys (drop arity bndrs) res) $ + hang (text "Join point returns different type than body") + 2 (vcat [ text "Join bndr:" <+> ppr bndr <+> dcolon <+> ppr (idType bndr) + , text "Join arity:" <+> ppr arity + , text "Body type:" <+> ppr body_ty ]) + | otherwise + = return () + checkJoinOcc :: Id -> JoinArity -> LintM () -- Check that if the occurrence is a JoinId, then so is the -- binding site, and it's a valid join Id @@ -1115,11 +1207,15 @@ lintTyApp fun_ty arg_ty = failWithL (mkTyAppMsg fun_ty arg_ty) ----------------- + +-- | @lintValApp arg fun_ty arg_ty@ lints an application of @fun arg@ +-- where @fun :: fun_ty@ and @arg :: arg_ty@, returning the type of the +-- application. lintValApp :: CoreExpr -> LintedType -> LintedType -> LintM LintedType lintValApp arg fun_ty arg_ty - | Just (arg,res) <- splitFunTy_maybe fun_ty - = do { ensureEqTys arg arg_ty err1 - ; return res } + | Just (arg_ty', res_ty') <- splitFunTy_maybe fun_ty + = do { ensureEqTys arg_ty' arg_ty err1 + ; return res_ty' } | otherwise = failWithL err2 where @@ -2756,11 +2852,11 @@ mkInvalidJoinPointMsg var ty 2 (ppr var <+> dcolon <+> ppr ty) mkBadJoinArityMsg :: Var -> Int -> Int -> CoreExpr -> SDoc -mkBadJoinArityMsg var ar nlams rhs +mkBadJoinArityMsg var ar n rhs = vcat [ text "Join point has too few lambdas", text "Join var:" <+> ppr var, text "Join arity:" <+> ppr ar, - text "Number of lambdas:" <+> ppr nlams, + text "Number of lambdas:" <+> ppr (ar - n), text "Rhs = " <+> ppr rhs ] ===================================== compiler/GHC/Core/Opt/OccurAnal.hs ===================================== @@ -39,6 +39,7 @@ import GHC.Types.Demand ( argOneShots, argsOneShots ) import GHC.Data.Graph.Directed ( SCC(..), Node(..) , stronglyConnCompFromEdgedVerticesUniq , stronglyConnCompFromEdgedVerticesUniqR ) +import GHC.Builtin.Names( runRWKey ) import GHC.Types.Unique import GHC.Types.Unique.FM import GHC.Types.Unique.Set @@ -1882,8 +1883,15 @@ occAnalApp :: OccEnv -> (UsageDetails, Expr CoreBndr) -- Naked variables (not applied) end up here too occAnalApp env (Var fun, args, ticks) - | null ticks = (all_uds, mkApps fun' args') - | otherwise = (all_uds, mkTicks ticks $ mkApps fun' args') + -- Account for join arity of runRW# continuation + -- See Note [Simplification of runRW#] + | fun `hasKey` runRWKey + , [t1, t2, arg] <- args + , let (usage, arg') = occAnalRhs env (Just 1) arg + = (usage, mkTicks ticks $ mkApps (Var fun) [t1, t2, arg']) + + | otherwise + = (all_uds, mkTicks ticks $ mkApps fun' args') where (fun', fun_id') = lookupVarEnv (occ_bs_env env) fun `orElse` (Var fun, fun) ===================================== compiler/GHC/Core/Opt/SetLevels.hs ===================================== @@ -91,11 +91,13 @@ import GHC.Types.Demand ( StrictSig, Demand, isStrictDmd, splitStrictSig, import GHC.Types.Cpr ( mkCprSig, botCpr ) import GHC.Types.Name ( getOccName, mkSystemVarName ) import GHC.Types.Name.Occurrence ( occNameString ) +import GHC.Types.Unique ( hasKey ) import GHC.Core.Type ( Type, mkLamTypes, splitTyConApp_maybe, tyCoVarsOfType , mightBeUnliftedType, closeOverKindsDSet ) import GHC.Types.Basic ( Arity, RecFlag(..), isRec ) import GHC.Core.DataCon ( dataConOrigResTy ) import GHC.Builtin.Types +import GHC.Builtin.Names ( runRWKey ) import GHC.Types.Unique.Supply import GHC.Utils.Misc import GHC.Utils.Outputable @@ -399,8 +401,14 @@ lvlNonTailExpr env expr lvlApp :: LevelEnv -> CoreExprWithFVs -> (CoreExprWithFVs, [CoreExprWithFVs]) -- Input application - -> LvlM LevelledExpr -- Result expression + -> LvlM LevelledExpr -- Result expression lvlApp env orig_expr ((_,AnnVar fn), args) + -- Try to ensure that runRW#'s continuation isn't floated out. + -- See Note [Simplification of runRW#]. + | fn `hasKey` runRWKey + = do { args' <- mapM (lvlExpr env) args + ; return (foldl' App (lookupVar env fn) args') } + | floatOverSat env -- See Note [Floating over-saturated applications] , arity > 0 , arity < n_val_args ===================================== compiler/GHC/Core/Opt/Simplify.hs ===================================== @@ -37,10 +37,13 @@ import GHC.Core.DataCon , StrictnessMark (..) ) import GHC.Core.Opt.Monad ( Tick(..), SimplMode(..) ) import GHC.Core +import GHC.Builtin.Types.Prim( realWorldStatePrimTy ) +import GHC.Builtin.Names( runRWKey ) import GHC.Types.Demand ( StrictSig(..), dmdTypeDepth, isStrictDmd , mkClosedStrictSig, topDmd, botDiv ) import GHC.Types.Cpr ( mkCprSig, botCpr ) import GHC.Core.Ppr ( pprCoreExpr ) +import GHC.Types.Unique ( hasKey ) import GHC.Core.Unfold import GHC.Core.Utils import GHC.Core.SimpleOpt ( pushCoTyArg, pushCoValArg @@ -1877,14 +1880,36 @@ rebuildCall env info (CastIt co cont) rebuildCall env info (ApplyToTy { sc_arg_ty = arg_ty, sc_cont = cont }) = rebuildCall env (addTyArgTo info arg_ty) cont -rebuildCall env info@(ArgInfo { ai_encl = encl_rules, ai_type = fun_ty +---------- The runRW# rule. Do this after absorbing all arguments ------ +-- runRW# :: forall (r :: RuntimeRep) (o :: TYPE r). (State# RealWorld -> o) -> o +-- K[ runRW# rr ty (\s. body) ] --> runRW rr' ty' (\s. K[ body ]) +rebuildCall env (ArgInfo { ai_fun = fun, ai_args = rev_args }) + (ApplyToVal { sc_arg = arg, sc_env = arg_se, sc_cont = cont }) + | fun `hasKey` runRWKey + , not (contIsStop cont) -- Don't fiddle around if the continuation is boring + , [ TyArg {}, TyArg {} ] <- rev_args + = do { s <- newId (fsLit "s") realWorldStatePrimTy + ; let env' = (arg_se `setInScopeFromE` env) `addNewInScopeIds` [s] + cont' = ApplyToVal { sc_dup = Simplified, sc_arg = Var s + , sc_env = env', sc_cont = cont } + ; body' <- simplExprC env' arg cont' + ; let arg' = Lam s body' + ty' = contResultType cont + rr' = getRuntimeRep ty' + call' = mkApps (Var fun) [mkTyArg rr', mkTyArg ty', arg'] + ; return (emptyFloats env, call') } + +rebuildCall env info@(ArgInfo { ai_type = fun_ty, ai_encl = encl_rules , ai_strs = str:strs, ai_discs = disc:discs }) (ApplyToVal { sc_arg = arg, sc_env = arg_se , sc_dup = dup_flag, sc_cont = cont }) + + -- Argument is already simplified | isSimplified dup_flag -- See Note [Avoid redundant simplification] = rebuildCall env (addValArgTo info' arg) cont - | str -- Strict argument + -- Strict arguments + | str , sm_case_case (getMode env) = -- pprTrace "Strict Arg" (ppr arg $$ ppr (seIdSubst env) $$ ppr (seInScope env)) $ simplExprF (arg_se `setInScopeFromE` env) arg @@ -1892,7 +1917,8 @@ rebuildCall env info@(ArgInfo { ai_encl = encl_rules, ai_type = fun_ty , sc_dup = Simplified, sc_cont = cont }) -- Note [Shadowing] - | otherwise -- Lazy argument + -- Lazy arguments + | otherwise -- DO NOT float anything outside, hence simplExprC -- There is no benefit (unlike in a let-binding), and we'd -- have to be very careful about bogus strictness through ===================================== compiler/GHC/Core/SimpleOpt.hs ===================================== @@ -957,6 +957,31 @@ will happen the next time either. See test T16254, which checks the behavior of newtypes. +Note [Don't float join points] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +exprIsConApp_maybe should succeed on + let v = e in Just v +returning [x=e] as one of the [FloatBind]. But it must +NOT succeed on + join j x = rhs in Just v +because join-points can't be gaily floated. Consider + case (join j x = rhs in Just) of + K p q -> blah +We absolutely must not "simplify" this to + join j x = rhs + in blah +because j's return type is (Maybe t), quite different to blah's. + +You might think this could never happen, because j can't be +tail-called in the body if the body returns a constructor. But +in !3113 we had a /dead/ join point (which is not illegal), +and its return type was wonky. + +The simple thing is not to float a join point. The next iteration +of the simplifier will sort everything out. And it there is +a join point, the chances are that the body is not a constructor +application, so failing faster is good. + Note [exprIsConApp_maybe for data-con wrappers: tricky corner] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Generally speaking @@ -1065,6 +1090,8 @@ exprIsConApp_maybe (in_scope, id_unf) expr in go subst' (float:floats) body (CC args co) go subst floats (Let (NonRec bndr rhs) expr) cont + | not (isJoinId bndr) + -- Crucial guard! See Note [Don't float join points] = let rhs' = subst_expr subst rhs (subst', bndr') = subst_bndr subst bndr float = FloatLet (NonRec bndr' rhs') ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -760,7 +760,13 @@ data ArgInfo = CpeApp CoreArg | CpeCast Coercion | CpeTick (Tickish Id) -{- Note [runRW arg] +instance Outputable ArgInfo where + ppr (CpeApp arg) = text "app" <+> ppr arg + ppr (CpeCast co) = text "cast" <+> ppr co + ppr (CpeTick tick) = text "tick" <+> ppr tick + +{- + Note [runRW arg] ~~~~~~~~~~~~~~~~~~~ If we got, say runRW# (case bot of {}) @@ -823,14 +829,23 @@ cpeApp top_env expr -- rather than the far superior "f x y". Test case is par01. = let (terminal, args', depth') = collect_args arg in cpe_app env terminal (args' ++ args) (depth + depth' - 1) - cpe_app env (Var f) [CpeApp _runtimeRep at Type{}, CpeApp _type at Type{}, CpeApp arg] 1 + cpe_app env (Var f) (CpeApp _runtimeRep at Type{} : CpeApp _type at Type{} : CpeApp arg : rest) n | f `hasKey` runRWKey + -- N.B. While it may appear that n == 1 in the case of runRW# + -- applications, keep in mind that we may have applications that return + , n >= 1 -- See Note [runRW magic] -- Replace (runRW# f) by (f realWorld#), beta reducing if possible (this -- is why we return a CorePrepEnv as well) = case arg of - Lam s body -> cpe_app (extendCorePrepEnv env s realWorldPrimId) body [] 0 - _ -> cpe_app env arg [CpeApp (Var realWorldPrimId)] 1 + Lam s body -> cpe_app (extendCorePrepEnv env s realWorldPrimId) body rest (n-2) + _ -> cpe_app env arg (CpeApp (Var realWorldPrimId) : rest) (n-1) + -- TODO: What about casts? + + cpe_app _env (Var f) args n + | f `hasKey` runRWKey + = pprPanic "cpe_app(runRW#)" (ppr args $$ ppr n) + cpe_app env (Var v) args depth = do { v1 <- fiddleCCall v ; let e2 = lookupCorePrepEnv env v1 @@ -959,8 +974,77 @@ pragma. It is levity-polymorphic. => (State# RealWorld -> (# State# RealWorld, o #)) -> (# State# RealWorld, o #) -It needs no special treatment in GHC except this special inlining here -in CorePrep (and in GHC.CoreToByteCode). +It's correctness needs no special treatment in GHC except this special inlining +here in CorePrep (and in GHC.CoreToByteCode). + +However, there are a variety of optimisation opportunities that the simplifier +takes advantage of. See Note [Simplification of runRW#]. + + +Note [Simplification of runRW#] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider the program, + + case runRW# (\s -> let n = I# 42# in n) of + I# n# -> f n# + +There is no reason why we should allocate an I# constructor given that we +immediately destructure it. To avoid this the simplifier will push strict +contexts into runRW's continuation. That is, it transforms + + K[ runRW# @r @ty cont ] + ~> + runRW# @r @ty K[cont] + +This has a few interesting implications. Consider, for instance, this program: + + join j = ... + in case runRW# @r @ty cont of + result -> jump j result + +Performing the transform described above would result in: + + join j x = ... + in runRW# @r @ty (\s -> + case cont of in + result -> jump j result + ) + +If runRW# were a "normal" function this call to join point j would not be +allowed in its continuation argument. However, since runRW# is inlined (as +described in Note [runRW magic] above), such join point occurences are +completely fine. Both occurrence analysis and Core Lint have special treatment +for runRW# applications. See Note [Linting of runRW#] for details on the latter. + +Moreover, it's helpful to ensure that runRW's continuation isn't floated out +(since doing so would then require a call, whereas we would otherwise end up +with straight-line). Consequently, GHC.Core.Opt.SetLevels.lvlApp has special +treatment for runRW# applications, ensure the arguments are not floated if +MFEs. + +Other considered designs +------------------------ + +One design that was rejected was to *require* that runRW#'s continuation be +headed by a lambda. However, this proved to be quite fragile. For instance, +SetLevels is very eager to float bottoming expressions. For instance given +something of the form, + + runRW# @r @ty (\s -> case expr of x -> undefined) + +SetLevels will see that the body the lambda is bottoming and will consequently +float it to the top-level (assuming expr has no free coercion variables which +prevent this). We therefore end up with + + runRW# @r @ty (\s -> lvl s) + +Which the simplifier will beta reduce, leaving us with + + runRW# @r @ty lvl + +Breaking our desired invariant. Ultimately we decided to simply accept that +the continuation may not be a manifest lambda. + -- --------------------------------------------------------------------------- -- CpeArg: produces a result satisfying CpeArg ===================================== compiler/GHC/HsToCore/Utils.hs ===================================== @@ -482,7 +482,6 @@ mkCoreAppDs _ (Var f `App` Type _r `App` Type ty1 `App` Type ty2 `App` arg1) arg Var v1 | isInternalName (idName v1) -> v1 -- Note [Desugaring seq], points (2) and (3) _ -> mkWildValBinder ty1 - mkCoreAppDs s fun arg = mkCoreApp s fun arg -- The rest is done in GHC.Core.Make -- NB: No argument can be levity polymorphic View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f10d11fa49fa9a7a506c4fdbdf86521c2a8d3495...46720997a0b1fa2971a884adf43de096ce130a7e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f10d11fa49fa9a7a506c4fdbdf86521c2a8d3495...46720997a0b1fa2971a884adf43de096ce130a7e You're receiving 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 29 05:40:08 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 29 May 2020 01:40:08 -0400 Subject: [Git][ghc/ghc][master] Eta expand un-saturated primops Message-ID: <5ed0a0387948e_6e263f9ed7570e802510234@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 277c2f26 by Ben Gamari at 2020-05-29T01:39:55-04:00 Eta expand un-saturated primops Now since we no longer try to predict CAFfyness we have no need for the solution to #16846. Eta expanding unsaturated primop applications is conceptually simpler, especially in the presence of levity polymorphism. This essentially reverts cac8dc9f51e31e4c0a6cd9bc302f7e1bc7c03beb, as suggested in #18079. Closes #18079. - - - - - 8 changed files: - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Types/Id.hs - testsuite/tests/codeGen/should_fail/T13233.hs - testsuite/tests/codeGen/should_fail/T13233.stderr - testsuite/tests/codeGen/should_fail/T13233_elab.stderr Changes: ===================================== compiler/GHC/Builtin/PrimOps.hs ===================================== @@ -590,33 +590,85 @@ primOpOcc op = case primOpInfo op of {- Note [Primop wrappers] ~~~~~~~~~~~~~~~~~~~~~~~~~ -Previously hasNoBinding would claim that PrimOpIds didn't have a curried -function definition. This caused quite some trouble as we would be forced to -eta expand unsaturated primop applications very late in the Core pipeline. Not -only would this produce unnecessary thunks, but it would also result in nasty -inconsistencies in CAFfy-ness determinations (see #16846 and -Note [CAFfyness inconsistencies due to late eta expansion] in GHC.Iface.Tidy). - -However, it was quite unnecessary for hasNoBinding to claim this; primops in -fact *do* have curried definitions which are found in GHC.PrimopWrappers, which -is auto-generated by utils/genprimops from prelude/primops.txt.pp. These wrappers -are standard Haskell functions mirroring the types of the primops they wrap. -For instance, in the case of plusInt# we would have: + +To support (limited) use of primops in GHCi genprimopcode generates the +GHC.PrimopWrappers module. This module contains a "primop wrapper" +binding for each primop. These are standard Haskell functions mirroring the +types of the primops they wrap. For instance, in the case of plusInt# we would +have: module GHC.PrimopWrappers where import GHC.Prim as P + + plusInt# :: Int# -> Int# -> Int# plusInt# a b = P.plusInt# a b -We now take advantage of these curried definitions by letting hasNoBinding -claim that PrimOpIds have a curried definition and then rewrite any unsaturated -PrimOpId applications that we find during CoreToStg as applications of the -associated wrapper (e.g. `GHC.Prim.plusInt# 3#` will get rewritten to -`GHC.PrimopWrappers.plusInt# 3#`).` The Id of the wrapper for a primop can be -found using 'PrimOp.primOpWrapperId'. +The Id for the wrapper of a primop can be found using +'GHC.Builtin.PrimOp.primOpWrapperId'. However, GHCi does not use this mechanism +to link primops; it rather does a rather hacky symbol lookup (see +GHC.ByteCode.Linker.primopToCLabel). TODO: Perhaps this should be changed? + +Note that these wrappers aren't *quite* +as expressive as their unwrapped breathern in that they may exhibit less levity +polymorphism. For instance, consider the case of mkWeakNoFinalizer# which has +type: + + mkWeakNoFinalizer# :: forall (r :: RuntimeRep) (k :: TYPE r) (v :: Type). + k -> v + -> State# RealWorld + -> (# State# RealWorld, Weak# v #) + +Naively we could generate a wrapper of the form, + + + mkWeakNoFinalizer# k v s = GHC.Prim.mkWeakNoFinalizer# k v s + +However, this would require that 'k' bind the levity-polymorphic key, +which is disallowed by our levity polymorphism validity checks (see Note +[Levity polymorphism invariants] in GHC.Core). Consequently, we give the +wrapper the simpler, less polymorphic type + + mkWeakNoFinalizer# :: forall (k :: Type) (v :: Type). + k -> v + -> State# RealWorld + -> (# State# RealWorld, Weak# v #) + +This simplification tends to be good enough for GHCi uses given that there are +few levity polymorphic primops and we do little simplification on interpreted +code anyways. + +TODO: This behavior is actually wrong; a program becomes ill-typed upon +replacing a real primop occurrence with one of its wrapper due to the fact that +the former has an additional type binder. Hmmm.... + +Note [Eta expanding primops] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +STG requires that primop applications be saturated. This makes code generation +significantly simpler since otherwise we would need to define a calling +convention for curried applications that can accomodate levity polymorphism. + +To ensure saturation, CorePrep eta expands expand all primop applications as +described in Note [Eta expansion of hasNoBinding things in CorePrep] in +GHC.Core.Prep. + +Historical Note: + +For a short period around GHC 8.8 we rewrote unsaturated primop applications to +rather use the primop's wrapper (see Note [Primop wrappers] in +GHC.Builtin.PrimOps) instead of eta expansion. This was because at the time +CoreTidy would try to predict the CAFfyness of bindings that would be produced +by CorePrep for inclusion in interface files. Eta expanding during CorePrep +proved to be very difficult to predict, leading to nasty inconsistencies in +CAFfyness determinations (see #16846). -Nota Bene: GHC.PrimopWrappers is needed *regardless*, because it's -used by GHCi, which does not implement primops direct at all. +Thankfully, we now no longer try to predict CAFfyness but rather compute it on +GHC STG (see Note [SRTs] in GHC.Cmm.Info.Build) and inject it into the interface +file after code generation (see TODO: Refer to whatever falls out of #18096). +This is much simpler and avoids the potential for inconsistency, allowing us to +return to the somewhat simpler eta expansion approach for unsaturated primops. +See #18079. -} -- | Returns the 'Id' of the wrapper associated with the given 'PrimOp'. ===================================== compiler/GHC/ByteCode/Linker.hs ===================================== @@ -176,6 +176,7 @@ nameToCLabel n suffix = mkFastString label ] +-- See Note [Primop wrappers] in GHC.Builtin.PrimOps primopToCLabel :: PrimOp -> String -> String primopToCLabel primop suffix = concat [ "ghczmprim_GHCziPrimopWrappers_" ===================================== compiler/GHC/CoreToStg.hs ===================================== @@ -45,7 +45,7 @@ import GHC.Driver.Session import GHC.Driver.Ways import GHC.Types.ForeignCall import GHC.Types.Demand ( isUsedOnce ) -import GHC.Builtin.PrimOps ( PrimCall(..), primOpWrapperId ) +import GHC.Builtin.PrimOps ( PrimCall(..) ) import GHC.Types.SrcLoc ( mkGeneralSrcSpan ) import GHC.Builtin.Names ( unsafeEqualityProofName ) @@ -539,12 +539,10 @@ coreToStgApp f args ticks = do (dropRuntimeRepArgs (fromMaybe [] (tyConAppArgs_maybe res_ty))) -- Some primitive operator that might be implemented as a library call. - -- As described in Note [Primop wrappers] in GHC.Builtin.PrimOps, here we - -- turn unsaturated primop applications into applications of - -- the primop's wrapper. - PrimOpId op - | saturated -> StgOpApp (StgPrimOp op) args' res_ty - | otherwise -> StgApp (primOpWrapperId op) args' + -- As noted by Note [Eta expanding primops] in GHC.Builtin.PrimOps + -- we require that primop applications be saturated. + PrimOpId op -> ASSERT( saturated ) + StgOpApp (StgPrimOp op) args' res_ty -- A call to some primitive Cmm function. FCallId (CCall (CCallSpec (StaticTarget _ lbl (Just pkgId) True) ===================================== compiler/GHC/CoreToStg/Prep.hs ===================================== @@ -71,7 +71,7 @@ import qualified Data.Set as S The goal of this pass is to prepare for code generation. -1. Saturate constructor applications. +1. Saturate constructor and primop applications. 2. Convert to A-normal form; that is, function arguments are always variables. @@ -1151,15 +1151,11 @@ maybeSaturate deals with eta expanding to saturate things that can't deal with unsaturated applications (identified by 'hasNoBinding', currently just foreign calls and unboxed tuple/sum constructors). -Note that eta expansion in CorePrep is very fragile due to the "prediction" of -CAFfyness made during tidying (see Note [CAFfyness inconsistencies due to eta -expansion in CorePrep] in GHC.Iface.Tidy for details. We previously saturated primop +Historical Note: Note that eta expansion in CorePrep used to be very fragile +due to the "prediction" of CAFfyness that we used to make during tidying. +We previously saturated primop applications here as well but due to this fragility (see #16846) we now deal with this another way, as described in Note [Primop wrappers] in GHC.Builtin.PrimOps. - -It's quite likely that eta expansion of constructor applications will -eventually break in a similar way to how primops did. We really should -eliminate this case as well. -} maybeSaturate :: Id -> CpeApp -> Int -> UniqSM CpeRhs ===================================== compiler/GHC/Types/Id.hs ===================================== @@ -515,20 +515,12 @@ hasNoBinding :: Id -> Bool -- ^ Returns @True@ of an 'Id' which may not have a -- binding, even though it is defined in this module. --- Data constructor workers used to be things of this kind, but --- they aren't any more. Instead, we inject a binding for --- them at the CorePrep stage. --- --- 'PrimOpId's also used to be of this kind. See Note [Primop wrappers] in GHC.Builtin.PrimOps. --- for the history of this. --- --- Note that CorePrep currently eta expands things no-binding things and this --- can cause quite subtle bugs. See Note [Eta expansion of hasNoBinding things --- in CorePrep] in CorePrep for details. --- --- EXCEPT: unboxed tuples, which definitely have no binding +-- Data constructor workers used to be things of this kind, but they aren't any +-- more. Instead, we inject a binding for them at the CorePrep stage. The +-- exception to this is unboxed tuples and sums datacons, which definitely have +-- no binding hasNoBinding id = case Var.idDetails id of - PrimOpId _ -> False -- See Note [Primop wrappers] in GHC.Builtin.PrimOps + PrimOpId _ -> True -- See Note [Eta expanding primops] in GHC.Builtin.PrimOps FCallId _ -> True DataConWorkId dc -> isUnboxedTupleCon dc || isUnboxedSumCon dc _ -> isCompulsoryUnfolding (idUnfolding id) ===================================== testsuite/tests/codeGen/should_fail/T13233.hs ===================================== @@ -21,9 +21,6 @@ obscure _ = () quux :: () quux = obscure (#,#) --- It used to be that primops has no binding. However, as described in --- Note [Primop wrappers] in GHC.Builtin.PrimOps we now rewrite unsaturated primop --- applications to their wrapper, which allows safe use of levity polymorphism. primop :: forall (rep :: RuntimeRep) (a :: TYPE rep) b c. a -> b -> (State# RealWorld -> (# State# RealWorld, c #)) -> State# RealWorld -> (# State# RealWorld, Weak# b #) ===================================== testsuite/tests/codeGen/should_fail/T13233.stderr ===================================== @@ -20,3 +20,15 @@ T13233.hs:22:16: error: Levity-polymorphic arguments: a :: TYPE rep1 b :: TYPE rep2 + +T13233.hs:27:10: error: + Cannot use function with levity-polymorphic arguments: + mkWeak# :: a + -> b + -> (State# RealWorld -> (# State# RealWorld, c #)) + -> State# RealWorld + -> (# State# RealWorld, Weak# b #) + (Note that levity-polymorphic primops such as 'coerce' and unboxed tuples + are eta-expanded internally because they must occur fully saturated. + Use -fprint-typechecker-elaboration to display the full expression.) + Levity-polymorphic arguments: a :: TYPE rep ===================================== testsuite/tests/codeGen/should_fail/T13233_elab.stderr ===================================== @@ -18,3 +18,12 @@ T13233_elab.hs:25:16: error: Levity-polymorphic arguments: a :: TYPE rep1 b :: TYPE rep2 + +T13233_elab.hs:33:10: + Cannot use function with levity-polymorphic arguments: + mkWeak# @rep @a @b @c :: a + -> b + -> (State# RealWorld -> (# State# RealWorld, c #)) + -> State# RealWorld + -> (# State# RealWorld, Weak# b #) + Levity-polymorphic arguments: a :: TYPE rep View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/277c2f26e6966e0cfaa1ddcd297af44766f37958 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/277c2f26e6966e0cfaa1ddcd297af44766f37958 You're receiving 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 29 05:40:44 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 29 May 2020 01:40:44 -0400 Subject: [Git][ghc/ghc][master] base: Scrap deprecation plan for Data.Monoid.{First,Last} Message-ID: <5ed0a05cbca16_6e2611db28542514969@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: f44d7ae0 by Simon Jakobi at 2020-05-29T01:40:34-04:00 base: Scrap deprecation plan for Data.Monoid.{First,Last} See the discussion on the libraries mailing list for context: https://mail.haskell.org/pipermail/libraries/2020-April/030357.html - - - - - 2 changed files: - libraries/base/Data/Monoid.hs - libraries/base/changelog.md Changes: ===================================== libraries/base/Data/Monoid.hs ===================================== @@ -129,16 +129,6 @@ import Data.Semigroup.Internal -- -- >>> getFirst (First (Just "hello") <> First Nothing <> First (Just "world")) -- Just "hello" --- --- Use of this type is discouraged. Note the following equivalence: --- --- > Data.Monoid.First x === Maybe (Data.Semigroup.First x) --- --- In addition to being equivalent in the structural sense, the two --- also have 'Monoid' instances that behave the same. This type will --- be marked deprecated in GHC 8.8, and removed in GHC 8.10. --- Users are advised to use the variant from "Data.Semigroup" and wrap --- it in 'Maybe'. newtype First a = First { getFirst :: Maybe a } deriving ( Eq -- ^ @since 2.01 , Ord -- ^ @since 2.01 @@ -168,16 +158,6 @@ instance Monoid (First a) where -- -- >>> getLast (Last (Just "hello") <> Last Nothing <> Last (Just "world")) -- Just "world" --- --- Use of this type is discouraged. Note the following equivalence: --- --- > Data.Monoid.Last x === Maybe (Data.Semigroup.Last x) --- --- In addition to being equivalent in the structural sense, the two --- also have 'Monoid' instances that behave the same. This type will --- be marked deprecated in GHC 8.8, and removed in GHC 8.10. --- Users are advised to use the variant from "Data.Semigroup" and wrap --- it in 'Maybe'. newtype Last a = Last { getLast :: Maybe a } deriving ( Eq -- ^ @since 2.01 , Ord -- ^ @since 2.01 ===================================== libraries/base/changelog.md ===================================== @@ -11,6 +11,9 @@ * Add `singleton` function for `Data.List.NonEmpty`. + * The planned deprecation of `Data.Monoid.First` and `Data.Monoid.Last` + is scrapped due to difficulties with the suggested migration path. + * Add `Generic` instances to `Fingerprint`, `GiveGCStats`, `GCFlags`, `ConcFlags`, `DebugFlags`, `CCFlags`, `DoHeapProfile`, `ProfFlags`, `DoTrace`, `TraceFlags`, `TickyFlags`, `ParFlags`, `RTSFlags`, `RTSStats`, View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f44d7ae08442ae6227db37cacc97fe0def8017c5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f44d7ae08442ae6227db37cacc97fe0def8017c5 You're receiving 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 29 05:41:22 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 29 May 2020 01:41:22 -0400 Subject: [Git][ghc/ghc][master] Fix typo in documentation Message-ID: <5ed0a0823995a_6e26121fd8b42517832@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 8b494895 by Jeremy Schlatter at 2020-05-29T01:41:12-04:00 Fix typo in documentation - - - - - 1 changed file: - docs/users_guide/using-concurrent.rst Changes: ===================================== docs/users_guide/using-concurrent.rst ===================================== @@ -16,7 +16,7 @@ Optionally, the program may be linked with the :ghc-flag:`-threaded` option (see :ref:`options-linker`. This provides two benefits: - It enables the :rts-flag:`-N ⟨x⟩` to be used, which allows threads to run in - parallelism on a multi-processor or multi-core machine. See :ref:`using-smp`. + parallel on a multi-processor or multi-core machine. See :ref:`using-smp`. - If a thread makes a foreign call (and the call is not marked ``unsafe``), then other Haskell threads in the program will continue View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8b4948951198f93290191d4ee32f92dffed803f4 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8b4948951198f93290191d4ee32f92dffed803f4 You're receiving 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 29 05:42:02 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 29 May 2020 01:42:02 -0400 Subject: [Git][ghc/ghc][master] Always define USE_PTHREAD_FOR_ITIMER for FreeBSD. Message-ID: <5ed0a0aaef432_6e26db7740825207dc@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 998450f4 by Gleb Popov at 2020-05-29T01:41:53-04:00 Always define USE_PTHREAD_FOR_ITIMER for FreeBSD. - - - - - 1 changed file: - rts/posix/Itimer.c Changes: ===================================== rts/posix/Itimer.c ===================================== @@ -48,7 +48,7 @@ #define USE_PTHREAD_FOR_ITIMER #endif -#if defined(freebsd_HOST_OS) && defined(THREADED_RTS) +#if defined(freebsd_HOST_OS) #define USE_PTHREAD_FOR_ITIMER #endif View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/998450f4c67e8f701455927c9619b8d53f2b733b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/998450f4c67e8f701455927c9619b8d53f2b733b You're receiving 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 29 05:42:46 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 29 May 2020 01:42:46 -0400 Subject: [Git][ghc/ghc][master] hadrian: introduce 'install' target Message-ID: <5ed0a0d6474d8_6e26db7740825234ad@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: f9a513e0 by Alp Mestanogullari at 2020-05-29T01:42:36-04:00 hadrian: introduce 'install' target Its logic is very simple. It `need`s the `binary-dist-dir` target and runs suitable `configure` and `make install` commands for the user. A new `--prefix` command line argument is introduced to specify where GHC should be installed. - - - - - 3 changed files: - hadrian/README.md - hadrian/src/CommandLine.hs - hadrian/src/Rules/BinaryDist.hs Changes: ===================================== hadrian/README.md ===================================== @@ -258,6 +258,19 @@ $ ./configure [--prefix=PATH] && make install workflow, for now. +### Building and installing GHC + +You can get Hadrian to build _and_ install a binary distribution in one go +with the following command: + +``` sh +$ build install --prefix=/some/absolute/path +``` + +This builds everything that would be shipped in a bindist, without creating +the archive, and just runs `./configure --prefix=PATH` and `make install` +to get GHC installed installed at `/some/absolute/path`. + #### Building Stage3 It is possible to define a build flavour that builds a Stage3 compiler, which is ===================================== hadrian/src/CommandLine.hs ===================================== @@ -1,7 +1,8 @@ module CommandLine ( optDescrs, cmdLineArgsMap, cmdFlavour, lookupFreeze1, lookupFreeze2, cmdIntegerSimple, cmdProgressInfo, cmdConfigure, cmdCompleteSetting, - cmdDocsArgs, lookupBuildRoot, TestArgs(..), TestSpeed(..), defaultTestArgs + cmdDocsArgs, lookupBuildRoot, TestArgs(..), TestSpeed(..), defaultTestArgs, + cmdPrefix ) where import Data.Either @@ -30,6 +31,7 @@ data CommandLineArgs = CommandLineArgs , buildRoot :: BuildRoot , testArgs :: TestArgs , docTargets :: DocTargets + , prefix :: Maybe FilePath , completeStg :: Maybe String } deriving (Eq, Show) @@ -45,6 +47,7 @@ defaultCommandLineArgs = CommandLineArgs , buildRoot = BuildRoot "_build" , testArgs = defaultTestArgs , docTargets = Set.fromList [minBound..maxBound] + , prefix = Nothing , completeStg = Nothing } -- | These arguments are used by the `test` target. @@ -207,6 +210,9 @@ readBrokenTests way = let newTests = words tests ++ brokenTests (testArgs flags) in flags { testArgs = (testArgs flags) {brokenTests = newTests} } +readPrefix :: Maybe String -> Either String (CommandLineArgs -> CommandLineArgs) +readPrefix ms = Right $ \flags -> flags { prefix = ms } + readCompleteStg :: Maybe String -> Either String (CommandLineArgs -> CommandLineArgs) readCompleteStg ms = Right $ \flags -> flags { completeStg = ms } @@ -281,6 +287,8 @@ optDescrs = , Option [] ["broken-test"] (OptArg readBrokenTests "TEST_NAME") "consider these tests to be broken" , Option ['a'] ["test-accept"] (NoArg readTestAccept) "Accept new output of tests" + , Option [] ["prefix"] (OptArg readPrefix "PATH") + "Destination path for the bindist 'install' rule" , Option [] ["complete-setting"] (OptArg readCompleteStg "SETTING") "Setting key to autocomplete, for the 'autocomplete' target." ] @@ -332,6 +340,9 @@ cmdConfigure = configure <$> cmdLineArgs cmdFlavour :: Action (Maybe String) cmdFlavour = flavour <$> cmdLineArgs +cmdPrefix :: Action (Maybe String) +cmdPrefix = prefix <$> cmdLineArgs + cmdCompleteSetting :: Action (Maybe String) cmdCompleteSetting = completeStg <$> cmdLineArgs ===================================== hadrian/src/Rules/BinaryDist.hs ===================================== @@ -2,6 +2,7 @@ module Rules.BinaryDist where import Hadrian.Haskell.Cabal +import CommandLine import Context import Expression import Oracles.Setting @@ -98,6 +99,18 @@ other, the install script: bindistRules :: Rules () bindistRules = do root <- buildRootRules + phony "install" $ do + need ["binary-dist-dir"] + version <- setting ProjectVersion + targetPlatform <- setting TargetPlatformFull + let ghcVersionPretty = "ghc-" ++ version ++ "-" ++ targetPlatform + bindistFilesDir = root -/- "bindist" -/- ghcVersionPretty + prefixErr = "You must specify a path with --prefix when using the" + ++ " 'install' rule" + installPrefix <- fromMaybe (error prefixErr) <$> cmdPrefix + runBuilder (Configure bindistFilesDir) ["--prefix="++installPrefix] [] [] + runBuilder (Make bindistFilesDir) ["install"] [] [] + phony "binary-dist-dir" $ do -- We 'need' all binaries and libraries targets <- mapM pkgTarget =<< stagePackages Stage1 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f9a513e064bd8a33ad6f8aa5fb8673931507eca1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f9a513e064bd8a33ad6f8aa5fb8673931507eca1 You're receiving 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 29 06:14:26 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 29 May 2020 02:14:26 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 12 commits: Fix "build/elem" RULE. Message-ID: <5ed0a84295bfd_6e2611db28542532217@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: f10d11fa by Andreas Klebinger at 2020-05-29T01:38:42-04: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. - - - - - bbeb2389 by Ben Gamari at 2020-05-29T01:39:19-04:00 CoreToStg: Add Outputable ArgInfo instance - - - - - 0e3361ca by Simon Peyton Jones at 2020-05-29T01:39:19-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. - - - - - c49f7df0 by Simon Peyton Jones at 2020-05-29T01:39:19-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. - - - - - 46720997 by Ben Gamari at 2020-05-29T01:39:19-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 Metric Decrease: ManyConstructors Co-Authored-By: Simon Peyton-Jone <simonpj at microsoft.com> - - - - - 277c2f26 by Ben Gamari at 2020-05-29T01:39:55-04:00 Eta expand un-saturated primops Now since we no longer try to predict CAFfyness we have no need for the solution to #16846. Eta expanding unsaturated primop applications is conceptually simpler, especially in the presence of levity polymorphism. This essentially reverts cac8dc9f51e31e4c0a6cd9bc302f7e1bc7c03beb, as suggested in #18079. Closes #18079. - - - - - f44d7ae0 by Simon Jakobi at 2020-05-29T01:40:34-04:00 base: Scrap deprecation plan for Data.Monoid.{First,Last} See the discussion on the libraries mailing list for context: https://mail.haskell.org/pipermail/libraries/2020-April/030357.html - - - - - 8b494895 by Jeremy Schlatter at 2020-05-29T01:41:12-04:00 Fix typo in documentation - - - - - 998450f4 by Gleb Popov at 2020-05-29T01:41:53-04:00 Always define USE_PTHREAD_FOR_ITIMER for FreeBSD. - - - - - f9a513e0 by Alp Mestanogullari at 2020-05-29T01:42:36-04:00 hadrian: introduce 'install' target Its logic is very simple. It `need`s the `binary-dist-dir` target and runs suitable `configure` and `make install` commands for the user. A new `--prefix` command line argument is introduced to specify where GHC should be installed. - - - - - ed57b03a by Travis Whitaker at 2020-05-29T02:14:20-04:00 Build a threaded stage 1 if the bootstrapping GHC supports it. - - - - - 1532b5cf by Peter Trommler at 2020-05-29T02:14:21-04:00 PPC NCG: No per-symbol .section ".toc" directives All position independent symbols are collected during code generation and emitted in one go. Prepending each symbol with a .section ".toc" directive is redundant. This patch drops the per-symbol directives leading to smaller assembler files. Fixes #18250 - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Types/Id.hs - compiler/ghc.mk - configure.ac - docs/users_guide/using-concurrent.rst - ghc/ghc.mk - hadrian/README.md - hadrian/cfg/system.config.in - hadrian/src/CommandLine.hs - hadrian/src/Expression.hs - hadrian/src/Oracles/Flag.hs - hadrian/src/Rules/BinaryDist.hs - hadrian/src/Settings/Packages.hs - libraries/base/Data/Monoid.hs - libraries/base/GHC/Base.hs - libraries/base/GHC/List.hs - libraries/base/changelog.md - + libraries/base/tests/perf/Makefile The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/32d09881327fbf23433922902bcac845090aa3a4...1532b5cf64b99ffdef2730878a08a252ca12a76d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/32d09881327fbf23433922902bcac845090aa3a4...1532b5cf64b99ffdef2730878a08a252ca12a76d You're receiving 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 29 09:05:12 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Fri, 29 May 2020 05:05:12 -0400 Subject: [Git][ghc/ghc][wip/T18126-deep] Wibbles Message-ID: <5ed0d04888326_6e263f9f0cbba3d825516a5@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T18126-deep at Glasgow Haskell Compiler / GHC Commits: eae80258 by Simon Peyton Jones at 2020-05-29T10:03:40+01:00 Wibbles - - - - - 5 changed files: - compiler/GHC/Tc/Gen/App.hs - compiler/GHC/Tc/Gen/Expr.hs - compiler/GHC/Tc/Utils/Unify.hs - testsuite/tests/impredicative/icfp20-ok.hs - testsuite/tests/typecheck/should_fail/tcfail133.stderr Changes: ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -2,12 +2,11 @@ % (c) The University of Glasgow 2006 (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 - -} {-# LANGUAGE CPP, TupleSections, ScopedTypeVariables #-} {-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE TypeFamilies, DataKinds, TypeApplications #-} +{-# LANGUAGE TypeFamilies, DataKinds, GADTs, TypeApplications #-} {-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow] {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} @@ -25,8 +24,7 @@ module GHC.Tc.Gen.App , addExprCtxt ) where -import {-# SOURCE #-} GHC.Tc.Gen.Expr( tcExpr, tcCheckPolyExprNC - , tcInferRhoNC, tcExprWithSig ) +import {-# SOURCE #-} GHC.Tc.Gen.Expr( tcExpr, tcCheckPolyExprNC, tcExprWithSig ) import GHC.Hs import GHC.Tc.TyCl.PatSyn( patSynBuilderOcc ) @@ -155,9 +153,10 @@ data TcPass = TcpRn -- Arguments decomposed | TcpTc -- Typechecked data HsExprArg (p :: TcPass) - = EValArg SrcSpan -- Of the function - (EValArg p) - !(XEType p) + = EValArg { eva_loc :: SrcSpan -- Of the function + , eva_arg :: EValArg p + , eva_ty :: !(XEType p) + , eva_gd :: Bool } | ETypeArg SrcSpan -- Of the function (LHsWcType GhcRn) @@ -170,12 +169,18 @@ data HsExprArg (p :: TcPass) | EWrap !(XEWrap p) -- Wrapper, after instantiation -data EValArg (p :: TcPass) - = ValArg (LHsExpr (GhcPass (XPass p))) - | ValArgQL SrcSpan (HsExpr GhcTc) [HsExprArg p] TcRhoType Rebuilder +data EValArg (p :: TcPass) where + ValArg :: LHsExpr (GhcPass (XPass p)) -> EValArg p + ValArgQL :: { va_loc :: SrcSpan + , va_fun :: HsExpr GhcTc -- Function, typechecked + , va_args :: [HsExprArg 'TcpInst] -- Args, instantiated + , va_ty :: TcRhoType -- Result type + , va_rebuild :: Rebuilder } -- How to reassemble + -> EValArg 'TcpInst -- Only exists in TcpInst phase mkEValArg :: SrcSpan -> LHsExpr GhcRn -> HsExprArg 'TcpRn -mkEValArg l e = EValArg l (ValArg e) noExtField +mkEValArg l e = EValArg { eva_loc = l, eva_arg = ValArg e + , eva_ty = noExtField, eva_gd = False } type family XPass p where XPass 'TcpRn = 'Renamed @@ -191,7 +196,9 @@ type family XEWrap p where XEWrap _ = HsWrapper instance OutputableBndrId (XPass p) => Outputable (HsExprArg p) where - ppr (EValArg _ tm _) = text "EValArg" <+> ppr tm + ppr (EValArg { eva_arg = arg, eva_gd = gd }) + = text "EValArg" <> if gd then text "(gd)" else text "(un-gd)" + <+> ppr arg ppr (EPrag _ p) = text "EPrag" <+> ppr p ppr (ETypeArg _ hs_ty _) = char '@' <> ppr hs_ty ppr (EPar _) = text "EPar" @@ -200,13 +207,14 @@ instance OutputableBndrId (XPass p) => Outputable (HsExprArg p) where instance OutputableBndrId (XPass p) => Outputable (EValArg p) where ppr (ValArg e) = ppr e - ppr (ValArgQL _ fun args ty _) = hang (text "ValArgQL" <+> ppr fun) - 2 (vcat [ ppr args - , text "app_ty:" <+> ppr ty ]) + ppr (ValArgQL { va_fun = fun, va_args = args, va_ty = ty}) + = hang (text "ValArgQL" <+> ppr fun) + 2 (vcat [ ppr args, text "va_ty:" <+> ppr ty ]) pprHsExprArgTc :: HsExprArg 'TcpInst -> SDoc -pprHsExprArgTc (EValArg _ tm ty) = text "EValArg" <+> hang (ppr tm) 2 (dcolon <+> ppr ty) -pprHsExprArgTc arg = ppr arg +pprHsExprArgTc (EValArg { eva_arg = tm, eva_ty = ty }) + = text "EValArg" <+> hang (ppr tm) 2 (dcolon <+> ppr ty) +pprHsExprArgTc arg = ppr arg type family XExprTypeArg id where XExprTypeArg 'Parsed = NoExtField @@ -226,8 +234,9 @@ addArgWrap wrap args type Rebuilder = HsExpr GhcTc -> [HsExprArg 'TcpTc]-> HsExpr GhcTc zonkArg :: HsExprArg 'TcpInst -> TcM (HsExprArg 'TcpInst) -zonkArg (EValArg l tm ty) = do { ty <- zonkTcType ty - ; return (EValArg l tm ty) } +zonkArg eva@(EValArg { eva_ty = ty }) + = do { ty' <- zonkTcType ty + ; return (eva { eva_ty = ty' }) } zonkArg arg = return arg splitHsApps :: HsExpr GhcRn -> (HsExpr GhcRn, [HsExprArg 'TcpRn], Rebuilder) @@ -249,7 +258,8 @@ rebuildInfixApps :: Fixity -> Rebuilder rebuildInfixApps fix fun args = go fun args where - go fun (EValArg l (ValArg arg1) _ : EValArg _ (ValArg arg2) _ : args) + go fun (EValArg { eva_arg = ValArg arg1, eva_loc = l } : + EValArg { eva_arg = ValArg arg2 } : args) = rebuildPrefixApps (OpApp fix arg1 (L l fun) arg2) args go fun (EWrap wrap : args) = go (mkHsWrap wrap fun) args go fun args = rebuildPrefixApps fun args @@ -260,7 +270,8 @@ rebuildPrefixApps fun args where go fun [] = fun go fun (EWrap wrap : args) = go (mkHsWrap wrap fun) args - go fun (EValArg l (ValArg arg) _ : args) = go (HsApp noExtField (L l fun) arg) args + go fun (EValArg { eva_loc = l, + eva_arg = ValArg arg } : args) = go (HsApp noExtField (L l fun) arg) args go fun (ETypeArg l hs_ty ty : args) = go (HsAppType ty (L l fun) hs_ty) args go fun (EPar l : args) = go (HsPar noExtField (L l fun)) args go fun (EPrag l p : args) = go (HsPragE noExtField p (L l fun)) args @@ -278,13 +289,18 @@ isArgPar :: HsExprArg id -> Bool isArgPar (EPar {}) = True isArgPar _ = False -getFunLoc :: [HsExprArg 'TcpRn] -> Maybe SrcSpan -getFunLoc [] = Nothing -getFunLoc (a:_) = Just $ case a of - EValArg l _ _ -> l - ETypeArg l _ _ -> l - EPrag l _ -> l - EPar l -> l +setSrcSpanFromArgs :: [HsExprArg 'TcpRn] -> TcM a -> TcM a +setSrcSpanFromArgs [] thing_inside + = thing_inside -- Don't set the location twice +setSrcSpanFromArgs (arg:_) thing_inside + = setSrcSpan (argFunLoc arg) thing_inside + +argFunLoc :: HsExprArg 'TcpRn -> SrcSpan +argFunLoc (EValArg { eva_loc = l }) = l +argFunLoc (ETypeArg l _ _) = l +argFunLoc (EPrag l _) = l +argFunLoc (EPar l) = l + {- ********************************************************************* * * @@ -297,33 +313,23 @@ tcInferSigmaTy :: LHsExpr GhcRn -> TcM TcSigmaType tcInferSigmaTy (L loc rn_expr) | (rn_fun, rn_args, _) <- splitHsApps rn_expr = setSrcSpan loc $ - do { (tc_fun, fun_sigma) <- tcInferAppHead rn_fun rn_args - ; impred <- xoptM LangExt.ImpredicativeTypes - ; (_delta, inst_args, app_res_sigma) <- tcInstFun impred False rn_fun fun_sigma rn_args - ; _tc_args <- tcArgs impred tc_fun inst_args + do { impred <- xoptM LangExt.ImpredicativeTypes + ; (tc_fun, fun_sigma) <- tcInferAppHead rn_fun rn_args + ; let rn_args' = maybeAddGuardFlags impred fun_sigma rn_args + ; (_delta, inst_args, app_res_sigma) <- tcInstFun impred False rn_fun fun_sigma rn_args' + ; _tc_args <- tcValArgs impred tc_fun inst_args ; return app_res_sigma } -tcApp, tcApp1 :: HsExpr GhcRn -> ExpRhoType -> TcM (HsExpr GhcTc) -tcApp expr@(OpApp _ _ op _) res_ty - | (L _ (HsVar _ (L _ op_name))) <- op - , op_name `hasKey` dollarIdKey -- Note [Typing rule for ($)] - = do { impred <- xoptM LangExt.ImpredicativeTypes - - -- Use old ($) rule if ImpredicativeTypes is off - ; if not impred then oldTcDollar expr res_ty - else tcApp1 expr res_ty } - -tcApp expr res_ty = tcApp1 expr res_ty - --------------------- -tcApp1 rn_expr exp_res_ty +tcApp :: HsExpr GhcRn -> ExpRhoType -> TcM (HsExpr GhcTc) +tcApp rn_expr exp_res_ty | (rn_fun, rn_args, rebuild) <- splitHsApps rn_expr = do { impred <- impred_call rn_fun ; (tc_fun, fun_sigma) <- tcInferAppHead rn_fun rn_args -- Instantiate - ; (delta, inst_args, app_res_rho) <- tcInstFun impred True rn_fun fun_sigma rn_args + ; let rn_args' = maybeAddGuardFlags impred fun_sigma rn_args + ; (delta, inst_args, app_res_rho) <- tcInstFun impred True rn_fun fun_sigma rn_args' -- Quick look at result ; when (impred && not (isEmptyVarSet delta)) $ @@ -342,7 +348,7 @@ tcApp1 rn_expr exp_res_ty , text "rn_expr:" <+> ppr rn_expr ]) -- Typecheck the value arguments separately - ; tc_args <- tcArgs impred tc_fun inst_args + ; tc_args <- tcValArgs impred tc_fun inst_args -- Special case for tagToEnum# ; if isTagToEnum rn_fun @@ -384,17 +390,12 @@ tcInferAppHead :: HsExpr GhcRn -- -- See Note [Typechecking applications] tcInferAppHead fun args - = set_fun_loc args $ + = setSrcSpanFromArgs args $ do { mb_tc_fun <- tcInferAppHead_maybe fun args ; case mb_tc_fun of Just (fun', fun_sigma) -> return (fun', fun_sigma) Nothing -> addErrCtxt (exprCtxt fun) $ tcInfer (tcExpr fun) } - where - set_fun_loc args thing_inside - = case getFunLoc args of - Nothing -> thing_inside -- Don't set the location twice - Just loc -> setSrcSpan loc thing_inside tcInferAppHead_maybe :: HsExpr GhcRn -> [HsExprArg 'TcpRn] @@ -413,7 +414,7 @@ tcInferAppHead_maybe fun args -- Disgusting special case for ambiguous record selectors go_rec_fld (Ambiguous _ lbl) | arg1 : _ <- filterOut isArgPar args -- A value arg is first - , EValArg _ (ValArg (L _ arg)) _ <- arg1 + , EValArg { eva_arg = ValArg (L _ arg) } <- arg1 , 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 @@ -423,11 +424,11 @@ tcInferAppHead_maybe fun args ---------------- -tcArgs :: Bool -- Quick-look on? - -> HsExpr GhcTc -- The function (for error messages) - -> [HsExprArg 'TcpInst] -- Actual argument - -> TcM [HsExprArg 'TcpTc] -- Resulting argument -tcArgs quick_look fun args +tcValArgs :: Bool -- Quick-look on? + -> HsExpr GhcTc -- The function (for error messages) + -> [HsExprArg 'TcpInst] -- Actual argument + -> TcM [HsExprArg 'TcpTc] -- Resulting argument +tcValArgs quick_look fun args = go 1 args where go _ [] = return [] @@ -441,7 +442,7 @@ tcArgs quick_look fun args tc_arg n (EWrap wrap) = return (n, EWrap wrap) tc_arg n (ETypeArg l hs_ty ty) = return (n+1, ETypeArg l hs_ty ty) - tc_arg n (EValArg l arg arg_ty) + tc_arg n eva@(EValArg { eva_arg = arg, eva_ty = arg_ty }) = do { -- Crucial step: expose QL results before checking arg_ty arg_ty <- if quick_look then zonkTcType arg_ty else return arg_ty @@ -450,18 +451,20 @@ tcArgs quick_look fun args ; arg' <- addErrCtxt (funAppCtxt fun arg n) $ tcEValArg arg arg_ty - ; return (n+1, EValArg l (ValArg arg') arg_ty) } + ; return (n+1, eva { eva_arg = ValArg arg', eva_ty = arg_ty }) } tcEValArg :: EValArg 'TcpInst -> TcSigmaType -> TcM (LHsExpr GhcTc) -- Typecheck one value argument of a function call tcEValArg (ValArg arg) exp_arg_sigma = tcCheckPolyExprNC arg exp_arg_sigma -tcEValArg (ValArgQL loc fun args app_res_rho rebuild) exp_arg_sigma - = do { tc_args <- tcArgs True fun args - ; (wrap, co) <- tcSkolemise GenSigCtxt exp_arg_sigma $ \ exp_arg_rho -> - unifyType Nothing app_res_rho exp_arg_rho - ; return (L loc $ mkHsWrap wrap $ mkHsWrapCo co $ rebuild fun tc_args) } +tcEValArg (ValArgQL { va_loc = loc, va_fun = fun, va_args = args + , va_ty = app_res_rho, va_rebuild = rebuild }) exp_arg_sigma + = do { traceTc "tcEValArg {" (vcat [ ppr fun <+> ppr args ]) + ; tc_args <- tcValArgs True fun args + ; co <- unifyType Nothing app_res_rho exp_arg_sigma + ; traceTc "tcEValArg }" empty + ; return (L loc $ mkHsWrapCo co $ rebuild fun tc_args) } tcValArg :: HsExpr GhcRn -- The function (for error messages) -> LHsExpr GhcRn -- Actual argument @@ -477,65 +480,6 @@ tcValArg fun arg arg_ty arg_no ; tcCheckPolyExprNC arg arg_ty } -{- ********************************************************************* -* * - Old typechecking for ($) -* * -********************************************************************* -} - --- This oldTcDollar nonsense is a HORRIBLE HACK to keep --- us going for now. For some reason, Quick Look doesn't --- yet give the same answers, sadly -oldTcDollar :: HsExpr GhcRn -> ExpRhoType -> TcM (HsExpr GhcTc) -oldTcDollar expr@(OpApp fix arg1 op arg2) res_ty - | (L loc nl_op@(HsVar _ (L lv op_name))) <- op - = do { - traceTc "Application rule" (ppr op) - ; (arg1', arg1_ty) <- addErrCtxt (funAppCtxt op arg1 1) $ - tcInferRhoNC arg1 - - ; let doc = text "The first argument of ($) takes" - orig1 = lexprCtOrigin arg1 - ; (wrap_arg1, [arg2_sigma], op_res_ty) <- - matchActualFunTysRho doc orig1 (Just (unLoc arg1)) 1 arg1_ty - - -- We have (arg1 $ arg2) - -- So: arg1_ty = arg2_ty -> op_res_ty - -- where arg2_sigma maybe polymorphic; that's the point - - ; arg2' <- tcValArg nl_op arg2 arg2_sigma 2 - - -- Make sure that the argument type has kind '*' - -- ($) :: forall (r:RuntimeRep) (a:*) (b:TYPE r). (a->b) -> a -> b - -- Eg we do not want to allow (D# $ 4.0#) #5570 - -- (which gives a seg fault) - ; _ <- unifyKind (Just (XHsType $ NHsCoreTy arg2_sigma)) - (tcTypeKind arg2_sigma) liftedTypeKind - -- Ignore the evidence. arg2_sigma must have type * or #, - -- because we know (arg2_sigma -> op_res_ty) is well-kinded - -- (because otherwise matchActualFunTysRho would fail) - -- So this 'unifyKind' will either succeed with Refl, or will - -- produce an insoluble constraint * ~ #, which we'll report later. - - -- NB: unlike the argument type, the *result* type, op_res_ty can - -- have any kind (#8739), so we don't need to check anything for that - - ; op_id <- tcLookupId op_name - ; let op' = L loc (mkHsWrap (mkWpTyApps [ getRuntimeRep op_res_ty - , arg2_sigma - , op_res_ty]) - (HsVar noExtField (L lv op_id))) - -- arg1' :: arg1_ty - -- wrap_arg1 :: arg1_ty "->" (arg2_sigma -> op_res_ty) - -- op' :: (a2_ty -> op_res_ty) -> a2_ty -> op_res_ty - - expr' = OpApp fix (mkLHsWrap wrap_arg1 arg1') op' arg2' - - ; tcWrapResult expr expr' op_res_ty res_ty } - -oldTcDollar expr _ = pprPanic "oldTcDollar" (ppr expr) - - {- ********************************************************************* * * Instantiating the call @@ -550,8 +494,11 @@ tcInstFun :: Bool -- True <=> ImpredicativeTypes is on; do quick-look , [HsExprArg 'TcpInst] , TcSigmaType ) tcInstFun impred_on inst_final rn_fun fun_sigma rn_args - = traceTc "tcInstFun" (ppr rn_fun $$ ppr rn_args) >> - go emptyVarSet [] [] fun_sigma rn_args + = setSrcSpanFromArgs rn_args $ + -- Setting the location is important for the class constraints + -- that may be emitted from instantiating fun_sigma + do { traceTc "tcInstFun" (ppr rn_fun $$ ppr rn_args) + ; go emptyVarSet [] [] fun_sigma rn_args } where fun_orig = exprCtOrigin rn_fun herald = sep [ text "The function" <+> quotes (ppr rn_fun) @@ -645,136 +592,16 @@ tcInstFun impred_on inst_final rn_fun fun_sigma rn_args ; writeMetaTyVar kappa (mkCastTy fun_ty' kind_co) ; go delta' acc' so_far fun_ty' args } - go1 delta acc so_far fun_ty (EValArg loc arg _ : rest_args) + go1 delta acc so_far fun_ty + (eva@(EValArg { eva_arg = arg, eva_gd = guarded }) : rest_args) = do { (wrap, arg_ty, res_ty) <- matchActualFunTy herald (Just rn_fun) (n_val_args, so_far) fun_ty - ; (delta', val_arg) <- quickLookArg impred_on delta arg arg_ty - ; let acc' = EValArg loc val_arg arg_ty : addArgWrap wrap acc + ; (delta', val_arg) <- quickLookArg impred_on guarded delta arg arg_ty + ; let acc' = eva { eva_arg = val_arg, eva_ty = arg_ty } + : addArgWrap wrap acc ; go delta' acc' (arg_ty:so_far) res_ty rest_args } -{- -tcInstFunNoEv :: HsExpr GhcRn -> TcSigmaType -> [HsExprArg 'TcpRn] - -> TcM (Maybe (Delta, TcSigmaType)) --- This is a version of tcInstFun, but specialised for the call --- in quickLookArg. In particular --- * No evidence generation; see Note [No evidence in quick look] --- * No instantiated arguments returned; all that matters --- is the result type (and the Delta set) -tcInstFunNoEv rn_fun fun_sigma rn_args - = traceTc "tcInstFunNoEv" (ppr rn_fun $$ ppr rn_args) >> - go emptyVarSet fun_sigma rn_args - where - -- go: If fun_ty=kappa, look it up in Theta - go delta fun_ty args - | Just kappa <- tcGetTyVar_maybe fun_ty - , kappa `elemVarSet` delta - = do { cts <- readMetaTyVar kappa - ; case cts of - Indirect fun_ty' -> go delta fun_ty' args - Flexi -> go1 delta fun_ty args } - | otherwise - = go1 delta fun_ty args - - go1 :: Delta -> TcSigmaType -> [HsExprArg 'TcpRn] - -> TcM (Maybe (Delta, TcRhoType)) - - go1 delta fun_ty [] = return (Just (delta, fun_ty)) - go1 delta fun_ty (EPar {} : args) = go1 delta fun_ty args - go1 delta fun_ty (EPrag {} : args) = go1 delta fun_ty args - - go1 delta fun_ty args@(ETypeArg {} : _) - | (tvbs, body1) <- tcSplitSomeForAllTys (== Inferred) fun_ty - , (theta, body2) <- tcSplitPhiTy body1 - , not (null tvbs && null theta) - , let tvs = map binderVar tvbs - = do { (delta', fun_rho) <- qlInstTyNoEv delta tvs body2 - ; go1 delta' fun_rho args } - - go1 delta fun_ty (ETypeArg _ hs_ty_arg _ : args) - = do { (_ty_arg, inst_ty) <- tcVTA fun_ty hs_ty_arg - ; go delta inst_ty args } - - go1 delta fun_ty args@(EValArg {} : _) - | (tvs, theta, body) <- tcSplitSigmaTy fun_ty - , not (null tvs && null theta) - = do { (delta', fun_rho) <- qlInstTyNoEv delta tvs body - ; go1 delta' fun_rho args } - - go1 delta fun_ty (EValArg _ arg _ : args) - | Just (arg_ty, res_ty) <- tcSplitFunTy_maybe fun_ty - = do { delta' <- quickLookArg True delta arg arg_ty - ; go delta' res_ty args } - - | otherwise - = return Nothing - -qlTopInstantiate :: HsExpr GhcRn -> TcSigmaType - -> TcM ( Delta -- Instantiation variables - , HsWrapper - , TcRhoType) -- No top level forall or (=>) --- Just like topInstantiate, but also returns the instantiation variables -qlTopInstantiate rn_fun ty - = go ty - where - fun_orig = exprCtOrigin rn_fun - go ty | (tvs, theta, body) <- tcSplitSigmaTy ty - , not (null tvs && null theta) - = do { (tvs1, wrap1, body1) <- instantiateSigma fun_orig tvs theta body - ; (tvs2, wrap2, rho) <- go body1 - ; return ( mkVarSet tvs1 `unionVarSet` tvs2 - , wrap2 <.> wrap1, rho) } - - | otherwise = return (emptyVarSet, idHsWrapper, ty) - -qlTopInstantiateNoEv :: TcSigmaType -> TcM ( Delta, TcRhoType) --- Just like qlTopInstantiate but without evidence -qlTopInstantiateNoEv ty - = go emptyVarSet ty - where - go delta ty | (tvs, theta, body) <- tcSplitSigmaTy ty - , not (null tvs && null theta) - = do { (delta1, body1) <- qlInstTyNoEv delta tvs body - ; (delta2, rho) <- go delta1 body1 - ; return ( delta2, rho) } - | otherwise = return (delta, ty) - -qlInstTyNoEv :: Delta -> [TyVar] -> TcSigmaType -> TcM (Delta, TcSigmaType) --- Instantiates just the type variables of a polymorphic type, --- and substitutes in the body -qlInstTyNoEv delta tvs body_ty - = do { (subst, inst_tvs) <- mapAccumLM newMetaTyVarX empty_subst tvs - ; return (delta `extendVarSetList` inst_tvs, substTy subst body_ty) } - where - free_tvs = tyCoVarsOfType body_ty - in_scope = mkInScopeSet (free_tvs `delVarSetList` tvs) - empty_subst = mkEmptyTCvSubst in_scope --} -{- Note [No evidence in quick look] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Supose we are quick-looking a call (f (g x)). Then we will do -quickLookArg on the argument (g x). When instantiating - g :: Eq a => a -> a -in quickLookArg, we don't want to spit out a class constraint for -(Eq kappa) into the monad -- it is a total waste, and duplicates what we -will later do during the "real" typechecking of this argument. - -You might think that: - -* Duplicate constraints do no harm except efficiency. But they do, - because they must be solved from Givens, and the type variables - in quick look may be different to those in the "rea" typecheck. - -* we could generate those constraints, but then discard them -- - inefficient, but correct. But alas we do generate some useful and - important kind-equality constraints, and it's not clear how to - separate the important from useless ones. - -So instead we bite the bullet, and have "NoEv" versions of some - * tcInstFunNoEv - * qlTopInstantiateNoEv - * qlInstTyNoEv --} {- ********************************************************************* * * @@ -854,7 +681,7 @@ 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 +Fortunately in tcValArgs 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 Hole constraint; @@ -899,6 +726,67 @@ and we had the visible type application -} +{- ********************************************************************* +* * + Guardedness +* * +********************************************************************* -} + +maybeAddGuardFlags :: Bool -> TcSigmaType -> [HsExprArg 'TcpRn] + -> [HsExprArg 'TcpRn] +maybeAddGuardFlags impred fun_ty args + | impred = snd (addGuardFlags fun_ty args) + | otherwise = args -- No Quick Look, no need to add guardedness + +addGuardFlags :: TcSigmaType -> [HsExprArg 'TcpRn] + -> (Bool, [HsExprArg 'TcpRn]) + -- True <=> there are no free quantified variables + -- in the result of the call +addGuardFlags fun_ty args + = go emptyVarSet [] fun_ty args + where + need_instantiation [] = True + need_instantiation (EValArg {} : _) = True + need_instantiation _ = False + + go bvs acc fun_ty args + | need_instantiation args + , (tvs, theta, rho) <- tcSplitSigmaTy fun_ty + , not (null tvs && null theta) + = go (bvs `extendVarSetList` tvs) acc rho args + + go bvs acc fun_ty [] + = ( tyCoVarsOfType fun_ty `disjointVarSet` bvs + , reverse acc) + + go bvs acc fun_ty (arg@(EPar {}) : args) = go bvs (arg : acc) fun_ty args + go bvs acc fun_ty (arg@(EPrag {}) : args) = go bvs (arg : acc) fun_ty args + + go bvs acc fun_ty args@(arg@(ETypeArg {}) : rest_args) + | (tvbs, body1) <- tcSplitSomeForAllTys (== Inferred) fun_ty + , (theta, body2) <- tcSplitPhiTy body1 + , not (null tvbs && null theta) + = go (bvs `extendVarSetList` binderVars tvbs) acc body2 args + | Just (_tv, res_ty) <- tcSplitForAllTy_maybe fun_ty + = go bvs (arg:acc) res_ty rest_args + + go bvs acc fun_ty (arg@(EValArg {}) : rest_args) + | Just (arg_ty, res_ty) <- tcSplitFunTy_maybe fun_ty + = go bvs (arg { eva_gd = isGuardedTy arg_ty } : acc) + res_ty rest_args + + go _ acc _ args = bale_out acc args + + bale_out acc [] = (False, reverse acc) + bale_out acc (arg@(EValArg {}) : args) + = bale_out (arg { eva_gd = False } : acc) args + bale_out acc (arg:args) = bale_out (arg:acc) args + +isGuardedTy :: TcType -> Bool +isGuardedTy ty + | Just (tc,_) <- tcSplitTyConApp_maybe ty = isGenerativeTyCon tc Nominal + | Just {} <- tcSplitAppTy_maybe ty = True + | otherwise = False {- ********************************************************************* @@ -910,7 +798,7 @@ and we had the visible type application type Delta = TcTyVarSet -- Set of instantiation variables ---------------- -quickLookArg :: Bool -> Delta -> EValArg 'TcpRn -> TcSigmaType +quickLookArg :: Bool -> Bool -> Delta -> EValArg 'TcpRn -> TcSigmaType -> TcM (Delta, EValArg 'TcpInst) -- Special behaviour only for (f e1 .. en) -- Even narrower than tcInferAppHead! But plenty for now. @@ -919,72 +807,54 @@ quickLookArg :: Bool -> Delta -> EValArg 'TcpRn -> TcSigmaType -- with added instantiation variables from -- (a) the call itself -- (b) the arguments of the call -quickLookArg impred_on delta (ValArg larg@(L loc arg)) arg_ty - | not impred_on - = return no_ql_result - | isEmptyVarSet delta - = return no_ql_result +quickLookArg impred_on guarded delta (ValArg larg@(L loc arg)) arg_ty + | not impred_on = return no_ql_result + | isEmptyVarSet delta = return no_ql_result + | not (isRhoTy arg_ty) = return no_ql_result | otherwise - = do { let (rn_fun,rn_args,rebuild) = splitHsApps arg + = setSrcSpan loc $ + do { let (rn_fun,rn_args,rebuild) = splitHsApps arg ; mb_fun_ty <- tcInferAppHead_maybe rn_fun rn_args - ; traceTc "quickLookArg 1" $ (ppr rn_fun <+> ppr rn_args $$ ppr mb_fun_ty) + ; traceTc "quickLookArg 1" $ + vcat [ text "arg:" <+> ppr arg + , text "head:" <+> ppr rn_fun <+> dcolon <+> ppr mb_fun_ty + , text "args:" <+> ppr rn_args ] + ; case mb_fun_ty of { Nothing -> -- fun is too complicated return no_ql_result ; Just (fun', fun_sigma) -> - do { (delta1, inst_args, app_res_rho) <- tcInstFun impred_on True rn_fun fun_sigma rn_args + do { let (no_free_kappas, rn_args') = addGuardFlags fun_sigma rn_args + ; traceTc "quickLookArg 2" $ + vcat [ text "no_free_kappas:" <+> ppr no_free_kappas + , text "guarded:" <+> ppr guarded ] + ; if not (guarded || no_free_kappas) + then return no_ql_result + else + do { (delta_app, inst_args, app_res_rho) + <- tcInstFun True True rn_fun fun_sigma rn_args' ; traceTc "quickLookArg" $ - vcat [ text "delta:" <+> ppr delta - , text "delta1:" <+> ppr delta1 - , text "arg:" <+> ppr arg + vcat [ text "arg:" <+> ppr arg + , text "delta:" <+> ppr delta + , text "delta_app:" <+> ppr delta_app , text "arg_ty:" <+> ppr arg_ty - , text "app_res_rho:" <+> ppr app_res_rho - , text "guarded" <+> ppr (isRigidTy arg_ty) ] - - ; let delta' = delta `unionVarSet` delta1 + , text "app_res_rho:" <+> ppr app_res_rho ] - -- Test for guardedness, and if so, unify + -- Do quick-look unification -- NB: arg_ty may not be zonked, but that's ok - ; when (isEmptyVarSet delta1 || isRigidTy arg_ty) $ - qlUnify delta' arg_ty app_res_rho - - ; let ql_arg = ValArgQL loc fun' inst_args app_res_rho rebuild - ; return (delta', ql_arg) } } } - + ; let delta' = delta `unionVarSet` delta_app + ; qlUnify delta' arg_ty app_res_rho + + ; let ql_arg = ValArgQL { va_loc = loc, va_fun = fun' + , va_args = inst_args + , va_ty = app_res_rho + , va_rebuild = rebuild } + ; return (delta', ql_arg) } } } } where no_ql_result = (delta, ValArg larg) ----------------- -{- -quickLookFun :: HsExpr GhcRn -> TcM (Maybe TcSigmaType) --- An extremely cut-down form of tcInferId --- Returns only the type; and does none of the extra checks --- We could use tcInferId, except for performance; --- indeed tcLookupFunTy always return the second component --- of what tcInferId would return -quickLookFun (HsVar _ (L _ name)) - = do { thing <- tcLookup name - ; case thing of - ATcId { tct_id = id } -> return (Just (idType id)) - AGlobal (AnId id) -> return (Just (idType id)) - AGlobal (AConLike cl) -> case cl of - RealDataCon dc -> return (Just (dataConUserType dc)) - PatSynCon ps -> case patSynBuilderOcc ps of - Just (_, ty) -> return (Just ty) - Nothing -> return Nothing - - _ -> return Nothing } - -quickLookFun (ExprWithTySig _ _ hs_ty) - | isCompleteHsSig hs_ty - = do { sig_ty <- tcHsSigWcType ExprSigCtxt hs_ty - ; return (Just sig_ty) } - -quickLookFun _ = return Nothing --} - --------------------- qlUnify :: Delta -> TcType -> TcType -> TcM () qlUnify delta ty1 ty2 @@ -1068,8 +938,8 @@ qlUnify delta ty1 ty2 | kappa `elemVarSet` ty2_tvs = return () -- Occurs-check - | not (isAlmostFunctionFree ty2) - = return () -- Sigh. See Note [Quick Look at type families] +-- | not (isAlmostFunctionFree ty2) +-- = return () -- Sigh. See Note [Quick Look at type families] | otherwise = do { -- Unify the kinds; see Note [Kinds in QL unify] ===================================== compiler/GHC/Tc/Gen/Expr.hs ===================================== @@ -333,100 +333,10 @@ With PostfixOperators we don't actually require the function to take two arguments at all. For example, (x `not`) means (not x); you get postfix operators! Not Haskell 98, but it's less work and kind of useful. - -Note [Typing rule for ($)] -~~~~~~~~~~~~~~~~~~~~~~~~~~ -People write - runST $ blah -so much, where - runST :: (forall s. ST s a) -> a -that I have finally given in and written a special type-checking -rule just for saturated applications of ($). - * Infer the type of the first argument - * Decompose it; should be of form (arg2_ty -> res_ty), - where arg2_ty might be a polytype - * Use arg2_ty to typecheck arg2 -} tcExpr expr@(OpApp {}) res_ty = tcApp expr res_ty -{- -tcExpr expr@(OpApp fix arg1 op arg2) res_ty - | (L loc (HsVar _ (L lv op_name))) <- op - , op_name `hasKey` dollarIdKey -- Note [Typing rule for ($)] - = do { - traceTc "Application rule" (ppr op) - ; (arg1', arg1_ty) <- addErrCtxt (funAppCtxt op arg1 1) $ - tcInferRhoNC arg1 - - ; let doc = text "The first argument of ($) takes" - orig1 = lexprCtOrigin arg1 - ; (wrap_arg1, [arg2_sigma], op_res_ty) <- - matchActualFunTysRho doc orig1 (Just (unLoc arg1)) 1 arg1_ty - - -- We have (arg1 $ arg2) - -- So: arg1_ty = arg2_ty -> op_res_ty - -- where arg2_sigma maybe polymorphic; that's the point - - ; arg2' <- tcValArg nl_op arg2 arg2_sigma 2 - - -- Make sure that the argument type has kind '*' - -- ($) :: forall (r:RuntimeRep) (a:*) (b:TYPE r). (a->b) -> a -> b - -- Eg we do not want to allow (D# $ 4.0#) #5570 - -- (which gives a seg fault) - ; _ <- unifyKind (Just (XHsType $ NHsCoreTy arg2_sigma)) - (tcTypeKind arg2_sigma) liftedTypeKind - -- Ignore the evidence. arg2_sigma must have type * or #, - -- because we know (arg2_sigma -> op_res_ty) is well-kinded - -- (because otherwise matchActualFunTysRho would fail) - -- So this 'unifyKind' will either succeed with Refl, or will - -- produce an insoluble constraint * ~ #, which we'll report later. - - -- NB: unlike the argument type, the *result* type, op_res_ty can - -- have any kind (#8739), so we don't need to check anything for that - - ; op_id <- tcLookupId op_name - ; let op' = L loc (mkHsWrap (mkWpTyApps [ getRuntimeRep op_res_ty - , arg2_sigma - , op_res_ty]) - (HsVar noExtField (L lv op_id))) - -- arg1' :: arg1_ty - -- wrap_arg1 :: arg1_ty "->" (arg2_sigma -> op_res_ty) - -- op' :: (a2_ty -> op_res_ty) -> a2_ty -> op_res_ty - - expr' = OpApp fix (mkLHsWrap wrap_arg1 arg1') op' arg2' - - ; tcWrapResult expr expr' op_res_ty res_ty } - - | L loc (HsRecFld _ (Ambiguous _ lbl)) <- op - , Just sig_ty <- obviousSig (unLoc arg1) - -- See Note [Disambiguating record fields] - = do { sig_tc_ty <- tcHsSigWcType ExprSigCtxt sig_ty - ; sel_name <- disambiguateSelector lbl sig_tc_ty - ; let op' = L loc (HsRecFld noExtField (Unambiguous sel_name lbl)) - ; tcExpr (OpApp fix arg1 op' arg2) res_ty - } - - | otherwise - = do { traceTc "Non Application rule" (ppr op) - ; (op', op_ty) <- tcInferRhoNC op - - ; (wrap_fun, [arg1_ty, arg2_ty], op_res_ty) - <- matchActualFunTysRho (mk_op_msg op) fn_orig - (Just (unLoc op)) 2 op_ty - -- You might think we should use tcInferApp here, but there is - -- too much impedance-matching, because tcApp may return wrappers as - -- well as type-checked arguments. - - ; arg1' <- tcValArg nl_op arg1 arg1_ty 1 - ; arg2' <- tcValArg nl_op arg2 arg2_ty 2 - - ; let expr' = OpApp fix arg1' (mkLHsWrap wrap_fun op') arg2' - ; tcWrapResult expr expr' op_res_ty res_ty } - where - fn_orig = exprCtOrigin nl_op - nl_op = unLoc op --} -- Right sections, equivalent to \ x -> x `op` expr, or -- \ x -> op x expr ===================================== compiler/GHC/Tc/Utils/Unify.hs ===================================== @@ -14,7 +14,7 @@ module GHC.Tc.Utils.Unify ( -- Full-blown subsumption tcWrapResult, tcWrapResultO, tcWrapResultMono, - tcSkolemise, tcSkolemiseScoped, tcSkolemiseET, + tcSkolemise, tcSkolemiseScoped, tcSkolemiseAlways, tcSkolemiseET, tcSubType, tcSubTypeSigma, tcSubTypePat, checkConstraints, checkTvConstraints, buildImplicationFor, buildTvImplication, emitResidualTvConstraint, @@ -960,7 +960,7 @@ tcSkolemiseScoped is very similar, but differs in two ways: See Note [When to build an implication] below. -} -tcSkolemise, tcSkolemiseScoped +tcSkolemise, tcSkolemiseScoped, tcSkolemiseAlways :: UserTypeCtxt -> TcSigmaType -> (TcType -> TcM result) -> TcM (HsWrapper, result) @@ -983,6 +983,9 @@ tcSkolemise ctxt expected_ty thing_inside = do { res <- thing_inside expected_ty ; return (idHsWrapper, res) } | otherwise + = tcSkolemiseAlways ctxt expected_ty thing_inside + +tcSkolemiseAlways ctxt expected_ty thing_inside = do { (wrap, tv_prs, given, rho_ty) <- topSkolemise expected_ty ; let skol_tvs = map snd tv_prs @@ -1156,7 +1159,7 @@ take care: [W] C Int b2 -- from g_blan and fundpes can yield [D] b1 ~ b2, even though the two functions have literally nothing to do with each other. #14185 is an example. - Building an implication keeps them separage. + Building an implication keeps them separate. -} {- ===================================== testsuite/tests/impredicative/icfp20-ok.hs ===================================== @@ -69,3 +69,6 @@ d4 = runST $ argST st1 :: forall a. (forall s. ST s a) -> a st1 x = id (runST @a) x + +-- Not in the paper's table +c10 = head ids True ===================================== testsuite/tests/typecheck/should_fail/tcfail133.stderr ===================================== @@ -14,8 +14,7 @@ tcfail133.hs:68:7: error: ...plus 25 others ...plus 12 instances involving out-of-scope types (use -fprint-potential-instances to see them all) - • In the first argument of ‘($)’, namely ‘show’ - In the expression: show $ add (One :@ Zero) (One :@ One) + • In the expression: show $ add (One :@ Zero) (One :@ One) In an equation for ‘foo’: foo = show $ add (One :@ Zero) (One :@ One) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/eae80258c718ee303910818acf715e78a98a7f59 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/eae80258c718ee303910818acf715e78a98a7f59 You're receiving 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 29 14:06:52 2020 From: gitlab at gitlab.haskell.org (David Eichmann) Date: Fri, 29 May 2020 10:06:52 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/io_uring Message-ID: <5ed116fcee6eb_6e263f9ed7570e8025971bf@gitlab.haskell.org.mail> David Eichmann pushed new branch wip/io_uring at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/io_uring You're receiving 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 29 14:10:18 2020 From: gitlab at gitlab.haskell.org (David Eichmann) Date: Fri, 29 May 2020 10:10:18 -0400 Subject: [Git][ghc/ghc][wip/io_uring] Refactor Event Manager Backend to allow for arbitrty asynchronous IO Message-ID: <5ed117ca5a9fb_6e263f9f0bb937fc25988ad@gitlab.haskell.org.mail> David Eichmann pushed to branch wip/io_uring at Glasgow Haskell Compiler / GHC Commits: 576e092b by David Eichmann at 2020-05-29T15:09:48+01:00 Refactor Event Manager Backend to allow for arbitrty asynchronous IO - - - - - 5 changed files: - libraries/base/GHC/Event/EPoll.hsc - libraries/base/GHC/Event/Internal.hs - libraries/base/GHC/Event/Manager.hs - libraries/base/GHC/Event/Poll.hsc - libraries/base/GHC/Event/TimerManager.hs Changes: ===================================== libraries/base/GHC/Event/EPoll.hsc ===================================== @@ -71,7 +71,13 @@ new :: IO E.Backend new = do epfd <- epollCreate evts <- A.new 64 - let !be = E.backend poll modifyFd modifyFdOnce delete (EPoll epfd evts) + let !be = E.backend + poll + modifyFd + modifyFdOnce + (\_ _ -> Nothing) + delete + (EPoll epfd evts) return be delete :: EPoll -> IO () @@ -109,7 +115,7 @@ modifyFdOnce ep fd evt = -- events that are ready. poll :: EPoll -- ^ state -> Maybe Timeout -- ^ timeout in milliseconds - -> (Fd -> E.Event -> IO ()) -- ^ I/O callback + -> (E.IOResult -> IO ()) -- ^ I/O callback -> IO Int poll ep mtimeout f = do let events = epollEvents ep @@ -122,7 +128,7 @@ poll ep mtimeout f = do Nothing -> epollWaitNonBlock fd es cap when (n > 0) $ do - A.forM_ events $ \e -> f (eventFd e) (toEvent (eventTypes e)) + A.forM_ events $ \e -> f (E.IOResult_Event (eventFd e) (toEvent (eventTypes e))) cap <- A.capacity events when (cap == n) $ A.ensureCapacity events (2 * cap) return n ===================================== libraries/base/GHC/Event/Internal.hs ===================================== @@ -6,6 +6,8 @@ module GHC.Event.Internal -- * Event back end Backend , backend + , IOAction + , IOResult(..) , delete , poll , modifyFd @@ -38,6 +40,22 @@ import GHC.Num (Num(..)) import GHC.Show (Show(..)) import Data.Semigroup.Internal (stimesMonoid) + +data IOAction -- TODO add actions + -- IOAction_Read IOActionID ... + -- IOAction_Write IOActionID ... + -- ... + +data IOResult + -- | An event has occurred for a file handle. See IOAction_SetFdEvents and + -- IOAction_SetFdEventsOnce. + = IOResult_Event Fd Event + + -- IOResult_Read IOActionID ... + -- IOResult_Write IOActionID ... + -- ... + + -- | An I\/O event. newtype Event = Event Int deriving Eq -- ^ @since 4.4.0.0 @@ -161,10 +179,11 @@ data Backend = forall a. Backend { -- | Poll backend for new events. The provided callback is called -- once per file descriptor with new events. - , _bePoll :: a -- backend state - -> Maybe Timeout -- timeout in milliseconds ('Nothing' for non-blocking poll) - -> (Fd -> Event -> IO ()) -- I/O callback - -> IO Int + , _bePoll + :: a -- backend state + -> Maybe Timeout -- timeout in milliseconds ('Nothing' for non-blocking poll) + -> (IOResult -> IO ()) -- I/O callback + -> IO Int -- ???? negative is error, 0 is success but no IOResults found, positive is success with IO Results. ??? -- | Register, modify, or unregister interest in the given events -- on the given file descriptor. @@ -172,48 +191,60 @@ data Backend = forall a. Backend { -> Fd -- file descriptor -> Event -- old events to watch for ('mempty' for new) -> Event -- new events to watch for ('mempty' to delete) - -> IO Bool + -> IO Bool -- The Bool indicates True for success, + -- False for a known failure, else this may throw + -- with `throwErrno`. -- | Register interest in new events on a given file descriptor, set -- to be deactivated after the first event. , _beModifyFdOnce :: a -> Fd -- file descriptor -> Event -- new events to watch - -> IO Bool + -> IO Bool -- Bool indicates success (see _beModifyFd) + + -- | Perform some IO action (non-blocking). + , _beDoIOAction + :: a + -> IOAction -- action to perform + -> Maybe (IO Bool) -- Nothing if the io action is not supported, and + -- the caller should use Fd Events instead. Else + -- Just the action to do the (non-blocking) IO + -- action. Bool indicates success (see _beModifyFd). , _beDelete :: a -> IO () } -backend :: (a -> Maybe Timeout -> (Fd -> Event -> IO ()) -> IO Int) +backend :: (a -> Maybe Timeout -> (IOResult -> IO ()) -> IO Int) -> (a -> Fd -> Event -> Event -> IO Bool) -> (a -> Fd -> Event -> IO Bool) + -> (a -> IOAction -> Maybe (IO Bool)) -> (a -> IO ()) -> a -> Backend -backend bPoll bModifyFd bModifyFdOnce bDelete state = - Backend state bPoll bModifyFd bModifyFdOnce bDelete +backend bPoll bModifyFd bModifyFdOnce bDoIOAction bDelete state = + Backend state bPoll bModifyFd bModifyFdOnce bDoIOAction bDelete {-# INLINE backend #-} -poll :: Backend -> Maybe Timeout -> (Fd -> Event -> IO ()) -> IO Int -poll (Backend bState bPoll _ _ _) = bPoll bState +poll :: Backend -> Maybe Timeout -> (IOResult -> IO ()) -> IO Int +poll (Backend bState bPoll _ _ _ _) = bPoll bState {-# INLINE poll #-} -- | Returns 'True' if the modification succeeded. -- Returns 'False' if this backend does not support -- event notifications on this type of file. modifyFd :: Backend -> Fd -> Event -> Event -> IO Bool -modifyFd (Backend bState _ bModifyFd _ _) = bModifyFd bState +modifyFd (Backend bState _ bModifyFd _ _ _) = bModifyFd bState {-# INLINE modifyFd #-} -- | Returns 'True' if the modification succeeded. -- Returns 'False' if this backend does not support -- event notifications on this type of file. modifyFdOnce :: Backend -> Fd -> Event -> IO Bool -modifyFdOnce (Backend bState _ _ bModifyFdOnce _) = bModifyFdOnce bState +modifyFdOnce (Backend bState _ _ bModifyFdOnce _ _) = bModifyFdOnce bState {-# INLINE modifyFdOnce #-} delete :: Backend -> IO () -delete (Backend bState _ _ _ bDelete) = bDelete bState +delete (Backend bState _ _ _ _ bDelete) = bDelete bState {-# INLINE delete #-} -- | Throw an 'Prelude.IOError' corresponding to the current value of ===================================== libraries/base/GHC/Event/Manager.hs ===================================== @@ -293,12 +293,12 @@ step mgr at EventManager{..} = do state `seq` return state where waitForIO = do - n1 <- I.poll emBackend Nothing (onFdEvent mgr) + n1 <- I.poll emBackend Nothing (onIOResult mgr) when (n1 <= 0) $ do yield - n2 <- I.poll emBackend Nothing (onFdEvent mgr) + n2 <- I.poll emBackend Nothing (onIOResult mgr) when (n2 <= 0) $ do - _ <- I.poll emBackend (Just Forever) (onFdEvent mgr) + _ <- I.poll emBackend (Just Forever) (onIOResult mgr) return () ------------------------------------------------------------------------ @@ -444,6 +444,11 @@ closeFd_ mgr tbl fd = do ------------------------------------------------------------------------ -- Utilities +-- | Call the callbacks corresponding ot the given IOResult. +onIOResult :: EventManager -> I.IOResult -> IO () +onIOResult em ioResult = case ioResult of + I.IOResult_Event fd events -> onFdEvent em fd events + -- | Call the callbacks corresponding to the given file descriptor. onFdEvent :: EventManager -> Fd -> Event -> IO () onFdEvent mgr fd evs ===================================== libraries/base/GHC/Event/Poll.hsc ===================================== @@ -51,7 +51,7 @@ data Poll = Poll { } new :: IO E.Backend -new = E.backend poll modifyFd modifyFdOnce (\_ -> return ()) `liftM` +new = E.backend poll modifyFd modifyFdOnce (\_ _ -> Nothing) (\_ -> return ()) `liftM` liftM2 Poll (newMVar =<< A.empty) A.empty modifyFd :: Poll -> Fd -> E.Event -> E.Event -> IO Bool @@ -78,7 +78,7 @@ reworkFd p (PollFd fd npevt opevt) = do poll :: Poll -> Maybe E.Timeout - -> (Fd -> E.Event -> IO ()) + -> (E.IOResult -> IO ()) -> IO Int poll p mtout f = do let a = pollFd p @@ -95,7 +95,7 @@ poll p mtout f = do A.loop a 0 $ \i e -> do let r = pfdRevents e if r /= 0 - then do f (pfdFd e) (toEvent r) + then do f (E.IOResult_Event (pfdFd e) (toEvent r)) let i' = i + 1 return (i', i' == n) else return (i, True) ===================================== libraries/base/GHC/Event/TimerManager.hs ===================================== @@ -50,9 +50,8 @@ import GHC.Num (Num(..)) import GHC.Real (quot, fromIntegral) import GHC.Show (Show(..)) import GHC.Event.Control -import GHC.Event.Internal (Backend, Event, evtRead, Timeout(..)) +import GHC.Event.Internal (Backend, evtRead, Timeout(..)) import GHC.Event.Unique (Unique, UniqueSource, newSource, newUnique) -import System.Posix.Types (Fd) import qualified GHC.Event.Internal as I import qualified GHC.Event.PSQ as Q @@ -99,13 +98,15 @@ data TimerManager = TimerManager ------------------------------------------------------------------------ -- Creation -handleControlEvent :: TimerManager -> Fd -> Event -> IO () -handleControlEvent mgr fd _evt = do +handleControlEvent :: TimerManager -> I.IOResult -> IO () +handleControlEvent mgr (I.IOResult_Event fd _evt) = do msg <- readControlMessage (emControl mgr) fd case msg of CMsgWakeup -> return () CMsgDie -> writeIORef (emState mgr) Finished CMsgSignal fp s -> runHandlers fp s +-- TimerManager should only use the event api of the backend to wait on timers. +-- handleControlEvent _ _ = errorWithoutStackTrace "unexpected non-event IO result" newDefaultBackend :: IO Backend #if defined(HAVE_POLL) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/576e092b4a506a9b8bbc7702b03dbf80adb478fe -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/576e092b4a506a9b8bbc7702b03dbf80adb478fe You're receiving 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 29 14:19:03 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Fri, 29 May 2020 10:19:03 -0400 Subject: [Git][ghc/ghc][wip/T18126-deep] 2 commits: More wibbles to make ($) work Message-ID: <5ed119d74b543_6e26db7740826006c7@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T18126-deep at Glasgow Haskell Compiler / GHC Commits: 9d4776a5 by Simon Peyton Jones at 2020-05-29T14:54:27+01:00 More wibbles to make ($) work This all relates to 5.4 - - - - - 78b4c82c by Simon Peyton Jones at 2020-05-29T15:18:32+01:00 More wibbles - - - - - 3 changed files: - compiler/GHC/Tc/Gen/App.hs - testsuite/tests/impredicative/all.T - + testsuite/tests/impredicative/cabal-example.hs Changes: ===================================== compiler/GHC/Tc/Gen/App.hs ===================================== @@ -155,8 +155,7 @@ data TcPass = TcpRn -- Arguments decomposed data HsExprArg (p :: TcPass) = EValArg { eva_loc :: SrcSpan -- Of the function , eva_arg :: EValArg p - , eva_ty :: !(XEType p) - , eva_gd :: Bool } + , eva_ty :: !(XEType p) } | ETypeArg SrcSpan -- Of the function (LHsWcType GhcRn) @@ -180,7 +179,7 @@ data EValArg (p :: TcPass) where mkEValArg :: SrcSpan -> LHsExpr GhcRn -> HsExprArg 'TcpRn mkEValArg l e = EValArg { eva_loc = l, eva_arg = ValArg e - , eva_ty = noExtField, eva_gd = False } + , eva_ty = noExtField } type family XPass p where XPass 'TcpRn = 'Renamed @@ -196,9 +195,8 @@ type family XEWrap p where XEWrap _ = HsWrapper instance OutputableBndrId (XPass p) => Outputable (HsExprArg p) where - ppr (EValArg { eva_arg = arg, eva_gd = gd }) - = text "EValArg" <> if gd then text "(gd)" else text "(un-gd)" - <+> ppr arg + ppr (EValArg { eva_arg = arg }) + = text "EValArg" <+> ppr arg ppr (EPrag _ p) = text "EPrag" <+> ppr p ppr (ETypeArg _ hs_ty _) = char '@' <> ppr hs_ty ppr (EPar _) = text "EPar" @@ -315,8 +313,7 @@ tcInferSigmaTy (L loc rn_expr) = setSrcSpan loc $ do { impred <- xoptM LangExt.ImpredicativeTypes ; (tc_fun, fun_sigma) <- tcInferAppHead rn_fun rn_args - ; let rn_args' = maybeAddGuardFlags impred fun_sigma rn_args - ; (_delta, inst_args, app_res_sigma) <- tcInstFun impred False rn_fun fun_sigma rn_args' + ; (_delta, inst_args, app_res_sigma) <- tcInstFun impred False rn_fun fun_sigma rn_args ; _tc_args <- tcValArgs impred tc_fun inst_args ; return app_res_sigma } @@ -328,8 +325,7 @@ tcApp rn_expr exp_res_ty ; (tc_fun, fun_sigma) <- tcInferAppHead rn_fun rn_args -- Instantiate - ; let rn_args' = maybeAddGuardFlags impred fun_sigma rn_args - ; (delta, inst_args, app_res_rho) <- tcInstFun impred True rn_fun fun_sigma rn_args' + ; (delta, inst_args, app_res_rho) <- tcInstFun impred True rn_fun fun_sigma rn_args -- Quick look at result ; when (impred && not (isEmptyVarSet delta)) $ @@ -593,11 +589,13 @@ tcInstFun impred_on inst_final rn_fun fun_sigma rn_args ; go delta' acc' so_far fun_ty' args } go1 delta acc so_far fun_ty - (eva@(EValArg { eva_arg = arg, eva_gd = guarded }) : rest_args) + (eva@(EValArg { eva_arg = ValArg arg }) : rest_args) = do { (wrap, arg_ty, res_ty) <- matchActualFunTy herald (Just rn_fun) (n_val_args, so_far) fun_ty - ; (delta', val_arg) <- quickLookArg impred_on guarded delta arg arg_ty - ; let acc' = eva { eva_arg = val_arg, eva_ty = arg_ty } + ; (delta', arg') <- if impred_on + then quickLookArg delta arg arg_ty + else return (delta, ValArg arg) + ; let acc' = eva { eva_arg = arg', eva_ty = arg_ty } : addArgWrap wrap acc ; go delta' acc' (arg_ty:so_far) res_ty rest_args } @@ -732,61 +730,41 @@ and we had the visible type application * * ********************************************************************* -} -maybeAddGuardFlags :: Bool -> TcSigmaType -> [HsExprArg 'TcpRn] - -> [HsExprArg 'TcpRn] -maybeAddGuardFlags impred fun_ty args - | impred = snd (addGuardFlags fun_ty args) - | otherwise = args -- No Quick Look, no need to add guardedness - -addGuardFlags :: TcSigmaType -> [HsExprArg 'TcpRn] - -> (Bool, [HsExprArg 'TcpRn]) - -- True <=> there are no free quantified variables - -- in the result of the call -addGuardFlags fun_ty args - = go emptyVarSet [] fun_ty args +findNoKappa :: TcSigmaType -> [HsExprArg 'TcpRn] -> Bool + -- True <=> there are no free quantified variables + -- in the result of the call +findNoKappa fun_ty args + = go emptyVarSet fun_ty args where need_instantiation [] = True need_instantiation (EValArg {} : _) = True need_instantiation _ = False - go bvs acc fun_ty args + go bvs fun_ty args | need_instantiation args , (tvs, theta, rho) <- tcSplitSigmaTy fun_ty , not (null tvs && null theta) - = go (bvs `extendVarSetList` tvs) acc rho args + = go (bvs `extendVarSetList` tvs) rho args - go bvs acc fun_ty [] - = ( tyCoVarsOfType fun_ty `disjointVarSet` bvs - , reverse acc) + go bvs fun_ty [] = tyCoVarsOfType fun_ty `disjointVarSet` bvs - go bvs acc fun_ty (arg@(EPar {}) : args) = go bvs (arg : acc) fun_ty args - go bvs acc fun_ty (arg@(EPrag {}) : args) = go bvs (arg : acc) fun_ty args + go bvs fun_ty (EPar {} : args) = go bvs fun_ty args + go bvs fun_ty (EPrag {} : args) = go bvs fun_ty args - go bvs acc fun_ty args@(arg@(ETypeArg {}) : rest_args) + go bvs fun_ty args@(ETypeArg {} : rest_args) | (tvbs, body1) <- tcSplitSomeForAllTys (== Inferred) fun_ty , (theta, body2) <- tcSplitPhiTy body1 , not (null tvbs && null theta) - = go (bvs `extendVarSetList` binderVars tvbs) acc body2 args + = go (bvs `extendVarSetList` binderVars tvbs) body2 args | Just (_tv, res_ty) <- tcSplitForAllTy_maybe fun_ty - = go bvs (arg:acc) res_ty rest_args + = go bvs res_ty rest_args - go bvs acc fun_ty (arg@(EValArg {}) : rest_args) - | Just (arg_ty, res_ty) <- tcSplitFunTy_maybe fun_ty - = go bvs (arg { eva_gd = isGuardedTy arg_ty } : acc) - res_ty rest_args + go bvs fun_ty (EValArg {} : rest_args) + | Just (_, res_ty) <- tcSplitFunTy_maybe fun_ty + = go bvs res_ty rest_args - go _ acc _ args = bale_out acc args + go _ _ _ = False - bale_out acc [] = (False, reverse acc) - bale_out acc (arg@(EValArg {}) : args) - = bale_out (arg { eva_gd = False } : acc) args - bale_out acc (arg:args) = bale_out (arg:acc) args - -isGuardedTy :: TcType -> Bool -isGuardedTy ty - | Just (tc,_) <- tcSplitTyConApp_maybe ty = isGenerativeTyCon tc Nominal - | Just {} <- tcSplitAppTy_maybe ty = True - | otherwise = False {- ********************************************************************* @@ -798,20 +776,45 @@ isGuardedTy ty type Delta = TcTyVarSet -- Set of instantiation variables ---------------- -quickLookArg :: Bool -> Bool -> Delta -> EValArg 'TcpRn -> TcSigmaType +quickLookArg :: Delta -> LHsExpr GhcRn -> TcSigmaType -> TcM (Delta, EValArg 'TcpInst) -- Special behaviour only for (f e1 .. en) --- Even narrower than tcInferAppHead! But plenty for now. -- -- The returned Delta is a superset of the one passed in -- with added instantiation variables from -- (a) the call itself -- (b) the arguments of the call -quickLookArg impred_on guarded delta (ValArg larg@(L loc arg)) arg_ty - | not impred_on = return no_ql_result +quickLookArg delta arg arg_ty | isEmptyVarSet delta = return no_ql_result - | not (isRhoTy arg_ty) = return no_ql_result - | otherwise + | otherwise = go arg_ty + where + no_ql_result = (delta, ValArg arg) + guarded = isGuardedTy arg_ty + -- NB: guardedness is computed based on the original, + -- unzonked arg_ty, so we deliberately do not exploit + -- guardedness that emerges a result of QL on earlier args + + go arg_ty | not (isRhoTy arg_ty) + = return no_ql_result + + | Just kappa <- tcGetTyVar_maybe arg_ty + , kappa `elemVarSet` delta + = do { info <- readMetaTyVar kappa + ; case info of + Indirect arg_ty' -> go arg_ty' + Flexi -> quickLookArg1 guarded delta arg arg_ty } + | otherwise + = quickLookArg1 guarded delta arg arg_ty + +isGuardedTy :: TcType -> Bool +isGuardedTy ty + | Just (tc,_) <- tcSplitTyConApp_maybe ty = isGenerativeTyCon tc Nominal + | Just {} <- tcSplitAppTy_maybe ty = True + | otherwise = False + +quickLookArg1 :: Bool -> Delta -> LHsExpr GhcRn -> TcSigmaType + -> TcM (Delta, EValArg 'TcpInst) +quickLookArg1 guarded delta larg@(L loc arg) arg_ty = setSrcSpan loc $ do { let (rn_fun,rn_args,rebuild) = splitHsApps arg ; mb_fun_ty <- tcInferAppHead_maybe rn_fun rn_args @@ -825,7 +828,7 @@ quickLookArg impred_on guarded delta (ValArg larg@(L loc arg)) arg_ty return no_ql_result ; Just (fun', fun_sigma) -> - do { let (no_free_kappas, rn_args') = addGuardFlags fun_sigma rn_args + do { let no_free_kappas = findNoKappa fun_sigma rn_args ; traceTc "quickLookArg 2" $ vcat [ text "no_free_kappas:" <+> ppr no_free_kappas , text "guarded:" <+> ppr guarded ] @@ -833,7 +836,7 @@ quickLookArg impred_on guarded delta (ValArg larg@(L loc arg)) arg_ty then return no_ql_result else do { (delta_app, inst_args, app_res_rho) - <- tcInstFun True True rn_fun fun_sigma rn_args' + <- tcInstFun True True rn_fun fun_sigma rn_args ; traceTc "quickLookArg" $ vcat [ text "arg:" <+> ppr arg , text "delta:" <+> ppr delta ===================================== testsuite/tests/impredicative/all.T ===================================== @@ -10,7 +10,8 @@ test('Church1', normal, compile, ['']) test('boxy', normal, compile, ['']) test('Compose', normal, compile, ['']) test('T2193', normal, compile_and_run, ['']) -test('icfp20-ok', normal, compile, ['']) -test('icfp20-fail', normal, compile_fail, ['']) -test('T18126-1', normal, compile, ['']) -test('T18126-nasty', normal, compile, ['']) +test('icfp20-ok', normal, compile, ['']) +test('icfp20-fail', normal, compile_fail, ['']) +test('T18126-1', normal, compile, ['']) +test('T18126-nasty', normal, compile, ['']) +test('cabal-example', normal, compile, ['']) ===================================== testsuite/tests/impredicative/cabal-example.hs ===================================== @@ -0,0 +1,47 @@ +{- This example illustrates a nasty case of "vacuous" abstraction + It comes from Cabal library Distribution.Simple.Utils + +Consider this + + type HCS = (?callStack :: CallStack) + wcs :: forall a. (HCS => a) -> a + foo :: Int + ($) :: forall p q. (p->q) -> p -> q + +The call: wcs $ foo + +From QL on the first arg of $ we instantiate wcs with a:=kappa. Then +we can work out what p and q must instantiate to. (the (p->q) arg of +($) is guarded): get p := (HCS => kappa), q := kappa + +But alas, the second arg of $, namely foo, satisfies our +fiv(rho_r)=empty condition. (Here rho_r is Int.) So we try to mgu( +HCS => kappa, Int ), and fail. + +The basic problem is this: we said in 5.4 of the Quick Look paper we +didn’t about vacuous type abstraction, but we clearly do care about +type-class abstraction. + +How does this work in GHC today, with the built-in rule? It works +because we are order-dependent: we look at the first argument first. + +The same would work here. If we applied the QL substitution as we go, +by the time we got to the second argument, the expected type would +look like (HCS => kappa), and we would abandon QL on it (App-lightning +only applies to rho). But the price is order-dependence. +-} + +module CabalEx where + +import GHC.Stack( withFrozenCallStack ) + +-- withFrozenCallStack :: HasCallStack +-- => ( HasCallStack => a ) +-- -> a + +printRawCommandAndArgsAndEnv :: Int -> IO () +printRawCommandAndArgsAndEnv = error "urk" + +printRawCommandAndArgs :: Int -> IO () +printRawCommandAndArgs verbosity + = withFrozenCallStack $ printRawCommandAndArgsAndEnv verbosity View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/eae80258c718ee303910818acf715e78a98a7f59...78b4c82c30d28e3eb11d05beaee1a03267661482 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/eae80258c718ee303910818acf715e78a98a7f59...78b4c82c30d28e3eb11d05beaee1a03267661482 You're receiving 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 29 15:01:50 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Fri, 29 May 2020 11:01:50 -0400 Subject: [Git][ghc/ghc][wip/osa1/std_string_thunks] Introduce a standard thunk for allocating strings Message-ID: <5ed123de1e8f5_6e2611db28542607134@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/std_string_thunks at Glasgow Haskell Compiler / GHC Commits: 6eaa4ca2 by Ömer Sinan Ağacan at 2020-05-29T18:01:30+03:00 Introduce a standard thunk for allocating strings Currently for a top-level closure in the form hey = unpackCString# x we generate code like this: Main.hey_entry() // [R1] { info_tbls: [(c2T4, label: Main.hey_info rep: HeapRep static { Thunk } srt: Nothing)] stack_info: arg_space: 8 updfr_space: Just 8 } {offset c2T4: // global _rqm::P64 = R1; if ((Sp + 8) - 24 < SpLim) (likely: False) goto c2T5; else goto c2T6; c2T5: // global R1 = _rqm::P64; call (stg_gc_enter_1)(R1) args: 8, res: 0, upd: 8; c2T6: // global (_c2T1::I64) = call "ccall" arg hints: [PtrHint, PtrHint] result hints: [PtrHint] newCAF(BaseReg, _rqm::P64); if (_c2T1::I64 == 0) goto c2T3; else goto c2T2; c2T3: // global call (I64[_rqm::P64])() args: 8, res: 0, upd: 8; c2T2: // global I64[Sp - 16] = stg_bh_upd_frame_info; I64[Sp - 8] = _c2T1::I64; R2 = hey1_r2Gg_bytes; Sp = Sp - 16; call GHC.CString.unpackCString#_info(R2) args: 24, res: 0, upd: 24; } } This code is generated for every string literal. Only difference between top-level closures like this is the argument for the bytes of the string (hey1_r2Gg_bytes in the code above). With this patch we introduce a standard thunk in the RTS, called stg_MK_STRING_info, that does what `unpackCString# x` does, except it gets the bytes address from the payload. Using this, for the closure above, we generate this: Main.hey_closure" { Main.hey_closure: const stg_MK_STRING_info; const hey1_r1Gg_bytes; const 0; const 0; } This is much smaller in code. Trying to fix top-level thunk layouts - - - - - 5 changed files: - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/StgToCmm/Bind.hs - includes/stg/MiscClosures.h - rts/RtsSymbols.c - rts/StgStdThunks.cmm Changes: ===================================== compiler/GHC/Cmm/CLabel.hs ===================================== @@ -23,6 +23,7 @@ module GHC.Cmm.CLabel ( mkConInfoTableLabel, mkApEntryLabel, mkApInfoTableLabel, + mkMkStringInfoTableLabel, mkClosureTableLabel, mkBytesLabel, @@ -61,6 +62,7 @@ module GHC.Cmm.CLabel ( mkCAFBlackHoleInfoTableLabel, mkRtsPrimOpLabel, mkRtsSlowFastTickyCtrLabel, + mkRtsMkStringLabel, mkSelectorInfoLabel, mkSelectorEntryLabel, @@ -426,6 +428,8 @@ data RtsLabelInfo | RtsApInfoTable Bool{-updatable-} Int{-arity-} -- ^ AP thunks | RtsApEntry Bool{-updatable-} Int{-arity-} + | RtsMkStringInfoTable + | RtsPrimOp PrimOp | RtsApFast FastString -- ^ _fast versions of generic apply | RtsSlowFastTickyCtr String @@ -569,16 +573,16 @@ mkLocalBlockLabel u = LocalBlockLabel u mkRtsPrimOpLabel :: PrimOp -> CLabel mkRtsPrimOpLabel primop = RtsLabel (RtsPrimOp primop) -mkSelectorInfoLabel :: Bool -> Int -> CLabel -mkSelectorEntryLabel :: Bool -> Int -> CLabel +mkSelectorInfoLabel, mkSelectorEntryLabel :: Bool -> Int -> CLabel mkSelectorInfoLabel upd off = RtsLabel (RtsSelectorInfoTable upd off) mkSelectorEntryLabel upd off = RtsLabel (RtsSelectorEntry upd off) -mkApInfoTableLabel :: Bool -> Int -> CLabel -mkApEntryLabel :: Bool -> Int -> CLabel +mkApInfoTableLabel, mkApEntryLabel :: Bool -> Int -> CLabel mkApInfoTableLabel upd off = RtsLabel (RtsApInfoTable upd off) mkApEntryLabel upd off = RtsLabel (RtsApEntry upd off) +mkMkStringInfoTableLabel :: CLabel +mkMkStringInfoTableLabel = RtsLabel RtsMkStringInfoTable -- A call to some primitive hand written Cmm code mkPrimCallLabel :: PrimCall -> CLabel @@ -671,6 +675,8 @@ mkRtsApFastLabel str = RtsLabel (RtsApFast str) mkRtsSlowFastTickyCtrLabel :: String -> CLabel mkRtsSlowFastTickyCtrLabel pat = RtsLabel (RtsSlowFastTickyCtr pat) +mkRtsMkStringLabel :: CLabel +mkRtsMkStringLabel = RtsLabel RtsMkStringInfoTable -- Constructing Code Coverage Labels mkHpcTicksLabel :: Module -> CLabel @@ -1296,6 +1302,8 @@ pprCLbl dflags = \case (CCS_Label ccs) -> ppr ccs (HpcTicksLabel mod) -> text "_hpc_tickboxes_" <> ppr mod <> ptext (sLit "_hpc") + (RtsLabel RtsMkStringInfoTable) -> text "stg_MK_STRING_info" + (AsmTempLabel {}) -> panic "pprCLbl AsmTempLabel" (AsmTempDerivedLabel {}) -> panic "pprCLbl AsmTempDerivedLabel" (DynamicLinkerLabel {}) -> panic "pprCLbl DynamicLinkerLabel" ===================================== compiler/GHC/StgToCmm/Bind.hs ===================================== @@ -51,6 +51,8 @@ import GHC.Utils.Outputable import GHC.Data.FastString import GHC.Driver.Session +import GHC.Builtin.Names (unpackCStringName) + import Control.Monad ------------------------------------------------------------------------ @@ -76,6 +78,9 @@ cgTopRhsClosure dflags rec id ccs upd_flag args body = lf_info = mkClosureLFInfo platform id TopLevel [] upd_flag args in (cg_id_info, gen_code dflags lf_info closure_label) where + + gen_code :: DynFlags -> LambdaFormInfo -> CLabel -> FCode () + -- special case for a indirection (f = g). We create an IND_STATIC -- closure pointing directly to the indirectee. This is exactly -- what the CAF will eventually evaluate to anyway, we're just @@ -90,11 +95,43 @@ cgTopRhsClosure dflags rec id ccs upd_flag args body = -- concurrent/should_run/4030 fails, for instance. -- gen_code _ _ closure_label - | StgApp f [] <- body, null args, isNonRec rec + | StgApp f [] <- body + , null args + , isNonRec rec = do cg_info <- getCgIdInfo f emitDataCon closure_label indStaticInfoTable ccs [unLit (idInfoToAmode cg_info)] + gen_code _ _ closure_label + | StgApp f [arg] <- stripStgTicksTopE (not . tickishIsCode) body + , idName f == unpackCStringName + = do -- TODO: What to do with ticks? + pprTrace "unpackCString#" (ppr body) (return ()) + arg' <- getArgAmode (NonVoid arg) + case arg' of + CmmLit lit -> do + let info = CmmInfoTable + { cit_lbl = mkRtsMkStringLabel + , cit_rep = HeapRep True 0 1 Thunk + , cit_prof = NoProfilingInfo + , cit_srt = Nothing + , cit_clo = Nothing + } + emitDecl $ CmmData (Section Data closure_label) $ + -- CmmStatics closure_label info ccs payload + let platform = targetPlatform dflags + layout = + [ CmmLabel (cit_lbl info) -- info ptr + , mkIntCLit platform 0 -- padding for indirectee after update + , mkIntCLit platform 0 -- static link + , mkIntCLit platform 0 -- saved info + , lit -- the payload! TODO FIXME HACK: we have to put it here as we don't support payload in top-level closures!!!!! + ] + in CmmStaticsRaw closure_label (map CmmStaticLit layout) + + _ -> panic "cgTopRhsClosure.gen_code" + + gen_code dflags lf_info _closure_label = do { let name = idName id ; mod_name <- getModuleName @@ -222,6 +259,34 @@ mkRhsClosure :: DynFlags -> Id -> CostCentreStack -> CgStgExpr -> FCode (CgIdInfo, FCode CmmAGraph) +{- + TODO: Consider handling this too. Not sure if it's going to save us much to + so this needs benchmarking. + +---------- unpackCString# -------------------- +mkRhsClosure dflags bndr _cc + [] -- No free variables, because this is top-level + Updatable -- Updatable thunk + [] -- A thunk + expr + + | let expr_no_ticks = stripStgTicksTopE (not . tickishIsCode) expr + , StgApp fn [arg] <- expr + , idName fn == unpackCStringName + = -- TODO: What to do with ticks? + -- A non-top-level unpackCString# closure. Most unpackCString# closures are + -- floted to the top-level, but sometimes we see simplifier-generated thunks + -- like: + -- + -- sat_sK0 [Occ=Once] :: [GHC.Types.Char] + -- [LclId] = + -- {} \u [] + -- GHC.CString.unpackCString# + -- "Oops! The program has entered an `absent' argument!\n"#; + -- + pprPanic "mkRhsClosure" (text "unpackCString# closure:" <+> ppr expr) +-} + {- mkRhsClosure looks for two special forms of the right-hand side: a) selector thunks b) AP thunks ===================================== includes/stg/MiscClosures.h ===================================== @@ -241,6 +241,9 @@ RTS_THUNK(stg_ap_5_upd); RTS_THUNK(stg_ap_6_upd); RTS_THUNK(stg_ap_7_upd); +// Standard entry for `unpackCString# str` thunks +RTS_ENTRY(stg_MK_STRING); + /* standard application routines (see also utils/genapply, * and GHC.StgToCmm.ArgRep). */ ===================================== rts/RtsSymbols.c ===================================== @@ -914,6 +914,7 @@ SymI_HasProto(stg_sel_13_noupd_info) \ SymI_HasProto(stg_sel_14_noupd_info) \ SymI_HasProto(stg_sel_15_noupd_info) \ + SymI_HasProto(stg_MK_STRING_info) \ SymI_HasProto(stg_upd_frame_info) \ SymI_HasProto(stg_bh_upd_frame_info) \ SymI_HasProto(suspendThread) \ ===================================== rts/StgStdThunks.cmm ===================================== @@ -13,6 +13,8 @@ #include "Cmm.h" #include "Updates.h" +import CLOSURE ghczmprim_GHCziCString_unpackCStringzh_closure; + /* ----------------------------------------------------------------------------- The code for a thunk that simply extracts a field from a single-constructor datatype depends only on the offset of the field @@ -284,3 +286,37 @@ INFO_TABLE(stg_ap_7_upd,7,0,THUNK,"stg_ap_7_upd_info","stg_ap_7_upd_info") StgThunk_payload(node,6)); } } + +/* ----------------------------------------------------------------------------- + Making strings + -------------------------------------------------------------------------- */ + +// FIXME HACK: We use CONSTR_NOCAF with 4 nptrs as we don't support having +// payload in top-level thunks. Fields are: +// - Padding for indirectee -- this is part of the thunk header! So below we use +// index 2 for the payload +// - Static link +// - Saved info +// - The actual payload! +INFO_TABLE(stg_MK_STRING, 0, 0, THUNK_STATIC, "stg_MK_STRING", "stg_MK_STRING") + (P_ node) +{ + W_ newCAF_ret; + + // TODO (osa): Not sure why we do stack check before `newCAF`, but this is + // how `unpackCString# str` thunks are today. + STK_CHK_ENTER(WDS(2), node); + + (newCAF_ret) = ccall newCAF(BaseReg "ptr", node "ptr"); + + if (newCAF_ret == 0) { + jump node(); + } else { + // Stack check done above + Sp_adj(-2); + Sp(1) = newCAF_ret; + Sp(0) = stg_bh_upd_frame_info; + // TODO: Make this a direct call + jump stg_ap_n_fast(ghczmprim_GHCziCString_unpackCStringzh_closure, StgThunk_payload(node, 2)); + } +} View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6eaa4ca235b245b18c7827f7e11552987dc368fa -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6eaa4ca235b245b18c7827f7e11552987dc368fa You're receiving 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 29 16:15:56 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 29 May 2020 12:15:56 -0400 Subject: [Git][ghc/ghc][wip/T18078] Implement cast worker/wrapper properly Message-ID: <5ed1353cd05c_6e263f9f0cbba3d8262791b@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18078 at Glasgow Haskell Compiler / GHC Commits: 47025bbf by Simon Peyton Jones at 2020-05-29T12:14:08-04: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 also discovered that unsafeCoerce wasn't being inlined if the context was boring. So (\x. f (unsafeCoerce x)) would create a thunk -- yikes! I fixed that by making inlineBoringOK a bit cleverer: see Note [Inline unsafeCoerce] in GHC.Core.Unfold. I also found that unsafeCoerceName was unused, so I removed it. 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% Metric Decrease: T15164 T13701 Metric Increase: T12150 T12234 T12425 - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Opt/CSE.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/Driver.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/SimpleOpt.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Types/Basic.hs - compiler/GHC/Types/Id/Make.hs - compiler/GHC/Types/Var.hs - compiler/GHC/Utils/Binary.hs - libraries/base/Unsafe/Coerce.hs - testsuite/tests/codeGen/should_compile/debug.stdout - testsuite/tests/deSugar/should_compile/T2431.stderr - testsuite/tests/perf/compiler/T16473.stdout - testsuite/tests/simplCore/should_compile/T13143.stderr - + testsuite/tests/simplCore/should_compile/T17673.hs - + testsuite/tests/simplCore/should_compile/T17673.stderr - + testsuite/tests/simplCore/should_compile/T18078.hs - + testsuite/tests/simplCore/should_compile/T18078.stderr - testsuite/tests/simplCore/should_compile/T3772.stdout - testsuite/tests/simplCore/should_compile/T7360.stderr - testsuite/tests/simplCore/should_compile/T7865.stdout The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/47025bbf175086d6eec1599de5ffb9c078498145 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/47025bbf175086d6eec1599de5ffb9c078498145 You're receiving 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 29 16:20:24 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 29 May 2020 12:20:24 -0400 Subject: [Git][ghc/ghc][wip/T17775] 23 commits: core-spec: Modify file paths according to new module hierarchy Message-ID: <5ed136489beb9_6e263f9ed75052ac26300ee@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: ede24126 by Takenobu Tani at 2020-05-27T00:13:55-04:00 core-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Core.hs <= coreSyn/CoreSyn.hs * GHC/Core/Coercion.hs <= types/Coercion.hs * GHC/Core/Coercion/Axiom.hs <= types/CoAxiom.hs * GHC/Core/Coercion/Opt.hs <= types/OptCoercion.hs * GHC/Core/DataCon.hs <= basicTypes/DataCon.hs * GHC/Core/FamInstEnv.hs <= types/FamInstEnv.hs * GHC/Core/Lint.hs <= coreSyn/CoreLint.hs * GHC/Core/Subst.hs <= coreSyn/CoreSubst.hs * GHC/Core/TyCo/Rep.hs <= types/TyCoRep.hs * GHC/Core/TyCon.hs <= types/TyCon.hs * GHC/Core/Type.hs <= types/Type.hs * GHC/Core/Unify.hs <= types/Unify.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/Var.hs <= basicTypes/Var.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [skip ci] - - - - - 04750304 by Ben Gamari at 2020-05-27T00:14:33-04:00 eventlog: Fix racy flushing Previously no attempt was made to avoid multiple threads writing their capability-local eventlog buffers to the eventlog writer simultaneously. This could result in multiple eventlog streams being interleaved. Fix this by documenting that the EventLogWriter's write() and flush() functions may be called reentrantly and fix the default writer to protect its FILE* by a mutex. Fixes #18210. - - - - - d6203f24 by Joshua Price at 2020-05-27T00:15:17-04:00 Make `identifier` parse unparenthesized `->` (#18060) - - - - - 28deee28 by Ben Gamari at 2020-05-28T16:23:21-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 - - - - - 1f393e1e by Ben Gamari at 2020-05-28T16:23:21-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 haddock.Cabal haddock.base haddock.compiler - - - - - 5f621a78 by Vladislav Zavialov at 2020-05-28T16:23:58-04:00 Add Semigroup/Monoid for Q (#18123) - - - - - dc5f004c by Xavier Denis at 2020-05-28T16:24:37-04:00 Fix #18071 Run the core linter on candidate instances to ensure they are well-kinded. Better handle quantified constraints by using a CtWanted to avoid having unsolved constraints thrown away at the end by the solver. - - - - - 10e6982c by Sebastian Graf at 2020-05-28T16:25:14-04:00 FloatOut: Only eta-expand dead-end RHS if arity will increase (#18231) Otherwise we risk turning trivial RHS into non-trivial RHS, introducing unnecessary bindings in the next Simplifier run, resulting in more churn. Fixes #18231. - - - - - 08dab5f7 by Sebastian Graf at 2020-05-28T16:25:14-04:00 DmdAnal: Recognise precise exceptions from case alternatives (#18086) Consider ```hs m :: IO () m = do putStrLn "foo" error "bar" ``` `m` (from #18086) always throws a (precise or imprecise) exception or diverges. Yet demand analysis infers `<L,A>` as demand signature instead of `<L,A>x` for it. That's because the demand analyser sees `putStrLn` occuring in a case scrutinee and decides that it has to `deferAfterPreciseException`, because `putStrLn` throws a precise exception on some control flow paths. This will mask the `botDiv` `Divergence`of the single case alt containing `error` to `topDiv`. Since `putStrLn` has `topDiv` itself, the final `Divergence` is `topDiv`. This is easily fixed: `deferAfterPreciseException` works by `lub`ing with the demand type of a virtual case branch denoting the precise exceptional control flow. We used `nopDmdType` before, but we can be more precise and use `exnDmdType`, which is `nopDmdType` with `exnDiv`. Now the `Divergence` from the case alt will degrade `botDiv` to `exnDiv` instead of `topDiv`, which combines with the result from the scrutinee to `exnDiv`, and all is well. Fixes #18086. - - - - - aef95f11 by Ben Gamari at 2020-05-28T16:25:53-04:00 Ticky-ticky: Record DataCon name in ticker name This makes it significantly easier to spot the nature of allocations regressions and comes at a reasonably low cost. - - - - - 8f021b8c by Ben Gamari at 2020-05-28T16:26:34-04:00 hadrian: Don't track GHC's verbosity argument Teach hadrian to ignore GHC's -v argument in its recompilation check, thus fixing #18131. - - - - - 13d9380b by Ben Gamari at 2020-05-28T16:27:20-04:00 Rip out CmmStackInfo(updfr_space) As noted in #18232, this field is currently completely unused and moreover doesn't have a clear meaning. - - - - - f10d11fa by Andreas Klebinger at 2020-05-29T01:38:42-04: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. - - - - - bbeb2389 by Ben Gamari at 2020-05-29T01:39:19-04:00 CoreToStg: Add Outputable ArgInfo instance - - - - - 0e3361ca by Simon Peyton Jones at 2020-05-29T01:39:19-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. - - - - - c49f7df0 by Simon Peyton Jones at 2020-05-29T01:39:19-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. - - - - - 46720997 by Ben Gamari at 2020-05-29T01:39:19-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 Metric Decrease: ManyConstructors Co-Authored-By: Simon Peyton-Jone <simonpj at microsoft.com> - - - - - 277c2f26 by Ben Gamari at 2020-05-29T01:39:55-04:00 Eta expand un-saturated primops Now since we no longer try to predict CAFfyness we have no need for the solution to #16846. Eta expanding unsaturated primop applications is conceptually simpler, especially in the presence of levity polymorphism. This essentially reverts cac8dc9f51e31e4c0a6cd9bc302f7e1bc7c03beb, as suggested in #18079. Closes #18079. - - - - - f44d7ae0 by Simon Jakobi at 2020-05-29T01:40:34-04:00 base: Scrap deprecation plan for Data.Monoid.{First,Last} See the discussion on the libraries mailing list for context: https://mail.haskell.org/pipermail/libraries/2020-April/030357.html - - - - - 8b494895 by Jeremy Schlatter at 2020-05-29T01:41:12-04:00 Fix typo in documentation - - - - - 998450f4 by Gleb Popov at 2020-05-29T01:41:53-04:00 Always define USE_PTHREAD_FOR_ITIMER for FreeBSD. - - - - - f9a513e0 by Alp Mestanogullari at 2020-05-29T01:42:36-04:00 hadrian: introduce 'install' target Its logic is very simple. It `need`s the `binary-dist-dir` target and runs suitable `configure` and `make install` commands for the user. A new `--prefix` command line argument is introduced to specify where GHC should be installed. - - - - - c754528c by Simon Peyton Jones at 2020-05-29T12:18:40-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 Updates Cabal submodule. Metric Increase: T12150 Metric Decrease: haddock.Cabal haddock.base - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/LayoutStack.hs - compiler/GHC/Cmm/Ppr.hs - compiler/GHC/Cmm/ProcPoint.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Monad.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Parser.y The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d224b07b450d50089bad13dc0860b7c9d863f904...c754528c168026ef3dcbc86cf97a6a0eb4f68606 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d224b07b450d50089bad13dc0860b7c9d863f904...c754528c168026ef3dcbc86cf97a6a0eb4f68606 You're receiving 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 29 16:47:40 2020 From: gitlab at gitlab.haskell.org (Matthew Pickering) Date: Fri, 29 May 2020 12:47:40 -0400 Subject: [Git][ghc/ghc][wip/con-info] Also store closure labels Message-ID: <5ed13cacdbe6_6e2681629e026384c9@gitlab.haskell.org.mail> Matthew Pickering pushed to branch wip/con-info at Glasgow Haskell Compiler / GHC Commits: d28a579a by Matthew Pickering at 2020-05-29T17:46:48+01:00 Also store closure labels - - - - - 8 changed files: - 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/Utils.hs - compiler/GHC/Types/CostCentre.hs - compiler/GHC/Types/SrcLoc.hs Changes: ===================================== compiler/GHC/CoreToStg.hs ===================================== @@ -1,4 +1,4 @@ -{-# LANGUAGE CPP, DeriveFunctor #-} +{-# LANGUAGE CPP, DeriveFunctor, TupleSections #-} -- -- (c) The GRASP/AQUA Project, Glasgow University, 1993-1998 @@ -33,7 +33,7 @@ import GHC.Core.DataCon import GHC.Types.CostCentre import GHC.Types.Var.Env import GHC.Unit.Module -import GHC.Types.Name ( isExternalName, nameModule_maybe ) +import GHC.Types.Name ( getName, getOccName, occNameString, nameSrcSpan, isExternalName, nameModule_maybe ) import GHC.Types.Basic ( Arity ) import GHC.Builtin.Types ( unboxedUnitDataCon, unitDataConId ) import GHC.Types.Literal @@ -48,6 +48,7 @@ import GHC.Types.Demand ( isUsedOnce ) import GHC.Builtin.PrimOps ( PrimCall(..), primOpWrapperId ) import GHC.Types.SrcLoc ( mkGeneralSrcSpan ) import GHC.Builtin.Names ( unsafeEqualityProofName ) +import GHC.Data.Maybe import Data.List.NonEmpty (nonEmpty, toList) import Data.Maybe (fromMaybe) @@ -229,12 +230,12 @@ import GHC.Types.SrcLoc coreToStg :: DynFlags -> Module -> CoreProgram - -> ([StgTopBinding], DCMap, CollectedCCs) + -> ([StgTopBinding], InfoTableProvMap, CollectedCCs) coreToStg dflags this_mod pgm = (pgm', denv, final_ccs) where (_, denv, (local_ccs, local_cc_stacks), pgm') - = coreTopBindsToStg dflags this_mod emptyVarEnv emptyUniqMap emptyCollectedCCs pgm + = coreTopBindsToStg dflags this_mod emptyVarEnv emptyInfoTableProvMap emptyCollectedCCs pgm prof = WayProf `Set.member` ways dflags @@ -252,10 +253,10 @@ coreTopBindsToStg :: DynFlags -> Module -> IdEnv HowBound -- environment for the bindings - -> DCMap + -> InfoTableProvMap -> CollectedCCs -> CoreProgram - -> (IdEnv HowBound, DCMap,CollectedCCs, [StgTopBinding]) + -> (IdEnv HowBound, InfoTableProvMap,CollectedCCs, [StgTopBinding]) coreTopBindsToStg _ _ env denv ccs [] = (env, denv, ccs, []) @@ -271,10 +272,10 @@ coreTopBindToStg :: DynFlags -> Module -> IdEnv HowBound - -> DCMap + -> InfoTableProvMap -> CollectedCCs -> CoreBind - -> (IdEnv HowBound, DCMap, CollectedCCs, StgTopBinding) + -> (IdEnv HowBound, InfoTableProvMap, CollectedCCs, StgTopBinding) coreTopBindToStg _ _ env dcenv ccs (NonRec id e) | Just str <- exprIsTickedString_maybe e @@ -339,7 +340,9 @@ coreToTopStgRhs dflags ccs this_mod (bndr, rhs) mkTopStgRhs dflags this_mod ccs bndr new_rhs stg_arity = stgRhsArity stg_rhs - + ; case stg_rhs of + StgRhsClosure {} -> recordStgIdPosition bndr (((, occNameString (getOccName bndr))) <$> (srcSpanToRealSrcSpan (nameSrcSpan (getName bndr)))) + _ -> return () ; return (ASSERT2( arity_ok stg_arity, mk_arity_msg stg_arity) stg_rhs, ccs') } where @@ -686,13 +689,16 @@ coreToStgRhs :: (Id,CoreExpr) coreToStgRhs (bndr, rhs) = do new_rhs <- coreToStgExpr rhs + recordStgIdPosition bndr (quickSourcePos rhs) return (mkStgRhs bndr new_rhs) +quickSourcePos (Tick (SourceNote ss m) _) = Just (ss, m) +quickSourcePos _ = Nothing + -- Generate a top-level RHS. Any new cost centres generated for CAFs will be -- appended to `CollectedCCs` argument. mkTopStgRhs :: DynFlags -> Module -> CollectedCCs -> Id -> StgExpr -> (StgRhs, CollectedCCs) - mkTopStgRhs dflags this_mod ccs bndr rhs | StgLam bndrs body <- rhs = -- StgLam can't have empty arguments, so not CAF @@ -833,7 +839,7 @@ isPAP env _ = False newtype CtsM a = CtsM { unCtsM :: DynFlags -- Needed for checking for bad coercions in coreToStgArgs -> IdEnv HowBound - -> RWS (Maybe (RealSrcSpan, String)) () DCMap a + -> RWS (Maybe (RealSrcSpan, String)) () InfoTableProvMap a } deriving (Functor) @@ -869,7 +875,7 @@ data LetInfo -- The std monad functions: -initCts :: DynFlags -> IdEnv HowBound -> DCMap -> CtsM a -> (a, DCMap) +initCts :: DynFlags -> IdEnv HowBound -> InfoTableProvMap -> CtsM a -> (a, InfoTableProvMap) initCts dflags env u m = let (a, d, ()) = runRWS (unCtsM m dflags env) Nothing u in (a, d) @@ -918,11 +924,19 @@ incDc :: DataCon -> CtsM Int incDc dc = CtsM $ \_ _ -> do env <- get 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 + let dcMap' = alterUniqMap (maybe (Just [(0, cc)]) (\xs@((k, _):_) -> Just ((k + 1, cc) : xs))) (provDC env) dc + put (env { provDC = dcMap' }) + let Just r = lookupUniqMap dcMap' dc return (fst (head r)) +recordStgIdPosition :: Id -> Maybe (RealSrcSpan, String) -> CtsM () +recordStgIdPosition id ss = CtsM $ \_ _ -> do + cc <- ask + pprTraceM "recordStgIdPosition" (ppr id $$ ppr cc $$ ppr ss) + case firstJust ss cc of + Nothing -> return () + Just r -> modify (\env -> env { provClosure = addToUniqMap (provClosure env) id r}) + withSpan :: (RealSrcSpan, String) -> CtsM a -> CtsM a withSpan s (CtsM act) = CtsM (\a b -> local (const $ Just s) (act a b)) ===================================== compiler/GHC/Driver/CodeOutput.hs ===================================== @@ -321,8 +321,8 @@ profilingInitCode dflags this_mod (local_CCs, singleton_CCSs) -- | Generate code to initialise info pointer origin -ipInitCode :: DynFlags -> Module -> DCMap -> SDoc -ipInitCode dflags this_mod dcmap +ipInitCode :: DynFlags -> Module -> InfoTableProvMap -> SDoc +ipInitCode dflags this_mod (InfoTableProvMap dcmap closure_map) = pprTraceIt "codeOutput" $ if not (gopt Opt_SccProfilingOn dflags) then empty else vcat @@ -336,7 +336,9 @@ ipInitCode dflags this_mod dcmap ]) ] where - ents = convertDCMap this_mod dcmap + dc_ents = convertDCMap this_mod dcmap + closure_ents = convertClosureMap this_mod closure_map + ents = closure_ents ++ dc_ents emit_ipe_decl ipe = text "extern InfoProvEnt" <+> ipe_lbl <> text "[];" where ipe_lbl = ppr (mkIPELabel ipe) ===================================== compiler/GHC/Driver/Hooks.hs ===================================== @@ -110,7 +110,7 @@ data Hooks = Hooks , getValueSafelyHook :: Maybe (HscEnv -> Name -> Type -> IO (Maybe HValue)) , createIservProcessHook :: Maybe (CreateProcess -> IO ProcessHandle) - , stgToCmmHook :: Maybe (DynFlags -> Module -> DCMap -> [TyCon] -> CollectedCCs + , stgToCmmHook :: Maybe (DynFlags -> Module -> InfoTableProvMap -> [TyCon] -> CollectedCCs -> [CgStgTopBinding] -> HpcInfo -> Stream IO CmmGroup ()) , cmmToRawCmmHook :: forall a . Maybe (DynFlags -> Maybe Module -> Stream IO CmmGroupSRTs a ===================================== compiler/GHC/Driver/Main.hs ===================================== @@ -1542,7 +1542,7 @@ This reduces residency towards the end of the CodeGen phase significantly (5-10%). -} -doCodeGen :: HscEnv -> Module -> DCMap -> [TyCon] +doCodeGen :: HscEnv -> Module -> InfoTableProvMap -> [TyCon] -> CollectedCCs -> [StgTopBinding] -> HpcInfo @@ -1591,7 +1591,7 @@ doCodeGen hsc_env this_mod denv data_tycons myCoreToStg :: DynFlags -> Module -> CoreProgram -> IO ( [StgTopBinding] -- output program - , DCMap + , InfoTableProvMap , 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 ===================================== @@ -64,7 +64,7 @@ import Data.Maybe codeGen :: DynFlags -> Module - -> DCMap + -> InfoTableProvMap -> [TyCon] -> CollectedCCs -- (Local/global) cost-centres needing declaring/registering. -> [CgStgTopBinding] -- Bindings to convert @@ -72,7 +72,7 @@ codeGen :: DynFlags -> Stream IO CmmGroup () -- Output as a stream, so codegen can -- be interleaved with output -codeGen dflags this_mod dcmap@(UniqMap denv) data_tycons +codeGen dflags this_mod (InfoTableProvMap (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 ===================================== compiler/GHC/StgToCmm/Utils.hs ===================================== @@ -45,7 +45,7 @@ module GHC.StgToCmm.Utils ( emitUpdRemSetPush, emitUpdRemSetPushThunk, - convertDCMap + convertDCMap, convertClosureMap ) where #include "HsVersions.h" @@ -91,6 +91,7 @@ import GHC.Types.Unique.Map import GHC.Types.Unique.FM import Data.Maybe import GHC.Core.DataCon +import GHC.Types.Id ------------------------------------------------------------------------- @@ -632,11 +633,15 @@ emitUpdRemSetPushThunk ptr = do False +convertClosureMap :: Module -> ClosureMap -> [InfoTableEnt] +convertClosureMap this_mod (UniqMap denv) = + map (\(bndr, (ss, l)) -> InfoTableEnt (mkClosureTableLabel (idName bndr) (idCafInfo bndr)) (this_mod, ss, l)) (nonDetEltsUFM denv) + convertDCMap :: Module -> DCMap -> [InfoTableEnt] convertDCMap this_mod (UniqMap denv) = - concatMap (\(dc, ns) -> mapMaybe (\(k, mss) -> + concatMap (\(dc, ns) -> mapMaybe (\(k, mss) -> case mss of Nothing -> Nothing - Just (ss, l) -> Just $ - InfoTableEnt (mkConInfoTableLabel (dataConName dc) (Just (this_mod, k))) + 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, + DCMap, ClosureMap, InfoTableProvMap(..), emptyInfoTableProvMap, CostCentreStack, CollectedCCs, emptyCollectedCCs, collectCC, currentCCS, dontCareCCS, @@ -189,6 +189,13 @@ data CostCentreStack type DCMap = UniqMap DataCon [(Int, Maybe (RealSrcSpan, String))] +type ClosureMap = UniqMap Id (RealSrcSpan, String) + +data InfoTableProvMap = InfoTableProvMap + { provDC :: DCMap + , provClosure :: ClosureMap } + +emptyInfoTableProvMap = InfoTableProvMap emptyUniqMap emptyUniqMap -- synonym for triple which describes the cost centre info in the generated -- code for a module. @@ -209,6 +216,7 @@ currentCCS = CurrentCCS dontCareCCS = DontCareCCS ----------------------------------------------------------------------------- + -- Predicates on Cost-Centre Stacks isCurrentCCS :: CostCentreStack -> Bool ===================================== compiler/GHC/Types/SrcLoc.hs ===================================== @@ -53,6 +53,7 @@ module GHC.Types.SrcLoc ( srcSpanStart, srcSpanEnd, realSrcSpanStart, realSrcSpanEnd, srcSpanFileName_maybe, + srcSpanToRealSrcSpan, pprUserRealSpan, -- ** Unsafely deconstructing SrcSpan @@ -511,6 +512,10 @@ srcSpanFileName_maybe :: SrcSpan -> Maybe FastString srcSpanFileName_maybe (RealSrcSpan s _) = Just (srcSpanFile s) srcSpanFileName_maybe (UnhelpfulSpan _) = Nothing +srcSpanToRealSrcSpan :: SrcSpan -> Maybe RealSrcSpan +srcSpanToRealSrcSpan (RealSrcSpan ss _) = Just ss +srcSpanToRealSrcSpan _ = Nothing + {- ************************************************************************ * * View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d28a579ab4daf2a587477940565f2cf684db0262 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d28a579ab4daf2a587477940565f2cf684db0262 You're receiving 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 29 17:34:58 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 29 May 2020 13:34:58 -0400 Subject: [Git][ghc/ghc][master] Build a threaded stage 1 if the bootstrapping GHC supports it. Message-ID: <5ed147c26d8ef_6e2611db2854266592e@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 67738db1 by Travis Whitaker at 2020-05-29T13:34:48-04:00 Build a threaded stage 1 if the bootstrapping GHC supports it. - - - - - 8 changed files: - compiler/ghc.mk - configure.ac - ghc/ghc.mk - hadrian/cfg/system.config.in - hadrian/src/Expression.hs - hadrian/src/Oracles/Flag.hs - hadrian/src/Settings/Packages.hs - mk/config.mk.in Changes: ===================================== compiler/ghc.mk ===================================== @@ -194,6 +194,12 @@ ifeq "$(GhcThreaded)" "YES" compiler_stage2_CONFIGURE_OPTS += --ghc-option=-optc-DTHREADED_RTS endif +# If the bootstrapping GHC supplies the threaded RTS, then we can have a +# threaded stage 1 too. +ifeq "$(GhcThreadedRts)" "YES" +compiler_stage1_CONFIGURE_OPTS += --ghc-option=-optc-DTHREADED_RTS +endif + ifeq "$(GhcWithNativeCodeGen)" "YES" compiler_stage1_CONFIGURE_OPTS += --flags=ncg compiler_stage2_CONFIGURE_OPTS += --flags=ncg ===================================== configure.ac ===================================== @@ -124,6 +124,9 @@ AC_ARG_VAR(CC_STAGE0, [C compiler command (bootstrap)]) AC_ARG_VAR(LD_STAGE0, [Linker command (bootstrap)]) AC_ARG_VAR(AR_STAGE0, [Archive command (bootstrap)]) +dnl RTS ways supplied by the bootstrapping compiler. +AC_ARG_VAR(RTS_WAYS_STAGE0, [RTS ways]) + if test "$WithGhc" != ""; then FPTOOLS_GHC_VERSION([GhcVersion], [GhcMajVersion], [GhcMinVersion], [GhcPatchLevel])dnl @@ -151,6 +154,17 @@ if test "$WithGhc" != ""; then fi BOOTSTRAPPING_GHC_INFO_FIELD([AR_OPTS_STAGE0],[ar flags]) BOOTSTRAPPING_GHC_INFO_FIELD([ArSupportsAtFile_STAGE0],[ar supports at file]) + BOOTSTRAPPING_GHC_INFO_FIELD([RTS_WAYS_STAGE0],[RTS ways]) + + dnl Check whether or not the bootstrapping GHC has a threaded RTS. This + dnl determines whether or not we can have a threaded stage 1. + dnl See Note [Linking ghc-bin against threaded stage0 RTS] in + dnl hadrian/src/Settings/Packages.hs for details. + if echo ${RTS_WAYS_STAGE0} | grep '.*thr.*' 2>&1 >/dev/null; then + AC_SUBST(GhcThreadedRts, YES) + else + AC_SUBST(GhcThreadedRts, NO) + fi fi dnl ** Must have GHC to build GHC @@ -1454,6 +1468,7 @@ Configure completed successfully. echo "\ Bootstrapping using : $WithGhc which is version : $GhcVersion + with threaded RTS? : $GhcThreadedRts " if test "x$CcLlvmBackend" = "xYES"; then ===================================== ghc/ghc.mk ===================================== @@ -66,8 +66,15 @@ else ghc_stage2_CONFIGURE_OPTS += -f-threaded ghc_stage3_CONFIGURE_OPTS += -f-threaded endif -# Stage-0 compiler isn't guaranteed to have a threaded RTS. + +# If stage 0 supplies a threaded RTS, we can use it for stage 1. +# See Note [Linking ghc-bin against threaded stage0 RTS] in +# hadrian/src/Settings/Packages.hs for details. +ifeq "$(GhcThreadedRts)" "YES" +ghc_stage1_MORE_HC_OPTS += -threaded +else ghc_stage1_CONFIGURE_OPTS += -f-threaded +endif ifeq "$(GhcProfiled)" "YES" ghc_stage2_PROGRAM_WAY = p ===================================== hadrian/cfg/system.config.in ===================================== @@ -79,6 +79,8 @@ ghc-major-version = @GhcMajVersion@ ghc-minor-version = @GhcMinVersion@ ghc-patch-level = @GhcPatchLevel@ +bootstrap-threaded-rts = @GhcThreadedRts@ + supports-this-unit-id = @SUPPORTS_THIS_UNIT_ID@ project-name = @ProjectName@ ===================================== hadrian/src/Expression.hs ===================================== @@ -6,8 +6,9 @@ module Expression ( expr, exprIO, arg, remove, -- ** Predicates - (?), stage, stage0, stage1, stage2, notStage0, package, notPackage, - packageOneOf, libraryPackage, builder, way, input, inputs, output, outputs, + (?), stage, stage0, stage1, stage2, notStage0, threadedBootstrapper, + package, notPackage, packageOneOf, libraryPackage, builder, way, input, + inputs, output, outputs, -- ** Evaluation interpret, interpretInContext, @@ -26,6 +27,7 @@ import Base import Builder import Context hiding (stage, package, way) import Expression.Type +import Oracles.Flag import Hadrian.Expression hiding (Expr, Predicate, Args) import Hadrian.Haskell.Cabal.Type import Hadrian.Oracles.Cabal @@ -86,6 +88,19 @@ instance BuilderPredicate a => BuilderPredicate (FilePath -> a) where way :: Way -> Predicate way w = (w ==) <$> getWay +{- +Note [Stage Names] +~~~~~~~~~~~~~~~~~~ + +Code referring to specific stages can be a bit tricky. In Hadrian, the stages +have the same names they carried in the autoconf build system, but they are +often referred to by the stage used to construct them. For example, the stage 1 +artifacts will be placed in _build/stage0, because they are constructed by the +stage 0 compiler. The stage predicates in this module behave the same way, +'stage0' will return 'True' while stage 0 is being used to build the stage 1 +compiler. +-} + -- | Is the build currently in stage 0? stage0 :: Predicate stage0 = stage Stage0 @@ -102,6 +117,13 @@ stage2 = stage Stage2 notStage0 :: Predicate notStage0 = notM stage0 +-- | Whether or not the bootstrapping compiler provides a threaded RTS. We need +-- to know this when building stage 1, since stage 1 links against the +-- compiler's RTS ways. See Note [Linking ghc-bin against threaded stage0 RTS] +-- in Settings.Packages for details. +threadedBootstrapper :: Predicate +threadedBootstrapper = expr (flag BootstrapThreadedRts) + -- | Is a certain package /not/ built right now? notPackage :: Package -> Predicate notPackage = notM . package ===================================== hadrian/src/Oracles/Flag.hs ===================================== @@ -24,25 +24,27 @@ data Flag = ArSupportsAtFile | WithLibnuma | HaveLibMingwEx | UseSystemFfi + | BootstrapThreadedRts -- Note, if a flag is set to empty string we treat it as set to NO. This seems -- fragile, but some flags do behave like this. flag :: Flag -> Action Bool flag f = do let key = case f of - ArSupportsAtFile -> "ar-supports-at-file" - CrossCompiling -> "cross-compiling" - CcLlvmBackend -> "cc-llvm-backend" - GhcUnregisterised -> "ghc-unregisterised" - TablesNextToCode -> "tables-next-to-code" - GmpInTree -> "intree-gmp" - GmpFrameworkPref -> "gmp-framework-preferred" - LeadingUnderscore -> "leading-underscore" - SolarisBrokenShld -> "solaris-broken-shld" - WithLibdw -> "with-libdw" - WithLibnuma -> "with-libnuma" - HaveLibMingwEx -> "have-lib-mingw-ex" - UseSystemFfi -> "use-system-ffi" + ArSupportsAtFile -> "ar-supports-at-file" + CrossCompiling -> "cross-compiling" + CcLlvmBackend -> "cc-llvm-backend" + GhcUnregisterised -> "ghc-unregisterised" + TablesNextToCode -> "tables-next-to-code" + GmpInTree -> "intree-gmp" + GmpFrameworkPref -> "gmp-framework-preferred" + LeadingUnderscore -> "leading-underscore" + SolarisBrokenShld -> "solaris-broken-shld" + WithLibdw -> "with-libdw" + WithLibnuma -> "with-libnuma" + HaveLibMingwEx -> "have-lib-mingw-ex" + UseSystemFfi -> "use-system-ffi" + BootstrapThreadedRts -> "bootstrap-threaded-rts" value <- lookupValueOrError configFile key when (value `notElem` ["YES", "NO", ""]) . error $ "Configuration flag " ++ quote (key ++ " = " ++ value) ++ " cannot be parsed." ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -64,8 +64,13 @@ packageArgs = do , flag GhcUnregisterised ? arg "--ghc-option=-DNO_REGS" , notM targetSupportsSMP ? arg "--ghc-option=-DNOSMP" , notM targetSupportsSMP ? arg "--ghc-option=-optc-DNOSMP" + -- When building stage 1 or later, use thread-safe RTS functions if + -- the configuration calls for a threaded GHC. , (any (wayUnit Threaded) rtsWays) ? notStage0 ? arg "--ghc-option=-optc-DTHREADED_RTS" + -- When building stage 1, use thread-safe RTS functions if the + -- bootstrapping (stage 0) compiler provides a threaded RTS way. + , stage0 ? threadedBootstrapper ? arg "--ghc-option=-optc-DTHREADED_RTS" , ghcWithInterpreter ? ghciWithDebugger <$> flavour ? notStage0 ? arg "--ghc-option=-DDEBUGGER" @@ -90,11 +95,26 @@ packageArgs = do , builder (Cabal Flags) ? mconcat [ ghcWithInterpreter ? notStage0 ? arg "ghci" , cross ? arg "-terminfo" - -- the 'threaded' flag is True by default, but - -- let's record explicitly that we link all ghc - -- executables with the threaded runtime. - , stage0 ? arg "-threaded" - , notStage0 ? ifM (ghcThreaded <$> expr flavour) (arg "threaded") (arg "-threaded") ] + -- Note [Linking ghc-bin against threaded stage0 RTS] + -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + -- We must maintain the invariant that GHCs linked with '-threaded' + -- are built with '-optc=-DTHREADED_RTS', otherwise we'll end up + -- with a GHC that can use the threaded runtime, but contains some + -- non-thread-safe functions. See + -- https://gitlab.haskell.org/ghc/ghc/issues/18024 for an example of + -- the sort of issues this can cause. + , ifM stage0 + -- We build a threaded stage 1 if the bootstrapping compiler + -- supports it. + (ifM threadedBootstrapper + (arg "threaded") + (arg "-threaded")) + -- We build a threaded stage N, N>1 if the configuration calls + -- for it. + (ifM (ghcThreaded <$> expr flavour) + (arg "threaded") + (arg "-threaded")) + ] ] -------------------------------- ghcPkg -------------------------------- ===================================== mk/config.mk.in ===================================== @@ -199,6 +199,9 @@ endif # `GhcUnregisterised` mode doesn't allow that. GhcWithSMP := $(strip $(if $(filter YESNO, $(ArchSupportsSMP)$(GhcUnregisterised)),YES,NO)) +# Whether or not the bootstrapping GHC supplies a threaded RTS. +GhcThreadedRts = @GhcThreadedRts@ + # Whether to include GHCi in the compiler. Depends on whether the RTS linker # has support for this OS/ARCH combination. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/67738db10010fd28a8e997b5c8f83ea591b88a0e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/67738db10010fd28a8e997b5c8f83ea591b88a0e You're receiving 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 29 17:35:38 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 29 May 2020 13:35:38 -0400 Subject: [Git][ghc/ghc][master] PPC NCG: No per-symbol .section ".toc" directives Message-ID: <5ed147ea2b3fe_6e263f9ed7570e802675536@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: aac19e6c by Peter Trommler at 2020-05-29T13:35:24-04:00 PPC NCG: No per-symbol .section ".toc" directives All position independent symbols are collected during code generation and emitted in one go. Prepending each symbol with a .section ".toc" directive is redundant. This patch drops the per-symbol directives leading to smaller assembler files. Fixes #18250 - - - - - 1 changed file: - compiler/GHC/CmmToAsm/PIC.hs Changes: ===================================== compiler/GHC/CmmToAsm/PIC.hs ===================================== @@ -682,7 +682,6 @@ pprImportedSymbol dflags config importedLbl = case (arch,os) of -> case dynamicLinkerLabelInfo importedLbl of Just (SymbolPtr, lbl) -> vcat [ - text ".section \".toc\", \"aw\"", text ".LC_" <> pprCLabel dflags lbl <> char ':', text "\t.quad" <+> pprCLabel dflags lbl ] _ -> empty @@ -845,4 +844,3 @@ initializePicBase_x86 ArchX86 OSDarwin picReg initializePicBase_x86 _ _ _ _ = panic "initializePicBase_x86: not needed" - View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/aac19e6caa0c94e159610f124114186ee20bcdd1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/aac19e6caa0c94e159610f124114186ee20bcdd1 You're receiving 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 29 18:07:11 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Fri, 29 May 2020 14:07:11 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 9 commits: Build a threaded stage 1 if the bootstrapping GHC supports it. Message-ID: <5ed14f4f98414_6e263f9f0cbba3d82694587@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 67738db1 by Travis Whitaker at 2020-05-29T13:34:48-04:00 Build a threaded stage 1 if the bootstrapping GHC supports it. - - - - - aac19e6c by Peter Trommler at 2020-05-29T13:35:24-04:00 PPC NCG: No per-symbol .section ".toc" directives All position independent symbols are collected during code generation and emitted in one go. Prepending each symbol with a .section ".toc" directive is redundant. This patch drops the per-symbol directives leading to smaller assembler files. Fixes #18250 - - - - - 6f1b09c6 by Ben Gamari at 2020-05-29T14:06:51-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. - - - - - a59304d7 by Ben Gamari at 2020-05-29T14:06:51-04:00 users-guide: Note change in getNumProcessors in users guide - - - - - e45e0516 by Ben Gamari at 2020-05-29T14:06:51-04:00 rts: Drop compatibility shims for Windows Vista We can now assume that the thread and processor group interfaces are available. - - - - - 2999c4dc by Peter Trommler at 2020-05-29T14:06:51-04:00 PPC NCG: Fix .size directive on powerpc64 ELF v1 Thanks to Sergei Trofimovich for pointing out the issue. Fixes #18237 - - - - - d9eab84f by Andreas Klebinger at 2020-05-29T14:06:52-04:00 Optimize GHC.Utils.Monad. Many functions in this module are recursive and as such are marked loop breakers. Which means they are unlikely to get an unfolding. This is *bad*. We always want to specialize them to specific Monads. Which requires a visible unfolding at the use site. I rewrote the recursive ones from: foo f x = ... foo x' ... to foo f x = go x where go x = ... As well as giving some pragmas to make all of them available for specialization. The end result is a reduction of allocations of about -1.4% for nofib/spectral/simple/Main.hs when compiled with `-O`. ------------------------- Metric Decrease: T12425 T14683 T5631 T9233 T9675 T9961 WWRec ------------------------- - - - - - 1b722f0b by Ben Gamari at 2020-05-29T14:06:52-04:00 Windows: Bump Windows toolchain to 0.2 - - - - - 4448ba12 by Zubin Duggal at 2020-05-29T14:07:01-04:00 Simplify contexts in GHC.Iface.Ext.Ast - - - - - 18 changed files: - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Utils/Monad.hs - compiler/ghc.mk - configure.ac - docs/users_guide/8.12.1-notes.rst - docs/users_guide/using-concurrent.rst - ghc/ghc.mk - hadrian/cfg/system.config.in - hadrian/src/Expression.hs - hadrian/src/Oracles/Flag.hs - hadrian/src/Settings/Packages.hs - mk/config.mk.in - mk/get-win32-tarballs.py - rts/ghc.mk - rts/posix/OSThreads.c - rts/win32/OSThreads.c Changes: ===================================== compiler/GHC/CmmToAsm/PIC.hs ===================================== @@ -682,7 +682,6 @@ pprImportedSymbol dflags config importedLbl = case (arch,os) of -> case dynamicLinkerLabelInfo importedLbl of Just (SymbolPtr, lbl) -> vcat [ - text ".section \".toc\", \"aw\"", text ".LC_" <> pprCLabel dflags lbl <> char ':', text "\t.quad" <+> pprCLabel dflags lbl ] _ -> empty @@ -845,4 +844,3 @@ initializePicBase_x86 ArchX86 OSDarwin picReg initializePicBase_x86 _ _ _ _ = panic "initializePicBase_x86: not needed" - ===================================== compiler/GHC/CmmToAsm/PPC/Ppr.hs ===================================== @@ -86,8 +86,13 @@ pprNatCmmDecl config proc@(CmmProc top_info lbl _ (ListGraph blocks)) = pprSizeDecl :: Platform -> CLabel -> SDoc pprSizeDecl platform lbl = if osElfTarget (platformOS platform) - then text "\t.size" <+> ppr lbl <> text ", .-" <> ppr lbl + then text "\t.size" <+> prettyLbl <> text ", .-" <> codeLbl else empty + where + prettyLbl = ppr lbl + codeLbl + | platformArch platform == ArchPPC_64 ELF_V1 = char '.' <> prettyLbl + | otherwise = prettyLbl pprFunctionDescriptor :: CLabel -> SDoc pprFunctionDescriptor lab = pprGloblDecl lab ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -2,9 +2,12 @@ Main functions for .hie file generation -} {-# LANGUAGE CPP #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE UndecidableSuperClasses #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE ScopedTypeVariables #-} @@ -572,7 +575,7 @@ class ToHie a where toHie :: a -> HieM [HieAST Type] -- | Used to collect type info -class Data a => HasType a where +class HasType a where getTypeNode :: a -> HieM [HieAST Type] instance (ToHie a) => ToHie [a] where @@ -584,12 +587,6 @@ instance (ToHie a) => ToHie (Bag a) where instance (ToHie a) => ToHie (Maybe a) where toHie = maybe (pure []) toHie -instance ToHie (Context (Located NoExtField)) where - toHie _ = pure [] - -instance ToHie (TScoped NoExtField) where - toHie _ = pure [] - instance ToHie (IEContext (Located ModuleName)) where toHie (IEC c (L (RealSrcSpan span _) mname)) = do org <- ask @@ -667,9 +664,6 @@ instance ToHie (EvBindContext (Located TcEvBinds)) where ] toHie _ = pure [] -instance ToHie (EvBindContext (Located NoExtField)) where - toHie _ = pure [] - instance ToHie (Located HsWrapper) where toHie (L osp wrap) = case wrap of @@ -685,32 +679,19 @@ instance ToHie (Located HsWrapper) where concatMapM (toHie . C EvidenceVarUse . L osp) $ evVarsOfTermList a _ -> pure [] --- | Dummy instances - never called -instance ToHie (TScoped (LHsSigWcType GhcTc)) where - toHie _ = pure [] -instance ToHie (TScoped (LHsWcType GhcTc)) where - toHie _ = pure [] -instance ToHie (SigContext (LSig GhcTc)) where - toHie _ = pure [] -instance ToHie (TScoped Type) where - toHie _ = pure [] - -instance HasType (LHsBind GhcRn) where - getTypeNode (L spn bind) = makeNode bind spn +instance HiePass p => HasType (LHsBind (GhcPass p)) where + getTypeNode (L spn bind) = + case hiePass @p of + HieRn -> makeNode bind spn + HieTc -> case bind of + FunBind{fun_id = name} -> makeTypeNode bind spn (varType $ unLoc name) + _ -> makeNode bind spn -instance HasType (LHsBind GhcTc) where - getTypeNode (L spn bind) = case bind of - FunBind{fun_id = name} -> makeTypeNode bind spn (varType $ unLoc name) - _ -> makeNode bind spn - -instance HasType (Located (Pat GhcRn)) where - getTypeNode (L spn pat) = makeNode pat spn - -instance HasType (Located (Pat GhcTc)) where - getTypeNode (L spn opat) = makeTypeNode opat spn (hsPatType opat) - -instance HasType (LHsExpr GhcRn) where - getTypeNode (L spn e) = makeNode e spn +instance HiePass p => HasType (Located (Pat (GhcPass p))) where + getTypeNode (L spn pat) = + case hiePass @p of + HieRn -> makeNode pat spn + HieTc -> makeTypeNode pat spn (hsPatType pat) -- | This instance tries to construct 'HieAST' nodes which include the type of -- the expression. It is not yet possible to do this efficiently for all @@ -727,73 +708,99 @@ instance HasType (LHsExpr GhcRn) where -- expression's type is going to be expensive. -- -- See #16233 -instance HasType (LHsExpr GhcTc) where +instance HiePass p => HasType (LHsExpr (GhcPass p)) where getTypeNode e@(L spn e') = - -- Some expression forms have their type immediately available - let tyOpt = case e' of - HsLit _ l -> Just (hsLitType l) - HsOverLit _ o -> Just (overLitType o) - - HsLam _ (MG { mg_ext = groupTy }) -> Just (matchGroupType groupTy) - HsLamCase _ (MG { mg_ext = groupTy }) -> Just (matchGroupType groupTy) - HsCase _ _ (MG { mg_ext = groupTy }) -> Just (mg_res_ty groupTy) - - ExplicitList ty _ _ -> Just (mkListTy ty) - ExplicitSum ty _ _ _ -> Just (mkSumTy ty) - HsDo ty _ _ -> Just ty - HsMultiIf ty _ -> Just ty - - _ -> Nothing - - in - case tyOpt of - Just t -> makeTypeNode e' spn t - Nothing - | skipDesugaring e' -> fallback - | otherwise -> do - hs_env <- lift $ lift $ Hsc $ \e w -> return (e,w) - (_,mbe) <- liftIO $ deSugarExpr hs_env e - maybe fallback (makeTypeNode e' spn . exprType) mbe - where - fallback = makeNode e' spn - - matchGroupType :: MatchGroupTc -> Type - matchGroupType (MatchGroupTc args res) = mkVisFunTys args res - - -- | Skip desugaring of these expressions for performance reasons. - -- - -- See impact on Haddock output (esp. missing type annotations or links) - -- before marking more things here as 'False'. See impact on Haddock - -- performance before marking more things as 'True'. - skipDesugaring :: HsExpr GhcTc -> Bool - skipDesugaring e = case e of - HsVar{} -> False - HsUnboundVar{} -> False - HsConLikeOut{} -> False - HsRecFld{} -> False - HsOverLabel{} -> False - HsIPVar{} -> False - XExpr (HsWrap{}) -> False - _ -> True - -instance ( ToHie (Context (Located (IdP (GhcPass a)))) - , ToHie (MatchGroup (GhcPass a) (LHsExpr (GhcPass a))) - , ToHie (PScoped (LPat (GhcPass a))) - , ToHie (GRHSs (GhcPass a) (LHsExpr (GhcPass a))) - , ToHie (LHsExpr (GhcPass a)) - , ToHie (Located (PatSynBind (GhcPass a) (GhcPass a))) - , HasType (LHsBind (GhcPass a)) - , ModifyState (IdP (GhcPass a)) - , Data (HsBind (GhcPass a)) - , IsPass a - ) => ToHie (BindContext (LHsBind (GhcPass a))) where + case hiePass @p of + HieRn -> makeNode e' spn + HieTc -> + -- Some expression forms have their type immediately available + let tyOpt = case e' of + HsLit _ l -> Just (hsLitType l) + HsOverLit _ o -> Just (overLitType o) + + HsLam _ (MG { mg_ext = groupTy }) -> Just (matchGroupType groupTy) + HsLamCase _ (MG { mg_ext = groupTy }) -> Just (matchGroupType groupTy) + HsCase _ _ (MG { mg_ext = groupTy }) -> Just (mg_res_ty groupTy) + + ExplicitList ty _ _ -> Just (mkListTy ty) + ExplicitSum ty _ _ _ -> Just (mkSumTy ty) + HsDo ty _ _ -> Just ty + HsMultiIf ty _ -> Just ty + + _ -> Nothing + + in + case tyOpt of + Just t -> makeTypeNode e' spn t + Nothing + | skipDesugaring e' -> fallback + | otherwise -> do + hs_env <- lift $ lift $ Hsc $ \e w -> return (e,w) + (_,mbe) <- liftIO $ deSugarExpr hs_env e + maybe fallback (makeTypeNode e' spn . exprType) mbe + where + fallback = makeNode e' spn + + matchGroupType :: MatchGroupTc -> Type + matchGroupType (MatchGroupTc args res) = mkVisFunTys args res + + -- | Skip desugaring of these expressions for performance reasons. + -- + -- See impact on Haddock output (esp. missing type annotations or links) + -- before marking more things here as 'False'. See impact on Haddock + -- performance before marking more things as 'True'. + skipDesugaring :: HsExpr GhcTc -> Bool + skipDesugaring e = case e of + HsVar{} -> False + HsUnboundVar{} -> False + HsConLikeOut{} -> False + HsRecFld{} -> False + HsOverLabel{} -> False + HsIPVar{} -> False + XExpr (HsWrap{}) -> False + _ -> True + +data HiePassEv p where + HieRn :: HiePassEv 'Renamed + HieTc :: HiePassEv 'Typechecked + +class ( IsPass p + , HiePass (NoGhcTcPass p) + , ModifyState (IdGhcP p) + , Data (GRHS (GhcPass p) (Located (HsExpr (GhcPass p)))) + , Data (HsExpr (GhcPass p)) + , Data (HsCmd (GhcPass p)) + , Data (AmbiguousFieldOcc (GhcPass p)) + , Data (HsCmdTop (GhcPass p)) + , Data (GRHS (GhcPass p) (Located (HsCmd (GhcPass p)))) + , Data (HsSplice (GhcPass p)) + , Data (HsLocalBinds (GhcPass p)) + , Data (FieldOcc (GhcPass p)) + , Data (HsTupArg (GhcPass p)) + , Data (IPBind (GhcPass p)) + , ToHie (Context (Located (IdGhcP p))) + , ToHie (RFContext (Located (AmbiguousFieldOcc (GhcPass p)))) + , ToHie (RFContext (Located (FieldOcc (GhcPass p)))) + , ToHie (TScoped (LHsWcType (GhcPass (NoGhcTcPass p)))) + , ToHie (TScoped (LHsSigWcType (GhcPass (NoGhcTcPass p)))) + , HasRealDataConName (GhcPass p) + ) + => HiePass p where + hiePass :: HiePassEv p + +instance HiePass 'Renamed where + hiePass = HieRn +instance HiePass 'Typechecked where + hiePass = HieTc + +instance HiePass p => ToHie (BindContext (LHsBind (GhcPass p))) where toHie (BC context scope b@(L span bind)) = concatM $ getTypeNode b : case bind of FunBind{fun_id = name, fun_matches = matches, fun_ext = wrap} -> [ toHie $ C (ValBind context scope $ getRealSpan span) name , toHie matches - , case ghcPass @a of - GhcTc -> toHie $ L span wrap + , case hiePass @p of + HieTc -> toHie $ L span wrap _ -> pure [] ] PatBind{pat_lhs = lhs, pat_rhs = rhs} -> @@ -822,25 +829,22 @@ instance ( ToHie (Context (Located (IdP (GhcPass a)))) [ toHie $ L span psb -- PatSynBinds only occur at the top level ] -instance ( ToHie (LMatch a body) - ) => ToHie (MatchGroup a body) where +instance ( HiePass p + , ToHie (Located body) + , Data body + ) => ToHie (MatchGroup (GhcPass p) (Located body)) where toHie mg = case mg of MG{ mg_alts = (L span alts) , mg_origin = origin} -> local (setOrigin origin) $ concatM [ locOnly span , toHie alts ] - XMatchGroup _ -> pure [] setOrigin :: Origin -> NodeOrigin -> NodeOrigin setOrigin FromSource _ = SourceInfo setOrigin Generated _ = GeneratedInfo -instance ( ToHie (Context (Located (IdP a))) - , ToHie (PScoped (LPat a)) - , ToHie (HsPatSynDir a) - , (a ~ GhcPass p) - ) => ToHie (Located (PatSynBind a a)) where +instance HiePass p => ToHie (Located (PatSynBind (GhcPass p) (GhcPass p))) where toHie (L sp psb) = concatM $ case psb of PSB{psb_id=var, psb_args=dets, psb_def=pat, psb_dir=dir} -> [ toHie $ C (Decl PatSynDec $ getRealSpan sp) var @@ -865,50 +869,39 @@ instance ( ToHie (Context (Located (IdP a))) toBind (InfixCon a b) = InfixCon (C Use a) (C Use b) toBind (RecCon r) = RecCon $ map (PSC detSpan) r -instance ( ToHie (MatchGroup a (LHsExpr a)) - ) => ToHie (HsPatSynDir a) where +instance HiePass p => ToHie (HsPatSynDir (GhcPass p)) where toHie dir = case dir of ExplicitBidirectional mg -> toHie mg _ -> pure [] -instance ( a ~ GhcPass p - , ToHie body - , ToHie (HsMatchContext (NoGhcTc a)) - , ToHie (PScoped (LPat a)) - , ToHie (GRHSs a body) - , Data (Match a body) - ) => ToHie (LMatch (GhcPass p) body) where - toHie (L span m ) = concatM $ makeNode m span : case m of +instance ( HiePass p + , Data body + , ToHie (Located body) + ) => ToHie (LMatch (GhcPass p) (Located body)) where + toHie (L span m ) = concatM $ node : case m of Match{m_ctxt=mctx, m_pats = pats, m_grhss = grhss } -> [ toHie mctx , let rhsScope = mkScope $ grhss_span grhss in toHie $ patScopes Nothing rhsScope NoScope pats , toHie grhss ] + where + node = case hiePass @p of + HieTc -> makeNode m span + HieRn -> makeNode m span -instance ( ToHie (Context (Located (IdP a))) - ) => ToHie (HsMatchContext a) where +instance HiePass p => ToHie (HsMatchContext (GhcPass p)) where toHie (FunRhs{mc_fun=name}) = toHie $ C MatchBind name toHie (StmtCtxt a) = toHie a toHie _ = pure [] -instance ( ToHie (HsMatchContext a) - ) => ToHie (HsStmtContext a) where +instance HiePass p => ToHie (HsStmtContext (GhcPass p)) where toHie (PatGuard a) = toHie a toHie (ParStmtCtxt a) = toHie a toHie (TransStmtCtxt a) = toHie a toHie _ = pure [] -instance ( a ~ GhcPass p - , IsPass p - , ToHie (Context (Located (IdP a))) - , ToHie (RContext (HsRecFields a (PScoped (LPat a)))) - , ToHie (LHsExpr a) - , ToHie (TScoped (LHsSigWcType a)) - , HasType (LPat a) - , Data (HsSplice a) - , IsPass p - ) => ToHie (PScoped (Located (Pat (GhcPass p)))) where +instance HiePass p => ToHie (PScoped (Located (Pat (GhcPass p)))) where toHie (PS rsp scope pscope lpat@(L ospan opat)) = concatM $ getTypeNode lpat : case opat of WildPat _ -> @@ -941,25 +934,25 @@ instance ( a ~ GhcPass p SumPat _ pat _ _ -> [ toHie $ PS rsp scope pscope pat ] - ConPat {pat_con = con, pat_args = dets, pat_con_ext = ext}-> - [ case ghcPass @p of - GhcPs -> toHie $ C Use $ con - GhcRn -> toHie $ C Use $ con - GhcTc -> toHie $ C Use $ fmap conLikeName con - , toHie $ contextify dets - , case ghcPass @p of - GhcTc -> - let ev_binds = cpt_binds ext + ConPat {pat_con = con, pat_args = dets, pat_con_ext = ext} -> + case hiePass @p of + HieTc -> + [ toHie $ C Use $ fmap conLikeName con + , toHie $ contextify dets + , let ev_binds = cpt_binds ext ev_vars = cpt_dicts ext wrap = cpt_wrap ext evscope = mkScope ospan `combineScopes` scope `combineScopes` pscope - in concatM [ toHie $ EvBindContext scope rsp $ L ospan ev_binds - , toHie $ L ospan wrap - , toHie $ map (C (EvidenceVarBind EvPatternBind evscope rsp) - . L ospan) ev_vars - ] - _ -> pure [] - ] + in concatM [ toHie $ EvBindContext scope rsp $ L ospan ev_binds + , toHie $ L ospan wrap + , toHie $ map (C (EvidenceVarBind EvPatternBind evscope rsp) + . L ospan) ev_vars + ] + ] + HieRn -> + [ toHie $ C Use con + , toHie $ contextify dets + ] ViewPat _ expr pat -> [ toHie expr , toHie $ PS rsp scope pscope pat @@ -976,26 +969,26 @@ instance ( a ~ GhcPass p ] SigPat _ pat sig -> [ toHie $ PS rsp scope pscope pat - , let cscope = mkLScope pat in - case ghcPass @p of - GhcPs -> pure [] - GhcTc -> pure [] - GhcRn -> + , case hiePass @p of + HieTc -> + let cscope = mkLScope pat in toHie $ TS (ResolvedScopes [cscope, scope, pscope]) - sig - ] - XPat e -> case ghcPass @p of + sig + HieRn -> pure [] + ] + XPat e -> + case hiePass @p of + HieTc -> + let CoPat wrap pat _ = e + in [ toHie $ L ospan wrap + , toHie $ PS rsp scope pscope $ (L ospan pat) + ] #if __GLASGOW_HASKELL__ < 811 - GhcPs -> noExtCon e - GhcRn -> noExtCon e + HieRn -> [] #endif - GhcTc -> - [ toHie $ L ospan wrap - , toHie $ PS rsp scope pscope $ (L ospan pat :: LPat a) - ] - where - CoPat wrap pat _ = e where + contextify :: a ~ LPat (GhcPass p) => HsConDetails a (HsRecFields (GhcPass p) a) + -> HsConDetails (PScoped a) (RContext (HsRecFields (GhcPass p) (PScoped a))) contextify (PrefixCon args) = PrefixCon $ patScopes rsp scope pscope args contextify (InfixCon a b) = InfixCon a' b' where [a', b'] = patScopes rsp scope pscope [a,b] @@ -1006,6 +999,7 @@ 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 $ [ bindingsOnly $ map (C $ TyVarBind (mkScope span) sc) (wcs++tvs) @@ -1013,48 +1007,31 @@ instance ToHie (TScoped (HsPatSigType GhcRn)) where ] -- See Note [Scoping Rules for SigPat] -instance ( ToHie body - , ToHie (LGRHS a body) - , ToHie (RScoped (LHsLocalBinds a)) - ) => ToHie (GRHSs a body) where +instance ( ToHie (Located body) + , HiePass p + , Data body + ) => ToHie (GRHSs (GhcPass p) (Located body)) where toHie grhs = concatM $ case grhs of GRHSs _ grhss binds -> [ toHie grhss , toHie $ RS (mkScope $ grhss_span grhs) binds ] - XGRHSs _ -> [] instance ( ToHie (Located body) - , ToHie (RScoped (GuardLStmt (GhcPass a))) - , Data (GRHS (GhcPass a) (Located body)) + , HiePass a + , Data body ) => ToHie (LGRHS (GhcPass a) (Located body)) where - toHie (L span g) = concatM $ makeNode g span : case g of + toHie (L span g) = concatM $ node : case g of GRHS _ guards body -> [ toHie $ listScopes (mkLScope body) guards , toHie body ] + where + node = case hiePass @a of + HieRn -> makeNode g span + HieTc -> makeNode g span -instance ( a ~ GhcPass p - , ToHie (Context (Located (IdP a))) - , HasType (LHsExpr a) - , ToHie (PScoped (LPat a)) - , ToHie (MatchGroup a (LHsExpr a)) - , ToHie (LGRHS a (LHsExpr a)) - , ToHie (RContext (HsRecordBinds a)) - , ToHie (RFContext (Located (AmbiguousFieldOcc a))) - , ToHie (ArithSeqInfo a) - , ToHie (LHsCmdTop a) - , ToHie (RScoped (GuardLStmt a)) - , ToHie (RScoped (LHsLocalBinds a)) - , ToHie (TScoped (LHsWcType (NoGhcTc a))) - , ToHie (TScoped (LHsSigWcType (NoGhcTc a))) - , Data (HsExpr a) - , Data (HsSplice a) - , Data (HsTupArg a) - , Data (AmbiguousFieldOcc a) - , (HasRealDataConName a) - , IsPass p - ) => ToHie (LHsExpr (GhcPass p)) where +instance HiePass p => ToHie (LHsExpr (GhcPass p)) where toHie e@(L mspan oexpr) = concatM $ getTypeNode e : case oexpr of HsVar _ (L _ var) -> [ toHie $ C Use (L mspan var) @@ -1135,7 +1112,7 @@ instance ( a ~ GhcPass p [ toHie exprs ] RecordCon {rcon_ext = mrealcon, rcon_con_name = name, rcon_flds = binds} -> - [ toHie $ C Use (getRealDataCon @a mrealcon name) + [ toHie $ C Use (getRealDataCon @(GhcPass p) mrealcon name) -- See Note [Real DataCon Name] , toHie $ RC RecFieldAssign $ binds ] @@ -1186,30 +1163,20 @@ instance ( a ~ GhcPass p -> [ toHie $ L mspan a , toHie (L mspan w) ] - | otherwise - -> [] + | otherwise -> [] -instance ( a ~ GhcPass p - , ToHie (LHsExpr a) - , Data (HsTupArg a) - ) => ToHie (LHsTupArg (GhcPass p)) where +instance HiePass p => ToHie (LHsTupArg (GhcPass p)) where toHie (L span arg) = concatM $ makeNode arg span : case arg of Present _ expr -> [ toHie expr ] Missing _ -> [] -instance ( a ~ GhcPass p - , ToHie (PScoped (LPat a)) - , ToHie (LHsExpr a) - , ToHie (SigContext (LSig a)) - , ToHie (RScoped (LHsLocalBinds a)) - , ToHie (RScoped (ApplicativeArg a)) - , ToHie (Located body) - , Data (StmtLR a a (Located body)) - , Data (StmtLR a a (Located (HsExpr a))) +instance ( ToHie (Located body) + , Data body + , HiePass p ) => ToHie (RScoped (LStmt (GhcPass p) (Located body))) where - toHie (RS scope (L span stmt)) = concatM $ makeNode stmt span : case stmt of + toHie (RS scope (L span stmt)) = concatM $ node : case stmt of LastStmt _ body _ _ -> [ toHie body ] @@ -1239,47 +1206,36 @@ instance ( a ~ GhcPass p RecStmt {recS_stmts = stmts} -> [ toHie $ map (RS $ combineScopes scope (mkScope span)) stmts ] + where + node = case hiePass @p of + HieTc -> makeNode stmt span + HieRn -> makeNode stmt span -instance ( ToHie (LHsExpr a) - , ToHie (PScoped (LPat a)) - , ToHie (BindContext (LHsBind a)) - , ToHie (SigContext (LSig a)) - , ToHie (RScoped (HsValBindsLR a a)) - , ToHie (EvBindContext (Located (XIPBinds a))) - , ToHie (RScoped (LIPBind a)) - , Data (HsLocalBinds a) - ) => ToHie (RScoped (LHsLocalBinds a)) where +instance HiePass p => ToHie (RScoped (LHsLocalBinds (GhcPass p))) where toHie (RS scope (L sp binds)) = concatM $ makeNode binds sp : case binds of EmptyLocalBinds _ -> [] HsIPBinds _ ipbinds -> case ipbinds of IPBinds evbinds xs -> let sc = combineScopes scope $ mkScope sp in - [ toHie $ EvBindContext sc (getRealSpan sp) $ L sp evbinds + [ case hiePass @p of + HieTc -> toHie $ EvBindContext sc (getRealSpan sp) $ L sp evbinds + HieRn -> pure [] , toHie $ map (RS sc) xs ] - XHsIPBinds _ -> [] HsValBinds _ valBinds -> [ toHie $ RS (combineScopes scope $ mkScope sp) valBinds ] - XHsLocalBindsLR _ -> [] -instance ( ToHie (LHsExpr a) - , ToHie (Context (Located (IdP a))) - , Data (IPBind a) - ) => ToHie (RScoped (LIPBind a)) where +instance HiePass p => ToHie (RScoped (LIPBind (GhcPass p))) where toHie (RS scope (L sp bind)) = concatM $ makeNode bind sp : case bind of IPBind _ (Left _) expr -> [toHie expr] IPBind _ (Right v) expr -> [ toHie $ C (EvidenceVarBind EvImplicitBind scope (getRealSpan sp)) - $ L sp v + $ L sp v , toHie expr ] - XIPBind _ -> [] -instance ( ToHie (BindContext (LHsBind a)) - , ToHie (SigContext (LSig a)) - , ToHie (RScoped (XXValBindsLR a a)) - ) => ToHie (RScoped (HsValBindsLR a a)) where +instance HiePass p => ToHie (RScoped (HsValBindsLR (GhcPass p) (GhcPass p))) where toHie (RS sc v) = concatM $ case v of ValBinds _ binds sigs -> [ toHie $ fmap (BC RegularBind sc) binds @@ -1287,26 +1243,19 @@ instance ( ToHie (BindContext (LHsBind a)) ] XValBindsLR x -> [ toHie $ RS sc x ] -instance ToHie (RScoped (NHsValBindsLR GhcTc)) where - toHie (RS sc (NValBinds binds sigs)) = concatM $ - [ toHie (concatMap (map (BC RegularBind sc) . bagToList . snd) binds) - , toHie $ fmap (SC (SI BindSig Nothing)) sigs - ] -instance ToHie (RScoped (NHsValBindsLR GhcRn)) where +instance HiePass p => ToHie (RScoped (NHsValBindsLR (GhcPass p))) where toHie (RS sc (NValBinds binds sigs)) = concatM $ [ toHie (concatMap (map (BC RegularBind sc) . bagToList . snd) binds) , toHie $ fmap (SC (SI BindSig Nothing)) sigs ] -instance ( ToHie (RContext (LHsRecField a arg)) - ) => ToHie (RContext (HsRecFields a arg)) where +instance ( ToHie arg , HasLoc arg , Data arg + , HiePass p ) => ToHie (RContext (HsRecFields (GhcPass p) arg)) where toHie (RC c (HsRecFields fields _)) = toHie $ map (RC c) fields instance ( ToHie (RFContext (Located label)) - , ToHie arg - , HasLoc arg + , ToHie arg , HasLoc arg , Data arg , Data label - , Data arg ) => ToHie (RContext (LHsRecField' label arg)) where toHie (RC c (L span recfld)) = concatM $ makeNode recfld span : case recfld of HsRecField label expr _ -> @@ -1349,16 +1298,7 @@ instance ToHie (RFContext (Located (AmbiguousFieldOcc GhcTc))) where in [ toHie $ C (RecField c rhs) (L nspan var') ] -instance ( a ~ GhcPass p - , ToHie (PScoped (LPat a)) - , ToHie (BindContext (LHsBind a)) - , ToHie (LHsExpr a) - , ToHie (SigContext (LSig a)) - , ToHie (RScoped (HsValBindsLR a a)) - , ToHie (RScoped (ExprLStmt a)) - , Data (StmtLR a a (Located (HsExpr a))) - , Data (HsLocalBinds a) - ) => ToHie (RScoped (ApplicativeArg (GhcPass p))) where +instance HiePass p => ToHie (RScoped (ApplicativeArg (GhcPass p))) where toHie (RS sc (ApplicativeArgOne _ pat expr _)) = concatM [ toHie $ PS Nothing sc NoScope pat , toHie expr @@ -1373,29 +1313,13 @@ instance (ToHie arg, ToHie rec) => ToHie (HsConDetails arg rec) where toHie (RecCon rec) = toHie rec toHie (InfixCon a b) = concatM [ toHie a, toHie b] -instance ( ToHie (LHsCmd a) - , Data (HsCmdTop a) - ) => ToHie (LHsCmdTop a) where +instance HiePass p => ToHie (LHsCmdTop (GhcPass p)) where toHie (L span top) = concatM $ makeNode top span : case top of HsCmdTop _ cmd -> [ toHie cmd ] - XCmdTop _ -> [] - -instance ( a ~ GhcPass p - , ToHie (PScoped (LPat a)) - , ToHie (BindContext (LHsBind a)) - , ToHie (LHsExpr a) - , ToHie (MatchGroup a (LHsCmd a)) - , ToHie (SigContext (LSig a)) - , ToHie (RScoped (HsValBindsLR a a)) - , ToHie (RScoped (LHsLocalBinds a)) - , Data (HsCmd a) - , Data (HsCmdTop a) - , Data (StmtLR a a (Located (HsCmd a))) - , Data (HsLocalBinds a) - , Data (StmtLR a a (Located (HsExpr a))) - ) => ToHie (LHsCmd (GhcPass p)) where + +instance HiePass p => ToHie (LHsCmd (GhcPass p)) where toHie (L span cmd) = concatM $ makeNode cmd span : case cmd of HsCmdArrApp _ a b _ _ -> [ toHie a @@ -1658,48 +1582,51 @@ instance ToHie (StandaloneKindSig GhcRn) where , toHie $ TS (ResolvedScopes []) typ ] -instance ToHie (SigContext (LSig GhcRn)) where - toHie (SC (SI styp msp) (L sp sig)) = concatM $ makeNode sig sp : case sig of - TypeSig _ names typ -> - [ toHie $ map (C TyDecl) names - , toHie $ TS (UnresolvedScope (map unLoc names) Nothing) typ - ] - PatSynSig _ names typ -> - [ toHie $ map (C TyDecl) names - , toHie $ TS (UnresolvedScope (map unLoc names) Nothing) typ - ] - ClassOpSig _ _ names typ -> - [ case styp of - ClassSig -> toHie $ map (C $ ClassTyDecl $ getRealSpan sp) names - _ -> toHie $ map (C $ TyDecl) names - , toHie $ TS (UnresolvedScope (map unLoc names) msp) typ - ] - IdSig _ _ -> [] - FixSig _ fsig -> - [ toHie $ L sp fsig - ] - InlineSig _ name _ -> - [ toHie $ (C Use) name - ] - SpecSig _ name typs _ -> - [ toHie $ (C Use) name - , toHie $ map (TS (ResolvedScopes [])) typs - ] - SpecInstSig _ _ typ -> - [ toHie $ TS (ResolvedScopes []) typ - ] - MinimalSig _ _ form -> - [ toHie form - ] - SCCFunSig _ _ name mtxt -> - [ toHie $ (C Use) name - , maybe (pure []) (locOnly . getLoc) mtxt - ] - CompleteMatchSig _ _ (L ispan names) typ -> - [ locOnly ispan - , toHie $ map (C Use) names - , toHie $ fmap (C Use) typ - ] +instance HiePass p => ToHie (SigContext (LSig (GhcPass p))) where + toHie (SC (SI styp msp) (L sp sig)) = + case hiePass @p of + HieTc -> pure [] + HieRn -> concatM $ makeNode sig sp : case sig of + TypeSig _ names typ -> + [ toHie $ map (C TyDecl) names + , toHie $ TS (UnresolvedScope (map unLoc names) Nothing) typ + ] + PatSynSig _ names typ -> + [ toHie $ map (C TyDecl) names + , toHie $ TS (UnresolvedScope (map unLoc names) Nothing) typ + ] + ClassOpSig _ _ names typ -> + [ case styp of + ClassSig -> toHie $ map (C $ ClassTyDecl $ getRealSpan sp) names + _ -> toHie $ map (C $ TyDecl) names + , toHie $ TS (UnresolvedScope (map unLoc names) msp) typ + ] + IdSig _ _ -> [] + FixSig _ fsig -> + [ toHie $ L sp fsig + ] + InlineSig _ name _ -> + [ toHie $ (C Use) name + ] + SpecSig _ name typs _ -> + [ toHie $ (C Use) name + , toHie $ map (TS (ResolvedScopes [])) typs + ] + SpecInstSig _ _ typ -> + [ toHie $ TS (ResolvedScopes []) typ + ] + MinimalSig _ _ form -> + [ toHie form + ] + SCCFunSig _ _ name mtxt -> + [ toHie $ (C Use) name + , maybe (pure []) (locOnly . getLoc) mtxt + ] + CompleteMatchSig _ _ (L ispan names) typ -> + [ locOnly ispan + , toHie $ map (C Use) names + , toHie $ fmap (C Use) typ + ] instance ToHie (LHsType GhcRn) where toHie x = toHie $ TS (ResolvedScopes []) x @@ -1863,11 +1790,7 @@ instance ToHie (LBooleanFormula (Located Name)) where instance ToHie (Located HsIPName) where toHie (L span e) = makeNode e span -instance ( a ~ GhcPass p - , ToHie (LHsExpr a) - , Data (HsSplice a) - , IsPass p - ) => ToHie (Located (HsSplice a)) where +instance HiePass p => ToHie (Located (HsSplice (GhcPass p))) where toHie (L span sp) = concatM $ makeNode sp span : case sp of HsTypedSplice _ _ _ expr -> [ toHie expr ===================================== compiler/GHC/Utils/Monad.hs ===================================== @@ -138,22 +138,31 @@ mapAndUnzip5M :: Monad m => (a -> m (b,c,d,e,f)) -> [a] -> m ([b],[c],[d],[e],[f -- See Note [Inline @mapAndUnzipNM@ functions] above. mapAndUnzip5M f xs = unzip5 <$> traverse f xs +-- TODO: mapAccumLM is used in many places. Surely most of +-- these don't actually want to be lazy. We should add a strict +-- variant and use it where appropriate. + -- | Monadic version of mapAccumL mapAccumLM :: Monad m => (acc -> x -> m (acc, y)) -- ^ combining function -> acc -- ^ initial state -> [x] -- ^ inputs -> m (acc, [y]) -- ^ final state, outputs -mapAccumLM _ s [] = return (s, []) -mapAccumLM f s (x:xs) = do - (s1, x') <- f s x - (s2, xs') <- mapAccumLM f s1 xs - return (s2, x' : xs') +mapAccumLM f s xs = + go s xs + where + go s (x:xs) = do + (s1, x') <- f s x + (s2, xs') <- go s1 xs + return (s2, x' : xs') + go s [] = return (s, []) -- | Monadic version of mapSnd mapSndM :: Monad m => (b -> m c) -> [(a,b)] -> m [(a,c)] -mapSndM _ [] = return [] -mapSndM f ((a,b):xs) = do { c <- f b; rs <- mapSndM f xs; return ((a,c):rs) } +mapSndM f xs = go xs + where + go [] = return [] + go ((a,b):xs) = do { c <- f b; rs <- go xs; return ((a,c):rs) } -- | Monadic version of concatMap concatMapM :: Monad m => (a -> m [b]) -> [a] -> m [b] @@ -176,15 +185,19 @@ fmapEitherM _ fr (Right b) = fr b >>= (return . Right) -- | Monadic version of 'any', aborts the computation at the first @True@ value anyM :: Monad m => (a -> m Bool) -> [a] -> m Bool -anyM _ [] = return False -anyM f (x:xs) = do b <- f x +anyM f xs = go xs + where + go [] = return False + go (x:xs) = do b <- f x if b then return True - else anyM f xs + else go xs -- | Monad version of 'all', aborts the computation at the first @False@ value allM :: Monad m => (a -> m Bool) -> [a] -> m Bool -allM _ [] = return True -allM f (b:bs) = (f b) >>= (\bv -> if bv then allM f bs else return False) +allM f bs = go bs + where + go [] = return True + go (b:bs) = (f b) >>= (\bv -> if bv then go bs else return False) -- | Monadic version of or orM :: Monad m => m Bool -> m Bool -> m Bool ===================================== compiler/ghc.mk ===================================== @@ -194,6 +194,12 @@ ifeq "$(GhcThreaded)" "YES" compiler_stage2_CONFIGURE_OPTS += --ghc-option=-optc-DTHREADED_RTS endif +# If the bootstrapping GHC supplies the threaded RTS, then we can have a +# threaded stage 1 too. +ifeq "$(GhcThreadedRts)" "YES" +compiler_stage1_CONFIGURE_OPTS += --ghc-option=-optc-DTHREADED_RTS +endif + ifeq "$(GhcWithNativeCodeGen)" "YES" compiler_stage1_CONFIGURE_OPTS += --flags=ncg compiler_stage2_CONFIGURE_OPTS += --flags=ncg ===================================== configure.ac ===================================== @@ -124,6 +124,9 @@ AC_ARG_VAR(CC_STAGE0, [C compiler command (bootstrap)]) AC_ARG_VAR(LD_STAGE0, [Linker command (bootstrap)]) AC_ARG_VAR(AR_STAGE0, [Archive command (bootstrap)]) +dnl RTS ways supplied by the bootstrapping compiler. +AC_ARG_VAR(RTS_WAYS_STAGE0, [RTS ways]) + if test "$WithGhc" != ""; then FPTOOLS_GHC_VERSION([GhcVersion], [GhcMajVersion], [GhcMinVersion], [GhcPatchLevel])dnl @@ -151,6 +154,17 @@ if test "$WithGhc" != ""; then fi BOOTSTRAPPING_GHC_INFO_FIELD([AR_OPTS_STAGE0],[ar flags]) BOOTSTRAPPING_GHC_INFO_FIELD([ArSupportsAtFile_STAGE0],[ar supports at file]) + BOOTSTRAPPING_GHC_INFO_FIELD([RTS_WAYS_STAGE0],[RTS ways]) + + dnl Check whether or not the bootstrapping GHC has a threaded RTS. This + dnl determines whether or not we can have a threaded stage 1. + dnl See Note [Linking ghc-bin against threaded stage0 RTS] in + dnl hadrian/src/Settings/Packages.hs for details. + if echo ${RTS_WAYS_STAGE0} | grep '.*thr.*' 2>&1 >/dev/null; then + AC_SUBST(GhcThreadedRts, YES) + else + AC_SUBST(GhcThreadedRts, NO) + fi fi dnl ** Must have GHC to build GHC @@ -964,7 +978,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 @@ -1454,6 +1468,7 @@ Configure completed successfully. echo "\ Bootstrapping using : $WithGhc which is version : $GhcVersion + with threaded RTS? : $GhcThreadedRts " if test "x$CcLlvmBackend" = "xYES"; then ===================================== docs/users_guide/8.12.1-notes.rst ===================================== @@ -17,7 +17,7 @@ Highlights digit improvements in runtime for inner loops. In the mean this improved runtime by about 0.8%. For details - see ticket #17823. + see ticket :ghc-ticket:`17823`. Full details ------------ @@ -95,7 +95,7 @@ Language effectively allows users to choose which variables can or can't be instantiated through visible type application. More information can be found here: :ref:`Manually-defining-inferred-variables`. - + Compiler ~~~~~~~~ @@ -105,11 +105,18 @@ 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) + escaping spaces in file names with a backslash. (:ghc-ticket:`18027`) Runtime system ~~~~~~~~~~~~~~ +- :rts-flag:`-N` without a count now tries to respect the number of processors + in the process's affinity mask, making GHC's behavior more predictable in + containerized settings (:ghc-ticket:`14781`). + +- Support for Windows Vista has been dropped. GHC-compiled programs now require + Windows 7 or later. + Template Haskell ~~~~~~~~~~~~~~~~ ===================================== docs/users_guide/using-concurrent.rst ===================================== @@ -111,6 +111,7 @@ There are two ways to run a program on multiple processors: call use the RTS :rts-flag:`-N ⟨x⟩` options. .. rts-flag:: -N ⟨x⟩ + -N -maxN ⟨x⟩ Use ⟨x⟩ simultaneous threads when running the program. ===================================== ghc/ghc.mk ===================================== @@ -66,8 +66,15 @@ else ghc_stage2_CONFIGURE_OPTS += -f-threaded ghc_stage3_CONFIGURE_OPTS += -f-threaded endif -# Stage-0 compiler isn't guaranteed to have a threaded RTS. + +# If stage 0 supplies a threaded RTS, we can use it for stage 1. +# See Note [Linking ghc-bin against threaded stage0 RTS] in +# hadrian/src/Settings/Packages.hs for details. +ifeq "$(GhcThreadedRts)" "YES" +ghc_stage1_MORE_HC_OPTS += -threaded +else ghc_stage1_CONFIGURE_OPTS += -f-threaded +endif ifeq "$(GhcProfiled)" "YES" ghc_stage2_PROGRAM_WAY = p ===================================== hadrian/cfg/system.config.in ===================================== @@ -79,6 +79,8 @@ ghc-major-version = @GhcMajVersion@ ghc-minor-version = @GhcMinVersion@ ghc-patch-level = @GhcPatchLevel@ +bootstrap-threaded-rts = @GhcThreadedRts@ + supports-this-unit-id = @SUPPORTS_THIS_UNIT_ID@ project-name = @ProjectName@ ===================================== hadrian/src/Expression.hs ===================================== @@ -6,8 +6,9 @@ module Expression ( expr, exprIO, arg, remove, -- ** Predicates - (?), stage, stage0, stage1, stage2, notStage0, package, notPackage, - packageOneOf, libraryPackage, builder, way, input, inputs, output, outputs, + (?), stage, stage0, stage1, stage2, notStage0, threadedBootstrapper, + package, notPackage, packageOneOf, libraryPackage, builder, way, input, + inputs, output, outputs, -- ** Evaluation interpret, interpretInContext, @@ -26,6 +27,7 @@ import Base import Builder import Context hiding (stage, package, way) import Expression.Type +import Oracles.Flag import Hadrian.Expression hiding (Expr, Predicate, Args) import Hadrian.Haskell.Cabal.Type import Hadrian.Oracles.Cabal @@ -86,6 +88,19 @@ instance BuilderPredicate a => BuilderPredicate (FilePath -> a) where way :: Way -> Predicate way w = (w ==) <$> getWay +{- +Note [Stage Names] +~~~~~~~~~~~~~~~~~~ + +Code referring to specific stages can be a bit tricky. In Hadrian, the stages +have the same names they carried in the autoconf build system, but they are +often referred to by the stage used to construct them. For example, the stage 1 +artifacts will be placed in _build/stage0, because they are constructed by the +stage 0 compiler. The stage predicates in this module behave the same way, +'stage0' will return 'True' while stage 0 is being used to build the stage 1 +compiler. +-} + -- | Is the build currently in stage 0? stage0 :: Predicate stage0 = stage Stage0 @@ -102,6 +117,13 @@ stage2 = stage Stage2 notStage0 :: Predicate notStage0 = notM stage0 +-- | Whether or not the bootstrapping compiler provides a threaded RTS. We need +-- to know this when building stage 1, since stage 1 links against the +-- compiler's RTS ways. See Note [Linking ghc-bin against threaded stage0 RTS] +-- in Settings.Packages for details. +threadedBootstrapper :: Predicate +threadedBootstrapper = expr (flag BootstrapThreadedRts) + -- | Is a certain package /not/ built right now? notPackage :: Package -> Predicate notPackage = notM . package ===================================== hadrian/src/Oracles/Flag.hs ===================================== @@ -24,25 +24,27 @@ data Flag = ArSupportsAtFile | WithLibnuma | HaveLibMingwEx | UseSystemFfi + | BootstrapThreadedRts -- Note, if a flag is set to empty string we treat it as set to NO. This seems -- fragile, but some flags do behave like this. flag :: Flag -> Action Bool flag f = do let key = case f of - ArSupportsAtFile -> "ar-supports-at-file" - CrossCompiling -> "cross-compiling" - CcLlvmBackend -> "cc-llvm-backend" - GhcUnregisterised -> "ghc-unregisterised" - TablesNextToCode -> "tables-next-to-code" - GmpInTree -> "intree-gmp" - GmpFrameworkPref -> "gmp-framework-preferred" - LeadingUnderscore -> "leading-underscore" - SolarisBrokenShld -> "solaris-broken-shld" - WithLibdw -> "with-libdw" - WithLibnuma -> "with-libnuma" - HaveLibMingwEx -> "have-lib-mingw-ex" - UseSystemFfi -> "use-system-ffi" + ArSupportsAtFile -> "ar-supports-at-file" + CrossCompiling -> "cross-compiling" + CcLlvmBackend -> "cc-llvm-backend" + GhcUnregisterised -> "ghc-unregisterised" + TablesNextToCode -> "tables-next-to-code" + GmpInTree -> "intree-gmp" + GmpFrameworkPref -> "gmp-framework-preferred" + LeadingUnderscore -> "leading-underscore" + SolarisBrokenShld -> "solaris-broken-shld" + WithLibdw -> "with-libdw" + WithLibnuma -> "with-libnuma" + HaveLibMingwEx -> "have-lib-mingw-ex" + UseSystemFfi -> "use-system-ffi" + BootstrapThreadedRts -> "bootstrap-threaded-rts" value <- lookupValueOrError configFile key when (value `notElem` ["YES", "NO", ""]) . error $ "Configuration flag " ++ quote (key ++ " = " ++ value) ++ " cannot be parsed." ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -64,8 +64,13 @@ packageArgs = do , flag GhcUnregisterised ? arg "--ghc-option=-DNO_REGS" , notM targetSupportsSMP ? arg "--ghc-option=-DNOSMP" , notM targetSupportsSMP ? arg "--ghc-option=-optc-DNOSMP" + -- When building stage 1 or later, use thread-safe RTS functions if + -- the configuration calls for a threaded GHC. , (any (wayUnit Threaded) rtsWays) ? notStage0 ? arg "--ghc-option=-optc-DTHREADED_RTS" + -- When building stage 1, use thread-safe RTS functions if the + -- bootstrapping (stage 0) compiler provides a threaded RTS way. + , stage0 ? threadedBootstrapper ? arg "--ghc-option=-optc-DTHREADED_RTS" , ghcWithInterpreter ? ghciWithDebugger <$> flavour ? notStage0 ? arg "--ghc-option=-DDEBUGGER" @@ -90,11 +95,26 @@ packageArgs = do , builder (Cabal Flags) ? mconcat [ ghcWithInterpreter ? notStage0 ? arg "ghci" , cross ? arg "-terminfo" - -- the 'threaded' flag is True by default, but - -- let's record explicitly that we link all ghc - -- executables with the threaded runtime. - , stage0 ? arg "-threaded" - , notStage0 ? ifM (ghcThreaded <$> expr flavour) (arg "threaded") (arg "-threaded") ] + -- Note [Linking ghc-bin against threaded stage0 RTS] + -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + -- We must maintain the invariant that GHCs linked with '-threaded' + -- are built with '-optc=-DTHREADED_RTS', otherwise we'll end up + -- with a GHC that can use the threaded runtime, but contains some + -- non-thread-safe functions. See + -- https://gitlab.haskell.org/ghc/ghc/issues/18024 for an example of + -- the sort of issues this can cause. + , ifM stage0 + -- We build a threaded stage 1 if the bootstrapping compiler + -- supports it. + (ifM threadedBootstrapper + (arg "threaded") + (arg "-threaded")) + -- We build a threaded stage N, N>1 if the configuration calls + -- for it. + (ifM (ghcThreaded <$> expr flavour) + (arg "threaded") + (arg "-threaded")) + ] ] -------------------------------- ghcPkg -------------------------------- @@ -442,4 +462,4 @@ rtsWarnings = mconcat -- and also centralizes the versioning. -- | Minimum supported Windows version. windowsVersion :: String -windowsVersion = "0x06000100" +windowsVersion = "0x06010000" ===================================== mk/config.mk.in ===================================== @@ -199,6 +199,9 @@ endif # `GhcUnregisterised` mode doesn't allow that. GhcWithSMP := $(strip $(if $(filter YESNO, $(ArchSupportsSMP)$(GhcUnregisterised)),YES,NO)) +# Whether or not the bootstrapping GHC supplies a threaded RTS. +GhcThreadedRts = @GhcThreadedRts@ + # Whether to include GHCi in the compiler. Depends on whether the RTS linker # has support for this OS/ARCH combination. ===================================== mk/get-win32-tarballs.py ===================================== @@ -7,7 +7,7 @@ import subprocess import argparse from sys import stderr -TARBALL_VERSION = '0.1' +TARBALL_VERSION = '0.2' BASE_URL = "https://downloads.haskell.org/ghc/mingw/{}".format(TARBALL_VERSION) DEST = Path('ghc-tarballs/mingw-w64') ARCHS = ['i686', 'x86_64', 'sources'] ===================================== rts/ghc.mk ===================================== @@ -25,7 +25,7 @@ rts_VERSION = 1.0 # If we're compiling on windows, enforce that we only support Vista SP1+ # Adding this here means it doesn't have to be done in individual .c files # and also centralizes the versioning. -rts_WINVER = 0x06000100 +rts_WINVER = 0x06010000 # merge GhcLibWays and GhcRTSWays but strip out duplicates rts_WAYS = $(GhcLibWays) $(filter-out $(GhcLibWays),$(GhcRTSWays)) ===================================== 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)); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1532b5cf64b99ffdef2730878a08a252ca12a76d...4448ba12bf76cc0dd7c3cee66916bbc428f968c5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/1532b5cf64b99ffdef2730878a08a252ca12a76d...4448ba12bf76cc0dd7c3cee66916bbc428f968c5 You're receiving 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 29 19:10:54 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 29 May 2020 15:10:54 -0400 Subject: [Git][ghc/ghc][wip/T18234] 4 commits: Hadrian: fix binary-dist target for cross-compilation Message-ID: <5ed15e3ee2ec3_6e263f9ed7387e4827233ca@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18234 at Glasgow Haskell Compiler / GHC Commits: 46f62bcd by Sylvain Henry at 2020-05-29T19:53:17+02:00 Hadrian: fix binary-dist target for cross-compilation - - - - - e448cc40 by Ben Gamari at 2020-05-29T15:10:47-04:00 gitlab-ci: Add usage message to ci.sh - - - - - 681a58d4 by Ben Gamari at 2020-05-29T15:10:47-04:00 gitlab-ci: Make names more consistent - - - - - 21cb2c3d by Ben Gamari at 2020-05-29T15:10:47-04:00 gitlab-ci: Introduce a nightly cross-compilation job This adds a job to test cross-compilation from x86-64 to AArch64 with Hadrian. Fixes #18234. - - - - - 3 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - hadrian/src/Rules/BinaryDist.hs 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: 6223fe0b5942f4fa35bdec92c74566cf195bfb42 + DOCKER_REV: ba119705df5222fe74208a85019cb980e2c4318f # Sequential version number capturing the versions of all tools fetched by # .gitlab/ci.sh. @@ -178,7 +178,7 @@ lint-release-changelogs: # Validation via Pipelines (hadrian) ############################################################ -.validate-hadrian: +.build-hadrian: variables: FLAVOUR: "validate" script: @@ -198,11 +198,8 @@ lint-release-changelogs: - ghc.tar.xz - junit.xml -.validate-linux-hadrian: - extends: .validate-hadrian - image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV" - variables: - TEST_ENV: "x86_64-linux-deb9-hadrian" +.build-linux-hadrian: + extends: .build-hadrian before_script: # workaround for docker permissions - sudo chown ghc:ghc -R . @@ -212,20 +209,54 @@ lint-release-changelogs: - "git fetch https://gitlab.haskell.org/ghc/ghc-performance-notes.git refs/notes/perf:refs/notes/perf || true" after_script: - .gitlab/ci.sh clean + +.build-x86_64-linux-deb9-hadrian: + extends: .build-linux-hadrian + image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV" tags: - x86_64-linux validate-x86_64-linux-deb9-hadrian: - extends: .validate-linux-hadrian + extends: .build-x86_64-linux-deb9-hadrian stage: build + variables: + TEST_ENV: "x86_64-linux-deb9-hadrian" validate-x86_64-linux-deb9-unreg-hadrian: - extends: .validate-linux-hadrian + extends: .build-x86_64-linux-deb9-hadrian stage: full-build variables: CONFIGURE_ARGS: --enable-unregisterised TEST_ENV: "x86_64-linux-deb9-unreg-hadrian" +.build-x86_64-linux-deb10-hadrian: + extends: .build-hadrian + image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV" + before_script: + # workaround for docker permissions + - sudo chown ghc:ghc -R . + - git submodule sync --recursive + - git submodule update --init --recursive + - git checkout .gitmodules + - "git fetch https://gitlab.haskell.org/ghc/ghc-performance-notes.git refs/notes/perf:refs/notes/perf || true" + after_script: + - .gitlab/ci.sh clean + tags: + - x86_64-linux + +nightly-x86_64-linux-deb10-hadrian-cross-aarch64: + #<<: *nightly + stage: build + extends: .build-x86_64-linux-deb10-hadrian + variables: + CONFIGURE_ARGS: --with-intree-gmp + CROSS_TARGET: "aarch64-linux-gnu" + + +############################################################ +# GHC-in-GHCi (Hadrian) +############################################################ + hadrian-ghc-in-ghci: stage: quick-build image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV" @@ -327,7 +358,7 @@ release-x86_64-freebsd: stage: full-build .build-x86_64-freebsd-hadrian: - extends: .validate-hadrian + extends: .build-hadrian stage: full-build tags: - x86_64-freebsd @@ -678,7 +709,7 @@ release-x86_64-linux-deb8: ################################# .build-x86_64-linux-alpine-hadrian: - extends: .validate-linux-hadrian + extends: .build-linux-hadrian stage: full-build image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-alpine:$DOCKER_REV" # There are currently a few failing tests ===================================== .gitlab/ci.sh ===================================== @@ -2,6 +2,8 @@ # shellcheck disable=SC2230 # This is the primary driver of the GitLab CI infrastructure. +# Run `ci.sh usage` for usage information. + set -e -o pipefail @@ -60,14 +62,64 @@ function run() { TOP="$(pwd)" +function usage() { + cat </stage1/bin/haddock[.exe]) to -- the bindist's bindir (/bindist/ghc-.../bin/). - haddockPath <- programPath (vanillaContext Stage1 haddock) - copyFile haddockPath - (bindistFilesDir -/- "bin" -/- takeFileName haddockPath) + unless cross $ do + haddockPath <- programPath (vanillaContext Stage1 haddock) + copyFile haddockPath + (bindistFilesDir -/- "bin" -/- takeFileName haddockPath) -- We then 'need' all the files necessary to configure and install -- (as in, './configure [...] && make install') this build on some View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6d2b964c01912b39d352b0e4421981ae449629a5...21cb2c3df1cb5857aebd0f5ba69c7f0e19eb1419 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6d2b964c01912b39d352b0e4421981ae449629a5...21cb2c3df1cb5857aebd0f5ba69c7f0e19eb1419 You're receiving 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 29 19:21:56 2020 From: gitlab at gitlab.haskell.org (Vladislav Zavialov) Date: Fri, 29 May 2020 15:21:56 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/t18251-error-messages Message-ID: <5ed160d42e1ff_6e263f9ee299af3c2724085@gitlab.haskell.org.mail> Vladislav Zavialov pushed new branch wip/t18251-error-messages at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/t18251-error-messages You're receiving 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 29 22:15:42 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Fri, 29 May 2020 18:15:42 -0400 Subject: [Git][ghc/ghc][wip/T18078] 23 commits: GHC.Core.Unfold: Refactor traceInline Message-ID: <5ed1898eb5157_6e263f9ee299af3c27393ee@gitlab.haskell.org.mail> Simon Peyton Jones pushed to branch wip/T18078 at Glasgow Haskell Compiler / GHC Commits: 28deee28 by Ben Gamari at 2020-05-28T16:23:21-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 - - - - - 1f393e1e by Ben Gamari at 2020-05-28T16:23:21-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 haddock.Cabal haddock.base haddock.compiler - - - - - 5f621a78 by Vladislav Zavialov at 2020-05-28T16:23:58-04:00 Add Semigroup/Monoid for Q (#18123) - - - - - dc5f004c by Xavier Denis at 2020-05-28T16:24:37-04:00 Fix #18071 Run the core linter on candidate instances to ensure they are well-kinded. Better handle quantified constraints by using a CtWanted to avoid having unsolved constraints thrown away at the end by the solver. - - - - - 10e6982c by Sebastian Graf at 2020-05-28T16:25:14-04:00 FloatOut: Only eta-expand dead-end RHS if arity will increase (#18231) Otherwise we risk turning trivial RHS into non-trivial RHS, introducing unnecessary bindings in the next Simplifier run, resulting in more churn. Fixes #18231. - - - - - 08dab5f7 by Sebastian Graf at 2020-05-28T16:25:14-04:00 DmdAnal: Recognise precise exceptions from case alternatives (#18086) Consider ```hs m :: IO () m = do putStrLn "foo" error "bar" ``` `m` (from #18086) always throws a (precise or imprecise) exception or diverges. Yet demand analysis infers `<L,A>` as demand signature instead of `<L,A>x` for it. That's because the demand analyser sees `putStrLn` occuring in a case scrutinee and decides that it has to `deferAfterPreciseException`, because `putStrLn` throws a precise exception on some control flow paths. This will mask the `botDiv` `Divergence`of the single case alt containing `error` to `topDiv`. Since `putStrLn` has `topDiv` itself, the final `Divergence` is `topDiv`. This is easily fixed: `deferAfterPreciseException` works by `lub`ing with the demand type of a virtual case branch denoting the precise exceptional control flow. We used `nopDmdType` before, but we can be more precise and use `exnDmdType`, which is `nopDmdType` with `exnDiv`. Now the `Divergence` from the case alt will degrade `botDiv` to `exnDiv` instead of `topDiv`, which combines with the result from the scrutinee to `exnDiv`, and all is well. Fixes #18086. - - - - - aef95f11 by Ben Gamari at 2020-05-28T16:25:53-04:00 Ticky-ticky: Record DataCon name in ticker name This makes it significantly easier to spot the nature of allocations regressions and comes at a reasonably low cost. - - - - - 8f021b8c by Ben Gamari at 2020-05-28T16:26:34-04:00 hadrian: Don't track GHC's verbosity argument Teach hadrian to ignore GHC's -v argument in its recompilation check, thus fixing #18131. - - - - - 13d9380b by Ben Gamari at 2020-05-28T16:27:20-04:00 Rip out CmmStackInfo(updfr_space) As noted in #18232, this field is currently completely unused and moreover doesn't have a clear meaning. - - - - - f10d11fa by Andreas Klebinger at 2020-05-29T01:38:42-04: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. - - - - - bbeb2389 by Ben Gamari at 2020-05-29T01:39:19-04:00 CoreToStg: Add Outputable ArgInfo instance - - - - - 0e3361ca by Simon Peyton Jones at 2020-05-29T01:39:19-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. - - - - - c49f7df0 by Simon Peyton Jones at 2020-05-29T01:39:19-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. - - - - - 46720997 by Ben Gamari at 2020-05-29T01:39:19-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 Metric Decrease: ManyConstructors Co-Authored-By: Simon Peyton-Jone <simonpj at microsoft.com> - - - - - 277c2f26 by Ben Gamari at 2020-05-29T01:39:55-04:00 Eta expand un-saturated primops Now since we no longer try to predict CAFfyness we have no need for the solution to #16846. Eta expanding unsaturated primop applications is conceptually simpler, especially in the presence of levity polymorphism. This essentially reverts cac8dc9f51e31e4c0a6cd9bc302f7e1bc7c03beb, as suggested in #18079. Closes #18079. - - - - - f44d7ae0 by Simon Jakobi at 2020-05-29T01:40:34-04:00 base: Scrap deprecation plan for Data.Monoid.{First,Last} See the discussion on the libraries mailing list for context: https://mail.haskell.org/pipermail/libraries/2020-April/030357.html - - - - - 8b494895 by Jeremy Schlatter at 2020-05-29T01:41:12-04:00 Fix typo in documentation - - - - - 998450f4 by Gleb Popov at 2020-05-29T01:41:53-04:00 Always define USE_PTHREAD_FOR_ITIMER for FreeBSD. - - - - - f9a513e0 by Alp Mestanogullari at 2020-05-29T01:42:36-04:00 hadrian: introduce 'install' target Its logic is very simple. It `need`s the `binary-dist-dir` target and runs suitable `configure` and `make install` commands for the user. A new `--prefix` command line argument is introduced to specify where GHC should be installed. - - - - - 67738db1 by Travis Whitaker at 2020-05-29T13:34:48-04:00 Build a threaded stage 1 if the bootstrapping GHC supports it. - - - - - aac19e6c by Peter Trommler at 2020-05-29T13:35:24-04:00 PPC NCG: No per-symbol .section ".toc" directives All position independent symbols are collected during code generation and emitted in one go. Prepending each symbol with a .section ".toc" directive is redundant. This patch drops the per-symbol directives leading to smaller assembler files. Fixes #18250 - - - - - c562c313 by Simon Peyton Jones at 2020-05-29T23:02:20+01:00 Optimisation in Unique.Supply This patch switches on -fno-state-hack in GHC.Types.Unique.Supply. It turned out that my fixes for #18078 (coercion floating) changed the optimisation pathway for mkSplitUniqSupply in such a way that we had an extra allocation inside the inner loop. Adding -fno-state-hack fixed that -- and indeed the loop in mkSplitUniqSupply is a classic example of the way in which -fno-state-hack can be bad; see #18238. Moreover, the new code is better than the old. They allocate the same, but the old code ends up with a partial application. The net effect is that the test perf/should_run/UniqLoop runs 20% faster! From 2.5s down to 2.0s. The allocation numbers are the same -- but elapsed time falls. Good! The bad thing about this is that it's terribly delicate. But at least it's a good example of such delicacy in action. There is a long Note [Optimising the unique supply] which now explains all this. - - - - - 12f458eb by Simon Peyton Jones at 2020-05-29T23:05:06+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 also discovered that unsafeCoerce wasn't being inlined if the context was boring. So (\x. f (unsafeCoerce x)) would create a thunk -- yikes! I fixed that by making inlineBoringOK a bit cleverer: see Note [Inline unsafeCoerce] in GHC.Core.Unfold. I also found that unsafeCoerceName was unused, so I removed it. 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% Metric Decrease: T15164 T13701 Metric Increase: T12150 T12234 T12425 - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/LayoutStack.hs - compiler/GHC/Cmm/Ppr.hs - compiler/GHC/Cmm/ProcPoint.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/CSE.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/CprAnal.hs - compiler/GHC/Core/Opt/Driver.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Monad.hs - compiler/GHC/Core/Opt/Simplify/Utils.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Utils.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/HsToCore/Utils.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/47025bbf175086d6eec1599de5ffb9c078498145...12f458eb7e63b6ca8a2d5a3c94ab355582763ecc -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/47025bbf175086d6eec1599de5ffb9c078498145...12f458eb7e63b6ca8a2d5a3c94ab355582763ecc You're receiving 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 29 23:03:44 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 29 May 2020 19:03:44 -0400 Subject: [Git][ghc/ghc][wip/T17775] Simple subsumption Message-ID: <5ed194d09b445_6e263f9f0bb937fc27449b4@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T17775 at Glasgow Haskell Compiler / GHC Commits: 5f0099e3 by Simon Peyton Jones at 2020-05-29T23:02:16+00: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 Updates Cabal and haddock submodules. Metric Increase: T12150 Metric Decrease: haddock.Cabal haddock.base - - - - - 20 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/Type.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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5f0099e321dbdedb4c6aa2ccf49a7dad0b3ea041 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5f0099e321dbdedb4c6aa2ccf49a7dad0b3ea041 You're receiving 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 30 00:04:47 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 29 May 2020 20:04:47 -0400 Subject: [Git][ghc/ghc][wip/tyconapp-opts] 41 commits: Revert "Specify kind variables for inferred kinds in base." Message-ID: <5ed1a31fd6640_6e263f9ed4d7839c27609f2@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/tyconapp-opts at Glasgow Haskell Compiler / GHC Commits: 013d7120 by Ben Gamari at 2020-05-25T09:48:17-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. - - - - - 4c4312ed by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Drop redundant ad-hoc boot module check To determine whether the module is a boot module Coverage.addTicksToBinds was checking for a `boot` suffix in the module source filename. This is quite ad-hoc and shouldn't be necessary; the callsite in `deSugar` already checks that the module isn't a boot module. - - - - - 1abf3c84 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make tickBoxCount strict This could otherwise easily cause a leak of (+) thunks. - - - - - b2813750 by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Make ccIndices strict This just seems like a good idea. - - - - - 02e278eb by Ben Gamari at 2020-05-25T09:48:53-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. - - - - - b8c014ce by Ben Gamari at 2020-05-25T09:48:53-04:00 Coverage: Factor out addMixEntry - - - - - 53814a64 by Zubin Duggal at 2020-05-26T03:03:24-04:00 Add info about typeclass evidence to .hie files See `testsuite/tests/hiefile/should_run/HieQueries.hs` and `testsuite/tests/hiefile/should_run/HieQueries.stdout` for an example of this We add two new fields, `EvidenceVarBind` and `EvidenceVarUse` to the `ContextInfo` associated with an Identifier. These are associated with the appropriate identifiers for the evidence variables collected when we come across `HsWrappers`, `TcEvBinds` and `IPBinds` while traversing the AST. Instance dictionary and superclass selector dictionaries from `tcg_insts` and classes defined in `tcg_tcs` are also recorded in the AST as originating from their definition span This allows us to save a complete picture of the evidence constructed by the constraint solver, and will let us report this to the user, enabling features like going to the instance definition from the invocation of a class method(or any other method taking a constraint) and finding all usages of a particular instance. Additionally, - Mark NodeInfo with an origin so we can differentiate between bindings origininating in the source vs those in ghc - Along with typeclass evidence info, also include information on Implicit Parameters - Add a few utility functions to HieUtils in order to query the new info Updates haddock submodule - - - - - 6604906c by Sebastian Graf at 2020-05-26T03:04:04-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. - - - - - cf772f19 by Sylvain Henry at 2020-05-26T03:04:45-04:00 Enhance Note [About units] for Backpack - - - - - ede24126 by Takenobu Tani at 2020-05-27T00:13:55-04:00 core-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Core.hs <= coreSyn/CoreSyn.hs * GHC/Core/Coercion.hs <= types/Coercion.hs * GHC/Core/Coercion/Axiom.hs <= types/CoAxiom.hs * GHC/Core/Coercion/Opt.hs <= types/OptCoercion.hs * GHC/Core/DataCon.hs <= basicTypes/DataCon.hs * GHC/Core/FamInstEnv.hs <= types/FamInstEnv.hs * GHC/Core/Lint.hs <= coreSyn/CoreLint.hs * GHC/Core/Subst.hs <= coreSyn/CoreSubst.hs * GHC/Core/TyCo/Rep.hs <= types/TyCoRep.hs * GHC/Core/TyCon.hs <= types/TyCon.hs * GHC/Core/Type.hs <= types/Type.hs * GHC/Core/Unify.hs <= types/Unify.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/Var.hs <= basicTypes/Var.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [skip ci] - - - - - 04750304 by Ben Gamari at 2020-05-27T00:14:33-04:00 eventlog: Fix racy flushing Previously no attempt was made to avoid multiple threads writing their capability-local eventlog buffers to the eventlog writer simultaneously. This could result in multiple eventlog streams being interleaved. Fix this by documenting that the EventLogWriter's write() and flush() functions may be called reentrantly and fix the default writer to protect its FILE* by a mutex. Fixes #18210. - - - - - d6203f24 by Joshua Price at 2020-05-27T00:15:17-04:00 Make `identifier` parse unparenthesized `->` (#18060) - - - - - 28deee28 by Ben Gamari at 2020-05-28T16:23:21-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 - - - - - 1f393e1e by Ben Gamari at 2020-05-28T16:23:21-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 haddock.Cabal haddock.base haddock.compiler - - - - - 5f621a78 by Vladislav Zavialov at 2020-05-28T16:23:58-04:00 Add Semigroup/Monoid for Q (#18123) - - - - - dc5f004c by Xavier Denis at 2020-05-28T16:24:37-04:00 Fix #18071 Run the core linter on candidate instances to ensure they are well-kinded. Better handle quantified constraints by using a CtWanted to avoid having unsolved constraints thrown away at the end by the solver. - - - - - 10e6982c by Sebastian Graf at 2020-05-28T16:25:14-04:00 FloatOut: Only eta-expand dead-end RHS if arity will increase (#18231) Otherwise we risk turning trivial RHS into non-trivial RHS, introducing unnecessary bindings in the next Simplifier run, resulting in more churn. Fixes #18231. - - - - - 08dab5f7 by Sebastian Graf at 2020-05-28T16:25:14-04:00 DmdAnal: Recognise precise exceptions from case alternatives (#18086) Consider ```hs m :: IO () m = do putStrLn "foo" error "bar" ``` `m` (from #18086) always throws a (precise or imprecise) exception or diverges. Yet demand analysis infers `<L,A>` as demand signature instead of `<L,A>x` for it. That's because the demand analyser sees `putStrLn` occuring in a case scrutinee and decides that it has to `deferAfterPreciseException`, because `putStrLn` throws a precise exception on some control flow paths. This will mask the `botDiv` `Divergence`of the single case alt containing `error` to `topDiv`. Since `putStrLn` has `topDiv` itself, the final `Divergence` is `topDiv`. This is easily fixed: `deferAfterPreciseException` works by `lub`ing with the demand type of a virtual case branch denoting the precise exceptional control flow. We used `nopDmdType` before, but we can be more precise and use `exnDmdType`, which is `nopDmdType` with `exnDiv`. Now the `Divergence` from the case alt will degrade `botDiv` to `exnDiv` instead of `topDiv`, which combines with the result from the scrutinee to `exnDiv`, and all is well. Fixes #18086. - - - - - aef95f11 by Ben Gamari at 2020-05-28T16:25:53-04:00 Ticky-ticky: Record DataCon name in ticker name This makes it significantly easier to spot the nature of allocations regressions and comes at a reasonably low cost. - - - - - 8f021b8c by Ben Gamari at 2020-05-28T16:26:34-04:00 hadrian: Don't track GHC's verbosity argument Teach hadrian to ignore GHC's -v argument in its recompilation check, thus fixing #18131. - - - - - 13d9380b by Ben Gamari at 2020-05-28T16:27:20-04:00 Rip out CmmStackInfo(updfr_space) As noted in #18232, this field is currently completely unused and moreover doesn't have a clear meaning. - - - - - f10d11fa by Andreas Klebinger at 2020-05-29T01:38:42-04: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. - - - - - bbeb2389 by Ben Gamari at 2020-05-29T01:39:19-04:00 CoreToStg: Add Outputable ArgInfo instance - - - - - 0e3361ca by Simon Peyton Jones at 2020-05-29T01:39:19-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. - - - - - c49f7df0 by Simon Peyton Jones at 2020-05-29T01:39:19-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. - - - - - 46720997 by Ben Gamari at 2020-05-29T01:39:19-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 Metric Decrease: ManyConstructors Co-Authored-By: Simon Peyton-Jone <simonpj at microsoft.com> - - - - - 277c2f26 by Ben Gamari at 2020-05-29T01:39:55-04:00 Eta expand un-saturated primops Now since we no longer try to predict CAFfyness we have no need for the solution to #16846. Eta expanding unsaturated primop applications is conceptually simpler, especially in the presence of levity polymorphism. This essentially reverts cac8dc9f51e31e4c0a6cd9bc302f7e1bc7c03beb, as suggested in #18079. Closes #18079. - - - - - f44d7ae0 by Simon Jakobi at 2020-05-29T01:40:34-04:00 base: Scrap deprecation plan for Data.Monoid.{First,Last} See the discussion on the libraries mailing list for context: https://mail.haskell.org/pipermail/libraries/2020-April/030357.html - - - - - 8b494895 by Jeremy Schlatter at 2020-05-29T01:41:12-04:00 Fix typo in documentation - - - - - 998450f4 by Gleb Popov at 2020-05-29T01:41:53-04:00 Always define USE_PTHREAD_FOR_ITIMER for FreeBSD. - - - - - f9a513e0 by Alp Mestanogullari at 2020-05-29T01:42:36-04:00 hadrian: introduce 'install' target Its logic is very simple. It `need`s the `binary-dist-dir` target and runs suitable `configure` and `make install` commands for the user. A new `--prefix` command line argument is introduced to specify where GHC should be installed. - - - - - 67738db1 by Travis Whitaker at 2020-05-29T13:34:48-04:00 Build a threaded stage 1 if the bootstrapping GHC supports it. - - - - - aac19e6c by Peter Trommler at 2020-05-29T13:35:24-04:00 PPC NCG: No per-symbol .section ".toc" directives All position independent symbols are collected during code generation and emitted in one go. Prepending each symbol with a .section ".toc" directive is redundant. This patch drops the per-symbol directives leading to smaller assembler files. Fixes #18250 - - - - - 4fb6dd05 by Ben Gamari at 2020-05-29T20:03:53-04:00 Notes from call - - - - - 815d664b by Ben Gamari at 2020-05-29T20:03:53-04:00 Shortcut mkTvSubstPrs on empty list Surprisingly enough this reduces compilation time on Cabal by nearly 1%. - - - - - 3881b117 by Ben Gamari at 2020-05-29T20:03:53-04:00 Shortcut coreView - - - - - c07e2d7d by Ben Gamari at 2020-05-29T20:03:53-04:00 expandSynTyCon_maybe: Special-case nullary tycons This avoids both allocation and some instructions. - - - - - 410a285a by Ben Gamari at 2020-05-29T20:03:53-04:00 Optimise tcView - - - - - 69fabfd3 by Ben Gamari at 2020-05-29T20:03:53-04:00 Inline expandSynTyCon_maybe This is necessary to avoid some needless allocation since we currently lack nested CPR on sums. Metric Decrease: T12227 T12545 T12707 T14683 T3064 T5631 T5642 T9020 T9872a - - - - - 2f5404a0 by Ben Gamari at 2020-05-29T20:03:53-04:00 Some cleanup - - - - - a5a182b0 by Ben Gamari at 2020-05-29T20:04:19-04:00 hi Metric Decrease: T13035 haddock.Cabal haddock.base Metric Increase: T9872c - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/LayoutStack.hs - compiler/GHC/Cmm/Ppr.hs - compiler/GHC/Cmm/ProcPoint.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Monad.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/HsToCore/Coverage.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8811b5e918718923de9f33d74f6b4ef56b3f3d83...a5a182b0117a9786d4c0f30280126570ee2fbea5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8811b5e918718923de9f33d74f6b4ef56b3f3d83...a5a182b0117a9786d4c0f30280126570ee2fbea5 You're receiving 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 30 00:25:47 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 29 May 2020 20:25:47 -0400 Subject: [Git][ghc/ghc][wip/bump-base] 28 commits: Add info about typeclass evidence to .hie files Message-ID: <5ed1a80b3ea99_6e263f9f0bb937fc27714d2@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/bump-base at Glasgow Haskell Compiler / GHC Commits: 53814a64 by Zubin Duggal at 2020-05-26T03:03:24-04:00 Add info about typeclass evidence to .hie files See `testsuite/tests/hiefile/should_run/HieQueries.hs` and `testsuite/tests/hiefile/should_run/HieQueries.stdout` for an example of this We add two new fields, `EvidenceVarBind` and `EvidenceVarUse` to the `ContextInfo` associated with an Identifier. These are associated with the appropriate identifiers for the evidence variables collected when we come across `HsWrappers`, `TcEvBinds` and `IPBinds` while traversing the AST. Instance dictionary and superclass selector dictionaries from `tcg_insts` and classes defined in `tcg_tcs` are also recorded in the AST as originating from their definition span This allows us to save a complete picture of the evidence constructed by the constraint solver, and will let us report this to the user, enabling features like going to the instance definition from the invocation of a class method(or any other method taking a constraint) and finding all usages of a particular instance. Additionally, - Mark NodeInfo with an origin so we can differentiate between bindings origininating in the source vs those in ghc - Along with typeclass evidence info, also include information on Implicit Parameters - Add a few utility functions to HieUtils in order to query the new info Updates haddock submodule - - - - - 6604906c by Sebastian Graf at 2020-05-26T03:04:04-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. - - - - - cf772f19 by Sylvain Henry at 2020-05-26T03:04:45-04:00 Enhance Note [About units] for Backpack - - - - - ede24126 by Takenobu Tani at 2020-05-27T00:13:55-04:00 core-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Core.hs <= coreSyn/CoreSyn.hs * GHC/Core/Coercion.hs <= types/Coercion.hs * GHC/Core/Coercion/Axiom.hs <= types/CoAxiom.hs * GHC/Core/Coercion/Opt.hs <= types/OptCoercion.hs * GHC/Core/DataCon.hs <= basicTypes/DataCon.hs * GHC/Core/FamInstEnv.hs <= types/FamInstEnv.hs * GHC/Core/Lint.hs <= coreSyn/CoreLint.hs * GHC/Core/Subst.hs <= coreSyn/CoreSubst.hs * GHC/Core/TyCo/Rep.hs <= types/TyCoRep.hs * GHC/Core/TyCon.hs <= types/TyCon.hs * GHC/Core/Type.hs <= types/Type.hs * GHC/Core/Unify.hs <= types/Unify.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/Var.hs <= basicTypes/Var.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [skip ci] - - - - - 04750304 by Ben Gamari at 2020-05-27T00:14:33-04:00 eventlog: Fix racy flushing Previously no attempt was made to avoid multiple threads writing their capability-local eventlog buffers to the eventlog writer simultaneously. This could result in multiple eventlog streams being interleaved. Fix this by documenting that the EventLogWriter's write() and flush() functions may be called reentrantly and fix the default writer to protect its FILE* by a mutex. Fixes #18210. - - - - - d6203f24 by Joshua Price at 2020-05-27T00:15:17-04:00 Make `identifier` parse unparenthesized `->` (#18060) - - - - - 28deee28 by Ben Gamari at 2020-05-28T16:23:21-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 - - - - - 1f393e1e by Ben Gamari at 2020-05-28T16:23:21-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 haddock.Cabal haddock.base haddock.compiler - - - - - 5f621a78 by Vladislav Zavialov at 2020-05-28T16:23:58-04:00 Add Semigroup/Monoid for Q (#18123) - - - - - dc5f004c by Xavier Denis at 2020-05-28T16:24:37-04:00 Fix #18071 Run the core linter on candidate instances to ensure they are well-kinded. Better handle quantified constraints by using a CtWanted to avoid having unsolved constraints thrown away at the end by the solver. - - - - - 10e6982c by Sebastian Graf at 2020-05-28T16:25:14-04:00 FloatOut: Only eta-expand dead-end RHS if arity will increase (#18231) Otherwise we risk turning trivial RHS into non-trivial RHS, introducing unnecessary bindings in the next Simplifier run, resulting in more churn. Fixes #18231. - - - - - 08dab5f7 by Sebastian Graf at 2020-05-28T16:25:14-04:00 DmdAnal: Recognise precise exceptions from case alternatives (#18086) Consider ```hs m :: IO () m = do putStrLn "foo" error "bar" ``` `m` (from #18086) always throws a (precise or imprecise) exception or diverges. Yet demand analysis infers `<L,A>` as demand signature instead of `<L,A>x` for it. That's because the demand analyser sees `putStrLn` occuring in a case scrutinee and decides that it has to `deferAfterPreciseException`, because `putStrLn` throws a precise exception on some control flow paths. This will mask the `botDiv` `Divergence`of the single case alt containing `error` to `topDiv`. Since `putStrLn` has `topDiv` itself, the final `Divergence` is `topDiv`. This is easily fixed: `deferAfterPreciseException` works by `lub`ing with the demand type of a virtual case branch denoting the precise exceptional control flow. We used `nopDmdType` before, but we can be more precise and use `exnDmdType`, which is `nopDmdType` with `exnDiv`. Now the `Divergence` from the case alt will degrade `botDiv` to `exnDiv` instead of `topDiv`, which combines with the result from the scrutinee to `exnDiv`, and all is well. Fixes #18086. - - - - - aef95f11 by Ben Gamari at 2020-05-28T16:25:53-04:00 Ticky-ticky: Record DataCon name in ticker name This makes it significantly easier to spot the nature of allocations regressions and comes at a reasonably low cost. - - - - - 8f021b8c by Ben Gamari at 2020-05-28T16:26:34-04:00 hadrian: Don't track GHC's verbosity argument Teach hadrian to ignore GHC's -v argument in its recompilation check, thus fixing #18131. - - - - - 13d9380b by Ben Gamari at 2020-05-28T16:27:20-04:00 Rip out CmmStackInfo(updfr_space) As noted in #18232, this field is currently completely unused and moreover doesn't have a clear meaning. - - - - - f10d11fa by Andreas Klebinger at 2020-05-29T01:38:42-04: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. - - - - - bbeb2389 by Ben Gamari at 2020-05-29T01:39:19-04:00 CoreToStg: Add Outputable ArgInfo instance - - - - - 0e3361ca by Simon Peyton Jones at 2020-05-29T01:39:19-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. - - - - - c49f7df0 by Simon Peyton Jones at 2020-05-29T01:39:19-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. - - - - - 46720997 by Ben Gamari at 2020-05-29T01:39:19-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 Metric Decrease: ManyConstructors Co-Authored-By: Simon Peyton-Jone <simonpj at microsoft.com> - - - - - 277c2f26 by Ben Gamari at 2020-05-29T01:39:55-04:00 Eta expand un-saturated primops Now since we no longer try to predict CAFfyness we have no need for the solution to #16846. Eta expanding unsaturated primop applications is conceptually simpler, especially in the presence of levity polymorphism. This essentially reverts cac8dc9f51e31e4c0a6cd9bc302f7e1bc7c03beb, as suggested in #18079. Closes #18079. - - - - - f44d7ae0 by Simon Jakobi at 2020-05-29T01:40:34-04:00 base: Scrap deprecation plan for Data.Monoid.{First,Last} See the discussion on the libraries mailing list for context: https://mail.haskell.org/pipermail/libraries/2020-April/030357.html - - - - - 8b494895 by Jeremy Schlatter at 2020-05-29T01:41:12-04:00 Fix typo in documentation - - - - - 998450f4 by Gleb Popov at 2020-05-29T01:41:53-04:00 Always define USE_PTHREAD_FOR_ITIMER for FreeBSD. - - - - - f9a513e0 by Alp Mestanogullari at 2020-05-29T01:42:36-04:00 hadrian: introduce 'install' target Its logic is very simple. It `need`s the `binary-dist-dir` target and runs suitable `configure` and `make install` commands for the user. A new `--prefix` command line argument is introduced to specify where GHC should be installed. - - - - - 67738db1 by Travis Whitaker at 2020-05-29T13:34:48-04:00 Build a threaded stage 1 if the bootstrapping GHC supports it. - - - - - aac19e6c by Peter Trommler at 2020-05-29T13:35:24-04:00 PPC NCG: No per-symbol .section ".toc" directives All position independent symbols are collected during code generation and emitted in one go. Prepending each symbol with a .section ".toc" directive is redundant. This patch drops the per-symbol directives leading to smaller assembler files. Fixes #18250 - - - - - 44930130 by Ben Gamari at 2020-05-29T20:24:45-04:00 base: Bump to 4.15.0.0 - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/LayoutStack.hs - compiler/GHC/Cmm/Ppr.hs - compiler/GHC/Cmm/ProcPoint.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Monad.hs - compiler/GHC/Core/Opt/SpecConstr.hs - compiler/GHC/Core/Opt/WorkWrap/Utils.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Ext/Binary.hs - compiler/GHC/Iface/Ext/Debug.hs - compiler/GHC/Iface/Ext/Types.hs - compiler/GHC/Iface/Ext/Utils.hs - compiler/GHC/Parser.y The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c1a8577c1f18bfedc6a67197c80fd206286d1f87...4493013017d52822f3869b1cf53fd1dc08367487 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c1a8577c1f18bfedc6a67197c80fd206286d1f87...4493013017d52822f3869b1cf53fd1dc08367487 You're receiving 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 30 01:01:46 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 29 May 2020 21:01:46 -0400 Subject: [Git][ghc/ghc][wip/bump-base] base: Bump to 4.15.0.0 Message-ID: <5ed1b07ace15a_6e2611db28542775611@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/bump-base at Glasgow Haskell Compiler / GHC Commits: 3a81e8fb by Ben Gamari at 2020-05-29T21:01:38-04:00 base: Bump to 4.15.0.0 - - - - - 30 changed files: - compiler/ghc.cabal.in - libraries/array - libraries/base/base.cabal - libraries/deepseq - libraries/directory - libraries/filepath - libraries/ghc-boot-th/ghc-boot-th.cabal.in - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghc-compact/ghc-compact.cabal - libraries/ghci/ghci.cabal.in - libraries/haskeline - libraries/hpc - libraries/parsec - libraries/process - libraries/stm - libraries/template-haskell/template-haskell.cabal.in - libraries/terminfo - libraries/unix - testsuite/tests/dependent/should_compile/T14729.stderr - testsuite/tests/dependent/should_compile/T15743.stderr - testsuite/tests/dependent/should_compile/T15743e.stderr - testsuite/tests/indexed-types/should_compile/T15711.stderr - testsuite/tests/indexed-types/should_compile/T15852.stderr - testsuite/tests/polykinds/T15592.stderr - testsuite/tests/polykinds/T15592b.stderr - testsuite/tests/printer/T18052a.stderr - testsuite/tests/typecheck/should_compile/T12763.stderr - testsuite/tests/typecheck/should_compile/subsumption_sort_hole_fits.stderr - utils/haddock - utils/hsc2hs Changes: ===================================== compiler/ghc.cabal.in ===================================== @@ -59,7 +59,7 @@ Library Default-Language: Haskell2010 Exposed: False - Build-Depends: base >= 4.11 && < 4.15, + Build-Depends: base >= 4.11 && < 4.16, deepseq >= 1.4 && < 1.5, directory >= 1 && < 1.4, process >= 1 && < 1.7, ===================================== libraries/array ===================================== @@ -1 +1 @@ -Subproject commit f73f681e52546b1e35cb9e8a62fe49c33f259d98 +Subproject commit ab535173d7885ebfc2005d8da2765f0f52c923ce ===================================== 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 ===================================== libraries/deepseq ===================================== @@ -1 +1 @@ -Subproject commit da0eda33f540786b6823c6f542ab59cf9d1b71d9 +Subproject commit 13c1c84415da727ab56e9fa33aca5046b6683848 ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit 36bd1921258b759724a95ce56c5e880edf0972a2 +Subproject commit 3d9ca6edc0703860829ab3210db78bb4c4ff72b9 ===================================== libraries/filepath ===================================== @@ -1 +1 @@ -Subproject commit 023eedaeb142d47b7b5a41fe4cc4150da0bd0042 +Subproject commit 9088df9f97914664c9360857347d65c32dd6c892 ===================================== libraries/ghc-boot-th/ghc-boot-th.cabal.in ===================================== @@ -36,4 +36,4 @@ Library GHC.ForeignSrcLang.Type GHC.Lexeme - build-depends: base >= 4.7 && < 4.15 + build-depends: base >= 4.7 && < 4.16 ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -55,7 +55,7 @@ Library -- GHC.Version -- GHC.Platform.Host - build-depends: base >= 4.7 && < 4.15, + build-depends: base >= 4.7 && < 4.16, binary == 0.8.*, bytestring == 0.10.*, containers >= 0.5 && < 0.7, ===================================== libraries/ghc-compact/ghc-compact.cabal ===================================== @@ -37,7 +37,7 @@ library CPP build-depends: ghc-prim >= 0.5.3 && < 0.7, - base >= 4.9.0 && < 4.15, + base >= 4.9.0 && < 4.16, bytestring >= 0.10.6.0 ghc-options: -Wall ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -72,7 +72,7 @@ library Build-Depends: array == 0.5.*, - base >= 4.8 && < 4.15, + base >= 4.8 && < 4.16, binary == 0.8.*, bytestring == 0.10.*, containers >= 0.5 && < 0.7, ===================================== libraries/haskeline ===================================== @@ -1 +1 @@ -Subproject commit 463fc49d17bfab846cceba48bccc02ef285e6cba +Subproject commit 0382e3acdb8433e1d9c33ca5947784e78134f838 ===================================== libraries/hpc ===================================== @@ -1 +1 @@ -Subproject commit f73c482db30a40cfa12074de51335b70a0974931 +Subproject commit 43bb9061a748aee6a95a9f1db33a2b1e5f770634 ===================================== libraries/parsec ===================================== @@ -1 +1 @@ -Subproject commit ce416997e15438ca616667995660e123ef7e219d +Subproject commit 190492494fe92e8dd42165190b7ac112be1f7389 ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit 1afc36ecd38c069251a836e1c1c8b3a3043ddc01 +Subproject commit 8f4ecebb6578a179a6c04074cb06600683e2e50c ===================================== libraries/stm ===================================== @@ -1 +1 @@ -Subproject commit faf9904137044e35a589c7c1579e1bfa03789c84 +Subproject commit 444f672416a354c3cfde9d94ec237a36be46ef59 ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -55,7 +55,7 @@ Library Language.Haskell.TH.Lib.Map build-depends: - base >= 4.11 && < 4.15, + base >= 4.11 && < 4.16, ghc-boot-th == @ProjectVersionMunged@, ghc-prim, pretty == 1.1.* ===================================== libraries/terminfo ===================================== @@ -1 +1 @@ -Subproject commit 27e694688d2d6eee69959a8b6a128c584c84aa72 +Subproject commit 3ebb36f4a2c42b74ec4e35efccc2be34c198a830 ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 1a993b89c570e03ba74f196f5d065a0ebe624010 +Subproject commit ea13d990580273a883368793dfbb826cab5a22d4 ===================================== testsuite/tests/dependent/should_compile/T14729.stderr ===================================== @@ -11,5 +11,5 @@ COERCION AXIOMS FAMILY INSTANCES type instance F Int = Bool -- Defined at T14729.hs:10:15 Dependent modules: [] -Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, - integer-gmp-1.0.2.0] +Dependent packages: [base-4.15.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] ===================================== testsuite/tests/dependent/should_compile/T15743.stderr ===================================== @@ -3,5 +3,5 @@ TYPE CONSTRUCTORS forall {k1} k2 (k3 :: k2). Proxy k3 -> k1 -> k2 -> * roles nominal nominal nominal phantom phantom phantom Dependent modules: [] -Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, - integer-gmp-1.0.2.0] +Dependent packages: [base-4.15.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] ===================================== testsuite/tests/dependent/should_compile/T15743e.stderr ===================================== @@ -52,5 +52,5 @@ DATA CONSTRUCTORS (d :: Proxy k5) (e :: Proxy k7). f c -> T k8 a b f c d e Dependent modules: [] -Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, - integer-gmp-1.0.2.0] +Dependent packages: [base-4.15.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] ===================================== testsuite/tests/indexed-types/should_compile/T15711.stderr ===================================== @@ -3,5 +3,5 @@ TYPE CONSTRUCTORS associated type family F{2} :: forall a. Maybe a -> * roles nominal nominal Dependent modules: [] -Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, - integer-gmp-1.0.2.0] +Dependent packages: [base-4.15.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] ===================================== testsuite/tests/indexed-types/should_compile/T15852.stderr ===================================== @@ -9,5 +9,5 @@ FAMILY INSTANCES data instance forall {k1} {k2} {j :: k1} {c :: k2}. DF (Proxy c) -- Defined at T15852.hs:10:15 Dependent modules: [] -Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, - integer-gmp-1.0.2.0] +Dependent packages: [base-4.15.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] ===================================== testsuite/tests/polykinds/T15592.stderr ===================================== @@ -5,5 +5,5 @@ DATA CONSTRUCTORS MkT :: forall {k} k1 (f :: k1 -> k -> *) (a :: k1) (b :: k). f a b -> T f a b -> T f a b Dependent modules: [] -Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, - integer-gmp-1.0.2.0] +Dependent packages: [base-4.15.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] ===================================== testsuite/tests/polykinds/T15592b.stderr ===================================== @@ -4,5 +4,5 @@ TYPE CONSTRUCTORS forall k (f :: k -> *) (a :: k). f a -> * roles nominal nominal nominal nominal Dependent modules: [] -Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, - integer-gmp-1.0.2.0] +Dependent packages: [base-4.15.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] ===================================== testsuite/tests/printer/T18052a.stderr ===================================== @@ -6,7 +6,7 @@ TYPE CONSTRUCTORS PATTERN SYNONYMS (:||:) :: forall {a} {b}. a -> b -> (a, b) Dependent modules: [] -Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, +Dependent packages: [base-4.15.0.0, ghc-prim-0.6.1, integer-gmp-1.0.3.0] ==================== Tidy Core ==================== ===================================== testsuite/tests/typecheck/should_compile/T12763.stderr ===================================== @@ -8,5 +8,5 @@ COERCION AXIOMS CLASS INSTANCES instance C Int -- Defined at T12763.hs:9:10 Dependent modules: [] -Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, - integer-gmp-1.0.2.0] +Dependent packages: [base-4.15.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] ===================================== testsuite/tests/typecheck/should_compile/subsumption_sort_hole_fits.stderr ===================================== @@ -9,10 +9,10 @@ subsumption_sort_hole_fits.hs:2:5: warning: [-Wtyped-holes (in -Wdefault)] Valid hole fits include lines :: String -> [String] (imported from ‘Prelude’ at subsumption_sort_hole_fits.hs:1:1 - (and originally defined in ‘base-4.14.0.0:Data.OldList’)) + (and originally defined in ‘base-4.15.0.0:Data.OldList’)) words :: String -> [String] (imported from ‘Prelude’ at subsumption_sort_hole_fits.hs:1:1 - (and originally defined in ‘base-4.14.0.0:Data.OldList’)) + (and originally defined in ‘base-4.15.0.0:Data.OldList’)) read :: forall a. Read a => String -> a with read @[String] (imported from ‘Prelude’ at subsumption_sort_hole_fits.hs:1:1 ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 8134a3be2c01ab5f1b88fed86c4ad7cc2f417f0a +Subproject commit 7475d84fa8d3a764dd8b54f8513f21170103f976 ===================================== utils/hsc2hs ===================================== @@ -1 +1 @@ -Subproject commit 24100ea521596922d3edc8370b3d9f7b845ae4cf +Subproject commit e792dd8e5589d42a4d416f78df8efb70995f95e3 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3a81e8fb4a5d243ce443410906dda768a1f66e70 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/3a81e8fb4a5d243ce443410906dda768a1f66e70 You're receiving 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 30 01:06:01 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 29 May 2020 21:06:01 -0400 Subject: [Git][ghc/ghc][wip/T14482] ghc -M: Ensure that .hs-boot files are built before .hs files Message-ID: <5ed1b17975b67_6e263f9f0bb937fc2776169@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T14482 at Glasgow Haskell Compiler / GHC Commits: 8d428a9a by Ben Gamari at 2020-05-29T21:05:56-04:00 ghc -M: Ensure that .hs-boot files are built before .hs files See Note [Ensure hs-boot files are built before source files]. Fixes #14882. - - - - - 1 changed file: - compiler/GHC/Driver/MakeFile.hs Changes: ===================================== compiler/GHC/Driver/MakeFile.hs ===================================== @@ -93,7 +93,9 @@ doMkDependHS srcs = do -- and complaining about cycles hsc_env <- getSession root <- liftIO getCurrentDirectory - mapM_ (liftIO . processDeps dflags hsc_env excl_mods root (mkd_tmp_hdl files)) sorted + + mapM_ (liftIO . processDeps dflags hsc_env (mgBootModules module_graph) + excl_mods root (mkd_tmp_hdl files)) sorted -- If -ddump-mod-cycles, show cycles in the module graph liftIO $ dumpModCycles dflags module_graph @@ -178,10 +180,11 @@ beginMkDependHS dflags = do processDeps :: DynFlags -> HscEnv - -> [ModuleName] - -> FilePath - -> Handle -- Write dependencies to here - -> SCC ModSummary + -> ModuleSet -- ^ modules with hs-boot files + -> [ModuleName] -- ^ modules to exclude + -> FilePath -- ^ root directory + -> Handle -- ^ Write dependencies to here + -> SCC ModSummary -- ^ a SCC of dependent modules -> IO () -- Write suitable dependencies to handle -- Always: @@ -198,11 +201,11 @@ processDeps :: DynFlags -- -- For {-# SOURCE #-} imports the "hi" will be "hi-boot". -processDeps dflags _ _ _ _ (CyclicSCC nodes) +processDeps dflags _ _ _ _ _ (CyclicSCC nodes) = -- There shouldn't be any cycles; report them throwGhcExceptionIO (ProgramError (showSDoc dflags $ GHC.cyclicModuleErr nodes)) -processDeps dflags hsc_env excl_mods root hdl (AcyclicSCC node) +processDeps dflags hsc_env boot_mods excl_mods root hdl (AcyclicSCC node) = do { let extra_suffixes = depSuffixes dflags include_pkg_deps = depIncludePkgDeps dflags src_file = msHsFilePath node @@ -249,9 +252,41 @@ processDeps dflags hsc_env excl_mods root hdl (AcyclicSCC node) ; do_imps True (ms_srcimps node) ; do_imps False (ms_imps node) - } + -- For each module with a hs-boot file, emit a + -- dependency from the object to the hi-boot file. + -- See Note [Ensure hs-boot files are built before + -- source files]. + ; case (ms_hsc_src, has_boot_file node) of + (HsSrcFile, Just hs_boot_loc) -> + writeDependency root hdl obj_files (ml_hi_file hs_boot_loc) + _ -> return () + } + where + has_boot_file :: ModSummary -> Maybe ModLocation + has_boot_file ms + | ms_mod ms `elemModuleSet` boot_mods + = Just $ addBootSuffixLocn (ms_location ms) + | otherwise + = Nothing + +-- Note [Ensure hs-boot files are built before source files] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- In general we need to take care to ensure that `.hs-boot` files +-- are built before their associated `.hs` files. The reason is that +-- the existence of a .hi-boot file will affect the code generated +-- during the compilation of the .hs file. If the .hi-boot file is *not* +-- built prior to the .hs file then you can end up with situations like +-- #14481, where the logic which makes DFun decls work in boot files +-- fails to fire (see Note [DFun impedance matching] and Note [DFun +-- knot-tying] in GHC.Tc.Module. +-- +-- Consequently, we inject "artificial" dependencies from objects to +-- the hi-boot files of any modules which produced the object. This avoids +-- #14481 and #14482. +-- + findDependency :: HscEnv -> SrcSpan -> Maybe FastString -- package qualifier, if any View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8d428a9a0b2cbcfdd4f86d7d64cd73cf6350556b -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8d428a9a0b2cbcfdd4f86d7d64cd73cf6350556b You're receiving 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 30 01:19:12 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 29 May 2020 21:19:12 -0400 Subject: [Git][ghc/ghc][wip/tyconapp-opts] 8 commits: Notes from call Message-ID: <5ed1b4904afdc_6e2656b8118277665a@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/tyconapp-opts at Glasgow Haskell Compiler / GHC Commits: fe0dbf42 by Ben Gamari at 2020-05-29T21:19:01-04:00 Notes from call - - - - - 1e2408ff by Ben Gamari at 2020-05-29T21:19:03-04:00 Shortcut mkTvSubstPrs on empty list Surprisingly enough this reduces compilation time on Cabal by nearly 1%. - - - - - 927e0134 by Ben Gamari at 2020-05-29T21:19:03-04:00 Shortcut coreView - - - - - caddb71f by Ben Gamari at 2020-05-29T21:19:03-04:00 expandSynTyCon_maybe: Special-case nullary tycons This avoids both allocation and some instructions. - - - - - 84e8b819 by Ben Gamari at 2020-05-29T21:19:03-04:00 Optimise tcView - - - - - bc717022 by Ben Gamari at 2020-05-29T21:19:03-04:00 Inline expandSynTyCon_maybe This is necessary to avoid some needless allocation since we currently lack nested CPR on sums. Metric Decrease: T12227 T12545 T12707 T14683 T3064 T5631 T5642 T9020 T9872a - - - - - a442c3e5 by Ben Gamari at 2020-05-29T21:19:03-04:00 Some cleanup - - - - - 7951df0d by Ben Gamari at 2020-05-29T21:19:03-04:00 hi Metric Decrease: T13035 haddock.Cabal haddock.base Metric Increase: T9872c - - - - - 19 changed files: - compiler/GHC/Builtin/Types.hs - compiler/GHC/Builtin/Types/Prim.hs - compiler/GHC/Core/TyCo/Subst.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unify.hs - compiler/GHC/Tc/Solver/Canonical.hs - compiler/GHC/Tc/Utils/TcType.hs - testsuite/tests/deSugar/should_compile/T2431.stderr - testsuite/tests/deriving/should_compile/T14578.stderr - testsuite/tests/plugins/plugins09.stdout - testsuite/tests/plugins/plugins10.stdout - testsuite/tests/plugins/plugins11.stdout - testsuite/tests/plugins/static-plugins.stdout - testsuite/tests/printer/T18052a.stderr - testsuite/tests/simplCore/should_compile/T13143.stderr - testsuite/tests/simplCore/should_compile/T18013.stderr - testsuite/tests/simplCore/should_compile/T7360.stderr - testsuite/tests/typecheck/should_compile/T13032.stderr Changes: ===================================== compiler/GHC/Builtin/Types.hs ===================================== @@ -145,6 +145,7 @@ import GHC.Types.Id import GHC.Settings.Constants ( mAX_TUPLE_SIZE, mAX_CTUPLE_SIZE, mAX_SUM_SIZE ) import GHC.Unit.Module ( Module ) import GHC.Core.Type +import qualified GHC.Core.TyCo.Rep as TyCoRep (Type(TyConApp)) import GHC.Types.RepType import GHC.Core.DataCon import {-# SOURCE #-} GHC.Core.ConLike @@ -647,7 +648,7 @@ constraintKindTyCon :: TyCon constraintKindTyCon = pcTyCon constraintKindTyConName Nothing [] [] liftedTypeKind, typeToTypeKind, constraintKind :: Kind -liftedTypeKind = tYPE liftedRepTy +liftedTypeKind = TyCoRep.TyConApp liftedTypeKindTyCon [] typeToTypeKind = liftedTypeKind `mkVisFunTy` liftedTypeKind constraintKind = mkTyConApp constraintKindTyCon [] @@ -1215,8 +1216,8 @@ runtimeRepTy = mkTyConTy runtimeRepTyCon -- type Type = tYPE 'LiftedRep liftedTypeKindTyCon :: TyCon liftedTypeKindTyCon = buildSynTyCon liftedTypeKindTyConName - [] liftedTypeKind [] - (tYPE liftedRepTy) + [] liftedTypeKind [] rhs + where rhs = TyCoRep.TyConApp tYPETyCon [liftedRepTy] runtimeRepTyCon :: TyCon runtimeRepTyCon = pcTyCon runtimeRepTyConName Nothing [] ===================================== compiler/GHC/Builtin/Types/Prim.hs ===================================== @@ -541,8 +541,35 @@ mkPrimTcName built_in_syntax occ key tycon -- | Given a RuntimeRep, applies TYPE to it. -- see Note [TYPE and RuntimeRep] tYPE :: Type -> Type +tYPE (TyConApp tc []) + | tc `hasKey` liftedRepDataConKey = liftedTypeKind -- TYPE 'LiftedPtrRep tYPE rr = TyConApp tYPETyCon [rr] +-- Note [Prefer Type over TYPE 'LiftedPtrRep] +-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +-- +-- The Core of nearly any program will have numerous occurrences of +-- @TYPE 'LiftedPtrRep@ floating about. Consequently, we try hard to ensure +-- that operations on such types are efficient: +-- +-- * Instead of representing the lifted kind as +-- @TyConApp tYPETyCon [liftedRepDataCon]@ we rather prefer to +-- use the 'GHC.Types.Type' type synonym (available in GHC as +-- 'TysPrim.liftedTypeKind'). Note only is this a smaller AST but it also +-- guarantees sharing on the heap. +-- +-- * To avoid allocating 'TyConApp' constructors 'TysPrim.tYPE' +-- catches the lifted case and uses `liftedTypeKind` instead of building an +-- application. +-- +-- * Similarly, 'Type.mkTyConApp' catches applications of TYPE and +-- handles them using 'TysPrim.tYPE', ensuring that it benefits from the +-- optimisation described above. +-- +-- * Since 'liftedTypeKind' is a nullary type synonym application, +-- it benefits from the optimisation described in Note [Comparing nullary +-- type synonyms] in "GHC.Core.Type". + {- ************************************************************************ * * ===================================== compiler/GHC/Core/TyCo/Subst.hs ===================================== @@ -423,6 +423,7 @@ zipTCvSubst tcvs tys -- | Generates the in-scope set for the 'TCvSubst' from the types in the -- incoming environment. No CoVars, please! mkTvSubstPrs :: [(TyVar, Type)] -> TCvSubst +mkTvSubstPrs [] = emptyTCvSubst mkTvSubstPrs prs = ASSERT2( onlyTyVarsAndNoCoercionTy, text "prs" <+> ppr prs ) mkTvSubst in_scope tenv ===================================== compiler/GHC/Core/TyCon.hs ===================================== @@ -2302,10 +2302,12 @@ expandSynTyCon_maybe -- ^ Expand a type synonym application, if any expandSynTyCon_maybe tc tys | SynonymTyCon { tyConTyVars = tvs, synTcRhs = rhs, tyConArity = arity } <- tc - = case tys `listLengthCmp` arity of - GT -> Just (tvs `zip` tys, rhs, drop arity tys) - EQ -> Just (tvs `zip` tys, rhs, []) - LT -> Nothing + = case tys of + [] -> Just ([], rhs, []) -- Avoid a bit of work in the case of nullary synonyms + _ -> case tys `listLengthCmp` arity of + GT -> Just (tvs `zip` tys, rhs, drop arity tys) + EQ -> Just (tvs `zip` tys, rhs, []) + LT -> Nothing | otherwise = Nothing ===================================== compiler/GHC/Core/Type.hs ===================================== @@ -353,15 +353,16 @@ See also #11715, which tracks removing this inconsistency. -} -- | Gives the typechecker view of a type. This unwraps synonyms but --- leaves 'Constraint' alone. c.f. coreView, which turns Constraint into --- TYPE LiftedRep. Returns Nothing if no unwrapping happens. +-- leaves 'Constraint' alone. c.f. 'coreView', which turns 'Constraint' into +-- @TYPE LiftedRep at . Returns 'Nothing' if no unwrapping happens. -- See also Note [coreView vs tcView] {-# INLINE tcView #-} tcView :: Type -> Maybe Type -tcView (TyConApp tc tys) | Just (tenv, rhs, tys') <- expandSynTyCon_maybe tc tys - = Just (mkAppTys (substTy (mkTvSubstPrs tenv) rhs) tys') +tcView (TyConApp tc tys) + | res@(Just _) <- expandSynTyConApp_maybe tc tys + = res -- The free vars of 'rhs' should all be bound by 'tenv', so it's - -- ok to use 'substTy' here. + -- ok to use 'substTy' here (which is what expandSynTyConApp_maybe does). -- See also Note [The substitution invariant] in GHC.Core.TyCo.Subst. -- Its important to use mkAppTys, rather than (foldl AppTy), -- because the function part might well return a @@ -370,17 +371,16 @@ tcView _ = Nothing {-# INLINE coreView #-} coreView :: Type -> Maybe Type --- ^ This function Strips off the /top layer only/ of a type synonym +-- ^ This function strips off the /top layer only/ of a type synonym -- application (if any) its underlying representation type. --- Returns Nothing if there is nothing to look through. +-- Returns 'Nothing' if there is nothing to look through. -- This function considers 'Constraint' to be a synonym of @TYPE LiftedRep at . -- -- By being non-recursive and inlined, this case analysis gets efficiently -- joined onto the case analysis that the caller is already doing coreView ty@(TyConApp tc tys) - | Just (tenv, rhs, tys') <- expandSynTyCon_maybe tc tys - = Just (mkAppTys (substTy (mkTvSubstPrs tenv) rhs) tys') - -- This equation is exactly like tcView + | res@(Just _) <- expandSynTyConApp_maybe tc tys + = res -- At the Core level, Constraint = Type -- See Note [coreView vs tcView] @@ -391,6 +391,21 @@ coreView ty@(TyConApp tc tys) coreView _ = Nothing ----------------------------------------------- +expandSynTyConApp_maybe :: TyCon -> [Type] -> Maybe Type +expandSynTyConApp_maybe tc tys + | Just (tvs, rhs) <- synTyConDefn_maybe tc + = case tys of + [] -> Just (mkAppTys rhs tys) + _ -> case tys `listLengthCmp` arity of + GT -> Just (mkAppTys rhs' (drop arity tys)) + EQ -> Just rhs' + LT -> Nothing + where + arity = tyConArity tc + rhs' = substTy (mkTvSubstPrs (tvs `zip` tys)) rhs + | otherwise + = Nothing + expandTypeSynonyms :: Type -> Type -- ^ Expand out all type synonyms. Actually, it'd suffice to expand out -- just the ones that discard type variables (e.g. type Funny a = Int) @@ -1222,8 +1237,10 @@ TyConApp constructors were all duplicates of `Type` applied to no arguments. Therefore in `mkTyConApp` we have a special case for `Type` to ensure that only one `TyConApp 'Type []` closure is allocated during the course of -compilation. In order to avoid a potentially expensive series of checks in -`mkTyConApp` only this egregious case is special cased at the moment. +compilation. + +We also have a similar special-case for applications of TYPE; see +Note [Prefer Type over TYPE 'LiftedPtrRep] for details. --------------------------------------------------------------------- @@ -1243,6 +1260,10 @@ mkTyConApp tycon tys | tycon == liftedTypeKindTyCon = ASSERT2( null tys, ppr tycon $$ ppr tys ) liftedTypeKindTyConApp + -- Note [Prefer Type over TYPE 'LiftedPtrRep] + | tycon == tYPETyCon + , [rep] <- tys + = tYPE rep | otherwise = TyConApp tycon tys @@ -2200,6 +2221,36 @@ But the left is an AppTy while the right is a TyConApp. The solution is to use repSplitAppTy_maybe to break up the TyConApp into its pieces and then continue. Easy to do, but also easy to forget to do. + +Note [Comparing nullary type synonyms] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider the task of testing equality between two 'Type's of the form + + TyConApp tc [] + +where @tc@ is a type synonym. A naive way to perform this comparison these +would first expand the synonym and then compare the resulting expansions. + +However, this is obviously wasteful and the RHS of @tc@ may be large; it is +much better to rather compare the TyCons directly. Consequently, before +expanding type synonyms in type comparisons we first look for a nullary +TyConApp and simply compare the TyCons if we find one. Of course, if we find +that the TyCons are *not* equal then we still need to perform the expansion as +their RHSs may still be equal. + +We perform this optimisation in a number of places: + + * GHC.Core.Types.eqType + * GHC.Core.Types.nonDetCmpType + * GHC.Core.Unify.unify_ty + * TcCanonical.can_eq_nc' + * TcUnify.uType + +This optimisation is especially helpful for the ubiquitous GHC.Types.Type, +since GHC prefers to use the type synonym over @TYPE 'LiftedPtr@ applications +whenever possible. See [Prefer Type over TYPE 'LiftedPtrRep] in TysPrim for +details. + -} eqType :: Type -> Type -> Bool @@ -2308,6 +2359,10 @@ nonDetCmpTypeX env orig_t1 orig_t2 = -- Returns both the resulting ordering relation between the two types -- and whether either contains a cast. go :: RnEnv2 -> Type -> Type -> TypeOrdering + -- See Note [Comparing nullary type synonyms]. + go _ (TyConApp tc1 []) (TyConApp tc2 []) + | tc1 == tc2 + = TEQ go env t1 t2 | Just t1' <- coreView t1 = go env t1' t2 | Just t2' <- coreView t2 = go env t1 t2' ===================================== compiler/GHC/Core/Unify.hs ===================================== @@ -956,6 +956,11 @@ unify_ty :: UMEnv -- Respects newtypes, PredTypes unify_ty env ty1 ty2 kco + -- See Note [Comparing nullary type synonyms] in GHC.Core.Type. + | TyConApp tc1 [] <- ty1 + , TyConApp tc2 [] <- ty2 + , tc1 == tc2 = return () + -- TODO: More commentary needed here | Just ty1' <- tcView ty1 = unify_ty env ty1' ty2 kco | Just ty2' <- tcView ty2 = unify_ty env ty1 ty2' kco ===================================== compiler/GHC/Tc/Solver/Canonical.hs ===================================== @@ -953,6 +953,11 @@ can_eq_nc' -> Type -> Type -- RHS, after and before type-synonym expansion, resp -> TcS (StopOrContinue Ct) +-- See Note [Comparing nullary type synonyms] in GHC.Core.Type. +can_eq_nc' _flat _rdr_env _envs ev eq_rel ty1@(TyConApp tc1 []) _ps_ty1 (TyConApp tc2 []) _ps_ty2 + | tc1 == tc2 + = canEqReflexive ev eq_rel ty1 + -- Expand synonyms first; see Note [Type synonyms and canonicalization] can_eq_nc' flat rdr_env envs ev eq_rel ty1 ps_ty1 ty2 ps_ty2 | Just ty1' <- tcView ty1 = can_eq_nc' flat rdr_env envs ev eq_rel ty1' ps_ty1 ty2 ps_ty2 ===================================== compiler/GHC/Tc/Utils/TcType.hs ===================================== @@ -1528,6 +1528,11 @@ tc_eq_type keep_syns vis_only orig_ty1 orig_ty2 = go orig_env orig_ty1 orig_ty2 where go :: RnEnv2 -> Type -> Type -> Bool + -- See Note [Comparing nullary type synonyms] in GHC.Core.Type. + go _ (TyConApp tc1 []) (TyConApp tc2 []) + | tc1 == tc2 + = True + go env t1 t2 | not keep_syns, Just t1' <- tcView t1 = go env t1' t2 go env t1 t2 | not keep_syns, Just t2' <- tcView t2 = go env t1 t2' ===================================== testsuite/tests/deSugar/should_compile/T2431.stderr ===================================== @@ -1,9 +1,9 @@ ==================== Tidy Core ==================== Result size of Tidy Core - = {terms: 63, types: 43, coercions: 1, joins: 0/0} + = {terms: 63, types: 39, coercions: 1, joins: 0/0} --- RHS size: {terms: 2, types: 4, coercions: 1, joins: 0/0} +-- RHS size: {terms: 2, types: 3, coercions: 1, joins: 0/0} T2431.$WRefl [InlPrag=INLINE[0] CONLIKE] :: forall a. a :~: a [GblId[DataConWrapper], Caf=NoCafRefs, @@ -15,7 +15,7 @@ T2431.$WRefl [InlPrag=INLINE[0] CONLIKE] :: forall a. a :~: a T2431.$WRefl = \ (@a) -> T2431.Refl @a @a @~(_N :: a GHC.Prim.~# a) --- RHS size: {terms: 4, types: 8, coercions: 0, joins: 0/0} +-- RHS size: {terms: 4, types: 7, coercions: 0, joins: 0/0} absurd :: forall a. (Int :~: Bool) -> a [GblId, Arity=1, Str=b, Cpr=b, Unf=OtherCon []] absurd = \ (@a) (x :: Int :~: Bool) -> case x of { } @@ -110,6 +110,3 @@ T2431.$tc'Refl $tc'Refl2 1# $krep3 - - - ===================================== testsuite/tests/deriving/should_compile/T14578.stderr ===================================== @@ -9,40 +9,39 @@ Derived class instances: GHC.Base.sconcat :: GHC.Base.NonEmpty (T14578.Wat f g a) -> T14578.Wat f g a GHC.Base.stimes :: - forall (b :: TYPE 'GHC.Types.LiftedRep). + forall (b :: GHC.Types.Type). 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 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 @GHC.Types.Type @GHC.Types.Type f g) a + -> T14578.App (Data.Functor.Compose.Compose @GHC.Types.Type @GHC.Types.Type f g) a + -> T14578.App (Data.Functor.Compose.Compose @GHC.Types.Type @GHC.Types.Type 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 f g) a)) + ((GHC.Base.<>) + @(T14578.App (Data.Functor.Compose.Compose @GHC.Types.Type @GHC.Types.Type f g) a)) GHC.Base.sconcat = GHC.Prim.coerce - @(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.App (Data.Functor.Compose.Compose @GHC.Types.Type @GHC.Types.Type f g) a) + -> T14578.App (Data.Functor.Compose.Compose @GHC.Types.Type @GHC.Types.Type 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 f g) a)) + @(T14578.App (Data.Functor.Compose.Compose @GHC.Types.Type @GHC.Types.Type f g) a)) GHC.Base.stimes = GHC.Prim.coerce @(b - -> T14578.App (Data.Functor.Compose.Compose f g) a - -> T14578.App (Data.Functor.Compose.Compose f g) a) + -> T14578.App (Data.Functor.Compose.Compose @GHC.Types.Type @GHC.Types.Type f g) a + -> T14578.App (Data.Functor.Compose.Compose @GHC.Types.Type @GHC.Types.Type f g) a) @(b -> T14578.Wat f g a -> T14578.Wat f g a) (GHC.Base.stimes - @(T14578.App (Data.Functor.Compose.Compose f g) a)) + @(T14578.App (Data.Functor.Compose.Compose @GHC.Types.Type @GHC.Types.Type f g) a)) instance GHC.Base.Functor f => GHC.Base.Functor (T14578.App f) where GHC.Base.fmap :: - forall (a :: TYPE 'GHC.Types.LiftedRep) - (b :: TYPE 'GHC.Types.LiftedRep). + forall (a :: GHC.Types.Type) (b :: GHC.Types.Type). (a -> b) -> T14578.App f a -> T14578.App f b (GHC.Base.<$) :: - forall (a :: TYPE 'GHC.Types.LiftedRep) - (b :: TYPE 'GHC.Types.LiftedRep). + forall (a :: GHC.Types.Type) (b :: GHC.Types.Type). a -> T14578.App f b -> T14578.App f a GHC.Base.fmap = GHC.Prim.coerce @@ -55,24 +54,20 @@ Derived class instances: instance GHC.Base.Applicative f => GHC.Base.Applicative (T14578.App f) where - GHC.Base.pure :: - forall (a :: TYPE 'GHC.Types.LiftedRep). a -> T14578.App f a + GHC.Base.pure :: forall (a :: GHC.Types.Type). a -> T14578.App f a (GHC.Base.<*>) :: - forall (a :: TYPE 'GHC.Types.LiftedRep) - (b :: TYPE 'GHC.Types.LiftedRep). + forall (a :: GHC.Types.Type) (b :: GHC.Types.Type). T14578.App f (a -> b) -> T14578.App f a -> T14578.App f b GHC.Base.liftA2 :: - forall (a :: TYPE 'GHC.Types.LiftedRep) - (b :: TYPE 'GHC.Types.LiftedRep) - (c :: TYPE 'GHC.Types.LiftedRep). + forall (a :: GHC.Types.Type) + (b :: GHC.Types.Type) + (c :: GHC.Types.Type). (a -> b -> c) -> T14578.App f a -> T14578.App f b -> T14578.App f c (GHC.Base.*>) :: - forall (a :: TYPE 'GHC.Types.LiftedRep) - (b :: TYPE 'GHC.Types.LiftedRep). + forall (a :: GHC.Types.Type) (b :: GHC.Types.Type). T14578.App f a -> T14578.App f b -> T14578.App f b (GHC.Base.<*) :: - forall (a :: TYPE 'GHC.Types.LiftedRep) - (b :: TYPE 'GHC.Types.LiftedRep). + forall (a :: GHC.Types.Type) (b :: GHC.Types.Type). T14578.App f a -> T14578.App f b -> T14578.App f a GHC.Base.pure = GHC.Prim.coerce ===================================== testsuite/tests/plugins/plugins09.stdout ===================================== @@ -3,7 +3,6 @@ interfacePlugin: Prelude interfacePlugin: GHC.Float interfacePlugin: GHC.Base typeCheckPlugin (rn) -interfacePlugin: GHC.Types typeCheckPlugin (tc) interfacePlugin: GHC.Integer.Type interfacePlugin: GHC.Natural ===================================== testsuite/tests/plugins/plugins10.stdout ===================================== @@ -6,7 +6,6 @@ interfacePlugin: GHC.Float interfacePlugin: GHC.Base interfacePlugin: Language.Haskell.TH.Syntax typeCheckPlugin (rn) -interfacePlugin: GHC.Types typeCheckPlugin (tc) interfacePlugin: GHC.Integer.Type interfacePlugin: GHC.Natural ===================================== testsuite/tests/plugins/plugins11.stdout ===================================== @@ -3,7 +3,6 @@ interfacePlugin: Prelude interfacePlugin: GHC.Float interfacePlugin: GHC.Base typeCheckPlugin (rn) -interfacePlugin: GHC.Types typeCheckPlugin (tc) interfacePlugin: GHC.Integer.Type interfacePlugin: GHC.Natural ===================================== testsuite/tests/plugins/static-plugins.stdout ===================================== @@ -5,11 +5,11 @@ interfacePlugin: GHC.Float interfacePlugin: GHC.Base interfacePlugin: System.IO typeCheckPlugin (rn) -interfacePlugin: GHC.Prim -interfacePlugin: GHC.Show interfacePlugin: GHC.Types +interfacePlugin: GHC.Show interfacePlugin: GHC.TopHandler typeCheckPlugin (tc) +interfacePlugin: GHC.Prim interfacePlugin: GHC.CString interfacePlugin: GHC.Integer.Type interfacePlugin: GHC.Natural ===================================== testsuite/tests/printer/T18052a.stderr ===================================== @@ -11,7 +11,7 @@ Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, ==================== Tidy Core ==================== Result size of Tidy Core - = {terms: 18, types: 53, coercions: 0, joins: 0/0} + = {terms: 18, types: 46, coercions: 0, joins: 0/0} -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} T18052a.$b:||: :: forall {a} {b}. a -> b -> (a, b) @@ -23,7 +23,7 @@ T18052a.$b:||: = GHC.Tuple.(,) [GblId] (+++) = (++) --- RHS size: {terms: 13, types: 20, coercions: 0, joins: 0/0} +-- RHS size: {terms: 13, types: 18, coercions: 0, joins: 0/0} T18052a.$m:||: :: forall {rep :: GHC.Types.RuntimeRep} {r :: TYPE rep} {a} {b}. (a, b) -> (a -> b -> r) -> (GHC.Prim.Void# -> r) -> r ===================================== testsuite/tests/simplCore/should_compile/T13143.stderr ===================================== @@ -1,17 +1,17 @@ ==================== Tidy Core ==================== Result size of Tidy Core - = {terms: 71, types: 44, coercions: 0, joins: 0/0} + = {terms: 71, types: 40, coercions: 0, joins: 0/0} Rec { --- RHS size: {terms: 4, types: 4, coercions: 0, joins: 0/0} +-- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0} T13143.$wf [InlPrag=NOINLINE, Occ=LoopBreaker] :: forall {a}. GHC.Prim.Void# -> a [GblId, Arity=1, Str=b, Cpr=b, Unf=OtherCon []] T13143.$wf = \ (@a) _ [Occ=Dead] -> T13143.$wf @a GHC.Prim.void# end Rec } --- RHS size: {terms: 4, types: 4, coercions: 0, joins: 0/0} +-- RHS size: {terms: 4, types: 3, coercions: 0, joins: 0/0} f [InlPrag=NOUSERINLINE[0]] :: forall a. Int -> a [GblId, Arity=1, ===================================== testsuite/tests/simplCore/should_compile/T18013.stderr ===================================== @@ -129,9 +129,9 @@ Rule fired: Class op fmap (BUILTIN) ==================== Tidy Core ==================== Result size of Tidy Core - = {terms: 52, types: 106, coercions: 15, joins: 0/1} + = {terms: 52, types: 101, coercions: 15, joins: 0/1} --- RHS size: {terms: 37, types: 87, coercions: 15, joins: 0/1} +-- RHS size: {terms: 37, types: 84, coercions: 15, joins: 0/1} mapMaybeRule :: forall a b. Rule IO a b -> Rule IO (Maybe a) (Maybe b) [GblId, ===================================== testsuite/tests/simplCore/should_compile/T7360.stderr ===================================== @@ -1,7 +1,7 @@ ==================== Tidy Core ==================== Result size of Tidy Core - = {terms: 106, types: 47, coercions: 0, joins: 0/0} + = {terms: 106, types: 45, coercions: 0, joins: 0/0} -- RHS size: {terms: 6, types: 3, coercions: 0, joins: 0/0} T7360.$WFoo3 [InlPrag=INLINE[0] CONLIKE] :: Int -> Foo @@ -31,7 +31,7 @@ T7360.fun4 :: () WorkFree=False, Expandable=False, Guidance=IF_ARGS [] 20 0}] T7360.fun4 = fun1 T7360.Foo1 --- RHS size: {terms: 11, types: 8, coercions: 0, joins: 0/0} +-- RHS size: {terms: 11, types: 7, coercions: 0, joins: 0/0} fun2 :: forall {a}. [a] -> ((), Int) [GblId, Arity=1, ===================================== testsuite/tests/typecheck/should_compile/T13032.stderr ===================================== @@ -1,9 +1,9 @@ ==================== Desugar (after optimization) ==================== Result size of Desugar (after optimization) - = {terms: 13, types: 24, coercions: 0, joins: 0/0} + = {terms: 13, types: 18, coercions: 0, joins: 0/0} --- RHS size: {terms: 6, types: 11, coercions: 0, joins: 0/0} +-- RHS size: {terms: 6, types: 8, coercions: 0, joins: 0/0} f :: forall a b. (a ~ b) => a -> b -> Bool [LclIdX, Unf=Unf{Src=, TopLvl=True, Value=True, ConLike=True, View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a5a182b0117a9786d4c0f30280126570ee2fbea5...7951df0db45713b316de80b12509babaea73d9af -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a5a182b0117a9786d4c0f30280126570ee2fbea5...7951df0db45713b316de80b12509babaea73d9af You're receiving 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 30 02:29:07 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Fri, 29 May 2020 22:29:07 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/sjakobi/deprecate-option-v2 Message-ID: <5ed1c4f34eeae_6e2656b811827858fd@gitlab.haskell.org.mail> Simon Jakobi pushed new branch wip/sjakobi/deprecate-option-v2 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/sjakobi/deprecate-option-v2 You're receiving 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 30 03:07:02 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Fri, 29 May 2020 23:07:02 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/perform-blocking-gc Message-ID: <5ed1cdd6df3d1_6e2656b8118279209@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/perform-blocking-gc at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/perform-blocking-gc You're receiving 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 30 06:40:50 2020 From: gitlab at gitlab.haskell.org (Alex D) Date: Sat, 30 May 2020 02:40:50 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T17669-test Message-ID: <5ed1fff2cc2c8_6e2656b811828026eb@gitlab.haskell.org.mail> Alex D pushed new branch wip/T17669-test at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T17669-test You're receiving 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 30 10:07:41 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 30 May 2020 06:07:41 -0400 Subject: [Git][ghc/ghc][master] 3 commits: rts: Teach getNumProcessors to return available processors Message-ID: <5ed2306d69a50_6e2611db28542818891@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 4413828b by Ben Gamari at 2020-05-30T06:07:31-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. - - - - - 1449435c by Ben Gamari at 2020-05-30T06:07:31-04:00 users-guide: Note change in getNumProcessors in users guide - - - - - 3d960169 by Ben Gamari at 2020-05-30T06:07:31-04:00 rts: Drop compatibility shims for Windows Vista We can now assume that the thread and processor group interfaces are available. - - - - - 7 changed files: - configure.ac - docs/users_guide/8.12.1-notes.rst - docs/users_guide/using-concurrent.rst - hadrian/src/Settings/Packages.hs - rts/ghc.mk - rts/posix/OSThreads.c - rts/win32/OSThreads.c Changes: ===================================== configure.ac ===================================== @@ -978,7 +978,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 ===================================== docs/users_guide/8.12.1-notes.rst ===================================== @@ -17,7 +17,7 @@ Highlights digit improvements in runtime for inner loops. In the mean this improved runtime by about 0.8%. For details - see ticket #17823. + see ticket :ghc-ticket:`17823`. Full details ------------ @@ -95,7 +95,7 @@ Language effectively allows users to choose which variables can or can't be instantiated through visible type application. More information can be found here: :ref:`Manually-defining-inferred-variables`. - + Compiler ~~~~~~~~ @@ -105,11 +105,18 @@ 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) + escaping spaces in file names with a backslash. (:ghc-ticket:`18027`) Runtime system ~~~~~~~~~~~~~~ +- :rts-flag:`-N` without a count now tries to respect the number of processors + in the process's affinity mask, making GHC's behavior more predictable in + containerized settings (:ghc-ticket:`14781`). + +- Support for Windows Vista has been dropped. GHC-compiled programs now require + Windows 7 or later. + Template Haskell ~~~~~~~~~~~~~~~~ ===================================== docs/users_guide/using-concurrent.rst ===================================== @@ -111,6 +111,7 @@ There are two ways to run a program on multiple processors: call use the RTS :rts-flag:`-N ⟨x⟩` options. .. rts-flag:: -N ⟨x⟩ + -N -maxN ⟨x⟩ Use ⟨x⟩ simultaneous threads when running the program. ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -462,4 +462,4 @@ rtsWarnings = mconcat -- and also centralizes the versioning. -- | Minimum supported Windows version. windowsVersion :: String -windowsVersion = "0x06000100" +windowsVersion = "0x06010000" ===================================== rts/ghc.mk ===================================== @@ -25,7 +25,7 @@ rts_VERSION = 1.0 # If we're compiling on windows, enforce that we only support Vista SP1+ # Adding this here means it doesn't have to be done in individual .c files # and also centralizes the versioning. -rts_WINVER = 0x06000100 +rts_WINVER = 0x06010000 # merge GhcLibWays and GhcRTSWays but strip out duplicates rts_WAYS = $(GhcLibWays) $(filter-out $(GhcLibWays),$(GhcRTSWays)) ===================================== 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)); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/aac19e6caa0c94e159610f124114186ee20bcdd1...3d96016926cc88506db416f87b6e4b68a3a0d25f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/aac19e6caa0c94e159610f124114186ee20bcdd1...3d96016926cc88506db416f87b6e4b68a3a0d25f You're receiving 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 30 10:08:17 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 30 May 2020 06:08:17 -0400 Subject: [Git][ghc/ghc][master] PPC NCG: Fix .size directive on powerpc64 ELF v1 Message-ID: <5ed23091a7da6_6e2681629e02823268@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 7f8f948c by Peter Trommler at 2020-05-30T06:08:07-04:00 PPC NCG: Fix .size directive on powerpc64 ELF v1 Thanks to Sergei Trofimovich for pointing out the issue. Fixes #18237 - - - - - 1 changed file: - compiler/GHC/CmmToAsm/PPC/Ppr.hs Changes: ===================================== compiler/GHC/CmmToAsm/PPC/Ppr.hs ===================================== @@ -86,8 +86,13 @@ pprNatCmmDecl config proc@(CmmProc top_info lbl _ (ListGraph blocks)) = pprSizeDecl :: Platform -> CLabel -> SDoc pprSizeDecl platform lbl = if osElfTarget (platformOS platform) - then text "\t.size" <+> ppr lbl <> text ", .-" <> ppr lbl + then text "\t.size" <+> prettyLbl <> text ", .-" <> codeLbl else empty + where + prettyLbl = ppr lbl + codeLbl + | platformArch platform == ArchPPC_64 ELF_V1 = char '.' <> prettyLbl + | otherwise = prettyLbl pprFunctionDescriptor :: CLabel -> SDoc pprFunctionDescriptor lab = pprGloblDecl lab View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7f8f948c024c46282228243391238d09b297cd9d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7f8f948c024c46282228243391238d09b297cd9d You're receiving 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 30 10:08:54 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 30 May 2020 06:08:54 -0400 Subject: [Git][ghc/ghc][master] Optimize GHC.Utils.Monad. Message-ID: <5ed230b6d7a_6e2656b81182826172@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 7c555b05 by Andreas Klebinger at 2020-05-30T06:08:43-04:00 Optimize GHC.Utils.Monad. Many functions in this module are recursive and as such are marked loop breakers. Which means they are unlikely to get an unfolding. This is *bad*. We always want to specialize them to specific Monads. Which requires a visible unfolding at the use site. I rewrote the recursive ones from: foo f x = ... foo x' ... to foo f x = go x where go x = ... As well as giving some pragmas to make all of them available for specialization. The end result is a reduction of allocations of about -1.4% for nofib/spectral/simple/Main.hs when compiled with `-O`. ------------------------- Metric Decrease: T12425 T14683 T5631 T9233 T9675 T9961 WWRec ------------------------- - - - - - 1 changed file: - compiler/GHC/Utils/Monad.hs Changes: ===================================== compiler/GHC/Utils/Monad.hs ===================================== @@ -138,22 +138,31 @@ mapAndUnzip5M :: Monad m => (a -> m (b,c,d,e,f)) -> [a] -> m ([b],[c],[d],[e],[f -- See Note [Inline @mapAndUnzipNM@ functions] above. mapAndUnzip5M f xs = unzip5 <$> traverse f xs +-- TODO: mapAccumLM is used in many places. Surely most of +-- these don't actually want to be lazy. We should add a strict +-- variant and use it where appropriate. + -- | Monadic version of mapAccumL mapAccumLM :: Monad m => (acc -> x -> m (acc, y)) -- ^ combining function -> acc -- ^ initial state -> [x] -- ^ inputs -> m (acc, [y]) -- ^ final state, outputs -mapAccumLM _ s [] = return (s, []) -mapAccumLM f s (x:xs) = do - (s1, x') <- f s x - (s2, xs') <- mapAccumLM f s1 xs - return (s2, x' : xs') +mapAccumLM f s xs = + go s xs + where + go s (x:xs) = do + (s1, x') <- f s x + (s2, xs') <- go s1 xs + return (s2, x' : xs') + go s [] = return (s, []) -- | Monadic version of mapSnd mapSndM :: Monad m => (b -> m c) -> [(a,b)] -> m [(a,c)] -mapSndM _ [] = return [] -mapSndM f ((a,b):xs) = do { c <- f b; rs <- mapSndM f xs; return ((a,c):rs) } +mapSndM f xs = go xs + where + go [] = return [] + go ((a,b):xs) = do { c <- f b; rs <- go xs; return ((a,c):rs) } -- | Monadic version of concatMap concatMapM :: Monad m => (a -> m [b]) -> [a] -> m [b] @@ -176,15 +185,19 @@ fmapEitherM _ fr (Right b) = fr b >>= (return . Right) -- | Monadic version of 'any', aborts the computation at the first @True@ value anyM :: Monad m => (a -> m Bool) -> [a] -> m Bool -anyM _ [] = return False -anyM f (x:xs) = do b <- f x +anyM f xs = go xs + where + go [] = return False + go (x:xs) = do b <- f x if b then return True - else anyM f xs + else go xs -- | Monad version of 'all', aborts the computation at the first @False@ value allM :: Monad m => (a -> m Bool) -> [a] -> m Bool -allM _ [] = return True -allM f (b:bs) = (f b) >>= (\bv -> if bv then allM f bs else return False) +allM f bs = go bs + where + go [] = return True + go (b:bs) = (f b) >>= (\bv -> if bv then go bs else return False) -- | Monadic version of or orM :: Monad m => m Bool -> m Bool -> m Bool View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7c555b054bf074a9ab612f9d93e3475bfb8c6594 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7c555b054bf074a9ab612f9d93e3475bfb8c6594 You're receiving 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 30 10:09:30 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 30 May 2020 06:09:30 -0400 Subject: [Git][ghc/ghc][master] Windows: Bump Windows toolchain to 0.2 Message-ID: <5ed230da99400_6e263f9f0bb937fc28289c9@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 8b1cb5df by Ben Gamari at 2020-05-30T06:09:20-04:00 Windows: Bump Windows toolchain to 0.2 - - - - - 1 changed file: - mk/get-win32-tarballs.py Changes: ===================================== mk/get-win32-tarballs.py ===================================== @@ -7,7 +7,7 @@ import subprocess import argparse from sys import stderr -TARBALL_VERSION = '0.1' +TARBALL_VERSION = '0.2' BASE_URL = "https://downloads.haskell.org/ghc/mingw/{}".format(TARBALL_VERSION) DEST = Path('ghc-tarballs/mingw-w64') ARCHS = ['i686', 'x86_64', 'sources'] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8b1cb5df126b1829fca8e8caf050dff4ca9df3f3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8b1cb5df126b1829fca8e8caf050dff4ca9df3f3 You're receiving 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 30 10:10:14 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 30 May 2020 06:10:14 -0400 Subject: [Git][ghc/ghc][master] Simplify contexts in GHC.Iface.Ext.Ast Message-ID: <5ed23106e0661_6e2611db285428317fa@gitlab.haskell.org.mail> Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC Commits: 6947231a by Zubin Duggal at 2020-05-30T06:10:02-04:00 Simplify contexts in GHC.Iface.Ext.Ast - - - - - 1 changed file: - compiler/GHC/Iface/Ext/Ast.hs Changes: ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -2,9 +2,12 @@ Main functions for .hie file generation -} {-# LANGUAGE CPP #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE UndecidableSuperClasses #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE ScopedTypeVariables #-} @@ -572,7 +575,7 @@ class ToHie a where toHie :: a -> HieM [HieAST Type] -- | Used to collect type info -class Data a => HasType a where +class HasType a where getTypeNode :: a -> HieM [HieAST Type] instance (ToHie a) => ToHie [a] where @@ -584,12 +587,6 @@ instance (ToHie a) => ToHie (Bag a) where instance (ToHie a) => ToHie (Maybe a) where toHie = maybe (pure []) toHie -instance ToHie (Context (Located NoExtField)) where - toHie _ = pure [] - -instance ToHie (TScoped NoExtField) where - toHie _ = pure [] - instance ToHie (IEContext (Located ModuleName)) where toHie (IEC c (L (RealSrcSpan span _) mname)) = do org <- ask @@ -667,9 +664,6 @@ instance ToHie (EvBindContext (Located TcEvBinds)) where ] toHie _ = pure [] -instance ToHie (EvBindContext (Located NoExtField)) where - toHie _ = pure [] - instance ToHie (Located HsWrapper) where toHie (L osp wrap) = case wrap of @@ -685,32 +679,19 @@ instance ToHie (Located HsWrapper) where concatMapM (toHie . C EvidenceVarUse . L osp) $ evVarsOfTermList a _ -> pure [] --- | Dummy instances - never called -instance ToHie (TScoped (LHsSigWcType GhcTc)) where - toHie _ = pure [] -instance ToHie (TScoped (LHsWcType GhcTc)) where - toHie _ = pure [] -instance ToHie (SigContext (LSig GhcTc)) where - toHie _ = pure [] -instance ToHie (TScoped Type) where - toHie _ = pure [] - -instance HasType (LHsBind GhcRn) where - getTypeNode (L spn bind) = makeNode bind spn +instance HiePass p => HasType (LHsBind (GhcPass p)) where + getTypeNode (L spn bind) = + case hiePass @p of + HieRn -> makeNode bind spn + HieTc -> case bind of + FunBind{fun_id = name} -> makeTypeNode bind spn (varType $ unLoc name) + _ -> makeNode bind spn -instance HasType (LHsBind GhcTc) where - getTypeNode (L spn bind) = case bind of - FunBind{fun_id = name} -> makeTypeNode bind spn (varType $ unLoc name) - _ -> makeNode bind spn - -instance HasType (Located (Pat GhcRn)) where - getTypeNode (L spn pat) = makeNode pat spn - -instance HasType (Located (Pat GhcTc)) where - getTypeNode (L spn opat) = makeTypeNode opat spn (hsPatType opat) - -instance HasType (LHsExpr GhcRn) where - getTypeNode (L spn e) = makeNode e spn +instance HiePass p => HasType (Located (Pat (GhcPass p))) where + getTypeNode (L spn pat) = + case hiePass @p of + HieRn -> makeNode pat spn + HieTc -> makeTypeNode pat spn (hsPatType pat) -- | This instance tries to construct 'HieAST' nodes which include the type of -- the expression. It is not yet possible to do this efficiently for all @@ -727,73 +708,99 @@ instance HasType (LHsExpr GhcRn) where -- expression's type is going to be expensive. -- -- See #16233 -instance HasType (LHsExpr GhcTc) where +instance HiePass p => HasType (LHsExpr (GhcPass p)) where getTypeNode e@(L spn e') = - -- Some expression forms have their type immediately available - let tyOpt = case e' of - HsLit _ l -> Just (hsLitType l) - HsOverLit _ o -> Just (overLitType o) - - HsLam _ (MG { mg_ext = groupTy }) -> Just (matchGroupType groupTy) - HsLamCase _ (MG { mg_ext = groupTy }) -> Just (matchGroupType groupTy) - HsCase _ _ (MG { mg_ext = groupTy }) -> Just (mg_res_ty groupTy) - - ExplicitList ty _ _ -> Just (mkListTy ty) - ExplicitSum ty _ _ _ -> Just (mkSumTy ty) - HsDo ty _ _ -> Just ty - HsMultiIf ty _ -> Just ty - - _ -> Nothing - - in - case tyOpt of - Just t -> makeTypeNode e' spn t - Nothing - | skipDesugaring e' -> fallback - | otherwise -> do - hs_env <- lift $ lift $ Hsc $ \e w -> return (e,w) - (_,mbe) <- liftIO $ deSugarExpr hs_env e - maybe fallback (makeTypeNode e' spn . exprType) mbe - where - fallback = makeNode e' spn - - matchGroupType :: MatchGroupTc -> Type - matchGroupType (MatchGroupTc args res) = mkVisFunTys args res - - -- | Skip desugaring of these expressions for performance reasons. - -- - -- See impact on Haddock output (esp. missing type annotations or links) - -- before marking more things here as 'False'. See impact on Haddock - -- performance before marking more things as 'True'. - skipDesugaring :: HsExpr GhcTc -> Bool - skipDesugaring e = case e of - HsVar{} -> False - HsUnboundVar{} -> False - HsConLikeOut{} -> False - HsRecFld{} -> False - HsOverLabel{} -> False - HsIPVar{} -> False - XExpr (HsWrap{}) -> False - _ -> True - -instance ( ToHie (Context (Located (IdP (GhcPass a)))) - , ToHie (MatchGroup (GhcPass a) (LHsExpr (GhcPass a))) - , ToHie (PScoped (LPat (GhcPass a))) - , ToHie (GRHSs (GhcPass a) (LHsExpr (GhcPass a))) - , ToHie (LHsExpr (GhcPass a)) - , ToHie (Located (PatSynBind (GhcPass a) (GhcPass a))) - , HasType (LHsBind (GhcPass a)) - , ModifyState (IdP (GhcPass a)) - , Data (HsBind (GhcPass a)) - , IsPass a - ) => ToHie (BindContext (LHsBind (GhcPass a))) where + case hiePass @p of + HieRn -> makeNode e' spn + HieTc -> + -- Some expression forms have their type immediately available + let tyOpt = case e' of + HsLit _ l -> Just (hsLitType l) + HsOverLit _ o -> Just (overLitType o) + + HsLam _ (MG { mg_ext = groupTy }) -> Just (matchGroupType groupTy) + HsLamCase _ (MG { mg_ext = groupTy }) -> Just (matchGroupType groupTy) + HsCase _ _ (MG { mg_ext = groupTy }) -> Just (mg_res_ty groupTy) + + ExplicitList ty _ _ -> Just (mkListTy ty) + ExplicitSum ty _ _ _ -> Just (mkSumTy ty) + HsDo ty _ _ -> Just ty + HsMultiIf ty _ -> Just ty + + _ -> Nothing + + in + case tyOpt of + Just t -> makeTypeNode e' spn t + Nothing + | skipDesugaring e' -> fallback + | otherwise -> do + hs_env <- lift $ lift $ Hsc $ \e w -> return (e,w) + (_,mbe) <- liftIO $ deSugarExpr hs_env e + maybe fallback (makeTypeNode e' spn . exprType) mbe + where + fallback = makeNode e' spn + + matchGroupType :: MatchGroupTc -> Type + matchGroupType (MatchGroupTc args res) = mkVisFunTys args res + + -- | Skip desugaring of these expressions for performance reasons. + -- + -- See impact on Haddock output (esp. missing type annotations or links) + -- before marking more things here as 'False'. See impact on Haddock + -- performance before marking more things as 'True'. + skipDesugaring :: HsExpr GhcTc -> Bool + skipDesugaring e = case e of + HsVar{} -> False + HsUnboundVar{} -> False + HsConLikeOut{} -> False + HsRecFld{} -> False + HsOverLabel{} -> False + HsIPVar{} -> False + XExpr (HsWrap{}) -> False + _ -> True + +data HiePassEv p where + HieRn :: HiePassEv 'Renamed + HieTc :: HiePassEv 'Typechecked + +class ( IsPass p + , HiePass (NoGhcTcPass p) + , ModifyState (IdGhcP p) + , Data (GRHS (GhcPass p) (Located (HsExpr (GhcPass p)))) + , Data (HsExpr (GhcPass p)) + , Data (HsCmd (GhcPass p)) + , Data (AmbiguousFieldOcc (GhcPass p)) + , Data (HsCmdTop (GhcPass p)) + , Data (GRHS (GhcPass p) (Located (HsCmd (GhcPass p)))) + , Data (HsSplice (GhcPass p)) + , Data (HsLocalBinds (GhcPass p)) + , Data (FieldOcc (GhcPass p)) + , Data (HsTupArg (GhcPass p)) + , Data (IPBind (GhcPass p)) + , ToHie (Context (Located (IdGhcP p))) + , ToHie (RFContext (Located (AmbiguousFieldOcc (GhcPass p)))) + , ToHie (RFContext (Located (FieldOcc (GhcPass p)))) + , ToHie (TScoped (LHsWcType (GhcPass (NoGhcTcPass p)))) + , ToHie (TScoped (LHsSigWcType (GhcPass (NoGhcTcPass p)))) + , HasRealDataConName (GhcPass p) + ) + => HiePass p where + hiePass :: HiePassEv p + +instance HiePass 'Renamed where + hiePass = HieRn +instance HiePass 'Typechecked where + hiePass = HieTc + +instance HiePass p => ToHie (BindContext (LHsBind (GhcPass p))) where toHie (BC context scope b@(L span bind)) = concatM $ getTypeNode b : case bind of FunBind{fun_id = name, fun_matches = matches, fun_ext = wrap} -> [ toHie $ C (ValBind context scope $ getRealSpan span) name , toHie matches - , case ghcPass @a of - GhcTc -> toHie $ L span wrap + , case hiePass @p of + HieTc -> toHie $ L span wrap _ -> pure [] ] PatBind{pat_lhs = lhs, pat_rhs = rhs} -> @@ -822,25 +829,22 @@ instance ( ToHie (Context (Located (IdP (GhcPass a)))) [ toHie $ L span psb -- PatSynBinds only occur at the top level ] -instance ( ToHie (LMatch a body) - ) => ToHie (MatchGroup a body) where +instance ( HiePass p + , ToHie (Located body) + , Data body + ) => ToHie (MatchGroup (GhcPass p) (Located body)) where toHie mg = case mg of MG{ mg_alts = (L span alts) , mg_origin = origin} -> local (setOrigin origin) $ concatM [ locOnly span , toHie alts ] - XMatchGroup _ -> pure [] setOrigin :: Origin -> NodeOrigin -> NodeOrigin setOrigin FromSource _ = SourceInfo setOrigin Generated _ = GeneratedInfo -instance ( ToHie (Context (Located (IdP a))) - , ToHie (PScoped (LPat a)) - , ToHie (HsPatSynDir a) - , (a ~ GhcPass p) - ) => ToHie (Located (PatSynBind a a)) where +instance HiePass p => ToHie (Located (PatSynBind (GhcPass p) (GhcPass p))) where toHie (L sp psb) = concatM $ case psb of PSB{psb_id=var, psb_args=dets, psb_def=pat, psb_dir=dir} -> [ toHie $ C (Decl PatSynDec $ getRealSpan sp) var @@ -865,50 +869,39 @@ instance ( ToHie (Context (Located (IdP a))) toBind (InfixCon a b) = InfixCon (C Use a) (C Use b) toBind (RecCon r) = RecCon $ map (PSC detSpan) r -instance ( ToHie (MatchGroup a (LHsExpr a)) - ) => ToHie (HsPatSynDir a) where +instance HiePass p => ToHie (HsPatSynDir (GhcPass p)) where toHie dir = case dir of ExplicitBidirectional mg -> toHie mg _ -> pure [] -instance ( a ~ GhcPass p - , ToHie body - , ToHie (HsMatchContext (NoGhcTc a)) - , ToHie (PScoped (LPat a)) - , ToHie (GRHSs a body) - , Data (Match a body) - ) => ToHie (LMatch (GhcPass p) body) where - toHie (L span m ) = concatM $ makeNode m span : case m of +instance ( HiePass p + , Data body + , ToHie (Located body) + ) => ToHie (LMatch (GhcPass p) (Located body)) where + toHie (L span m ) = concatM $ node : case m of Match{m_ctxt=mctx, m_pats = pats, m_grhss = grhss } -> [ toHie mctx , let rhsScope = mkScope $ grhss_span grhss in toHie $ patScopes Nothing rhsScope NoScope pats , toHie grhss ] + where + node = case hiePass @p of + HieTc -> makeNode m span + HieRn -> makeNode m span -instance ( ToHie (Context (Located (IdP a))) - ) => ToHie (HsMatchContext a) where +instance HiePass p => ToHie (HsMatchContext (GhcPass p)) where toHie (FunRhs{mc_fun=name}) = toHie $ C MatchBind name toHie (StmtCtxt a) = toHie a toHie _ = pure [] -instance ( ToHie (HsMatchContext a) - ) => ToHie (HsStmtContext a) where +instance HiePass p => ToHie (HsStmtContext (GhcPass p)) where toHie (PatGuard a) = toHie a toHie (ParStmtCtxt a) = toHie a toHie (TransStmtCtxt a) = toHie a toHie _ = pure [] -instance ( a ~ GhcPass p - , IsPass p - , ToHie (Context (Located (IdP a))) - , ToHie (RContext (HsRecFields a (PScoped (LPat a)))) - , ToHie (LHsExpr a) - , ToHie (TScoped (LHsSigWcType a)) - , HasType (LPat a) - , Data (HsSplice a) - , IsPass p - ) => ToHie (PScoped (Located (Pat (GhcPass p)))) where +instance HiePass p => ToHie (PScoped (Located (Pat (GhcPass p)))) where toHie (PS rsp scope pscope lpat@(L ospan opat)) = concatM $ getTypeNode lpat : case opat of WildPat _ -> @@ -941,25 +934,25 @@ instance ( a ~ GhcPass p SumPat _ pat _ _ -> [ toHie $ PS rsp scope pscope pat ] - ConPat {pat_con = con, pat_args = dets, pat_con_ext = ext}-> - [ case ghcPass @p of - GhcPs -> toHie $ C Use $ con - GhcRn -> toHie $ C Use $ con - GhcTc -> toHie $ C Use $ fmap conLikeName con - , toHie $ contextify dets - , case ghcPass @p of - GhcTc -> - let ev_binds = cpt_binds ext + ConPat {pat_con = con, pat_args = dets, pat_con_ext = ext} -> + case hiePass @p of + HieTc -> + [ toHie $ C Use $ fmap conLikeName con + , toHie $ contextify dets + , let ev_binds = cpt_binds ext ev_vars = cpt_dicts ext wrap = cpt_wrap ext evscope = mkScope ospan `combineScopes` scope `combineScopes` pscope - in concatM [ toHie $ EvBindContext scope rsp $ L ospan ev_binds - , toHie $ L ospan wrap - , toHie $ map (C (EvidenceVarBind EvPatternBind evscope rsp) - . L ospan) ev_vars - ] - _ -> pure [] - ] + in concatM [ toHie $ EvBindContext scope rsp $ L ospan ev_binds + , toHie $ L ospan wrap + , toHie $ map (C (EvidenceVarBind EvPatternBind evscope rsp) + . L ospan) ev_vars + ] + ] + HieRn -> + [ toHie $ C Use con + , toHie $ contextify dets + ] ViewPat _ expr pat -> [ toHie expr , toHie $ PS rsp scope pscope pat @@ -976,26 +969,26 @@ instance ( a ~ GhcPass p ] SigPat _ pat sig -> [ toHie $ PS rsp scope pscope pat - , let cscope = mkLScope pat in - case ghcPass @p of - GhcPs -> pure [] - GhcTc -> pure [] - GhcRn -> + , case hiePass @p of + HieTc -> + let cscope = mkLScope pat in toHie $ TS (ResolvedScopes [cscope, scope, pscope]) - sig - ] - XPat e -> case ghcPass @p of + sig + HieRn -> pure [] + ] + XPat e -> + case hiePass @p of + HieTc -> + let CoPat wrap pat _ = e + in [ toHie $ L ospan wrap + , toHie $ PS rsp scope pscope $ (L ospan pat) + ] #if __GLASGOW_HASKELL__ < 811 - GhcPs -> noExtCon e - GhcRn -> noExtCon e + HieRn -> [] #endif - GhcTc -> - [ toHie $ L ospan wrap - , toHie $ PS rsp scope pscope $ (L ospan pat :: LPat a) - ] - where - CoPat wrap pat _ = e where + contextify :: a ~ LPat (GhcPass p) => HsConDetails a (HsRecFields (GhcPass p) a) + -> HsConDetails (PScoped a) (RContext (HsRecFields (GhcPass p) (PScoped a))) contextify (PrefixCon args) = PrefixCon $ patScopes rsp scope pscope args contextify (InfixCon a b) = InfixCon a' b' where [a', b'] = patScopes rsp scope pscope [a,b] @@ -1006,6 +999,7 @@ 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 $ [ bindingsOnly $ map (C $ TyVarBind (mkScope span) sc) (wcs++tvs) @@ -1013,48 +1007,31 @@ instance ToHie (TScoped (HsPatSigType GhcRn)) where ] -- See Note [Scoping Rules for SigPat] -instance ( ToHie body - , ToHie (LGRHS a body) - , ToHie (RScoped (LHsLocalBinds a)) - ) => ToHie (GRHSs a body) where +instance ( ToHie (Located body) + , HiePass p + , Data body + ) => ToHie (GRHSs (GhcPass p) (Located body)) where toHie grhs = concatM $ case grhs of GRHSs _ grhss binds -> [ toHie grhss , toHie $ RS (mkScope $ grhss_span grhs) binds ] - XGRHSs _ -> [] instance ( ToHie (Located body) - , ToHie (RScoped (GuardLStmt (GhcPass a))) - , Data (GRHS (GhcPass a) (Located body)) + , HiePass a + , Data body ) => ToHie (LGRHS (GhcPass a) (Located body)) where - toHie (L span g) = concatM $ makeNode g span : case g of + toHie (L span g) = concatM $ node : case g of GRHS _ guards body -> [ toHie $ listScopes (mkLScope body) guards , toHie body ] + where + node = case hiePass @a of + HieRn -> makeNode g span + HieTc -> makeNode g span -instance ( a ~ GhcPass p - , ToHie (Context (Located (IdP a))) - , HasType (LHsExpr a) - , ToHie (PScoped (LPat a)) - , ToHie (MatchGroup a (LHsExpr a)) - , ToHie (LGRHS a (LHsExpr a)) - , ToHie (RContext (HsRecordBinds a)) - , ToHie (RFContext (Located (AmbiguousFieldOcc a))) - , ToHie (ArithSeqInfo a) - , ToHie (LHsCmdTop a) - , ToHie (RScoped (GuardLStmt a)) - , ToHie (RScoped (LHsLocalBinds a)) - , ToHie (TScoped (LHsWcType (NoGhcTc a))) - , ToHie (TScoped (LHsSigWcType (NoGhcTc a))) - , Data (HsExpr a) - , Data (HsSplice a) - , Data (HsTupArg a) - , Data (AmbiguousFieldOcc a) - , (HasRealDataConName a) - , IsPass p - ) => ToHie (LHsExpr (GhcPass p)) where +instance HiePass p => ToHie (LHsExpr (GhcPass p)) where toHie e@(L mspan oexpr) = concatM $ getTypeNode e : case oexpr of HsVar _ (L _ var) -> [ toHie $ C Use (L mspan var) @@ -1135,7 +1112,7 @@ instance ( a ~ GhcPass p [ toHie exprs ] RecordCon {rcon_ext = mrealcon, rcon_con_name = name, rcon_flds = binds} -> - [ toHie $ C Use (getRealDataCon @a mrealcon name) + [ toHie $ C Use (getRealDataCon @(GhcPass p) mrealcon name) -- See Note [Real DataCon Name] , toHie $ RC RecFieldAssign $ binds ] @@ -1186,30 +1163,20 @@ instance ( a ~ GhcPass p -> [ toHie $ L mspan a , toHie (L mspan w) ] - | otherwise - -> [] + | otherwise -> [] -instance ( a ~ GhcPass p - , ToHie (LHsExpr a) - , Data (HsTupArg a) - ) => ToHie (LHsTupArg (GhcPass p)) where +instance HiePass p => ToHie (LHsTupArg (GhcPass p)) where toHie (L span arg) = concatM $ makeNode arg span : case arg of Present _ expr -> [ toHie expr ] Missing _ -> [] -instance ( a ~ GhcPass p - , ToHie (PScoped (LPat a)) - , ToHie (LHsExpr a) - , ToHie (SigContext (LSig a)) - , ToHie (RScoped (LHsLocalBinds a)) - , ToHie (RScoped (ApplicativeArg a)) - , ToHie (Located body) - , Data (StmtLR a a (Located body)) - , Data (StmtLR a a (Located (HsExpr a))) +instance ( ToHie (Located body) + , Data body + , HiePass p ) => ToHie (RScoped (LStmt (GhcPass p) (Located body))) where - toHie (RS scope (L span stmt)) = concatM $ makeNode stmt span : case stmt of + toHie (RS scope (L span stmt)) = concatM $ node : case stmt of LastStmt _ body _ _ -> [ toHie body ] @@ -1239,47 +1206,36 @@ instance ( a ~ GhcPass p RecStmt {recS_stmts = stmts} -> [ toHie $ map (RS $ combineScopes scope (mkScope span)) stmts ] + where + node = case hiePass @p of + HieTc -> makeNode stmt span + HieRn -> makeNode stmt span -instance ( ToHie (LHsExpr a) - , ToHie (PScoped (LPat a)) - , ToHie (BindContext (LHsBind a)) - , ToHie (SigContext (LSig a)) - , ToHie (RScoped (HsValBindsLR a a)) - , ToHie (EvBindContext (Located (XIPBinds a))) - , ToHie (RScoped (LIPBind a)) - , Data (HsLocalBinds a) - ) => ToHie (RScoped (LHsLocalBinds a)) where +instance HiePass p => ToHie (RScoped (LHsLocalBinds (GhcPass p))) where toHie (RS scope (L sp binds)) = concatM $ makeNode binds sp : case binds of EmptyLocalBinds _ -> [] HsIPBinds _ ipbinds -> case ipbinds of IPBinds evbinds xs -> let sc = combineScopes scope $ mkScope sp in - [ toHie $ EvBindContext sc (getRealSpan sp) $ L sp evbinds + [ case hiePass @p of + HieTc -> toHie $ EvBindContext sc (getRealSpan sp) $ L sp evbinds + HieRn -> pure [] , toHie $ map (RS sc) xs ] - XHsIPBinds _ -> [] HsValBinds _ valBinds -> [ toHie $ RS (combineScopes scope $ mkScope sp) valBinds ] - XHsLocalBindsLR _ -> [] -instance ( ToHie (LHsExpr a) - , ToHie (Context (Located (IdP a))) - , Data (IPBind a) - ) => ToHie (RScoped (LIPBind a)) where +instance HiePass p => ToHie (RScoped (LIPBind (GhcPass p))) where toHie (RS scope (L sp bind)) = concatM $ makeNode bind sp : case bind of IPBind _ (Left _) expr -> [toHie expr] IPBind _ (Right v) expr -> [ toHie $ C (EvidenceVarBind EvImplicitBind scope (getRealSpan sp)) - $ L sp v + $ L sp v , toHie expr ] - XIPBind _ -> [] -instance ( ToHie (BindContext (LHsBind a)) - , ToHie (SigContext (LSig a)) - , ToHie (RScoped (XXValBindsLR a a)) - ) => ToHie (RScoped (HsValBindsLR a a)) where +instance HiePass p => ToHie (RScoped (HsValBindsLR (GhcPass p) (GhcPass p))) where toHie (RS sc v) = concatM $ case v of ValBinds _ binds sigs -> [ toHie $ fmap (BC RegularBind sc) binds @@ -1287,26 +1243,19 @@ instance ( ToHie (BindContext (LHsBind a)) ] XValBindsLR x -> [ toHie $ RS sc x ] -instance ToHie (RScoped (NHsValBindsLR GhcTc)) where - toHie (RS sc (NValBinds binds sigs)) = concatM $ - [ toHie (concatMap (map (BC RegularBind sc) . bagToList . snd) binds) - , toHie $ fmap (SC (SI BindSig Nothing)) sigs - ] -instance ToHie (RScoped (NHsValBindsLR GhcRn)) where +instance HiePass p => ToHie (RScoped (NHsValBindsLR (GhcPass p))) where toHie (RS sc (NValBinds binds sigs)) = concatM $ [ toHie (concatMap (map (BC RegularBind sc) . bagToList . snd) binds) , toHie $ fmap (SC (SI BindSig Nothing)) sigs ] -instance ( ToHie (RContext (LHsRecField a arg)) - ) => ToHie (RContext (HsRecFields a arg)) where +instance ( ToHie arg , HasLoc arg , Data arg + , HiePass p ) => ToHie (RContext (HsRecFields (GhcPass p) arg)) where toHie (RC c (HsRecFields fields _)) = toHie $ map (RC c) fields instance ( ToHie (RFContext (Located label)) - , ToHie arg - , HasLoc arg + , ToHie arg , HasLoc arg , Data arg , Data label - , Data arg ) => ToHie (RContext (LHsRecField' label arg)) where toHie (RC c (L span recfld)) = concatM $ makeNode recfld span : case recfld of HsRecField label expr _ -> @@ -1349,16 +1298,7 @@ instance ToHie (RFContext (Located (AmbiguousFieldOcc GhcTc))) where in [ toHie $ C (RecField c rhs) (L nspan var') ] -instance ( a ~ GhcPass p - , ToHie (PScoped (LPat a)) - , ToHie (BindContext (LHsBind a)) - , ToHie (LHsExpr a) - , ToHie (SigContext (LSig a)) - , ToHie (RScoped (HsValBindsLR a a)) - , ToHie (RScoped (ExprLStmt a)) - , Data (StmtLR a a (Located (HsExpr a))) - , Data (HsLocalBinds a) - ) => ToHie (RScoped (ApplicativeArg (GhcPass p))) where +instance HiePass p => ToHie (RScoped (ApplicativeArg (GhcPass p))) where toHie (RS sc (ApplicativeArgOne _ pat expr _)) = concatM [ toHie $ PS Nothing sc NoScope pat , toHie expr @@ -1373,29 +1313,13 @@ instance (ToHie arg, ToHie rec) => ToHie (HsConDetails arg rec) where toHie (RecCon rec) = toHie rec toHie (InfixCon a b) = concatM [ toHie a, toHie b] -instance ( ToHie (LHsCmd a) - , Data (HsCmdTop a) - ) => ToHie (LHsCmdTop a) where +instance HiePass p => ToHie (LHsCmdTop (GhcPass p)) where toHie (L span top) = concatM $ makeNode top span : case top of HsCmdTop _ cmd -> [ toHie cmd ] - XCmdTop _ -> [] - -instance ( a ~ GhcPass p - , ToHie (PScoped (LPat a)) - , ToHie (BindContext (LHsBind a)) - , ToHie (LHsExpr a) - , ToHie (MatchGroup a (LHsCmd a)) - , ToHie (SigContext (LSig a)) - , ToHie (RScoped (HsValBindsLR a a)) - , ToHie (RScoped (LHsLocalBinds a)) - , Data (HsCmd a) - , Data (HsCmdTop a) - , Data (StmtLR a a (Located (HsCmd a))) - , Data (HsLocalBinds a) - , Data (StmtLR a a (Located (HsExpr a))) - ) => ToHie (LHsCmd (GhcPass p)) where + +instance HiePass p => ToHie (LHsCmd (GhcPass p)) where toHie (L span cmd) = concatM $ makeNode cmd span : case cmd of HsCmdArrApp _ a b _ _ -> [ toHie a @@ -1658,48 +1582,51 @@ instance ToHie (StandaloneKindSig GhcRn) where , toHie $ TS (ResolvedScopes []) typ ] -instance ToHie (SigContext (LSig GhcRn)) where - toHie (SC (SI styp msp) (L sp sig)) = concatM $ makeNode sig sp : case sig of - TypeSig _ names typ -> - [ toHie $ map (C TyDecl) names - , toHie $ TS (UnresolvedScope (map unLoc names) Nothing) typ - ] - PatSynSig _ names typ -> - [ toHie $ map (C TyDecl) names - , toHie $ TS (UnresolvedScope (map unLoc names) Nothing) typ - ] - ClassOpSig _ _ names typ -> - [ case styp of - ClassSig -> toHie $ map (C $ ClassTyDecl $ getRealSpan sp) names - _ -> toHie $ map (C $ TyDecl) names - , toHie $ TS (UnresolvedScope (map unLoc names) msp) typ - ] - IdSig _ _ -> [] - FixSig _ fsig -> - [ toHie $ L sp fsig - ] - InlineSig _ name _ -> - [ toHie $ (C Use) name - ] - SpecSig _ name typs _ -> - [ toHie $ (C Use) name - , toHie $ map (TS (ResolvedScopes [])) typs - ] - SpecInstSig _ _ typ -> - [ toHie $ TS (ResolvedScopes []) typ - ] - MinimalSig _ _ form -> - [ toHie form - ] - SCCFunSig _ _ name mtxt -> - [ toHie $ (C Use) name - , maybe (pure []) (locOnly . getLoc) mtxt - ] - CompleteMatchSig _ _ (L ispan names) typ -> - [ locOnly ispan - , toHie $ map (C Use) names - , toHie $ fmap (C Use) typ - ] +instance HiePass p => ToHie (SigContext (LSig (GhcPass p))) where + toHie (SC (SI styp msp) (L sp sig)) = + case hiePass @p of + HieTc -> pure [] + HieRn -> concatM $ makeNode sig sp : case sig of + TypeSig _ names typ -> + [ toHie $ map (C TyDecl) names + , toHie $ TS (UnresolvedScope (map unLoc names) Nothing) typ + ] + PatSynSig _ names typ -> + [ toHie $ map (C TyDecl) names + , toHie $ TS (UnresolvedScope (map unLoc names) Nothing) typ + ] + ClassOpSig _ _ names typ -> + [ case styp of + ClassSig -> toHie $ map (C $ ClassTyDecl $ getRealSpan sp) names + _ -> toHie $ map (C $ TyDecl) names + , toHie $ TS (UnresolvedScope (map unLoc names) msp) typ + ] + IdSig _ _ -> [] + FixSig _ fsig -> + [ toHie $ L sp fsig + ] + InlineSig _ name _ -> + [ toHie $ (C Use) name + ] + SpecSig _ name typs _ -> + [ toHie $ (C Use) name + , toHie $ map (TS (ResolvedScopes [])) typs + ] + SpecInstSig _ _ typ -> + [ toHie $ TS (ResolvedScopes []) typ + ] + MinimalSig _ _ form -> + [ toHie form + ] + SCCFunSig _ _ name mtxt -> + [ toHie $ (C Use) name + , maybe (pure []) (locOnly . getLoc) mtxt + ] + CompleteMatchSig _ _ (L ispan names) typ -> + [ locOnly ispan + , toHie $ map (C Use) names + , toHie $ fmap (C Use) typ + ] instance ToHie (LHsType GhcRn) where toHie x = toHie $ TS (ResolvedScopes []) x @@ -1863,11 +1790,7 @@ instance ToHie (LBooleanFormula (Located Name)) where instance ToHie (Located HsIPName) where toHie (L span e) = makeNode e span -instance ( a ~ GhcPass p - , ToHie (LHsExpr a) - , Data (HsSplice a) - , IsPass p - ) => ToHie (Located (HsSplice a)) where +instance HiePass p => ToHie (Located (HsSplice (GhcPass p))) where toHie (L span sp) = concatM $ makeNode sp span : case sp of HsTypedSplice _ _ _ expr -> [ toHie expr View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6947231abd8c33840860ad51699b76efd4725f0e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6947231abd8c33840860ad51699b76efd4725f0e You're receiving 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 30 11:26:40 2020 From: gitlab at gitlab.haskell.org (Simon Jakobi) Date: Sat, 30 May 2020 07:26:40 -0400 Subject: [Git][ghc/ghc][wip/sjakobi/deprecate-option-v2] deepseq: Use the old wip/ghc-mr-842 branch to silence warnings Message-ID: <5ed242f0ab936_6e263f9ee2575ed428390bb@gitlab.haskell.org.mail> Simon Jakobi pushed to branch wip/sjakobi/deprecate-option-v2 at Glasgow Haskell Compiler / GHC Commits: 8a7845b6 by Simon Jakobi at 2020-05-30T13:25:25+02:00 deepseq: Use the old wip/ghc-mr-842 branch to silence warnings - - - - - 1 changed file: - libraries/deepseq Changes: ===================================== libraries/deepseq ===================================== @@ -1 +1 @@ -Subproject commit da0eda33f540786b6823c6f542ab59cf9d1b71d9 +Subproject commit 9e6c68937b60cec4cd0b19a1476fbafef6d2fabe View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8a7845b69e8681f6d525fb51fd5b82a5dd985227 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/8a7845b69e8681f6d525fb51fd5b82a5dd985227 You're receiving 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 30 13:36:08 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 30 May 2020 09:36:08 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 27 commits: rts: Teach getNumProcessors to return available processors Message-ID: <5ed26148d8fcb_6e26114ed14c28505d1@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 4413828b by Ben Gamari at 2020-05-30T06:07:31-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. - - - - - 1449435c by Ben Gamari at 2020-05-30T06:07:31-04:00 users-guide: Note change in getNumProcessors in users guide - - - - - 3d960169 by Ben Gamari at 2020-05-30T06:07:31-04:00 rts: Drop compatibility shims for Windows Vista We can now assume that the thread and processor group interfaces are available. - - - - - 7f8f948c by Peter Trommler at 2020-05-30T06:08:07-04:00 PPC NCG: Fix .size directive on powerpc64 ELF v1 Thanks to Sergei Trofimovich for pointing out the issue. Fixes #18237 - - - - - 7c555b05 by Andreas Klebinger at 2020-05-30T06:08:43-04:00 Optimize GHC.Utils.Monad. Many functions in this module are recursive and as such are marked loop breakers. Which means they are unlikely to get an unfolding. This is *bad*. We always want to specialize them to specific Monads. Which requires a visible unfolding at the use site. I rewrote the recursive ones from: foo f x = ... foo x' ... to foo f x = go x where go x = ... As well as giving some pragmas to make all of them available for specialization. The end result is a reduction of allocations of about -1.4% for nofib/spectral/simple/Main.hs when compiled with `-O`. ------------------------- Metric Decrease: T12425 T14683 T5631 T9233 T9675 T9961 WWRec ------------------------- - - - - - 8b1cb5df by Ben Gamari at 2020-05-30T06:09:20-04:00 Windows: Bump Windows toolchain to 0.2 - - - - - 6947231a by Zubin Duggal at 2020-05-30T06:10:02-04:00 Simplify contexts in GHC.Iface.Ext.Ast - - - - - 26142d19 by Daniel Gröber at 2020-05-30T09:35:32-04:00 Cleanup OVERWRITING_CLOSURE logic The code is just more confusing than it needs to be. We don't need to mix the threaded check with the ldv profiling check since ldv's init already checks for this. Hence they can be two separate checks. Taking the sanity checking into account is also cleaner via DebugFlags.sanity. No need for checking the DEBUG define. The ZERO_SLOP_FOR_LDV_PROF and ZERO_SLOP_FOR_SANITY_CHECK definitions the old code had also make things a lot more opaque IMO so I removed those. - - - - - f884f60d by Daniel Gröber at 2020-05-30T09:35:32-04:00 Fix OVERWRITING_CLOSURE assuming closures are not inherently used The new ASSERT in LDV_recordDead() was being tripped up by MVars when removeFromMVarBlockedQueue() calls OVERWRITING_CLOSURE() via OVERWRITE_INFO(). - - - - - 1d158799 by Daniel Gröber at 2020-05-30T09:35:32-04:00 Always zero shrunk mutable array slop when profiling When shrinking arrays in the profiling way we currently don't always zero the leftover slop. This means we can't traverse such closures in the heap profiler. The old Note [zeroing slop] and #8402 have some rationale for why this is so but I belive the reasoning doesn't apply to mutable closures. There users already have to ensure multiple threads don't step on each other's toes so zeroing should be safe. - - - - - 3c119dde by Ben Gamari at 2020-05-30T09:35:33-04:00 testsuite: Add test for #18151 - - - - - 941b8536 by Ben Gamari at 2020-05-30T09:35:33-04:00 testsuite: Add test for desugaring of PostfixOperators - - - - - 7c460772 by Ben Gamari at 2020-05-30T09:35:33-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. - - - - - c61a596d by Kirill Elagin at 2020-05-30T09:35:39-04:00 Winferred-safe-imports: Do not exit with error Currently, when -Winferred-safe-imports is enabled, even when it is not turned into an error, the compiler will still exit with exit code 1 if this warning was emitted. Make sure it is really treated as a warning. - - - - - fb28c9dc by Ben Gamari at 2020-05-30T09:35:39-04:00 nonmoving: Optimise log2_ceil - - - - - c6bbde4b by Bodigrim at 2020-05-30T09:35:40-04:00 Clarify description of fromListN - - - - - e66d45eb by Bodigrim at 2020-05-30T09:35:40-04:00 Apply suggestion to libraries/base/GHC/Exts.hs - - - - - fcb29323 by Jeremy Schlatter at 2020-05-30T09:35:42-04:00 Fix wording in documentation The duplicate "orphan instance" phrase here doesn't make sense, and was probably an accident. - - - - - e6797ded by Matthew Pickering at 2020-05-30T09:35:43-04:00 Use a newtype `Code` for the return type of typed quotations (Proposal #195) There are three problems with the current API: 1. It is hard to properly write instances for ``Quote m => m (TExp a)`` as the type is the composition of two type constructors. Doing so in your program involves making your own newtype and doing a lot of wrapping/unwrapping. For example, if I want to create a language which I can either run immediately or generate code from I could write the following with the new API. :: class Lang r where _int :: Int -> r Int _if :: r Bool -> r a -> r a -> r a instance Lang Identity where _int = Identity _if (Identity b) (Identity t) (Identity f) = Identity (if b then t else f) instance Quote m => Lang (Code m) where _int = liftTyped _if cb ct cf = [|| if $$cb then $$ct else $$cf ||] 2. When doing code generation it is common to want to store code fragments in a map. When doing typed code generation, these code fragments contain a type index so it is desirable to store them in one of the parameterised map data types such as ``DMap`` from ``dependent-map`` or ``MapF`` from ``parameterized-utils``. :: compiler :: Env -> AST a -> Code Q a data AST a where ... data Ident a = ... type Env = MapF Ident (Code Q) newtype Code m a = Code (m (TExp a)) In this example, the ``MapF`` maps an ``Ident String`` directly to a ``Code Q String``. Using one of these map types currently requires creating your own newtype and constantly wrapping every quotation and unwrapping it when using a splice. Achievable, but it creates even more syntactic noise than normal metaprogramming. 3. ``m (TExp a)`` is ugly to read and write, understanding ``Code m a`` is easier. This is a weak reason but one everyone can surely agree with. - - - - - 60bfcc9f by Takenobu Tani at 2020-05-30T09:35:53-04:00 configure: Modify aclocal.m4 according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * Rename: * compiler/GHC/Parser.hs <= compiler/parser/Parser.hs * compiler/GHC/Parser/Lexer.hs <= compiler/Parser/Lexer.hs * Add: * compiler/GHC/Cmm/Lexer.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular - - - - - a3711abf by Ben Gamari at 2020-05-30T09:35:54-04:00 testsuite: Don't fail if we can't unlink __symlink_test Afterall, it's possible we were unable to create it due to lack of symlink permission. - - - - - 8641898f by Ben Gamari at 2020-05-30T09:35:54-04:00 testsuite: Refactor ghostscript detection Tamar reported that he saw crashes due to unhandled exceptions. - - - - - 8c31a6bf by Ben Gamari at 2020-05-30T09:35:54-04:00 testsuite/perf_notes: Fix ill-typed assignments - - - - - f4bc785d by Ben Gamari at 2020-05-30T09:35:54-04:00 testsuite/testutil: Fix bytes/str mismatch - - - - - fe75764a by Ben Gamari at 2020-05-30T09:35:54-04:00 testsuite: Work around spurious mypy failure - - - - - 8bfdc1f8 by Takenobu Tani at 2020-05-30T09:35:56-04:00 Clean up file paths for new module hierarchy This updates comments only. This patch replaces file references according to new module hierarchy. See also: * https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular * https://gitlab.haskell.org/ghc/ghc/issues/13009 - - - - - ae9f06ba by Takenobu Tani at 2020-05-30T09:35:56-04:00 Modify file paths to module paths for new module hierarchy This updates comments only. This patch replaces module references according to new module hierarchy [1][2]. For files under the `compiler/` directory, I replace them as module paths instead of file paths. For instance, `GHC.Unit.State` instead of `compiler/GHC/Unit/State.hs` [3]. For current and future haddock's markup, this patch encloses the module name with "" [4]. [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: https://gitlab.haskell.org/ghc/ghc/issues/13009 [3]: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/3375#note_276613 [4]: https://haskell-haddock.readthedocs.io/en/latest/markup.html#linking-to-modules - - - - - 30 changed files: - aclocal.m4 - compiler/GHC.hs - compiler/GHC/Builtin/Names/TH.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/Base.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/HsToCore/PmCheck/Types.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Parser/Lexer.x - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToCmm/Utils.hs - compiler/GHC/SysTools/ExtraObj.hs - compiler/GHC/Tc/Deriv.hs - compiler/GHC/Tc/Deriv/Generate.hs - compiler/GHC/Tc/Gen/Splice.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Utils/Monad.hs - compiler/GHC/Utils/Outputable.hs - compiler/GHC/Utils/Ppr.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4448ba12bf76cc0dd7c3cee66916bbc428f968c5...ae9f06bac738415f38080b759690229ea802e328 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/4448ba12bf76cc0dd7c3cee66916bbc428f968c5...ae9f06bac738415f38080b759690229ea802e328 You're receiving 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 30 14:12:58 2020 From: gitlab at gitlab.haskell.org (Vladislav Zavialov) Date: Sat, 30 May 2020 10:12:58 -0400 Subject: [Git][ghc/ghc][wip/t18251-error-messages] 10 commits: rts: Teach getNumProcessors to return available processors Message-ID: <5ed269ea369b9_6e2611a0b9e4288617a@gitlab.haskell.org.mail> Vladislav Zavialov pushed to branch wip/t18251-error-messages at Glasgow Haskell Compiler / GHC Commits: 4413828b by Ben Gamari at 2020-05-30T06:07:31-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. - - - - - 1449435c by Ben Gamari at 2020-05-30T06:07:31-04:00 users-guide: Note change in getNumProcessors in users guide - - - - - 3d960169 by Ben Gamari at 2020-05-30T06:07:31-04:00 rts: Drop compatibility shims for Windows Vista We can now assume that the thread and processor group interfaces are available. - - - - - 7f8f948c by Peter Trommler at 2020-05-30T06:08:07-04:00 PPC NCG: Fix .size directive on powerpc64 ELF v1 Thanks to Sergei Trofimovich for pointing out the issue. Fixes #18237 - - - - - 7c555b05 by Andreas Klebinger at 2020-05-30T06:08:43-04:00 Optimize GHC.Utils.Monad. Many functions in this module are recursive and as such are marked loop breakers. Which means they are unlikely to get an unfolding. This is *bad*. We always want to specialize them to specific Monads. Which requires a visible unfolding at the use site. I rewrote the recursive ones from: foo f x = ... foo x' ... to foo f x = go x where go x = ... As well as giving some pragmas to make all of them available for specialization. The end result is a reduction of allocations of about -1.4% for nofib/spectral/simple/Main.hs when compiled with `-O`. ------------------------- Metric Decrease: T12425 T14683 T5631 T9233 T9675 T9961 WWRec ------------------------- - - - - - 8b1cb5df by Ben Gamari at 2020-05-30T06:09:20-04:00 Windows: Bump Windows toolchain to 0.2 - - - - - 6947231a by Zubin Duggal at 2020-05-30T06:10:02-04:00 Simplify contexts in GHC.Iface.Ext.Ast - - - - - db288f7b by Vladislav Zavialov at 2020-05-30T17:10:43+03:00 Improve parser error messages for the @-operator Since GHC diverges from the Haskell Report by allowing the user to define (@) as an infix operator, we better give a good error message when the user does so unintentionally. In general, this is rather hard to do, as some failures will be discovered only in the renamer or the type checker: x :: (Integer, Integer) x @ (a, b) = (1, 2) This patch does *not* address this general case. However, it gives much better error messages when the binding is not syntactically valid: pairs xs @ (_:xs') = zip xs xs' Before this patch, the error message was rather puzzling: <interactive>:1:1: error: Parse error in pattern: pairs After this patch, the error message includes a hint: <interactive>:1:1: error: Parse error in pattern: pairs In a function binding for the ‘@’ operator. Perhaps you meant an as-pattern, which must not be surrounded by whitespace - - - - - db3cdeea by Vladislav Zavialov at 2020-05-30T17:10:44+03:00 Improve parser error messages for TypeApplications With this patch, we always parse f @t as a type application, thereby producing better error messages. This steals two syntactic forms: * Prefix form of the @-operator in expressions. Since the @-operator is a divergence from the Haskell Report anyway, this is not a major loss. * Prefix form of @-patterns. Since we are stealing loose infix form anyway, might as well sacrifice the prefix form for the sake of much better error messages. - - - - - 833faecd by Vladislav Zavialov at 2020-05-30T17:10:44+03:00 Improve parser error messages for TemplateHaskellQuotes While [e| |], [t| |], [d| |], and so on, steal syntax from list comprehensions, [| |] and [|| ||] do not steal any syntax. Thus we can improve error messages by always accepting them in the lexer. Turns out the renamer already performs necessary validation. - - - - - 30 changed files: - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Lexer.x - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Utils/Monad.hs - configure.ac - docs/users_guide/8.12.1-notes.rst - docs/users_guide/bugs.rst - docs/users_guide/using-concurrent.rst - hadrian/src/Settings/Packages.hs - mk/get-win32-tarballs.py - rts/ghc.mk - rts/posix/OSThreads.c - rts/win32/OSThreads.c - + testsuite/tests/parser/should_fail/T18251a.hs - + testsuite/tests/parser/should_fail/T18251a.stderr - + testsuite/tests/parser/should_fail/T18251b.hs - + testsuite/tests/parser/should_fail/T18251b.stderr - + testsuite/tests/parser/should_fail/T18251c.hs - + testsuite/tests/parser/should_fail/T18251c.stderr - + testsuite/tests/parser/should_fail/T18251d.hs - + testsuite/tests/parser/should_fail/T18251d.stderr - + testsuite/tests/parser/should_fail/T18251e.hs - + testsuite/tests/parser/should_fail/T18251e.stderr - + testsuite/tests/parser/should_fail/T18251f.hs - + testsuite/tests/parser/should_fail/T18251f.stderr - testsuite/tests/parser/should_fail/all.T - testsuite/tests/th/T12411.stderr - testsuite/tests/typecheck/should_fail/T15527.stderr Changes: ===================================== compiler/GHC/CmmToAsm/PPC/Ppr.hs ===================================== @@ -86,8 +86,13 @@ pprNatCmmDecl config proc@(CmmProc top_info lbl _ (ListGraph blocks)) = pprSizeDecl :: Platform -> CLabel -> SDoc pprSizeDecl platform lbl = if osElfTarget (platformOS platform) - then text "\t.size" <+> ppr lbl <> text ", .-" <> ppr lbl + then text "\t.size" <+> prettyLbl <> text ", .-" <> codeLbl else empty + where + prettyLbl = ppr lbl + codeLbl + | platformArch platform == ArchPPC_64 ELF_V1 = char '.' <> prettyLbl + | otherwise = prettyLbl pprFunctionDescriptor :: CLabel -> SDoc pprFunctionDescriptor lab = pprGloblDecl lab ===================================== compiler/GHC/Iface/Ext/Ast.hs ===================================== @@ -2,9 +2,12 @@ Main functions for .hie file generation -} {-# LANGUAGE CPP #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE UndecidableSuperClasses #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE ScopedTypeVariables #-} @@ -572,7 +575,7 @@ class ToHie a where toHie :: a -> HieM [HieAST Type] -- | Used to collect type info -class Data a => HasType a where +class HasType a where getTypeNode :: a -> HieM [HieAST Type] instance (ToHie a) => ToHie [a] where @@ -584,12 +587,6 @@ instance (ToHie a) => ToHie (Bag a) where instance (ToHie a) => ToHie (Maybe a) where toHie = maybe (pure []) toHie -instance ToHie (Context (Located NoExtField)) where - toHie _ = pure [] - -instance ToHie (TScoped NoExtField) where - toHie _ = pure [] - instance ToHie (IEContext (Located ModuleName)) where toHie (IEC c (L (RealSrcSpan span _) mname)) = do org <- ask @@ -667,9 +664,6 @@ instance ToHie (EvBindContext (Located TcEvBinds)) where ] toHie _ = pure [] -instance ToHie (EvBindContext (Located NoExtField)) where - toHie _ = pure [] - instance ToHie (Located HsWrapper) where toHie (L osp wrap) = case wrap of @@ -685,32 +679,19 @@ instance ToHie (Located HsWrapper) where concatMapM (toHie . C EvidenceVarUse . L osp) $ evVarsOfTermList a _ -> pure [] --- | Dummy instances - never called -instance ToHie (TScoped (LHsSigWcType GhcTc)) where - toHie _ = pure [] -instance ToHie (TScoped (LHsWcType GhcTc)) where - toHie _ = pure [] -instance ToHie (SigContext (LSig GhcTc)) where - toHie _ = pure [] -instance ToHie (TScoped Type) where - toHie _ = pure [] - -instance HasType (LHsBind GhcRn) where - getTypeNode (L spn bind) = makeNode bind spn +instance HiePass p => HasType (LHsBind (GhcPass p)) where + getTypeNode (L spn bind) = + case hiePass @p of + HieRn -> makeNode bind spn + HieTc -> case bind of + FunBind{fun_id = name} -> makeTypeNode bind spn (varType $ unLoc name) + _ -> makeNode bind spn -instance HasType (LHsBind GhcTc) where - getTypeNode (L spn bind) = case bind of - FunBind{fun_id = name} -> makeTypeNode bind spn (varType $ unLoc name) - _ -> makeNode bind spn - -instance HasType (Located (Pat GhcRn)) where - getTypeNode (L spn pat) = makeNode pat spn - -instance HasType (Located (Pat GhcTc)) where - getTypeNode (L spn opat) = makeTypeNode opat spn (hsPatType opat) - -instance HasType (LHsExpr GhcRn) where - getTypeNode (L spn e) = makeNode e spn +instance HiePass p => HasType (Located (Pat (GhcPass p))) where + getTypeNode (L spn pat) = + case hiePass @p of + HieRn -> makeNode pat spn + HieTc -> makeTypeNode pat spn (hsPatType pat) -- | This instance tries to construct 'HieAST' nodes which include the type of -- the expression. It is not yet possible to do this efficiently for all @@ -727,73 +708,99 @@ instance HasType (LHsExpr GhcRn) where -- expression's type is going to be expensive. -- -- See #16233 -instance HasType (LHsExpr GhcTc) where +instance HiePass p => HasType (LHsExpr (GhcPass p)) where getTypeNode e@(L spn e') = - -- Some expression forms have their type immediately available - let tyOpt = case e' of - HsLit _ l -> Just (hsLitType l) - HsOverLit _ o -> Just (overLitType o) - - HsLam _ (MG { mg_ext = groupTy }) -> Just (matchGroupType groupTy) - HsLamCase _ (MG { mg_ext = groupTy }) -> Just (matchGroupType groupTy) - HsCase _ _ (MG { mg_ext = groupTy }) -> Just (mg_res_ty groupTy) - - ExplicitList ty _ _ -> Just (mkListTy ty) - ExplicitSum ty _ _ _ -> Just (mkSumTy ty) - HsDo ty _ _ -> Just ty - HsMultiIf ty _ -> Just ty - - _ -> Nothing - - in - case tyOpt of - Just t -> makeTypeNode e' spn t - Nothing - | skipDesugaring e' -> fallback - | otherwise -> do - hs_env <- lift $ lift $ Hsc $ \e w -> return (e,w) - (_,mbe) <- liftIO $ deSugarExpr hs_env e - maybe fallback (makeTypeNode e' spn . exprType) mbe - where - fallback = makeNode e' spn - - matchGroupType :: MatchGroupTc -> Type - matchGroupType (MatchGroupTc args res) = mkVisFunTys args res - - -- | Skip desugaring of these expressions for performance reasons. - -- - -- See impact on Haddock output (esp. missing type annotations or links) - -- before marking more things here as 'False'. See impact on Haddock - -- performance before marking more things as 'True'. - skipDesugaring :: HsExpr GhcTc -> Bool - skipDesugaring e = case e of - HsVar{} -> False - HsUnboundVar{} -> False - HsConLikeOut{} -> False - HsRecFld{} -> False - HsOverLabel{} -> False - HsIPVar{} -> False - XExpr (HsWrap{}) -> False - _ -> True - -instance ( ToHie (Context (Located (IdP (GhcPass a)))) - , ToHie (MatchGroup (GhcPass a) (LHsExpr (GhcPass a))) - , ToHie (PScoped (LPat (GhcPass a))) - , ToHie (GRHSs (GhcPass a) (LHsExpr (GhcPass a))) - , ToHie (LHsExpr (GhcPass a)) - , ToHie (Located (PatSynBind (GhcPass a) (GhcPass a))) - , HasType (LHsBind (GhcPass a)) - , ModifyState (IdP (GhcPass a)) - , Data (HsBind (GhcPass a)) - , IsPass a - ) => ToHie (BindContext (LHsBind (GhcPass a))) where + case hiePass @p of + HieRn -> makeNode e' spn + HieTc -> + -- Some expression forms have their type immediately available + let tyOpt = case e' of + HsLit _ l -> Just (hsLitType l) + HsOverLit _ o -> Just (overLitType o) + + HsLam _ (MG { mg_ext = groupTy }) -> Just (matchGroupType groupTy) + HsLamCase _ (MG { mg_ext = groupTy }) -> Just (matchGroupType groupTy) + HsCase _ _ (MG { mg_ext = groupTy }) -> Just (mg_res_ty groupTy) + + ExplicitList ty _ _ -> Just (mkListTy ty) + ExplicitSum ty _ _ _ -> Just (mkSumTy ty) + HsDo ty _ _ -> Just ty + HsMultiIf ty _ -> Just ty + + _ -> Nothing + + in + case tyOpt of + Just t -> makeTypeNode e' spn t + Nothing + | skipDesugaring e' -> fallback + | otherwise -> do + hs_env <- lift $ lift $ Hsc $ \e w -> return (e,w) + (_,mbe) <- liftIO $ deSugarExpr hs_env e + maybe fallback (makeTypeNode e' spn . exprType) mbe + where + fallback = makeNode e' spn + + matchGroupType :: MatchGroupTc -> Type + matchGroupType (MatchGroupTc args res) = mkVisFunTys args res + + -- | Skip desugaring of these expressions for performance reasons. + -- + -- See impact on Haddock output (esp. missing type annotations or links) + -- before marking more things here as 'False'. See impact on Haddock + -- performance before marking more things as 'True'. + skipDesugaring :: HsExpr GhcTc -> Bool + skipDesugaring e = case e of + HsVar{} -> False + HsUnboundVar{} -> False + HsConLikeOut{} -> False + HsRecFld{} -> False + HsOverLabel{} -> False + HsIPVar{} -> False + XExpr (HsWrap{}) -> False + _ -> True + +data HiePassEv p where + HieRn :: HiePassEv 'Renamed + HieTc :: HiePassEv 'Typechecked + +class ( IsPass p + , HiePass (NoGhcTcPass p) + , ModifyState (IdGhcP p) + , Data (GRHS (GhcPass p) (Located (HsExpr (GhcPass p)))) + , Data (HsExpr (GhcPass p)) + , Data (HsCmd (GhcPass p)) + , Data (AmbiguousFieldOcc (GhcPass p)) + , Data (HsCmdTop (GhcPass p)) + , Data (GRHS (GhcPass p) (Located (HsCmd (GhcPass p)))) + , Data (HsSplice (GhcPass p)) + , Data (HsLocalBinds (GhcPass p)) + , Data (FieldOcc (GhcPass p)) + , Data (HsTupArg (GhcPass p)) + , Data (IPBind (GhcPass p)) + , ToHie (Context (Located (IdGhcP p))) + , ToHie (RFContext (Located (AmbiguousFieldOcc (GhcPass p)))) + , ToHie (RFContext (Located (FieldOcc (GhcPass p)))) + , ToHie (TScoped (LHsWcType (GhcPass (NoGhcTcPass p)))) + , ToHie (TScoped (LHsSigWcType (GhcPass (NoGhcTcPass p)))) + , HasRealDataConName (GhcPass p) + ) + => HiePass p where + hiePass :: HiePassEv p + +instance HiePass 'Renamed where + hiePass = HieRn +instance HiePass 'Typechecked where + hiePass = HieTc + +instance HiePass p => ToHie (BindContext (LHsBind (GhcPass p))) where toHie (BC context scope b@(L span bind)) = concatM $ getTypeNode b : case bind of FunBind{fun_id = name, fun_matches = matches, fun_ext = wrap} -> [ toHie $ C (ValBind context scope $ getRealSpan span) name , toHie matches - , case ghcPass @a of - GhcTc -> toHie $ L span wrap + , case hiePass @p of + HieTc -> toHie $ L span wrap _ -> pure [] ] PatBind{pat_lhs = lhs, pat_rhs = rhs} -> @@ -822,25 +829,22 @@ instance ( ToHie (Context (Located (IdP (GhcPass a)))) [ toHie $ L span psb -- PatSynBinds only occur at the top level ] -instance ( ToHie (LMatch a body) - ) => ToHie (MatchGroup a body) where +instance ( HiePass p + , ToHie (Located body) + , Data body + ) => ToHie (MatchGroup (GhcPass p) (Located body)) where toHie mg = case mg of MG{ mg_alts = (L span alts) , mg_origin = origin} -> local (setOrigin origin) $ concatM [ locOnly span , toHie alts ] - XMatchGroup _ -> pure [] setOrigin :: Origin -> NodeOrigin -> NodeOrigin setOrigin FromSource _ = SourceInfo setOrigin Generated _ = GeneratedInfo -instance ( ToHie (Context (Located (IdP a))) - , ToHie (PScoped (LPat a)) - , ToHie (HsPatSynDir a) - , (a ~ GhcPass p) - ) => ToHie (Located (PatSynBind a a)) where +instance HiePass p => ToHie (Located (PatSynBind (GhcPass p) (GhcPass p))) where toHie (L sp psb) = concatM $ case psb of PSB{psb_id=var, psb_args=dets, psb_def=pat, psb_dir=dir} -> [ toHie $ C (Decl PatSynDec $ getRealSpan sp) var @@ -865,50 +869,39 @@ instance ( ToHie (Context (Located (IdP a))) toBind (InfixCon a b) = InfixCon (C Use a) (C Use b) toBind (RecCon r) = RecCon $ map (PSC detSpan) r -instance ( ToHie (MatchGroup a (LHsExpr a)) - ) => ToHie (HsPatSynDir a) where +instance HiePass p => ToHie (HsPatSynDir (GhcPass p)) where toHie dir = case dir of ExplicitBidirectional mg -> toHie mg _ -> pure [] -instance ( a ~ GhcPass p - , ToHie body - , ToHie (HsMatchContext (NoGhcTc a)) - , ToHie (PScoped (LPat a)) - , ToHie (GRHSs a body) - , Data (Match a body) - ) => ToHie (LMatch (GhcPass p) body) where - toHie (L span m ) = concatM $ makeNode m span : case m of +instance ( HiePass p + , Data body + , ToHie (Located body) + ) => ToHie (LMatch (GhcPass p) (Located body)) where + toHie (L span m ) = concatM $ node : case m of Match{m_ctxt=mctx, m_pats = pats, m_grhss = grhss } -> [ toHie mctx , let rhsScope = mkScope $ grhss_span grhss in toHie $ patScopes Nothing rhsScope NoScope pats , toHie grhss ] + where + node = case hiePass @p of + HieTc -> makeNode m span + HieRn -> makeNode m span -instance ( ToHie (Context (Located (IdP a))) - ) => ToHie (HsMatchContext a) where +instance HiePass p => ToHie (HsMatchContext (GhcPass p)) where toHie (FunRhs{mc_fun=name}) = toHie $ C MatchBind name toHie (StmtCtxt a) = toHie a toHie _ = pure [] -instance ( ToHie (HsMatchContext a) - ) => ToHie (HsStmtContext a) where +instance HiePass p => ToHie (HsStmtContext (GhcPass p)) where toHie (PatGuard a) = toHie a toHie (ParStmtCtxt a) = toHie a toHie (TransStmtCtxt a) = toHie a toHie _ = pure [] -instance ( a ~ GhcPass p - , IsPass p - , ToHie (Context (Located (IdP a))) - , ToHie (RContext (HsRecFields a (PScoped (LPat a)))) - , ToHie (LHsExpr a) - , ToHie (TScoped (LHsSigWcType a)) - , HasType (LPat a) - , Data (HsSplice a) - , IsPass p - ) => ToHie (PScoped (Located (Pat (GhcPass p)))) where +instance HiePass p => ToHie (PScoped (Located (Pat (GhcPass p)))) where toHie (PS rsp scope pscope lpat@(L ospan opat)) = concatM $ getTypeNode lpat : case opat of WildPat _ -> @@ -941,25 +934,25 @@ instance ( a ~ GhcPass p SumPat _ pat _ _ -> [ toHie $ PS rsp scope pscope pat ] - ConPat {pat_con = con, pat_args = dets, pat_con_ext = ext}-> - [ case ghcPass @p of - GhcPs -> toHie $ C Use $ con - GhcRn -> toHie $ C Use $ con - GhcTc -> toHie $ C Use $ fmap conLikeName con - , toHie $ contextify dets - , case ghcPass @p of - GhcTc -> - let ev_binds = cpt_binds ext + ConPat {pat_con = con, pat_args = dets, pat_con_ext = ext} -> + case hiePass @p of + HieTc -> + [ toHie $ C Use $ fmap conLikeName con + , toHie $ contextify dets + , let ev_binds = cpt_binds ext ev_vars = cpt_dicts ext wrap = cpt_wrap ext evscope = mkScope ospan `combineScopes` scope `combineScopes` pscope - in concatM [ toHie $ EvBindContext scope rsp $ L ospan ev_binds - , toHie $ L ospan wrap - , toHie $ map (C (EvidenceVarBind EvPatternBind evscope rsp) - . L ospan) ev_vars - ] - _ -> pure [] - ] + in concatM [ toHie $ EvBindContext scope rsp $ L ospan ev_binds + , toHie $ L ospan wrap + , toHie $ map (C (EvidenceVarBind EvPatternBind evscope rsp) + . L ospan) ev_vars + ] + ] + HieRn -> + [ toHie $ C Use con + , toHie $ contextify dets + ] ViewPat _ expr pat -> [ toHie expr , toHie $ PS rsp scope pscope pat @@ -976,26 +969,26 @@ instance ( a ~ GhcPass p ] SigPat _ pat sig -> [ toHie $ PS rsp scope pscope pat - , let cscope = mkLScope pat in - case ghcPass @p of - GhcPs -> pure [] - GhcTc -> pure [] - GhcRn -> + , case hiePass @p of + HieTc -> + let cscope = mkLScope pat in toHie $ TS (ResolvedScopes [cscope, scope, pscope]) - sig - ] - XPat e -> case ghcPass @p of + sig + HieRn -> pure [] + ] + XPat e -> + case hiePass @p of + HieTc -> + let CoPat wrap pat _ = e + in [ toHie $ L ospan wrap + , toHie $ PS rsp scope pscope $ (L ospan pat) + ] #if __GLASGOW_HASKELL__ < 811 - GhcPs -> noExtCon e - GhcRn -> noExtCon e + HieRn -> [] #endif - GhcTc -> - [ toHie $ L ospan wrap - , toHie $ PS rsp scope pscope $ (L ospan pat :: LPat a) - ] - where - CoPat wrap pat _ = e where + contextify :: a ~ LPat (GhcPass p) => HsConDetails a (HsRecFields (GhcPass p) a) + -> HsConDetails (PScoped a) (RContext (HsRecFields (GhcPass p) (PScoped a))) contextify (PrefixCon args) = PrefixCon $ patScopes rsp scope pscope args contextify (InfixCon a b) = InfixCon a' b' where [a', b'] = patScopes rsp scope pscope [a,b] @@ -1006,6 +999,7 @@ 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 $ [ bindingsOnly $ map (C $ TyVarBind (mkScope span) sc) (wcs++tvs) @@ -1013,48 +1007,31 @@ instance ToHie (TScoped (HsPatSigType GhcRn)) where ] -- See Note [Scoping Rules for SigPat] -instance ( ToHie body - , ToHie (LGRHS a body) - , ToHie (RScoped (LHsLocalBinds a)) - ) => ToHie (GRHSs a body) where +instance ( ToHie (Located body) + , HiePass p + , Data body + ) => ToHie (GRHSs (GhcPass p) (Located body)) where toHie grhs = concatM $ case grhs of GRHSs _ grhss binds -> [ toHie grhss , toHie $ RS (mkScope $ grhss_span grhs) binds ] - XGRHSs _ -> [] instance ( ToHie (Located body) - , ToHie (RScoped (GuardLStmt (GhcPass a))) - , Data (GRHS (GhcPass a) (Located body)) + , HiePass a + , Data body ) => ToHie (LGRHS (GhcPass a) (Located body)) where - toHie (L span g) = concatM $ makeNode g span : case g of + toHie (L span g) = concatM $ node : case g of GRHS _ guards body -> [ toHie $ listScopes (mkLScope body) guards , toHie body ] + where + node = case hiePass @a of + HieRn -> makeNode g span + HieTc -> makeNode g span -instance ( a ~ GhcPass p - , ToHie (Context (Located (IdP a))) - , HasType (LHsExpr a) - , ToHie (PScoped (LPat a)) - , ToHie (MatchGroup a (LHsExpr a)) - , ToHie (LGRHS a (LHsExpr a)) - , ToHie (RContext (HsRecordBinds a)) - , ToHie (RFContext (Located (AmbiguousFieldOcc a))) - , ToHie (ArithSeqInfo a) - , ToHie (LHsCmdTop a) - , ToHie (RScoped (GuardLStmt a)) - , ToHie (RScoped (LHsLocalBinds a)) - , ToHie (TScoped (LHsWcType (NoGhcTc a))) - , ToHie (TScoped (LHsSigWcType (NoGhcTc a))) - , Data (HsExpr a) - , Data (HsSplice a) - , Data (HsTupArg a) - , Data (AmbiguousFieldOcc a) - , (HasRealDataConName a) - , IsPass p - ) => ToHie (LHsExpr (GhcPass p)) where +instance HiePass p => ToHie (LHsExpr (GhcPass p)) where toHie e@(L mspan oexpr) = concatM $ getTypeNode e : case oexpr of HsVar _ (L _ var) -> [ toHie $ C Use (L mspan var) @@ -1135,7 +1112,7 @@ instance ( a ~ GhcPass p [ toHie exprs ] RecordCon {rcon_ext = mrealcon, rcon_con_name = name, rcon_flds = binds} -> - [ toHie $ C Use (getRealDataCon @a mrealcon name) + [ toHie $ C Use (getRealDataCon @(GhcPass p) mrealcon name) -- See Note [Real DataCon Name] , toHie $ RC RecFieldAssign $ binds ] @@ -1186,30 +1163,20 @@ instance ( a ~ GhcPass p -> [ toHie $ L mspan a , toHie (L mspan w) ] - | otherwise - -> [] + | otherwise -> [] -instance ( a ~ GhcPass p - , ToHie (LHsExpr a) - , Data (HsTupArg a) - ) => ToHie (LHsTupArg (GhcPass p)) where +instance HiePass p => ToHie (LHsTupArg (GhcPass p)) where toHie (L span arg) = concatM $ makeNode arg span : case arg of Present _ expr -> [ toHie expr ] Missing _ -> [] -instance ( a ~ GhcPass p - , ToHie (PScoped (LPat a)) - , ToHie (LHsExpr a) - , ToHie (SigContext (LSig a)) - , ToHie (RScoped (LHsLocalBinds a)) - , ToHie (RScoped (ApplicativeArg a)) - , ToHie (Located body) - , Data (StmtLR a a (Located body)) - , Data (StmtLR a a (Located (HsExpr a))) +instance ( ToHie (Located body) + , Data body + , HiePass p ) => ToHie (RScoped (LStmt (GhcPass p) (Located body))) where - toHie (RS scope (L span stmt)) = concatM $ makeNode stmt span : case stmt of + toHie (RS scope (L span stmt)) = concatM $ node : case stmt of LastStmt _ body _ _ -> [ toHie body ] @@ -1239,47 +1206,36 @@ instance ( a ~ GhcPass p RecStmt {recS_stmts = stmts} -> [ toHie $ map (RS $ combineScopes scope (mkScope span)) stmts ] + where + node = case hiePass @p of + HieTc -> makeNode stmt span + HieRn -> makeNode stmt span -instance ( ToHie (LHsExpr a) - , ToHie (PScoped (LPat a)) - , ToHie (BindContext (LHsBind a)) - , ToHie (SigContext (LSig a)) - , ToHie (RScoped (HsValBindsLR a a)) - , ToHie (EvBindContext (Located (XIPBinds a))) - , ToHie (RScoped (LIPBind a)) - , Data (HsLocalBinds a) - ) => ToHie (RScoped (LHsLocalBinds a)) where +instance HiePass p => ToHie (RScoped (LHsLocalBinds (GhcPass p))) where toHie (RS scope (L sp binds)) = concatM $ makeNode binds sp : case binds of EmptyLocalBinds _ -> [] HsIPBinds _ ipbinds -> case ipbinds of IPBinds evbinds xs -> let sc = combineScopes scope $ mkScope sp in - [ toHie $ EvBindContext sc (getRealSpan sp) $ L sp evbinds + [ case hiePass @p of + HieTc -> toHie $ EvBindContext sc (getRealSpan sp) $ L sp evbinds + HieRn -> pure [] , toHie $ map (RS sc) xs ] - XHsIPBinds _ -> [] HsValBinds _ valBinds -> [ toHie $ RS (combineScopes scope $ mkScope sp) valBinds ] - XHsLocalBindsLR _ -> [] -instance ( ToHie (LHsExpr a) - , ToHie (Context (Located (IdP a))) - , Data (IPBind a) - ) => ToHie (RScoped (LIPBind a)) where +instance HiePass p => ToHie (RScoped (LIPBind (GhcPass p))) where toHie (RS scope (L sp bind)) = concatM $ makeNode bind sp : case bind of IPBind _ (Left _) expr -> [toHie expr] IPBind _ (Right v) expr -> [ toHie $ C (EvidenceVarBind EvImplicitBind scope (getRealSpan sp)) - $ L sp v + $ L sp v , toHie expr ] - XIPBind _ -> [] -instance ( ToHie (BindContext (LHsBind a)) - , ToHie (SigContext (LSig a)) - , ToHie (RScoped (XXValBindsLR a a)) - ) => ToHie (RScoped (HsValBindsLR a a)) where +instance HiePass p => ToHie (RScoped (HsValBindsLR (GhcPass p) (GhcPass p))) where toHie (RS sc v) = concatM $ case v of ValBinds _ binds sigs -> [ toHie $ fmap (BC RegularBind sc) binds @@ -1287,26 +1243,19 @@ instance ( ToHie (BindContext (LHsBind a)) ] XValBindsLR x -> [ toHie $ RS sc x ] -instance ToHie (RScoped (NHsValBindsLR GhcTc)) where - toHie (RS sc (NValBinds binds sigs)) = concatM $ - [ toHie (concatMap (map (BC RegularBind sc) . bagToList . snd) binds) - , toHie $ fmap (SC (SI BindSig Nothing)) sigs - ] -instance ToHie (RScoped (NHsValBindsLR GhcRn)) where +instance HiePass p => ToHie (RScoped (NHsValBindsLR (GhcPass p))) where toHie (RS sc (NValBinds binds sigs)) = concatM $ [ toHie (concatMap (map (BC RegularBind sc) . bagToList . snd) binds) , toHie $ fmap (SC (SI BindSig Nothing)) sigs ] -instance ( ToHie (RContext (LHsRecField a arg)) - ) => ToHie (RContext (HsRecFields a arg)) where +instance ( ToHie arg , HasLoc arg , Data arg + , HiePass p ) => ToHie (RContext (HsRecFields (GhcPass p) arg)) where toHie (RC c (HsRecFields fields _)) = toHie $ map (RC c) fields instance ( ToHie (RFContext (Located label)) - , ToHie arg - , HasLoc arg + , ToHie arg , HasLoc arg , Data arg , Data label - , Data arg ) => ToHie (RContext (LHsRecField' label arg)) where toHie (RC c (L span recfld)) = concatM $ makeNode recfld span : case recfld of HsRecField label expr _ -> @@ -1349,16 +1298,7 @@ instance ToHie (RFContext (Located (AmbiguousFieldOcc GhcTc))) where in [ toHie $ C (RecField c rhs) (L nspan var') ] -instance ( a ~ GhcPass p - , ToHie (PScoped (LPat a)) - , ToHie (BindContext (LHsBind a)) - , ToHie (LHsExpr a) - , ToHie (SigContext (LSig a)) - , ToHie (RScoped (HsValBindsLR a a)) - , ToHie (RScoped (ExprLStmt a)) - , Data (StmtLR a a (Located (HsExpr a))) - , Data (HsLocalBinds a) - ) => ToHie (RScoped (ApplicativeArg (GhcPass p))) where +instance HiePass p => ToHie (RScoped (ApplicativeArg (GhcPass p))) where toHie (RS sc (ApplicativeArgOne _ pat expr _)) = concatM [ toHie $ PS Nothing sc NoScope pat , toHie expr @@ -1373,29 +1313,13 @@ instance (ToHie arg, ToHie rec) => ToHie (HsConDetails arg rec) where toHie (RecCon rec) = toHie rec toHie (InfixCon a b) = concatM [ toHie a, toHie b] -instance ( ToHie (LHsCmd a) - , Data (HsCmdTop a) - ) => ToHie (LHsCmdTop a) where +instance HiePass p => ToHie (LHsCmdTop (GhcPass p)) where toHie (L span top) = concatM $ makeNode top span : case top of HsCmdTop _ cmd -> [ toHie cmd ] - XCmdTop _ -> [] - -instance ( a ~ GhcPass p - , ToHie (PScoped (LPat a)) - , ToHie (BindContext (LHsBind a)) - , ToHie (LHsExpr a) - , ToHie (MatchGroup a (LHsCmd a)) - , ToHie (SigContext (LSig a)) - , ToHie (RScoped (HsValBindsLR a a)) - , ToHie (RScoped (LHsLocalBinds a)) - , Data (HsCmd a) - , Data (HsCmdTop a) - , Data (StmtLR a a (Located (HsCmd a))) - , Data (HsLocalBinds a) - , Data (StmtLR a a (Located (HsExpr a))) - ) => ToHie (LHsCmd (GhcPass p)) where + +instance HiePass p => ToHie (LHsCmd (GhcPass p)) where toHie (L span cmd) = concatM $ makeNode cmd span : case cmd of HsCmdArrApp _ a b _ _ -> [ toHie a @@ -1658,48 +1582,51 @@ instance ToHie (StandaloneKindSig GhcRn) where , toHie $ TS (ResolvedScopes []) typ ] -instance ToHie (SigContext (LSig GhcRn)) where - toHie (SC (SI styp msp) (L sp sig)) = concatM $ makeNode sig sp : case sig of - TypeSig _ names typ -> - [ toHie $ map (C TyDecl) names - , toHie $ TS (UnresolvedScope (map unLoc names) Nothing) typ - ] - PatSynSig _ names typ -> - [ toHie $ map (C TyDecl) names - , toHie $ TS (UnresolvedScope (map unLoc names) Nothing) typ - ] - ClassOpSig _ _ names typ -> - [ case styp of - ClassSig -> toHie $ map (C $ ClassTyDecl $ getRealSpan sp) names - _ -> toHie $ map (C $ TyDecl) names - , toHie $ TS (UnresolvedScope (map unLoc names) msp) typ - ] - IdSig _ _ -> [] - FixSig _ fsig -> - [ toHie $ L sp fsig - ] - InlineSig _ name _ -> - [ toHie $ (C Use) name - ] - SpecSig _ name typs _ -> - [ toHie $ (C Use) name - , toHie $ map (TS (ResolvedScopes [])) typs - ] - SpecInstSig _ _ typ -> - [ toHie $ TS (ResolvedScopes []) typ - ] - MinimalSig _ _ form -> - [ toHie form - ] - SCCFunSig _ _ name mtxt -> - [ toHie $ (C Use) name - , maybe (pure []) (locOnly . getLoc) mtxt - ] - CompleteMatchSig _ _ (L ispan names) typ -> - [ locOnly ispan - , toHie $ map (C Use) names - , toHie $ fmap (C Use) typ - ] +instance HiePass p => ToHie (SigContext (LSig (GhcPass p))) where + toHie (SC (SI styp msp) (L sp sig)) = + case hiePass @p of + HieTc -> pure [] + HieRn -> concatM $ makeNode sig sp : case sig of + TypeSig _ names typ -> + [ toHie $ map (C TyDecl) names + , toHie $ TS (UnresolvedScope (map unLoc names) Nothing) typ + ] + PatSynSig _ names typ -> + [ toHie $ map (C TyDecl) names + , toHie $ TS (UnresolvedScope (map unLoc names) Nothing) typ + ] + ClassOpSig _ _ names typ -> + [ case styp of + ClassSig -> toHie $ map (C $ ClassTyDecl $ getRealSpan sp) names + _ -> toHie $ map (C $ TyDecl) names + , toHie $ TS (UnresolvedScope (map unLoc names) msp) typ + ] + IdSig _ _ -> [] + FixSig _ fsig -> + [ toHie $ L sp fsig + ] + InlineSig _ name _ -> + [ toHie $ (C Use) name + ] + SpecSig _ name typs _ -> + [ toHie $ (C Use) name + , toHie $ map (TS (ResolvedScopes [])) typs + ] + SpecInstSig _ _ typ -> + [ toHie $ TS (ResolvedScopes []) typ + ] + MinimalSig _ _ form -> + [ toHie form + ] + SCCFunSig _ _ name mtxt -> + [ toHie $ (C Use) name + , maybe (pure []) (locOnly . getLoc) mtxt + ] + CompleteMatchSig _ _ (L ispan names) typ -> + [ locOnly ispan + , toHie $ map (C Use) names + , toHie $ fmap (C Use) typ + ] instance ToHie (LHsType GhcRn) where toHie x = toHie $ TS (ResolvedScopes []) x @@ -1863,11 +1790,7 @@ instance ToHie (LBooleanFormula (Located Name)) where instance ToHie (Located HsIPName) where toHie (L span e) = makeNode e span -instance ( a ~ GhcPass p - , ToHie (LHsExpr a) - , Data (HsSplice a) - , IsPass p - ) => ToHie (Located (HsSplice a)) where +instance HiePass p => ToHie (Located (HsSplice (GhcPass p))) where toHie (L span sp) = concatM $ makeNode sp span : case sp of HsTypedSplice _ _ _ expr -> [ toHie expr ===================================== compiler/GHC/Parser.y ===================================== @@ -2738,11 +2738,9 @@ fexp :: { ECP } mkHsAppPV (comb2 $1 $>) $1 $2 } -- See Note [Whitespace-sensitive operator parsing] in GHC.Parser.Lexer - | fexp PREFIX_AT atype {% runECP_P $1 >>= \ $1 -> - runPV (checkExpBlockArguments $1) >>= \_ -> - fmap ecpFromExp $ - ams (sLL $1 $> $ HsAppType noExtField $1 (mkHsWildCardBndrs $3)) - [mj AnnAt $2] } + | fexp PREFIX_AT atype { ECP $ + runECP_PV $1 >>= \ $1 -> + amms (mkHsAppTypePV (comb2 $1 $>) $1 $3) [mj AnnAt $2] } | 'static' aexp {% runECP_P $2 >>= \ $2 -> fmap ecpFromExp $ ===================================== compiler/GHC/Parser/Lexer.x ===================================== @@ -366,15 +366,20 @@ $tab { warnTab } -- "special" symbols <0> { - "[|" / { ifExtension ThQuotesBit } { token (ITopenExpQuote NoE NormalSyntax) } - "[||" / { ifExtension ThQuotesBit } { token (ITopenTExpQuote NoE) } + + -- Don't check ThQuotesBit here as the renamer can produce a better + -- error message than the lexer (see the thQuotesEnabled check in rnBracket). + "[|" { token (ITopenExpQuote NoE NormalSyntax) } + "[||" { token (ITopenTExpQuote NoE) } + "|]" { token (ITcloseQuote NormalSyntax) } + "||]" { token ITcloseTExpQuote } + + -- Check ThQuotesBit here as to not steal syntax. "[e|" / { ifExtension ThQuotesBit } { token (ITopenExpQuote HasE NormalSyntax) } "[e||" / { ifExtension ThQuotesBit } { token (ITopenTExpQuote HasE) } "[p|" / { ifExtension ThQuotesBit } { token ITopenPatQuote } "[d|" / { ifExtension ThQuotesBit } { layout_token ITopenDecQuote } "[t|" / { ifExtension ThQuotesBit } { token ITopenTypQuote } - "|]" / { ifExtension ThQuotesBit } { token (ITcloseQuote NormalSyntax) } - "||]" / { ifExtension ThQuotesBit } { token ITcloseTExpQuote } "[" @varid "|" / { ifExtension QqBit } { lex_quasiquote_tok } @@ -1449,7 +1454,7 @@ qconsym buf len = ITqconsym $! splitQualName buf len False -- See Note [Whitespace-sensitive operator parsing] varsym_prefix :: Action varsym_prefix = sym $ \exts s -> - if | TypeApplicationsBit `xtest` exts, s == fsLit "@" + if | s == fsLit "@" -- regardless of TypeApplications for better error messages -> return ITtypeApp | ThQuotesBit `xtest` exts, s == fsLit "$" -> return ITdollar @@ -2461,7 +2466,6 @@ data ExtBits | BinaryLiteralsBit | NegativeLiteralsBit | HexFloatLiteralsBit - | TypeApplicationsBit | StaticPointersBit | NumericUnderscoresBit | StarIsTypeBit @@ -2548,7 +2552,6 @@ mkParserFlags' warningFlags extensionFlags thisPackage .|. NegativeLiteralsBit `xoptBit` LangExt.NegativeLiterals .|. HexFloatLiteralsBit `xoptBit` LangExt.HexFloatLiterals .|. PatternSynonymsBit `xoptBit` LangExt.PatternSynonyms - .|. TypeApplicationsBit `xoptBit` LangExt.TypeApplications .|. StaticPointersBit `xoptBit` LangExt.StaticPointers .|. NumericUnderscoresBit `xoptBit` LangExt.NumericUnderscores .|. StarIsTypeBit `xoptBit` LangExt.StarIsType ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -1137,6 +1137,13 @@ checkAPat loc e0 = do | nPlusKPatterns && (plus == plus_RDR) -> return (mkNPlusKPat (L nloc n) (L lloc lit)) + -- Improve error messages for the @-operator when the user meant an @-pattern + PatBuilderOpApp _ op _ | opIsAt (unLoc op) -> do + addError (getLoc op) $ + text "Found a binding for the" <+> quotes (ppr op) <+> text "operator in a pattern position." $$ + perhaps_as_pat + return (WildPat noExtField) + PatBuilderOpApp l (L cl c) r | isRdrDataCon c -> do l <- checkLPat l @@ -1171,6 +1178,9 @@ patFail loc e = addFatalError loc $ text "Parse error in pattern:" <+> ppr e patIsRec :: RdrName -> Bool patIsRec e = e == mkUnqual varName (fsLit "rec") +opIsAt :: RdrName -> Bool +opIsAt e = e == mkUnqual varName (fsLit "@") + --------------------------------------------------------------------------- -- Check Equation Syntax @@ -1203,7 +1213,7 @@ checkFunBind :: SrcStrictness -> Located (GRHSs GhcPs (LHsExpr GhcPs)) -> P ([AddAnn],HsBind GhcPs) checkFunBind strictness ann lhs_loc fun is_infix pats (L rhs_span grhss) - = do ps <- mapM checkPattern pats + = do ps <- runPV_msg param_hint (mapM checkLPat pats) let match_span = combineSrcSpans lhs_loc rhs_span -- Add back the annotations stripped from any HsPar values in the lhs -- mapM_ (\a -> a match_span) ann @@ -1217,6 +1227,15 @@ checkFunBind strictness ann lhs_loc fun is_infix pats (L rhs_span grhss) , m_grhss = grhss })]) -- The span of the match covers the entire equation. -- That isn't quite right, but it'll do for now. + where + param_hint + | Infix <- is_infix + = text "In a function binding for the" <+> quotes (ppr fun) <+> text "operator." $$ + if opIsAt (unLoc fun) then perhaps_as_pat else empty + | otherwise = empty + +perhaps_as_pat :: SDoc +perhaps_as_pat = text "Perhaps you meant an as-pattern, which must not be surrounded by whitespace" makeFunBind :: Located RdrName -> [LMatch GhcPs (LHsExpr GhcPs)] -> HsBind GhcPs @@ -1792,6 +1811,8 @@ class b ~ (Body b) GhcPs => DisambECP b where superFunArg :: (DisambECP (FunArg b) => PV (Located b)) -> PV (Located b) -- | Disambiguate "f x" (function application) mkHsAppPV :: SrcSpan -> Located b -> Located (FunArg b) -> PV (Located b) + -- | Disambiguate "f @t" (visible type application) + mkHsAppTypePV :: SrcSpan -> Located b -> LHsType GhcPs -> PV (Located b) -- | Disambiguate "if ... then ... else ..." mkHsIfPV :: SrcSpan -> LHsExpr GhcPs @@ -1906,6 +1927,7 @@ instance DisambECP (HsCmd GhcPs) where checkCmdBlockArguments c checkExpBlockArguments e return $ L l (HsCmdApp noExtField c e) + mkHsAppTypePV l c t = cmdFail l (ppr c <+> text "@" <> ppr t) mkHsIfPV l c semi1 a semi2 b = do checkDoAndIfThenElse c semi1 a semi2 b return $ L l (mkHsCmdIf c a b) @@ -1963,6 +1985,9 @@ instance DisambECP (HsExpr GhcPs) where checkExpBlockArguments e1 checkExpBlockArguments e2 return $ L l (HsApp noExtField e1 e2) + mkHsAppTypePV l e t = do + checkExpBlockArguments e + return $ L l (HsAppType noExtField e (mkHsWildCardBndrs t)) mkHsIfPV l c semi1 a semi2 b = do checkDoAndIfThenElse c semi1 a semi2 b return $ L l (mkHsIf c a b) @@ -2045,6 +2070,8 @@ instance DisambECP (PatBuilder GhcPs) where type FunArg (PatBuilder GhcPs) = PatBuilder GhcPs superFunArg m = m mkHsAppPV l p1 p2 = return $ L l (PatBuilderApp p1 p2) + mkHsAppTypePV l _ _ = addFatalError l $ + text "Type applications in patterns are not yet supported" mkHsIfPV l _ _ _ _ _ = addFatalError l $ text "(if ... then ... else ...)-syntax in pattern" mkHsDoPV l _ = addFatalError l $ text "do-notation in pattern" mkHsParPV l p = return $ L l (PatBuilderPar p) ===================================== compiler/GHC/Utils/Monad.hs ===================================== @@ -138,22 +138,31 @@ mapAndUnzip5M :: Monad m => (a -> m (b,c,d,e,f)) -> [a] -> m ([b],[c],[d],[e],[f -- See Note [Inline @mapAndUnzipNM@ functions] above. mapAndUnzip5M f xs = unzip5 <$> traverse f xs +-- TODO: mapAccumLM is used in many places. Surely most of +-- these don't actually want to be lazy. We should add a strict +-- variant and use it where appropriate. + -- | Monadic version of mapAccumL mapAccumLM :: Monad m => (acc -> x -> m (acc, y)) -- ^ combining function -> acc -- ^ initial state -> [x] -- ^ inputs -> m (acc, [y]) -- ^ final state, outputs -mapAccumLM _ s [] = return (s, []) -mapAccumLM f s (x:xs) = do - (s1, x') <- f s x - (s2, xs') <- mapAccumLM f s1 xs - return (s2, x' : xs') +mapAccumLM f s xs = + go s xs + where + go s (x:xs) = do + (s1, x') <- f s x + (s2, xs') <- go s1 xs + return (s2, x' : xs') + go s [] = return (s, []) -- | Monadic version of mapSnd mapSndM :: Monad m => (b -> m c) -> [(a,b)] -> m [(a,c)] -mapSndM _ [] = return [] -mapSndM f ((a,b):xs) = do { c <- f b; rs <- mapSndM f xs; return ((a,c):rs) } +mapSndM f xs = go xs + where + go [] = return [] + go ((a,b):xs) = do { c <- f b; rs <- go xs; return ((a,c):rs) } -- | Monadic version of concatMap concatMapM :: Monad m => (a -> m [b]) -> [a] -> m [b] @@ -176,15 +185,19 @@ fmapEitherM _ fr (Right b) = fr b >>= (return . Right) -- | Monadic version of 'any', aborts the computation at the first @True@ value anyM :: Monad m => (a -> m Bool) -> [a] -> m Bool -anyM _ [] = return False -anyM f (x:xs) = do b <- f x +anyM f xs = go xs + where + go [] = return False + go (x:xs) = do b <- f x if b then return True - else anyM f xs + else go xs -- | Monad version of 'all', aborts the computation at the first @False@ value allM :: Monad m => (a -> m Bool) -> [a] -> m Bool -allM _ [] = return True -allM f (b:bs) = (f b) >>= (\bv -> if bv then allM f bs else return False) +allM f bs = go bs + where + go [] = return True + go (b:bs) = (f b) >>= (\bv -> if bv then go bs else return False) -- | Monadic version of or orM :: Monad m => m Bool -> m Bool -> m Bool ===================================== configure.ac ===================================== @@ -978,7 +978,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 ===================================== docs/users_guide/8.12.1-notes.rst ===================================== @@ -17,7 +17,7 @@ Highlights digit improvements in runtime for inner loops. In the mean this improved runtime by about 0.8%. For details - see ticket #17823. + see ticket :ghc-ticket:`17823`. Full details ------------ @@ -95,7 +95,7 @@ Language effectively allows users to choose which variables can or can't be instantiated through visible type application. More information can be found here: :ref:`Manually-defining-inferred-variables`. - + Compiler ~~~~~~~~ @@ -105,11 +105,18 @@ 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) + escaping spaces in file names with a backslash. (:ghc-ticket:`18027`) Runtime system ~~~~~~~~~~~~~~ +- :rts-flag:`-N` without a count now tries to respect the number of processors + in the process's affinity mask, making GHC's behavior more predictable in + containerized settings (:ghc-ticket:`14781`). + +- Support for Windows Vista has been dropped. GHC-compiled programs now require + Windows 7 or later. + Template Haskell ~~~~~~~~~~~~~~~~ ===================================== docs/users_guide/bugs.rst ===================================== @@ -76,13 +76,20 @@ Lexical syntax See `GHC Proposal #229 `__ for the precise rules. -- As-patterns must not be surrounded by whitespace:: +- As-patterns must not be surrounded by whitespace on either side:: f p@(x, y, z) = ... -- accepted by both GHC and the Haskell Report - f p @ (x, y, z) = ... -- accepted by the Haskell Report but not GHC - When surrounded by whitespace, ``(@)`` is treated by GHC as a regular infix - operator. + -- accepted by the Haskell Report but not GHC: + f p @ (x, y, z) = ... + f p @(x, y, z) = ... + f p@ (x, y, z) = ... + + When surrounded by whitespace on both sides, ``(@)`` is treated by GHC as a + regular infix operator. + + When preceded but not followed by whitespace, ``(@)`` is treated as a + visible type application. See `GHC Proposal #229 `__ for the precise rules. ===================================== docs/users_guide/using-concurrent.rst ===================================== @@ -111,6 +111,7 @@ There are two ways to run a program on multiple processors: call use the RTS :rts-flag:`-N ⟨x⟩` options. .. rts-flag:: -N ⟨x⟩ + -N -maxN ⟨x⟩ Use ⟨x⟩ simultaneous threads when running the program. ===================================== hadrian/src/Settings/Packages.hs ===================================== @@ -462,4 +462,4 @@ rtsWarnings = mconcat -- and also centralizes the versioning. -- | Minimum supported Windows version. windowsVersion :: String -windowsVersion = "0x06000100" +windowsVersion = "0x06010000" ===================================== mk/get-win32-tarballs.py ===================================== @@ -7,7 +7,7 @@ import subprocess import argparse from sys import stderr -TARBALL_VERSION = '0.1' +TARBALL_VERSION = '0.2' BASE_URL = "https://downloads.haskell.org/ghc/mingw/{}".format(TARBALL_VERSION) DEST = Path('ghc-tarballs/mingw-w64') ARCHS = ['i686', 'x86_64', 'sources'] ===================================== rts/ghc.mk ===================================== @@ -25,7 +25,7 @@ rts_VERSION = 1.0 # If we're compiling on windows, enforce that we only support Vista SP1+ # Adding this here means it doesn't have to be done in individual .c files # and also centralizes the versioning. -rts_WINVER = 0x06000100 +rts_WINVER = 0x06010000 # merge GhcLibWays and GhcRTSWays but strip out duplicates rts_WAYS = $(GhcLibWays) $(filter-out $(GhcLibWays),$(GhcRTSWays)) ===================================== 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/parser/should_fail/T18251a.hs ===================================== @@ -0,0 +1,3 @@ +module T18251a where + +pairs xs @ (_:xs') = zip xs xs' ===================================== testsuite/tests/parser/should_fail/T18251a.stderr ===================================== @@ -0,0 +1,5 @@ + +T18251a.hs:3:1: error: + Parse error in pattern: pairs + In a function binding for the ‘@’ operator. + Perhaps you meant an as-pattern, which must not be surrounded by whitespace ===================================== testsuite/tests/parser/should_fail/T18251b.hs ===================================== @@ -0,0 +1,3 @@ +module T18251a where + +pairs (xs @ (_:xs')) = zip xs xs' ===================================== testsuite/tests/parser/should_fail/T18251b.stderr ===================================== @@ -0,0 +1,4 @@ + +T18251b.hs:3:11: error: + Found a binding for the ‘@’ operator in a pattern position. + Perhaps you meant an as-pattern, which must not be surrounded by whitespace ===================================== testsuite/tests/parser/should_fail/T18251c.hs ===================================== @@ -0,0 +1,3 @@ +module T18251c where + +f = id @Int ===================================== testsuite/tests/parser/should_fail/T18251c.stderr ===================================== @@ -0,0 +1,4 @@ + +T18251c.hs:3:5: error: + Illegal visible type application ‘@Int’ + Perhaps you intended to use TypeApplications ===================================== testsuite/tests/parser/should_fail/T18251d.hs ===================================== @@ -0,0 +1,6 @@ +{-# LANGUAGE ExplicitForAll #-} + +module T18251d where + +f :: forall a. a -> () +f @a _ = () ===================================== testsuite/tests/parser/should_fail/T18251d.stderr ===================================== @@ -0,0 +1,3 @@ + +T18251d.hs:6:1: error: + Type applications in patterns are not yet supported ===================================== testsuite/tests/parser/should_fail/T18251e.hs ===================================== @@ -0,0 +1,3 @@ +module T18251e where + +a = [| id |] ===================================== testsuite/tests/parser/should_fail/T18251e.stderr ===================================== @@ -0,0 +1,5 @@ + +T18251e.hs:3:5: error: + • Syntax error on [| id |] + Perhaps you intended to use TemplateHaskell or TemplateHaskellQuotes + • In the Template Haskell quotation [| id |] ===================================== testsuite/tests/parser/should_fail/T18251f.hs ===================================== @@ -0,0 +1,3 @@ +module T18251f where + +f ! x y = x + y ===================================== testsuite/tests/parser/should_fail/T18251f.stderr ===================================== @@ -0,0 +1,4 @@ + +T18251f.hs:3:5: error: + Parse error in pattern: x + In a function binding for the ‘!’ operator. ===================================== testsuite/tests/parser/should_fail/all.T ===================================== @@ -166,4 +166,10 @@ 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, ['']) +test('T18130Fail', normal, compile_fail, ['']) +test('T18251a', normal, compile_fail, ['']) +test('T18251b', normal, compile_fail, ['']) +test('T18251c', normal, compile_fail, ['']) +test('T18251d', normal, compile_fail, ['']) +test('T18251e', normal, compile_fail, ['']) +test('T18251f', normal, compile_fail, ['']) ===================================== testsuite/tests/th/T12411.stderr ===================================== @@ -1,8 +1,6 @@ -T12411.hs:4:6: error: - Variable not in scope: - (@) - :: (a1 -> f0 a1) -> t0 -> Language.Haskell.TH.Lib.Internal.DecsQ +T12411.hs:4:1: error: + Illegal visible type application ‘@Q’ + Perhaps you intended to use TypeApplications -T12411.hs:4:7: error: - Data constructor not in scope: Q :: [a0] -> t0 +T12411.hs:4:7: error: Not in scope: type constructor or class ‘Q’ ===================================== testsuite/tests/typecheck/should_fail/T15527.stderr ===================================== @@ -1,8 +1,4 @@ -T15527.hs:4:10: error: - Variable not in scope: - (@) - :: ((b0 -> c0) -> (a0 -> b0) -> a0 -> c0) - -> t0 -> (Int -> Int) -> (Int -> Int) -> Int -> Int - -T15527.hs:4:11: error: Data constructor not in scope: Int +T15527.hs:4:6: error: + Illegal visible type application ‘@Int’ + Perhaps you intended to use TypeApplications View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/13c61680f73c6f103a2da465e55ed98ec5820515...833faecd96df5f9e36831cb196f400c5aeeea4c2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/13c61680f73c6f103a2da465e55ed98ec5820515...833faecd96df5f9e36831cb196f400c5aeeea4c2 You're receiving 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 30 14:21:28 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 30 May 2020 10:21:28 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/backports Message-ID: <5ed26be84d057_6e263f9ee36616e42895170@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/backports at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/backports You're receiving 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 30 14:24:51 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 30 May 2020 10:24:51 -0400 Subject: [Git][ghc/ghc][wip/backports-8.8] FastString: fix eager reading of string ptr in hashStr Message-ID: <5ed26cb311fb8_6e263f9ee36616e429041ce@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/backports-8.8 at Glasgow Haskell Compiler / GHC Commits: bc05d359 by Ömer Sinan Ağacan at 2020-05-30T10:20:52-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 cb1785d9f839e34a3a4892f354f0c51cc6553c0e) - - - - - 1 changed file: - compiler/utils/FastString.hs Changes: ===================================== compiler/utils/FastString.hs ===================================== @@ -519,16 +519,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 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bc05d3599545ddca50dbd8a557fd71785f6cb6fd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bc05d3599545ddca50dbd8a557fd71785f6cb6fd You're receiving 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 30 15:11:01 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 30 May 2020 11:11:01 -0400 Subject: [Git][ghc/ghc][wip/backports] 8 commits: rts/CNF: Fix fixup comparison function Message-ID: <5ed2778566425_6e263f9ee36616e429238aa@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/backports at Glasgow Haskell Compiler / GHC Commits: 8ec9a77d by Ben Gamari at 2020-05-30T10:31:04-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 (cherry picked from commit cf4f1e2f78840d25b132de55bce1e02256334ace) - - - - - 90aa3c33 by Ryan Scott at 2020-05-30T10:33:49-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. (cherry picked from commit 518a63d4d7e31e49a81ad66d5e5ccb1f790f6de9) - - - - - 2436537a by Ryan Scott at 2020-05-30T10:38:12-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. (cherry picked from commit cd8409c26d4370bf2cdcd76801974e99a9adf7b0) - - - - - 3c82e336 by Sebastian Graf at 2020-05-30T10:44:29-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. (cherry picked from commit ed58d4fdcbc7b4fa8fbdf3d638a8d53c444ef4f2) - - - - - 84a23093 by Ryan Scott at 2020-05-30T10:45:46-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. (cherry picked from commit a0d8e92e9c9b67426aa139d6bc46363d8940f992) - - - - - 3e31aad8 by Simon Peyton Jones at 2020-05-30T10:46:54-04: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. (cherry picked from commit d7002bccd7d131f8ee9b1ddcd83d62262622294d) - - - - - 3c0e6d70 by Simon Peyton Jones at 2020-05-30T10:47:03-04:00 Improve pretty-printing for TyConBinders In particular, show their kinds. (cherry picked from commit fa37940cd72f82abc460f5c0a5de64dd75cee6ae) - - - - - 99e643ba by Simon Peyton Jones at 2020-05-30T11:10:33-04: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. (cherry picked from commit b9605396f1f1560aea94792646b835cadcb49f45) - - - - - 30 changed files: - compiler/GHC/Hs/Decls.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/prelude/PrelInfo.hs - compiler/prelude/PrelNames.hs - compiler/prelude/TysWiredIn.hs - compiler/typecheck/TcHsSyn.hs - compiler/typecheck/TcHsType.hs - compiler/typecheck/TcInstDcls.hs - compiler/typecheck/TcMType.hs - compiler/typecheck/TcTyClsDecls.hs - compiler/types/TyCon.hs - + libraries/ghc-compact/tests/T16992.hs - + libraries/ghc-compact/tests/T16992.stdout - libraries/ghc-compact/tests/all.T - rts/sm/CNF.c - + testsuite/tests/deriving/should_compile/T18055.hs - testsuite/tests/deriving/should_compile/all.T - testsuite/tests/partial-sigs/should_compile/ExprSigLocal.stderr - testsuite/tests/partial-sigs/should_compile/SplicesUsed.stderr - testsuite/tests/partial-sigs/should_compile/T10519.stderr - testsuite/tests/partial-sigs/should_compile/T12844.stderr - testsuite/tests/partial-sigs/should_compile/T13482.stderr - testsuite/tests/partial-sigs/should_compile/T14217.stderr - testsuite/tests/partial-sigs/should_compile/T14715.stderr - testsuite/tests/partial-sigs/should_compile/T15039a.stderr - testsuite/tests/partial-sigs/should_compile/T15039c.stderr - testsuite/tests/partial-sigs/should_compile/T16728.stderr - testsuite/tests/partial-sigs/should_compile/T16728b.stderr - testsuite/tests/partial-sigs/should_fail/ExtraConstraintsWildcardNotEnabled.stderr - testsuite/tests/partial-sigs/should_fail/InstantiatedNamedWildcardsInConstraints.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8bb8ef56f69e89eacfd94f3b7e870d7ccc8dee7f...99e643baf247fa5276ab4199cfd5a18e4c1d76d2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/8bb8ef56f69e89eacfd94f3b7e870d7ccc8dee7f...99e643baf247fa5276ab4199cfd5a18e4c1d76d2 You're receiving 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 30 15:39:05 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 30 May 2020 11:39:05 -0400 Subject: [Git][ghc/ghc][wip/backports] 9 commits: llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 Message-ID: <5ed27e191a877_6e26ae31e0829245bc@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/backports at Glasgow Haskell Compiler / GHC Commits: 3e1c9f61 by Tuan Le at 2020-05-30T11:38:56-04:00 llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 (cherry picked from commit 0004ccb885e534c386ceae21580fc59ec7ad0ede) - - - - - f01ab28d by Ben Gamari at 2020-05-30T11:38:56-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 (cherry picked from commit cf4f1e2f78840d25b132de55bce1e02256334ace) - - - - - c753669d by Ryan Scott at 2020-05-30T11:38:56-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. (cherry picked from commit 518a63d4d7e31e49a81ad66d5e5ccb1f790f6de9) - - - - - 03b17302 by Ryan Scott at 2020-05-30T11:38:56-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. (cherry picked from commit cd8409c26d4370bf2cdcd76801974e99a9adf7b0) - - - - - afa455ec by Sebastian Graf at 2020-05-30T11:38:56-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. (cherry picked from commit ed58d4fdcbc7b4fa8fbdf3d638a8d53c444ef4f2) - - - - - a2fddfb8 by Ryan Scott at 2020-05-30T11:38:56-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. (cherry picked from commit a0d8e92e9c9b67426aa139d6bc46363d8940f992) - - - - - c72907f8 by Simon Peyton Jones at 2020-05-30T11:38:56-04: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. (cherry picked from commit d7002bccd7d131f8ee9b1ddcd83d62262622294d) - - - - - 4ab0db36 by Simon Peyton Jones at 2020-05-30T11:38:56-04:00 Improve pretty-printing for TyConBinders In particular, show their kinds. (cherry picked from commit fa37940cd72f82abc460f5c0a5de64dd75cee6ae) - - - - - ec0968e3 by Simon Peyton Jones at 2020-05-30T11:38:56-04: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. (cherry picked from commit b9605396f1f1560aea94792646b835cadcb49f45) - - - - - 30 changed files: - compiler/GHC/Hs/Decls.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/cmm/Cmm.hs - compiler/cmm/PprC.hs - compiler/llvmGen/LlvmCodeGen/Data.hs - compiler/prelude/PrelInfo.hs - compiler/prelude/PrelNames.hs - compiler/prelude/TysWiredIn.hs - compiler/typecheck/TcHsSyn.hs - compiler/typecheck/TcHsType.hs - compiler/typecheck/TcInstDcls.hs - compiler/typecheck/TcMType.hs - compiler/typecheck/TcTyClsDecls.hs - compiler/types/TyCon.hs - + libraries/ghc-compact/tests/T16992.hs - + libraries/ghc-compact/tests/T16992.stdout - libraries/ghc-compact/tests/all.T - rts/sm/CNF.c - + testsuite/tests/codeGen/should_gen_asm/T18137.asm - + testsuite/tests/codeGen/should_gen_asm/T18137.hs - testsuite/tests/codeGen/should_gen_asm/all.T - + testsuite/tests/deriving/should_compile/T18055.hs - testsuite/tests/deriving/should_compile/all.T - testsuite/tests/partial-sigs/should_compile/ExprSigLocal.stderr - testsuite/tests/partial-sigs/should_compile/SplicesUsed.stderr - testsuite/tests/partial-sigs/should_compile/T10519.stderr - testsuite/tests/partial-sigs/should_compile/T12844.stderr - testsuite/tests/partial-sigs/should_compile/T13482.stderr - testsuite/tests/partial-sigs/should_compile/T14217.stderr - testsuite/tests/partial-sigs/should_compile/T14715.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/99e643baf247fa5276ab4199cfd5a18e4c1d76d2...ec0968e3cd6757501c6b79bdec62b16a5bafc833 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/99e643baf247fa5276ab4199cfd5a18e4c1d76d2...ec0968e3cd6757501c6b79bdec62b16a5bafc833 You're receiving 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 30 15:46:35 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 30 May 2020 11:46:35 -0400 Subject: [Git][ghc/ghc][wip/T18234] 32 commits: GHC.Core.Unfold: Refactor traceInline Message-ID: <5ed27fdbe4a36_6e2611a0b9e42928788@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18234 at Glasgow Haskell Compiler / GHC Commits: 28deee28 by Ben Gamari at 2020-05-28T16:23:21-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 - - - - - 1f393e1e by Ben Gamari at 2020-05-28T16:23:21-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 haddock.Cabal haddock.base haddock.compiler - - - - - 5f621a78 by Vladislav Zavialov at 2020-05-28T16:23:58-04:00 Add Semigroup/Monoid for Q (#18123) - - - - - dc5f004c by Xavier Denis at 2020-05-28T16:24:37-04:00 Fix #18071 Run the core linter on candidate instances to ensure they are well-kinded. Better handle quantified constraints by using a CtWanted to avoid having unsolved constraints thrown away at the end by the solver. - - - - - 10e6982c by Sebastian Graf at 2020-05-28T16:25:14-04:00 FloatOut: Only eta-expand dead-end RHS if arity will increase (#18231) Otherwise we risk turning trivial RHS into non-trivial RHS, introducing unnecessary bindings in the next Simplifier run, resulting in more churn. Fixes #18231. - - - - - 08dab5f7 by Sebastian Graf at 2020-05-28T16:25:14-04:00 DmdAnal: Recognise precise exceptions from case alternatives (#18086) Consider ```hs m :: IO () m = do putStrLn "foo" error "bar" ``` `m` (from #18086) always throws a (precise or imprecise) exception or diverges. Yet demand analysis infers `<L,A>` as demand signature instead of `<L,A>x` for it. That's because the demand analyser sees `putStrLn` occuring in a case scrutinee and decides that it has to `deferAfterPreciseException`, because `putStrLn` throws a precise exception on some control flow paths. This will mask the `botDiv` `Divergence`of the single case alt containing `error` to `topDiv`. Since `putStrLn` has `topDiv` itself, the final `Divergence` is `topDiv`. This is easily fixed: `deferAfterPreciseException` works by `lub`ing with the demand type of a virtual case branch denoting the precise exceptional control flow. We used `nopDmdType` before, but we can be more precise and use `exnDmdType`, which is `nopDmdType` with `exnDiv`. Now the `Divergence` from the case alt will degrade `botDiv` to `exnDiv` instead of `topDiv`, which combines with the result from the scrutinee to `exnDiv`, and all is well. Fixes #18086. - - - - - aef95f11 by Ben Gamari at 2020-05-28T16:25:53-04:00 Ticky-ticky: Record DataCon name in ticker name This makes it significantly easier to spot the nature of allocations regressions and comes at a reasonably low cost. - - - - - 8f021b8c by Ben Gamari at 2020-05-28T16:26:34-04:00 hadrian: Don't track GHC's verbosity argument Teach hadrian to ignore GHC's -v argument in its recompilation check, thus fixing #18131. - - - - - 13d9380b by Ben Gamari at 2020-05-28T16:27:20-04:00 Rip out CmmStackInfo(updfr_space) As noted in #18232, this field is currently completely unused and moreover doesn't have a clear meaning. - - - - - f10d11fa by Andreas Klebinger at 2020-05-29T01:38:42-04: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. - - - - - bbeb2389 by Ben Gamari at 2020-05-29T01:39:19-04:00 CoreToStg: Add Outputable ArgInfo instance - - - - - 0e3361ca by Simon Peyton Jones at 2020-05-29T01:39:19-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. - - - - - c49f7df0 by Simon Peyton Jones at 2020-05-29T01:39:19-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. - - - - - 46720997 by Ben Gamari at 2020-05-29T01:39:19-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 Metric Decrease: ManyConstructors Co-Authored-By: Simon Peyton-Jone <simonpj at microsoft.com> - - - - - 277c2f26 by Ben Gamari at 2020-05-29T01:39:55-04:00 Eta expand un-saturated primops Now since we no longer try to predict CAFfyness we have no need for the solution to #16846. Eta expanding unsaturated primop applications is conceptually simpler, especially in the presence of levity polymorphism. This essentially reverts cac8dc9f51e31e4c0a6cd9bc302f7e1bc7c03beb, as suggested in #18079. Closes #18079. - - - - - f44d7ae0 by Simon Jakobi at 2020-05-29T01:40:34-04:00 base: Scrap deprecation plan for Data.Monoid.{First,Last} See the discussion on the libraries mailing list for context: https://mail.haskell.org/pipermail/libraries/2020-April/030357.html - - - - - 8b494895 by Jeremy Schlatter at 2020-05-29T01:41:12-04:00 Fix typo in documentation - - - - - 998450f4 by Gleb Popov at 2020-05-29T01:41:53-04:00 Always define USE_PTHREAD_FOR_ITIMER for FreeBSD. - - - - - f9a513e0 by Alp Mestanogullari at 2020-05-29T01:42:36-04:00 hadrian: introduce 'install' target Its logic is very simple. It `need`s the `binary-dist-dir` target and runs suitable `configure` and `make install` commands for the user. A new `--prefix` command line argument is introduced to specify where GHC should be installed. - - - - - 67738db1 by Travis Whitaker at 2020-05-29T13:34:48-04:00 Build a threaded stage 1 if the bootstrapping GHC supports it. - - - - - aac19e6c by Peter Trommler at 2020-05-29T13:35:24-04:00 PPC NCG: No per-symbol .section ".toc" directives All position independent symbols are collected during code generation and emitted in one go. Prepending each symbol with a .section ".toc" directive is redundant. This patch drops the per-symbol directives leading to smaller assembler files. Fixes #18250 - - - - - 4413828b by Ben Gamari at 2020-05-30T06:07:31-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. - - - - - 1449435c by Ben Gamari at 2020-05-30T06:07:31-04:00 users-guide: Note change in getNumProcessors in users guide - - - - - 3d960169 by Ben Gamari at 2020-05-30T06:07:31-04:00 rts: Drop compatibility shims for Windows Vista We can now assume that the thread and processor group interfaces are available. - - - - - 7f8f948c by Peter Trommler at 2020-05-30T06:08:07-04:00 PPC NCG: Fix .size directive on powerpc64 ELF v1 Thanks to Sergei Trofimovich for pointing out the issue. Fixes #18237 - - - - - 7c555b05 by Andreas Klebinger at 2020-05-30T06:08:43-04:00 Optimize GHC.Utils.Monad. Many functions in this module are recursive and as such are marked loop breakers. Which means they are unlikely to get an unfolding. This is *bad*. We always want to specialize them to specific Monads. Which requires a visible unfolding at the use site. I rewrote the recursive ones from: foo f x = ... foo x' ... to foo f x = go x where go x = ... As well as giving some pragmas to make all of them available for specialization. The end result is a reduction of allocations of about -1.4% for nofib/spectral/simple/Main.hs when compiled with `-O`. ------------------------- Metric Decrease: T12425 T14683 T5631 T9233 T9675 T9961 WWRec ------------------------- - - - - - 8b1cb5df by Ben Gamari at 2020-05-30T06:09:20-04:00 Windows: Bump Windows toolchain to 0.2 - - - - - 6947231a by Zubin Duggal at 2020-05-30T06:10:02-04:00 Simplify contexts in GHC.Iface.Ext.Ast - - - - - d23dafab by Sylvain Henry at 2020-05-30T11:46:08-04:00 Hadrian: fix binary-dist target for cross-compilation - - - - - 9ea96091 by Ben Gamari at 2020-05-30T11:46:08-04:00 gitlab-ci: Add usage message to ci.sh - - - - - d5e7fd0b by Ben Gamari at 2020-05-30T11:46:08-04:00 gitlab-ci: Make names more consistent - - - - - d58b84f1 by Ben Gamari at 2020-05-30T11:46:29-04:00 gitlab-ci: Introduce a nightly cross-compilation job This adds a job to test cross-compilation from x86-64 to AArch64 with Hadrian. Fixes #18234. - - - - - 30 changed files: - .gitlab-ci.yml - .gitlab/ci.sh - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/LayoutStack.hs - compiler/GHC/Cmm/Ppr.hs - compiler/GHC/Cmm/ProcPoint.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Monad.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/StgToCmm/Bind.hs - compiler/GHC/StgToCmm/Monad.hs - compiler/GHC/StgToCmm/Ticky.hs - compiler/GHC/Tc/Solver/Flatten.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/21cb2c3df1cb5857aebd0f5ba69c7f0e19eb1419...d58b84f1f59dfbfcf0f076eab9f1aa054fbe10f6 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/21cb2c3df1cb5857aebd0f5ba69c7f0e19eb1419...d58b84f1f59dfbfcf0f076eab9f1aa054fbe10f6 You're receiving 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 30 15:50:28 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 30 May 2020 11:50:28 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 20 commits: Cleanup OVERWRITING_CLOSURE logic Message-ID: <5ed280c4413d4_6e2611a0b9e429383d0@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: f178557d by Daniel Gröber at 2020-05-30T11:49:40-04:00 Cleanup OVERWRITING_CLOSURE logic The code is just more confusing than it needs to be. We don't need to mix the threaded check with the ldv profiling check since ldv's init already checks for this. Hence they can be two separate checks. Taking the sanity checking into account is also cleaner via DebugFlags.sanity. No need for checking the DEBUG define. The ZERO_SLOP_FOR_LDV_PROF and ZERO_SLOP_FOR_SANITY_CHECK definitions the old code had also make things a lot more opaque IMO so I removed those. - - - - - c5c5ed2c by Daniel Gröber at 2020-05-30T11:49:40-04:00 Fix OVERWRITING_CLOSURE assuming closures are not inherently used The new ASSERT in LDV_recordDead() was being tripped up by MVars when removeFromMVarBlockedQueue() calls OVERWRITING_CLOSURE() via OVERWRITE_INFO(). - - - - - 9ca9bb94 by Daniel Gröber at 2020-05-30T11:49:40-04:00 Always zero shrunk mutable array slop when profiling When shrinking arrays in the profiling way we currently don't always zero the leftover slop. This means we can't traverse such closures in the heap profiler. The old Note [zeroing slop] and #8402 have some rationale for why this is so but I belive the reasoning doesn't apply to mutable closures. There users already have to ensure multiple threads don't step on each other's toes so zeroing should be safe. - - - - - 8682beae by Ben Gamari at 2020-05-30T11:49:40-04:00 testsuite: Add test for #18151 - - - - - 34db6a0b by Ben Gamari at 2020-05-30T11:49:40-04:00 testsuite: Add test for desugaring of PostfixOperators - - - - - 2f054f65 by Ben Gamari at 2020-05-30T11:49:40-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. - - - - - fb21b586 by Kirill Elagin at 2020-05-30T11:49:50-04:00 Winferred-safe-imports: Do not exit with error Currently, when -Winferred-safe-imports is enabled, even when it is not turned into an error, the compiler will still exit with exit code 1 if this warning was emitted. Make sure it is really treated as a warning. - - - - - 2b915b25 by Ben Gamari at 2020-05-30T11:49:51-04:00 nonmoving: Optimise log2_ceil - - - - - cbd16b60 by Bodigrim at 2020-05-30T11:49:51-04:00 Clarify description of fromListN - - - - - 7fa0a9d8 by Bodigrim at 2020-05-30T11:49:51-04:00 Apply suggestion to libraries/base/GHC/Exts.hs - - - - - 86428f6b by Jeremy Schlatter at 2020-05-30T11:49:54-04:00 Fix wording in documentation The duplicate "orphan instance" phrase here doesn't make sense, and was probably an accident. - - - - - 0ec612ed by Takenobu Tani at 2020-05-30T11:50:04-04:00 configure: Modify aclocal.m4 according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * Rename: * compiler/GHC/Parser.hs <= compiler/parser/Parser.hs * compiler/GHC/Parser/Lexer.hs <= compiler/Parser/Lexer.hs * Add: * compiler/GHC/Cmm/Lexer.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular - - - - - 38b188ab by Ben Gamari at 2020-05-30T11:50:04-04:00 testsuite: Don't fail if we can't unlink __symlink_test Afterall, it's possible we were unable to create it due to lack of symlink permission. - - - - - b36dbe16 by Ben Gamari at 2020-05-30T11:50:04-04:00 testsuite: Refactor ghostscript detection Tamar reported that he saw crashes due to unhandled exceptions. - - - - - b6de960b by Ben Gamari at 2020-05-30T11:50:04-04:00 testsuite/perf_notes: Fix ill-typed assignments - - - - - 3e3de1af by Ben Gamari at 2020-05-30T11:50:04-04:00 testsuite/testutil: Fix bytes/str mismatch - - - - - f117ffc5 by Ben Gamari at 2020-05-30T11:50:04-04:00 testsuite: Work around spurious mypy failure - - - - - 9b3e71bd by Takenobu Tani at 2020-05-30T11:50:07-04:00 Clean up file paths for new module hierarchy This updates comments only. This patch replaces file references according to new module hierarchy. See also: * https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular * https://gitlab.haskell.org/ghc/ghc/issues/13009 - - - - - 56f5309b by Takenobu Tani at 2020-05-30T11:50:07-04:00 Modify file paths to module paths for new module hierarchy This updates comments only. This patch replaces module references according to new module hierarchy [1][2]. For files under the `compiler/` directory, I replace them as module paths instead of file paths. For instance, `GHC.Unit.State` instead of `compiler/GHC/Unit/State.hs` [3]. For current and future haddock's markup, this patch encloses the module name with "" [4]. [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: https://gitlab.haskell.org/ghc/ghc/issues/13009 [3]: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/3375#note_276613 [4]: https://haskell-haddock.readthedocs.io/en/latest/markup.html#linking-to-modules - - - - - 83e3ffc7 by Sylvain Henry at 2020-05-30T11:50:18-04:00 Hadrian: fix binary-dist target for cross-compilation - - - - - 30 changed files: - aclocal.m4 - compiler/GHC.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/SPARC/Base.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/HsToCore/PmCheck/Types.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Parser/Lexer.x - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToCmm/Utils.hs - compiler/GHC/SysTools/ExtraObj.hs - compiler/GHC/Tc/Deriv.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Utils/Outputable.hs - compiler/GHC/Utils/Ppr.hs - compiler/ghc.mk - docs/users_guide/separate_compilation.rst - hadrian/src/Rules/BinaryDist.hs - hadrian/src/Way.hs - includes/Cmm.h The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ae9f06bac738415f38080b759690229ea802e328...83e3ffc7f732060a42d69d47648415e563f04e5e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ae9f06bac738415f38080b759690229ea802e328...83e3ffc7f732060a42d69d47648415e563f04e5e You're receiving 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 30 16:18:26 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 30 May 2020 12:18:26 -0400 Subject: [Git][ghc/ghc][wip/backports] 6 commits: Create di_scoped_tvs for associated data family instances properly Message-ID: <5ed28752a8d35_6e263f9ed4d7839c296892f@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/backports at Glasgow Haskell Compiler / GHC Commits: 7795b53b by Ryan Scott at 2020-05-30T16:17:46+00: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. (cherry picked from commit cd8409c26d4370bf2cdcd76801974e99a9adf7b0) - - - - - 2923cfd6 by Sebastian Graf at 2020-05-30T16:17:46+00: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. (cherry picked from commit ed58d4fdcbc7b4fa8fbdf3d638a8d53c444ef4f2) - - - - - 2c54f842 by Ryan Scott at 2020-05-30T16:17:46+00: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. (cherry picked from commit a0d8e92e9c9b67426aa139d6bc46363d8940f992) - - - - - 0071044d by Simon Peyton Jones at 2020-05-30T16:17:46+00: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. (cherry picked from commit d7002bccd7d131f8ee9b1ddcd83d62262622294d) - - - - - fb58c8ef by Simon Peyton Jones at 2020-05-30T16:17:47+00:00 Improve pretty-printing for TyConBinders In particular, show their kinds. (cherry picked from commit fa37940cd72f82abc460f5c0a5de64dd75cee6ae) - - - - - 0e49e13e by Simon Peyton Jones at 2020-05-30T16:17:47+00: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. (cherry picked from commit b9605396f1f1560aea94792646b835cadcb49f45) - - - - - 30 changed files: - compiler/GHC/Hs/Decls.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/typecheck/TcHsSyn.hs - compiler/typecheck/TcHsType.hs - compiler/typecheck/TcInstDcls.hs - compiler/typecheck/TcMType.hs - compiler/typecheck/TcTyClsDecls.hs - compiler/types/TyCon.hs - + testsuite/tests/deriving/should_compile/T18055.hs - testsuite/tests/deriving/should_compile/all.T - testsuite/tests/partial-sigs/should_compile/ExprSigLocal.stderr - testsuite/tests/partial-sigs/should_compile/SplicesUsed.stderr - testsuite/tests/partial-sigs/should_compile/T10519.stderr - testsuite/tests/partial-sigs/should_compile/T12844.stderr - testsuite/tests/partial-sigs/should_compile/T13482.stderr - testsuite/tests/partial-sigs/should_compile/T14217.stderr - testsuite/tests/partial-sigs/should_compile/T14715.stderr - testsuite/tests/partial-sigs/should_compile/T15039a.stderr - testsuite/tests/partial-sigs/should_compile/T15039c.stderr - testsuite/tests/partial-sigs/should_compile/T16728.stderr - testsuite/tests/partial-sigs/should_compile/T16728b.stderr - testsuite/tests/partial-sigs/should_fail/ExtraConstraintsWildcardNotEnabled.stderr - testsuite/tests/partial-sigs/should_fail/InstantiatedNamedWildcardsInConstraints.stderr - testsuite/tests/partial-sigs/should_fail/NamedWildcardExplicitForall.stderr - testsuite/tests/partial-sigs/should_fail/T10615.stderr - + testsuite/tests/pmcheck/should_compile/T17977.hs - + testsuite/tests/pmcheck/should_compile/T17977b.hs - + testsuite/tests/pmcheck/should_compile/T17977b.stderr - testsuite/tests/pmcheck/should_compile/all.T - testsuite/tests/polykinds/T11203.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ec0968e3cd6757501c6b79bdec62b16a5bafc833...0e49e13e5d0d5cbc49710226bf21a6fe0d923084 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ec0968e3cd6757501c6b79bdec62b16a5bafc833...0e49e13e5d0d5cbc49710226bf21a6fe0d923084 You're receiving 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 30 16:51:37 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 30 May 2020 12:51:37 -0400 Subject: [Git][ghc/ghc][wip/perform-blocking-gc] rts: Introduce performBlockingMajorGC Message-ID: <5ed28f194198_6e263f9ed4d7839c29693a3@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/perform-blocking-gc at Glasgow Haskell Compiler / GHC Commits: da04a864 by Ben Gamari at 2020-05-30T12:51:29-04:00 rts: Introduce performBlockingMajorGC - - - - - 7 changed files: - libraries/base/System/Mem.hs - rts/RtsSymbols.c - rts/Schedule.c - rts/sm/GC.c - rts/sm/GC.h - rts/sm/NonMoving.c - rts/sm/NonMoving.h Changes: ===================================== libraries/base/System/Mem.hs ===================================== @@ -3,7 +3,7 @@ -- Module : System.Mem -- Copyright : (c) The University of Glasgow 2001 -- License : BSD-style (see the file libraries/base/LICENSE) --- +-- -- Maintainer : libraries at haskell.org -- Stability : provisional -- Portability : portable @@ -19,6 +19,7 @@ module System.Mem ( -- * Garbage collection performGC + , performBlockingMajorGC , performMajorGC , performMinorGC @@ -35,6 +36,12 @@ import GHC.Conc.Sync performGC :: IO () performGC = performMajorGC +-- | Triggers an immediate major garbage collection, ensuring that collection +-- finishes before returning. +-- +-- @since 4.15.0.0 +foreign import ccall "performBlockingMajorGC" performBlockingMajorGC :: IO () + -- | Triggers an immediate major garbage collection. -- -- @since 4.7.0.0 ===================================== rts/RtsSymbols.c ===================================== @@ -717,13 +717,14 @@ SymI_HasProto(stg_isMutableByteArrayPinnedzh) \ SymI_HasProto(stg_shrinkMutableByteArrayzh) \ SymI_HasProto(stg_resizzeMutableByteArrayzh) \ - SymI_HasProto(stg_shrinkSmallMutableArrayzh) \ + SymI_HasProto(stg_shrinkSmallMutableArrayzh) \ SymI_HasProto(newSpark) \ - SymI_HasProto(updateRemembSetPushThunk) \ - SymI_HasProto(updateRemembSetPushThunk_) \ - SymI_HasProto(updateRemembSetPushClosure_) \ + SymI_HasProto(updateRemembSetPushThunk) \ + SymI_HasProto(updateRemembSetPushThunk_) \ + SymI_HasProto(updateRemembSetPushClosure_) \ SymI_HasProto(performGC) \ SymI_HasProto(performMajorGC) \ + SymI_HasProto(performBlockingMajorGC) \ SymI_HasProto(prog_argc) \ SymI_HasProto(prog_argv) \ SymI_HasProto(stg_putMVarzh) \ ===================================== rts/Schedule.c ===================================== @@ -165,7 +165,9 @@ static bool scheduleHandleThreadFinished( Capability *cap, Task *task, StgTSO *t ); static bool scheduleNeedHeapProfile(bool ready_to_gc); static void scheduleDoGC( Capability **pcap, Task *task, - bool force_major, bool deadlock_detect ); + bool force_major, + bool deadlock_detect, + bool force_nonconcurrent ); static void deleteThread (StgTSO *tso); static void deleteAllThreads (void); @@ -265,7 +267,7 @@ schedule (Capability *initialCapability, Task *task) case SCHED_INTERRUPTING: debugTrace(DEBUG_sched, "SCHED_INTERRUPTING"); /* scheduleDoGC() deletes all the threads */ - scheduleDoGC(&cap,task,true,false); + scheduleDoGC(&cap, task, true, false, false); // after scheduleDoGC(), we must be shutting down. Either some // other Capability did the final GC, or we did it above, @@ -562,7 +564,7 @@ run_thread: } if (ready_to_gc || scheduleNeedHeapProfile(ready_to_gc)) { - scheduleDoGC(&cap,task,false,false); + scheduleDoGC(&cap, task, false, false, false); } } /* end of while() */ } @@ -936,7 +938,10 @@ scheduleDetectDeadlock (Capability **pcap, Task *task) // they are unreachable and will therefore be sent an // exception. Any threads thus released will be immediately // runnable. - scheduleDoGC (pcap, task, true/*force major GC*/, true/*deadlock detection*/); + scheduleDoGC (pcap, task, + true/*force major GC*/, + true/*deadlock detection*/, + false/*force_nonconcurrent*/); cap = *pcap; // when force_major == true. scheduleDoGC sets // recent_activity to ACTIVITY_DONE_GC and turns off the timer @@ -1557,7 +1562,7 @@ void releaseAllCapabilities(uint32_t n, Capability *keep_cap, Task *task) // behind deadlock_detect argument. static void scheduleDoGC (Capability **pcap, Task *task USED_IF_THREADS, - bool force_major, bool deadlock_detect) + bool force_major, bool deadlock_detect, bool force_nonconcurrent) { Capability *cap = *pcap; bool heap_census; @@ -1850,9 +1855,11 @@ delete_threads_and_gc: // emerge they don't immediately re-enter the GC. pending_sync = 0; signalCondition(&sync_finished_cond); - GarbageCollect(collect_gen, heap_census, deadlock_detect, gc_type, cap, idle_cap); + GarbageCollect(collect_gen, heap_census, deadlock_detect, + force_nonconcurrent, gc_type, cap, idle_cap); #else - GarbageCollect(collect_gen, heap_census, deadlock_detect, 0, cap, NULL); + GarbageCollect(collect_gen, heap_census, deadlock_detect, + force_nonconcurrent, 0, cap, NULL); #endif // If we're shutting down, don't leave any idle GC work to do. @@ -2720,7 +2727,7 @@ exitScheduler (bool wait_foreign USED_IF_THREADS) nonmovingStop(); Capability *cap = task->cap; waitForCapability(&cap,task); - scheduleDoGC(&cap,task,true,false); + scheduleDoGC(&cap,task,true,false,false); ASSERT(task->incall->tso == NULL); releaseCapability(cap); } @@ -2775,7 +2782,7 @@ void markScheduler (evac_fn evac USED_IF_NOT_THREADS, -------------------------------------------------------------------------- */ static void -performGC_(bool force_major) +performGC_(bool force_major, bool force_nonconcurrent) { Task *task; Capability *cap = NULL; @@ -2788,7 +2795,7 @@ performGC_(bool force_major) // TODO: do we need to traceTask*() here? waitForCapability(&cap,task); - scheduleDoGC(&cap,task,force_major,false); + scheduleDoGC(&cap, task, force_major, false, force_nonconcurrent); releaseCapability(cap); boundTaskExiting(task); } @@ -2796,13 +2803,19 @@ performGC_(bool force_major) void performGC(void) { - performGC_(false); + performGC_(false, false); } void performMajorGC(void) { - performGC_(true); + performGC_(true, false); +} + +void +performBlockingMajorGC(void) +{ + performGC_(true, true); } /* --------------------------------------------------------------------------- ===================================== rts/sm/GC.c ===================================== @@ -196,6 +196,7 @@ void GarbageCollect (uint32_t collect_gen, const bool do_heap_census, const bool deadlock_detect, + const bool force_nonconcurrent, uint32_t gc_type USED_IF_THREADS, Capability *cap, bool idle_cap[]) @@ -779,7 +780,7 @@ GarbageCollect (uint32_t collect_gen, // upd_rem_set nonmovingAddUpdRemSetBlocks(&gct->cap->upd_rem_set.queue); #endif - nonmovingCollect(&dead_weak_ptr_list, &resurrected_threads); + nonmovingCollect(&dead_weak_ptr_list, &resurrected_threads, force_nonconcurrent); ACQUIRE_SM_LOCK; } ===================================== rts/sm/GC.h ===================================== @@ -20,6 +20,7 @@ void GarbageCollect (uint32_t collect_gen, bool do_heap_census, bool deadlock_detect, + bool force_nonconcurrent, uint32_t gc_type, Capability *cap, bool idle_cap[]); ===================================== rts/sm/NonMoving.c ===================================== @@ -900,7 +900,9 @@ static void nonmovingMarkWeakPtrList(MarkQueue *mark_queue, StgWeak *dead_weak_p } } -void nonmovingCollect(StgWeak **dead_weaks, StgTSO **resurrected_threads) +void nonmovingCollect(StgWeak **dead_weaks, + StgTSO **resurrected_threads, + bool force_nonmoving) { #if defined(THREADED_RTS) // We can't start a new collection until the old one has finished @@ -979,7 +981,7 @@ void nonmovingCollect(StgWeak **dead_weaks, StgTSO **resurrected_threads) // again for the sync if we let it go, because it'll immediately start doing // a major GC, because that's what we do when exiting scheduler (see // exitScheduler()). - if (sched_state == SCHED_RUNNING) { + if (sched_state == SCHED_RUNNING && !force_nonconcurrent) { concurrent_coll_running = true; nonmoving_write_barrier_enabled = true; debugTrace(DEBUG_nonmoving_gc, "Starting concurrent mark thread"); ===================================== rts/sm/NonMoving.h ===================================== @@ -126,7 +126,8 @@ void nonmovingExit(void); // directly, but in a pause. // void nonmovingCollect(StgWeak **dead_weaks, - StgTSO **resurrected_threads); + StgTSO **resurrected_threads, + bool force_nonmoving); void *nonmovingAllocate(Capability *cap, StgWord sz); void nonmovingAddCapabilities(uint32_t new_n_caps); View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/da04a8647230fa97e84cfc4b319ce097e2b2d734 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/da04a8647230fa97e84cfc4b319ce097e2b2d734 You're receiving 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 30 17:04:36 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 30 May 2020 13:04:36 -0400 Subject: [Git][ghc/ghc][wip/backports] 3 commits: Improve skolemisation Message-ID: <5ed2922469588_6e2681629e0297157@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/backports at Glasgow Haskell Compiler / GHC Commits: 2fab423c by Simon Peyton Jones at 2020-05-30T13:04:13-04: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. (cherry picked from commit d7002bccd7d131f8ee9b1ddcd83d62262622294d) - - - - - 61d29c90 by Simon Peyton Jones at 2020-05-30T13:04:13-04:00 Improve pretty-printing for TyConBinders In particular, show their kinds. (cherry picked from commit fa37940cd72f82abc460f5c0a5de64dd75cee6ae) - - - - - 748925ad by Simon Peyton Jones at 2020-05-30T13:04:30-04: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. (cherry picked from commit b9605396f1f1560aea94792646b835cadcb49f45) - - - - - 30 changed files: - compiler/GHC/Hs/Decls.hs - compiler/typecheck/TcHsSyn.hs - compiler/typecheck/TcHsType.hs - compiler/typecheck/TcInstDcls.hs - compiler/typecheck/TcMType.hs - compiler/typecheck/TcTyClsDecls.hs - compiler/types/TyCon.hs - testsuite/tests/partial-sigs/should_compile/ExprSigLocal.stderr - testsuite/tests/partial-sigs/should_compile/SplicesUsed.stderr - testsuite/tests/partial-sigs/should_compile/T10519.stderr - testsuite/tests/partial-sigs/should_compile/T12844.stderr - testsuite/tests/partial-sigs/should_compile/T13482.stderr - testsuite/tests/partial-sigs/should_compile/T14217.stderr - testsuite/tests/partial-sigs/should_compile/T14715.stderr - testsuite/tests/partial-sigs/should_compile/T15039a.stderr - testsuite/tests/partial-sigs/should_compile/T15039c.stderr - testsuite/tests/partial-sigs/should_compile/T16728.stderr - testsuite/tests/partial-sigs/should_compile/T16728b.stderr - testsuite/tests/partial-sigs/should_fail/ExtraConstraintsWildcardNotEnabled.stderr - testsuite/tests/partial-sigs/should_fail/InstantiatedNamedWildcardsInConstraints.stderr - testsuite/tests/partial-sigs/should_fail/NamedWildcardExplicitForall.stderr - testsuite/tests/partial-sigs/should_fail/T10615.stderr - testsuite/tests/polykinds/T11203.stderr - testsuite/tests/polykinds/T11821a.stderr - testsuite/tests/typecheck/should_compile/Makefile - + testsuite/tests/typecheck/should_compile/T17566.hs - + testsuite/tests/typecheck/should_compile/T17566a.hs - testsuite/tests/typecheck/should_compile/all.T - + testsuite/tests/typecheck/should_fail/T17566b.hs - + testsuite/tests/typecheck/should_fail/T17566b.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0e49e13e5d0d5cbc49710226bf21a6fe0d923084...748925ad536bd939cdd71c73f4fe9122b56647e8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0e49e13e5d0d5cbc49710226bf21a6fe0d923084...748925ad536bd939cdd71c73f4fe9122b56647e8 You're receiving 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 30 17:21:10 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 30 May 2020 13:21:10 -0400 Subject: [Git][ghc/ghc][wip/backports] testsuite: Accept output on ghc-8.10 Message-ID: <5ed29606b7148_6e263f9ed4d7839c2980768@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/backports at Glasgow Haskell Compiler / GHC Commits: 46e6f291 by Ben Gamari at 2020-05-30T17:20:28+00:00 testsuite: Accept output on ghc-8.10 It's not entirely clear which of the above patches introduced these differences, but they all look reasonable. - - - - - 7 changed files: - testsuite/tests/dependent/should_fail/SelfDep.stderr - testsuite/tests/dependent/should_fail/T16344.stderr - testsuite/tests/ghci/T18060/T18060.stdout - testsuite/tests/partial-sigs/should_compile/T15039b.stderr - testsuite/tests/partial-sigs/should_compile/T15039d.stderr - testsuite/tests/polykinds/PolyKinds06.stderr - testsuite/tests/typecheck/should_fail/T7892.stderr Changes: ===================================== testsuite/tests/dependent/should_fail/SelfDep.stderr ===================================== @@ -3,4 +3,3 @@ SelfDep.hs:5:11: error: • Type constructor ‘T’ cannot be used here (it is defined and used in the same recursive group) • In the kind ‘T -> *’ - In the data type declaration for ‘T’ ===================================== testsuite/tests/dependent/should_fail/T16344.stderr ===================================== @@ -4,3 +4,7 @@ T16344.hs:7:46: error: • In the second argument of ‘T’, namely ‘Int’ In the type ‘(T Type Int Bool)’ In the definition of data constructor ‘MkT’ + NB: Type ‘T’ was inferred to use visible dependent quantification. + Most types with visible dependent quantification are + polymorphically recursive and need a standalone kind + signature. Perhaps supply one, with StandaloneKindSignatures. ===================================== testsuite/tests/ghci/T18060/T18060.stdout ===================================== @@ -7,6 +7,3 @@ instance Functor ((->) r) -- Defined in ‘GHC.Base’ instance Monad ((->) r) -- Defined in ‘GHC.Base’ instance Monoid b => Monoid (a -> b) -- Defined in ‘GHC.Base’ instance Semigroup b => Semigroup (a -> b) -- Defined in ‘GHC.Base’ -type (~) :: forall k. k -> k -> Constraint -class (a ~ b) => (~) a b - -- Defined in ‘GHC.Types’ ===================================== testsuite/tests/partial-sigs/should_compile/T15039b.stderr ===================================== @@ -52,6 +52,6 @@ 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 - at T15039b.hs:36:1-14 + at T15039b.hs:35:1-44 • In the type signature: ex7 :: _ => Coercion (a :: Type) (b :: Type) ===================================== testsuite/tests/partial-sigs/should_compile/T15039d.stderr ===================================== @@ -53,6 +53,6 @@ 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 - at T15039d.hs:36:1-14 + at T15039d.hs:35:1-44 • In the type signature: ex7 :: _ => Coercion (a :: Type) (b :: Type) ===================================== testsuite/tests/polykinds/PolyKinds06.stderr ===================================== @@ -3,4 +3,3 @@ PolyKinds06.hs:9:11: error: • Type constructor ‘A’ cannot be used here (it is defined and used in the same recursive group) • In the kind ‘A -> *’ - In the data type declaration for ‘B’ ===================================== testsuite/tests/typecheck/should_fail/T7892.stderr ===================================== @@ -1,4 +1,2 @@ -T7892.hs:5:4: error: - • Expected kind ‘* -> *’, but ‘f’ has kind ‘*’ - • In the associated type family declaration for ‘F’ +T7892.hs:5:4: error: Expected kind ‘* -> *’, but ‘f’ has kind ‘*’ View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/46e6f291658c968693360c528d5abb956497cad2 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/46e6f291658c968693360c528d5abb956497cad2 You're receiving 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 30 19:24:33 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sat, 30 May 2020 15:24:33 -0400 Subject: [Git][ghc/ghc][wip/backports] Bump win32 toolchain to 0.2 Message-ID: <5ed2b2f19fe72_6e26ae31e0829882a9@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/backports at Glasgow Haskell Compiler / GHC Commits: 254e625f by Ben Gamari at 2020-05-30T19:24:03+00:00 Bump win32 toolchain to 0.2 - - - - - 1 changed file: - mk/get-win32-tarballs.py Changes: ===================================== mk/get-win32-tarballs.py ===================================== @@ -6,7 +6,7 @@ import urllib.request import subprocess import argparse -TARBALL_VERSION = '0.1' +TARBALL_VERSION = '0.2' BASE_URL = "https://downloads.haskell.org/ghc/mingw/{}".format(TARBALL_VERSION) DEST = Path('ghc-tarballs/mingw-w64') ARCHS = ['i686', 'x86_64', 'sources'] View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/254e625fcc89c13cf5d8476859acd7c4e2170f80 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/254e625fcc89c13cf5d8476859acd7c4e2170f80 You're receiving 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 30 23:41:33 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sat, 30 May 2020 19:41:33 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 20 commits: Cleanup OVERWRITING_CLOSURE logic Message-ID: <5ed2ef2dcc384_6e263f9eebb4876830289cf@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 0ac0ca2f by Daniel Gröber at 2020-05-30T19:41:04-04:00 Cleanup OVERWRITING_CLOSURE logic The code is just more confusing than it needs to be. We don't need to mix the threaded check with the ldv profiling check since ldv's init already checks for this. Hence they can be two separate checks. Taking the sanity checking into account is also cleaner via DebugFlags.sanity. No need for checking the DEBUG define. The ZERO_SLOP_FOR_LDV_PROF and ZERO_SLOP_FOR_SANITY_CHECK definitions the old code had also make things a lot more opaque IMO so I removed those. - - - - - cfa5683d by Daniel Gröber at 2020-05-30T19:41:04-04:00 Fix OVERWRITING_CLOSURE assuming closures are not inherently used The new ASSERT in LDV_recordDead() was being tripped up by MVars when removeFromMVarBlockedQueue() calls OVERWRITING_CLOSURE() via OVERWRITE_INFO(). - - - - - 11e85c44 by Daniel Gröber at 2020-05-30T19:41:04-04:00 Always zero shrunk mutable array slop when profiling When shrinking arrays in the profiling way we currently don't always zero the leftover slop. This means we can't traverse such closures in the heap profiler. The old Note [zeroing slop] and #8402 have some rationale for why this is so but I belive the reasoning doesn't apply to mutable closures. There users already have to ensure multiple threads don't step on each other's toes so zeroing should be safe. - - - - - c833b109 by Ben Gamari at 2020-05-30T19:41:04-04:00 testsuite: Add test for #18151 - - - - - ab4aa55d by Ben Gamari at 2020-05-30T19:41:04-04:00 testsuite: Add test for desugaring of PostfixOperators - - - - - e51f4d9b by Ben Gamari at 2020-05-30T19:41:04-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. - - - - - 085cf7af by Kirill Elagin at 2020-05-30T19:41:11-04:00 Winferred-safe-imports: Do not exit with error Currently, when -Winferred-safe-imports is enabled, even when it is not turned into an error, the compiler will still exit with exit code 1 if this warning was emitted. Make sure it is really treated as a warning. - - - - - 655e6901 by Ben Gamari at 2020-05-30T19:41:11-04:00 nonmoving: Optimise log2_ceil - - - - - 047c9295 by Bodigrim at 2020-05-30T19:41:12-04:00 Clarify description of fromListN - - - - - 27f6717c by Bodigrim at 2020-05-30T19:41:12-04:00 Apply suggestion to libraries/base/GHC/Exts.hs - - - - - 00ccd0e0 by Jeremy Schlatter at 2020-05-30T19:41:13-04:00 Fix wording in documentation The duplicate "orphan instance" phrase here doesn't make sense, and was probably an accident. - - - - - 056faa2b by Takenobu Tani at 2020-05-30T19:41:17-04:00 configure: Modify aclocal.m4 according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * Rename: * compiler/GHC/Parser.hs <= compiler/parser/Parser.hs * compiler/GHC/Parser/Lexer.hs <= compiler/Parser/Lexer.hs * Add: * compiler/GHC/Cmm/Lexer.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular - - - - - 9c16617c by Ben Gamari at 2020-05-30T19:41:17-04:00 testsuite: Don't fail if we can't unlink __symlink_test Afterall, it's possible we were unable to create it due to lack of symlink permission. - - - - - 9df72aac by Ben Gamari at 2020-05-30T19:41:17-04:00 testsuite: Refactor ghostscript detection Tamar reported that he saw crashes due to unhandled exceptions. - - - - - cce2a242 by Ben Gamari at 2020-05-30T19:41:17-04:00 testsuite/perf_notes: Fix ill-typed assignments - - - - - 5a411c42 by Ben Gamari at 2020-05-30T19:41:17-04:00 testsuite/testutil: Fix bytes/str mismatch - - - - - 4b1f70ab by Ben Gamari at 2020-05-30T19:41:18-04:00 testsuite: Work around spurious mypy failure - - - - - 264c4e11 by Takenobu Tani at 2020-05-30T19:41:20-04:00 Clean up file paths for new module hierarchy This updates comments only. This patch replaces file references according to new module hierarchy. See also: * https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular * https://gitlab.haskell.org/ghc/ghc/issues/13009 - - - - - 4172cfbc by Takenobu Tani at 2020-05-30T19:41:20-04:00 Modify file paths to module paths for new module hierarchy This updates comments only. This patch replaces module references according to new module hierarchy [1][2]. For files under the `compiler/` directory, I replace them as module paths instead of file paths. For instance, `GHC.Unit.State` instead of `compiler/GHC/Unit/State.hs` [3]. For current and future haddock's markup, this patch encloses the module name with "" [4]. [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: https://gitlab.haskell.org/ghc/ghc/issues/13009 [3]: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/3375#note_276613 [4]: https://haskell-haddock.readthedocs.io/en/latest/markup.html#linking-to-modules - - - - - f7b73d9d by Sylvain Henry at 2020-05-30T19:41:22-04:00 Hadrian: fix binary-dist target for cross-compilation - - - - - 30 changed files: - aclocal.m4 - compiler/GHC.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/SPARC/Base.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/HsToCore/PmCheck/Types.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/Parser/Lexer.x - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToCmm/Utils.hs - compiler/GHC/SysTools/ExtraObj.hs - compiler/GHC/Tc/Deriv.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Utils/Outputable.hs - compiler/GHC/Utils/Ppr.hs - compiler/ghc.mk - docs/users_guide/separate_compilation.rst - hadrian/src/Rules/BinaryDist.hs - hadrian/src/Way.hs - includes/Cmm.h The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/83e3ffc7f732060a42d69d47648415e563f04e5e...f7b73d9d468193584b57308264fced4c8810385a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/83e3ffc7f732060a42d69d47648415e563f04e5e...f7b73d9d468193584b57308264fced4c8810385a You're receiving 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 31 05:10:58 2020 From: gitlab at gitlab.haskell.org (Alex D) Date: Sun, 31 May 2020 01:10:58 -0400 Subject: [Git][ghc/ghc][wip/T17669-test] Add test for #17669 Message-ID: <5ed33c6224949_6e263f9eef6ae988307475f@gitlab.haskell.org.mail> Alex D pushed to branch wip/T17669-test at Glasgow Haskell Compiler / GHC Commits: d143e803 by nineonine at 2020-05-30T22:10:42-07:00 Add test for #17669 - - - - - 3 changed files: - + testsuite/tests/ghci/scripts/T17669.script - + testsuite/tests/ghci/scripts/T17669.stdout - testsuite/tests/ghci/scripts/all.T Changes: ===================================== testsuite/tests/ghci/scripts/T17669.script ===================================== @@ -0,0 +1,7 @@ +:set -v1 +System.IO.writeFile "T17669.hs" "module T17669 where main :: IO ();main = putStrLn \"this\"" +:load T17669.hs +:main +System.IO.writeFile "T17669.hs" "module T17669 where main :: IO ();main = putStrLn \"that\"" +:reload +:main ===================================== testsuite/tests/ghci/scripts/T17669.stdout ===================================== @@ -0,0 +1,6 @@ +[1 of 1] Compiling T17669 ( T17669.hs, T17669.o ) +Ok, one module loaded. +this +[1 of 1] Compiling T17669 ( T17669.hs, T17669.o ) +Ok, one module loaded. +that ===================================== testsuite/tests/ghci/scripts/all.T ===================================== @@ -314,3 +314,4 @@ test('T17384', normal, ghci_script, ['T17384.script']) test('T17403', normal, ghci_script, ['T17403.script']) test('T17431', normal, ghci_script, ['T17431.script']) test('T17549', normal, ghci_script, ['T17549.script']) +test('T17669', [extra_run_opts('-fexternal-interpreter -fobject-code'), expect_broken(17669)], ghci_script, ['T17669.script']) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d143e80303d454babfa2184f5d804a7a61222233 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/d143e80303d454babfa2184f5d804a7a61222233 You're receiving 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 31 06:32:52 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 31 May 2020 02:32:52 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 23 commits: Clean up boot vs non-boot disambiguating types Message-ID: <5ed34f94ee396_6e263f9ee42e45b030979ef@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: da956cef by John Ericson at 2020-05-30T09:39:27-04:00 Clean up boot vs non-boot disambiguating types We often have (ModuleName, Bool) or (Module, Bool) pairs for "extended" module names (without or with a unit id) disambiguating boot and normal modules. We think this is important enough across the compiler that it deserves a new nominal product type. We do this with synnoyms and a functor named with a `Gen` prefix, matching other newly created definitions. It was also requested that we keep custom `IsBoot` / `NotBoot` sum type. So we have it too. This means changing many the many bools to use that instead. - - - - - e20f3442 by Daniel Gröber at 2020-05-31T02:32:06-04:00 Cleanup OVERWRITING_CLOSURE logic The code is just more confusing than it needs to be. We don't need to mix the threaded check with the ldv profiling check since ldv's init already checks for this. Hence they can be two separate checks. Taking the sanity checking into account is also cleaner via DebugFlags.sanity. No need for checking the DEBUG define. The ZERO_SLOP_FOR_LDV_PROF and ZERO_SLOP_FOR_SANITY_CHECK definitions the old code had also make things a lot more opaque IMO so I removed those. - - - - - 71811815 by Daniel Gröber at 2020-05-31T02:32:06-04:00 Fix OVERWRITING_CLOSURE assuming closures are not inherently used The new ASSERT in LDV_recordDead() was being tripped up by MVars when removeFromMVarBlockedQueue() calls OVERWRITING_CLOSURE() via OVERWRITE_INFO(). - - - - - c982036d by Daniel Gröber at 2020-05-31T02:32:06-04:00 Always zero shrunk mutable array slop when profiling When shrinking arrays in the profiling way we currently don't always zero the leftover slop. This means we can't traverse such closures in the heap profiler. The old Note [zeroing slop] and #8402 have some rationale for why this is so but I belive the reasoning doesn't apply to mutable closures. There users already have to ensure multiple threads don't step on each other's toes so zeroing should be safe. - - - - - 913931e9 by Ben Gamari at 2020-05-31T02:32:07-04:00 testsuite: Add test for #18151 - - - - - 5c49e457 by Ben Gamari at 2020-05-31T02:32:07-04:00 testsuite: Add test for desugaring of PostfixOperators - - - - - 32962409 by Ben Gamari at 2020-05-31T02:32:07-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. - - - - - c2d6ce51 by Kirill Elagin at 2020-05-31T02:32:11-04:00 Winferred-safe-imports: Do not exit with error Currently, when -Winferred-safe-imports is enabled, even when it is not turned into an error, the compiler will still exit with exit code 1 if this warning was emitted. Make sure it is really treated as a warning. - - - - - 7ef4cea1 by Ben Gamari at 2020-05-31T02:32:12-04:00 nonmoving: Optimise log2_ceil - - - - - 59fe971c by Bodigrim at 2020-05-31T02:32:12-04:00 Clarify description of fromListN - - - - - 7a275da4 by Bodigrim at 2020-05-31T02:32:12-04:00 Apply suggestion to libraries/base/GHC/Exts.hs - - - - - 5ae43678 by fendor at 2020-05-31T02:32:22-04:00 Add `isInScope` check to `lintCoercion` Mirrors the behaviour of `lintType`. - - - - - 67a80a8a by fendor at 2020-05-31T02:32:22-04:00 Lint rhs of IfaceRule - - - - - 10c93d91 by Jeremy Schlatter at 2020-05-31T02:32:23-04:00 Fix wording in documentation The duplicate "orphan instance" phrase here doesn't make sense, and was probably an accident. - - - - - 5b286d4c by Takenobu Tani at 2020-05-31T02:32:39-04:00 configure: Modify aclocal.m4 according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * Rename: * compiler/GHC/Parser.hs <= compiler/parser/Parser.hs * compiler/GHC/Parser/Lexer.hs <= compiler/Parser/Lexer.hs * Add: * compiler/GHC/Cmm/Lexer.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular - - - - - f0ac8704 by Ben Gamari at 2020-05-31T02:32:40-04:00 testsuite: Don't fail if we can't unlink __symlink_test Afterall, it's possible we were unable to create it due to lack of symlink permission. - - - - - eface331 by Ben Gamari at 2020-05-31T02:32:40-04:00 testsuite: Refactor ghostscript detection Tamar reported that he saw crashes due to unhandled exceptions. - - - - - 200ed348 by Ben Gamari at 2020-05-31T02:32:40-04:00 testsuite/perf_notes: Fix ill-typed assignments - - - - - 5f63e0e0 by Ben Gamari at 2020-05-31T02:32:40-04:00 testsuite/testutil: Fix bytes/str mismatch - - - - - 81631c53 by Ben Gamari at 2020-05-31T02:32:40-04:00 testsuite: Work around spurious mypy failure - - - - - 683d04c0 by Takenobu Tani at 2020-05-31T02:32:42-04:00 Clean up file paths for new module hierarchy This updates comments only. This patch replaces file references according to new module hierarchy. See also: * https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular * https://gitlab.haskell.org/ghc/ghc/issues/13009 - - - - - 0685ee61 by Takenobu Tani at 2020-05-31T02:32:42-04:00 Modify file paths to module paths for new module hierarchy This updates comments only. This patch replaces module references according to new module hierarchy [1][2]. For files under the `compiler/` directory, I replace them as module paths instead of file paths. For instance, `GHC.Unit.State` instead of `compiler/GHC/Unit/State.hs` [3]. For current and future haddock's markup, this patch encloses the module name with "" [4]. [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: https://gitlab.haskell.org/ghc/ghc/issues/13009 [3]: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/3375#note_276613 [4]: https://haskell-haddock.readthedocs.io/en/latest/markup.html#linking-to-modules - - - - - c3e9088d by Sylvain Henry at 2020-05-31T02:32:44-04:00 Hadrian: fix binary-dist target for cross-compilation - - - - - 30 changed files: - aclocal.m4 - compiler/GHC.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/SPARC/Base.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Driver/Types.hs - compiler/GHC/Hs/ImpExp.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Monad.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/HsToCore/PmCheck/Types.hs - compiler/GHC/HsToCore/Usage.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Load.hs - compiler/GHC/Iface/Recomp.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Header.hs - compiler/GHC/Parser/Lexer.x The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f7b73d9d468193584b57308264fced4c8810385a...c3e9088d557c27f7d4da518fe184d3cde2f7755d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f7b73d9d468193584b57308264fced4c8810385a...c3e9088d557c27f7d4da518fe184d3cde2f7755d You're receiving 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 31 06:43:56 2020 From: gitlab at gitlab.haskell.org (=?UTF-8?B?w5ZtZXIgU2luYW4gQcSfYWNhbg==?=) Date: Sun, 31 May 2020 02:43:56 -0400 Subject: [Git][ghc/ghc][wip/osa1/std_string_thunks] 30 commits: GHC.Core.Unfold: Refactor traceInline Message-ID: <5ed3522c4948a_6e263f9ed4149c4c31167c4@gitlab.haskell.org.mail> Ömer Sinan Ağacan pushed to branch wip/osa1/std_string_thunks at Glasgow Haskell Compiler / GHC Commits: 28deee28 by Ben Gamari at 2020-05-28T16:23:21-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 - - - - - 1f393e1e by Ben Gamari at 2020-05-28T16:23:21-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 haddock.Cabal haddock.base haddock.compiler - - - - - 5f621a78 by Vladislav Zavialov at 2020-05-28T16:23:58-04:00 Add Semigroup/Monoid for Q (#18123) - - - - - dc5f004c by Xavier Denis at 2020-05-28T16:24:37-04:00 Fix #18071 Run the core linter on candidate instances to ensure they are well-kinded. Better handle quantified constraints by using a CtWanted to avoid having unsolved constraints thrown away at the end by the solver. - - - - - 10e6982c by Sebastian Graf at 2020-05-28T16:25:14-04:00 FloatOut: Only eta-expand dead-end RHS if arity will increase (#18231) Otherwise we risk turning trivial RHS into non-trivial RHS, introducing unnecessary bindings in the next Simplifier run, resulting in more churn. Fixes #18231. - - - - - 08dab5f7 by Sebastian Graf at 2020-05-28T16:25:14-04:00 DmdAnal: Recognise precise exceptions from case alternatives (#18086) Consider ```hs m :: IO () m = do putStrLn "foo" error "bar" ``` `m` (from #18086) always throws a (precise or imprecise) exception or diverges. Yet demand analysis infers `<L,A>` as demand signature instead of `<L,A>x` for it. That's because the demand analyser sees `putStrLn` occuring in a case scrutinee and decides that it has to `deferAfterPreciseException`, because `putStrLn` throws a precise exception on some control flow paths. This will mask the `botDiv` `Divergence`of the single case alt containing `error` to `topDiv`. Since `putStrLn` has `topDiv` itself, the final `Divergence` is `topDiv`. This is easily fixed: `deferAfterPreciseException` works by `lub`ing with the demand type of a virtual case branch denoting the precise exceptional control flow. We used `nopDmdType` before, but we can be more precise and use `exnDmdType`, which is `nopDmdType` with `exnDiv`. Now the `Divergence` from the case alt will degrade `botDiv` to `exnDiv` instead of `topDiv`, which combines with the result from the scrutinee to `exnDiv`, and all is well. Fixes #18086. - - - - - aef95f11 by Ben Gamari at 2020-05-28T16:25:53-04:00 Ticky-ticky: Record DataCon name in ticker name This makes it significantly easier to spot the nature of allocations regressions and comes at a reasonably low cost. - - - - - 8f021b8c by Ben Gamari at 2020-05-28T16:26:34-04:00 hadrian: Don't track GHC's verbosity argument Teach hadrian to ignore GHC's -v argument in its recompilation check, thus fixing #18131. - - - - - 13d9380b by Ben Gamari at 2020-05-28T16:27:20-04:00 Rip out CmmStackInfo(updfr_space) As noted in #18232, this field is currently completely unused and moreover doesn't have a clear meaning. - - - - - f10d11fa by Andreas Klebinger at 2020-05-29T01:38:42-04: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. - - - - - bbeb2389 by Ben Gamari at 2020-05-29T01:39:19-04:00 CoreToStg: Add Outputable ArgInfo instance - - - - - 0e3361ca by Simon Peyton Jones at 2020-05-29T01:39:19-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. - - - - - c49f7df0 by Simon Peyton Jones at 2020-05-29T01:39:19-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. - - - - - 46720997 by Ben Gamari at 2020-05-29T01:39:19-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 Metric Decrease: ManyConstructors Co-Authored-By: Simon Peyton-Jone <simonpj at microsoft.com> - - - - - 277c2f26 by Ben Gamari at 2020-05-29T01:39:55-04:00 Eta expand un-saturated primops Now since we no longer try to predict CAFfyness we have no need for the solution to #16846. Eta expanding unsaturated primop applications is conceptually simpler, especially in the presence of levity polymorphism. This essentially reverts cac8dc9f51e31e4c0a6cd9bc302f7e1bc7c03beb, as suggested in #18079. Closes #18079. - - - - - f44d7ae0 by Simon Jakobi at 2020-05-29T01:40:34-04:00 base: Scrap deprecation plan for Data.Monoid.{First,Last} See the discussion on the libraries mailing list for context: https://mail.haskell.org/pipermail/libraries/2020-April/030357.html - - - - - 8b494895 by Jeremy Schlatter at 2020-05-29T01:41:12-04:00 Fix typo in documentation - - - - - 998450f4 by Gleb Popov at 2020-05-29T01:41:53-04:00 Always define USE_PTHREAD_FOR_ITIMER for FreeBSD. - - - - - f9a513e0 by Alp Mestanogullari at 2020-05-29T01:42:36-04:00 hadrian: introduce 'install' target Its logic is very simple. It `need`s the `binary-dist-dir` target and runs suitable `configure` and `make install` commands for the user. A new `--prefix` command line argument is introduced to specify where GHC should be installed. - - - - - 67738db1 by Travis Whitaker at 2020-05-29T13:34:48-04:00 Build a threaded stage 1 if the bootstrapping GHC supports it. - - - - - aac19e6c by Peter Trommler at 2020-05-29T13:35:24-04:00 PPC NCG: No per-symbol .section ".toc" directives All position independent symbols are collected during code generation and emitted in one go. Prepending each symbol with a .section ".toc" directive is redundant. This patch drops the per-symbol directives leading to smaller assembler files. Fixes #18250 - - - - - 4413828b by Ben Gamari at 2020-05-30T06:07:31-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. - - - - - 1449435c by Ben Gamari at 2020-05-30T06:07:31-04:00 users-guide: Note change in getNumProcessors in users guide - - - - - 3d960169 by Ben Gamari at 2020-05-30T06:07:31-04:00 rts: Drop compatibility shims for Windows Vista We can now assume that the thread and processor group interfaces are available. - - - - - 7f8f948c by Peter Trommler at 2020-05-30T06:08:07-04:00 PPC NCG: Fix .size directive on powerpc64 ELF v1 Thanks to Sergei Trofimovich for pointing out the issue. Fixes #18237 - - - - - 7c555b05 by Andreas Klebinger at 2020-05-30T06:08:43-04:00 Optimize GHC.Utils.Monad. Many functions in this module are recursive and as such are marked loop breakers. Which means they are unlikely to get an unfolding. This is *bad*. We always want to specialize them to specific Monads. Which requires a visible unfolding at the use site. I rewrote the recursive ones from: foo f x = ... foo x' ... to foo f x = go x where go x = ... As well as giving some pragmas to make all of them available for specialization. The end result is a reduction of allocations of about -1.4% for nofib/spectral/simple/Main.hs when compiled with `-O`. ------------------------- Metric Decrease: T12425 T14683 T5631 T9233 T9675 T9961 WWRec ------------------------- - - - - - 8b1cb5df by Ben Gamari at 2020-05-30T06:09:20-04:00 Windows: Bump Windows toolchain to 0.2 - - - - - 6947231a by Zubin Duggal at 2020-05-30T06:10:02-04:00 Simplify contexts in GHC.Iface.Ext.Ast - - - - - ce41f0a7 by Ömer Sinan Ağacan at 2020-05-31T09:41:14+03:00 Introduce a standard thunk for allocating strings Currently for a top-level closure in the form hey = unpackCString# x we generate code like this: Main.hey_entry() // [R1] { info_tbls: [(c2T4, label: Main.hey_info rep: HeapRep static { Thunk } srt: Nothing)] stack_info: arg_space: 8 updfr_space: Just 8 } {offset c2T4: // global _rqm::P64 = R1; if ((Sp + 8) - 24 < SpLim) (likely: False) goto c2T5; else goto c2T6; c2T5: // global R1 = _rqm::P64; call (stg_gc_enter_1)(R1) args: 8, res: 0, upd: 8; c2T6: // global (_c2T1::I64) = call "ccall" arg hints: [PtrHint, PtrHint] result hints: [PtrHint] newCAF(BaseReg, _rqm::P64); if (_c2T1::I64 == 0) goto c2T3; else goto c2T2; c2T3: // global call (I64[_rqm::P64])() args: 8, res: 0, upd: 8; c2T2: // global I64[Sp - 16] = stg_bh_upd_frame_info; I64[Sp - 8] = _c2T1::I64; R2 = hey1_r2Gg_bytes; Sp = Sp - 16; call GHC.CString.unpackCString#_info(R2) args: 24, res: 0, upd: 24; } } This code is generated for every string literal. Only difference between top-level closures like this is the argument for the bytes of the string (hey1_r2Gg_bytes in the code above). With this patch we introduce a standard thunk in the RTS, called stg_MK_STRING_info, that does what `unpackCString# x` does, except it gets the bytes address from the payload. Using this, for the closure above, we generate this: Main.hey_closure" { Main.hey_closure: const stg_MK_STRING_info; const hey1_r1Gg_bytes; const 0; const 0; } This is much smaller in code. Trying to fix top-level thunk layouts - - - - - 64f83a02 by Ömer Sinan Ağacan at 2020-05-31T09:41:14+03:00 Implement non-ptr payload in THUNKs with least amount of hacks Also updates SRT analysis to be able to deal with THUNKs in CmmStatics form. Sigh - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/CLabel.hs - compiler/GHC/Cmm/Info/Build.hs - compiler/GHC/Cmm/LayoutStack.hs - compiler/GHC/Cmm/Parser.y - compiler/GHC/Cmm/Ppr.hs - compiler/GHC/Cmm/Ppr/Decl.hs - compiler/GHC/Cmm/ProcPoint.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Monad.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Runtime/Eval.hs - compiler/GHC/StgToCmm/Bind.hs - compiler/GHC/StgToCmm/Heap.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6eaa4ca235b245b18c7827f7e11552987dc368fa...64f83a02b1c64d70e3d99b7ae3606594f7db6b6d -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6eaa4ca235b245b18c7827f7e11552987dc368fa...64f83a02b1c64d70e3d99b7ae3606594f7db6b6d You're receiving 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 31 11:52:06 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Sun, 31 May 2020 07:52:06 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/simply-bind-tyvars Message-ID: <5ed39a665d8f1_6e263f9ed4149c4c315266c@gitlab.haskell.org.mail> Ryan Scott pushed new branch wip/simply-bind-tyvars at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/simply-bind-tyvars You're receiving 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 31 12:04:01 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 31 May 2020 08:04:01 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 22 commits: Cleanup OVERWRITING_CLOSURE logic Message-ID: <5ed39d3163397_6e263f9eebb487683156875@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: c51d3bd5 by Daniel Gröber at 2020-05-31T08:03:36-04:00 Cleanup OVERWRITING_CLOSURE logic The code is just more confusing than it needs to be. We don't need to mix the threaded check with the ldv profiling check since ldv's init already checks for this. Hence they can be two separate checks. Taking the sanity checking into account is also cleaner via DebugFlags.sanity. No need for checking the DEBUG define. The ZERO_SLOP_FOR_LDV_PROF and ZERO_SLOP_FOR_SANITY_CHECK definitions the old code had also make things a lot more opaque IMO so I removed those. - - - - - 49ae34bb by Daniel Gröber at 2020-05-31T08:03:36-04:00 Fix OVERWRITING_CLOSURE assuming closures are not inherently used The new ASSERT in LDV_recordDead() was being tripped up by MVars when removeFromMVarBlockedQueue() calls OVERWRITING_CLOSURE() via OVERWRITE_INFO(). - - - - - ba9529e5 by Daniel Gröber at 2020-05-31T08:03:36-04:00 Always zero shrunk mutable array slop when profiling When shrinking arrays in the profiling way we currently don't always zero the leftover slop. This means we can't traverse such closures in the heap profiler. The old Note [zeroing slop] and #8402 have some rationale for why this is so but I belive the reasoning doesn't apply to mutable closures. There users already have to ensure multiple threads don't step on each other's toes so zeroing should be safe. - - - - - 23d26bbd by Ben Gamari at 2020-05-31T08:03:37-04:00 testsuite: Add test for #18151 - - - - - 6667b4f2 by Ben Gamari at 2020-05-31T08:03:37-04:00 testsuite: Add test for desugaring of PostfixOperators - - - - - a1d5df6a by Ben Gamari at 2020-05-31T08:03:37-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. - - - - - f56120dc by Kirill Elagin at 2020-05-31T08:03:46-04:00 Winferred-safe-imports: Do not exit with error Currently, when -Winferred-safe-imports is enabled, even when it is not turned into an error, the compiler will still exit with exit code 1 if this warning was emitted. Make sure it is really treated as a warning. - - - - - ba7882bd by Ben Gamari at 2020-05-31T08:03:46-04:00 nonmoving: Optimise log2_ceil - - - - - ba8fc926 by Bodigrim at 2020-05-31T08:03:47-04:00 Clarify description of fromListN - - - - - 5375b1cf by Bodigrim at 2020-05-31T08:03:47-04:00 Apply suggestion to libraries/base/GHC/Exts.hs - - - - - e4824962 by fendor at 2020-05-31T08:03:48-04:00 Add `isInScope` check to `lintCoercion` Mirrors the behaviour of `lintType`. - - - - - 2b727245 by fendor at 2020-05-31T08:03:48-04:00 Lint rhs of IfaceRule - - - - - 50b2ceef by Jeremy Schlatter at 2020-05-31T08:03:50-04:00 Fix wording in documentation The duplicate "orphan instance" phrase here doesn't make sense, and was probably an accident. - - - - - d43e9448 by Takenobu Tani at 2020-05-31T08:03:51-04:00 configure: Modify aclocal.m4 according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * Rename: * compiler/GHC/Parser.hs <= compiler/parser/Parser.hs * compiler/GHC/Parser/Lexer.hs <= compiler/Parser/Lexer.hs * Add: * compiler/GHC/Cmm/Lexer.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular - - - - - 6481c390 by Ben Gamari at 2020-05-31T08:03:52-04:00 testsuite: Don't fail if we can't unlink __symlink_test Afterall, it's possible we were unable to create it due to lack of symlink permission. - - - - - 0d64a28a by Ben Gamari at 2020-05-31T08:03:52-04:00 testsuite: Refactor ghostscript detection Tamar reported that he saw crashes due to unhandled exceptions. - - - - - 54591739 by Ben Gamari at 2020-05-31T08:03:52-04:00 testsuite/perf_notes: Fix ill-typed assignments - - - - - eb4df111 by Ben Gamari at 2020-05-31T08:03:52-04:00 testsuite/testutil: Fix bytes/str mismatch - - - - - b37aacf5 by Ben Gamari at 2020-05-31T08:03:52-04:00 testsuite: Work around spurious mypy failure - - - - - 9d9d193e by Takenobu Tani at 2020-05-31T08:03:54-04:00 Clean up file paths for new module hierarchy This updates comments only. This patch replaces file references according to new module hierarchy. See also: * https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular * https://gitlab.haskell.org/ghc/ghc/issues/13009 - - - - - acd9032c by Takenobu Tani at 2020-05-31T08:03:54-04:00 Modify file paths to module paths for new module hierarchy This updates comments only. This patch replaces module references according to new module hierarchy [1][2]. For files under the `compiler/` directory, I replace them as module paths instead of file paths. For instance, `GHC.Unit.State` instead of `compiler/GHC/Unit/State.hs` [3]. For current and future haddock's markup, this patch encloses the module name with "" [4]. [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: https://gitlab.haskell.org/ghc/ghc/issues/13009 [3]: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/3375#note_276613 [4]: https://haskell-haddock.readthedocs.io/en/latest/markup.html#linking-to-modules - - - - - 61d992af by Sylvain Henry at 2020-05-31T08:03:56-04:00 Hadrian: fix binary-dist target for cross-compilation - - - - - 30 changed files: - aclocal.m4 - compiler/GHC.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/SPARC/Base.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/HsToCore/PmCheck/Types.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Parser/Lexer.x - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToCmm/Utils.hs - compiler/GHC/SysTools/ExtraObj.hs - compiler/GHC/Tc/Deriv.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Utils/Outputable.hs - compiler/GHC/Utils/Ppr.hs - compiler/ghc.mk - docs/users_guide/separate_compilation.rst - hadrian/src/Rules/BinaryDist.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c3e9088d557c27f7d4da518fe184d3cde2f7755d...61d992af80acb5578852f844430aee1fa5a843fb -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c3e9088d557c27f7d4da518fe184d3cde2f7755d...61d992af80acb5578852f844430aee1fa5a843fb You're receiving 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 31 13:22:58 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Sun, 31 May 2020 09:22:58 -0400 Subject: [Git][ghc/ghc][wip/T18191] 32 commits: core-spec: Modify file paths according to new module hierarchy Message-ID: <5ed3afb2218b0_6e2612bfae0c317725c@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T18191 at Glasgow Haskell Compiler / GHC Commits: ede24126 by Takenobu Tani at 2020-05-27T00:13:55-04:00 core-spec: Modify file paths according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * GHC/Core.hs <= coreSyn/CoreSyn.hs * GHC/Core/Coercion.hs <= types/Coercion.hs * GHC/Core/Coercion/Axiom.hs <= types/CoAxiom.hs * GHC/Core/Coercion/Opt.hs <= types/OptCoercion.hs * GHC/Core/DataCon.hs <= basicTypes/DataCon.hs * GHC/Core/FamInstEnv.hs <= types/FamInstEnv.hs * GHC/Core/Lint.hs <= coreSyn/CoreLint.hs * GHC/Core/Subst.hs <= coreSyn/CoreSubst.hs * GHC/Core/TyCo/Rep.hs <= types/TyCoRep.hs * GHC/Core/TyCon.hs <= types/TyCon.hs * GHC/Core/Type.hs <= types/Type.hs * GHC/Core/Unify.hs <= types/Unify.hs * GHC/Types/Literal.hs <= basicTypes/Literal.hs * GHC/Types/Var.hs <= basicTypes/Var.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [skip ci] - - - - - 04750304 by Ben Gamari at 2020-05-27T00:14:33-04:00 eventlog: Fix racy flushing Previously no attempt was made to avoid multiple threads writing their capability-local eventlog buffers to the eventlog writer simultaneously. This could result in multiple eventlog streams being interleaved. Fix this by documenting that the EventLogWriter's write() and flush() functions may be called reentrantly and fix the default writer to protect its FILE* by a mutex. Fixes #18210. - - - - - d6203f24 by Joshua Price at 2020-05-27T00:15:17-04:00 Make `identifier` parse unparenthesized `->` (#18060) - - - - - 28deee28 by Ben Gamari at 2020-05-28T16:23:21-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 - - - - - 1f393e1e by Ben Gamari at 2020-05-28T16:23:21-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 haddock.Cabal haddock.base haddock.compiler - - - - - 5f621a78 by Vladislav Zavialov at 2020-05-28T16:23:58-04:00 Add Semigroup/Monoid for Q (#18123) - - - - - dc5f004c by Xavier Denis at 2020-05-28T16:24:37-04:00 Fix #18071 Run the core linter on candidate instances to ensure they are well-kinded. Better handle quantified constraints by using a CtWanted to avoid having unsolved constraints thrown away at the end by the solver. - - - - - 10e6982c by Sebastian Graf at 2020-05-28T16:25:14-04:00 FloatOut: Only eta-expand dead-end RHS if arity will increase (#18231) Otherwise we risk turning trivial RHS into non-trivial RHS, introducing unnecessary bindings in the next Simplifier run, resulting in more churn. Fixes #18231. - - - - - 08dab5f7 by Sebastian Graf at 2020-05-28T16:25:14-04:00 DmdAnal: Recognise precise exceptions from case alternatives (#18086) Consider ```hs m :: IO () m = do putStrLn "foo" error "bar" ``` `m` (from #18086) always throws a (precise or imprecise) exception or diverges. Yet demand analysis infers `<L,A>` as demand signature instead of `<L,A>x` for it. That's because the demand analyser sees `putStrLn` occuring in a case scrutinee and decides that it has to `deferAfterPreciseException`, because `putStrLn` throws a precise exception on some control flow paths. This will mask the `botDiv` `Divergence`of the single case alt containing `error` to `topDiv`. Since `putStrLn` has `topDiv` itself, the final `Divergence` is `topDiv`. This is easily fixed: `deferAfterPreciseException` works by `lub`ing with the demand type of a virtual case branch denoting the precise exceptional control flow. We used `nopDmdType` before, but we can be more precise and use `exnDmdType`, which is `nopDmdType` with `exnDiv`. Now the `Divergence` from the case alt will degrade `botDiv` to `exnDiv` instead of `topDiv`, which combines with the result from the scrutinee to `exnDiv`, and all is well. Fixes #18086. - - - - - aef95f11 by Ben Gamari at 2020-05-28T16:25:53-04:00 Ticky-ticky: Record DataCon name in ticker name This makes it significantly easier to spot the nature of allocations regressions and comes at a reasonably low cost. - - - - - 8f021b8c by Ben Gamari at 2020-05-28T16:26:34-04:00 hadrian: Don't track GHC's verbosity argument Teach hadrian to ignore GHC's -v argument in its recompilation check, thus fixing #18131. - - - - - 13d9380b by Ben Gamari at 2020-05-28T16:27:20-04:00 Rip out CmmStackInfo(updfr_space) As noted in #18232, this field is currently completely unused and moreover doesn't have a clear meaning. - - - - - f10d11fa by Andreas Klebinger at 2020-05-29T01:38:42-04: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. - - - - - bbeb2389 by Ben Gamari at 2020-05-29T01:39:19-04:00 CoreToStg: Add Outputable ArgInfo instance - - - - - 0e3361ca by Simon Peyton Jones at 2020-05-29T01:39:19-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. - - - - - c49f7df0 by Simon Peyton Jones at 2020-05-29T01:39:19-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. - - - - - 46720997 by Ben Gamari at 2020-05-29T01:39:19-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 Metric Decrease: ManyConstructors Co-Authored-By: Simon Peyton-Jone <simonpj at microsoft.com> - - - - - 277c2f26 by Ben Gamari at 2020-05-29T01:39:55-04:00 Eta expand un-saturated primops Now since we no longer try to predict CAFfyness we have no need for the solution to #16846. Eta expanding unsaturated primop applications is conceptually simpler, especially in the presence of levity polymorphism. This essentially reverts cac8dc9f51e31e4c0a6cd9bc302f7e1bc7c03beb, as suggested in #18079. Closes #18079. - - - - - f44d7ae0 by Simon Jakobi at 2020-05-29T01:40:34-04:00 base: Scrap deprecation plan for Data.Monoid.{First,Last} See the discussion on the libraries mailing list for context: https://mail.haskell.org/pipermail/libraries/2020-April/030357.html - - - - - 8b494895 by Jeremy Schlatter at 2020-05-29T01:41:12-04:00 Fix typo in documentation - - - - - 998450f4 by Gleb Popov at 2020-05-29T01:41:53-04:00 Always define USE_PTHREAD_FOR_ITIMER for FreeBSD. - - - - - f9a513e0 by Alp Mestanogullari at 2020-05-29T01:42:36-04:00 hadrian: introduce 'install' target Its logic is very simple. It `need`s the `binary-dist-dir` target and runs suitable `configure` and `make install` commands for the user. A new `--prefix` command line argument is introduced to specify where GHC should be installed. - - - - - 67738db1 by Travis Whitaker at 2020-05-29T13:34:48-04:00 Build a threaded stage 1 if the bootstrapping GHC supports it. - - - - - aac19e6c by Peter Trommler at 2020-05-29T13:35:24-04:00 PPC NCG: No per-symbol .section ".toc" directives All position independent symbols are collected during code generation and emitted in one go. Prepending each symbol with a .section ".toc" directive is redundant. This patch drops the per-symbol directives leading to smaller assembler files. Fixes #18250 - - - - - 4413828b by Ben Gamari at 2020-05-30T06:07:31-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. - - - - - 1449435c by Ben Gamari at 2020-05-30T06:07:31-04:00 users-guide: Note change in getNumProcessors in users guide - - - - - 3d960169 by Ben Gamari at 2020-05-30T06:07:31-04:00 rts: Drop compatibility shims for Windows Vista We can now assume that the thread and processor group interfaces are available. - - - - - 7f8f948c by Peter Trommler at 2020-05-30T06:08:07-04:00 PPC NCG: Fix .size directive on powerpc64 ELF v1 Thanks to Sergei Trofimovich for pointing out the issue. Fixes #18237 - - - - - 7c555b05 by Andreas Klebinger at 2020-05-30T06:08:43-04:00 Optimize GHC.Utils.Monad. Many functions in this module are recursive and as such are marked loop breakers. Which means they are unlikely to get an unfolding. This is *bad*. We always want to specialize them to specific Monads. Which requires a visible unfolding at the use site. I rewrote the recursive ones from: foo f x = ... foo x' ... to foo f x = go x where go x = ... As well as giving some pragmas to make all of them available for specialization. The end result is a reduction of allocations of about -1.4% for nofib/spectral/simple/Main.hs when compiled with `-O`. ------------------------- Metric Decrease: T12425 T14683 T5631 T9233 T9675 T9961 WWRec ------------------------- - - - - - 8b1cb5df by Ben Gamari at 2020-05-30T06:09:20-04:00 Windows: Bump Windows toolchain to 0.2 - - - - - 6947231a by Zubin Duggal at 2020-05-30T06:10:02-04:00 Simplify contexts in GHC.Iface.Ext.Ast - - - - - 3865ad6d by Ryan Scott at 2020-05-31T09:17:13-04:00 Make GADT constructors adhere to the forall-or-nothing rule properly Issue #18191 revealed that the types of GADT constructors don't quite adhere to the `forall`-or-nothing rule. This patch serves to clean up this sad state of affairs somewhat. The main change is not in the code itself, but in the documentation, as this patch introduces two sections to the GHC User's Guide: * A "Formal syntax for GADTs" section that presents a BNF-style grammar for what is and isn't allowed in GADT constructor types. This mostly exists to codify GHC's existing behavior, but it also imposes a new restriction that addresses #18191: the outermost `forall` and/or context in a GADT constructor is not allowed to be surrounded by parentheses. Doing so would make these `forall`s/contexts nested, and GADTs do not support nested `forall`s/contexts at present. * A "`forall`-or-nothing rule" section that describes exactly what the `forall`-or-nothing rule is all about. Surprisingly, there was no mention of this anywhere in the User's Guide up until now! To adhere the new specification in the "Formal syntax for GADTs" section of the User's Guide, the following code changes were made: * A new function, `GHC.Hs.Type.splitLHsGADTPrefixTy`, was introduced. This is very much like `splitLHsSigmaTy`, except that it avoids splitting apart any parentheses, which can be syntactically significant for GADT types. See `Note [No nested foralls or contexts in GADT constructors]` in `GHC.Hs.Type`. * `ConDeclGADTPrefixPs`, an extension constructor for `XConDecl`, was introduced so that `GHC.Parser.PostProcess.mkGadtDecl` can return it when given a prefix GADT constructor. Unlike `ConDeclGADT`, `ConDeclGADTPrefixPs` does not split the GADT type into its argument and result types, as this cannot be done until after the type is renamed (see `Note [GADT abstract syntax]` in `GHC.Hs.Decls` for why this is the case). * `GHC.Renamer.Module.rnConDecl` now has an additional case for `ConDeclGADTPrefixPs` that (1) splits apart the full `LHsType` into its `forall`s, context, argument types, and result type, and (2) checks for nested `forall`s/contexts. Step (2) used to be performed the typechecker (in `GHC.Tc.TyCl.badDataConTyCon`) rather than the renamer, but now the relevant code from the typechecker can simply be deleted. One nice side effect of this change is that we are able to give a more accurate error message for GADT constructors that use visible dependent quantification (e.g., `MkFoo :: forall a -> a -> Foo a`), which improves the stderr in the `T16326_Fail6` test case. Fixes #18191. Bumps the Haddock submodule. - - - - - 30 changed files: - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/PrimOps.hs - compiler/GHC/ByteCode/Linker.hs - compiler/GHC/Cmm.hs - compiler/GHC/Cmm/LayoutStack.hs - compiler/GHC/Cmm/Ppr.hs - compiler/GHC/Cmm/ProcPoint.hs - compiler/GHC/CmmToAsm/PIC.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/Opt/FloatOut.hs - compiler/GHC/Core/Opt/OccurAnal.hs - compiler/GHC/Core/Opt/SetLevels.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Opt/Simplify/Monad.hs - compiler/GHC/Core/SimpleOpt.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/CoreToStg.hs - compiler/GHC/CoreToStg/Prep.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/HsToCore/Utils.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Parser/PostProcess/Haddock.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/448cfdfb7c50463a092d35ea48c5b1a33eee3ba0...3865ad6ddd01df28168ab33a436e4fbc08b626ce -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/448cfdfb7c50463a092d35ea48c5b1a33eee3ba0...3865ad6ddd01df28168ab33a436e4fbc08b626ce You're receiving 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 31 14:14:51 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 31 May 2020 10:14:51 -0400 Subject: [Git][ghc/ghc][ghc-8.8] FastString: fix eager reading of string ptr in hashStr Message-ID: <5ed3bbdbbf497_6e2611a0b9e431874a@gitlab.haskell.org.mail> Ben Gamari pushed to branch ghc-8.8 at Glasgow Haskell Compiler / GHC Commits: bc05d359 by Ömer Sinan Ağacan at 2020-05-30T10:20:52-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 cb1785d9f839e34a3a4892f354f0c51cc6553c0e) - - - - - 1 changed file: - compiler/utils/FastString.hs Changes: ===================================== compiler/utils/FastString.hs ===================================== @@ -519,16 +519,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 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bc05d3599545ddca50dbd8a557fd71785f6cb6fd -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/bc05d3599545ddca50dbd8a557fd71785f6cb6fd You're receiving 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 31 14:16:31 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 31 May 2020 10:16:31 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 25 commits: Cleanup OVERWRITING_CLOSURE logic Message-ID: <5ed3bc3f37681_6e263f9ed4149c4c3191657@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: 97b396b3 by Daniel Gröber at 2020-05-31T10:14:52-04:00 Cleanup OVERWRITING_CLOSURE logic The code is just more confusing than it needs to be. We don't need to mix the threaded check with the ldv profiling check since ldv's init already checks for this. Hence they can be two separate checks. Taking the sanity checking into account is also cleaner via DebugFlags.sanity. No need for checking the DEBUG define. The ZERO_SLOP_FOR_LDV_PROF and ZERO_SLOP_FOR_SANITY_CHECK definitions the old code had also make things a lot more opaque IMO so I removed those. - - - - - df70fcfc by Daniel Gröber at 2020-05-31T10:14:52-04:00 Fix OVERWRITING_CLOSURE assuming closures are not inherently used The new ASSERT in LDV_recordDead() was being tripped up by MVars when removeFromMVarBlockedQueue() calls OVERWRITING_CLOSURE() via OVERWRITE_INFO(). - - - - - 61a5f17f by Daniel Gröber at 2020-05-31T10:14:52-04:00 Always zero shrunk mutable array slop when profiling When shrinking arrays in the profiling way we currently don't always zero the leftover slop. This means we can't traverse such closures in the heap profiler. The old Note [zeroing slop] and #8402 have some rationale for why this is so but I belive the reasoning doesn't apply to mutable closures. There users already have to ensure multiple threads don't step on each other's toes so zeroing should be safe. - - - - - 0f5ab025 by Ben Gamari at 2020-05-31T10:14:53-04:00 testsuite: Add test for #18151 - - - - - 6d2cc1a1 by Ben Gamari at 2020-05-31T10:14:53-04:00 testsuite: Add test for desugaring of PostfixOperators - - - - - 59e6e58e by Ben Gamari at 2020-05-31T10:14:53-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. - - - - - 3d72609c by Kirill Elagin at 2020-05-31T10:15:19-04:00 Winferred-safe-imports: Do not exit with error Currently, when -Winferred-safe-imports is enabled, even when it is not turned into an error, the compiler will still exit with exit code 1 if this warning was emitted. Make sure it is really treated as a warning. - - - - - ea50b83f by Ben Gamari at 2020-05-31T10:15:19-04:00 nonmoving: Optimise log2_ceil - - - - - 09e0aa36 by Bodigrim at 2020-05-31T10:15:20-04:00 Clarify description of fromListN - - - - - 57bad180 by Bodigrim at 2020-05-31T10:15:20-04:00 Apply suggestion to libraries/base/GHC/Exts.hs - - - - - 1401363d by fendor at 2020-05-31T10:15:24-04:00 Add `isInScope` check to `lintCoercion` Mirrors the behaviour of `lintType`. - - - - - 5ab9d2b2 by fendor at 2020-05-31T10:15:24-04:00 Lint rhs of IfaceRule - - - - - 2af2f60f by Jeremy Schlatter at 2020-05-31T10:15:27-04:00 Fix wording in documentation The duplicate "orphan instance" phrase here doesn't make sense, and was probably an accident. - - - - - 0bcf3237 by Takenobu Tani at 2020-05-31T10:15:53-04:00 configure: Modify aclocal.m4 according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * Rename: * compiler/GHC/Parser.hs <= compiler/parser/Parser.hs * compiler/GHC/Parser/Lexer.hs <= compiler/Parser/Lexer.hs * Add: * compiler/GHC/Cmm/Lexer.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular - - - - - 268d9b56 by Ben Gamari at 2020-05-31T10:15:53-04:00 testsuite: Don't fail if we can't unlink __symlink_test Afterall, it's possible we were unable to create it due to lack of symlink permission. - - - - - 495c1593 by Ben Gamari at 2020-05-31T10:15:53-04:00 testsuite: Refactor ghostscript detection Tamar reported that he saw crashes due to unhandled exceptions. - - - - - 06cf3101 by Ben Gamari at 2020-05-31T10:15:53-04:00 testsuite/perf_notes: Fix ill-typed assignments - - - - - 118de0ff by Ben Gamari at 2020-05-31T10:15:53-04:00 testsuite/testutil: Fix bytes/str mismatch - - - - - 087704db by Ben Gamari at 2020-05-31T10:15:53-04:00 testsuite: Work around spurious mypy failure - - - - - 0536fe91 by Takenobu Tani at 2020-05-31T10:15:55-04:00 Clean up file paths for new module hierarchy This updates comments only. This patch replaces file references according to new module hierarchy. See also: * https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular * https://gitlab.haskell.org/ghc/ghc/issues/13009 - - - - - 999c1f83 by Takenobu Tani at 2020-05-31T10:15:55-04:00 Modify file paths to module paths for new module hierarchy This updates comments only. This patch replaces module references according to new module hierarchy [1][2]. For files under the `compiler/` directory, I replace them as module paths instead of file paths. For instance, `GHC.Unit.State` instead of `compiler/GHC/Unit/State.hs` [3]. For current and future haddock's markup, this patch encloses the module name with "" [4]. [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: https://gitlab.haskell.org/ghc/ghc/issues/13009 [3]: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/3375#note_276613 [4]: https://haskell-haddock.readthedocs.io/en/latest/markup.html#linking-to-modules - - - - - 4b335c4f by Sylvain Henry at 2020-05-31T10:16:16-04:00 Hadrian: fix binary-dist target for cross-compilation - - - - - 3aeae2c1 by Vladislav Zavialov at 2020-05-31T10:16:16-04:00 Improve parser error messages for the @-operator Since GHC diverges from the Haskell Report by allowing the user to define (@) as an infix operator, we better give a good error message when the user does so unintentionally. In general, this is rather hard to do, as some failures will be discovered only in the renamer or the type checker: x :: (Integer, Integer) x @ (a, b) = (1, 2) This patch does *not* address this general case. However, it gives much better error messages when the binding is not syntactically valid: pairs xs @ (_:xs') = zip xs xs' Before this patch, the error message was rather puzzling: <interactive>:1:1: error: Parse error in pattern: pairs After this patch, the error message includes a hint: <interactive>:1:1: error: Parse error in pattern: pairs In a function binding for the ‘@’ operator. Perhaps you meant an as-pattern, which must not be surrounded by whitespace - - - - - bb31292c by Vladislav Zavialov at 2020-05-31T10:16:16-04:00 Improve parser error messages for TypeApplications With this patch, we always parse f @t as a type application, thereby producing better error messages. This steals two syntactic forms: * Prefix form of the @-operator in expressions. Since the @-operator is a divergence from the Haskell Report anyway, this is not a major loss. * Prefix form of @-patterns. Since we are stealing loose infix form anyway, might as well sacrifice the prefix form for the sake of much better error messages. - - - - - 6c919f0b by Vladislav Zavialov at 2020-05-31T10:16:17-04:00 Improve parser error messages for TemplateHaskellQuotes While [e| |], [t| |], [d| |], and so on, steal syntax from list comprehensions, [| |] and [|| ||] do not steal any syntax. Thus we can improve error messages by always accepting them in the lexer. Turns out the renamer already performs necessary validation. - - - - - 30 changed files: - aclocal.m4 - compiler/GHC.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/SPARC/Base.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/HsToCore/PmCheck/Types.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Lexer.x - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToCmm/Utils.hs - compiler/GHC/SysTools/ExtraObj.hs - compiler/GHC/Tc/Deriv.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Utils/Outputable.hs - compiler/GHC/Utils/Ppr.hs - compiler/ghc.mk The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/61d992af80acb5578852f844430aee1fa5a843fb...6c919f0b252e385b8e9ffb313ea280ca28cd2913 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/61d992af80acb5578852f844430aee1fa5a843fb...6c919f0b252e385b8e9ffb313ea280ca28cd2913 You're receiving 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 31 14:37:17 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Sun, 31 May 2020 10:37:17 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18240 Message-ID: <5ed3c11d4f990_6e2612bfae0c3210789@gitlab.haskell.org.mail> Ryan Scott pushed new branch wip/T18240 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18240 You're receiving 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 31 14:39:59 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 31 May 2020 10:39:59 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/landing Message-ID: <5ed3c1bf76386_6e263f9f0ba73bc43210913@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/landing at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/landing You're receiving 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 31 15:08:30 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 31 May 2020 11:08:30 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/fix-xelatex Message-ID: <5ed3c86e513a1_6e2612cfb0e032163bf@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/fix-xelatex at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/fix-xelatex You're receiving 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 31 15:15:28 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 31 May 2020 11:15:28 -0400 Subject: [Git][ghc/ghc][wip/bump-base] 35 commits: rts: Teach getNumProcessors to return available processors Message-ID: <5ed3ca10d4583_6e263f9f0ba73bc432243a4@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/bump-base at Glasgow Haskell Compiler / GHC Commits: 4413828b by Ben Gamari at 2020-05-30T06:07:31-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. - - - - - 1449435c by Ben Gamari at 2020-05-30T06:07:31-04:00 users-guide: Note change in getNumProcessors in users guide - - - - - 3d960169 by Ben Gamari at 2020-05-30T06:07:31-04:00 rts: Drop compatibility shims for Windows Vista We can now assume that the thread and processor group interfaces are available. - - - - - 7f8f948c by Peter Trommler at 2020-05-30T06:08:07-04:00 PPC NCG: Fix .size directive on powerpc64 ELF v1 Thanks to Sergei Trofimovich for pointing out the issue. Fixes #18237 - - - - - 7c555b05 by Andreas Klebinger at 2020-05-30T06:08:43-04:00 Optimize GHC.Utils.Monad. Many functions in this module are recursive and as such are marked loop breakers. Which means they are unlikely to get an unfolding. This is *bad*. We always want to specialize them to specific Monads. Which requires a visible unfolding at the use site. I rewrote the recursive ones from: foo f x = ... foo x' ... to foo f x = go x where go x = ... As well as giving some pragmas to make all of them available for specialization. The end result is a reduction of allocations of about -1.4% for nofib/spectral/simple/Main.hs when compiled with `-O`. ------------------------- Metric Decrease: T12425 T14683 T5631 T9233 T9675 T9961 WWRec ------------------------- - - - - - 8b1cb5df by Ben Gamari at 2020-05-30T06:09:20-04:00 Windows: Bump Windows toolchain to 0.2 - - - - - 6947231a by Zubin Duggal at 2020-05-30T06:10:02-04:00 Simplify contexts in GHC.Iface.Ext.Ast - - - - - 97b396b3 by Daniel Gröber at 2020-05-31T10:14:52-04:00 Cleanup OVERWRITING_CLOSURE logic The code is just more confusing than it needs to be. We don't need to mix the threaded check with the ldv profiling check since ldv's init already checks for this. Hence they can be two separate checks. Taking the sanity checking into account is also cleaner via DebugFlags.sanity. No need for checking the DEBUG define. The ZERO_SLOP_FOR_LDV_PROF and ZERO_SLOP_FOR_SANITY_CHECK definitions the old code had also make things a lot more opaque IMO so I removed those. - - - - - df70fcfc by Daniel Gröber at 2020-05-31T10:14:52-04:00 Fix OVERWRITING_CLOSURE assuming closures are not inherently used The new ASSERT in LDV_recordDead() was being tripped up by MVars when removeFromMVarBlockedQueue() calls OVERWRITING_CLOSURE() via OVERWRITE_INFO(). - - - - - 61a5f17f by Daniel Gröber at 2020-05-31T10:14:52-04:00 Always zero shrunk mutable array slop when profiling When shrinking arrays in the profiling way we currently don't always zero the leftover slop. This means we can't traverse such closures in the heap profiler. The old Note [zeroing slop] and #8402 have some rationale for why this is so but I belive the reasoning doesn't apply to mutable closures. There users already have to ensure multiple threads don't step on each other's toes so zeroing should be safe. - - - - - 0f5ab025 by Ben Gamari at 2020-05-31T10:14:53-04:00 testsuite: Add test for #18151 - - - - - 6d2cc1a1 by Ben Gamari at 2020-05-31T10:14:53-04:00 testsuite: Add test for desugaring of PostfixOperators - - - - - 59e6e58e by Ben Gamari at 2020-05-31T10:14:53-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. - - - - - 3d72609c by Kirill Elagin at 2020-05-31T10:15:19-04:00 Winferred-safe-imports: Do not exit with error Currently, when -Winferred-safe-imports is enabled, even when it is not turned into an error, the compiler will still exit with exit code 1 if this warning was emitted. Make sure it is really treated as a warning. - - - - - ea50b83f by Ben Gamari at 2020-05-31T10:15:19-04:00 nonmoving: Optimise log2_ceil - - - - - 09e0aa36 by Bodigrim at 2020-05-31T10:15:20-04:00 Clarify description of fromListN - - - - - 57bad180 by Bodigrim at 2020-05-31T10:15:20-04:00 Apply suggestion to libraries/base/GHC/Exts.hs - - - - - 1401363d by fendor at 2020-05-31T10:15:24-04:00 Add `isInScope` check to `lintCoercion` Mirrors the behaviour of `lintType`. - - - - - 5ab9d2b2 by fendor at 2020-05-31T10:15:24-04:00 Lint rhs of IfaceRule - - - - - 2af2f60f by Jeremy Schlatter at 2020-05-31T10:15:27-04:00 Fix wording in documentation The duplicate "orphan instance" phrase here doesn't make sense, and was probably an accident. - - - - - 0bcf3237 by Takenobu Tani at 2020-05-31T10:15:53-04:00 configure: Modify aclocal.m4 according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * Rename: * compiler/GHC/Parser.hs <= compiler/parser/Parser.hs * compiler/GHC/Parser/Lexer.hs <= compiler/Parser/Lexer.hs * Add: * compiler/GHC/Cmm/Lexer.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular - - - - - 268d9b56 by Ben Gamari at 2020-05-31T10:15:53-04:00 testsuite: Don't fail if we can't unlink __symlink_test Afterall, it's possible we were unable to create it due to lack of symlink permission. - - - - - 495c1593 by Ben Gamari at 2020-05-31T10:15:53-04:00 testsuite: Refactor ghostscript detection Tamar reported that he saw crashes due to unhandled exceptions. - - - - - 06cf3101 by Ben Gamari at 2020-05-31T10:15:53-04:00 testsuite/perf_notes: Fix ill-typed assignments - - - - - 118de0ff by Ben Gamari at 2020-05-31T10:15:53-04:00 testsuite/testutil: Fix bytes/str mismatch - - - - - 087704db by Ben Gamari at 2020-05-31T10:15:53-04:00 testsuite: Work around spurious mypy failure - - - - - 0536fe91 by Takenobu Tani at 2020-05-31T10:15:55-04:00 Clean up file paths for new module hierarchy This updates comments only. This patch replaces file references according to new module hierarchy. See also: * https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular * https://gitlab.haskell.org/ghc/ghc/issues/13009 - - - - - 999c1f83 by Takenobu Tani at 2020-05-31T10:15:55-04:00 Modify file paths to module paths for new module hierarchy This updates comments only. This patch replaces module references according to new module hierarchy [1][2]. For files under the `compiler/` directory, I replace them as module paths instead of file paths. For instance, `GHC.Unit.State` instead of `compiler/GHC/Unit/State.hs` [3]. For current and future haddock's markup, this patch encloses the module name with "" [4]. [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: https://gitlab.haskell.org/ghc/ghc/issues/13009 [3]: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/3375#note_276613 [4]: https://haskell-haddock.readthedocs.io/en/latest/markup.html#linking-to-modules - - - - - 4b335c4f by Sylvain Henry at 2020-05-31T10:16:16-04:00 Hadrian: fix binary-dist target for cross-compilation - - - - - 3aeae2c1 by Vladislav Zavialov at 2020-05-31T10:16:16-04:00 Improve parser error messages for the @-operator Since GHC diverges from the Haskell Report by allowing the user to define (@) as an infix operator, we better give a good error message when the user does so unintentionally. In general, this is rather hard to do, as some failures will be discovered only in the renamer or the type checker: x :: (Integer, Integer) x @ (a, b) = (1, 2) This patch does *not* address this general case. However, it gives much better error messages when the binding is not syntactically valid: pairs xs @ (_:xs') = zip xs xs' Before this patch, the error message was rather puzzling: <interactive>:1:1: error: Parse error in pattern: pairs After this patch, the error message includes a hint: <interactive>:1:1: error: Parse error in pattern: pairs In a function binding for the ‘@’ operator. Perhaps you meant an as-pattern, which must not be surrounded by whitespace - - - - - bb31292c by Vladislav Zavialov at 2020-05-31T10:16:16-04:00 Improve parser error messages for TypeApplications With this patch, we always parse f @t as a type application, thereby producing better error messages. This steals two syntactic forms: * Prefix form of the @-operator in expressions. Since the @-operator is a divergence from the Haskell Report anyway, this is not a major loss. * Prefix form of @-patterns. Since we are stealing loose infix form anyway, might as well sacrifice the prefix form for the sake of much better error messages. - - - - - 6c919f0b by Vladislav Zavialov at 2020-05-31T10:16:17-04:00 Improve parser error messages for TemplateHaskellQuotes While [e| |], [t| |], [d| |], and so on, steal syntax from list comprehensions, [| |] and [|| ||] do not steal any syntax. Thus we can improve error messages by always accepting them in the lexer. Turns out the renamer already performs necessary validation. - - - - - 5ce86de8 by John Ericson at 2020-05-31T10:39:29-04:00 Clean up boot vs non-boot disambiguating types We often have (ModuleName, Bool) or (Module, Bool) pairs for "extended" module names (without or with a unit id) disambiguating boot and normal modules. We think this is important enough across the compiler that it deserves a new nominal product type. We do this with synnoyms and a functor named with a `Gen` prefix, matching other newly created definitions. It was also requested that we keep custom `IsBoot` / `NotBoot` sum type. So we have it too. This means changing many the many bools to use that instead. Updates `haddock` submodule. - - - - - 9ed36e7b by Simon Peyton Jones at 2020-05-31T10:39:40-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 Updates Cabal submodule. Metric Increase: T12150 Metric Decrease: haddock.Cabal haddock.base - - - - - a7a36da8 by Ben Gamari at 2020-05-31T11:15:21-04:00 base: Bump to 4.15.0.0 - - - - - 30 changed files: - aclocal.m4 - compiler/GHC.hs - compiler/GHC/Builtin/Names.hs - compiler/GHC/Builtin/Types.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/PPC/Ppr.hs - compiler/GHC/CmmToAsm/SPARC/Base.hs - compiler/GHC/Core/Coercion.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Type.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Driver/Backpack.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/Driver/Make.hs - compiler/GHC/Driver/MakeFile.hs - compiler/GHC/Driver/Types.hs - compiler/GHC/Hs/Binds.hs - compiler/GHC/Hs/ImpExp.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/HsToCore/Binds.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/Monad.hs - compiler/GHC/HsToCore/PmCheck.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/HsToCore/PmCheck/Types.hs The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3a81e8fb4a5d243ce443410906dda768a1f66e70...a7a36da8c1943a580f8eb7517b220fba5cd5daa3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3a81e8fb4a5d243ce443410906dda768a1f66e70...a7a36da8c1943a580f8eb7517b220fba5cd5daa3 You're receiving 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 31 15:17:17 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 31 May 2020 11:17:17 -0400 Subject: [Git][ghc/ghc][wip/bump-base] base: Bump to 4.15.0.0 Message-ID: <5ed3ca7d1ac3f_6e263f9ed4149c4c32249e6@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/bump-base at Glasgow Haskell Compiler / GHC Commits: a79d4891 by Ben Gamari at 2020-05-31T11:17:09-04:00 base: Bump to 4.15.0.0 - - - - - 30 changed files: - compiler/ghc.cabal.in - libraries/array - libraries/base/base.cabal - libraries/deepseq - libraries/directory - libraries/filepath - libraries/ghc-boot-th/ghc-boot-th.cabal.in - libraries/ghc-boot/ghc-boot.cabal.in - libraries/ghc-compact/ghc-compact.cabal - libraries/ghci/ghci.cabal.in - libraries/haskeline - libraries/hpc - libraries/parsec - libraries/process - libraries/stm - libraries/template-haskell/template-haskell.cabal.in - libraries/terminfo - libraries/unix - testsuite/tests/dependent/should_compile/T14729.stderr - testsuite/tests/dependent/should_compile/T15743.stderr - testsuite/tests/dependent/should_compile/T15743e.stderr - testsuite/tests/indexed-types/should_compile/T15711.stderr - testsuite/tests/indexed-types/should_compile/T15852.stderr - testsuite/tests/polykinds/T15592.stderr - testsuite/tests/polykinds/T15592b.stderr - testsuite/tests/printer/T18052a.stderr - testsuite/tests/typecheck/should_compile/T12763.stderr - testsuite/tests/typecheck/should_compile/subsumption_sort_hole_fits.stderr - utils/haddock - utils/hsc2hs Changes: ===================================== compiler/ghc.cabal.in ===================================== @@ -59,7 +59,7 @@ Library Default-Language: Haskell2010 Exposed: False - Build-Depends: base >= 4.11 && < 4.15, + Build-Depends: base >= 4.11 && < 4.16, deepseq >= 1.4 && < 1.5, directory >= 1 && < 1.4, process >= 1 && < 1.7, ===================================== libraries/array ===================================== @@ -1 +1 @@ -Subproject commit f73f681e52546b1e35cb9e8a62fe49c33f259d98 +Subproject commit ab535173d7885ebfc2005d8da2765f0f52c923ce ===================================== 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 ===================================== libraries/deepseq ===================================== @@ -1 +1 @@ -Subproject commit da0eda33f540786b6823c6f542ab59cf9d1b71d9 +Subproject commit 13c1c84415da727ab56e9fa33aca5046b6683848 ===================================== libraries/directory ===================================== @@ -1 +1 @@ -Subproject commit 36bd1921258b759724a95ce56c5e880edf0972a2 +Subproject commit 3d9ca6edc0703860829ab3210db78bb4c4ff72b9 ===================================== libraries/filepath ===================================== @@ -1 +1 @@ -Subproject commit 023eedaeb142d47b7b5a41fe4cc4150da0bd0042 +Subproject commit 9088df9f97914664c9360857347d65c32dd6c892 ===================================== libraries/ghc-boot-th/ghc-boot-th.cabal.in ===================================== @@ -36,4 +36,4 @@ Library GHC.ForeignSrcLang.Type GHC.Lexeme - build-depends: base >= 4.7 && < 4.15 + build-depends: base >= 4.7 && < 4.16 ===================================== libraries/ghc-boot/ghc-boot.cabal.in ===================================== @@ -55,7 +55,7 @@ Library -- GHC.Version -- GHC.Platform.Host - build-depends: base >= 4.7 && < 4.15, + build-depends: base >= 4.7 && < 4.16, binary == 0.8.*, bytestring == 0.10.*, containers >= 0.5 && < 0.7, ===================================== libraries/ghc-compact/ghc-compact.cabal ===================================== @@ -37,7 +37,7 @@ library CPP build-depends: ghc-prim >= 0.5.3 && < 0.7, - base >= 4.9.0 && < 4.15, + base >= 4.9.0 && < 4.16, bytestring >= 0.10.6.0 ghc-options: -Wall ===================================== libraries/ghci/ghci.cabal.in ===================================== @@ -72,7 +72,7 @@ library Build-Depends: array == 0.5.*, - base >= 4.8 && < 4.15, + base >= 4.8 && < 4.16, binary == 0.8.*, bytestring == 0.10.*, containers >= 0.5 && < 0.7, ===================================== libraries/haskeline ===================================== @@ -1 +1 @@ -Subproject commit 3d3e7c18a44fa904f004e5eac0e666e396f1b3f4 +Subproject commit d3885e4bc1dfe6b06829871361bf9330414fc9e2 ===================================== libraries/hpc ===================================== @@ -1 +1 @@ -Subproject commit f73c482db30a40cfa12074de51335b70a0974931 +Subproject commit 772de3f7b43e31178f042ba77c071594845363e3 ===================================== libraries/parsec ===================================== @@ -1 +1 @@ -Subproject commit ce416997e15438ca616667995660e123ef7e219d +Subproject commit 190492494fe92e8dd42165190b7ac112be1f7389 ===================================== libraries/process ===================================== @@ -1 +1 @@ -Subproject commit 1afc36ecd38c069251a836e1c1c8b3a3043ddc01 +Subproject commit 8f4ecebb6578a179a6c04074cb06600683e2e50c ===================================== libraries/stm ===================================== @@ -1 +1 @@ -Subproject commit faf9904137044e35a589c7c1579e1bfa03789c84 +Subproject commit 444f672416a354c3cfde9d94ec237a36be46ef59 ===================================== libraries/template-haskell/template-haskell.cabal.in ===================================== @@ -55,7 +55,7 @@ Library Language.Haskell.TH.Lib.Map build-depends: - base >= 4.11 && < 4.15, + base >= 4.11 && < 4.16, ghc-boot-th == @ProjectVersionMunged@, ghc-prim, pretty == 1.1.* ===================================== libraries/terminfo ===================================== @@ -1 +1 @@ -Subproject commit 27e694688d2d6eee69959a8b6a128c584c84aa72 +Subproject commit 3ebb36f4a2c42b74ec4e35efccc2be34c198a830 ===================================== libraries/unix ===================================== @@ -1 +1 @@ -Subproject commit 1a993b89c570e03ba74f196f5d065a0ebe624010 +Subproject commit ea13d990580273a883368793dfbb826cab5a22d4 ===================================== testsuite/tests/dependent/should_compile/T14729.stderr ===================================== @@ -11,5 +11,5 @@ COERCION AXIOMS FAMILY INSTANCES type instance F Int = Bool -- Defined at T14729.hs:10:15 Dependent modules: [] -Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, - integer-gmp-1.0.2.0] +Dependent packages: [base-4.15.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] ===================================== testsuite/tests/dependent/should_compile/T15743.stderr ===================================== @@ -3,5 +3,5 @@ TYPE CONSTRUCTORS forall {k1} k2 (k3 :: k2). Proxy k3 -> k1 -> k2 -> * roles nominal nominal nominal phantom phantom phantom Dependent modules: [] -Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, - integer-gmp-1.0.2.0] +Dependent packages: [base-4.15.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] ===================================== testsuite/tests/dependent/should_compile/T15743e.stderr ===================================== @@ -52,5 +52,5 @@ DATA CONSTRUCTORS (d :: Proxy k5) (e :: Proxy k7). f c -> T k8 a b f c d e Dependent modules: [] -Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, - integer-gmp-1.0.2.0] +Dependent packages: [base-4.15.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] ===================================== testsuite/tests/indexed-types/should_compile/T15711.stderr ===================================== @@ -3,5 +3,5 @@ TYPE CONSTRUCTORS associated type family F{2} :: forall a. Maybe a -> * roles nominal nominal Dependent modules: [] -Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, - integer-gmp-1.0.2.0] +Dependent packages: [base-4.15.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] ===================================== testsuite/tests/indexed-types/should_compile/T15852.stderr ===================================== @@ -9,5 +9,5 @@ FAMILY INSTANCES data instance forall {k1} {k2} {j :: k1} {c :: k2}. DF (Proxy c) -- Defined at T15852.hs:10:15 Dependent modules: [] -Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, - integer-gmp-1.0.2.0] +Dependent packages: [base-4.15.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] ===================================== testsuite/tests/polykinds/T15592.stderr ===================================== @@ -5,5 +5,5 @@ DATA CONSTRUCTORS MkT :: forall {k} k1 (f :: k1 -> k -> *) (a :: k1) (b :: k). f a b -> T f a b -> T f a b Dependent modules: [] -Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, - integer-gmp-1.0.2.0] +Dependent packages: [base-4.15.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] ===================================== testsuite/tests/polykinds/T15592b.stderr ===================================== @@ -4,5 +4,5 @@ TYPE CONSTRUCTORS forall k (f :: k -> *) (a :: k). f a -> * roles nominal nominal nominal nominal Dependent modules: [] -Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, - integer-gmp-1.0.2.0] +Dependent packages: [base-4.15.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] ===================================== testsuite/tests/printer/T18052a.stderr ===================================== @@ -6,7 +6,7 @@ TYPE CONSTRUCTORS PATTERN SYNONYMS (:||:) :: forall {a} {b}. a -> b -> (a, b) Dependent modules: [] -Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, +Dependent packages: [base-4.15.0.0, ghc-prim-0.6.1, integer-gmp-1.0.3.0] ==================== Tidy Core ==================== ===================================== testsuite/tests/typecheck/should_compile/T12763.stderr ===================================== @@ -8,5 +8,5 @@ COERCION AXIOMS CLASS INSTANCES instance C Int -- Defined at T12763.hs:9:10 Dependent modules: [] -Dependent packages: [base-4.14.0.0, ghc-prim-0.6.1, - integer-gmp-1.0.2.0] +Dependent packages: [base-4.15.0.0, ghc-prim-0.6.1, + integer-gmp-1.0.3.0] ===================================== testsuite/tests/typecheck/should_compile/subsumption_sort_hole_fits.stderr ===================================== @@ -9,10 +9,10 @@ subsumption_sort_hole_fits.hs:2:5: warning: [-Wtyped-holes (in -Wdefault)] Valid hole fits include lines :: String -> [String] (imported from ‘Prelude’ at subsumption_sort_hole_fits.hs:1:1 - (and originally defined in ‘base-4.14.0.0:Data.OldList’)) + (and originally defined in ‘base-4.15.0.0:Data.OldList’)) words :: String -> [String] (imported from ‘Prelude’ at subsumption_sort_hole_fits.hs:1:1 - (and originally defined in ‘base-4.14.0.0:Data.OldList’)) + (and originally defined in ‘base-4.15.0.0:Data.OldList’)) read :: forall a. Read a => String -> a with read @[String] (imported from ‘Prelude’ at subsumption_sort_hole_fits.hs:1:1 ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 60c85324ae083e2ac3d6180c0f20db5cdb31168b +Subproject commit 7475d84fa8d3a764dd8b54f8513f21170103f976 ===================================== utils/hsc2hs ===================================== @@ -1 +1 @@ -Subproject commit 24100ea521596922d3edc8370b3d9f7b845ae4cf +Subproject commit e792dd8e5589d42a4d416f78df8efb70995f95e3 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a79d489188976438dc9fa7771a0afad9b2485bc5 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/a79d489188976438dc9fa7771a0afad9b2485bc5 You're receiving 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 31 15:24:34 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Sun, 31 May 2020 11:24:34 -0400 Subject: [Git][ghc/ghc][wip/simply-bind-tyvars] Use "rewrite rule" instead of "transformation rule" consistently Message-ID: <5ed3cc326fd30_6e263f9ee42e45b032254b7@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/simply-bind-tyvars at Glasgow Haskell Compiler / GHC Commits: 0e30ccaf by Ryan Scott at 2020-05-31T11:22:31-04:00 Use "rewrite rule" instead of "transformation rule" consistently - - - - - 15 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Driver/Types.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/HsToCore.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Utils.hs - compiler/GHC/Tc/Gen/Rule.hs - testsuite/tests/dependent/should_fail/T16326_Fail10.stderr - testsuite/tests/rename/should_compile/ExplicitForAllRules1.stderr - testsuite/tests/safeHaskell/ghci/p14.stderr - testsuite/tests/typecheck/should_compile/T10072.stderr - testsuite/tests/typecheck/should_fail/T5853.stderr Changes: ===================================== compiler/GHC/Core.hs ===================================== @@ -1291,7 +1291,7 @@ Orphan-hood is computed {- ************************************************************************ * * -\subsection{Transformation rules} +\subsection{Rewrite rules} * * ************************************************************************ ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -467,7 +467,7 @@ lintCoreBindings dflags pass local_in_scope binds where all_pairs = flattenBinds binds -- Put all the top-level binders in scope at the start - -- This is because transformation rules can bring something + -- This is because rewrite rules can bring something -- into use 'unexpectedly'; see Note [Glomming] in OccurAnal binders = map fst all_pairs ===================================== compiler/GHC/Core/Opt/Simplify.hs ===================================== @@ -170,7 +170,7 @@ simplTopBinds :: SimplEnv -> [InBind] -> SimplM (SimplFloats, SimplEnv) -- See Note [The big picture] simplTopBinds env0 binds0 = do { -- Put all the top-level binders into scope at the start - -- so that if a transformation rule has unexpectedly brought + -- so that if a rewrite rule has unexpectedly brought -- anything into scope, then we don't get a complaint about that. -- It's rather as if the top-level binders were imported. -- See note [Glomming] in OccurAnal. ===================================== compiler/GHC/Core/Rules.hs ===================================== @@ -1,7 +1,7 @@ {- (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 -\section[CoreRules]{Transformation rules} +\section[CoreRules]{Rewrite rules} -} {-# LANGUAGE CPP #-} ===================================== compiler/GHC/Driver/Types.hs ===================================== @@ -2486,7 +2486,7 @@ lookupFixity env n = case lookupNameEnv env n of -- * An instance declaration in a module other than the definition -- module for one of the type constructors or classes in the instance head -- --- * A transformation rule in a module other than the one defining +-- * A rewrite rule in a module other than the one defining -- the function in the head of the rule -- type WhetherHasOrphans = Bool ===================================== compiler/GHC/Hs/Decls.hs ===================================== @@ -2184,7 +2184,7 @@ instance Outputable ForeignExport where {- ************************************************************************ * * -\subsection{Transformation rules} +\subsection{Rewrite rules} * * ************************************************************************ -} ===================================== compiler/GHC/HsToCore.hs ===================================== @@ -354,7 +354,7 @@ to the binders in the top-level bindings Reason - It makes the rules easier to look up - - It means that transformation rules and specialisations for + - It means that rewrite rules and specialisations for locally defined Ids are handled uniformly - It keeps alive things that are referred to only from a rule (the occurrence analyser knows about rules attached to Ids) @@ -368,7 +368,7 @@ Reason ************************************************************************ * * -* Desugaring transformation rules +* Desugaring rewrite rules * * ************************************************************************ -} ===================================== compiler/GHC/Rename/Module.hs ===================================== @@ -1068,7 +1068,7 @@ bindRuleTyVars _ _ thing_inside = thing_inside Nothing {- Note [Rule LHS validity checking] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Check the shape of a transformation rule LHS. Currently we only allow +Check the shape of a rewrite rule LHS. Currently we only allow LHSs of the form @(f e1 .. en)@, where @f@ is not one of the @forall@'d variables. ===================================== compiler/GHC/Rename/Utils.hs ===================================== @@ -495,7 +495,7 @@ pprHsDocContext PatCtx = text "a pattern type-signature" pprHsDocContext SpecInstSigCtx = text "a SPECIALISE instance pragma" pprHsDocContext DefaultDeclCtx = text "a `default' declaration" pprHsDocContext DerivDeclCtx = text "a deriving declaration" -pprHsDocContext (RuleCtx name) = text "the transformation rule" <+> ftext name +pprHsDocContext (RuleCtx name) = text "the rewrite rule" <+> doubleQuotes (ftext name) pprHsDocContext (TyDataCtx tycon) = text "the data type declaration for" <+> quotes (ppr tycon) pprHsDocContext (FamPatCtx tycon) = text "a type pattern of family instance for" <+> quotes (ppr tycon) pprHsDocContext (TySynCtx name) = text "the declaration for type synonym" <+> quotes (ppr name) ===================================== compiler/GHC/Tc/Gen/Rule.hs ===================================== @@ -7,7 +7,7 @@ {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE TypeFamilies #-} --- | Typechecking transformation rules +-- | Typechecking rewrite rules module GHC.Tc.Gen.Rule ( tcRules ) where import GHC.Prelude @@ -239,7 +239,7 @@ tcRuleTmBndrs (L _ (RuleBndrSig _ (L _ name) rn_ty) : rule_bndrs) ; return (map snd tvs ++ tyvars, id : tmvars) } ruleCtxt :: FastString -> SDoc -ruleCtxt name = text "When checking the transformation rule" <+> +ruleCtxt name = text "When checking the rewrite rule" <+> doubleQuotes (ftext name) ===================================== testsuite/tests/dependent/should_fail/T16326_Fail10.stderr ===================================== @@ -4,4 +4,4 @@ T16326_Fail10.hs:12:18: error: forall a -> a -> a (GHC does not yet support this) • In a RULE for ‘x’: forall a -> a -> a - When checking the transformation rule "flurmp" + When checking the rewrite rule "flurmp" ===================================== testsuite/tests/rename/should_compile/ExplicitForAllRules1.stderr ===================================== @@ -1,4 +1,4 @@ ExplicitForAllRules1.hs:49:31: warning: [-Wunused-foralls (in -Wextra)] Unused quantified type variable ‘b’ - In the transformation rule example7 + In the rewrite rule "example7" ===================================== testsuite/tests/safeHaskell/ghci/p14.stderr ===================================== @@ -1,6 +1,6 @@ :9:25: error: - No instance for (Num a) arising from a use of ‘f’ - Possible fix: add (Num a) to the context of the RULE "id/Int" - In the expression: f - When checking the transformation rule "id/Int" + • No instance for (Num a) arising from a use of ‘f’ + Possible fix: add (Num a) to the context of the RULE "id/Int" + • In the expression: f + When checking the rewrite rule "id/Int" ===================================== testsuite/tests/typecheck/should_compile/T10072.stderr ===================================== @@ -7,4 +7,4 @@ T10072.hs:3:31: error: To use the inferred type, enable PartialTypeSignatures • In the type ‘a -> _’ In a RULE for ‘f’: a -> _ - When checking the transformation rule "map/empty" + When checking the rewrite rule "map/empty" ===================================== testsuite/tests/typecheck/should_fail/T5853.stderr ===================================== @@ -9,7 +9,7 @@ T5853.hs:15:52: error: bound by the RULE "map/map" at T5853.hs:15:2-57 NB: ‘Subst’ is a non-injective type family • In the expression: (f . g) <$> xs - When checking the transformation rule "map/map" + When checking the rewrite rule "map/map" • Relevant bindings include f :: Elem fa -> b (bound at T5853.hs:15:19) g :: a -> Elem fa (bound at T5853.hs:15:21) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0e30ccaf1babce0ac7797252a004820ea95c803c -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/0e30ccaf1babce0ac7797252a004820ea95c803c You're receiving 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 31 15:47:56 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Sun, 31 May 2020 11:47:56 -0400 Subject: [Git][ghc/ghc][wip/T18191] Make GADT constructors adhere to the forall-or-nothing rule properly Message-ID: <5ed3d1acc881f_6e263f9ed4149c4c32308a5@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/T18191 at Glasgow Haskell Compiler / GHC Commits: 7b89ce1c by Ryan Scott at 2020-05-31T11:47:37-04:00 Make GADT constructors adhere to the forall-or-nothing rule properly Issue #18191 revealed that the types of GADT constructors don't quite adhere to the `forall`-or-nothing rule. This patch serves to clean up this sad state of affairs somewhat. The main change is not in the code itself, but in the documentation, as this patch introduces two sections to the GHC User's Guide: * A "Formal syntax for GADTs" section that presents a BNF-style grammar for what is and isn't allowed in GADT constructor types. This mostly exists to codify GHC's existing behavior, but it also imposes a new restriction that addresses #18191: the outermost `forall` and/or context in a GADT constructor is not allowed to be surrounded by parentheses. Doing so would make these `forall`s/contexts nested, and GADTs do not support nested `forall`s/contexts at present. * A "`forall`-or-nothing rule" section that describes exactly what the `forall`-or-nothing rule is all about. Surprisingly, there was no mention of this anywhere in the User's Guide up until now! To adhere the new specification in the "Formal syntax for GADTs" section of the User's Guide, the following code changes were made: * A new function, `GHC.Hs.Type.splitLHsGADTPrefixTy`, was introduced. This is very much like `splitLHsSigmaTy`, except that it avoids splitting apart any parentheses, which can be syntactically significant for GADT types. See `Note [No nested foralls or contexts in GADT constructors]` in `GHC.Hs.Type`. * `ConDeclGADTPrefixPs`, an extension constructor for `XConDecl`, was introduced so that `GHC.Parser.PostProcess.mkGadtDecl` can return it when given a prefix GADT constructor. Unlike `ConDeclGADT`, `ConDeclGADTPrefixPs` does not split the GADT type into its argument and result types, as this cannot be done until after the type is renamed (see `Note [GADT abstract syntax]` in `GHC.Hs.Decls` for why this is the case). * `GHC.Renamer.Module.rnConDecl` now has an additional case for `ConDeclGADTPrefixPs` that (1) splits apart the full `LHsType` into its `forall`s, context, argument types, and result type, and (2) checks for nested `forall`s/contexts. Step (2) used to be performed the typechecker (in `GHC.Tc.TyCl.badDataConTyCon`) rather than the renamer, but now the relevant code from the typechecker can simply be deleted. One nice side effect of this change is that we are able to give a more accurate error message for GADT constructors that use visible dependent quantification (e.g., `MkFoo :: forall a -> a -> Foo a`), which improves the stderr in the `T16326_Fail6` test case. Fixes #18191. Bumps the Haddock submodule. - - - - - 27 changed files: - compiler/GHC/Hs/Decls.hs - compiler/GHC/Hs/Instances.hs - compiler/GHC/Hs/Type.hs - compiler/GHC/Hs/Utils.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Parser/PostProcess/Haddock.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Tc/TyCl.hs - compiler/GHC/ThToHs.hs - docs/users_guide/8.12.1-notes.rst - docs/users_guide/exts/explicit_forall.rst - docs/users_guide/exts/gadt_syntax.rst - testsuite/tests/dependent/should_fail/T16326_Fail6.stderr - testsuite/tests/gadt/T12087.stderr - testsuite/tests/gadt/T14320.hs - + testsuite/tests/gadt/T14320.stderr - testsuite/tests/gadt/T16427.stderr - + testsuite/tests/gadt/T18191.hs - + testsuite/tests/gadt/T18191.stderr - testsuite/tests/gadt/all.T - testsuite/tests/ghc-api/annotations/T10399.stdout - testsuite/tests/ghc-api/annotations/Test10399.hs - testsuite/tests/parser/should_compile/T15323.hs - testsuite/tests/parser/should_compile/T15323.stderr - testsuite/tests/rename/should_compile/T5331.stderr - utils/haddock Changes: ===================================== compiler/GHC/Hs/Decls.hs ===================================== @@ -5,6 +5,7 @@ {-# LANGUAGE DeriveDataTypeable, DeriveFunctor, DeriveFoldable, DeriveTraversable #-} +{-# LANGUAGE CPP #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} @@ -70,7 +71,7 @@ module GHC.Hs.Decls ( ForeignDecl(..), LForeignDecl, ForeignImport(..), ForeignExport(..), CImportSpec(..), -- ** Data-constructor declarations - ConDecl(..), LConDecl, + ConDecl(..), LConDecl, ConDeclGADTPrefixPs(..), HsConDeclDetails, hsConDeclArgTys, hsConDeclTheta, getConNames, getConArgs, -- ** Document comments @@ -109,6 +110,7 @@ import GHC.Core.Coercion import GHC.Types.ForeignCall import GHC.Hs.Extension import GHC.Types.Name +import GHC.Types.Name.Reader import GHC.Types.Name.Set -- others: @@ -1422,54 +1424,92 @@ type instance XConDeclGADT GhcRn = [Name] -- Implicitly bound type variables type instance XConDeclGADT GhcTc = NoExtField type instance XConDeclH98 (GhcPass _) = NoExtField -type instance XXConDecl (GhcPass _) = NoExtCon + +type instance XXConDecl GhcPs = ConDeclGADTPrefixPs +type instance XXConDecl GhcRn = NoExtCon +type instance XXConDecl GhcTc = NoExtCon + +-- | Stores the types of prefix GADT constructors in the parser. This is used +-- in lieu of ConDeclGADT, which requires knowing the specific argument and +-- result types, as this is difficult to determine in general in the parser. +-- See @Note [GADT abstract syntax]@. +data ConDeclGADTPrefixPs = ConDeclGADTPrefixPs + { con_gp_names :: [Located RdrName] + -- ^ The GADT constructor declaration's names. + , con_gp_ty :: LHsSigType GhcPs + -- ^ The type after the @::@. + , con_gp_doc :: Maybe LHsDocString + -- ^ A possible Haddock comment. + } {- Note [GADT abstract syntax] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -There's a wrinkle in ConDeclGADT - -* For record syntax, it's all uniform. Given: - data T a where - K :: forall a. Ord a => { x :: [a], ... } -> T a - we make the a ConDeclGADT for K with - con_qvars = {a} - con_mb_cxt = Just [Ord a] - con_args = RecCon - con_res_ty = T a - - We need the RecCon before the reanmer, so we can find the record field - binders in GHC.Hs.Utils.hsConDeclsBinders. - -* However for a GADT constr declaration which is not a record, it can - be hard parse until we know operator fixities. Consider for example - C :: a :*: b -> a :*: b -> a :+: b - Initially this type will parse as - a :*: (b -> (a :*: (b -> (a :+: b)))) - so it's hard to split up the arguments until we've done the precedence - resolution (in the renamer). - - So: - In the parser (GHC.Parser.PostProcess.mkGadtDecl), we put the whole constr - type into the res_ty for a ConDeclGADT for now, and use - PrefixCon [] - con_args = PrefixCon [] - con_res_ty = a :*: (b -> (a :*: (b -> (a :+: b)))) - - - In the renamer (GHC.Rename.Module.rnConDecl), we unravel it after - operator fixities are sorted. So we generate. So we end - up with - con_args = PrefixCon [ a :*: b, a :*: b ] - con_res_ty = a :+: b +There are two broad ways to classify GADT constructors: + +* Record-syntax constructors. For example: + + data T a where + K :: forall a. Ord a => { x :: [a], ... } -> T a + +* Prefix constructors, which do not use record syntax. For example: + + data T a where + K :: forall a. Ord a => [a] -> ... -> T a + +Initially, both forms of GADT constructors are initially parsed as a single +LHsType. However, GADTs have a certain structure, requiring distinct argument +and result types, as well as imposing restrictions on where `forall`s and +contexts can be (see Note [No nested foralls or contexts in GADT constructors] +in GHC.Hs.Type). As a result, it is convenient to split up the LHsType into +its individual components, which are stored in the ConDeclGADT constructor of +ConDecl. + +Where should this splitting occur? For GADT constructors with record syntax, +we split in the parser (in GHC.Parser.PostProcess.mkGadtDecl). We must do this +splitting before the renamer, as we need the record field names for use in +GHC.Hs.Utils.hsConDeclsBinders. + +For prefix GADT constructors, however, the situation is more complicated. It +can be difficult to split a prefix GADT type until we know type operator +fixities. Consider this, for example: + + C :: a :*: b -> a :*: b -> a :+: b + +Initially, the type of C will parse as: + + a :*: (b -> (a :*: (b -> (a :+: b)))) + +So it's hard to split up the arguments until we've done the precedence +resolution (in the renamer). (Unlike prefix GADT types, record GADT types +do not have this problem because of their uniform syntax.) + +As a result, we deliberately avoid splitting prefix GADT types in the parser. +Instead, we store the entire LHsType in ConDeclGADTPrefixPs, a GHC-specific +extension constructor to ConDecl. Later, in the renamer +(in GHC.Rename.Module.rnConDecl), we resolve the fixities of all type operators +in the LHsType, which facilitates splitting it into argument and result types +accurately. We finish renaming a ConDeclGADTPrefixPs by putting the split +components into a ConDeclGADT. This is why ConDeclGADTPrefixPs has the suffix +-Ps, as it is only used by the parser. + +Note that the existence of ConDeclGADTPrefixPs does not imply that ConDeclGADT +goes completely unused by the parser. Other consumers of GHC's abstract syntax +are still free to use ConDeclGADT. Indeed, both Haddock and Template Haskell +construct values of type `ConDecl GhcPs` by way of ConDeclGADT, as neither of +them have the same difficulties with operator precedence that GHC's parser +does. As an example, see GHC.ThToHs.cvtConstr, which converts Template Haskell +syntax into GHC syntax. -} -- | Haskell data Constructor Declaration Details type HsConDeclDetails pass = HsConDetails (LBangType pass) (Located [LConDeclField pass]) -getConNames :: ConDecl (GhcPass p) -> [Located (IdP (GhcPass p))] +getConNames :: ConDecl GhcRn -> [Located Name] getConNames ConDeclH98 {con_name = name} = [name] getConNames ConDeclGADT {con_names = names} = names -getConArgs :: ConDecl pass -> HsConDeclDetails pass +getConArgs :: ConDecl GhcRn -> HsConDeclDetails GhcRn getConArgs d = con_args d hsConDeclArgTys :: HsConDeclDetails pass -> [LBangType pass] @@ -1518,16 +1558,30 @@ instance Outputable NewOrData where ppr NewType = text "newtype" ppr DataType = text "data" -pp_condecls :: (OutputableBndrId p) => [LConDecl (GhcPass p)] -> SDoc -pp_condecls cs@(L _ ConDeclGADT{} : _) -- In GADT syntax +pp_condecls :: forall p. OutputableBndrId p => [LConDecl (GhcPass p)] -> SDoc +pp_condecls cs + | gadt_syntax -- In GADT syntax = hang (text "where") 2 (vcat (map ppr cs)) -pp_condecls cs -- In H98 syntax + | otherwise -- In H98 syntax = equals <+> sep (punctuate (text " |") (map ppr cs)) + where + gadt_syntax = case cs of + [] -> False + (L _ ConDeclH98{} : _) -> False + (L _ ConDeclGADT{} : _) -> True + (L _ (XConDecl x) : _) -> + case ghcPass @p of + GhcPs | ConDeclGADTPrefixPs{} <- x + -> True +#if __GLASGOW_HASKELL__ < 811 + GhcRn -> noExtCon x + GhcTc -> noExtCon x +#endif instance (OutputableBndrId p) => Outputable (ConDecl (GhcPass p)) where ppr = pprConDecl -pprConDecl :: (OutputableBndrId p) => ConDecl (GhcPass p) -> SDoc +pprConDecl :: forall p. OutputableBndrId p => ConDecl (GhcPass p) -> SDoc pprConDecl (ConDeclH98 { con_name = L _ con , con_ex_tvs = ex_tvs , con_mb_cxt = mcxt @@ -1558,6 +1612,16 @@ pprConDecl (ConDeclGADT { con_names = cons, con_qvars = qvars ppr_arrow_chain (a:as) = sep (a : map (arrow <+>) as) ppr_arrow_chain [] = empty +pprConDecl (XConDecl x) = + case ghcPass @p of + GhcPs | ConDeclGADTPrefixPs { con_gp_names = cons, con_gp_ty = ty + , con_gp_doc = doc } <- x + -> ppr_mbDoc doc <+> ppr_con_names cons <+> dcolon <+> ppr ty +#if __GLASGOW_HASKELL__ < 811 + GhcRn -> noExtCon x + GhcTc -> noExtCon x +#endif + ppr_con_names :: (OutputableBndr a) => [Located a] -> SDoc ppr_con_names = pprWithCommas (pprPrefixOcc . unLoc) ===================================== compiler/GHC/Hs/Instances.hs ===================================== @@ -159,6 +159,8 @@ deriving instance Data (ConDecl GhcPs) deriving instance Data (ConDecl GhcRn) deriving instance Data (ConDecl GhcTc) +deriving instance Data ConDeclGADTPrefixPs + -- deriving instance DataIdLR p p => Data (TyFamInstDecl p) deriving instance Data (TyFamInstDecl GhcPs) deriving instance Data (TyFamInstDecl GhcRn) ===================================== compiler/GHC/Hs/Type.hs ===================================== @@ -58,7 +58,8 @@ module GHC.Hs.Type ( hsLTyVarName, hsLTyVarNames, hsLTyVarLocName, hsExplicitLTyVarNames, splitLHsInstDeclTy, getLHsInstDeclHead, getLHsInstDeclClass_maybe, splitLHsPatSynTy, - splitLHsForAllTyInvis, splitLHsQualTy, splitLHsSigmaTyInvis, + splitLHsForAllTyInvis, splitLHsQualTy, + splitLHsSigmaTyInvis, splitLHsGADTPrefixTy, splitHsFunType, hsTyGetAppHead_maybe, mkHsOpTy, mkHsAppTy, mkHsAppTys, mkHsAppKindTy, ignoreParens, hsSigType, hsSigWcType, hsPatSigType, @@ -1347,6 +1348,85 @@ splitLHsSigmaTyInvis ty , (ctxt, ty2) <- splitLHsQualTy ty1 = (tvs, ctxt, ty2) +-- | Decompose a prefix GADT type into its constituent parts. +-- Returns @(mb_tvbs, mb_ctxt, body)@, where: +-- +-- * @mb_tvbs@ are @Just@ the leading @forall at s, if they are provided. +-- Otherwise, they are @Nothing at . +-- +-- * @mb_ctxt@ is @Just@ the context, if it is provided. +-- Otherwise, it is @Nothing at . +-- +-- * @body@ is the body of the type after the optional @forall at s and context. +-- +-- This function is careful not to look through parentheses. +-- See @Note [No nested foralls or contexts in GADT constructors]@ for why this +-- is important. +splitLHsGADTPrefixTy :: + LHsType pass + -> (Maybe [LHsTyVarBndr Specificity pass], Maybe (LHsContext pass), LHsType pass) +splitLHsGADTPrefixTy ty + | (mb_tvbs, rho) <- split_forall ty + , (mb_ctxt, tau) <- split_ctxt rho + = (mb_tvbs, mb_ctxt, tau) + where + -- NB: We do not use splitLHsForAllTyInvis below, since that looks through + -- parentheses... + split_forall (L _ (HsForAllTy { hst_fvf = ForallInvis, hst_bndrs = bndrs + , hst_body = rho })) + = (Just bndrs, rho) + split_forall sigma + = (Nothing, sigma) + + -- ...similarly, we do not use splitLHsQualTy below, since that also looks + -- through parentheses. + split_ctxt (L _ (HsQualTy { hst_ctxt = cxt, hst_body = tau })) + = (Just cxt, tau) + split_ctxt tau + = (Nothing, tau) + +{- +Note [No nested foralls or contexts in GADT constructors] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +GADT constructors provide some freedom to change the order of foralls in their +types (see Note [DataCon user type variable binders] in GHC.Core.DataCon), but +this freedom is still limited. GADTs still require that all quantification +occurs "prenex". That is, any explicitly quantified type variables must occur +at the front of the GADT type, followed by any contexts, followed by the body of +the GADT type, in precisely that order. For instance: + + data T where + MkT1 :: forall a b. (Eq a, Eq b) => a -> b -> T + -- OK + MkT2 :: forall a. Eq a => forall b. a -> b -> T + -- Rejected, `forall b` is nested + MkT3 :: forall a b. Eq a => Eq b => a -> b -> T + -- Rejected, `Eq b` is nested + MkT4 :: Int -> forall a. a -> T + -- Rejected, `forall a` is nested + MkT5 :: forall a. Int -> Eq a => a -> T + -- Rejected, `Eq a` is nested + MkT6 :: (forall a. a -> T) + -- Rejected, `forall a` is nested due to the surrounding parentheses + MkT7 :: (Eq a => a -> t) + -- Rejected, `Eq a` is nested due to the surrounding parentheses + +For the full details, see the "Formal syntax for GADTs" section of the GHC +User's Guide. GHC enforces that GADT constructors do not have nested `forall`s +or contexts in two parts: + +1. The splitLHsGADTPrefixTy function is careful not to remove parentheses + in a prefix GADT constructor's type, as these parentheses can be + syntactically significant. If the third result returned by + splitLHsGADTPrefixTy contains any `forall`s or contexts, then they are + nested. +2. The renamer (in the ConDeclGADTPrefixPs case of GHC.Rename.Module.rnConDecl) + will check for nested `forall`s/contexts in the body of a prefix GADT type, + after it has determined what all of the argument types are. + (See Note [GADT abstract syntax] in GHC.Hs.Decls for why this check must wait + until the renamer.) +-} + -- | Decompose a type of the form @forall . body@ into its constituent -- parts. Only splits type variable binders that -- were quantified invisibly (e.g., @forall a.@, with a dot). ===================================== compiler/GHC/Hs/Utils.hs ===================================== @@ -1242,7 +1242,8 @@ hsTyClForeignBinders tycl_decls foreign_decls getSelectorNames (ns, fs) = map unLoc ns ++ map (extFieldOcc . unLoc) fs ------------------- -hsLTyClDeclBinders :: Located (TyClDecl (GhcPass p)) +hsLTyClDeclBinders :: IsPass p + => Located (TyClDecl (GhcPass p)) -> ([Located (IdP (GhcPass p))], [LFieldOcc (GhcPass p)]) -- ^ Returns all the /binding/ names of the decl. The first one is -- guaranteed to be the name of the decl. The first component @@ -1304,7 +1305,8 @@ getPatSynBinds binds , L _ (PatSynBind _ psb) <- bagToList lbinds ] ------------------- -hsLInstDeclBinders :: LInstDecl (GhcPass p) +hsLInstDeclBinders :: IsPass p + => LInstDecl (GhcPass p) -> ([Located (IdP (GhcPass p))], [LFieldOcc (GhcPass p)]) hsLInstDeclBinders (L _ (ClsInstD { cid_inst = ClsInstDecl @@ -1316,7 +1318,8 @@ hsLInstDeclBinders (L _ (TyFamInstD {})) = mempty ------------------- -- | the 'SrcLoc' returned are for the whole declarations, not just the names -hsDataFamInstBinders :: DataFamInstDecl (GhcPass p) +hsDataFamInstBinders :: IsPass p + => DataFamInstDecl (GhcPass p) -> ([Located (IdP (GhcPass p))], [LFieldOcc (GhcPass p)]) hsDataFamInstBinders (DataFamInstDecl { dfid_eqn = HsIB { hsib_body = FamEqn { feqn_rhs = defn }}}) @@ -1325,7 +1328,8 @@ hsDataFamInstBinders (DataFamInstDecl { dfid_eqn = HsIB { hsib_body = ------------------- -- | the 'SrcLoc' returned are for the whole declarations, not just the names -hsDataDefnBinders :: HsDataDefn (GhcPass p) +hsDataDefnBinders :: IsPass p + => HsDataDefn (GhcPass p) -> ([Located (IdP (GhcPass p))], [LFieldOcc (GhcPass p)]) hsDataDefnBinders (HsDataDefn { dd_cons = cons }) = hsConDeclsBinders cons @@ -1335,7 +1339,8 @@ hsDataDefnBinders (HsDataDefn { dd_cons = cons }) type Seen p = [LFieldOcc (GhcPass p)] -> [LFieldOcc (GhcPass p)] -- Filters out ones that have already been seen -hsConDeclsBinders :: [LConDecl (GhcPass p)] +hsConDeclsBinders :: forall p. IsPass p + => [LConDecl (GhcPass p)] -> ([Located (IdP (GhcPass p))], [LFieldOcc (GhcPass p)]) -- See hsLTyClDeclBinders for what this does -- The function is boringly complicated because of the records @@ -1365,6 +1370,16 @@ hsConDeclsBinders cons (remSeen', flds) = get_flds remSeen args (ns, fs) = go remSeen' rs + XConDecl x -> case ghcPass @p of + GhcPs | ConDeclGADTPrefixPs { con_gp_names = names } <- x + -> (map (L loc . unLoc) names ++ ns, fs) +#if __GLASGOW_HASKELL__ < 811 + GhcRn -> noExtCon x + GhcTc -> noExtCon x +#endif + where + (ns, fs) = go remSeen rs + get_flds :: Seen p -> HsConDeclDetails (GhcPass p) -> (Seen p, [LFieldOcc (GhcPass p)]) get_flds remSeen (RecCon flds) ===================================== compiler/GHC/Parser.y ===================================== @@ -2250,9 +2250,8 @@ gadt_constr :: { LConDecl GhcPs } -- see Note [Difference in parsing GADT and data constructors] -- Returns a list because of: C,D :: ty : con_list '::' sigtypedoc - {% let (gadt,anns) = mkGadtDecl (unLoc $1) $3 - in ams (sLL $1 $> gadt) - (mu AnnDcolon $2:anns) } + {% ams (sLL $1 $> (mkGadtDecl (unLoc $1) $3)) + [mu AnnDcolon $2] } {- Note [Difference in parsing GADT and data constructors] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ===================================== compiler/GHC/Parser/PostProcess.hs ===================================== @@ -685,43 +685,35 @@ mkConDeclH98 name mb_forall mb_cxt args , con_args = args , con_doc = Nothing } +-- | Construct a GADT-style data constructor from the constructor names and +-- their type. This will return different AST forms for record syntax +-- constructors and prefix constructors, as the latter must be handled +-- specially in the renamer. See @Note [GADT abstract syntax]@ in +-- "GHC.Hs.Decls" for the full story. mkGadtDecl :: [Located RdrName] - -> LHsType GhcPs -- Always a HsForAllTy - -> (ConDecl GhcPs, [AddAnn]) + -> LHsType GhcPs + -> ConDecl GhcPs mkGadtDecl names ty - = (ConDeclGADT { con_g_ext = noExtField - , con_names = names - , con_forall = L l $ isLHsForAllTy ty' - , con_qvars = tvs - , con_mb_cxt = mcxt - , con_args = args - , con_res_ty = res_ty - , con_doc = Nothing } - , anns1 ++ anns2) + | Just (mtvs, mcxt, args, res_ty) <- mb_record_gadt ty + = ConDeclGADT { con_g_ext = noExtField + , con_names = names + , con_forall = L (getLoc ty) $ isJust mtvs + , con_qvars = fromMaybe [] mtvs + , con_mb_cxt = mcxt + , con_args = args + , con_res_ty = res_ty + , con_doc = Nothing } + | otherwise + = XConDecl $ ConDeclGADTPrefixPs { con_gp_names = names + , con_gp_ty = mkLHsSigType ty + , con_gp_doc = Nothing } where - (ty'@(L l _),anns1) = peel_parens ty [] - (tvs, rho) = splitLHsForAllTyInvis ty' - (mcxt, tau, anns2) = split_rho rho [] - - split_rho (L _ (HsQualTy { hst_ctxt = cxt, hst_body = tau })) ann - = (Just cxt, tau, ann) - split_rho (L l (HsParTy _ ty)) ann - = split_rho ty (ann++mkParensApiAnn l) - split_rho tau ann - = (Nothing, tau, ann) - - (args, res_ty) = split_tau tau - - -- See Note [GADT abstract syntax] in GHC.Hs.Decls - split_tau (L _ (HsFunTy _ (L loc (HsRecTy _ rf)) res_ty)) - = (RecCon (L loc rf), res_ty) - split_tau tau - = (PrefixCon [], tau) - - peel_parens (L l (HsParTy _ ty)) ann = peel_parens ty - (ann++mkParensApiAnn l) - peel_parens ty ann = (ty, ann) - + mb_record_gadt ty + | (mtvs, mcxt, body_ty) <- splitLHsGADTPrefixTy ty + , L _ (HsFunTy _ (L loc (HsRecTy _ rf)) res_ty) <- body_ty + = Just (mtvs, mcxt, RecCon (L loc rf), res_ty) + | otherwise + = Nothing setRdrNameSpace :: RdrName -> NameSpace -> RdrName -- ^ This rather gruesome function is used mainly by the parser. ===================================== compiler/GHC/Parser/PostProcess/Haddock.hs ===================================== @@ -12,24 +12,28 @@ import Control.Monad -- ----------------------------------------------------------------------------- -- Adding documentation to record fields (used in parsing). -addFieldDoc :: LConDeclField a -> Maybe LHsDocString -> LConDeclField a +addFieldDoc :: LConDeclField GhcPs -> Maybe LHsDocString -> LConDeclField GhcPs addFieldDoc (L l fld) doc = L l (fld { cd_fld_doc = cd_fld_doc fld `mplus` doc }) -addFieldDocs :: [LConDeclField a] -> Maybe LHsDocString -> [LConDeclField a] +addFieldDocs :: [LConDeclField GhcPs] -> Maybe LHsDocString -> [LConDeclField GhcPs] addFieldDocs [] _ = [] addFieldDocs (x:xs) doc = addFieldDoc x doc : xs -addConDoc :: LConDecl a -> Maybe LHsDocString -> LConDecl a +addConDoc :: LConDecl GhcPs -> Maybe LHsDocString -> LConDecl GhcPs addConDoc decl Nothing = decl -addConDoc (L p c) doc = L p ( c { con_doc = con_doc c `mplus` doc } ) +addConDoc (L p c) doc = L p $ case c of + ConDeclH98 { con_doc = old_doc } -> c { con_doc = old_doc `mplus` doc } + ConDeclGADT { con_doc = old_doc } -> c { con_doc = old_doc `mplus` doc } + XConDecl x@(ConDeclGADTPrefixPs { con_gp_doc = old_doc }) -> + XConDecl (x { con_gp_doc = old_doc `mplus` doc }) -addConDocs :: [LConDecl a] -> Maybe LHsDocString -> [LConDecl a] +addConDocs :: [LConDecl GhcPs] -> Maybe LHsDocString -> [LConDecl GhcPs] addConDocs [] _ = [] addConDocs [x] doc = [addConDoc x doc] addConDocs (x:xs) doc = x : addConDocs xs doc -addConDocFirst :: [LConDecl a] -> Maybe LHsDocString -> [LConDecl a] +addConDocFirst :: [LConDecl GhcPs] -> Maybe LHsDocString -> [LConDecl GhcPs] addConDocFirst [] _ = [] addConDocFirst (x:xs) doc = addConDoc x doc : xs ===================================== compiler/GHC/Rename/Module.hs ===================================== @@ -1747,8 +1747,9 @@ rnDataDefn doc (HsDataDefn { dd_ND = new_or_data, dd_cType = cType } where h98_style = case condecls of -- Note [Stupid theta] - (L _ (ConDeclGADT {})) : _ -> False - _ -> True + (L _ (ConDeclGADT {})) : _ -> False + (L _ (XConDecl (ConDeclGADTPrefixPs {}))) : _ -> False + _ -> True rn_derivs (L loc ds) = do { deriv_strats_ok <- xoptM LangExt.DerivingStrategies @@ -2085,7 +2086,7 @@ rnConDecl decl@(ConDeclH98 { con_name = name, con_ex_tvs = ex_tvs do { (new_context, fvs1) <- rnMbContext ctxt mcxt ; (new_args, fvs2) <- rnConDeclDetails (unLoc new_name) ctxt args ; let all_fvs = fvs1 `plusFV` fvs2 - ; traceRn "rnConDecl" (ppr name <+> vcat + ; traceRn "rnConDecl (ConDeclH98)" (ppr name <+> vcat [ text "ex_tvs:" <+> ppr ex_tvs , text "new_ex_dqtvs':" <+> ppr new_ex_tvs ]) @@ -2128,22 +2129,66 @@ rnConDecl decl@(ConDeclGADT { con_names = names ; (new_res_ty, fvs3) <- rnLHsType ctxt res_ty ; let all_fvs = fvs1 `plusFV` fvs2 `plusFV` fvs3 - (args', res_ty') - = case args of - InfixCon {} -> pprPanic "rnConDecl" (ppr names) - RecCon {} -> (new_args, new_res_ty) - PrefixCon as | (arg_tys, final_res_ty) <- splitHsFunType new_res_ty - -> ASSERT( null as ) - -- See Note [GADT abstract syntax] in GHC.Hs.Decls - (PrefixCon arg_tys, final_res_ty) - - ; traceRn "rnConDecl2" (ppr names $$ ppr implicit_tkvs $$ ppr explicit_tkvs) + + ; traceRn "rnConDecl (ConDeclGADT)" + (ppr names $$ ppr implicit_tkvs $$ ppr explicit_tkvs) ; return (decl { con_g_ext = implicit_tkvs, con_names = new_names , con_qvars = explicit_tkvs, con_mb_cxt = new_cxt - , con_args = args', con_res_ty = res_ty' + , con_args = new_args, con_res_ty = new_res_ty , con_doc = mb_doc' }, all_fvs) } } +-- This case is only used for prefix GADT constructors generated by GHC's +-- parser, where we do not know the argument types until type operator +-- precedence has been resolved. See Note [GADT abstract syntax] in +-- GHC.Hs.Decls for the full story. +rnConDecl (XConDecl (ConDeclGADTPrefixPs { con_gp_names = names, con_gp_ty = ty + , con_gp_doc = mb_doc })) + = do { mapM_ (addLocM checkConName) names + ; new_names <- mapM lookupLocatedTopBndrRn names + ; mb_doc' <- rnMbLHsDoc mb_doc + + ; let ctxt = ConDeclCtx new_names + ; (ty', fvs) <- rnHsSigType ctxt TypeLevel Nothing ty + + -- Now that operator precedence has been resolved, we can split the + -- GADT type into its individual components below. + ; let HsIB { hsib_ext = implicit_tkvs, hsib_body = body } = ty' + (mb_explicit_tkvs, mb_cxt, tau) = splitLHsGADTPrefixTy body + lhas_forall = L (getLoc body) $ isJust mb_explicit_tkvs + explicit_tkvs = fromMaybe [] mb_explicit_tkvs + (arg_tys, res_ty) = splitHsFunType tau + arg_details = PrefixCon arg_tys + + -- Ensure that there are no nested `forall`s or contexts, per + -- Note [No nested foralls or contexts in GADT constructors] in + -- GHC.Hs.Type. + ; case res_ty of + L l (HsForAllTy { hst_fvf = fvf }) + | ForallVis <- fvf + -> setSrcSpan l $ addErr $ withHsDocContext ctxt $ vcat + [ text "Illegal visible, dependent quantification" <+> + text "in the type of a term" + , text "(GHC does not yet support this)" ] + | ForallInvis <- fvf + -> nested_foralls_contexts_err l ctxt + L l (HsQualTy {}) + -> nested_foralls_contexts_err l ctxt + _ -> pure () + + ; traceRn "rnConDecl (ConDeclGADTPrefixPs)" + (ppr names $$ ppr implicit_tkvs $$ ppr explicit_tkvs) + ; pure (ConDeclGADT { con_g_ext = implicit_tkvs, con_names = new_names + , con_forall = lhas_forall, con_qvars = explicit_tkvs + , con_mb_cxt = mb_cxt, con_args = arg_details + , con_res_ty = res_ty, con_doc = mb_doc' }, + fvs) } + where + nested_foralls_contexts_err :: SrcSpan -> HsDocContext -> RnM () + nested_foralls_contexts_err l ctxt = + setSrcSpan l $ addErr $ withHsDocContext ctxt $ + text "GADT constructor type signature cannot contain nested" + <+> quotes forAllLit <> text "s or contexts" rnMbContext :: HsDocContext -> Maybe (LHsContext GhcPs) -> RnM (Maybe (LHsContext GhcRn), FreeVars) ===================================== compiler/GHC/Tc/TyCl.hs ===================================== @@ -3073,7 +3073,7 @@ dataDeclChecks tc_name new_or_data (L _ stupid_theta) cons ----------------------------------- -consUseGadtSyntax :: [LConDecl a] -> Bool +consUseGadtSyntax :: [LConDecl GhcRn] -> Bool consUseGadtSyntax (L _ (ConDeclGADT {}) : _) = True consUseGadtSyntax _ = False -- All constructors have same shape @@ -4720,50 +4720,12 @@ noClassTyVarErr clas fam_tc badDataConTyCon :: DataCon -> Type -> SDoc badDataConTyCon data_con res_ty_tmpl - | ASSERT( all isTyVar tvs ) - tcIsForAllTy actual_res_ty - = nested_foralls_contexts_suggestion - | isJust (tcSplitPredFunTy_maybe actual_res_ty) - = nested_foralls_contexts_suggestion - | otherwise = hang (text "Data constructor" <+> quotes (ppr data_con) <+> text "returns type" <+> quotes (ppr actual_res_ty)) 2 (text "instead of an instance of its parent type" <+> quotes (ppr res_ty_tmpl)) where actual_res_ty = dataConOrigResTy data_con - -- This suggestion is useful for suggesting how to correct code like what - -- was reported in #12087: - -- - -- data F a where - -- MkF :: Ord a => Eq a => a -> F a - -- - -- Although nested foralls or contexts are allowed in function type - -- signatures, it is much more difficult to engineer GADT constructor type - -- signatures to allow something similar, so we error in the latter case. - -- Nevertheless, we can at least suggest how a user might reshuffle their - -- exotic GADT constructor type signature so that GHC will accept. - nested_foralls_contexts_suggestion = - text "GADT constructor type signature cannot contain nested" - <+> quotes forAllLit <> text "s or contexts" - $+$ hang (text "Suggestion: instead use this type signature:") - 2 (ppr (dataConName data_con) <+> dcolon <+> ppr suggested_ty) - - -- To construct a type that GHC would accept (suggested_ty), we: - -- - -- 1) Find the existentially quantified type variables and the class - -- predicates from the datacon. (NB: We don't need the universally - -- quantified type variables, since rejigConRes won't substitute them in - -- the result type if it fails, as in this scenario.) - -- 2) Split apart the return type (which is headed by a forall or a - -- context) using tcSplitNestedSigmaTys, collecting the type variables - -- and class predicates we find, as well as the rho type lurking - -- underneath the nested foralls and contexts. - -- 3) Smash together the type variables and class predicates from 1) and - -- 2), and prepend them to the rho type from 2). - (tvs, theta, rho) = tcSplitNestedSigmaTys (dataConUserType data_con) - suggested_ty = mkSpecSigmaTy tvs theta rho - badGadtDecl :: Name -> SDoc badGadtDecl tc_name = vcat [ text "Illegal generalised algebraic data declaration for" <+> quotes (ppr tc_name) ===================================== compiler/GHC/ThToHs.hs ===================================== @@ -50,7 +50,6 @@ import GHC.Utils.Lexeme import GHC.Utils.Misc import GHC.Data.FastString import GHC.Utils.Outputable as Outputable -import GHC.Utils.Monad ( foldrM ) import qualified Data.ByteString as BS import Control.Monad( unless, ap ) @@ -595,6 +594,8 @@ cvtConstr (ForallC tvs ctxt con) add_cxt (L loc cxt1) (Just (L _ cxt2)) = Just (L loc (cxt1 ++ cxt2)) + add_forall :: [LHsTyVarBndr Hs.Specificity GhcPs] -> LHsContext GhcPs + -> ConDecl GhcPs -> ConDecl GhcPs add_forall tvs' cxt' con@(ConDeclGADT { con_qvars = qvars, con_mb_cxt = cxt }) = con { con_forall = noLoc $ not (null all_tvs) , con_qvars = all_tvs @@ -609,7 +610,13 @@ cvtConstr (ForallC tvs ctxt con) where all_tvs = tvs' ++ ex_tvs - add_forall _ _ (XConDecl nec) = noExtCon nec + -- The GadtC and RecGadtC cases of cvtConstr will always return a + -- ConDeclGADT, not a ConDeclGADTPrefixPs, so this case is unreachable. + -- See Note [GADT abstract syntax] in GHC.Hs.Decls for more on the + -- distinction between ConDeclGADT and ConDeclGADTPrefixPs. + add_forall _ _ con@(XConDecl (ConDeclGADTPrefixPs {})) = + pprPanic "cvtConstr.add_forall: Unexpected ConDeclGADTPrefixPs" + (Outputable.ppr con) cvtConstr (GadtC [] _strtys _ty) = failWith (text "GadtC must have at least one constructor name") @@ -617,9 +624,8 @@ cvtConstr (GadtC [] _strtys _ty) cvtConstr (GadtC c strtys ty) = do { c' <- mapM cNameL c ; args <- mapM cvt_arg strtys - ; L _ ty' <- cvtType ty - ; c_ty <- mk_arr_apps args ty' - ; returnL $ fst $ mkGadtDecl c' c_ty} + ; ty' <- cvtType ty + ; returnL $ mk_gadt_decl c' (PrefixCon args) ty'} cvtConstr (RecGadtC [] _varstrtys _ty) = failWith (text "RecGadtC must have at least one constructor name") @@ -628,9 +634,19 @@ cvtConstr (RecGadtC c varstrtys ty) = do { c' <- mapM cNameL c ; ty' <- cvtType ty ; rec_flds <- mapM cvt_id_arg varstrtys - ; let rec_ty = noLoc (HsFunTy noExtField - (noLoc $ HsRecTy noExtField rec_flds) ty') - ; returnL $ fst $ mkGadtDecl c' rec_ty } + ; returnL $ mk_gadt_decl c' (RecCon $ noLoc rec_flds) ty' } + +mk_gadt_decl :: [Located RdrName] -> HsConDeclDetails GhcPs -> LHsType GhcPs + -> ConDecl GhcPs +mk_gadt_decl names args res_ty + = ConDeclGADT { con_g_ext = noExtField + , con_names = names + , con_forall = noLoc False + , con_qvars = [] + , con_mb_cxt = Nothing + , con_args = args + , con_res_ty = res_ty + , con_doc = Nothing } cvtSrcUnpackedness :: TH.SourceUnpackedness -> SrcUnpackedness cvtSrcUnpackedness NoSourceUnpackedness = NoSrcUnpack @@ -1647,13 +1663,6 @@ See (among other closed issued) https://gitlab.haskell.org/ghc/ghc/issues/14289 -} -- --------------------------------------------------------------------- --- | Constructs an arrow type with a specified return type -mk_arr_apps :: [LHsType GhcPs] -> HsType GhcPs -> CvtM (LHsType GhcPs) -mk_arr_apps tys return_ty = foldrM go return_ty tys >>= returnL - where go :: LHsType GhcPs -> HsType GhcPs -> CvtM (HsType GhcPs) - go arg ret_ty = do { ret_ty_l <- returnL ret_ty - ; return (HsFunTy noExtField arg ret_ty_l) } - split_ty_app :: TH.Type -> CvtM (TH.Type, [LHsTypeArg GhcPs]) split_ty_app ty = go ty [] where ===================================== docs/users_guide/8.12.1-notes.rst ===================================== @@ -96,6 +96,27 @@ Language instantiated through visible type application. More information can be found here: :ref:`Manually-defining-inferred-variables`. +* GADT constructor types now properly adhere to :ref:`forall-or-nothing`. As + a result, GHC will now reject some GADT constructors that previous versions + of GHC would accept, such as the following: :: + + data T where + MkT1 :: (forall a. a -> b -> T) + MkT2 :: (forall a. a -> T) + + ``MkT1`` and ``MkT2`` are rejected because the lack of an outermost + ``forall`` triggers implicit quantification, making the explicit ``forall``s + nested. Furthermore, GADT constructors do not permit the use of nested + ``forall``s, as explained in :ref:`formal-gadt-syntax`. + + In addition to rejecting nested ``forall``s, GHC is now more stringent about + rejecting uses of nested *contexts* in GADT constructors. For example, the + following example, which previous versions of GHC would accept, is now + rejected: + + data U a where + MkU :: (Show a => U a) + Compiler ~~~~~~~~ ===================================== docs/users_guide/exts/explicit_forall.rst ===================================== @@ -45,4 +45,81 @@ Notes: would warn about the unused type variable `a`. +.. _forall-or-nothing: + +The ``forall``-or-nothing rule +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In certain forms of types, type variables obey what is known as the +"``forall``-or-nothing" rule: if a type has an outermost, explicit +``forall``, then all of the type variables in the type must be explicitly +quantified. These two examples illustrate how the rule works: :: + + f :: forall a b. a -> b -> b -- OK, `a` and `b` are explicitly bound + g :: forall a. a -> forall b. b -> b -- OK, `a` and `b` are explicitly bound + h :: forall a. a -> b -> b -- Rejected, `b` is not in scope + +The type signatures for ``f``, ``g``, and ``h`` all begin with an outermost +``forall``, so every type variable in these signatures must be explicitly +bound by a ``forall``. Both ``f`` and ``g`` obey the ``forall``-or-nothing +rule, since they explicitly quantify ``a`` and ``b``. On the other hand, +``h`` does not explicitly quantify ``b``, so GHC will reject its type +signature for being improperly scoped. + +In places where the ``forall``-or-nothing rule takes effect, if a type does +*not* have an outermost ``forall``, then any type variables that are not +explicitly bound by a ``forall`` become implicitly quantified. For example: :: + + i :: a -> b -> b -- `a` and `b` are implicitly quantified + j :: a -> forall b. b -> b -- `a` is implicitly quantified + k :: (forall a. a -> b -> b) -- `b` is implicitly quantified + +GHC will accept ``i``, ``j``, and ``k``'s type signatures. Note that: + +- ``j``'s signature is accepted despite its mixture of implicit and explicit + quantification. As long as a ``forall`` is not an outermost one, it is fine + to use it among implicitly bound type variables. +- ``k``'s signature is accepted because the outermost parentheses imply that + the ``forall`` is not an outermost ``forall``. The ``forall``-or-nothing + rule is one of the few places in GHC where the presence or absence of + parentheses can be semantically significant! + +The ``forall``-or-nothing rule takes effect in the following places: + +- Type signature declarations for functions, values, and class methods +- Expression type annotations +- Instance declarations +- :ref:`class-default-signatures` +- Type signatures in a :ref:`specialize-pragma` or + :ref:`specialize-instance-pragma` +- :ref:`standalone-kind-signatures` +- Type signatures for :ref:`gadt` constructors +- Type signatures for :ref:`pattern-synonyms` +- :ref:`data-instance-declarations`, :ref:`type-instance-declarations`, + :ref:`closed-type-families`, and :ref:`assoc-inst` +- :ref:`rewrite-rules` in which the type variables are explicitly quantified +Notes: + +- :ref:`pattern-type-sigs` are a notable example of a place where + types do *not* obey the ``forall``-or-nothing rule. For example, GHC will + accept the following: :: + + f (g :: forall a. a -> b) x = g x :: b + + Furthermore, :ref:`rewrite-rules` do not obey the ``forall``-or-nothing rule + when their type variables are not explicitly quantified: :: + + {-# RULES "f" forall (g :: forall a. a -> b) x. f g x = g x :: b #-} + +- GADT constructors are extra particular about their ``forall``s. In addition + to adhering to the ``forall``-or-nothing rule, GADT constructors also forbid + nested ``forall``s. For example, GHC would reject the following GADT: :: + + data T where + MkT :: (forall a. a -> b -> T) + + Because of the lack of an outermost ``forall`` in the type of ``MkT``, the + ``b`` would be implicitly quantified. In effect, it would be as if one had + written ``MkT :: forall b. (forall a. a -> b -> T)``, which contains nested + ``forall``s. See :ref:`formal-gadt-syntax`. ===================================== docs/users_guide/exts/gadt_syntax.rst ===================================== @@ -103,6 +103,123 @@ implements this behaviour, odd though it is. But for GADT-style declarations, GHC's behaviour is much more useful, as well as much more intuitive. +.. _formal-gadt-syntax: + +Formal syntax for GADTs +~~~~~~~~~~~~~~~~~~~~~~~ + +To make more precise what is and what is not permitted inside of a GADT-style +constructor, we provide a BNF-style grammar for GADT below. Note that this +grammar is subject to change in the future. :: + + gadt_con ::= conids '::' opt_forall opt_ctxt gadt_body + + conids ::= conid + | conid ',' conids + + opt_forall ::= + | 'forall' tv_bndrs '.' + + tv_bndrs ::= + | tv_bndr tv_bndrs + + tv_bndr ::= tyvar + | '(' tyvar '::' ctype ')' + + opt_ctxt ::= + | btype '=>' + | '(' ctxt ')' '=>' + + ctxt ::= ctype + | ctype ',' ctxt + + gadt_body ::= prefix_gadt_body + | record_gadt_body + + prefix_gadt_body ::= '(' prefix_gadt_body ')' + | return_type + | opt_unpack btype '->' prefix_gadt_body + + record_gadt_body ::= '{' fieldtypes '}' '->' return_type + + fieldtypes ::= + | fieldnames '::' opt_unpack ctype + | fieldnames '::' opt_unpack ctype ',' fieldtypes + + fieldnames ::= fieldname + | fieldname ',' fieldnames + + opt_unpack ::= opt_bang + : {-# UNPACK #-} opt_bang + | {-# NOUNPACK #-} opt_bang + + opt_bang ::= + | '!' + | '~' + +Where: + +- ``btype`` is a type that is not allowed to have an outermost + ``forall``/``=>`` unless it is surrounded by parentheses. For example, + ``forall a. a`` and ``Eq a => a`` are not legal ``btype``s, but + ``(forall a. a)`` and ``(Eq a => a)`` are legal. +- ``ctype`` is a ``btype`` that has no restrictions on an outermost + ``forall``/``=>``, so ``forall a. a`` and ``Eq a => a`` are legal ``ctype``s. +- ``return_type`` is a type that is not allowed to have ``forall``s, ``=>``s, + or ``->``s. + +This is a simplified grammar that does not fully delve into all of the +implementation details of GHC's parser (such as the placement of Haddock +comments), but it is sufficient to attain an understanding of what is +syntactically allowed. Some further various observations about this grammar: + +- GADT constructor types are currently not permitted to have nested ``forall``s + or ``=>``s. (e.g., something like ``MkT :: Int -> forall a. a -> T`` would be + rejected.) As a result, ``gadt_sig`` puts all of its quantification and + constraints up front with ``opt_forall`` and ``opt_context``. Note that + higher-rank ``forall``s and ``=>``s are only permitted if they do not appear + directly to the right of a function arrow in a `prefix_gadt_body`. (e.g., + something like ``MkS :: Int -> (forall a. a) -> S`` is allowed, since + parentheses separate the ``forall`` from the ``->``.) +- Furthermore, GADT constructors do not permit outermost parentheses that + surround the ``opt_forall`` or ``opt_ctxt``, if at least one of them are + used. For example, ``MkU :: (forall a. a -> U)`` would be rejected, since + it would treat the ``forall`` as being nested. + + Note that it is acceptable to use parentheses in a ``prefix_gadt_body``. + For instance, ``MkV1 :: forall a. (a) -> (V1)`` is acceptable, as is + ``MkV2 :: forall a. (a -> V2)``. +- The function arrows in a ``prefix_gadt_body``, as well as the function + arrow in a ``record_gadt_body``, are required to be used infix. For + example, ``MkA :: (->) Int A`` would be rejected. +- GHC uses the function arrows in a ``prefix_gadt_body`` and + ``prefix_gadt_body`` to syntactically demarcate the function and result + types. Note that GHC does not attempt to be clever about looking through + type synonyms here. If you attempt to do this, for instance: :: + + type C = Int -> B + + data B where + MkB :: C + + Then GHC will interpret the return type of ``MkB`` to be ``C``, and since + GHC requires that the return type must be headed by ``B``, this will be + rejected. On the other hand, it is acceptable to use type synonyms within + the argument and result types themselves, so the following is permitted: :: + + type B1 = Int + type B2 = B + + data B where + MkB :: B1 -> B2 +- GHC will accept any combination of ``!``/``~`` and + ``{-# UNPACK #-}``/``{-# NOUNPACK #-}``, although GHC will ignore some + combinations. For example, GHC will produce a warning if you write + ``{-# UNPACK #-} ~Int`` and proceed as if you had written ``Int``. + +GADT syntax odds and ends +~~~~~~~~~~~~~~~~~~~~~~~~~ + The rest of this section gives further details about GADT-style data type declarations. ===================================== testsuite/tests/dependent/should_fail/T16326_Fail6.stderr ===================================== @@ -1,7 +1,5 @@ -T16326_Fail6.hs:9:3: error: - • GADT constructor type signature cannot contain nested ‘forall’s or contexts - Suggestion: instead use this type signature: - MkFoo :: forall a. a -> Foo a - • In the definition of data constructor ‘MkFoo’ - In the data type declaration for ‘Foo’ +T16326_Fail6.hs:9:12: error: + Illegal visible, dependent quantification in the type of a term + (GHC does not yet support this) + In the definition of data constructor ‘MkFoo’ ===================================== testsuite/tests/gadt/T12087.stderr ===================================== @@ -1,35 +1,20 @@ -T12087.hs:6:3: error: - • GADT constructor type signature cannot contain nested ‘forall’s or contexts - Suggestion: instead use this type signature: - MkF1 :: forall a. (Ord a, Eq a) => a -> F1 a - • In the definition of data constructor ‘MkF1’ - In the data type declaration for ‘F1’ +T12087.hs:6:20: error: + GADT constructor type signature cannot contain nested ‘forall’s or contexts + In the definition of data constructor ‘MkF1’ -T12087.hs:9:3: error: - • GADT constructor type signature cannot contain nested ‘forall’s or contexts - Suggestion: instead use this type signature: - MkF2 :: forall a. (Ord a, Eq a) => a -> F2 a - • In the definition of data constructor ‘MkF2’ - In the data type declaration for ‘F2’ +T12087.hs:9:25: error: + GADT constructor type signature cannot contain nested ‘forall’s or contexts + In the definition of data constructor ‘MkF2’ -T12087.hs:12:3: error: - • GADT constructor type signature cannot contain nested ‘forall’s or contexts - Suggestion: instead use this type signature: - MkF3 :: forall a b. (Eq a, Eq b) => a -> b -> F3 a - • In the definition of data constructor ‘MkF3’ - In the data type declaration for ‘F3’ +T12087.hs:12:34: error: + GADT constructor type signature cannot contain nested ‘forall’s or contexts + In the definition of data constructor ‘MkF3’ -T12087.hs:15:3: error: - • GADT constructor type signature cannot contain nested ‘forall’s or contexts - Suggestion: instead use this type signature: - MkF4 :: forall a b. (Eq a, Eq b) => a -> b -> F4 a - • In the definition of data constructor ‘MkF4’ - In the data type declaration for ‘F4’ +T12087.hs:15:36: error: + GADT constructor type signature cannot contain nested ‘forall’s or contexts + In the definition of data constructor ‘MkF4’ -T12087.hs:18:3: error: - • GADT constructor type signature cannot contain nested ‘forall’s or contexts - Suggestion: instead use this type signature: - MkF5 :: forall a b. Int -> Int -> a -> Int -> Int -> b -> F5 a - • In the definition of data constructor ‘MkF5’ - In the data type declaration for ‘F5’ +T12087.hs:18:25: error: + GADT constructor type signature cannot contain nested ‘forall’s or contexts + In the definition of data constructor ‘MkF5’ ===================================== testsuite/tests/gadt/T14320.hs ===================================== @@ -10,8 +10,8 @@ data Exp :: Type where newtype TypedExp :: Type -> Type where TEGood :: forall a . (Exp -> (TypedExp a)) --- The only difference here is that the type is wrapped in parentheses, --- but GHC 8.0.1 rejects this program +-- The presence of outer parentheses makes the `forall` nested, and +-- GADTs do not permit nested `forall`s. -- newtype TypedExpToo :: Type -> Type where TEBad :: (forall a . (Exp -> (TypedExpToo a))) ===================================== testsuite/tests/gadt/T14320.stderr ===================================== @@ -0,0 +1,4 @@ + +T14320.hs:17:14: error: + GADT constructor type signature cannot contain nested ‘forall’s or contexts + In the definition of data constructor ‘TEBad’ ===================================== testsuite/tests/gadt/T16427.stderr ===================================== @@ -1,7 +1,4 @@ -T16427.hs:5:14: error: - • GADT constructor type signature cannot contain nested ‘forall’s or contexts - Suggestion: instead use this type signature: - C :: forall b. Int -> b -> D - • In the definition of data constructor ‘C’ - In the data type declaration for ‘D’ +T16427.hs:5:26: error: + GADT constructor type signature cannot contain nested ‘forall’s or contexts + In the definition of data constructor ‘C’ ===================================== testsuite/tests/gadt/T18191.hs ===================================== @@ -0,0 +1,12 @@ +{-# LANGUAGE GADTs #-} +{-# LANGUAGE RankNTypes #-} +module T18191 where + +data T where + MkT :: (forall a. a -> b -> T) + +data S a where + MkS :: (forall a. S a) + +data U a where + MkU :: (Show a => U a) ===================================== testsuite/tests/gadt/T18191.stderr ===================================== @@ -0,0 +1,12 @@ + +T18191.hs:6:11: error: + GADT constructor type signature cannot contain nested ‘forall’s or contexts + In the definition of data constructor ‘MkT’ + +T18191.hs:9:11: error: + GADT constructor type signature cannot contain nested ‘forall’s or contexts + In the definition of data constructor ‘MkS’ + +T18191.hs:12:11: error: + GADT constructor type signature cannot contain nested ‘forall’s or contexts + In the definition of data constructor ‘MkU’ ===================================== testsuite/tests/gadt/all.T ===================================== @@ -113,10 +113,11 @@ test('T7558', normal, compile_fail, ['']) test('T9380', normal, compile_and_run, ['']) test('T12087', normal, compile_fail, ['']) test('T12468', normal, compile_fail, ['']) -test('T14320', normal, compile, ['']) +test('T14320', normal, compile_fail, ['']) test('T14719', normal, compile_fail, ['-fdiagnostics-show-caret']) test('T14808', normal, compile, ['']) test('T15009', normal, compile, ['']) test('T15558', normal, compile, ['']) test('T16427', normal, compile_fail, ['']) test('T17423', expect_broken(17423), compile_and_run, ['']) +test('T18191', normal, compile_fail, ['']) ===================================== testsuite/tests/ghc-api/annotations/T10399.stdout ===================================== @@ -34,9 +34,9 @@ ((Test10399.hs:12:30,AnnComma), [Test10399.hs:12:30]), ((Test10399.hs:12:31-32,AnnCloseP), [Test10399.hs:12:32]), ((Test10399.hs:12:31-32,AnnOpenP), [Test10399.hs:12:31]), -((Test10399.hs:(14,1)-(18,55),AnnData), [Test10399.hs:14:1-4]), -((Test10399.hs:(14,1)-(18,55),AnnSemi), [Test10399.hs:20:1]), -((Test10399.hs:(14,1)-(18,55),AnnWhere), [Test10399.hs:14:21-25]), +((Test10399.hs:(14,1)-(18,53),AnnData), [Test10399.hs:14:1-4]), +((Test10399.hs:(14,1)-(18,53),AnnSemi), [Test10399.hs:20:1]), +((Test10399.hs:(14,1)-(18,53),AnnWhere), [Test10399.hs:14:21-25]), ((Test10399.hs:15:5-64,AnnDcolon), [Test10399.hs:15:11-12]), ((Test10399.hs:15:5-64,AnnSemi), [Test10399.hs:16:5]), ((Test10399.hs:15:14-64,AnnDot), [Test10399.hs:15:23]), @@ -48,37 +48,29 @@ ((Test10399.hs:15:45-46,AnnBang), [Test10399.hs:15:45]), ((Test10399.hs:15:45-46,AnnRarrow), [Test10399.hs:15:48-49]), ((Test10399.hs:15:45-64,AnnRarrow), [Test10399.hs:15:48-49]), -((Test10399.hs:(16,5)-(17,69),AnnCloseP), [Test10399.hs:17:69]), -((Test10399.hs:(16,5)-(17,69),AnnDcolon), [Test10399.hs:16:12-13]), -((Test10399.hs:(16,5)-(17,69),AnnOpenP), [Test10399.hs:16:27]), -((Test10399.hs:(16,5)-(17,69),AnnSemi), [Test10399.hs:18:5]), -((Test10399.hs:(16,15)-(17,69),AnnDot), [Test10399.hs:16:25]), -((Test10399.hs:(16,15)-(17,69),AnnForall), [Test10399.hs:16:15-20]), -((Test10399.hs:(16,27)-(17,69),AnnCloseP), [Test10399.hs:17:69]), -((Test10399.hs:(16,27)-(17,69),AnnOpenP), [Test10399.hs:16:27]), -((Test10399.hs:16:28-43,AnnCloseP), [Test10399.hs:16:43, Test10399.hs:16:43]), -((Test10399.hs:16:28-43,AnnDarrow), [Test10399.hs:16:45-46]), -((Test10399.hs:16:28-43,AnnOpenP), [Test10399.hs:16:28, Test10399.hs:16:28]), -((Test10399.hs:16:30-33,AnnComma), [Test10399.hs:16:34]), -((Test10399.hs:16:48,AnnRarrow), [Test10399.hs:16:50-51]), -((Test10399.hs:(16,48)-(17,68),AnnRarrow), [Test10399.hs:16:50-51]), -((Test10399.hs:16:53-66,AnnRarrow), [Test10399.hs:17:45-46]), -((Test10399.hs:(16,53)-(17,68),AnnRarrow), [Test10399.hs:17:45-46]), -((Test10399.hs:17:48,AnnRarrow), [Test10399.hs:17:50-51]), -((Test10399.hs:17:48-68,AnnRarrow), [Test10399.hs:17:50-51]), -((Test10399.hs:17:66-68,AnnCloseS), [Test10399.hs:17:68]), -((Test10399.hs:17:66-68,AnnOpenS), [Test10399.hs:17:66]), -((Test10399.hs:18:5-55,AnnCloseP), [Test10399.hs:18:55]), -((Test10399.hs:18:5-55,AnnDcolon), [Test10399.hs:18:16-17]), -((Test10399.hs:18:5-55,AnnOpenP), [Test10399.hs:18:19]), -((Test10399.hs:18:19-55,AnnCloseP), [Test10399.hs:18:55]), -((Test10399.hs:18:19-55,AnnOpenP), [Test10399.hs:18:19]), -((Test10399.hs:18:20-54,AnnDot), [Test10399.hs:18:29]), -((Test10399.hs:18:20-54,AnnForall), [Test10399.hs:18:20-25]), -((Test10399.hs:18:31-36,AnnCloseP), [Test10399.hs:18:36]), -((Test10399.hs:18:31-36,AnnOpenP), [Test10399.hs:18:31]), -((Test10399.hs:18:31-36,AnnRarrow), [Test10399.hs:18:38-39]), -((Test10399.hs:18:31-54,AnnRarrow), [Test10399.hs:18:38-39]), +((Test10399.hs:(16,5)-(17,67),AnnDcolon), [Test10399.hs:16:12-13]), +((Test10399.hs:(16,5)-(17,67),AnnSemi), [Test10399.hs:18:5]), +((Test10399.hs:(16,15)-(17,67),AnnDot), [Test10399.hs:16:25]), +((Test10399.hs:(16,15)-(17,67),AnnForall), [Test10399.hs:16:15-20]), +((Test10399.hs:16:27-42,AnnCloseP), [Test10399.hs:16:42, Test10399.hs:16:42]), +((Test10399.hs:16:27-42,AnnDarrow), [Test10399.hs:16:44-45]), +((Test10399.hs:16:27-42,AnnOpenP), [Test10399.hs:16:27, Test10399.hs:16:27]), +((Test10399.hs:16:29-32,AnnComma), [Test10399.hs:16:33]), +((Test10399.hs:16:47,AnnRarrow), [Test10399.hs:16:49-50]), +((Test10399.hs:(16,47)-(17,67),AnnRarrow), [Test10399.hs:16:49-50]), +((Test10399.hs:16:52-65,AnnRarrow), [Test10399.hs:17:44-45]), +((Test10399.hs:(16,52)-(17,67),AnnRarrow), [Test10399.hs:17:44-45]), +((Test10399.hs:17:47,AnnRarrow), [Test10399.hs:17:49-50]), +((Test10399.hs:17:47-67,AnnRarrow), [Test10399.hs:17:49-50]), +((Test10399.hs:17:65-67,AnnCloseS), [Test10399.hs:17:67]), +((Test10399.hs:17:65-67,AnnOpenS), [Test10399.hs:17:65]), +((Test10399.hs:18:5-53,AnnDcolon), [Test10399.hs:18:16-17]), +((Test10399.hs:18:19-53,AnnDot), [Test10399.hs:18:28]), +((Test10399.hs:18:19-53,AnnForall), [Test10399.hs:18:19-24]), +((Test10399.hs:18:30-35,AnnCloseP), [Test10399.hs:18:35]), +((Test10399.hs:18:30-35,AnnOpenP), [Test10399.hs:18:30]), +((Test10399.hs:18:30-35,AnnRarrow), [Test10399.hs:18:37-38]), +((Test10399.hs:18:30-53,AnnRarrow), [Test10399.hs:18:37-38]), ((Test10399.hs:20:1-25,AnnCloseQ), [Test10399.hs:20:24-25]), ((Test10399.hs:20:1-25,AnnOpen), [Test10399.hs:20:1-3]), ((Test10399.hs:20:1-25,AnnSemi), [Test10399.hs:22:1]), ===================================== testsuite/tests/ghc-api/annotations/Test10399.hs ===================================== @@ -13,9 +13,9 @@ mkPoli = mkBila . map ((,,(),,()) <$> P.base <*> P.pos <*> P.form) data MaybeDefault v where SetTo :: forall v . ( Eq v, Show v ) => !v -> MaybeDefault v - SetTo4 :: forall v a. (( Eq v, Show v ) => v -> MaybeDefault v - -> a -> MaybeDefault [a]) - TestParens :: (forall v . (Eq v) -> MaybeDefault v) + SetTo4 :: forall v a. ( Eq v, Show v ) => v -> MaybeDefault v + -> a -> MaybeDefault [a] + TestParens :: forall v . (Eq v) -> MaybeDefault v [t| Map.Map T.Text $tc |] ===================================== testsuite/tests/parser/should_compile/T15323.hs ===================================== @@ -3,4 +3,4 @@ module T15323 where data MaybeDefault v where - TestParens :: (forall v . (Eq v) => MaybeDefault v) + TestParens :: forall v . (Eq v) => MaybeDefault v ===================================== testsuite/tests/parser/should_compile/T15323.stderr ===================================== @@ -8,7 +8,7 @@ {ModuleName: T15323})) (Nothing) [] - [({ T15323.hs:(5,1)-(6,56) } + [({ T15323.hs:(5,1)-(6,54) } (TyClD (NoExtField) (DataDecl @@ -33,63 +33,67 @@ []) (Nothing) (Nothing) - [({ T15323.hs:6:5-56 } - (ConDeclGADT - (NoExtField) - [({ T15323.hs:6:5-14 } - (Unqual - {OccName: TestParens}))] - ({ T15323.hs:6:21-55 } - (True)) - [({ T15323.hs:6:28 } - (UserTyVar - (NoExtField) - (SpecifiedSpec) - ({ T15323.hs:6:28 } - (Unqual - {OccName: v}))))] - (Just - ({ T15323.hs:6:32-37 } - [({ T15323.hs:6:32-37 } - (HsParTy - (NoExtField) - ({ T15323.hs:6:33-36 } - (HsAppTy - (NoExtField) - ({ T15323.hs:6:33-34 } - (HsTyVar - (NoExtField) - (NotPromoted) - ({ T15323.hs:6:33-34 } - (Unqual - {OccName: Eq})))) - ({ T15323.hs:6:36 } - (HsTyVar - (NoExtField) - (NotPromoted) - ({ T15323.hs:6:36 } - (Unqual - {OccName: v}))))))))])) - (PrefixCon - []) - ({ T15323.hs:6:42-55 } - (HsAppTy + [({ T15323.hs:6:5-54 } + (XConDecl + (ConDeclGADTPrefixPs + [({ T15323.hs:6:5-14 } + (Unqual + {OccName: TestParens}))] + (HsIB (NoExtField) - ({ T15323.hs:6:42-53 } - (HsTyVar + ({ T15323.hs:6:20-54 } + (HsForAllTy (NoExtField) - (NotPromoted) - ({ T15323.hs:6:42-53 } - (Unqual - {OccName: MaybeDefault})))) - ({ T15323.hs:6:55 } - (HsTyVar - (NoExtField) - (NotPromoted) - ({ T15323.hs:6:55 } - (Unqual - {OccName: v})))))) - (Nothing)))] + (ForallInvis) + [({ T15323.hs:6:27 } + (UserTyVar + (NoExtField) + (SpecifiedSpec) + ({ T15323.hs:6:27 } + (Unqual + {OccName: v}))))] + ({ T15323.hs:6:31-54 } + (HsQualTy + (NoExtField) + ({ T15323.hs:6:31-36 } + [({ T15323.hs:6:31-36 } + (HsParTy + (NoExtField) + ({ T15323.hs:6:32-35 } + (HsAppTy + (NoExtField) + ({ T15323.hs:6:32-33 } + (HsTyVar + (NoExtField) + (NotPromoted) + ({ T15323.hs:6:32-33 } + (Unqual + {OccName: Eq})))) + ({ T15323.hs:6:35 } + (HsTyVar + (NoExtField) + (NotPromoted) + ({ T15323.hs:6:35 } + (Unqual + {OccName: v}))))))))]) + ({ T15323.hs:6:41-54 } + (HsAppTy + (NoExtField) + ({ T15323.hs:6:41-52 } + (HsTyVar + (NoExtField) + (NotPromoted) + ({ T15323.hs:6:41-52 } + (Unqual + {OccName: MaybeDefault})))) + ({ T15323.hs:6:54 } + (HsTyVar + (NoExtField) + (NotPromoted) + ({ T15323.hs:6:54 } + (Unqual + {OccName: v}))))))))))) + (Nothing))))] ({ } [])))))] (Nothing) ===================================== testsuite/tests/rename/should_compile/T5331.stderr ===================================== @@ -5,7 +5,7 @@ T5331.hs:8:17: warning: [-Wunused-foralls (in -Wextra)] T5331.hs:11:16: warning: [-Wunused-foralls (in -Wextra)] Unused quantified type variable ‘a’ - In the definition of data constructor ‘W1’ + In the type ‘forall a. W’ T5331.hs:13:13: warning: [-Wunused-foralls (in -Wextra)] Unused quantified type variable ‘a’ ===================================== utils/haddock ===================================== @@ -1 +1 @@ -Subproject commit 8134a3be2c01ab5f1b88fed86c4ad7cc2f417f0a +Subproject commit ab0ab0a6254f0a8e302a7b13485084cbd2ed1247 View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7b89ce1c3cda917dcf628d24a84163d30d84098a -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7b89ce1c3cda917dcf628d24a84163d30d84098a You're receiving 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 31 16:57:12 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 31 May 2020 12:57:12 -0400 Subject: [Git][ghc/ghc][wip/landing] Simple subsumption Message-ID: <5ed3e1e89959b_6e263f9ed4149c4c3248774@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/landing at Glasgow Haskell Compiler / GHC Commits: 522f8882 by Simon Peyton Jones at 2020-05-31T12:55:40-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 Updates Cabal and haddock submodules. Metric Increase: T12150 Metric Decrease: haddock.Cabal haddock.base - - - - - 20 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/Type.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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/522f88828557e5fe483870b428b1135d343d8cb9 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/522f88828557e5fe483870b428b1135d343d8cb9 You're receiving 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 31 17:02:17 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 31 May 2020 13:02:17 -0400 Subject: [Git][ghc/ghc][wip/bump-base] 2 commits: Simple subsumption Message-ID: <5ed3e319a70d3_6e263f9ed4d7839c3249170@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/bump-base at Glasgow Haskell Compiler / GHC Commits: 522f8882 by Simon Peyton Jones at 2020-05-31T12:55:40-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 Updates Cabal and haddock submodules. Metric Increase: T12150 Metric Decrease: haddock.Cabal haddock.base - - - - - 6e90582e by Ben Gamari at 2020-05-31T13:02:08-04:00 base: Bump to 4.15.0.0 - - - - - 20 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/Type.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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a79d489188976438dc9fa7771a0afad9b2485bc5...6e90582eb76b41388d3bab4139b927c5be9b906e -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a79d489188976438dc9fa7771a0afad9b2485bc5...6e90582eb76b41388d3bab4139b927c5be9b906e You're receiving 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 31 17:25:17 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 31 May 2020 13:25:17 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18272 Message-ID: <5ed3e87d460a8_6e263f9ed4149c4c3251299@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/T18272 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18272 You're receiving 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 31 17:27:28 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 31 May 2020 13:27:28 -0400 Subject: [Git][ghc/ghc][wip/T18272] rts: Add Windows-specific implementation of rtsSleep Message-ID: <5ed3e900dadc7_6e263f9ed4d7839c325424e@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18272 at Glasgow Haskell Compiler / GHC Commits: 19f21f44 by Ben Gamari at 2020-05-31T13:27:19-04:00 rts: Add Windows-specific implementation of rtsSleep Previously we would use the POSIX path, which uses `nanosleep`. However, it turns out that `nanosleep` is provided by `libpthread` on Windows. In general we don't want to incur such a dependency. Avoid this by simply using `Sleep` on Windows. Fixes #18272. - - - - - 1 changed file: - rts/RtsUtils.c Changes: ===================================== rts/RtsUtils.c ===================================== @@ -156,10 +156,16 @@ reportHeapOverflow(void) Sleep for the given period of time. -------------------------------------------------------------------------- */ -/* Returns -1 on failure but handles EINTR internally. - * N.B. usleep has been removed from POSIX 2008 */ +/* Returns -1 on failure but handles EINTR internally. On Windows this will + * only have millisecond precision. */ int rtsSleep(Time t) { +#if defined(mingw32_HOST_OS) + // N.B. we can't use nanosleep on Windows as it would incur a pthreads + // dependency. See #18272. + Sleep(TimeToMS(t)); + return 0; +#else struct timespec req; req.tv_sec = TimeToSeconds(t); req.tv_nsec = TimeToNS(t - req.tv_sec * TIME_RESOLUTION); @@ -168,6 +174,7 @@ int rtsSleep(Time t) ret = nanosleep(&req, &req); } while (ret == -1 && errno == EINTR); return ret; +#endif /* mingw32_HOST_OS */ } /* ----------------------------------------------------------------------------- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/19f21f444d7f34ff8d6caba20fd2d0712d380cc3 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/19f21f444d7f34ff8d6caba20fd2d0712d380cc3 You're receiving 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 31 17:28:18 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 31 May 2020 13:28:18 -0400 Subject: [Git][ghc/ghc][wip/T18272] rts: Add Windows-specific implementation of rtsSleep Message-ID: <5ed3e9324a5ce_6e263f9ee42e45b032546e8@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18272 at Glasgow Haskell Compiler / GHC Commits: 58fad7d4 by Ben Gamari at 2020-05-31T13:28:09-04:00 rts: Add Windows-specific implementation of rtsSleep Previously we would use the POSIX path, which uses `nanosleep`. However, it turns out that `nanosleep` is provided by `libpthread` on Windows. In general we don't want to incur such a dependency. Avoid this by simply using `Sleep` on Windows. Fixes #18272. - - - - - 1 changed file: - rts/RtsUtils.c Changes: ===================================== rts/RtsUtils.c ===================================== @@ -156,10 +156,16 @@ reportHeapOverflow(void) Sleep for the given period of time. -------------------------------------------------------------------------- */ -/* Returns -1 on failure but handles EINTR internally. - * N.B. usleep has been removed from POSIX 2008 */ +/* Returns -1 on failure but handles EINTR internally. On Windows this will + * only have millisecond precision. */ int rtsSleep(Time t) { +#if defined(_WIN32) + // N.B. we can't use nanosleep on Windows as it would incur a pthreads + // dependency. See #18272. + Sleep(TimeToMS(t)); + return 0; +#else struct timespec req; req.tv_sec = TimeToSeconds(t); req.tv_nsec = TimeToNS(t - req.tv_sec * TIME_RESOLUTION); @@ -168,6 +174,7 @@ int rtsSleep(Time t) ret = nanosleep(&req, &req); } while (ret == -1 && errno == EINTR); return ret; +#endif /* _WIN32 */ } /* ----------------------------------------------------------------------------- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/58fad7d43479766f3a66dd1ef9cc4edbe84ff372 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/58fad7d43479766f3a66dd1ef9cc4edbe84ff372 You're receiving 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 31 19:47:28 2020 From: gitlab at gitlab.haskell.org (Marge Bot) Date: Sun, 31 May 2020 15:47:28 -0400 Subject: [Git][ghc/ghc][wip/marge_bot_batch_merge_job] 25 commits: Cleanup OVERWRITING_CLOSURE logic Message-ID: <5ed409d0ab458_6e263f9ed4149c4c32952e3@gitlab.haskell.org.mail> Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC Commits: ac15af69 by Daniel Gröber at 2020-05-31T15:46:57-04:00 Cleanup OVERWRITING_CLOSURE logic The code is just more confusing than it needs to be. We don't need to mix the threaded check with the ldv profiling check since ldv's init already checks for this. Hence they can be two separate checks. Taking the sanity checking into account is also cleaner via DebugFlags.sanity. No need for checking the DEBUG define. The ZERO_SLOP_FOR_LDV_PROF and ZERO_SLOP_FOR_SANITY_CHECK definitions the old code had also make things a lot more opaque IMO so I removed those. - - - - - 0f0c595d by Daniel Gröber at 2020-05-31T15:46:57-04:00 Fix OVERWRITING_CLOSURE assuming closures are not inherently used The new ASSERT in LDV_recordDead() was being tripped up by MVars when removeFromMVarBlockedQueue() calls OVERWRITING_CLOSURE() via OVERWRITE_INFO(). - - - - - d31f9b28 by Daniel Gröber at 2020-05-31T15:46:57-04:00 Always zero shrunk mutable array slop when profiling When shrinking arrays in the profiling way we currently don't always zero the leftover slop. This means we can't traverse such closures in the heap profiler. The old Note [zeroing slop] and #8402 have some rationale for why this is so but I belive the reasoning doesn't apply to mutable closures. There users already have to ensure multiple threads don't step on each other's toes so zeroing should be safe. - - - - - cb8f710a by Ben Gamari at 2020-05-31T15:46:58-04:00 testsuite: Add test for #18151 - - - - - ae70f450 by Ben Gamari at 2020-05-31T15:46:58-04:00 testsuite: Add test for desugaring of PostfixOperators - - - - - 4f410d3b by Ben Gamari at 2020-05-31T15:46:58-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. - - - - - a7705b0e by Kirill Elagin at 2020-05-31T15:47:00-04:00 Winferred-safe-imports: Do not exit with error Currently, when -Winferred-safe-imports is enabled, even when it is not turned into an error, the compiler will still exit with exit code 1 if this warning was emitted. Make sure it is really treated as a warning. - - - - - 17dd21f2 by Ben Gamari at 2020-05-31T15:47:01-04:00 nonmoving: Optimise log2_ceil - - - - - 9205f755 by Bodigrim at 2020-05-31T15:47:02-04:00 Clarify description of fromListN - - - - - df44f621 by Bodigrim at 2020-05-31T15:47:02-04:00 Apply suggestion to libraries/base/GHC/Exts.hs - - - - - 911fc51d by fendor at 2020-05-31T15:47:04-04:00 Add `isInScope` check to `lintCoercion` Mirrors the behaviour of `lintType`. - - - - - eec99d73 by fendor at 2020-05-31T15:47:04-04:00 Lint rhs of IfaceRule - - - - - 375c0a3e by Jeremy Schlatter at 2020-05-31T15:47:06-04:00 Fix wording in documentation The duplicate "orphan instance" phrase here doesn't make sense, and was probably an accident. - - - - - 6c44ffdc by Takenobu Tani at 2020-05-31T15:47:08-04:00 configure: Modify aclocal.m4 according to new module hierarchy This patch updates file paths according to new module hierarchy [1]: * Rename: * compiler/GHC/Parser.hs <= compiler/parser/Parser.hs * compiler/GHC/Parser/Lexer.hs <= compiler/Parser/Lexer.hs * Add: * compiler/GHC/Cmm/Lexer.hs [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular - - - - - 8fa7006b by Ben Gamari at 2020-05-31T15:47:09-04:00 testsuite: Don't fail if we can't unlink __symlink_test Afterall, it's possible we were unable to create it due to lack of symlink permission. - - - - - 0b1f0ae7 by Ben Gamari at 2020-05-31T15:47:09-04:00 testsuite: Refactor ghostscript detection Tamar reported that he saw crashes due to unhandled exceptions. - - - - - 09ebac3d by Ben Gamari at 2020-05-31T15:47:09-04:00 testsuite/perf_notes: Fix ill-typed assignments - - - - - 938cbe69 by Ben Gamari at 2020-05-31T15:47:09-04:00 testsuite/testutil: Fix bytes/str mismatch - - - - - 03b3adfd by Ben Gamari at 2020-05-31T15:47:09-04:00 testsuite: Work around spurious mypy failure - - - - - 339730d3 by Takenobu Tani at 2020-05-31T15:47:11-04:00 Clean up file paths for new module hierarchy This updates comments only. This patch replaces file references according to new module hierarchy. See also: * https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular * https://gitlab.haskell.org/ghc/ghc/issues/13009 - - - - - 697198f2 by Takenobu Tani at 2020-05-31T15:47:11-04:00 Modify file paths to module paths for new module hierarchy This updates comments only. This patch replaces module references according to new module hierarchy [1][2]. For files under the `compiler/` directory, I replace them as module paths instead of file paths. For instance, `GHC.Unit.State` instead of `compiler/GHC/Unit/State.hs` [3]. For current and future haddock's markup, this patch encloses the module name with "" [4]. [1]: https://gitlab.haskell.org/ghc/ghc/-/wikis/Make-GHC-codebase-more-modular [2]: https://gitlab.haskell.org/ghc/ghc/issues/13009 [3]: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/3375#note_276613 [4]: https://haskell-haddock.readthedocs.io/en/latest/markup.html#linking-to-modules - - - - - 9833e623 by Sylvain Henry at 2020-05-31T15:47:14-04:00 Hadrian: fix binary-dist target for cross-compilation - - - - - 86c02527 by Vladislav Zavialov at 2020-05-31T15:47:14-04:00 Improve parser error messages for the @-operator Since GHC diverges from the Haskell Report by allowing the user to define (@) as an infix operator, we better give a good error message when the user does so unintentionally. In general, this is rather hard to do, as some failures will be discovered only in the renamer or the type checker: x :: (Integer, Integer) x @ (a, b) = (1, 2) This patch does *not* address this general case. However, it gives much better error messages when the binding is not syntactically valid: pairs xs @ (_:xs') = zip xs xs' Before this patch, the error message was rather puzzling: <interactive>:1:1: error: Parse error in pattern: pairs After this patch, the error message includes a hint: <interactive>:1:1: error: Parse error in pattern: pairs In a function binding for the ‘@’ operator. Perhaps you meant an as-pattern, which must not be surrounded by whitespace - - - - - 42c20deb by Vladislav Zavialov at 2020-05-31T15:47:15-04:00 Improve parser error messages for TypeApplications With this patch, we always parse f @t as a type application, thereby producing better error messages. This steals two syntactic forms: * Prefix form of the @-operator in expressions. Since the @-operator is a divergence from the Haskell Report anyway, this is not a major loss. * Prefix form of @-patterns. Since we are stealing loose infix form anyway, might as well sacrifice the prefix form for the sake of much better error messages. - - - - - 9c633fb4 by Vladislav Zavialov at 2020-05-31T15:47:15-04:00 Improve parser error messages for TemplateHaskellQuotes While [e| |], [t| |], [d| |], and so on, steal syntax from list comprehensions, [| |] and [|| ||] do not steal any syntax. Thus we can improve error messages by always accepting them in the lexer. Turns out the renamer already performs necessary validation. - - - - - 30 changed files: - aclocal.m4 - compiler/GHC.hs - compiler/GHC/Cmm/Utils.hs - compiler/GHC/CmmToAsm/SPARC/Base.hs - compiler/GHC/Core/Coercion/Opt.hs - compiler/GHC/Core/InstEnv.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/ConstantFold.hs - compiler/GHC/Core/TyCo/Tidy.hs - compiler/GHC/Core/TyCon.hs - compiler/GHC/Core/Unfold.hs - compiler/GHC/Driver/Main.hs - compiler/GHC/HsToCore/Expr.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/GHC/HsToCore/PmCheck/Types.hs - compiler/GHC/Iface/Ext/Ast.hs - compiler/GHC/Iface/Type.hs - compiler/GHC/IfaceToCore.hs - compiler/GHC/Parser.y - compiler/GHC/Parser/Lexer.x - compiler/GHC/Parser/PostProcess.hs - compiler/GHC/Runtime/Interpreter.hs - compiler/GHC/StgToCmm/Expr.hs - compiler/GHC/StgToCmm/Utils.hs - compiler/GHC/SysTools/ExtraObj.hs - compiler/GHC/Tc/Deriv.hs - compiler/GHC/ThToHs.hs - compiler/GHC/Utils/Outputable.hs - compiler/GHC/Utils/Ppr.hs - compiler/ghc.mk The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6c919f0b252e385b8e9ffb313ea280ca28cd2913...9c633fb444747e56faa424271d19f8e65d03a99f -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6c919f0b252e385b8e9ffb313ea280ca28cd2913...9c633fb444747e56faa424271d19f8e65d03a99f You're receiving 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 31 21:57:18 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 31 May 2020 17:57:18 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18274 Message-ID: <5ed4283e5e1bf_6e263f9ed4d7839c33351cf@gitlab.haskell.org.mail> Ben Gamari pushed new branch wip/T18274 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18274 You're receiving 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 31 21:58:22 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 31 May 2020 17:58:22 -0400 Subject: [Git][ghc/ghc][wip/T18234] gitlab-ci: Introduce a nightly cross-compilation job Message-ID: <5ed4287e1a032_6e263f9ee42e45b03336794@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/T18234 at Glasgow Haskell Compiler / GHC Commits: 1f999751 by Ben Gamari at 2020-05-31T17:58:14-04:00 gitlab-ci: Introduce a nightly cross-compilation job This adds a job to test cross-compilation from x86-64 to AArch64 with Hadrian. Fixes #18234. - - - - - 2 changed files: - .gitlab-ci.yml - .gitlab/ci.sh 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: 6223fe0b5942f4fa35bdec92c74566cf195bfb42 + DOCKER_REV: ba119705df5222fe74208a85019cb980e2c4318f # Sequential version number capturing the versions of all tools fetched by # .gitlab/ci.sh. @@ -244,6 +244,14 @@ validate-x86_64-linux-deb9-unreg-hadrian: tags: - x86_64-linux +nightly-x86_64-linux-deb10-hadrian-cross-aarch64: + <<: *nightly + extends: .build-x86_64-linux-deb10-hadrian + stage: full-build + variables: + CONFIGURE_ARGS: --with-intree-gmp + CROSS_TARGET: "aarch64-linux-gnu" + ############################################################ # GHC-in-GHCi (Hadrian) ===================================== .gitlab/ci.sh ===================================== @@ -80,6 +80,7 @@ Modes: Environment variables: + CROSS_TARGET Triple of cross-compilation target. MSYSTEM (Windows-only) Which platform to build form (MINGW64 or MINGW32). Environment variables determining build configuration of Make system: @@ -114,11 +115,11 @@ EOF function mingw_init() { case "$MSYSTEM" in MINGW32) - triple="i386-unknown-mingw32" + target_triple="i386-unknown-mingw32" boot_triple="i386-unknown-mingw32" # triple of bootstrap GHC ;; MINGW64) - triple="x86_64-unknown-mingw32" + target_triple="x86_64-unknown-mingw32" boot_triple="x86_64-unknown-mingw32" # triple of bootstrap GHC ;; *) @@ -375,8 +376,8 @@ function configure() { end_section "booting" local target_args="" - if [[ -n "$triple" ]]; then - target_args="--target=$triple" + if [[ -n "$target_triple" ]]; then + target_args="--target=$target_triple" fi start_section "configuring" @@ -415,6 +416,11 @@ function push_perf_notes() { } function test_make() { + if [ -n "$CROSS_TARGET" ]; then + info "Can't test cross-compiled build." + return + fi + run "$MAKE" test_bindist TEST_PREP=YES run "$MAKE" V=0 test \ THREADS="$cores" \ @@ -432,6 +438,11 @@ function build_hadrian() { } function test_hadrian() { + if [ -n "$CROSS_TARGET" ]; then + info "Can't test cross-compiled build." + return + fi + cd _build/bindist/ghc-*/ run ./configure --prefix="$TOP"/_build/install run "$MAKE" install @@ -486,6 +497,11 @@ case "$(uname)" in *) fail "uname $(uname) is not supported" ;; esac +if [ -n "$CROSS_TARGET" ]; then + info "Cross-compiling for $CROSS_TARGET..." + target_triple="$CROSS_TARGET" +fi + set_toolchain_paths case $1 in View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1f999751a13b9a4bfea5cb814f50a3222f1548ce -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1f999751a13b9a4bfea5cb814f50a3222f1548ce You're receiving 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 31 22:03:45 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 31 May 2020 18:03:45 -0400 Subject: [Git][ghc/ghc][wip/backports] 10 commits: Add orderingTyCon to wiredInTyCons (#18185) Message-ID: <5ed429c1ab77b_6e263f9eefb171783340733@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/backports at Glasgow Haskell Compiler / GHC Commits: 88fd4829 by Ryan Scott at 2020-05-31T18:03:38-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. (cherry picked from commit 6ca3d6a6c19dcd885f3b0beeda192cd90e83e0bd) - - - - - a6befeb3 by Ben Gamari at 2020-05-31T18:03:38-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. (cherry picked from commit dcd6bdcce57430d08b335014625722c487ea08e4) - - - - - fa36474d by Tuan Le at 2020-05-31T18:03:38-04:00 llvmGen: Consider Relocatable read-only data as not constantReferences: #18137 (cherry picked from commit 0004ccb885e534c386ceae21580fc59ec7ad0ede) - - - - - 4a73e707 by Ben Gamari at 2020-05-31T18:03:38-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 (cherry picked from commit cf4f1e2f78840d25b132de55bce1e02256334ace) - - - - - 4219e9c1 by Ryan Scott at 2020-05-31T18:03:38-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. (cherry picked from commit 518a63d4d7e31e49a81ad66d5e5ccb1f790f6de9) - - - - - 761909b9 by Ryan Scott at 2020-05-31T18:03:38-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. (cherry picked from commit cd8409c26d4370bf2cdcd76801974e99a9adf7b0) - - - - - 30037e6d by Sebastian Graf at 2020-05-31T18:03:38-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. (cherry picked from commit ed58d4fdcbc7b4fa8fbdf3d638a8d53c444ef4f2) - - - - - 1666baa6 by Simon Peyton Jones at 2020-05-31T18:03:38-04: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. (cherry picked from commit d7002bccd7d131f8ee9b1ddcd83d62262622294d) - - - - - 84ba6d2c by Simon Peyton Jones at 2020-05-31T18:03:38-04:00 Improve pretty-printing for TyConBinders In particular, show their kinds. (cherry picked from commit fa37940cd72f82abc460f5c0a5de64dd75cee6ae) - - - - - 35277140 by Simon Peyton Jones at 2020-05-31T18:03:38-04: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. (cherry picked from commit b9605396f1f1560aea94792646b835cadcb49f45) - - - - - 30 changed files: - compiler/GHC/Hs/Decls.hs - compiler/GHC/HsToCore/PmCheck/Oracle.hs - compiler/cmm/Cmm.hs - compiler/cmm/PprC.hs - compiler/llvmGen/LlvmCodeGen/Data.hs - compiler/prelude/PrelInfo.hs - compiler/prelude/PrelNames.hs - compiler/prelude/TysWiredIn.hs - compiler/simplCore/SimplUtils.hs - compiler/specialise/Rules.hs - compiler/typecheck/TcHsSyn.hs - compiler/typecheck/TcHsType.hs - compiler/typecheck/TcInstDcls.hs - compiler/typecheck/TcMType.hs - compiler/typecheck/TcTyClsDecls.hs - compiler/types/TyCon.hs - + libraries/ghc-compact/tests/T16992.hs - + libraries/ghc-compact/tests/T16992.stdout - libraries/ghc-compact/tests/all.T - rts/sm/CNF.c - + testsuite/tests/codeGen/should_gen_asm/T18137.asm - + testsuite/tests/codeGen/should_gen_asm/T18137.hs - testsuite/tests/codeGen/should_gen_asm/all.T - + testsuite/tests/deriving/should_compile/T18055.hs - testsuite/tests/deriving/should_compile/all.T - testsuite/tests/partial-sigs/should_compile/ExprSigLocal.stderr - testsuite/tests/partial-sigs/should_compile/SplicesUsed.stderr - testsuite/tests/partial-sigs/should_compile/T10519.stderr - testsuite/tests/partial-sigs/should_compile/T12844.stderr - testsuite/tests/partial-sigs/should_compile/T13482.stderr The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/254e625fcc89c13cf5d8476859acd7c4e2170f80...3527714032fecf4e2cedec3a80b1642dec4224f1 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/254e625fcc89c13cf5d8476859acd7c4e2170f80...3527714032fecf4e2cedec3a80b1642dec4224f1 You're receiving 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 31 22:23:25 2020 From: gitlab at gitlab.haskell.org (Ben Gamari) Date: Sun, 31 May 2020 18:23:25 -0400 Subject: [Git][ghc/ghc][wip/landing] Simple subsumption Message-ID: <5ed42e5d24c84_6e263f9ee42e45b033425ee@gitlab.haskell.org.mail> Ben Gamari pushed to branch wip/landing at Glasgow Haskell Compiler / GHC Commits: b2569826 by Simon Peyton Jones at 2020-05-31T22:20:44+00: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 Updates Cabal and haddock submodules. Metric Increase: T12150 Metric Decrease: haddock.Cabal haddock.base - - - - - 20 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/Type.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 The diff was not included because it is too large. View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b2569826f73d77da7f11dc66d4bf57403ccbf762 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b2569826f73d77da7f11dc66d4bf57403ccbf762 You're receiving 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 31 22:34:59 2020 From: gitlab at gitlab.haskell.org (Simon Peyton Jones) Date: Sun, 31 May 2020 18:34:59 -0400 Subject: [Git][ghc/ghc] Pushed new branch wip/T18275 Message-ID: <5ed4311315ed7_6e263f9f0beaac9c3344360@gitlab.haskell.org.mail> Simon Peyton Jones pushed new branch wip/T18275 at Glasgow Haskell Compiler / GHC -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/T18275 You're receiving 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 31 23:29:33 2020 From: gitlab at gitlab.haskell.org (Ryan Scott) Date: Sun, 31 May 2020 19:29:33 -0400 Subject: [Git][ghc/ghc][wip/simply-bind-tyvars] Simplify bindLHsTyVarBndrs and bindHsQTyVars Message-ID: <5ed43dddabebb_6e2612cf2760335848a@gitlab.haskell.org.mail> Ryan Scott pushed to branch wip/simply-bind-tyvars at Glasgow Haskell Compiler / GHC Commits: 5de2e7a4 by Ryan Scott at 2020-05-31T19:28:30-04:00 Simplify bindLHsTyVarBndrs and bindHsQTyVars Both `bindLHsTyVarBndrs` and `bindHsQTyVars` take two separate `Maybe` arguments, which I find terribly confusing. Thankfully, it's possible to remove one `Maybe` argument from each of these functions, which this patch accomplishes: * `bindHsQTyVars` takes a `Maybe SDoc` argument, which is `Just` if GHC should warn about any of the quantified type variables going unused. However, every call site uses `Nothing` in practice. This makes sense, since it doesn't really make sense to warn about unused type variables bound by an `LHsQTyVars`. For instance, you wouldn't warn about the `a` in `data Proxy a = Proxy` going unused. As a result, I simply remove this `Maybe SDoc` argument altogether. * `bindLHsTyVarBndrs` also takes a `Maybe SDoc` argument for the same reasons that `bindHsQTyVars` took one. To make things more confusing, however, `bindLHsTyVarBndrs` also takes a separate `HsDocContext` argument, which is pretty-printed (to an `SDoc`) in warnings and error messages. In practice, the `Maybe SDoc` and the `HsDocContext` often contain the same text. See the call sites for `bindLHsTyVarBndrs` in `rnFamInstEqn` and `rnConDecl`, for instance. There are only a handful of call sites where the text differs between the `Maybe SDoc` and `HsDocContext` arguments: * In `rnHsRuleDecl`, where the `Maybe SDoc` says "`In the rule`" and the `HsDocContext` says "`In the transformation rule`". * In `rnHsTyKi`/`rn_ty`, where the `Maybe SDoc` says "`In the type`" but the `HsDocContext` is inhereted from the surrounding context (e.g., if `rnHsTyKi` were called on a top-level type signature, the `HsDocContext` would be "`In the type signature`" instead) In both cases, warnings/error messages arguably _improve_ by unifying making the `Maybe SDoc`'s text match that of the `HsDocContext`. As a result, I decided to remove the `Maybe SDoc` argument to `bindLHsTyVarBndrs` entirely and simply reuse the text from the `HsDocContext`. (I decided to change the phrase "transformation rule" to "rewrite rule" while I was in the area.) The `Maybe SDoc` argument has one other purpose: signaling when to emit "`Unused quantified type variable`" warnings. To recover this functionality, I replaced the `Maybe SDoc` argument with a boolean-like `WarnUnusedForalls` argument. The only `bindLHsTyVarBndrs` call site that chooses _not_ to emit these warnings in `bindHsQTyVars`. - - - - - 17 changed files: - compiler/GHC/Core.hs - compiler/GHC/Core/Lint.hs - compiler/GHC/Core/Opt/Simplify.hs - compiler/GHC/Core/Rules.hs - compiler/GHC/Driver/Types.hs - compiler/GHC/Hs/Decls.hs - compiler/GHC/HsToCore.hs - compiler/GHC/Rename/HsType.hs - compiler/GHC/Rename/Module.hs - compiler/GHC/Rename/Utils.hs - compiler/GHC/Tc/Gen/Rule.hs - testsuite/tests/dependent/should_fail/T16326_Fail10.stderr - testsuite/tests/rename/should_compile/ExplicitForAllRules1.stderr - testsuite/tests/rename/should_compile/T5331.stderr - testsuite/tests/safeHaskell/ghci/p14.stderr - testsuite/tests/typecheck/should_compile/T10072.stderr - testsuite/tests/typecheck/should_fail/T5853.stderr Changes: ===================================== compiler/GHC/Core.hs ===================================== @@ -1291,7 +1291,7 @@ Orphan-hood is computed {- ************************************************************************ * * -\subsection{Transformation rules} +\subsection{Rewrite rules} * * ************************************************************************ ===================================== compiler/GHC/Core/Lint.hs ===================================== @@ -467,7 +467,7 @@ lintCoreBindings dflags pass local_in_scope binds where all_pairs = flattenBinds binds -- Put all the top-level binders in scope at the start - -- This is because transformation rules can bring something + -- This is because rewrite rules can bring something -- into use 'unexpectedly'; see Note [Glomming] in OccurAnal binders = map fst all_pairs ===================================== compiler/GHC/Core/Opt/Simplify.hs ===================================== @@ -170,7 +170,7 @@ simplTopBinds :: SimplEnv -> [InBind] -> SimplM (SimplFloats, SimplEnv) -- See Note [The big picture] simplTopBinds env0 binds0 = do { -- Put all the top-level binders into scope at the start - -- so that if a transformation rule has unexpectedly brought + -- so that if a rewrite rule has unexpectedly brought -- anything into scope, then we don't get a complaint about that. -- It's rather as if the top-level binders were imported. -- See note [Glomming] in OccurAnal. ===================================== compiler/GHC/Core/Rules.hs ===================================== @@ -1,7 +1,7 @@ {- (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 -\section[CoreRules]{Transformation rules} +\section[CoreRules]{Rewrite rules} -} {-# LANGUAGE CPP #-} ===================================== compiler/GHC/Driver/Types.hs ===================================== @@ -2486,7 +2486,7 @@ lookupFixity env n = case lookupNameEnv env n of -- * An instance declaration in a module other than the definition -- module for one of the type constructors or classes in the instance head -- --- * A transformation rule in a module other than the one defining +-- * A rewrite rule in a module other than the one defining -- the function in the head of the rule -- type WhetherHasOrphans = Bool ===================================== compiler/GHC/Hs/Decls.hs ===================================== @@ -2184,7 +2184,7 @@ instance Outputable ForeignExport where {- ************************************************************************ * * -\subsection{Transformation rules} +\subsection{Rewrite rules} * * ************************************************************************ -} ===================================== compiler/GHC/HsToCore.hs ===================================== @@ -354,7 +354,7 @@ to the binders in the top-level bindings Reason - It makes the rules easier to look up - - It means that transformation rules and specialisations for + - It means that rewrite rules and specialisations for locally defined Ids are handled uniformly - It keeps alive things that are referred to only from a rule (the occurrence analyser knows about rules attached to Ids) @@ -368,7 +368,7 @@ Reason ************************************************************************ * * -* Desugaring transformation rules +* Desugaring rewrite rules * * ************************************************************************ -} ===================================== compiler/GHC/Rename/HsType.hs ===================================== @@ -23,8 +23,8 @@ module GHC.Rename.HsType ( checkPrecMatch, checkSectionPrec, -- Binding related stuff - bindLHsTyVarBndr, bindLHsTyVarBndrs, rnImplicitBndrs, - bindSigTyVarsFV, bindHsQTyVars, bindLRdrNames, + bindLHsTyVarBndr, bindLHsTyVarBndrs, WarnUnusedForalls(..), + rnImplicitBndrs, bindSigTyVarsFV, bindHsQTyVars, bindLRdrNames, extractHsTyRdrTyVars, extractHsTyRdrTyVarsKindVars, extractHsTysRdrTyVarsDups, extractRdrKindSigVars, extractDataDefnKindVars, @@ -41,9 +41,10 @@ import GHC.Driver.Session import GHC.Hs import GHC.Rename.Doc ( rnLHsDoc, rnMbLHsDoc ) import GHC.Rename.Env -import GHC.Rename.Utils ( HsDocContext(..), withHsDocContext, mapFvRn - , pprHsDocContext, bindLocalNamesFV, typeAppErr - , newLocalBndrRn, checkDupRdrNames, checkShadowedRdrNames ) +import GHC.Rename.Utils ( HsDocContext(..), inHsDocContext, withHsDocContext + , mapFvRn, pprHsDocContext, bindLocalNamesFV + , typeAppErr, newLocalBndrRn, checkDupRdrNames + , checkShadowedRdrNames ) import GHC.Rename.Fixity ( lookupFieldFixityRn, lookupFixityRn , lookupTyFixityRn ) import GHC.Tc.Utils.Monad @@ -203,9 +204,10 @@ rnWcBody ctxt nwc_rdrs hs_ty rn_ty :: RnTyKiEnv -> HsType GhcPs -> RnM (HsType GhcRn, FreeVars) -- A lot of faff just to allow the extra-constraints wildcard to appear - rn_ty env hs_ty@(HsForAllTy { hst_fvf = fvf, hst_bndrs = tvs - , hst_body = hs_body }) - = bindLHsTyVarBndrs (rtke_ctxt env) (Just $ inTypeDoc hs_ty) Nothing tvs $ \ tvs' -> + rn_ty env (HsForAllTy { hst_fvf = fvf, hst_bndrs = tvs + , hst_body = hs_body }) + = bindLHsTyVarBndrs (rtke_ctxt env) WarnUnusedForalls + Nothing tvs $ \ tvs' -> do { (hs_body', fvs) <- rn_lty env hs_body ; return (HsForAllTy { hst_fvf = fvf, hst_xforall = noExtField , hst_bndrs = tvs', hst_body = hs_body' } @@ -534,7 +536,7 @@ rnHsTyKi :: RnTyKiEnv -> HsType GhcPs -> RnM (HsType GhcRn, FreeVars) rnHsTyKi env ty@(HsForAllTy { hst_fvf = fvf, hst_bndrs = tyvars , hst_body = tau }) = do { checkPolyKinds env ty - ; bindLHsTyVarBndrs (rtke_ctxt env) (Just $ inTypeDoc ty) + ; bindLHsTyVarBndrs (rtke_ctxt env) WarnUnusedForalls Nothing tyvars $ \ tyvars' -> do { (tau', fvs) <- rnLHsTyKi env tau ; return ( HsForAllTy { hst_fvf = fvf, hst_xforall = noExtField @@ -845,11 +847,9 @@ bindLRdrNames rdrs thing_inside --------------- bindHsQTyVars :: forall a b. HsDocContext - -> Maybe SDoc -- Just d => check for unused tvs - -- d is a phrase like "in the type ..." -> Maybe a -- Just _ => an associated type decl -> [Located RdrName] -- Kind variables from scope, no dups - -> (LHsQTyVars GhcPs) + -> LHsQTyVars GhcPs -> (LHsQTyVars GhcRn -> Bool -> RnM (b, FreeVars)) -- The Bool is True <=> all kind variables used in the -- kind signature are bound on the left. Reason: @@ -863,7 +863,7 @@ bindHsQTyVars :: forall a b. -- and (ii) mentioned in the kinds of hsq_bndrs -- (b) Bring type variables into scope -- -bindHsQTyVars doc mb_in_doc mb_assoc body_kv_occs hsq_bndrs thing_inside +bindHsQTyVars doc mb_assoc body_kv_occs hsq_bndrs thing_inside = do { let hs_tv_bndrs = hsQTvExplicit hsq_bndrs bndr_kv_occs = extractHsTyVarBndrsKVs hs_tv_bndrs @@ -888,7 +888,7 @@ bindHsQTyVars doc mb_in_doc mb_assoc body_kv_occs hsq_bndrs thing_inside ; implicit_kv_nms <- mapM (newTyVarNameRn mb_assoc) implicit_kvs ; bindLocalNamesFV implicit_kv_nms $ - bindLHsTyVarBndrs doc mb_in_doc mb_assoc hs_tv_bndrs $ \ rn_bndrs -> + bindLHsTyVarBndrs doc NoWarnUnusedForalls mb_assoc hs_tv_bndrs $ \ rn_bndrs -> do { traceRn "bindHsQTyVars" (ppr hsq_bndrs $$ ppr implicit_kv_nms $$ ppr rn_bndrs) ; thing_inside (HsQTvs { hsq_ext = implicit_kv_nms , hsq_explicit = rn_bndrs }) @@ -992,15 +992,32 @@ So tvs is {k,a} and kvs is {k}. NB: we do this only at the binding site of 'tvs'. -} +-- | Should GHC warn if a quantified type variable goes unused? Usually, the +-- answer is \"yes\", but in the case of "LHsQTyVars", we avoid emitting a +-- warning. For example: +-- +-- @ +-- data Proxy a = Proxy +-- @ +-- +-- The @a@ type variable goes unused, but we do not wish to warn here. +data WarnUnusedForalls + = WarnUnusedForalls + | NoWarnUnusedForalls + +instance Outputable WarnUnusedForalls where + ppr wuf = text $ case wuf of + WarnUnusedForalls -> "WarnUnusedForalls" + NoWarnUnusedForalls -> "NoWarnUnusedForalls" + bindLHsTyVarBndrs :: (OutputableBndrFlag flag) => HsDocContext - -> Maybe SDoc -- Just d => check for unused tvs - -- d is a phrase like "in the type ..." + -> WarnUnusedForalls -> Maybe a -- Just _ => an associated type decl -> [LHsTyVarBndr flag GhcPs] -- User-written tyvars -> ([LHsTyVarBndr flag GhcRn] -> RnM (b, FreeVars)) -> RnM (b, FreeVars) -bindLHsTyVarBndrs doc mb_in_doc mb_assoc tv_bndrs thing_inside +bindLHsTyVarBndrs doc wuf mb_assoc tv_bndrs thing_inside = do { when (isNothing mb_assoc) (checkShadowedRdrNames tv_names_w_loc) ; checkDupRdrNames tv_names_w_loc ; go tv_bndrs thing_inside } @@ -1014,9 +1031,9 @@ bindLHsTyVarBndrs doc mb_in_doc mb_assoc tv_bndrs thing_inside ; warn_unused b' fvs ; return (res, fvs) } - warn_unused tv_bndr fvs = case mb_in_doc of - Just in_doc -> warnUnusedForAll in_doc tv_bndr fvs - Nothing -> return () + warn_unused tv_bndr fvs = case wuf of + WarnUnusedForalls -> warnUnusedForAll doc tv_bndr fvs + NoWarnUnusedForalls -> return () bindLHsTyVarBndr :: HsDocContext -> Maybe a -- associated class @@ -1456,16 +1473,14 @@ dataKindsErr env thing pp_what | isRnKindLevel env = text "kind" | otherwise = text "type" -inTypeDoc :: HsType GhcPs -> SDoc -inTypeDoc ty = text "In the type" <+> quotes (ppr ty) - -warnUnusedForAll :: (OutputableBndrFlag flag) => SDoc -> LHsTyVarBndr flag GhcRn -> FreeVars -> TcM () -warnUnusedForAll in_doc (L loc tv) used_names +warnUnusedForAll :: OutputableBndrFlag flag + => HsDocContext -> LHsTyVarBndr flag GhcRn -> FreeVars -> TcM () +warnUnusedForAll doc (L loc tv) used_names = whenWOptM Opt_WarnUnusedForalls $ unless (hsTyVarName tv `elemNameSet` used_names) $ addWarnAt (Reason Opt_WarnUnusedForalls) loc $ vcat [ text "Unused quantified type variable" <+> quotes (ppr tv) - , in_doc ] + , inHsDocContext doc ] opTyErr :: Outputable a => RdrName -> a -> SDoc opTyErr op overall_ty ===================================== compiler/GHC/Rename/Module.hs ===================================== @@ -31,7 +31,7 @@ import GHC.Rename.HsType import GHC.Rename.Bind import GHC.Rename.Env import GHC.Rename.Utils ( HsDocContext(..), mapFvRn, bindLocalNames - , checkDupRdrNames, inHsDocContext, bindLocalNamesFV + , checkDupRdrNames, bindLocalNamesFV , checkShadowedRdrNames, warnUnusedTypePatterns , extendTyVarEnvFVRn, newLocalBndrsRn , withHsDocContext ) @@ -720,7 +720,7 @@ rnFamInstEqn doc atfi rhs_kvars -- with a sensible binding location ; ((bndrs', pats', payload'), fvs) <- bindLocalNamesFV all_imp_var_names $ - bindLHsTyVarBndrs doc (Just $ inHsDocContext doc) + bindLHsTyVarBndrs doc WarnUnusedForalls Nothing bndrs $ \bndrs' -> -- Note: If we pass mb_cls instead of Nothing here, -- bindLHsTyVarBndrs will use class variables for any names @@ -1017,7 +1017,7 @@ rnHsRuleDecl (HsRule { rd_name = rule_name ; checkShadowedRdrNames rdr_names_w_loc ; names <- newLocalBndrsRn rdr_names_w_loc ; let doc = RuleCtx (snd $ unLoc rule_name) - ; bindRuleTyVars doc in_rule tyvs $ \ tyvs' -> + ; bindRuleTyVars doc tyvs $ \ tyvs' -> bindRuleTmVars doc tyvs' tmvs names $ \ tmvs' -> do { (lhs', fv_lhs') <- rnLExpr lhs ; (rhs', fv_rhs') <- rnLExpr rhs @@ -1033,7 +1033,6 @@ rnHsRuleDecl (HsRule { rd_name = rule_name get_var :: RuleBndr GhcPs -> Located RdrName get_var (RuleBndrSig _ v _) = v get_var (RuleBndr _ v) = v - in_rule = text "in the rule" <+> pprFullRuleName rule_name bindRuleTmVars :: HsDocContext -> Maybe ty_bndrs -> [LRuleBndr GhcPs] -> [Name] @@ -1059,17 +1058,17 @@ bindRuleTmVars doc tyvs vars names thing_inside bind_free_tvs = case tyvs of Nothing -> AlwaysBind Just _ -> NeverBind -bindRuleTyVars :: HsDocContext -> SDoc -> Maybe [LHsTyVarBndr () GhcPs] +bindRuleTyVars :: HsDocContext -> Maybe [LHsTyVarBndr () GhcPs] -> (Maybe [LHsTyVarBndr () GhcRn] -> RnM (b, FreeVars)) -> RnM (b, FreeVars) -bindRuleTyVars doc in_doc (Just bndrs) thing_inside - = bindLHsTyVarBndrs doc (Just in_doc) Nothing bndrs (thing_inside . Just) -bindRuleTyVars _ _ _ thing_inside = thing_inside Nothing +bindRuleTyVars doc (Just bndrs) thing_inside + = bindLHsTyVarBndrs doc WarnUnusedForalls Nothing bndrs (thing_inside . Just) +bindRuleTyVars _ _ thing_inside = thing_inside Nothing {- Note [Rule LHS validity checking] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Check the shape of a transformation rule LHS. Currently we only allow +Check the shape of a rewrite rule LHS. Currently we only allow LHSs of the form @(f e1 .. en)@, where @f@ is not one of the @forall@'d variables. @@ -1581,7 +1580,7 @@ rnTyClDecl (SynDecl { tcdLName = tycon, tcdTyVars = tyvars, ; let kvs = extractHsTyRdrTyVarsKindVars rhs doc = TySynCtx tycon ; traceRn "rntycl-ty" (ppr tycon <+> ppr kvs) - ; bindHsQTyVars doc Nothing Nothing kvs tyvars $ \ tyvars' _ -> + ; bindHsQTyVars doc Nothing kvs tyvars $ \ tyvars' _ -> do { (rhs', fvs) <- rnTySyn doc rhs ; return (SynDecl { tcdLName = tycon', tcdTyVars = tyvars' , tcdFixity = fixity @@ -1597,7 +1596,7 @@ rnTyClDecl (DataDecl ; let kvs = extractDataDefnKindVars defn doc = TyDataCtx tycon ; traceRn "rntycl-data" (ppr tycon <+> ppr kvs) - ; bindHsQTyVars doc Nothing Nothing kvs tyvars $ \ tyvars' no_rhs_kvs -> + ; bindHsQTyVars doc Nothing kvs tyvars $ \ tyvars' no_rhs_kvs -> do { (defn', fvs) <- rnDataDefn doc defn ; cusk <- data_decl_has_cusk tyvars' new_or_data no_rhs_kvs kind_sig ; let rn_info = DataDeclRn { tcdDataCusk = cusk @@ -1621,7 +1620,7 @@ rnTyClDecl (ClassDecl { tcdCtxt = context, tcdLName = lcls, -- Tyvars scope over superclass context and method signatures ; ((tyvars', context', fds', ats'), stuff_fvs) - <- bindHsQTyVars cls_doc Nothing Nothing kvs tyvars $ \ tyvars' _ -> do + <- bindHsQTyVars cls_doc Nothing kvs tyvars $ \ tyvars' _ -> do -- Checks for distinct tyvars { (context', cxt_fvs) <- rnContext cls_doc context ; fds' <- rnFds fds @@ -1878,7 +1877,7 @@ rnFamDecl mb_cls (FamilyDecl { fdLName = tycon, fdTyVars = tyvars , fdInjectivityAnn = injectivity }) = do { tycon' <- lookupLocatedTopBndrRn tycon ; ((tyvars', res_sig', injectivity'), fv1) <- - bindHsQTyVars doc Nothing mb_cls kvs tyvars $ \ tyvars' _ -> + bindHsQTyVars doc mb_cls kvs tyvars $ \ tyvars' _ -> do { let rn_sig = rnFamResultSig doc ; (res_sig', fv_kind) <- wrapLocFstM rn_sig res_sig ; injectivity' <- traverse (rnInjectivityAnn tyvars' res_sig') @@ -2080,7 +2079,7 @@ rnConDecl decl@(ConDeclH98 { con_name = name, con_ex_tvs = ex_tvs -- scoping we get. So no implicit binders at the existential forall ; let ctxt = ConDeclCtx [new_name] - ; bindLHsTyVarBndrs ctxt (Just (inHsDocContext ctxt)) + ; bindLHsTyVarBndrs ctxt WarnUnusedForalls Nothing ex_tvs $ \ new_ex_tvs -> do { (new_context, fvs1) <- rnMbContext ctxt mcxt ; (new_args, fvs2) <- rnConDeclDetails (unLoc new_name) ctxt args @@ -2118,11 +2117,11 @@ rnConDecl decl@(ConDeclGADT { con_names = names $ extractHsTvBndrs explicit_tkvs $ extractHsTysRdrTyVarsDups (theta ++ arg_tys ++ [res_ty]) - ; let ctxt = ConDeclCtx new_names - mb_ctxt = Just (inHsDocContext ctxt) + ; let ctxt = ConDeclCtx new_names ; rnImplicitBndrs implicit_bndrs $ \ implicit_tkvs -> - bindLHsTyVarBndrs ctxt mb_ctxt Nothing explicit_tkvs $ \ explicit_tkvs -> + bindLHsTyVarBndrs ctxt WarnUnusedForalls + Nothing explicit_tkvs $ \ explicit_tkvs -> do { (new_cxt, fvs1) <- rnMbContext ctxt mcxt ; (new_args, fvs2) <- rnConDeclDetails (unLoc (head new_names)) ctxt args ; (new_res_ty, fvs3) <- rnLHsType ctxt res_ty ===================================== compiler/GHC/Rename/Utils.hs ===================================== @@ -495,7 +495,7 @@ pprHsDocContext PatCtx = text "a pattern type-signature" pprHsDocContext SpecInstSigCtx = text "a SPECIALISE instance pragma" pprHsDocContext DefaultDeclCtx = text "a `default' declaration" pprHsDocContext DerivDeclCtx = text "a deriving declaration" -pprHsDocContext (RuleCtx name) = text "the transformation rule" <+> ftext name +pprHsDocContext (RuleCtx name) = text "the rewrite rule" <+> doubleQuotes (ftext name) pprHsDocContext (TyDataCtx tycon) = text "the data type declaration for" <+> quotes (ppr tycon) pprHsDocContext (FamPatCtx tycon) = text "a type pattern of family instance for" <+> quotes (ppr tycon) pprHsDocContext (TySynCtx name) = text "the declaration for type synonym" <+> quotes (ppr name) ===================================== compiler/GHC/Tc/Gen/Rule.hs ===================================== @@ -7,7 +7,7 @@ {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE TypeFamilies #-} --- | Typechecking transformation rules +-- | Typechecking rewrite rules module GHC.Tc.Gen.Rule ( tcRules ) where import GHC.Prelude @@ -239,7 +239,7 @@ tcRuleTmBndrs (L _ (RuleBndrSig _ (L _ name) rn_ty) : rule_bndrs) ; return (map snd tvs ++ tyvars, id : tmvars) } ruleCtxt :: FastString -> SDoc -ruleCtxt name = text "When checking the transformation rule" <+> +ruleCtxt name = text "When checking the rewrite rule" <+> doubleQuotes (ftext name) ===================================== testsuite/tests/dependent/should_fail/T16326_Fail10.stderr ===================================== @@ -4,4 +4,4 @@ T16326_Fail10.hs:12:18: error: forall a -> a -> a (GHC does not yet support this) • In a RULE for ‘x’: forall a -> a -> a - When checking the transformation rule "flurmp" + When checking the rewrite rule "flurmp" ===================================== testsuite/tests/rename/should_compile/ExplicitForAllRules1.stderr ===================================== @@ -1,4 +1,4 @@ ExplicitForAllRules1.hs:49:31: warning: [-Wunused-foralls (in -Wextra)] Unused quantified type variable ‘b’ - in the rule "example7" + In the rewrite rule "example7" ===================================== testsuite/tests/rename/should_compile/T5331.stderr ===================================== @@ -9,4 +9,4 @@ T5331.hs:11:16: warning: [-Wunused-foralls (in -Wextra)] T5331.hs:13:13: warning: [-Wunused-foralls (in -Wextra)] Unused quantified type variable ‘a’ - In the type ‘forall a. Int’ + In the type signature for ‘f’ ===================================== testsuite/tests/safeHaskell/ghci/p14.stderr ===================================== @@ -1,6 +1,6 @@ :9:25: error: - No instance for (Num a) arising from a use of ‘f’ - Possible fix: add (Num a) to the context of the RULE "id/Int" - In the expression: f - When checking the transformation rule "id/Int" + • No instance for (Num a) arising from a use of ‘f’ + Possible fix: add (Num a) to the context of the RULE "id/Int" + • In the expression: f + When checking the rewrite rule "id/Int" ===================================== testsuite/tests/typecheck/should_compile/T10072.stderr ===================================== @@ -7,4 +7,4 @@ T10072.hs:3:31: error: To use the inferred type, enable PartialTypeSignatures • In the type ‘a -> _’ In a RULE for ‘f’: a -> _ - When checking the transformation rule "map/empty" + When checking the rewrite rule "map/empty" ===================================== testsuite/tests/typecheck/should_fail/T5853.stderr ===================================== @@ -9,7 +9,7 @@ T5853.hs:15:52: error: bound by the RULE "map/map" at T5853.hs:15:2-57 NB: ‘Subst’ is a non-injective type family • In the expression: (f . g) <$> xs - When checking the transformation rule "map/map" + When checking the rewrite rule "map/map" • Relevant bindings include f :: Elem fa -> b (bound at T5853.hs:15:19) g :: a -> Elem fa (bound at T5853.hs:15:21) View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5de2e7a486509a0083a011b596dbf4b50994f0a8 -- View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/5de2e7a486509a0083a011b596dbf4b50994f0a8 You're receiving this email because of your account on gitlab.haskell.org. -------------- next part -------------- An HTML attachment was scrubbed... URL: