summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Newton <rrnewton@gmail.com>2013-08-31 15:28:02 -0400
committerRyan Newton <rrnewton@gmail.com>2013-08-31 15:28:02 -0400
commite251a51a990c3a9c95dabab139d42ad69479f61c (patch)
tree94243fe32bb64d0cab79074ef8de8cb3530d2973
parent6fd60b2382efa357fe99fa017fd343db9724d43a (diff)
parentea87014a7ad4454f18bb15f6f0ee4b6e61b148be (diff)
downloadhaskell-e251a51a990c3a9c95dabab139d42ad69479f61c.tar.gz
Merge branch 'master' into atomics
-rw-r--r--aclocal.m412
-rw-r--r--compiler/basicTypes/BasicTypes.lhs9
-rw-r--r--compiler/cmm/CmmExpr.hs10
-rw-r--r--compiler/cmm/cmm-notes2
-rw-r--r--compiler/codeGen/StgCmm.hs7
-rw-r--r--compiler/codeGen/StgCmmBind.hs16
-rw-r--r--compiler/codeGen/StgCmmClosure.hs147
-rw-r--r--compiler/codeGen/StgCmmExpr.hs111
-rw-r--r--compiler/codeGen/StgCmmMonad.hs125
-rw-r--r--compiler/codeGen/StgCmmProf.hs71
-rw-r--r--compiler/coreSyn/CoreSubst.lhs29
-rw-r--r--compiler/coreSyn/CoreSyn.lhs16
-rw-r--r--compiler/coreSyn/CoreTidy.lhs7
-rw-r--r--compiler/coreSyn/CoreUnfold.lhs6
-rw-r--r--compiler/coreSyn/CoreUtils.lhs48
-rw-r--r--compiler/coreSyn/PprCore.lhs2
-rw-r--r--compiler/deSugar/DsMeta.hs16
-rw-r--r--compiler/ghci/ByteCodeInstr.lhs2
-rw-r--r--compiler/hsSyn/HsBinds.lhs127
-rw-r--r--compiler/hsSyn/HsExpr.lhs60
-rw-r--r--compiler/iface/BinIface.hs2
-rw-r--r--compiler/iface/IfaceSyn.lhs35
-rw-r--r--compiler/iface/MkIface.lhs437
-rw-r--r--compiler/iface/TcIface.lhs74
-rw-r--r--compiler/llvmGen/LlvmCodeGen/Ppr.hs6
-rw-r--r--compiler/main/DriverPipeline.hs97
-rw-r--r--compiler/main/DynFlags.hs32
-rw-r--r--compiler/main/GhcMake.hs2
-rw-r--r--compiler/main/GhcMonad.hs8
-rw-r--r--compiler/main/HscTypes.lhs34
-rw-r--r--compiler/main/Packages.lhs17
-rw-r--r--compiler/main/SysTools.lhs17
-rw-r--r--compiler/main/TidyPgm.lhs5
-rw-r--r--compiler/parser/Parser.y.pp4
-rw-r--r--compiler/rename/RnEnv.lhs2
-rw-r--r--compiler/rename/RnNames.lhs9
-rw-r--r--compiler/rename/RnPat.lhs230
-rw-r--r--compiler/simplCore/OccurAnal.lhs4
-rw-r--r--compiler/simplCore/SimplCore.lhs11
-rw-r--r--compiler/simplCore/SimplEnv.lhs2
-rw-r--r--compiler/simplCore/Simplify.lhs8
-rw-r--r--compiler/specialise/SpecConstr.lhs2
-rw-r--r--compiler/stranal/WorkWrap.lhs32
-rw-r--r--compiler/typecheck/TcDeriv.lhs2
-rw-r--r--compiler/typecheck/TcErrors.lhs77
-rw-r--r--compiler/typecheck/TcRnTypes.lhs5
-rw-r--r--compiler/typecheck/TcSimplify.lhs87
-rw-r--r--compiler/typecheck/TcTyClsDecls.lhs4
-rw-r--r--compiler/types/CoAxiom.lhs8
-rw-r--r--compiler/types/InstEnv.lhs55
-rw-r--r--compiler/types/TypeRep.lhs2
-rw-r--r--compiler/types/Unify.lhs26
-rw-r--r--compiler/utils/FastString.lhs2
-rw-r--r--compiler/utils/Fingerprint.hsc43
-rw-r--r--compiler/vectorise/Vectorise/Builtins/Base.hs4
-rw-r--r--docs/storage-mgt/rp.tex2
-rw-r--r--docs/users_guide/7.8.1-notes.xml124
-rw-r--r--docs/users_guide/flags.xml77
-rw-r--r--docs/users_guide/ghci.xml17
-rw-r--r--docs/users_guide/glasgow_exts.xml68
-rw-r--r--docs/users_guide/phases.xml32
-rw-r--r--docs/users_guide/separate_compilation.xml35
-rw-r--r--docs/users_guide/using.xml564
-rw-r--r--ghc/InteractiveUI.hs22
-rw-r--r--ghc/ghc-bin.cabal.in5
-rw-r--r--includes/stg/SMP.h9
m---------libraries/Cabal0
-rw-r--r--libraries/bin-package-db/Distribution/InstalledPackageInfo/Binary.hs6
-rw-r--r--libraries/bin-package-db/bin-package-db.cabal4
m---------libraries/binary0
m---------libraries/bytestring0
m---------libraries/containers0
m---------libraries/haskeline0
m---------libraries/time0
-rw-r--r--mk/config.mk.in26
-rw-r--r--rts/CheckUnload.c303
-rw-r--r--rts/CheckUnload.h20
-rw-r--r--rts/Linker.c124
-rw-r--r--rts/LinkerInternals.h12
-rw-r--r--rts/StgCRun.c2
-rw-r--r--rts/ghc-frontpanel.glade1622
-rw-r--r--rts/ghc.mk4
-rw-r--r--rts/posix/OSMem.c21
-rw-r--r--rts/sm/GC.c5
-rw-r--r--settings.in1
-rwxr-xr-xsync-all32
-rw-r--r--utils/dll-split/Main.hs2
-rw-r--r--utils/genprimopcode/Main.hs2
-rw-r--r--utils/ghc-cabal/Main.hs13
-rw-r--r--utils/ghc-cabal/ghc-cabal.cabal2
-rwxr-xr-xvalidate50
91 files changed, 2456 insertions, 2958 deletions
diff --git a/aclocal.m4 b/aclocal.m4
index d604cc08e0..7e555446a1 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -25,7 +25,7 @@ AC_DEFUN([GHC_SELECT_FILE_EXTENSIONS],
x86_64-apple-darwin)
$3='.dylib'
;;
- arm-apple-darwin10)
+ arm-apple-darwin10|i386-apple-darwin11)
$2='.a'
$3='.dylib'
;;
@@ -103,7 +103,7 @@ AC_DEFUN([FPTOOLS_SET_PLATFORM_VARS],
echo "Can't work out target platform"
exit 1
fi
-
+
TargetArch=`echo "$target" | sed 's/-.*//'`
TargetVendor=`echo "$target" | sed -e 's/.*-\(.*\)-.*/\1/'`
TargetOS=`echo "$target" | sed 's/.*-//'`
@@ -464,6 +464,7 @@ AC_DEFUN([FP_SETTINGS],
SettingsPerlCommand="$PerlCmd"
SettingsDllWrapCommand="/bin/false"
SettingsWindresCommand="/bin/false"
+ SettingsLibtoolCommand="libtool"
SettingsTouchCommand='touch'
if test -z "$LlcCmd"
then
@@ -490,6 +491,7 @@ AC_DEFUN([FP_SETTINGS],
AC_SUBST(SettingsPerlCommand)
AC_SUBST(SettingsDllWrapCommand)
AC_SUBST(SettingsWindresCommand)
+ AC_SUBST(SettingsLibtoolCommand)
AC_SUBST(SettingsTouchCommand)
AC_SUBST(SettingsLlcCommand)
AC_SUBST(SettingsOptCommand)
@@ -1602,7 +1604,7 @@ then
# optimistiaclly assume that it actually works properly.
AC_DEFINE([USE_TIMER_CREATE], 1, [Define to 1 if we can use timer_create(CLOCK_PROCESS_CPUTIME_ID,...)])
else
- AC_CACHE_CHECK([for a working timer_create(CLOCK_REALTIME)],
+ AC_CACHE_CHECK([for a working timer_create(CLOCK_REALTIME)],
[fptools_cv_timer_create_works],
[AC_TRY_RUN([
#include <stdio.h>
@@ -1722,7 +1724,7 @@ out:
[fptools_cv_timer_create_works=no])
])
case $fptools_cv_timer_create_works in
- yes) AC_DEFINE([USE_TIMER_CREATE], 1,
+ yes) AC_DEFINE([USE_TIMER_CREATE], 1,
[Define to 1 if we can use timer_create(CLOCK_PROCESS_CPUTIME_ID,...)]);;
esac
fi
@@ -1918,7 +1920,7 @@ AC_DEFUN([GHC_CONVERT_VENDOR],[
# converts os from gnu to ghc naming, and assigns the result to $target_var
AC_DEFUN([GHC_CONVERT_OS],[
case "$1-$2" in
- darwin10-arm)
+ darwin10-arm|darwin11-i386)
$3="ios"
;;
*)
diff --git a/compiler/basicTypes/BasicTypes.lhs b/compiler/basicTypes/BasicTypes.lhs
index 838e368ea6..dfde994417 100644
--- a/compiler/basicTypes/BasicTypes.lhs
+++ b/compiler/basicTypes/BasicTypes.lhs
@@ -381,17 +381,16 @@ data OverlapFlag
-- its ambiguous which to choose)
| OverlapOk { isSafeOverlap :: Bool }
- -- | Like OverlapOk, but also ignore this instance
- -- if it doesn't match the constraint you are
- -- trying to resolve, but could match if the type variables
- -- in the constraint were instantiated
+ -- | Silently ignore this instance if you find any other that matches the
+ -- constraing you are trying to resolve, including when checking if there are
+ -- instances that do not match, but unify.
--
-- Example: constraint (Foo [b])
-- instances (Foo [Int]) Incoherent
-- (Foo [a])
-- Without the Incoherent flag, we'd complain that
-- instantiating 'b' would change which instance
- -- was chosen
+ -- was chosen. See also note [Incoherent instances]
| Incoherent { isSafeOverlap :: Bool }
deriving (Eq, Data, Typeable)
diff --git a/compiler/cmm/CmmExpr.hs b/compiler/cmm/CmmExpr.hs
index 1df8e848b8..d3624dac6b 100644
--- a/compiler/cmm/CmmExpr.hs
+++ b/compiler/cmm/CmmExpr.hs
@@ -18,7 +18,7 @@ module CmmExpr
, plusRegSet, minusRegSet, timesRegSet, sizeRegSet, nullRegSet
, regSetToList
, regUsedIn
-
+
, Area(..)
, module CmmMachOp
, module CmmType
@@ -119,7 +119,11 @@ data CmmLit
-- Invariant: must be a continuation BlockId
-- See Note [Continuation BlockId] in CmmNode.
- | CmmHighStackMark -- stands for the max stack space used during a procedure
+ | CmmHighStackMark -- A late-bound constant that stands for the max
+ -- #bytes of stack space used during a procedure.
+ -- During the stack-layout pass, CmmHighStackMark
+ -- is replaced by a CmmInt for the actual number
+ -- of bytes used
deriving Eq
cmmExprType :: DynFlags -> CmmExpr -> CmmType
@@ -336,7 +340,7 @@ data GlobalReg
| LongReg -- long int registers (64-bit, really)
{-# UNPACK #-} !Int -- its number
- | XmmReg -- 128-bit SIMD vector register
+ | XmmReg -- 128-bit SIMD vector register
{-# UNPACK #-} !Int -- its number
-- STG registers
diff --git a/compiler/cmm/cmm-notes b/compiler/cmm/cmm-notes
index 7f7107a18d..1ebe0621a9 100644
--- a/compiler/cmm/cmm-notes
+++ b/compiler/cmm/cmm-notes
@@ -79,7 +79,7 @@ Things to do:
into separate C procedures.
Short term:
- compute and attach liveness into to LastCall
+ compute and attach liveness into LastCall
right at end, split, cvt to old rep
[must split before cvt, because old rep is not expressive enough]
diff --git a/compiler/codeGen/StgCmm.hs b/compiler/codeGen/StgCmm.hs
index 8b3bac3b4f..9b1bce4b57 100644
--- a/compiler/codeGen/StgCmm.hs
+++ b/compiler/codeGen/StgCmm.hs
@@ -257,13 +257,10 @@ cgDataCon data_con
-- Stuff to support splitting
---------------------------------------------------------------
--- If we're splitting the object, we need to externalise all the
--- top-level names (and then make sure we only use the externalised
--- one in any C label we use which refers to this name).
-
maybeExternaliseId :: DynFlags -> Id -> FCode Id
maybeExternaliseId dflags id
- | gopt Opt_SplitObjs dflags, -- Externalise the name for -split-objs
+ | gopt Opt_SplitObjs dflags, -- See Note [Externalise when splitting]
+ -- in StgCmmMonad
isInternalName name = do { mod <- getModuleName
; returnFC (setIdName id (externalise mod)) }
| otherwise = returnFC id
diff --git a/compiler/codeGen/StgCmmBind.hs b/compiler/codeGen/StgCmmBind.hs
index ce5491dc10..dccefd0fb0 100644
--- a/compiler/codeGen/StgCmmBind.hs
+++ b/compiler/codeGen/StgCmmBind.hs
@@ -30,6 +30,7 @@ import StgCmmForeign (emitPrimCall)
import MkGraph
import CoreSyn ( AltCon(..) )
import SMRep
+import BlockId
import Cmm
import CmmInfo
import CmmUtils
@@ -476,7 +477,17 @@ closureCodeBody top_lvl bndr cl_info cc args arity body fv_details
; let node_points = nodeMustPointToIt dflags lf_info
node' = if node_points then Just node else Nothing
; when node_points (ldvEnterClosure cl_info)
-
+ -- Emit new label that might potentially be a header
+ -- of a self-recursive tail call. See Note
+ -- [Self-recursive tail calls] in StgCmmExpr
+ ; u <- newUnique
+ ; let loop_header_id = mkBlockId u
+ ; emitLabel loop_header_id
+ -- Extend reader monad with information that
+ -- self-recursive tail calls can be optimized into local
+ -- jumps
+ ; withSelfLoop (bndr, loop_header_id, arg_regs) $ do
+ {
-- Main payload
; entryHeapCheck cl_info node' arity arg_regs $ do
{ -- ticky after heap check to avoid double counting
@@ -490,7 +501,8 @@ closureCodeBody top_lvl bndr cl_info cc args arity body fv_details
-- heap check, to reduce live vars over check
; when node_points $ load_fvs node lf_info fv_bindings
; void $ cgExpr body
- }}
+ }}}
+
}
-- A function closure pointer may be tagged, so we
diff --git a/compiler/codeGen/StgCmmClosure.hs b/compiler/codeGen/StgCmmClosure.hs
index 611a570d70..04297b4258 100644
--- a/compiler/codeGen/StgCmmClosure.hs
+++ b/compiler/codeGen/StgCmmClosure.hs
@@ -27,10 +27,9 @@ module StgCmmClosure (
lfDynTag,
maybeIsLFCon, isLFThunk, isLFReEntrant, lfUpdatable,
- nodeMustPointToIt,
- CallMethod(..), getCallMethod,
-
- isKnownFun, funTag, tagForArity,
+ -- * Used by other modules
+ CgLoc(..), SelfLoopInfo, CallMethod(..),
+ nodeMustPointToIt, isKnownFun, funTag, tagForArity, getCallMethod,
-- * ClosureInfo
ClosureInfo,
@@ -69,11 +68,14 @@ module StgCmmClosure (
import StgSyn
import SMRep
import Cmm
+import PprCmmExpr()
+import BlockId
import CLabel
import Id
import IdInfo
import DataCon
+import FastString
import Name
import Type
import TypeRep
@@ -85,6 +87,37 @@ import DynFlags
import Util
-----------------------------------------------------------------------------
+-- Data types and synonyms
+-----------------------------------------------------------------------------
+
+-- These data types are mostly used by other modules, especially StgCmmMonad,
+-- but we define them here because some functions in this module need to
+-- have access to them as well
+
+data CgLoc
+ = CmmLoc CmmExpr -- A stable CmmExpr; that is, one not mentioning
+ -- Hp, so that it remains valid across calls
+
+ | LneLoc BlockId [LocalReg] -- A join point
+ -- A join point (= let-no-escape) should only
+ -- be tail-called, and in a saturated way.
+ -- To tail-call it, assign to these locals,
+ -- and branch to the block id
+
+instance Outputable CgLoc where
+ ppr (CmmLoc e) = ptext (sLit "cmm") <+> ppr e
+ ppr (LneLoc b rs) = ptext (sLit "lne") <+> ppr b <+> ppr rs
+
+type SelfLoopInfo = (Id, BlockId, [LocalReg])
+
+-- used by ticky profiling
+isKnownFun :: LambdaFormInfo -> Bool
+isKnownFun (LFReEntrant _ _ _ _) = True
+isKnownFun LFLetNoEscape = True
+isKnownFun _ = False
+
+
+-----------------------------------------------------------------------------
-- Representations
-----------------------------------------------------------------------------
@@ -122,23 +155,23 @@ isGcPtrRep _ = False
-- 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
+ = 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)
+ | LFThunk -- Thunk (zero arity)
TopLevelFlag
- !Bool -- True <=> no free vars
- !Bool -- True <=> updatable (i.e., *not* single-entry)
+ !Bool -- True <=> no free vars
+ !Bool -- True <=> updatable (i.e., *not* single-entry)
StandardFormInfo
- !Bool -- True <=> *might* be a function type
+ !Bool -- True <=> *might* be a function type
- | LFCon -- A saturated constructor application
- DataCon -- The constructor
+ | LFCon -- A saturated constructor application
+ DataCon -- The constructor
- | LFUnknown -- Used for function arguments and imported things.
+ | 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
@@ -149,10 +182,10 @@ data LambdaFormInfo
-- 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;
+ | LFUnLifted -- A value of unboxed type;
-- always a value, needs evaluation
- | LFLetNoEscape -- See LetNoEscape module for precise description
+ | LFLetNoEscape -- See LetNoEscape module for precise description
| LFBlackHole -- Used for the closures allocated to hold the result
-- of a CAF. We want the target of the update frame to
@@ -175,7 +208,7 @@ data StandardFormInfo
-- 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
+ 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.)
@@ -205,9 +238,9 @@ mkLFLetNoEscape :: LambdaFormInfo
mkLFLetNoEscape = LFLetNoEscape
-------------
-mkLFReEntrant :: TopLevelFlag -- True of top level
- -> [Id] -- Free vars
- -> [Id] -- Args
+mkLFReEntrant :: TopLevelFlag -- True of top level
+ -> [Id] -- Free vars
+ -> [Id] -- Args
-> ArgDescr -- Argument descriptor
-> LambdaFormInfo
@@ -256,7 +289,7 @@ mkLFImported :: Id -> LambdaFormInfo
mkLFImported id
| Just con <- isDataConWorkId_maybe id
, isNullaryRepDataCon con
- = LFCon con -- An imported nullary constructor
+ = LFCon con -- An imported nullary constructor
-- We assume that the constructor is evaluated so that
-- the id really does point directly to the constructor
@@ -465,49 +498,65 @@ When black-holing, single-entry closures could also be entered via node
(rather than directly) to catch double-entry. -}
data CallMethod
- = EnterIt -- No args, not a function
+ = EnterIt -- No args, not a function
- | JumpToIt -- A join point
+ | JumpToIt BlockId [LocalReg] -- A join point or a header of a local loop
- | ReturnIt -- It's a value (function, unboxed value,
+ | ReturnIt -- It's a value (function, unboxed value,
-- or constructor), so just return it.
| SlowCall -- Unknown fun, or known fun with
-- too few args.
| DirectEntry -- Jump directly, with args in regs
- CLabel -- The code label
- RepArity -- Its arity
+ CLabel -- The code label
+ RepArity -- Its arity
getCallMethod :: DynFlags
-> Name -- Function being applied
- -> CafInfo -- Can it refer to CAF's?
- -> LambdaFormInfo -- Its info
- -> RepArity -- Number of available arguments
+ -> Id -- Function Id used to chech if it can refer to
+ -- CAF's and whether the function is tail-calling
+ -- itself
+ -> LambdaFormInfo -- Its info
+ -> RepArity -- Number of available arguments
+ -> CgLoc -- Passed in from cgIdApp so that we can
+ -- handle let-no-escape bindings and self-recursive
+ -- tail calls using the same data constructor,
+ -- JumpToIt. This saves us one case branch in
+ -- cgIdApp
+ -> Maybe SelfLoopInfo -- can we perform a self-recursive tail call?
-> CallMethod
-getCallMethod dflags _name _ lf_info _n_args
+getCallMethod _ _ id _ n_args _cg_loc (Just (self_loop_id, block_id, args))
+ | id == self_loop_id, n_args == length args
+ -- If these patterns match then we know that:
+ -- * function is performing a self-recursive call in a tail position
+ -- * number of parameters of the function matches functions arity.
+ -- See Note [Self-recursive tail calls] in StgCmmExpr for more details
+ = JumpToIt block_id args
+
+getCallMethod dflags _name _ lf_info _n_args _cg_loc _self_loop_info
| nodeMustPointToIt dflags lf_info && gopt Opt_Parallel dflags
- = -- If we're parallel, then we must always enter via node.
+ = -- If we're parallel, then we must always enter via node.
-- The reason is that the closure may have been
-- fetched since we allocated it.
EnterIt
-getCallMethod dflags name caf (LFReEntrant _ arity _ _) n_args
+getCallMethod dflags name id (LFReEntrant _ arity _ _) n_args _cg_loc _self_loop_info
| n_args == 0 = ASSERT( arity /= 0 )
ReturnIt -- No args at all
| n_args < arity = SlowCall -- Not enough args
- | otherwise = DirectEntry (enterIdLabel dflags name caf) arity
+ | otherwise = DirectEntry (enterIdLabel dflags name (idCafInfo id)) arity
-getCallMethod _ _name _ LFUnLifted n_args
+getCallMethod _ _name _ LFUnLifted n_args _cg_loc _self_loop_info
= ASSERT( n_args == 0 ) ReturnIt
-getCallMethod _ _name _ (LFCon _) n_args
+getCallMethod _ _name _ (LFCon _) n_args _cg_loc _self_loop_info
= ASSERT( n_args == 0 ) ReturnIt
-getCallMethod dflags name caf (LFThunk _ _ updatable std_form_info is_fun) n_args
- | is_fun -- it *might* be a function, so we must "call" it (which is always safe)
- = SlowCall -- We cannot just enter it [in eval/apply, the entry code
+getCallMethod dflags name id (LFThunk _ _ updatable std_form_info is_fun) n_args _cg_loc _self_loop_info
+ | is_fun -- it *might* be a function, so we must "call" it (which is always safe)
+ = SlowCall -- We cannot just enter it [in eval/apply, the entry code
-- is the fast-entry code]
-- Since is_fun is False, we are *definitely* looking at a data value
@@ -527,27 +576,24 @@ getCallMethod dflags name caf (LFThunk _ _ updatable std_form_info is_fun) n_arg
| otherwise -- Jump direct to code for single-entry thunks
= ASSERT( n_args == 0 )
- DirectEntry (thunkEntryLabel dflags name caf std_form_info updatable) 0
+ DirectEntry (thunkEntryLabel dflags name (idCafInfo id) std_form_info updatable) 0
-getCallMethod _ _name _ (LFUnknown True) _n_args
+getCallMethod _ _name _ (LFUnknown True) _n_arg _cg_locs _self_loop_info
= SlowCall -- might be a function
-getCallMethod _ name _ (LFUnknown False) n_args
+getCallMethod _ name _ (LFUnknown False) n_args _cg_loc _self_loop_info
= ASSERT2( n_args == 0, ppr name <+> ppr n_args )
EnterIt -- Not a function
-getCallMethod _ _name _ LFBlackHole _n_args
- = SlowCall -- Presumably the black hole has by now
+getCallMethod _ _name _ LFBlackHole _n_args _cg_loc _self_loop_info
+ = SlowCall -- Presumably the black hole has by now
-- been updated, but we don't know with
-- what, so we slow call it
-getCallMethod _ _name _ LFLetNoEscape _n_args
- = JumpToIt
+getCallMethod _ _name _ LFLetNoEscape _n_args (LneLoc blk_id lne_regs) _self_loop_info
+ = JumpToIt blk_id lne_regs
-isKnownFun :: LambdaFormInfo -> Bool
-isKnownFun (LFReEntrant _ _ _ _) = True
-isKnownFun LFLetNoEscape = True
-isKnownFun _ = False
+getCallMethod _ _ _ _ _ _ _ = panic "Unknown call method"
-----------------------------------------------------------------------------
-- staticClosureRequired
@@ -680,7 +726,6 @@ mkCmmInfo ClosureInfo {..}
, cit_prof = closureProf
, cit_srt = NoC_SRT }
-
--------------------------------------
-- Building ClosureInfos
--------------------------------------
diff --git a/compiler/codeGen/StgCmmExpr.hs b/compiler/codeGen/StgCmmExpr.hs
index 24b12f7237..331e65819f 100644
--- a/compiler/codeGen/StgCmmExpr.hs
+++ b/compiler/codeGen/StgCmmExpr.hs
@@ -160,7 +160,7 @@ cgLetNoEscapeClosure bndr cc_slot _unused_cc args body
return ( lneIdInfo dflags bndr args
, code )
where
- code = forkProc $ do {
+ code = forkLneBody $ do {
; withNewTickyCounterLNE (idName bndr) args $ do
; restoreCurrentCostCentre cc_slot
; arg_regs <- bindArgsToRegs args
@@ -632,14 +632,20 @@ cgConApp con stg_args
cgIdApp :: Id -> [StgArg] -> FCode ReturnKind
cgIdApp fun_id [] | isVoidId fun_id = emitReturn []
cgIdApp fun_id args = do
- dflags <- getDynFlags
- fun_info <- getCgIdInfo fun_id
- let fun_arg = StgVarArg fun_id
- fun_name = idName fun_id
- fun = idInfoToAmode fun_info
- lf_info = cg_lf fun_info
+ dflags <- getDynFlags
+ fun_info <- getCgIdInfo fun_id
+ self_loop_info <- getSelfLoop
+ let cg_fun_id = cg_id fun_info
+ -- NB: use (cg_id fun_info) instead of fun_id, because
+ -- the former may be externalised for -split-objs.
+ -- See Note [Externalise when splitting] in StgCmmMonad
+
+ fun_arg = StgVarArg cg_fun_id
+ fun_name = idName cg_fun_id
+ fun = idInfoToAmode fun_info
+ lf_info = cg_lf fun_info
node_points dflags = nodeMustPointToIt dflags lf_info
- case (getCallMethod dflags fun_name (idCafInfo fun_id) lf_info (length args)) of
+ case (getCallMethod dflags fun_name cg_fun_id lf_info (length args) (cg_loc fun_info) self_loop_info) of
-- A value in WHNF, so we can just return it.
ReturnIt -> emitReturn [fun] -- ToDo: does ReturnIt guarantee tagged?
@@ -659,14 +665,87 @@ cgIdApp fun_id args = do
then directCall NativeNodeCall lbl arity (fun_arg:args)
else directCall NativeDirectCall lbl arity args }
- -- Let-no-escape call
- JumpToIt -> let (LneLoc blk_id lne_regs) = cg_loc fun_info
- in do
- { adjustHpBackwards -- always do this before a tail-call
- ; cmm_args <- getNonVoidArgAmodes args
- ; emitMultiAssign lne_regs cmm_args
- ; emit (mkBranch blk_id)
- ; return AssignedDirectly }
+ -- Let-no-escape call or self-recursive tail-call
+ JumpToIt blk_id lne_regs -> do
+ { adjustHpBackwards -- always do this before a tail-call
+ ; cmm_args <- getNonVoidArgAmodes args
+ ; emitMultiAssign lne_regs cmm_args
+ ; emit (mkBranch blk_id)
+ ; return AssignedDirectly }
+
+-- Note [Self-recursive tail calls]
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+--
+-- Self-recursive tail calls can be optimized into a local jump in the same
+-- way as let-no-escape bindings (see Note [What is a non-escaping let] in
+-- stgSyn/CoreToStg.lhs). Consider this:
+--
+-- foo.info:
+-- a = R1 // calling convention
+-- b = R2
+-- goto L1
+-- L1: ...
+-- ...
+-- ...
+-- L2: R1 = x
+-- R2 = y
+-- call foo(R1,R2)
+--
+-- Instead of putting x and y into registers (or other locations required by the
+-- calling convention) and performing a call we can put them into local
+-- variables a and b and perform jump to L1:
+--
+-- foo.info:
+-- a = R1
+-- b = R2
+-- goto L1
+-- L1: ...
+-- ...
+-- ...
+-- L2: a = x
+-- b = y
+-- goto L1
+--
+-- This can be done only when function is calling itself in a tail position
+-- and only if the call passes number of parameters equal to function's arity.
+-- Note that this cannot be performed if a function calls itself with a
+-- continuation.
+--
+-- This in fact implements optimization known as "loopification". It was
+-- described in "Low-level code optimizations in the Glasgow Haskell Compiler"
+-- by Krzysztof WoÅ›, though we use different approach. Krzysztof performed his
+-- optimization at the Cmm level, whereas we perform ours during code generation
+-- (Stg-to-Cmm pass) essentially making sure that optimized Cmm code is
+-- generated in the first place.
+--
+-- Implementation is spread across a couple of places in the code:
+--
+-- * FCode monad stores additional information in its reader environment
+-- (cgd_self_loop field). This information tells us which function can
+-- tail call itself in an optimized way (it is the function currently
+-- being compiled), what is the label of a loop header (L1 in example above)
+-- and information about local registers in which we should arguments
+-- before making a call (this would be a and b in example above).
+--
+-- * Whenever we are compiling a function, we set that information to reflect
+-- the fact that function currently being compiled can be jumped to, instead
+-- of called. We also have to emit a label to which we will be jumping. Both
+-- things are done in closureCodyBody in StgCmmBind.
+--
+-- * When we began compilation of another closure we remove the additional
+-- information from the environment. This is done by forkClosureBody
+-- in StgCmmMonad. Other functions that duplicate the environment -
+-- forkLneBody, forkAlts, codeOnly - duplicate that information. In other
+-- words, we only need to clean the environment of the self-loop information
+-- when compiling right hand side of a closure (binding).
+--
+-- * When compiling a call (cgIdApp) we use getCallMethod to decide what kind
+-- of call will be generated. getCallMethod decides to generate a self
+-- recursive tail call when (a) environment stores information about
+-- possible self tail-call; (b) that tail call is to a function currently
+-- being compiled; (c) number of passed arguments is equal to function's
+-- arity.
+
emitEnter :: CmmExpr -> FCode ReturnKind
emitEnter fun = do
diff --git a/compiler/codeGen/StgCmmMonad.hs b/compiler/codeGen/StgCmmMonad.hs
index c3dc50ef98..27d4fd6386 100644
--- a/compiler/codeGen/StgCmmMonad.hs
+++ b/compiler/codeGen/StgCmmMonad.hs
@@ -26,7 +26,7 @@ module StgCmmMonad (
mkCmmIfThenElse, mkCmmIfThen, mkCmmIfGoto,
mkCall, mkCmmCall,
- forkClosureBody, forkAlts, forkProc, codeOnly,
+ forkClosureBody, forkLneBody, forkAlts, codeOnly,
ConTagZ,
@@ -44,10 +44,10 @@ module StgCmmMonad (
getModuleName,
-- ideally we wouldn't export these, but some other modules access internal state
- getState, setState, getInfoDown, getDynFlags, getThisPackage,
+ getState, setState, getSelfLoop, withSelfLoop, getInfoDown, getDynFlags, getThisPackage,
-- more localised access to monad state
- CgIdInfo(..), CgLoc(..),
+ CgIdInfo(..),
getBinds, setBinds,
-- out of general friendliness, we also export ...
@@ -60,6 +60,7 @@ import Cmm
import StgCmmClosure
import DynFlags
import Hoopl
+import Maybes
import MkGraph
import BlockId
import CLabel
@@ -100,11 +101,10 @@ infixr 9 `thenFC`
-- - A reader monad, for CgInfoDownwards, containing
-- - DynFlags,
-- - the current Module
--- - the static top-level environmnet
-- - the update-frame offset
-- - the ticky counter label
-- - the Sequel (the continuation to return to)
-
+-- - the self-recursive tail call information
--------------------------------------------------------
@@ -169,51 +169,48 @@ fixC fcode = FCode (
data CgInfoDownwards -- information only passed *downwards* by the monad
= MkCgInfoDown {
- cgd_dflags :: DynFlags,
- cgd_mod :: Module, -- Module being compiled
- cgd_updfr_off :: UpdFrameOffset, -- Size of current update frame
- cgd_ticky :: CLabel, -- Current destination for ticky counts
- cgd_sequel :: Sequel -- What to do at end of basic block
+ cgd_dflags :: DynFlags,
+ cgd_mod :: Module, -- Module being compiled
+ cgd_updfr_off :: UpdFrameOffset, -- Size of current update frame
+ cgd_ticky :: CLabel, -- Current destination for ticky counts
+ cgd_sequel :: Sequel, -- What to do at end of basic block
+ cgd_self_loop :: Maybe SelfLoopInfo -- Which tail calls can be compiled
+ -- as local jumps? See Note
+ -- [Self-recursive tail calls] in
+ -- StgCmmExpr
}
type CgBindings = IdEnv CgIdInfo
data CgIdInfo
= CgIdInfo
- { cg_id :: Id -- Id that this is the info for
+ { cg_id :: Id -- Id that this is the info for
-- Can differ from the Id at occurrence sites by
-- virtue of being externalised, for splittable C
+ -- See Note [Externalise when splitting]
, cg_lf :: LambdaFormInfo
, cg_loc :: CgLoc -- CmmExpr for the *tagged* value
}
-data CgLoc
- = CmmLoc CmmExpr -- A stable CmmExpr; that is, one not mentioning
- -- Hp, so that it remains valid across calls
-
- | LneLoc BlockId [LocalReg] -- A join point
- -- A join point (= let-no-escape) should only
- -- be tail-called, and in a saturated way.
- -- To tail-call it, assign to these locals,
- -- and branch to the block id
+-- Note [Externalise when splitting]
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-- If we're splitting the object with -fsplit-objs, we need to
+-- externalise *all* the top-level names, and then make sure we only
+-- use the externalised one in any C label we use which refers to this
+-- name.
instance Outputable CgIdInfo where
ppr (CgIdInfo { cg_id = id, cg_loc = loc })
= ppr id <+> ptext (sLit "-->") <+> ppr loc
-instance Outputable CgLoc where
- ppr (CmmLoc e) = ptext (sLit "cmm") <+> ppr e
- ppr (LneLoc b rs) = ptext (sLit "lne") <+> ppr b <+> ppr rs
-
-
-- Sequel tells what to do with the result of this expression
data Sequel
- = Return Bool -- Return result(s) to continuation found on the stack
- -- True <=> the continuation is update code (???)
+ = Return Bool -- Return result(s) to continuation found on the stack.
+ -- True <=> the continuation is update code (???)
| AssignTo
- [LocalReg] -- Put result(s) in these regs and fall through
- -- NB: no void arguments here
+ [LocalReg] -- Put result(s) in these regs and fall through
+ -- NB: no void arguments here
--
Bool -- Should we adjust the heap pointer back to
-- recover space that's unused on this path?
@@ -300,7 +297,8 @@ initCgInfoDown dflags mod
, cgd_mod = mod
, cgd_updfr_off = initUpdFrameOff dflags
, cgd_ticky = mkTopTickyCtrLabel
- , cgd_sequel = initSequel }
+ , cgd_sequel = initSequel
+ , cgd_self_loop = Nothing }
initSequel :: Sequel
initSequel = Return False
@@ -322,9 +320,7 @@ data CgState
-- Both are ordered only so that we can
-- reduce forward references, when it's easy to do so
- cgs_binds :: CgBindings, -- [Id -> info] : *local* bindings environment
- -- Bindings for top-level things are given in
- -- the info-down part
+ cgs_binds :: CgBindings,
cgs_hp_usg :: HeapUsage,
@@ -332,10 +328,10 @@ data CgState
data HeapUsage =
HeapUsage {
- virtHp :: VirtualHpOffset, -- Virtual offset of highest-allocated word
- -- Incremented whenever we allocate
+ virtHp :: VirtualHpOffset, -- Virtual offset of highest-allocated word
+ -- Incremented whenever we allocate
realHp :: VirtualHpOffset -- realHp: Virtual offset of real heap ptr
- -- Used in instruction addressing modes
+ -- Used in instruction addressing modes
}
type VirtualHpOffset = WordOff
@@ -449,6 +445,16 @@ newUnique = do
getInfoDown :: FCode CgInfoDownwards
getInfoDown = FCode $ \info_down state -> (# info_down,state #)
+getSelfLoop :: FCode (Maybe SelfLoopInfo)
+getSelfLoop = do
+ info_down <- getInfoDown
+ return $ cgd_self_loop info_down
+
+withSelfLoop :: SelfLoopInfo -> FCode a -> FCode a
+withSelfLoop self_loop code = do
+ info_down <- getInfoDown
+ withInfoDown code (info_down {cgd_self_loop = Just self_loop})
+
instance HasDynFlags FCode where
getDynFlags = liftM cgd_dflags getInfoDown
@@ -475,7 +481,7 @@ getModuleName = do { info <- getInfoDown; return (cgd_mod info) }
withSequel :: Sequel -> FCode a -> FCode a
withSequel sequel code
= do { info <- getInfoDown
- ; withInfoDown code (info {cgd_sequel = sequel }) }
+ ; withInfoDown code (info {cgd_sequel = sequel, cgd_self_loop = Nothing }) }
getSequel :: FCode Sequel
getSequel = do { info <- getInfoDown
@@ -520,15 +526,12 @@ setTickyCtrLabel ticky code = do
--------------------------------------------------------
forkClosureBody :: FCode () -> FCode ()
--- forkClosureBody takes a code, $c$, and compiles it in a
--- fresh environment, except that:
--- - compilation info and statics are passed in unchanged.
--- - local bindings are passed in unchanged
--- (it's up to the enclosed code to re-bind the
--- free variables to a field of the closure)
---
--- The current state is passed on completely unaltered, except that
--- C-- from the fork is incorporated.
+-- forkClosureBody compiles body_code in environment where:
+-- - sequel, update stack frame and self loop info are
+-- set to fresh values
+-- - state is set to a fresh value, except for local bindings
+-- that are passed in unchanged. It's up to the enclosed code to
+-- re-bind the free variables to a field of the closure.
forkClosureBody body_code
= do { dflags <- getDynFlags
@@ -536,26 +539,25 @@ forkClosureBody body_code
; us <- newUniqSupply
; state <- getState
; let body_info_down = info { cgd_sequel = initSequel
- , cgd_updfr_off = initUpdFrameOff dflags }
+ , cgd_updfr_off = initUpdFrameOff dflags
+ , cgd_self_loop = Nothing }
fork_state_in = (initCgState us) { cgs_binds = cgs_binds state }
((),fork_state_out) = doFCode body_code body_info_down fork_state_in
; setState $ state `addCodeBlocksFrom` fork_state_out }
-forkProc :: FCode a -> FCode a
--- 'forkProc' takes a code and compiles it in the *current* environment,
--- returning the graph thus constructed.
+forkLneBody :: FCode a -> FCode a
+-- 'forkLneBody' takes a body of let-no-escape binding and compiles
+-- it in the *current* environment, returning the graph thus constructed.
--
-- The current environment is passed on completely unchanged to
-- the successor. In particular, any heap usage from the enclosed
-- code is discarded; it should deal with its own heap consumption.
--- forkProc is used to compile let-no-escape bindings.
-forkProc body_code
+forkLneBody body_code
= do { info_down <- getInfoDown
; us <- newUniqSupply
; state <- getState
- ; let info_down' = info_down -- { cgd_sequel = initSequel }
- fork_state_in = (initCgState us) { cgs_binds = cgs_binds state }
- (result, fork_state_out) = doFCode body_code info_down' fork_state_in
+ ; let fork_state_in = (initCgState us) { cgs_binds = cgs_binds state }
+ (result, fork_state_out) = doFCode body_code info_down fork_state_in
; setState $ state `addCodeBlocksFrom` fork_state_out
; return result }
@@ -565,10 +567,10 @@ codeOnly :: FCode () -> FCode ()
-- Used in almost-circular code to prevent false loop dependencies
codeOnly body_code
= do { info_down <- getInfoDown
- ; us <- newUniqSupply
- ; state <- getState
- ; let fork_state_in = (initCgState us) { cgs_binds = cgs_binds state,
- cgs_hp_usg = cgs_hp_usg state }
+ ; us <- newUniqSupply
+ ; state <- getState
+ ; let fork_state_in = (initCgState us) { cgs_binds = cgs_binds state
+ , cgs_hp_usg = cgs_hp_usg state }
((), fork_state_out) = doFCode body_code info_down fork_state_in
; setState $ state `addCodeBlocksFrom` fork_state_out }
@@ -587,9 +589,8 @@ forkAlts branch_fcodes
where
(us1,us2) = splitUniqSupply us
branch_state = (initCgState us1) {
- cgs_binds = cgs_binds state,
- cgs_hp_usg = cgs_hp_usg state }
-
+ cgs_binds = cgs_binds state
+ , cgs_hp_usg = cgs_hp_usg state }
(_us, results) = mapAccumL compile us branch_fcodes
(branch_results, branch_out_states) = unzip results
; setState $ foldl stateIncUsage state branch_out_states
diff --git a/compiler/codeGen/StgCmmProf.hs b/compiler/codeGen/StgCmmProf.hs
index b1eaa1c27b..5044d763a4 100644
--- a/compiler/codeGen/StgCmmProf.hs
+++ b/compiler/codeGen/StgCmmProf.hs
@@ -6,28 +6,21 @@
--
-----------------------------------------------------------------------------
-{-# OPTIONS -fno-warn-tabs #-}
--- The above warning supression flag is a temporary kludge.
--- While working on this module you are encouraged to remove it and
--- detab the module (please do the detabbing in a separate patch). See
--- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSpaces
--- for details
-
module StgCmmProf (
- initCostCentres, ccType, ccsType,
- mkCCostCentre, mkCCostCentreStack,
+ initCostCentres, ccType, ccsType,
+ mkCCostCentre, mkCCostCentreStack,
- -- Cost-centre Profiling
- dynProfHdr, profDynAlloc, profAlloc, staticProfHdr, initUpdFrameProf,
+ -- Cost-centre Profiling
+ dynProfHdr, profDynAlloc, profAlloc, staticProfHdr, initUpdFrameProf,
enterCostCentreThunk, enterCostCentreFun,
costCentreFrom,
curCCS, storeCurCCS,
emitSetCCC,
- saveCurrentCostCentre, restoreCurrentCostCentre,
+ saveCurrentCostCentre, restoreCurrentCostCentre,
- -- Lag/drag/void stuff
- ldvEnter, ldvEnterClosure, ldvRecordCreate
+ -- Lag/drag/void stuff
+ ldvEnter, ldvEnterClosure, ldvRecordCreate
) where
#include "HsVersions.h"
@@ -78,8 +71,8 @@ mkCCostCentreStack :: CostCentreStack -> CmmLit
mkCCostCentreStack ccs = CmmLabel (mkCCSLabel ccs)
costCentreFrom :: DynFlags
- -> CmmExpr -- A closure pointer
- -> CmmExpr -- The cost centre from that closure
+ -> CmmExpr -- A closure pointer
+ -> CmmExpr -- The cost centre from that closure
costCentreFrom dflags cl = CmmLoad (cmmOffsetB dflags cl (oFFSET_StgHeader_ccs dflags)) (ccsType dflags)
-- | The profiling header words in a static closure
@@ -94,43 +87,43 @@ dynProfHdr dflags ccs = ifProfilingL dflags [ccs, dynLdvInit dflags]
-- | Initialise the profiling field of an update frame
initUpdFrameProf :: CmmExpr -> FCode ()
initUpdFrameProf frame
- = ifProfiling $ -- frame->header.prof.ccs = CCCS
+ = ifProfiling $ -- frame->header.prof.ccs = CCCS
do dflags <- getDynFlags
emitStore (cmmOffset dflags frame (oFFSET_StgHeader_ccs dflags)) curCCS
-- frame->header.prof.hp.rs = NULL (or frame-header.prof.hp.ldvw = 0)
- -- is unnecessary because it is not used anyhow.
+ -- is unnecessary because it is not used anyhow.
---------------------------------------------------------------------------
--- Saving and restoring the current cost centre
+-- Saving and restoring the current cost centre
---------------------------------------------------------------------------
-{- Note [Saving the current cost centre]
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+{- Note [Saving the current cost centre]
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The current cost centre is like a global register. Like other
global registers, it's a caller-saves one. But consider
- case (f x) of (p,q) -> rhs
+ case (f x) of (p,q) -> rhs
Since 'f' may set the cost centre, we must restore it
before resuming rhs. So we want code like this:
- local_cc = CCC -- save
- r = f( x )
- CCC = local_cc -- restore
+ local_cc = CCC -- save
+ r = f( x )
+ CCC = local_cc -- restore
That is, we explicitly "save" the current cost centre in
a LocalReg, local_cc; and restore it after the call. The
C-- infrastructure will arrange to save local_cc across the
call.
The same goes for join points;
- let j x = join-stuff
- in blah-blah
+ let j x = join-stuff
+ in blah-blah
We want this kind of code:
- local_cc = CCC -- save
- blah-blah
+ local_cc = CCC -- save
+ blah-blah
J:
CCC = local_cc -- restore
-}
saveCurrentCostCentre :: FCode (Maybe LocalReg)
- -- Returns Nothing if profiling is off
+ -- Returns Nothing if profiling is off
saveCurrentCostCentre
= do dflags <- getDynFlags
if not (gopt Opt_SccProfilingOn dflags)
@@ -207,7 +200,7 @@ ifProfilingL dflags xs
---------------------------------------------------------------
--- Initialising Cost Centres & CCSs
+-- Initialising Cost Centres & CCSs
---------------------------------------------------------------
initCostCentres :: CollectedCCs -> FCode ()
@@ -233,15 +226,15 @@ emitCostCentreDecl cc = do
showPpr dflags (costCentreSrcSpan cc)
-- XXX going via FastString to get UTF-8 encoding is silly
; let
- lits = [ zero dflags, -- StgInt ccID,
- label, -- char *label,
- modl, -- char *module,
+ lits = [ zero dflags, -- StgInt ccID,
+ label, -- char *label,
+ modl, -- char *module,
loc, -- char *srcloc,
zero64, -- StgWord64 mem_alloc
zero dflags, -- StgWord time_ticks
is_caf, -- StgInt is_caf
zero dflags -- struct _CostCentre *link
- ]
+ ]
; emitDataLits (mkCCLabel cc) lits
}
@@ -290,19 +283,19 @@ emitSetCCC cc tick push
pushCostCentre :: LocalReg -> CmmExpr -> CostCentre -> FCode ()
pushCostCentre result ccs cc
= emitRtsCallWithResult result AddrHint
- rtsPackageId
+ rtsPackageId
(fsLit "pushCostCentre") [(ccs,AddrHint),
- (CmmLit (mkCCostCentre cc), AddrHint)]
+ (CmmLit (mkCCostCentre cc), AddrHint)]
False
bumpSccCount :: DynFlags -> CmmExpr -> CmmAGraph
bumpSccCount dflags ccs
= addToMem (rEP_CostCentreStack_scc_count dflags)
- (cmmOffsetB dflags ccs (oFFSET_CostCentreStack_scc_count dflags)) 1
+ (cmmOffsetB dflags ccs (oFFSET_CostCentreStack_scc_count dflags)) 1
-----------------------------------------------------------------------------
--
--- Lag/drag/void stuff
+-- Lag/drag/void stuff
--
-----------------------------------------------------------------------------
diff --git a/compiler/coreSyn/CoreSubst.lhs b/compiler/coreSyn/CoreSubst.lhs
index 25a751b423..2e6d907b51 100644
--- a/compiler/coreSyn/CoreSubst.lhs
+++ b/compiler/coreSyn/CoreSubst.lhs
@@ -22,7 +22,7 @@ module CoreSubst (
deShadowBinds, substSpec, substRulesForImportedIds,
substTy, substCo, substExpr, substExprSC, substBind, substBindSC,
substUnfolding, substUnfoldingSC,
- substUnfoldingSource, lookupIdSubst, lookupTvSubst, lookupCvSubst, substIdOcc,
+ lookupIdSubst, lookupTvSubst, lookupCvSubst, substIdOcc,
substTickish,
-- ** Operations on substitutions
@@ -665,36 +665,13 @@ substUnfolding subst unf@(CoreUnfolding { uf_tmpl = tmpl, uf_src = src })
| not (isStableSource src) -- Zap an unstable unfolding, to save substitution work
= NoUnfolding
| otherwise -- But keep a stable one!
- = seqExpr new_tmpl `seq`
- new_src `seq`
- unf { uf_tmpl = new_tmpl, uf_src = new_src }
+ = seqExpr new_tmpl `seq`
+ unf { uf_tmpl = new_tmpl }
where
new_tmpl = substExpr (text "subst-unf") subst tmpl
- new_src = substUnfoldingSource subst src
substUnfolding _ unf = unf -- NoUnfolding, OtherCon
--------------------
-substUnfoldingSource :: Subst -> UnfoldingSource -> UnfoldingSource
-substUnfoldingSource (Subst in_scope ids _ _) (InlineWrapper wkr)
- | Just wkr_expr <- lookupVarEnv ids wkr
- = case wkr_expr of
- Var w1 -> InlineWrapper w1
- _other -> -- WARN( True, text "Interesting! CoreSubst.substWorker1:" <+> ppr wkr
- -- <+> ifPprDebug (equals <+> ppr wkr_expr) )
- -- Note [Worker inlining]
- InlineStable -- It's not a wrapper any more, but still inline it!
-
- | Just w1 <- lookupInScope in_scope wkr = InlineWrapper w1
- | otherwise = -- WARN( True, text "Interesting! CoreSubst.substWorker2:" <+> ppr wkr )
- -- This can legitimately happen. The worker has been inlined and
- -- dropped as dead code, because we don't treat the UnfoldingSource
- -- as an "occurrence".
- -- Note [Worker inlining]
- InlineStable
-
-substUnfoldingSource _ src = src
-
------------------
substIdOcc :: Subst -> Id -> Id
-- These Ids should not be substituted to non-Ids
diff --git a/compiler/coreSyn/CoreSyn.lhs b/compiler/coreSyn/CoreSyn.lhs
index ede3a4052b..dd7307d190 100644
--- a/compiler/coreSyn/CoreSyn.lhs
+++ b/compiler/coreSyn/CoreSyn.lhs
@@ -739,12 +739,12 @@ data UnfoldingSource
-- (see MkId.lhs, calls to mkCompulsoryUnfolding).
-- Inline absolutely always, however boring the context.
- | InlineWrapper Id -- This unfolding is a the wrapper in a
- -- worker/wrapper split from the strictness analyser
- -- The Id is the worker-id
- -- Used to abbreviate the uf_tmpl in interface files
- -- which don't need to contain the RHS;
- -- it can be derived from the strictness info
+ | InlineWrapper -- This unfolding is the wrapper in a
+ -- worker/wrapper split from the strictness
+ -- analyser
+ --
+ -- cf some history in TcIface's Note [wrappers
+ -- in interface files]
@@ -844,9 +844,9 @@ isStableSource :: UnfoldingSource -> Bool
-- Keep the unfolding template
isStableSource InlineCompulsory = True
isStableSource InlineStable = True
-isStableSource (InlineWrapper {}) = True
+isStableSource InlineWrapper = True
isStableSource InlineRhs = False
-
+
-- | Retrieves the template of an unfolding: panics if none is known
unfoldingTemplate :: Unfolding -> CoreExpr
unfoldingTemplate = uf_tmpl
diff --git a/compiler/coreSyn/CoreTidy.lhs b/compiler/coreSyn/CoreTidy.lhs
index 8d45fbb9b4..f0c947246a 100644
--- a/compiler/coreSyn/CoreTidy.lhs
+++ b/compiler/coreSyn/CoreTidy.lhs
@@ -215,15 +215,10 @@ tidyUnfolding tidy_env
unf@(CoreUnfolding { uf_tmpl = unf_rhs, uf_src = src })
unf_from_rhs
| isStableSource src
- = unf { uf_tmpl = tidyExpr tidy_env unf_rhs, -- Preserves OccInfo
- uf_src = tidySrc tidy_env src }
+ = unf { uf_tmpl = tidyExpr tidy_env unf_rhs } -- Preserves OccInfo
| otherwise
= unf_from_rhs
tidyUnfolding _ unf _ = unf -- NoUnfolding or OtherCon
-
-tidySrc :: TidyEnv -> UnfoldingSource -> UnfoldingSource
-tidySrc tidy_env (InlineWrapper w) = InlineWrapper (tidyVarOcc tidy_env w)
-tidySrc _ inl_info = inl_info
\end{code}
Note [Tidy IdInfo]
diff --git a/compiler/coreSyn/CoreUnfold.lhs b/compiler/coreSyn/CoreUnfold.lhs
index 83a40d299a..bbf9e0eb40 100644
--- a/compiler/coreSyn/CoreUnfold.lhs
+++ b/compiler/coreSyn/CoreUnfold.lhs
@@ -101,9 +101,9 @@ mkDFunUnfolding :: [Var] -> DataCon -> [CoreExpr] -> Unfolding
mkDFunUnfolding bndrs con ops
= DFunUnfolding { df_bndrs = bndrs, df_con = con, df_args = ops }
-mkWwInlineRule :: Id -> CoreExpr -> Arity -> Unfolding
-mkWwInlineRule id expr arity
- = mkCoreUnfolding (InlineWrapper id) True
+mkWwInlineRule :: CoreExpr -> Arity -> Unfolding
+mkWwInlineRule expr arity
+ = mkCoreUnfolding InlineWrapper True
(simpleOptExpr expr) arity
(UnfWhen unSaturatedOk boringCxtNotOk)
diff --git a/compiler/coreSyn/CoreUtils.lhs b/compiler/coreSyn/CoreUtils.lhs
index ddf4406081..06f167cce0 100644
--- a/compiler/coreSyn/CoreUtils.lhs
+++ b/compiler/coreSyn/CoreUtils.lhs
@@ -139,33 +139,33 @@ Various possibilities suggest themselves:
\begin{code}
applyTypeToArg :: Type -> CoreExpr -> Type
--- ^ Determines the type resulting from applying an expression to a function with the given type
+-- ^ Determines the type resulting from applying an expression with given type
+-- to a given argument expression
applyTypeToArg fun_ty (Type arg_ty) = applyTy fun_ty arg_ty
applyTypeToArg fun_ty _ = funResultTy fun_ty
applyTypeToArgs :: CoreExpr -> Type -> [CoreExpr] -> Type
-- ^ A more efficient version of 'applyTypeToArg' when we have several arguments.
-- The first argument is just for debugging, and gives some context
-applyTypeToArgs _ op_ty [] = op_ty
-
-applyTypeToArgs e op_ty (Type ty : args)
- = -- Accumulate type arguments so we can instantiate all at once
- go [ty] args
+applyTypeToArgs e op_ty args
+ = go op_ty args
where
- go rev_tys (Type ty : args) = go (ty:rev_tys) args
- go rev_tys rest_args = applyTypeToArgs e op_ty' rest_args
- where
- op_ty' = applyTysD msg op_ty (reverse rev_tys)
- msg = ptext (sLit "applyTypeToArgs") <+>
- panic_msg e op_ty
-
-applyTypeToArgs e op_ty (_ : args)
- = case (splitFunTy_maybe op_ty) of
- Just (_, res_ty) -> applyTypeToArgs e res_ty args
- Nothing -> pprPanic "applyTypeToArgs" (panic_msg e op_ty)
-
-panic_msg :: CoreExpr -> Type -> SDoc
-panic_msg e op_ty = pprCoreExpr e $$ ppr op_ty
+ go op_ty [] = op_ty
+ go op_ty (Type ty : args) = go_ty_args op_ty [ty] args
+ go op_ty (_ : args) | Just (_, res_ty) <- splitFunTy_maybe op_ty
+ = go res_ty args
+ go _ _ = pprPanic "applyTypeToArgs" panic_msg
+
+ -- go_ty_args: accumulate type arguments so we can instantiate all at once
+ go_ty_args op_ty rev_tys (Type ty : args)
+ = go_ty_args op_ty (ty:rev_tys) args
+ go_ty_args op_ty rev_tys args
+ = go (applyTysD panic_msg_w_hdr op_ty (reverse rev_tys)) args
+
+ panic_msg_w_hdr = hang (ptext (sLit "applyTypeToArgs")) 2 panic_msg
+ panic_msg = vcat [ ptext (sLit "Expression:") <+> pprCoreExpr e
+ , ptext (sLit "Type:") <+> ppr op_ty
+ , ptext (sLit "Args:") <+> ppr args ]
\end{code}
%************************************************************************
@@ -1623,10 +1623,10 @@ tryEtaReduce bndrs body
-- for why we have an accumulating coercion
go [] fun co
| ok_fun fun
- , let result = mkCast fun co
- , not (any (`elemVarSet` exprFreeVars result) bndrs)
- = Just result -- Check for any of the binders free in the result
- -- including the accumulated coercion
+ , let used_vars = exprFreeVars fun `unionVarSet` tyCoVarsOfCo co
+ , not (any (`elemVarSet` used_vars) bndrs)
+ = Just (mkCast fun co) -- Check for any of the binders free in the result
+ -- including the accumulated coercion
go (b : bs) (App fun arg) co
| Just co' <- ok_arg b arg co
diff --git a/compiler/coreSyn/PprCore.lhs b/compiler/coreSyn/PprCore.lhs
index 0a6914e0b8..64e7d63590 100644
--- a/compiler/coreSyn/PprCore.lhs
+++ b/compiler/coreSyn/PprCore.lhs
@@ -422,7 +422,7 @@ instance Outputable UnfoldingGuidance where
instance Outputable UnfoldingSource where
ppr InlineCompulsory = ptext (sLit "Compulsory")
- ppr (InlineWrapper w) = ptext (sLit "Worker=") <> ppr w
+ ppr InlineWrapper = ptext (sLit "Wrapper")
ppr InlineStable = ptext (sLit "InlineStable")
ppr InlineRhs = ptext (sLit "<vanilla>")
diff --git a/compiler/deSugar/DsMeta.hs b/compiler/deSugar/DsMeta.hs
index 7a8fd2da70..218b00e8d0 100644
--- a/compiler/deSugar/DsMeta.hs
+++ b/compiler/deSugar/DsMeta.hs
@@ -1127,6 +1127,19 @@ repSts (BodyStmt e _ _ _ : ss) =
; z <- repNoBindSt e2
; (ss2,zs) <- repSts ss
; return (ss2, z : zs) }
+repSts (ParStmt stmt_blocks _ _ : ss) =
+ do { (ss_s, stmt_blocks1) <- mapAndUnzipM rep_stmt_block stmt_blocks
+ ; let stmt_blocks2 = nonEmptyCoreList stmt_blocks1
+ ss1 = concat ss_s
+ ; z <- repParSt stmt_blocks2
+ ; (ss2, zs) <- addBinds ss1 (repSts ss)
+ ; return (ss1++ss2, z : zs) }
+ where
+ rep_stmt_block :: ParStmtBlock Name Name -> DsM ([GenSymBind], Core [TH.StmtQ])
+ rep_stmt_block (ParStmtBlock stmts _ _) =
+ do { (ss1, zs) <- repSts (map unLoc stmts)
+ ; zs1 <- coreList stmtQTyConName zs
+ ; return (ss1, zs1) }
repSts [LastStmt e _]
= do { e2 <- repLE e
; z <- repNoBindSt e2
@@ -1618,6 +1631,9 @@ repLetSt (MkC ds) = rep2 letSName [ds]
repNoBindSt :: Core TH.ExpQ -> DsM (Core TH.StmtQ)
repNoBindSt (MkC e) = rep2 noBindSName [e]
+repParSt :: Core [[TH.StmtQ]] -> DsM (Core TH.StmtQ)
+repParSt (MkC sss) = rep2 parSName [sss]
+
-------------- Range (Arithmetic sequences) -----------
repFrom :: Core TH.ExpQ -> DsM (Core TH.ExpQ)
repFrom (MkC x) = rep2 fromEName [x]
diff --git a/compiler/ghci/ByteCodeInstr.lhs b/compiler/ghci/ByteCodeInstr.lhs
index 7fc84ae214..d93b05905c 100644
--- a/compiler/ghci/ByteCodeInstr.lhs
+++ b/compiler/ghci/ByteCodeInstr.lhs
@@ -86,7 +86,7 @@ data BCInstr
-- designers of the new Foreign library. In particular it is
-- quite impossible to convert an Addr to any other integral
-- type, and it appears impossible to get hold of the bits of
- -- an addr, even though we need to to assemble BCOs.
+ -- an addr, even though we need to assemble BCOs.
-- various kinds of application
| PUSH_APPLY_N
diff --git a/compiler/hsSyn/HsBinds.lhs b/compiler/hsSyn/HsBinds.lhs
index cb2538f574..db4c177b90 100644
--- a/compiler/hsSyn/HsBinds.lhs
+++ b/compiler/hsSyn/HsBinds.lhs
@@ -53,8 +53,9 @@ Global bindings (where clauses)
type HsLocalBinds id = HsLocalBindsLR id id
-data HsLocalBindsLR idL idR -- Bindings in a 'let' expression
- -- or a 'where' clause
+-- | Bindings in a 'let' expression
+-- or a 'where' clause
+data HsLocalBindsLR idL idR
= HsValBinds (HsValBindsLR idL idR)
| HsIPBinds (HsIPBinds idR)
| EmptyLocalBinds
@@ -62,15 +63,20 @@ data HsLocalBindsLR idL idR -- Bindings in a 'let' expression
type HsValBinds id = HsValBindsLR id id
-data HsValBindsLR idL idR -- Value bindings (not implicit parameters)
- = ValBindsIn -- Before renaming RHS; idR is always RdrName
- (LHsBindsLR idL idR) [LSig idR] -- Not dependency analysed
- -- Recursive by default
-
- | ValBindsOut -- After renaming RHS; idR can be Name or Id
- [(RecFlag, LHsBinds idL)] -- Dependency analysed, later bindings
- -- in the list may depend on earlier
- -- ones.
+-- | Value bindings (not implicit parameters)
+data HsValBindsLR idL idR
+ = -- | Before renaming RHS; idR is always RdrName
+ -- Not dependency analysed
+ -- Recursive by default
+ ValBindsIn
+ (LHsBindsLR idL idR) [LSig idR]
+
+ -- | After renaming RHS; idR can be Name or Id
+ -- Dependency analysed,
+ -- later bindings in the list may depend on earlier
+ -- ones.
+ | ValBindsOut
+ [(RecFlag, LHsBinds idL)]
[LSig Name]
deriving (Data, Typeable)
@@ -121,35 +127,38 @@ data HsBindLR idL idR
fun_tick :: Maybe (Tickish Id) -- ^ Tick to put on the rhs, if any
}
- | PatBind { -- The pattern is never a simple variable;
- -- That case is done by FunBind
+ -- | The pattern is never a simple variable;
+ -- That case is done by FunBind
+ | PatBind {
pat_lhs :: LPat idL,
pat_rhs :: GRHSs idR (LHsExpr idR),
- pat_rhs_ty :: PostTcType, -- Type of the GRHSs
- bind_fvs :: NameSet, -- See Note [Bind free vars]
+ pat_rhs_ty :: PostTcType, -- ^ Type of the GRHSs
+ bind_fvs :: NameSet, -- ^ See Note [Bind free vars]
pat_ticks :: (Maybe (Tickish Id), [Maybe (Tickish Id)])
-- ^ Tick to put on the rhs, if any, and ticks to put on
-- the bound variables.
}
- | VarBind { -- Dictionary binding and suchlike
- var_id :: idL, -- All VarBinds are introduced by the type checker
- var_rhs :: LHsExpr idR, -- Located only for consistency
- var_inline :: Bool -- True <=> inline this binding regardless
+ -- | Dictionary binding and suchlike.
+ -- All VarBinds are introduced by the type checker
+ | VarBind {
+ var_id :: idL,
+ var_rhs :: LHsExpr idR, -- ^ Located only for consistency
+ var_inline :: Bool -- ^ True <=> inline this binding regardless
-- (used for implication constraints only)
}
- | AbsBinds { -- Binds abstraction; TRANSLATION
+ | AbsBinds { -- Binds abstraction; TRANSLATION
abs_tvs :: [TyVar],
- abs_ev_vars :: [EvVar], -- Includes equality constraints
+ abs_ev_vars :: [EvVar], -- ^ Includes equality constraints
- -- AbsBinds only gets used when idL = idR after renaming,
+ -- | AbsBinds only gets used when idL = idR after renaming,
-- but these need to be idL's for the collect... code in HsUtil
-- to have the right type
abs_exports :: [ABExport idL],
- abs_ev_binds :: TcEvBinds, -- Evidence bindings
- abs_binds :: LHsBinds idL -- Typechecked user bindings
+ abs_ev_binds :: TcEvBinds, -- ^ Evidence bindings
+ abs_binds :: LHsBinds idL -- ^ Typechecked user bindings
}
deriving (Data, Typeable)
@@ -166,15 +175,15 @@ data HsBindLR idL idR
-- See Note [AbsBinds]
data ABExport id
- = ABE { abe_poly :: id -- Any INLINE pragmas is attached to this Id
+ = ABE { abe_poly :: id -- ^ Any INLINE pragmas is attached to this Id
, abe_mono :: id
- , abe_wrap :: HsWrapper -- See Note [AbsBinds wrappers]
+ , abe_wrap :: HsWrapper -- ^ See Note [AbsBinds wrappers]
-- Shape: (forall abs_tvs. abs_ev_vars => abe_mono) ~ abe_poly
- , abe_prags :: TcSpecPrags -- SPECIALISE pragmas
+ , abe_prags :: TcSpecPrags -- ^ SPECIALISE pragmas
} deriving (Data, Typeable)
+-- | Used for the NameSet in FunBind and PatBind prior to the renamer
placeHolderNames :: NameSet
--- Used for the NameSet in FunBind and PatBind prior to the renamer
placeHolderNames = panic "placeHolderNames"
\end{code}
@@ -501,43 +510,55 @@ serves for both.
\begin{code}
type LSig name = Located (Sig name)
-data Sig name -- Signatures and pragmas
- = -- An ordinary type signature
- -- f :: Num a => a -> a
+-- | Signatures and pragmas
+data Sig name
+ = -- | An ordinary type signature
+ -- @f :: Num a => a -> a@
TypeSig [Located name] (LHsType name)
- -- A type signature for a default method inside a class
- -- default eq :: (Representable0 a, GEq (Rep0 a)) => a -> a -> Bool
+ -- | A type signature for a default method inside a class
+ --
+ -- > default eq :: (Representable0 a, GEq (Rep0 a)) => a -> a -> Bool
+ --
| GenericSig [Located name] (LHsType name)
- -- A type signature in generated code, notably the code
+ -- | A type signature in generated code, notably the code
-- generated for record selectors. We simply record
-- the desired Id itself, replete with its name, type
-- and IdDetails. Otherwise it's just like a type
-- signature: there should be an accompanying binding
| IdSig Id
- -- An ordinary fixity declaration
- -- infixl *** 8
+ -- | An ordinary fixity declaration
+ --
+ -- > infixl *** 8
+ --
| FixSig (FixitySig name)
- -- An inline pragma
- -- {#- INLINE f #-}
+ -- | An inline pragma
+ --
+ -- > {#- INLINE f #-}
+ --
| InlineSig (Located name) -- Function name
InlinePragma -- Never defaultInlinePragma
- -- A specialisation pragma
- -- {-# SPECIALISE f :: Int -> Int #-}
- | SpecSig (Located name) -- Specialise a function or datatype ...
+ -- | A specialisation pragma
+ --
+ -- > {-# SPECIALISE f :: Int -> Int #-}
+ --
+ | SpecSig (Located name) -- Specialise a function or datatype ...
(LHsType name) -- ... to these types
- InlinePragma -- The pragma on SPECIALISE_INLINE form
+ InlinePragma -- The pragma on SPECIALISE_INLINE form.
-- If it's just defaultInlinePragma, then we said
-- SPECIALISE, not SPECIALISE_INLINE
- -- A specialisation pragma for instance declarations only
- -- {-# SPECIALISE instance Eq [Int] #-}
- | SpecInstSig (LHsType name) -- (Class tys); should be a specialisation of the
- -- current instance decl
+ -- | A specialisation pragma for instance declarations only
+ --
+ -- > {-# SPECIALISE instance Eq [Int] #-}
+ --
+ -- (Class tys); should be a specialisation of the
+ -- current instance declaration
+ | SpecInstSig (LHsType name)
deriving (Data, Typeable)
@@ -545,9 +566,9 @@ type LFixitySig name = Located (FixitySig name)
data FixitySig name = FixitySig (Located name) Fixity
deriving (Data, Typeable)
--- TsSpecPrags conveys pragmas from the type checker to the desugarer
+-- | TsSpecPrags conveys pragmas from the type checker to the desugarer
data TcSpecPrags
- = IsDefaultMethod -- Super-specialised: a default method should
+ = IsDefaultMethod -- ^ Super-specialised: a default method should
-- be macro-expanded at every call site
| SpecPrags [LTcSpecPrag]
deriving (Data, Typeable)
@@ -556,9 +577,11 @@ type LTcSpecPrag = Located TcSpecPrag
data TcSpecPrag
= SpecPrag
- Id -- The Id to be specialised
- HsWrapper -- An wrapper, that specialises the polymorphic function
- InlinePragma -- Inlining spec for the specialised function
+ Id
+ HsWrapper
+ InlinePragma
+ -- ^ The Id to be specialised, an wrapper that specialises the
+ -- polymorphic function, and inlining spec for the specialised function
deriving (Data, Typeable)
noSpecPrags :: TcSpecPrags
@@ -572,9 +595,7 @@ isDefaultMethod :: TcSpecPrags -> Bool
isDefaultMethod IsDefaultMethod = True
isDefaultMethod (SpecPrags {}) = False
-\end{code}
-\begin{code}
isFixityLSig :: LSig name -> Bool
isFixityLSig (L _ (FixSig {})) = True
isFixityLSig _ = False
diff --git a/compiler/hsSyn/HsExpr.lhs b/compiler/hsSyn/HsExpr.lhs
index ccbfc63a31..27286ca928 100644
--- a/compiler/hsSyn/HsExpr.lhs
+++ b/compiler/hsSyn/HsExpr.lhs
@@ -121,19 +121,19 @@ is Less Cool because
\begin{code}
-- | A Haskell expression.
data HsExpr id
- = HsVar id -- ^ variable
- | HsIPVar HsIPName -- ^ implicit parameter
+ = HsVar id -- ^ Variable
+ | HsIPVar HsIPName -- ^ Implicit parameter
| HsOverLit (HsOverLit id) -- ^ Overloaded literals
| HsLit HsLit -- ^ Simple (non-overloaded) literals
- | HsLam (MatchGroup id (LHsExpr id)) -- Currently always a single match
+ | HsLam (MatchGroup id (LHsExpr id)) -- ^ Lambda abstraction. Currently always a single match
- | HsLamCase PostTcType (MatchGroup id (LHsExpr id)) -- Lambda-case
+ | HsLamCase PostTcType (MatchGroup id (LHsExpr id)) -- ^ Lambda-case
- | HsApp (LHsExpr id) (LHsExpr id) -- Application
+ | HsApp (LHsExpr id) (LHsExpr id) -- ^ Application
- -- Operator applications:
+ -- | Operator applications:
-- NB Bracketed ops such as (+) come out as Vars.
-- NB We need an expr for the operator in an OpApp/Section since
@@ -144,17 +144,20 @@ data HsExpr id
Fixity -- Renamer adds fixity; bottom until then
(LHsExpr id) -- right operand
- | NegApp (LHsExpr id) -- negated expr
- (SyntaxExpr id) -- Name of 'negate'
+ -- | Negation operator. Contains the negated expression and the name
+ -- of 'negate'
+ | NegApp (LHsExpr id)
+ (SyntaxExpr id)
- | HsPar (LHsExpr id) -- Parenthesised expr; see Note [Parens in HsSyn]
+ | HsPar (LHsExpr id) -- ^ Parenthesised expr; see Note [Parens in HsSyn]
| SectionL (LHsExpr id) -- operand; see Note [Sections in HsSyn]
(LHsExpr id) -- operator
| SectionR (LHsExpr id) -- operator; see Note [Sections in HsSyn]
(LHsExpr id) -- operand
- | ExplicitTuple -- Used for explicit tuples and sections thereof
+ -- | Used for explicit tuples and sections thereof
+ | ExplicitTuple
[HsTupArg id]
Boxity
@@ -168,9 +171,11 @@ data HsExpr id
(LHsExpr id) -- then part
(LHsExpr id) -- else part
- | HsMultiIf PostTcType [LGRHS id (LHsExpr id)] -- Multi-way if
+ -- | Multi-way if
+ | HsMultiIf PostTcType [LGRHS id (LHsExpr id)]
- | HsLet (HsLocalBinds id) -- let(rec)
+ -- | let(rec)
+ | HsLet (HsLocalBinds id)
(LHsExpr id)
| HsDo (HsStmtContext Name) -- The parameterisation is unimportant
@@ -179,22 +184,24 @@ data HsExpr id
[ExprLStmt id] -- "do":one or more stmts
PostTcType -- Type of the whole expression
- | ExplicitList -- syntactic list
+ -- | Syntactic list: [a,b,c,...]
+ | ExplicitList
PostTcType -- Gives type of components of list
(Maybe (SyntaxExpr id)) -- For OverloadedLists, the fromListN witness
[LHsExpr id]
- | ExplicitPArr -- syntactic parallel array: [:e1, ..., en:]
+ -- | Syntactic parallel array: [:e1, ..., en:]
+ | ExplicitPArr
PostTcType -- type of elements of the parallel array
[LHsExpr id]
- -- Record construction
+ -- | Record construction
| RecordCon (Located id) -- The constructor. After type checking
-- it's the dataConWrapId of the constructor
PostTcExpr -- Data con Id applied to type args
(HsRecordBinds id)
- -- Record update
+ -- | Record update
| RecordUpd (LHsExpr id)
(HsRecordBinds id)
-- (HsMatchGroup Id) -- Filled in by the type checker to be
@@ -207,7 +214,8 @@ data HsExpr id
-- For a type family, the arg types are of the *instance* tycon,
-- not the family tycon
- | ExprWithTySig -- e :: type
+ -- | Expression with an explicit type signature. @e :: type@
+ | ExprWithTySig
(LHsExpr id)
(LHsType id)
@@ -216,12 +224,14 @@ data HsExpr id
(LHsType Name) -- Retain the signature for
-- round-tripping purposes
- | ArithSeq -- Arithmetic sequence
+ -- | Arithmetic sequence
+ | ArithSeq
PostTcExpr
(Maybe (SyntaxExpr id)) -- For OverloadedLists, the fromList witness
(ArithSeqInfo id)
- | PArrSeq -- arith. sequence for parallel array
+ -- | Arithmetic sequence for parallel array
+ | PArrSeq
PostTcExpr -- [:e1..e2:] or [:e1, e2..e3:]
(ArithSeqInfo id)
@@ -250,6 +260,7 @@ data HsExpr id
-----------------------------------------------------------
-- Arrow notation extension
+ -- | @proc@ notation for Arrows
| HsProc (LPat id) -- arrow abstraction, proc
(LHsCmdTop id) -- body of the abstraction
-- always has an empty stack
@@ -315,20 +326,21 @@ data HsExpr id
| HsUnboundVar RdrName
deriving (Data, Typeable)
--- HsTupArg is used for tuple sections
+-- | HsTupArg is used for tuple sections
-- (,a,) is represented by ExplicitTuple [Mising ty1, Present a, Missing ty3]
-- Which in turn stands for (\x:ty1 \y:ty2. (x,a,y))
data HsTupArg id
- = Present (LHsExpr id) -- The argument
- | Missing PostTcType -- The argument is missing, but this is its type
+ = Present (LHsExpr id) -- ^ The argument
+ | Missing PostTcType -- ^ The argument is missing, but this is its type
deriving (Data, Typeable)
tupArgPresent :: HsTupArg id -> Bool
tupArgPresent (Present {}) = True
tupArgPresent (Missing {}) = False
-type PendingSplice = (Name, LHsExpr Id) -- Typechecked splices, waiting to be
- -- pasted back in by the desugarer
+-- | Typechecked splices, waiting to be
+-- pasted back in by the desugarer
+type PendingSplice = (Name, LHsExpr Id)
\end{code}
diff --git a/compiler/iface/BinIface.hs b/compiler/iface/BinIface.hs
index b0bb88789d..c4c1bcd69e 100644
--- a/compiler/iface/BinIface.hs
+++ b/compiler/iface/BinIface.hs
@@ -414,5 +414,3 @@ getWayDescr dflags
where tag = buildTag dflags
-- if this is an unregisterised build, make sure our interfaces
-- can't be used by a registerised build.
-
-
diff --git a/compiler/iface/IfaceSyn.lhs b/compiler/iface/IfaceSyn.lhs
index 497c3ae525..8dc4188bb9 100644
--- a/compiler/iface/IfaceSyn.lhs
+++ b/compiler/iface/IfaceSyn.lhs
@@ -583,9 +583,7 @@ data IfaceUnfolding
Bool -- OK to inline even if context is boring
IfaceExpr
- | IfExtWrapper Arity IfExtName -- NB: sometimes we need a IfExtName (not just IfLclName)
- | IfLclWrapper Arity IfLclName -- because the worker can simplify to a function in
- -- another module.
+ | IfWrapper IfaceExpr -- cf TcIface's Note [wrappers in interface files]
| IfDFunUnfold [IfaceBndr] [IfaceExpr]
@@ -600,20 +598,15 @@ instance Binary IfaceUnfolding where
put_ bh b
put_ bh c
put_ bh d
- put_ bh (IfLclWrapper a n) = do
+ put_ bh (IfWrapper e) = do
putByte bh 2
- put_ bh a
- put_ bh n
- put_ bh (IfExtWrapper a n) = do
- putByte bh 3
- put_ bh a
- put_ bh n
+ put_ bh e
put_ bh (IfDFunUnfold as bs) = do
- putByte bh 4
+ putByte bh 3
put_ bh as
put_ bh bs
put_ bh (IfCompulsory e) = do
- putByte bh 5
+ putByte bh 4
put_ bh e
get bh = do
h <- getByte bh
@@ -626,13 +619,9 @@ instance Binary IfaceUnfolding where
c <- get bh
d <- get bh
return (IfInlineRule a b c d)
- 2 -> do a <- get bh
- n <- get bh
- return (IfLclWrapper a n)
- 3 -> do a <- get bh
- n <- get bh
- return (IfExtWrapper a n)
- 4 -> do as <- get bh
+ 2 -> do e <- get bh
+ return (IfWrapper e)
+ 3 -> do as <- get bh
bs <- get bh
return (IfDFunUnfold as bs)
_ -> do e <- get bh
@@ -1299,10 +1288,7 @@ instance Outputable IfaceUnfolding where
ppr (IfInlineRule a uok bok e) = sep [ptext (sLit "InlineRule")
<+> ppr (a,uok,bok),
pprParendIfaceExpr e]
- ppr (IfLclWrapper a wkr) = ptext (sLit "Worker(lcl):") <+> ppr wkr
- <+> parens (ptext (sLit "arity") <+> int a)
- ppr (IfExtWrapper a wkr) = ptext (sLit "Worker(ext):") <+> ppr wkr
- <+> parens (ptext (sLit "arity") <+> int a)
+ ppr (IfWrapper e) = ptext (sLit "Wrapper:") <+> parens (ppr e)
ppr (IfDFunUnfold bs es) = hang (ptext (sLit "DFun:") <+> sep (map ppr bs) <> dot)
2 (sep (map pprParendIfaceExpr es))
@@ -1460,8 +1446,7 @@ freeNamesIfUnfold :: IfaceUnfolding -> NameSet
freeNamesIfUnfold (IfCoreUnfold _ e) = freeNamesIfExpr e
freeNamesIfUnfold (IfCompulsory e) = freeNamesIfExpr e
freeNamesIfUnfold (IfInlineRule _ _ _ e) = freeNamesIfExpr e
-freeNamesIfUnfold (IfExtWrapper _ v) = unitNameSet v
-freeNamesIfUnfold (IfLclWrapper {}) = emptyNameSet
+freeNamesIfUnfold (IfWrapper e) = freeNamesIfExpr e
freeNamesIfUnfold (IfDFunUnfold bs es) = fnList freeNamesIfBndr bs &&& fnList freeNamesIfExpr es
freeNamesIfExpr :: IfaceExpr -> NameSet
diff --git a/compiler/iface/MkIface.lhs b/compiler/iface/MkIface.lhs
index 94c5264d35..d3b56d1f7b 100644
--- a/compiler/iface/MkIface.lhs
+++ b/compiler/iface/MkIface.lhs
@@ -7,10 +7,10 @@
-- | Module for constructing @ModIface@ values (interface files),
-- writing them to disk and comparing two versions to see if
-- recompilation is required.
-module MkIface (
+module MkIface (
mkUsedNames,
mkDependencies,
- mkIface, -- Build a ModIface from a ModGuts,
+ mkIface, -- Build a ModIface from a ModGuts,
-- including computing version information
mkIfaceTc,
@@ -37,9 +37,9 @@ found in the wiki commentary:
Please read the above page for a top-down description of how this all
works. Notes below cover specific issues related to the implementation.
-Basic idea:
+Basic idea:
- * In the mi_usages information in an interface, we record the
+ * In the mi_usages information in an interface, we record the
fingerprint of each free variable of the module
* In mkIface, we compute the fingerprint of each exported thing A.f.
@@ -47,8 +47,10 @@ Basic idea:
of the external reference when computing the fingerprint of A.f. So
if anything that A.f depends on changes, then A.f's fingerprint will
change.
- Also record any dependent files added with addDependentFile.
- In the future record any #include usages.
+ Also record any dependent files added with
+ * addDependentFile
+ * #include
+ * -optP-include
* In checkOldIface we compare the mi_usages for the module with
the actual fingerprint for all each thing recorded in mi_usages
@@ -187,11 +189,11 @@ mkIfaceTc hsc_env maybe_old_fingerprint safe_mode mod_details
this_mod (isHsBoot hsc_src) used_names used_th deps rdr_env
fix_env warns hpc_info (imp_mods imports)
(imp_trust_own_pkg imports) dep_files safe_mode mod_details
-
+
mkUsedNames :: TcGblEnv -> NameSet
mkUsedNames TcGblEnv{ tcg_dus = dus } = allUses dus
-
+
-- | Extract information from the rename and typecheck phases to produce
-- a dependencies information for the module being compiled.
mkDependencies :: TcGblEnv -> IO Dependencies
@@ -200,15 +202,15 @@ mkDependencies
tcg_imports = imports,
tcg_th_used = th_var
}
- = do
+ = do
-- Template Haskell used?
th_used <- readIORef th_var
let dep_mods = eltsUFM (delFromUFM (imp_dep_mods imports) (moduleName mod))
-- M.hi-boot can be in the imp_dep_mods, but we must remove
-- it before recording the modules on which this one depends!
- -- (We want to retain M.hi-boot in imp_dep_mods so that
- -- loadHiBootInterface can see if M's direct imports depend
- -- on M.hi-boot, and hence that we should do the hi-boot consistency
+ -- (We want to retain M.hi-boot in imp_dep_mods so that
+ -- loadHiBootInterface can see if M's direct imports depend
+ -- on M.hi-boot, and hence that we should do the hi-boot consistency
-- check.)
pkgs | th_used = insertList thPackageId (imp_dep_pkgs imports)
@@ -235,10 +237,10 @@ mkIface_ :: HscEnv -> Maybe Fingerprint -> Module -> IsBootInterface
-> SafeHaskellMode
-> ModDetails
-> IO (Messages, Maybe (ModIface, Bool))
-mkIface_ hsc_env maybe_old_fingerprint
+mkIface_ hsc_env maybe_old_fingerprint
this_mod is_boot used_names used_th deps rdr_env fix_env src_warns
hpc_info dir_imp_mods pkg_trust_req dependent_files safe_mode
- ModDetails{ md_insts = insts,
+ ModDetails{ md_insts = insts,
md_fam_insts = fam_insts,
md_rules = rules,
md_anns = anns,
@@ -250,104 +252,104 @@ mkIface_ hsc_env maybe_old_fingerprint
-- put exactly the info into the TypeEnv that we want
-- to expose in the interface
- = do { usages <- mkUsageInfo hsc_env this_mod dir_imp_mods used_names dependent_files
-
- ; let { entities = typeEnvElts type_env ;
- decls = [ tyThingToIfaceDecl entity
- | entity <- entities,
- let name = getName entity,
- not (isImplicitTyThing entity),
- -- No implicit Ids and class tycons in the interface file
- not (isWiredInName name),
- -- Nor wired-in things; the compiler knows about them anyhow
- nameIsLocalOrFrom this_mod name ]
- -- Sigh: see Note [Root-main Id] in TcRnDriver
-
- ; fixities = [(occ,fix) | FixItem occ fix <- nameEnvElts fix_env]
- ; warns = src_warns
- ; iface_rules = map (coreRuleToIfaceRule this_mod) rules
- ; iface_insts = map instanceToIfaceInst insts
- ; iface_fam_insts = map famInstToIfaceFamInst fam_insts
- ; iface_vect_info = flattenVectInfo vect_info
- ; trust_info = setSafeMode safe_mode
-
- ; intermediate_iface = ModIface {
- mi_module = this_mod,
- mi_boot = is_boot,
- mi_deps = deps,
- mi_usages = usages,
- mi_exports = mkIfaceExports exports,
-
- -- Sort these lexicographically, so that
- -- the result is stable across compilations
- mi_insts = sortBy cmp_inst iface_insts,
- mi_fam_insts = sortBy cmp_fam_inst iface_fam_insts,
- mi_rules = sortBy cmp_rule iface_rules,
-
- mi_vect_info = iface_vect_info,
-
- mi_fixities = fixities,
- mi_warns = warns,
- mi_anns = mkIfaceAnnotations anns,
- mi_globals = maybeGlobalRdrEnv rdr_env,
-
- -- Left out deliberately: filled in by addFingerprints
- mi_iface_hash = fingerprint0,
- mi_mod_hash = fingerprint0,
- mi_flag_hash = fingerprint0,
- mi_exp_hash = fingerprint0,
- mi_used_th = used_th,
- mi_orphan_hash = fingerprint0,
- mi_orphan = False, -- Always set by addFingerprints, but
- -- it's a strict field, so we can't omit it.
- mi_finsts = False, -- Ditto
- mi_decls = deliberatelyOmitted "decls",
- mi_hash_fn = deliberatelyOmitted "hash_fn",
- mi_hpc = isHpcUsed hpc_info,
- mi_trust = trust_info,
- mi_trust_pkg = pkg_trust_req,
-
- -- And build the cached values
- mi_warn_fn = mkIfaceWarnCache warns,
- mi_fix_fn = mkIfaceFixCache fixities }
- }
- ; (new_iface, no_change_at_all)
- <- {-# SCC "versioninfo" #-}
- addFingerprints hsc_env maybe_old_fingerprint
- intermediate_iface decls
-
- -- Warn about orphans
- ; let warn_orphs = wopt Opt_WarnOrphans dflags
- warn_auto_orphs = wopt Opt_WarnAutoOrphans dflags
- orph_warnings --- Laziness means no work done unless -fwarn-orphans
- | warn_orphs || warn_auto_orphs = rule_warns `unionBags` inst_warns
- | otherwise = emptyBag
- errs_and_warns = (orph_warnings, emptyBag)
- unqual = mkPrintUnqualified dflags rdr_env
- inst_warns = listToBag [ instOrphWarn dflags unqual d
- | (d,i) <- insts `zip` iface_insts
- , isNothing (ifInstOrph i) ]
- rule_warns = listToBag [ ruleOrphWarn dflags unqual this_mod r
- | r <- iface_rules
- , isNothing (ifRuleOrph r)
- , if ifRuleAuto r then warn_auto_orphs
- else warn_orphs ]
-
- ; if errorsFound dflags errs_and_warns
- then return ( errs_and_warns, Nothing )
- else do {
-
- -- Debug printing
- ; dumpIfSet_dyn dflags Opt_D_dump_hi "FINAL INTERFACE"
- (pprModIface new_iface)
-
- -- bug #1617: on reload we weren't updating the PrintUnqualified
- -- correctly. This stems from the fact that the interface had
- -- not changed, so addFingerprints returns the old ModIface
- -- with the old GlobalRdrEnv (mi_globals).
- ; let final_iface = new_iface{ mi_globals = maybeGlobalRdrEnv rdr_env }
-
- ; return (errs_and_warns, Just (final_iface, no_change_at_all)) }}
+ = do
+ usages <- mkUsageInfo hsc_env this_mod dir_imp_mods used_names dependent_files
+
+ let entities = typeEnvElts type_env
+ decls = [ tyThingToIfaceDecl entity
+ | entity <- entities,
+ let name = getName entity,
+ not (isImplicitTyThing entity),
+ -- No implicit Ids and class tycons in the interface file
+ not (isWiredInName name),
+ -- Nor wired-in things; the compiler knows about them anyhow
+ nameIsLocalOrFrom this_mod name ]
+ -- Sigh: see Note [Root-main Id] in TcRnDriver
+
+ fixities = [(occ,fix) | FixItem occ fix <- nameEnvElts fix_env]
+ warns = src_warns
+ iface_rules = map (coreRuleToIfaceRule this_mod) rules
+ iface_insts = map instanceToIfaceInst insts
+ iface_fam_insts = map famInstToIfaceFamInst fam_insts
+ iface_vect_info = flattenVectInfo vect_info
+ trust_info = setSafeMode safe_mode
+
+ intermediate_iface = ModIface {
+ mi_module = this_mod,
+ mi_boot = is_boot,
+ mi_deps = deps,
+ mi_usages = usages,
+ mi_exports = mkIfaceExports exports,
+
+ -- Sort these lexicographically, so that
+ -- the result is stable across compilations
+ mi_insts = sortBy cmp_inst iface_insts,
+ mi_fam_insts = sortBy cmp_fam_inst iface_fam_insts,
+ mi_rules = sortBy cmp_rule iface_rules,
+
+ mi_vect_info = iface_vect_info,
+
+ mi_fixities = fixities,
+ mi_warns = warns,
+ mi_anns = mkIfaceAnnotations anns,
+ mi_globals = maybeGlobalRdrEnv rdr_env,
+
+ -- Left out deliberately: filled in by addFingerprints
+ mi_iface_hash = fingerprint0,
+ mi_mod_hash = fingerprint0,
+ mi_flag_hash = fingerprint0,
+ mi_exp_hash = fingerprint0,
+ mi_used_th = used_th,
+ mi_orphan_hash = fingerprint0,
+ mi_orphan = False, -- Always set by addFingerprints, but
+ -- it's a strict field, so we can't omit it.
+ mi_finsts = False, -- Ditto
+ mi_decls = deliberatelyOmitted "decls",
+ mi_hash_fn = deliberatelyOmitted "hash_fn",
+ mi_hpc = isHpcUsed hpc_info,
+ mi_trust = trust_info,
+ mi_trust_pkg = pkg_trust_req,
+
+ -- And build the cached values
+ mi_warn_fn = mkIfaceWarnCache warns,
+ mi_fix_fn = mkIfaceFixCache fixities }
+
+ (new_iface, no_change_at_all)
+ <- {-# SCC "versioninfo" #-}
+ addFingerprints hsc_env maybe_old_fingerprint
+ intermediate_iface decls
+
+ -- Warn about orphans
+ let warn_orphs = wopt Opt_WarnOrphans dflags
+ warn_auto_orphs = wopt Opt_WarnAutoOrphans dflags
+ orph_warnings --- Laziness means no work done unless -fwarn-orphans
+ | warn_orphs || warn_auto_orphs = rule_warns `unionBags` inst_warns
+ | otherwise = emptyBag
+ errs_and_warns = (orph_warnings, emptyBag)
+ unqual = mkPrintUnqualified dflags rdr_env
+ inst_warns = listToBag [ instOrphWarn dflags unqual d
+ | (d,i) <- insts `zip` iface_insts
+ , isNothing (ifInstOrph i) ]
+ rule_warns = listToBag [ ruleOrphWarn dflags unqual this_mod r
+ | r <- iface_rules
+ , isNothing (ifRuleOrph r)
+ , if ifRuleAuto r then warn_auto_orphs
+ else warn_orphs ]
+
+ if errorsFound dflags errs_and_warns
+ then return ( errs_and_warns, Nothing )
+ else do
+ -- Debug printing
+ dumpIfSet_dyn dflags Opt_D_dump_hi "FINAL INTERFACE"
+ (pprModIface new_iface)
+
+ -- bug #1617: on reload we weren't updating the PrintUnqualified
+ -- correctly. This stems from the fact that the interface had
+ -- not changed, so addFingerprints returns the old ModIface
+ -- with the old GlobalRdrEnv (mi_globals).
+ let final_iface = new_iface{ mi_globals = maybeGlobalRdrEnv rdr_env }
+
+ return (errs_and_warns, Just (final_iface, no_change_at_all))
where
cmp_rule = comparing ifRuleName
-- Compare these lexicographically by OccName, *not* by unique,
@@ -377,14 +379,14 @@ mkIface_ hsc_env maybe_old_fingerprint
, vectInfoTyCon = vTyCon
, vectInfoParallelVars = vParallelVars
, vectInfoParallelTyCons = vParallelTyCons
- }) =
+ }) =
IfaceVectInfo
{ ifaceVectInfoVar = [Var.varName v | (v, _ ) <- varEnvElts vVar]
, ifaceVectInfoTyCon = [tyConName t | (t, t_v) <- nameEnvElts vTyCon, t /= t_v]
, ifaceVectInfoTyConReuse = [tyConName t | (t, t_v) <- nameEnvElts vTyCon, t == t_v]
, ifaceVectInfoParallelVars = [Var.varName v | v <- varSetElems vParallelVars]
, ifaceVectInfoParallelTyCons = nameSetToList vParallelTyCons
- }
+ }
-----------------------------
writeIfaceFile :: DynFlags -> FilePath -> ModIface -> IO ()
@@ -405,14 +407,14 @@ mkHashFun
-> ExternalPackageState -- ditto
-> (Name -> Fingerprint)
mkHashFun hsc_env eps
- = \name ->
- let
+ = \name ->
+ let
mod = ASSERT2( isExternalName name, ppr name ) nameModule name
occ = nameOccName name
- iface = lookupIfaceByModule (hsc_dflags hsc_env) hpt pit mod `orElse`
+ iface = lookupIfaceByModule (hsc_dflags hsc_env) hpt pit mod `orElse`
pprPanic "lookupVers2" (ppr mod <+> ppr occ)
- in
- snd (mi_hash_fn iface occ `orElse`
+ in
+ snd (mi_hash_fn iface occ `orElse`
pprPanic "lookupVers1" (ppr mod <+> ppr occ))
where
hpt = hsc_HPT hsc_env
@@ -427,7 +429,7 @@ addFingerprints
-> ModIface -- The new interface (lacking decls)
-> [IfaceDecl] -- The new decls
-> IO (ModIface, -- Updated interface
- Bool) -- True <=> no changes at all;
+ Bool) -- True <=> no changes at all;
-- no need to write Iface
addFingerprints hsc_env mb_old_fingerprint iface0 new_decls
@@ -437,7 +439,7 @@ addFingerprints hsc_env mb_old_fingerprint iface0 new_decls
-- The ABI of a declaration represents everything that is made
-- visible about the declaration that a client can depend on.
-- see IfaceDeclABI below.
- declABI :: IfaceDecl -> IfaceDeclABI
+ declABI :: IfaceDecl -> IfaceDeclABI
declABI decl = (this_mod, decl, extras)
where extras = declExtras fix_fn non_orph_rules non_orph_insts
non_orph_fis decl
@@ -450,7 +452,7 @@ addFingerprints hsc_env mb_old_fingerprint iface0 new_decls
]
name_module n = ASSERT2( isExternalName n, ppr n ) nameModule n
- localOccs = map (getUnique . getParent . getOccName)
+ localOccs = map (getUnique . getParent . getOccName)
. filter ((== this_mod) . name_module)
. nameSetToList
where getParent occ = lookupOccEnv parent_map occ `orElse` occ
@@ -460,7 +462,7 @@ addFingerprints hsc_env mb_old_fingerprint iface0 new_decls
-- to the TyCon for the purposes of calculating dependencies.
parent_map :: OccEnv OccName
parent_map = foldr extend emptyOccEnv new_decls
- where extend d env =
+ where extend d env =
extendOccEnvList env [ (b,n) | b <- ifaceDeclImplicitBndrs d ]
where n = ifName d
@@ -478,13 +480,13 @@ addFingerprints hsc_env mb_old_fingerprint iface0 new_decls
mk_put_name :: (OccEnv (OccName,Fingerprint))
-> BinHandle -> Name -> IO ()
mk_put_name local_env bh name
- | isWiredInName name = putNameLiterally bh name
+ | isWiredInName name = putNameLiterally bh name
-- wired-in names don't have fingerprints
| otherwise
= ASSERT2( isExternalName name, ppr name )
let hash | nameModule name /= this_mod = global_hash_fn name
| otherwise = snd (lookupOccEnv local_env (getOccName name)
- `orElse` pprPanic "urk! lookup local fingerprint"
+ `orElse` pprPanic "urk! lookup local fingerprint"
(ppr name)) -- (undefined,fingerprint0))
-- This panic indicates that we got the dependency
-- analysis wrong, because we needed a fingerprint for
@@ -498,10 +500,10 @@ addFingerprints hsc_env mb_old_fingerprint iface0 new_decls
-- take a strongly-connected group of declarations and compute
-- its fingerprint.
- fingerprint_group :: (OccEnv (OccName,Fingerprint),
+ fingerprint_group :: (OccEnv (OccName,Fingerprint),
[(Fingerprint,IfaceDecl)])
-> SCC IfaceDeclABI
- -> IO (OccEnv (OccName,Fingerprint),
+ -> IO (OccEnv (OccName,Fingerprint),
[(Fingerprint,IfaceDecl)])
fingerprint_group (local_env, decls_w_hashes) (AcyclicSCC abi)
@@ -537,7 +539,7 @@ addFingerprints hsc_env mb_old_fingerprint iface0 new_decls
(ifaceDeclFingerprints hash d))
--
- (local_env, decls_w_hashes) <-
+ (local_env, decls_w_hashes) <-
foldM fingerprint_group (emptyOccEnv, []) groups
-- when calculating fingerprints, we always need to use canonical
@@ -573,7 +575,7 @@ addFingerprints hsc_env mb_old_fingerprint iface0 new_decls
-- put the declarations in a canonical order, sorted by OccName
let sorted_decls = Map.elems $ Map.fromList $
[(ifName d, e) | e@(_, d) <- decls_w_hashes]
-
+
-- the flag hash depends on:
-- - (some of) dflags
-- it returns two hashes, one that shouldn't change
@@ -596,10 +598,10 @@ addFingerprints hsc_env mb_old_fingerprint iface0 new_decls
-- The interface hash depends on:
-- - the ABI hash, plus
-- - usages
- -- - deps
+ -- - deps (home and external packages, dependent files)
-- - hpc
iface_hash <- computeFingerprint putNameLiterally
- (mod_hash,
+ (mod_hash,
mi_usages iface0,
sorted_deps,
mi_hpc iface0)
@@ -636,11 +638,11 @@ addFingerprints hsc_env mb_old_fingerprint iface0 new_decls
getOrphanHashes :: HscEnv -> [Module] -> IO [Fingerprint]
getOrphanHashes hsc_env mods = do
eps <- hscEPS hsc_env
- let
+ let
hpt = hsc_HPT hsc_env
pit = eps_PIT eps
dflags = hsc_dflags hsc_env
- get_orph_hash mod =
+ get_orph_hash mod =
case lookupIfaceByModule dflags hpt pit mod of
Nothing -> pprPanic "moduleOrphanHash" (ppr mod)
Just iface -> mi_orphan_hash iface
@@ -659,7 +661,7 @@ sortDependencies d
%************************************************************************
%* *
- The ABI of an IfaceDecl
+ The ABI of an IfaceDecl
%* *
%************************************************************************
@@ -688,16 +690,16 @@ and fingerprinting that as part of the declaration.
\begin{code}
type IfaceDeclABI = (Module, IfaceDecl, IfaceDeclExtras)
-data IfaceDeclExtras
+data IfaceDeclExtras
= IfaceIdExtras Fixity [IfaceRule]
- | IfaceDataExtras
+ | IfaceDataExtras
Fixity -- Fixity of the tycon itself
[IfaceInstABI] -- Local class and family instances of this tycon
-- See Note [Orphans] in IfaceSyn
[(Fixity,[IfaceRule])] -- For each construcotr, fixity and RULES
- | IfaceClassExtras
+ | IfaceClassExtras
Fixity -- Fixity of the class itself
[IfaceInstABI] -- Local instances of this class *or*
-- of its associated data types
@@ -708,8 +710,8 @@ data IfaceDeclExtras
| IfaceOtherDeclExtras
--- When hashing a class or family instance, we hash only the
--- DFunId or CoAxiom, because that depends on all the
+-- When hashing a class or family instance, we hash only the
+-- DFunId or CoAxiom, because that depends on all the
-- information about the instance.
--
type IfaceInstABI = IfExtName -- Name of DFunId or CoAxiom that is evidence for the instance
@@ -718,7 +720,7 @@ abiDecl :: IfaceDeclABI -> IfaceDecl
abiDecl (_, decl, _) = decl
cmp_abiNames :: IfaceDeclABI -> IfaceDeclABI -> Ordering
-cmp_abiNames abi1 abi2 = ifName (abiDecl abi1) `compare`
+cmp_abiNames abi1 abi2 = ifName (abiDecl abi1) `compare`
ifName (abiDecl abi2)
freeNamesDeclABI :: IfaceDeclABI -> NameSet
@@ -781,21 +783,21 @@ declExtras :: (OccName -> Fixity)
declExtras fix_fn rule_env inst_env fi_env decl
= case decl of
- IfaceId{} -> IfaceIdExtras (fix_fn n)
+ IfaceId{} -> IfaceIdExtras (fix_fn n)
(lookupOccEnvL rule_env n)
- IfaceData{ifCons=cons} ->
+ IfaceData{ifCons=cons} ->
IfaceDataExtras (fix_fn n)
(map ifFamInstAxiom (lookupOccEnvL fi_env n) ++
map ifDFun (lookupOccEnvL inst_env n))
(map (id_extras . ifConOcc) (visibleIfConDecls cons))
- IfaceClass{ifSigs=sigs, ifATs=ats} ->
+ IfaceClass{ifSigs=sigs, ifATs=ats} ->
IfaceClassExtras (fix_fn n)
(map ifDFun $ (concatMap at_extras ats)
++ lookupOccEnvL inst_env n)
-- Include instances of the associated types
-- as well as instances of the class (Trac #5147)
[id_extras op | IfaceClassOp op _ _ <- sigs]
- IfaceSyn{} -> IfaceSynExtras (fix_fn n)
+ IfaceSyn{} -> IfaceSynExtras (fix_fn n)
(map ifFamInstAxiom (lookupOccEnvL fi_env n))
_other -> IfaceOtherDeclExtras
where
@@ -810,9 +812,10 @@ lookupOccEnvL env k = lookupOccEnv env k `orElse` []
-- used when we want to fingerprint a structure without depending on the
-- fingerprints of external Names that it refers to.
putNameLiterally :: BinHandle -> Name -> IO ()
-putNameLiterally bh name = ASSERT( isExternalName name )
- do { put_ bh $! nameModule name
- ; put_ bh $! nameOccName name }
+putNameLiterally bh name = ASSERT( isExternalName name )
+ do
+ put_ bh $! nameModule name
+ put_ bh $! nameOccName name
{-
-- for testing: use the md5sum command to generate fingerprints and
@@ -850,7 +853,7 @@ ruleOrphWarn dflags unqual mod rule
----------------------
-- mkOrphMap partitions instance decls or rules into
--- (a) an OccEnv for ones that are not orphans,
+-- (a) an OccEnv for ones that are not orphans,
-- mapping the local OccName to a list of its decls
-- (b) a list of orphan decls
mkOrphMap :: (decl -> Maybe OccName) -- (Just occ) for a non-orphan decl, keyed by occ
@@ -878,17 +881,18 @@ mkOrphMap get_key decls
\begin{code}
mkUsageInfo :: HscEnv -> Module -> ImportedMods -> NameSet -> [FilePath] -> IO [Usage]
mkUsageInfo hsc_env this_mod dir_imp_mods used_names dependent_files
- = do { eps <- hscEPS hsc_env
- ; mtimes <- mapM getModificationUTCTime dependent_files
- ; let mod_usages = mk_mod_usage_info (eps_PIT eps) hsc_env this_mod
- dir_imp_mods used_names
- ; let usages = mod_usages ++ map to_file_usage (zip dependent_files mtimes)
- ; usages `seqList` return usages }
- -- seq the list of Usages returned: occasionally these
- -- don't get evaluated for a while and we can end up hanging on to
- -- the entire collection of Ifaces.
- where
- to_file_usage (f, mtime) = UsageFile { usg_file_path = f, usg_mtime = mtime }
+ = do
+ eps <- hscEPS hsc_env
+ hashes <- mapM getFileHash dependent_files
+ let mod_usages = mk_mod_usage_info (eps_PIT eps) hsc_env this_mod
+ dir_imp_mods used_names
+ let usages = mod_usages ++ [ UsageFile { usg_file_path = f
+ , usg_file_hash = hash }
+ | (f, hash) <- zip dependent_files hashes ]
+ usages `seqList` return usages
+ -- seq the list of Usages returned: occasionally these
+ -- don't get evaluated for a while and we can end up hanging on to
+ -- the entire collection of Ifaces.
mk_mod_usage_info :: PackageIfaceTable
-> HscEnv
@@ -927,8 +931,8 @@ mk_mod_usage_info pit hsc_env this_mod direct_imports used_names
-- avoid quadratic behaviour (trac #2680)
extendModuleEnvWith (\_ xs -> occ:xs) mv_map mod [occ]
where occ = nameOccName name
-
- -- We want to create a Usage for a home module if
+
+ -- We want to create a Usage for a home module if
-- a) we used something from it; has something in used_names
-- b) we imported it, even if we used nothing from it
-- (need to recompile if its export list changes: export_fprint)
@@ -954,9 +958,9 @@ mk_mod_usage_info pit hsc_env this_mod direct_imports used_names
-- for directly-imported modules, we always want to record a usage
-- on the orphan hash. This is what triggers a recompilation if
-- an orphan is added or removed somewhere below us in the future.
-
- | otherwise
- = Just UsageHomeModule {
+
+ | otherwise
+ = Just UsageHomeModule {
usg_mod_name = moduleName mod,
usg_mod_hash = mod_hash,
usg_exports = export_hash,
@@ -981,7 +985,7 @@ mk_mod_usage_info pit hsc_env this_mod direct_imports used_names
Nothing -> (False, safeImplicitImpsReq dflags)
-- Nothing case is for implicit imports like 'System.IO' when 'putStrLn'
-- is used in the source code. We require them to be safe in Safe Haskell
-
+
used_occs = lookupModuleEnv ent_map mod `orElse` []
-- Making a Map here ensures that (a) we remove duplicates
@@ -991,8 +995,8 @@ mk_mod_usage_info pit hsc_env this_mod direct_imports used_names
-- using Ord on the OccNames, which is a lexicographic ordering.
ent_hashs :: Map OccName Fingerprint
ent_hashs = Map.fromList (map lookup_occ used_occs)
-
- lookup_occ occ =
+
+ lookup_occ occ =
case hash_env occ of
Nothing -> pprPanic "mkUsage" (ppr mod <+> ppr occ <+> ppr used_names)
Just r -> r
@@ -1019,7 +1023,7 @@ mkIfaceAnnotations :: [Annotation] -> [IfaceAnnotation]
mkIfaceAnnotations = map mkIfaceAnnotation
mkIfaceAnnotation :: Annotation -> IfaceAnnotation
-mkIfaceAnnotation (Annotation { ann_target = target, ann_value = serialized }) = IfaceAnnotation {
+mkIfaceAnnotation (Annotation { ann_target = target, ann_value = serialized }) = IfaceAnnotation {
ifAnnotatedTarget = fmap nameOccName target,
ifAnnotatedValue = serialized
}
@@ -1033,7 +1037,7 @@ mkIfaceExports exports
sort_subs :: AvailInfo -> AvailInfo
sort_subs (Avail n) = Avail n
sort_subs (AvailTC n []) = AvailTC n []
- sort_subs (AvailTC n (m:ms))
+ sort_subs (AvailTC n (m:ms))
| n==m = AvailTC n (m:sortBy stableNameCmp ms)
| otherwise = AvailTC n (sortBy stableNameCmp (m:ms))
-- Maintain the AvailTC Invariant
@@ -1046,7 +1050,7 @@ Consider this:
module Y( T(..) ) where { import X; data instance T Int = MkT Int }
The exported Avail from Y will look like
X.T{X.T, Y.MkT}
-That is, in Y,
+That is, in Y,
- only MkT is brought into scope by the data instance;
- but the parent (used for grouping and naming in T(..) exports) is X.T
- and in this case we export X.T too
@@ -1304,8 +1308,8 @@ checkModUsage _this_pkg UsagePackageModule{
-- recompile. This is safe but may entail more recompilation when
-- a dependent package has changed.
-checkModUsage this_pkg UsageHomeModule{
- usg_mod_name = mod_name,
+checkModUsage this_pkg UsageHomeModule{
+ usg_mod_name = mod_name,
usg_mod_hash = old_mod_hash,
usg_exports = maybe_old_export_hash,
usg_entities = old_decl_hash }
@@ -1322,26 +1326,28 @@ checkModUsage this_pkg UsageHomeModule{
-- CHECK MODULE
recompile <- checkModuleFingerprint reason old_mod_hash new_mod_hash
- if not (recompileRequired recompile) then return UpToDate else do
+ if not (recompileRequired recompile)
+ then return UpToDate
+ else do
-- CHECK EXPORT LIST
- checkMaybeHash reason maybe_old_export_hash new_export_hash
- (ptext (sLit " Export list changed")) $ do
+ checkMaybeHash reason maybe_old_export_hash new_export_hash
+ (ptext (sLit " Export list changed")) $ do
-- CHECK ITEMS ONE BY ONE
- recompile <- checkList [ checkEntityUsage reason new_decl_hash u
- | u <- old_decl_hash]
- if recompileRequired recompile
- then return recompile -- This one failed, so just bail out now
- else up_to_date (ptext (sLit " Great! The bits I use are up to date"))
-
+ recompile <- checkList [ checkEntityUsage reason new_decl_hash u
+ | u <- old_decl_hash]
+ if recompileRequired recompile
+ then return recompile -- This one failed, so just bail out now
+ else up_to_date (ptext (sLit " Great! The bits I use are up to date"))
+
checkModUsage _this_pkg UsageFile{ usg_file_path = file,
- usg_mtime = old_mtime } =
+ usg_file_hash = old_hash } =
liftIO $
handleIO handle $ do
- new_mtime <- getModificationUTCTime file
- if (old_mtime /= new_mtime)
+ new_hash <- getFileHash file
+ if (old_hash /= new_hash)
then return recomp
else return UpToDate
where
@@ -1439,7 +1445,7 @@ idToIfaceDecl id
--------------------------
coAxiomToIfaceDecl :: CoAxiom br -> IfaceDecl
--- We *do* tidy Axioms, because they are not (and cannot
+-- We *do* tidy Axioms, because they are not (and cannot
-- conveniently be) built in tidy form
coAxiomToIfaceDecl ax@(CoAxiom { co_ax_tc = tycon, co_ax_branches = branches
, co_ax_role = role })
@@ -1480,7 +1486,7 @@ coAxBranchToIfaceBranch' env0
-----------------
tyConToIfaceDecl :: TidyEnv -> TyCon -> IfaceDecl
--- We *do* tidy TyCons, because they are not (and cannot
+-- We *do* tidy TyCons, because they are not (and cannot
-- conveniently be) built in tidy form
tyConToIfaceDecl env tycon
| Just clas <- tyConClass_maybe tycon
@@ -1514,10 +1520,10 @@ tyConToIfaceDecl env tycon
(env1, tyvars) = tidyTyClTyVarBndrs env (tyConTyVars tycon)
to_ifsyn_rhs OpenSynFamilyTyCon = IfaceOpenSynFamilyTyCon
- to_ifsyn_rhs (ClosedSynFamilyTyCon ax)
+ to_ifsyn_rhs (ClosedSynFamilyTyCon ax)
= IfaceClosedSynFamilyTyCon (coAxiomName ax)
to_ifsyn_rhs AbstractClosedSynFamilyTyCon = IfaceAbstractClosedSynFamilyTyCon
- to_ifsyn_rhs (SynonymTyCon ty)
+ to_ifsyn_rhs (SynonymTyCon ty)
= IfaceSynonymTyCon (tidyToIfaceType env1 ty)
ifaceConDecls (NewTyCon { data_con = con }) = IfNewTyCon (ifaceConDecl con)
@@ -1529,7 +1535,7 @@ tyConToIfaceDecl env tycon
-- in TcRnDriver for GHCi, when browsing a module, in which case the
-- AbstractTyCon case is perfectly sensible.
- ifaceConDecl data_con
+ ifaceConDecl data_con
= IfCon { ifConOcc = getOccName (dataConName data_con),
ifConInfix = dataConIsInfix data_con,
ifConWrapper = isJust (dataConWrapId_maybe data_con),
@@ -1538,7 +1544,7 @@ tyConToIfaceDecl env tycon
ifConEqSpec = to_eq_spec eq_spec,
ifConCtxt = tidyToIfaceContext env2 theta,
ifConArgTys = map (tidyToIfaceType env2) arg_tys,
- ifConFields = map getOccName
+ ifConFields = map getOccName
(dataConFieldLabels data_con),
ifConStricts = map (toIfaceBang env2) (dataConRepBangs data_con) }
where
@@ -1548,7 +1554,7 @@ tyConToIfaceDecl env tycon
-- data constructor is fully standalone
(env1, univ_tvs') = tidyTyVarBndrs emptyTidyEnv univ_tvs
(env2, ex_tvs') = tidyTyVarBndrs env1 ex_tvs
- to_eq_spec spec = [ (getOccName (tidyTyVar env2 tv), tidyToIfaceType env2 ty)
+ to_eq_spec spec = [ (getOccName (tidyTyVar env2 tv), tidyToIfaceType env2 ty)
| (tv,ty) <- spec]
toIfaceBang :: TidyEnv -> HsBang -> IfaceBang
@@ -1569,19 +1575,19 @@ classToIfaceDecl env clas
ifSigs = map toIfaceClassOp op_stuff,
ifRec = boolToRecFlag (isRecursiveTyCon tycon) }
where
- (clas_tyvars, clas_fds, sc_theta, _, clas_ats, op_stuff)
+ (clas_tyvars, clas_fds, sc_theta, _, clas_ats, op_stuff)
= classExtraBigSig clas
tycon = classTyCon clas
(env1, clas_tyvars') = tidyTyVarBndrs env clas_tyvars
-
+
toIfaceAT :: ClassATItem -> IfaceAT
toIfaceAT (tc, defs)
= IfaceAT (tyConToIfaceDecl env1 tc) (map (coAxBranchToIfaceBranch' env1) defs)
toIfaceClassOp (sel_id, def_meth)
= ASSERT(sel_tyvars == clas_tyvars)
- IfaceClassOp (getOccName sel_id) (toDmSpec def_meth)
+ IfaceClassOp (getOccName sel_id) (toDmSpec def_meth)
(tidyToIfaceType env1 op_ty)
where
-- Be careful when splitting the type, because of things
@@ -1596,7 +1602,7 @@ classToIfaceDecl env clas
toDmSpec (GenDefMeth _) = GenericDM
toDmSpec (DefMeth _) = VanillaDM
- toIfaceFD (tvs1, tvs2) = (map (getFS . tidyTyVar env1) tvs1,
+ toIfaceFD (tvs1, tvs2) = (map (getFS . tidyTyVar env1) tvs1,
map (getFS . tidyTyVar env1) tvs2)
--------------------------
@@ -1611,7 +1617,7 @@ tidyTyClTyVarBndrs env tvs = mapAccumL tidyTyClTyVarBndr env tvs
tidyTyClTyVarBndr :: TidyEnv -> TyVar -> (TidyEnv, TyVar)
-- If the type variable "binder" is in scope, don't re-bind it
--- In a class decl, for example, the ATD binders mention
+-- In a class decl, for example, the ATD binders mention
-- (amd must mention) the class tyvars
tidyTyClTyVarBndr env@(_, subst) tv
| Just tv' <- lookupVarEnv subst tv = (env, tv')
@@ -1651,7 +1657,7 @@ instanceToIfaceInst (ClsInst { is_dfun = dfun_id, is_flag = oflag
orph | is_local cls_name = Just (nameOccName cls_name)
| all isJust mb_ns = ASSERT( not (null mb_ns) ) head mb_ns
| otherwise = Nothing
-
+
mb_ns :: [Maybe OccName] -- One for each fundep; a locally-defined name
-- that is not in the "determined" arguments
mb_ns | null fds = [choose_one arg_names]
@@ -1697,9 +1703,9 @@ famInstToIfaceFamInst (FamInst { fi_axiom = axiom,
--------------------------
toIfaceLetBndr :: Id -> IfaceLetBndr
toIfaceLetBndr id = IfLetBndr (occNameFS (getOccName id))
- (toIfaceType (idType id))
+ (toIfaceType (idType id))
(toIfaceIdInfo (idInfo id))
- -- Put into the interface file any IdInfo that CoreTidy.tidyLetBndr
+ -- Put into the interface file any IdInfo that CoreTidy.tidyLetBndr
-- has left on the Id. See Note [IdInfo on nested let-bindings] in IfaceSyn
--------------------------
@@ -1708,7 +1714,7 @@ toIfaceIdDetails VanillaId = IfVanillaId
toIfaceIdDetails (DFunId ns _) = IfDFunId ns
toIfaceIdDetails (RecSelId { sel_naughty = n
, sel_tycon = tc }) = IfRecSelId (toIfaceTyCon tc) n
-toIfaceIdDetails other = pprTrace "toIfaceIdDetails" (ppr other)
+toIfaceIdDetails other = pprTrace "toIfaceIdDetails" (ppr other)
IfVanillaId -- Unexpected
toIfaceIdInfo :: IdInfo -> IfaceIdInfo
@@ -1717,7 +1723,7 @@ toIfaceIdInfo id_info
inline_hsinfo, unfold_hsinfo] of
[] -> NoInfo
infos -> HasInfo infos
- -- NB: strictness must appear in the list before unfolding
+ -- NB: strictness and arity must appear in the list before unfolding
-- See TcIface.tcUnfolding
where
------------ Arity --------------
@@ -1738,9 +1744,9 @@ toIfaceIdInfo id_info
| otherwise = Nothing
------------ Unfolding --------------
- unfold_hsinfo = toIfUnfolding loop_breaker (unfoldingInfo id_info)
+ unfold_hsinfo = toIfUnfolding loop_breaker (unfoldingInfo id_info)
loop_breaker = isStrongLoopBreaker (occInfo id_info)
-
+
------------ Inline prag --------------
inline_prag = inlinePragInfo id_info
inline_hsinfo | isDefaultInlinePragma inline_prag = Nothing
@@ -1756,22 +1762,19 @@ toIfUnfolding lb (CoreUnfolding { uf_tmpl = rhs, uf_arity = arity
-> case guidance of
UnfWhen unsat_ok boring_ok -> IfInlineRule arity unsat_ok boring_ok if_rhs
_other -> IfCoreUnfold True if_rhs
- InlineWrapper w | isExternalName n -> IfExtWrapper arity n
- | otherwise -> IfLclWrapper arity (getFS n)
- where
- n = idName w
+ InlineWrapper -> IfWrapper if_rhs
InlineCompulsory -> IfCompulsory if_rhs
InlineRhs -> IfCoreUnfold False if_rhs
-- Yes, even if guidance is UnfNever, expose the unfolding
-- If we didn't want to expose the unfolding, TidyPgm would
- -- have stuck in NoUnfolding. For supercompilation we want
+ -- have stuck in NoUnfolding. For supercompilation we want
-- to see that unfolding!
where
if_rhs = toIfaceExpr rhs
toIfUnfolding lb (DFunUnfolding { df_bndrs = bndrs, df_args = args })
= Just (HsUnfold lb (IfDFunUnfold (map toIfaceBndr bndrs) (map toIfaceExpr args)))
- -- No need to serialise the data constructor;
+ -- No need to serialise the data constructor;
-- we can recover it from the type of the dfun
toIfUnfolding _ _
@@ -1783,13 +1786,13 @@ coreRuleToIfaceRule _ (BuiltinRule { ru_fn = fn})
= pprTrace "toHsRule: builtin" (ppr fn) $
bogusIfaceRule fn
-coreRuleToIfaceRule mod rule@(Rule { ru_name = name, ru_fn = fn,
+coreRuleToIfaceRule mod rule@(Rule { ru_name = name, ru_fn = fn,
ru_act = act, ru_bndrs = bndrs,
- ru_args = args, ru_rhs = rhs,
+ ru_args = args, ru_rhs = rhs,
ru_auto = auto })
- = IfaceRule { ifRuleName = name, ifActivation = act,
+ = IfaceRule { ifRuleName = name, ifActivation = act,
ifRuleBndrs = map toIfaceBndr bndrs,
- ifRuleHead = fn,
+ ifRuleHead = fn,
ifRuleArgs = map do_arg args,
ifRuleRhs = toIfaceExpr rhs,
ifRuleAuto = auto,
@@ -1814,8 +1817,8 @@ coreRuleToIfaceRule mod rule@(Rule { ru_name = name, ru_fn = fn,
bogusIfaceRule :: Name -> IfaceRule
bogusIfaceRule id_name
- = IfaceRule { ifRuleName = fsLit "bogus", ifActivation = NeverActive,
- ifRuleBndrs = [], ifRuleHead = id_name, ifRuleArgs = [],
+ = IfaceRule { ifRuleName = fsLit "bogus", ifActivation = NeverActive,
+ ifRuleBndrs = [], ifRuleHead = id_name, ifRuleArgs = [],
ifRuleRhs = IfaceExt id_name, ifRuleOrph = Nothing, ifRuleAuto = True }
---------------------
@@ -1826,7 +1829,7 @@ toIfaceExpr (Type ty) = IfaceType (toIfaceType ty)
toIfaceExpr (Coercion co) = IfaceCo (toIfaceCoercion co)
toIfaceExpr (Lam x b) = IfaceLam (toIfaceBndr x) (toIfaceExpr b)
toIfaceExpr (App f a) = toIfaceApp f [a]
-toIfaceExpr (Case s x ty as)
+toIfaceExpr (Case s x ty as)
| null as = IfaceECase (toIfaceExpr s) (toIfaceType ty)
| otherwise = IfaceCase (toIfaceExpr s) (getFS x) (map toIfaceAlt as)
toIfaceExpr (Let b e) = IfaceLet (toIfaceBind b) (toIfaceExpr e)
@@ -1861,7 +1864,7 @@ toIfaceApp (App f a) as = toIfaceApp f (a:as)
toIfaceApp (Var v) as
= case isDataConWorkId_maybe v of
-- We convert the *worker* for tuples into IfaceTuples
- Just dc | isTupleTyCon tc && saturated
+ Just dc | isTupleTyCon tc && saturated
-> IfaceTuple (tupleTyConSort tc) tup_args
where
val_args = dropWhile isTypeArg as
diff --git a/compiler/iface/TcIface.lhs b/compiler/iface/TcIface.lhs
index ae517ec0ab..dffd69b9ed 100644
--- a/compiler/iface/TcIface.lhs
+++ b/compiler/iface/TcIface.lhs
@@ -34,7 +34,6 @@ import CoreSyn
import CoreUtils
import CoreUnfold
import CoreLint
-import WorkWrap ( mkWrapper )
import MkCore ( castBottomExpr )
import Id
import MkId
@@ -46,7 +45,7 @@ import DataCon
import PrelNames
import TysWiredIn
import TysPrim ( superKindTyConName )
-import BasicTypes ( Arity, strongLoopBreaker )
+import BasicTypes ( strongLoopBreaker )
import Literal
import qualified Var
import VarEnv
@@ -55,7 +54,7 @@ import Name
import NameEnv
import NameSet
import OccurAnal ( occurAnalyseExpr )
-import Demand ( isBottomingSig )
+import Demand
import Module
import UniqFM
import UniqSupply
@@ -1205,6 +1204,25 @@ do_one (IfaceRec pairs) thing_inside
%* *
%************************************************************************
+Note [wrappers in interface files]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+We used to have a nice clever scheme in interface files for
+wrappers. A wrapper's unfolding can be reconstructed from its worker's
+id and its strictness. This decreased .hi file size (sometimes
+significantly, for modules like GHC.Classes with many high-arity w/w
+splits) and had a slight corresponding effect on compile times.
+
+However, when we added the second demand analysis, this scheme lead to
+some Core lint errors. The second analysis could change the strictness
+signatures, which sometimes resulted in a wrapper's regenerated
+unfolding applying the wrapper to too many arguments.
+
+Instead of repairing the clever .hi scheme, we abandoned it in favor
+of simplicity. The .hi sizes are usually insignificant (excluding the
++1M for base libraries), and compile time barely increases (~+1% for
+nofib). The nicer upshot is that unfolding sources no longer include
+an Id, so, eg, substitutions need not traverse them any longer.
+
\begin{code}
tcIdDetails :: Type -> IfaceIdDetails -> IfL IdDetails
tcIdDetails _ IfVanillaId = return VanillaId
@@ -1247,17 +1265,18 @@ tcUnfolding :: Name -> Type -> IdInfo -> IfaceUnfolding -> IfL Unfolding
tcUnfolding name _ info (IfCoreUnfold stable if_expr)
= do { dflags <- getDynFlags
; mb_expr <- tcPragExpr name if_expr
- ; let unf_src = if stable then InlineStable else InlineRhs
- ; return (case mb_expr of
- Nothing -> NoUnfolding
- Just expr -> mkUnfolding dflags unf_src
- True {- Top level -}
- is_bottoming
- expr) }
+ ; let unf_src | stable = InlineStable
+ | otherwise = InlineRhs
+ ; return $ case mb_expr of
+ Nothing -> NoUnfolding
+ Just expr -> mkUnfolding dflags unf_src
+ True {- Top level -}
+ (isBottomingSig strict_sig)
+ expr
+ }
where
-- Strictness should occur before unfolding!
- is_bottoming = isBottomingSig $ strictnessInfo info
-
+ strict_sig = strictnessInfo info
tcUnfolding name _ _ (IfCompulsory if_expr)
= do { mb_expr <- tcPragExpr name if_expr
; return (case mb_expr of
@@ -1282,30 +1301,15 @@ tcUnfolding name dfun_ty _ (IfDFunUnfold bs ops)
doc = text "Class ops for dfun" <+> ppr name
(_, _, cls, _) = tcSplitDFunTy dfun_ty
-tcUnfolding name ty info (IfExtWrapper arity wkr)
- = tcIfaceWrapper name ty info arity (tcIfaceExtId wkr)
-tcUnfolding name ty info (IfLclWrapper arity wkr)
- = tcIfaceWrapper name ty info arity (tcIfaceLclId wkr)
-
--------------
-tcIfaceWrapper :: Name -> Type -> IdInfo -> Arity -> IfL Id -> IfL Unfolding
-tcIfaceWrapper name ty info arity get_worker
- = do { mb_wkr_id <- forkM_maybe doc get_worker
- ; us <- newUniqueSupply
- ; dflags <- getDynFlags
- ; return (case mb_wkr_id of
- Nothing -> noUnfolding
- Just wkr_id -> make_inline_rule dflags wkr_id us) }
+tcUnfolding name _ info (IfWrapper if_expr)
+ = do { mb_expr <- tcPragExpr name if_expr
+ ; return $ case mb_expr of
+ Nothing -> NoUnfolding
+ Just expr -> mkWwInlineRule expr arity -- see Note [wrappers in interface files]
+ }
where
- doc = text "Worker for" <+> ppr name
-
- make_inline_rule dflags wkr_id us
- = mkWwInlineRule wkr_id
- (initUs_ us (mkWrapper dflags ty strict_sig) wkr_id)
- arity
- -- Again we rely here on strictness info
- -- always appearing before unfolding
- strict_sig = strictnessInfo info
+ -- Arity should occur before unfolding!
+ arity = arityInfo info
\end{code}
For unfoldings we try to do the job lazily, so that we never type check
diff --git a/compiler/llvmGen/LlvmCodeGen/Ppr.hs b/compiler/llvmGen/LlvmCodeGen/Ppr.hs
index 1c63d3f67f..202e685c0e 100644
--- a/compiler/llvmGen/LlvmCodeGen/Ppr.hs
+++ b/compiler/llvmGen/LlvmCodeGen/Ppr.hs
@@ -61,6 +61,9 @@ moduleLayout = sdocWithPlatform $ \platform ->
Platform { platformArch = ArchARM {}, platformOS = OSiOS } ->
text "target datalayout = \"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:128-a0:0:64-n32\""
$+$ text "target triple = \"arm-apple-darwin10\""
+ Platform { platformArch = ArchX86, platformOS = OSiOS } ->
+ text "target datalayout = \"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32\""
+ $+$ text "target triple = \"i386-apple-darwin11\""
_ ->
-- FIX: Other targets
empty
@@ -134,7 +137,7 @@ iTableSuf = "_itable"
-- | Create a specially crafted section declaration that encodes the order this
-- section should be in the final object code.
---
+--
-- The LlvmMangler.llvmFixupAsm pass over the assembly produced by LLVM uses
-- this section declaration to do its processing.
mkLayoutSection :: Int -> LMSection
@@ -146,4 +149,3 @@ mkLayoutSection n
-- be unique since we process the assembly pattern matching this.
infoSection :: String
infoSection = "X98A__STRIP,__me"
-
diff --git a/compiler/main/DriverPipeline.hs b/compiler/main/DriverPipeline.hs
index c5bcdc7a65..8fc44ed81f 100644
--- a/compiler/main/DriverPipeline.hs
+++ b/compiler/main/DriverPipeline.hs
@@ -295,6 +295,9 @@ link NoLink _ _ _
link LinkBinary dflags batch_attempt_linking hpt
= link' dflags batch_attempt_linking hpt
+link LinkStaticLib dflags batch_attempt_linking hpt
+ = link' dflags batch_attempt_linking hpt
+
link LinkDynLib dflags batch_attempt_linking hpt
= link' dflags batch_attempt_linking hpt
@@ -311,6 +314,10 @@ link' dflags batch_attempt_linking hpt
| batch_attempt_linking
= do
let
+ staticLink = case ghcLink dflags of
+ LinkStaticLib -> True
+ _ -> platformBinariesAreStaticLibs (targetPlatform dflags)
+
home_mod_infos = eltsUFM hpt
-- the packages we depend on
@@ -330,9 +337,9 @@ link' dflags batch_attempt_linking hpt
let getOfiles (LM _ _ us) = map nameOfObject (filter isObject us)
obj_files = concatMap getOfiles linkables
- exe_file = exeFileName dflags
+ exe_file = exeFileName staticLink dflags
- linking_needed <- linkingNeeded dflags linkables pkg_deps
+ linking_needed <- linkingNeeded dflags staticLink linkables pkg_deps
if not (gopt Opt_ForceRecomp dflags) && not linking_needed
then do debugTraceMsg dflags 2 (text exe_file <+> ptext (sLit "is up to date, linking not required."))
@@ -343,9 +350,10 @@ link' dflags batch_attempt_linking hpt
-- Don't showPass in Batch mode; doLink will do that for us.
let link = case ghcLink dflags of
- LinkBinary -> linkBinary
- LinkDynLib -> linkDynLibCheck
- other -> panicBadLink other
+ LinkBinary -> linkBinary
+ LinkStaticLib -> linkStaticLibCheck
+ LinkDynLib -> linkDynLibCheck
+ other -> panicBadLink other
link dflags obj_files pkg_deps
debugTraceMsg dflags 3 (text "link: done")
@@ -359,12 +367,12 @@ link' dflags batch_attempt_linking hpt
return Succeeded
-linkingNeeded :: DynFlags -> [Linkable] -> [PackageId] -> IO Bool
-linkingNeeded dflags linkables pkg_deps = do
+linkingNeeded :: DynFlags -> Bool -> [Linkable] -> [PackageId] -> IO Bool
+linkingNeeded dflags staticLink linkables pkg_deps = do
-- if the modification time on the executable is later than the
-- modification times on all of the objects and libraries, then omit
-- linking (unless the -fforce-recomp flag was given).
- let exe_file = exeFileName dflags
+ let exe_file = exeFileName staticLink dflags
e_exe_time <- tryIO $ getModificationUTCTime exe_file
case e_exe_time of
Left _ -> return True
@@ -482,10 +490,11 @@ doLink dflags stop_phase o_files
| otherwise
= case ghcLink dflags of
- NoLink -> return ()
- LinkBinary -> linkBinary dflags o_files []
- LinkDynLib -> linkDynLibCheck dflags o_files []
- other -> panicBadLink other
+ NoLink -> return ()
+ LinkBinary -> linkBinary dflags o_files []
+ LinkStaticLib -> linkStaticLibCheck dflags o_files []
+ LinkDynLib -> linkDynLibCheck dflags o_files []
+ other -> panicBadLink other
-- ---------------------------------------------------------------------------
@@ -1116,8 +1125,9 @@ runPhase (RealPhase cc_phase) input_fn dflags
split_opt | hcc && split_objs = [ "-DUSE_SPLIT_MARKERS" ]
| otherwise = [ ]
- let cc_opt | optLevel dflags >= 2 = "-O2"
- | otherwise = "-O"
+ let cc_opt | optLevel dflags >= 2 = [ "-O2" ]
+ | optLevel dflags >= 1 = [ "-O" ]
+ | otherwise = []
-- Decide next phase
let next_phase = As
@@ -1187,7 +1197,8 @@ runPhase (RealPhase cc_phase) input_fn dflags
then gcc_extra_viac_flags ++ more_hcc_opts
else [])
++ verbFlags
- ++ [ "-S", cc_opt ]
+ ++ [ "-S" ]
+ ++ cc_opt
++ [ "-D__GLASGOW_HASKELL__="++cProjectVersionInt ]
++ framework_paths
++ split_opt
@@ -1768,11 +1779,14 @@ getHCFilePackages filename =
-- the packages.
linkBinary :: DynFlags -> [FilePath] -> [PackageId] -> IO ()
-linkBinary dflags o_files dep_packages = do
+linkBinary = linkBinary' False
+
+linkBinary' :: Bool -> DynFlags -> [FilePath] -> [PackageId] -> IO ()
+linkBinary' staticLink dflags o_files dep_packages = do
let platform = targetPlatform dflags
mySettings = settings dflags
verbFlags = getVerbFlags dflags
- output_fn = exeFileName dflags
+ output_fn = exeFileName staticLink dflags
-- get the full list of packages to link with, by combining the
-- explicit packages with the auto packages and all of their
@@ -1813,13 +1827,15 @@ linkBinary dflags o_files dep_packages = do
extraLinkObj <- mkExtraObjToLinkIntoBinary dflags
noteLinkObjs <- mkNoteObjsToLinkIntoBinary dflags dep_packages
- pkg_link_opts <- if platformBinariesAreStaticLibs platform
- then -- If building an executable really means
- -- making a static library (e.g. iOS), then
- -- we don't want the options (like -lm)
- -- that getPackageLinkOpts gives us. #7720
- return []
- else getPackageLinkOpts dflags dep_packages
+ pkg_link_opts <- do
+ (package_hs_libs, extra_libs, other_flags) <- getPackageLinkOpts dflags dep_packages
+ return $ if staticLink
+ then package_hs_libs -- If building an executable really means making a static
+ -- library (e.g. iOS), then we only keep the -l options for
+ -- HS packages, because libtool doesn't accept other options.
+ -- In the case of iOS these need to be added by hand to the
+ -- final link in Xcode.
+ else package_hs_libs ++ extra_libs ++ other_flags
pkg_framework_path_opts <-
if platformUsesFrameworks platform
@@ -1867,14 +1883,17 @@ linkBinary dflags o_files dep_packages = do
let os = platformOS (targetPlatform dflags)
in if os == OSOsf3 then ["-lpthread", "-lexc"]
else if os `elem` [OSMinGW32, OSFreeBSD, OSOpenBSD,
- OSNetBSD, OSHaiku, OSQNXNTO]
+ OSNetBSD, OSHaiku, OSQNXNTO, OSiOS]
then []
else ["-lpthread"]
| otherwise = []
rc_objs <- maybeCreateManifest dflags output_fn
- SysTools.runLink dflags (
+ let link = if staticLink
+ then SysTools.runLibtool
+ else SysTools.runLink
+ link dflags (
map SysTools.Option verbFlags
++ [ SysTools.Option "-o"
, SysTools.FileOption "" output_fn
@@ -1897,6 +1916,7 @@ linkBinary dflags o_files dep_packages = do
-- ld: warning: could not create compact unwind for .LFB3: non-standard register 5 being saved in prolog
-- on x86.
++ (if sLdSupportsCompactUnwind mySettings &&
+ not staticLink &&
platformOS platform == OSDarwin &&
platformArch platform `elem` [ArchX86, ArchX86_64]
then ["-Wl,-no_compact_unwind"]
@@ -1909,7 +1929,8 @@ linkBinary dflags o_files dep_packages = do
-- whether this is something we ought to fix, but
-- for now this flags silences them.
++ (if platformOS platform == OSDarwin &&
- platformArch platform == ArchX86
+ platformArch platform == ArchX86 &&
+ not staticLink
then ["-Wl,-read_only_relocs,suppress"]
else [])
@@ -1935,17 +1956,20 @@ linkBinary dflags o_files dep_packages = do
throwGhcExceptionIO (InstallationError ("cannot move binary"))
-exeFileName :: DynFlags -> FilePath
-exeFileName dflags
+exeFileName :: Bool -> DynFlags -> FilePath
+exeFileName staticLink dflags
| Just s <- outputFile dflags =
- case platformOS (targetPlatform dflags) of
+ case platformOS (targetPlatform dflags) of
OSMinGW32 -> s <?.> "exe"
- OSiOS -> s <?.> "a"
- _ -> s
+ _ -> if staticLink
+ then s <?.> "a"
+ else s
| otherwise =
if platformOS (targetPlatform dflags) == OSMinGW32
then "main.exe"
- else "a.out"
+ else if staticLink
+ then "liba.a"
+ else "a.out"
where s <?.> ext | null (takeExtension s) = s <.> ext
| otherwise = s
@@ -2012,6 +2036,13 @@ linkDynLibCheck dflags o_files dep_packages
linkDynLib dflags o_files dep_packages
+linkStaticLibCheck :: DynFlags -> [String] -> [PackageId] -> IO ()
+linkStaticLibCheck dflags o_files dep_packages
+ = do
+ when (platformOS (targetPlatform dflags) `notElem` [OSiOS, OSDarwin]) $
+ throwGhcExceptionIO (ProgramError "Static archive creation only supported on Darwin/OS X/iOS")
+ linkBinary' True dflags o_files dep_packages
+
-- -----------------------------------------------------------------------------
-- Running CPP
diff --git a/compiler/main/DynFlags.hs b/compiler/main/DynFlags.hs
index 64ec8be612..e80cf656d3 100644
--- a/compiler/main/DynFlags.hs
+++ b/compiler/main/DynFlags.hs
@@ -66,7 +66,7 @@ module DynFlags (
ghcUsagePath, ghciUsagePath, topDir, tmpDir, rawSettings,
extraGccViaCFlags, systemPackageConfig,
pgm_L, pgm_P, pgm_F, pgm_c, pgm_s, pgm_a, pgm_l, pgm_dll, pgm_T,
- pgm_sysman, pgm_windres, pgm_lo, pgm_lc,
+ pgm_sysman, pgm_windres, pgm_libtool, pgm_lo, pgm_lc,
opt_L, opt_P, opt_F, opt_c, opt_a, opt_l,
opt_windres, opt_lo, opt_lc,
@@ -101,6 +101,7 @@ module DynFlags (
flagsPackage,
supportedLanguagesAndExtensions,
+ languageExtensions,
-- ** DynFlags C compiler options
picCCOpts, picPOpts,
@@ -277,6 +278,7 @@ data GeneralFlag
-- optimisation opts
| Opt_Strictness
+ | Opt_LateDmdAnal
| Opt_KillAbsence
| Opt_KillOneShot
| Opt_FullLaziness
@@ -500,6 +502,7 @@ data ExtensionFlag
| Opt_TypeFamilies
| Opt_OverloadedStrings
| Opt_OverloadedLists
+ | Opt_NumDecimals
| Opt_DisambiguateRecordFields
| Opt_RecordWildCards
| Opt_RecordPuns
@@ -513,7 +516,7 @@ data ExtensionFlag
| Opt_PolyKinds -- Kind polymorphism
| Opt_DataKinds -- Datatype promotion
| Opt_InstanceSigs
-
+
| Opt_StandaloneDeriving
| Opt_DeriveDataTypeable
| Opt_AutoDeriveTypeable -- Automatic derivation of Typeable
@@ -579,6 +582,8 @@ data DynFlags = DynFlags {
ruleCheck :: Maybe String,
strictnessBefore :: [Int], -- ^ Additional demand analysis
+ maxRelevantBinds :: Maybe Int, -- ^ Maximum number of bindings from the type envt
+ -- to show in type error messages
simplTickFactor :: Int, -- ^ Multiplier for simplifier ticks
specConstrThreshold :: Maybe Int, -- ^ Threshold for SpecConstr
specConstrCount :: Maybe Int, -- ^ Max number of specialisations for any one function
@@ -587,6 +592,7 @@ data DynFlags = DynFlags {
liberateCaseThreshold :: Maybe Int, -- ^ Threshold for LiberateCase
floatLamArgs :: Maybe Int, -- ^ Arg count for lambda floating
-- See CoreMonad.FloatOutSwitches
+
historySize :: Int,
cmdlineHcIncludes :: [String], -- ^ @\-\#includes@
@@ -798,6 +804,7 @@ data Settings = Settings {
sPgm_T :: String,
sPgm_sysman :: String,
sPgm_windres :: String,
+ sPgm_libtool :: String,
sPgm_lo :: (String,[Option]), -- LLVM: opt llvm optimiser
sPgm_lc :: (String,[Option]), -- LLVM: llc static compiler
-- options for particular phases
@@ -853,6 +860,8 @@ pgm_sysman :: DynFlags -> String
pgm_sysman dflags = sPgm_sysman (settings dflags)
pgm_windres :: DynFlags -> String
pgm_windres dflags = sPgm_windres (settings dflags)
+pgm_libtool :: DynFlags -> String
+pgm_libtool dflags = sPgm_libtool (settings dflags)
pgm_lo :: DynFlags -> (String,[Option])
pgm_lo dflags = sPgm_lo (settings dflags)
pgm_lc :: DynFlags -> (String,[Option])
@@ -948,6 +957,7 @@ data GhcLink
| LinkInMemory -- ^ Use the in-memory dynamic linker (works for both
-- bytecode and object code).
| LinkDynLib -- ^ Link objects into a dynamic lib (DLL on Windows, DSO on ELF platforms)
+ | LinkStaticLib -- ^ Link objects into a static lib
deriving (Eq, Show)
isNoLink :: GhcLink -> Bool
@@ -1242,12 +1252,14 @@ defaultDynFlags mySettings =
maxSimplIterations = 4,
shouldDumpSimplPhase = Nothing,
ruleCheck = Nothing,
+ maxRelevantBinds = Just 6,
simplTickFactor = 100,
specConstrThreshold = Just 2000,
specConstrCount = Just 3,
specConstrRecursive = 3,
liberateCaseThreshold = Just 2000,
floatLamArgs = Just 0, -- Default: float only if no fvs
+
historySize = 20,
strictnessBefore = [],
@@ -1671,7 +1683,7 @@ setObjectDir, setHiDir, setStubDir, setDumpDir, setOutputDir,
setDylibInstallName,
setObjectSuf, setHiSuf, setHcSuf, parseDynLibLoaderMode,
setPgmP, addOptl, addOptc, addOptP,
- addCmdlineFramework, addHaddockOpts, addGhciScript,
+ addCmdlineFramework, addHaddockOpts, addGhciScript,
setInteractivePrint
:: String -> DynFlags -> DynFlags
setOutputFile, setDynOutputFile, setOutputHi, setDumpPrefixForce
@@ -1956,7 +1968,7 @@ safeFlagCheck cmdl dflags =
apFix f = if safeInferOn dflags then id else f
- safeFailure loc str
+ safeFailure loc str
= [L loc $ str ++ " is not allowed in Safe Haskell; ignoring " ++ str]
{- **********************************************************************
@@ -2044,6 +2056,7 @@ dynamic_flags = [
, Flag "pgml" (hasArg (\f -> alterSettings (\s -> s { sPgm_l = (f,[])})))
, Flag "pgmdll" (hasArg (\f -> alterSettings (\s -> s { sPgm_dll = (f,[])})))
, Flag "pgmwindres" (hasArg (\f -> alterSettings (\s -> s { sPgm_windres = f})))
+ , Flag "pgmlibtool" (hasArg (\f -> alterSettings (\s -> s { sPgm_libtool = f})))
-- need to appear before -optl/-opta to be parsed as LLVM flags.
, Flag "optlo" (hasArg (\f -> alterSettings (\s -> s { sOpt_lo = f : sOpt_lo s})))
@@ -2078,6 +2091,7 @@ dynamic_flags = [
-------- Linking ----------------------------------------------------
, Flag "no-link" (noArg (\d -> d{ ghcLink=NoLink }))
, Flag "shared" (noArg (\d -> d{ ghcLink=LinkDynLib }))
+ , Flag "staticlib" (noArg (\d -> d{ ghcLink=LinkStaticLib }))
, Flag "dynload" (hasArg parseDynLibLoaderMode)
, Flag "dylib-install-name" (hasArg setDylibInstallName)
-- -dll-split is an internal flag, used only during the GHC build
@@ -2281,6 +2295,9 @@ dynamic_flags = [
, Flag "O" (optIntSuffixM (\mb_n -> setOptLevel (mb_n `orElse` 1)))
-- If the number is missing, use 1
+
+ , Flag "fmax-relevant-binds" (intSuffix (\n d -> d{ maxRelevantBinds = Just n }))
+ , Flag "fno-max-relevant-binds" (noArg (\d -> d{ maxRelevantBinds = Nothing }))
, Flag "fsimplifier-phases" (intSuffix (\n d -> d{ simplPhases = n }))
, Flag "fmax-simplifier-iterations" (intSuffix (\n d -> d{ maxSimplIterations = n }))
, Flag "fsimpl-tick-factor" (intSuffix (\n d -> d{ simplTickFactor = n }))
@@ -2296,6 +2313,7 @@ dynamic_flags = [
, Flag "fstrictness-before" (intSuffix (\n d -> d{ strictnessBefore = n : strictnessBefore d }))
, Flag "ffloat-lam-args" (intSuffix (\n d -> d{ floatLamArgs = Just n }))
, Flag "ffloat-all-lams" (noArg (\d -> d{ floatLamArgs = Nothing }))
+
, Flag "fhistory-size" (intSuffix (\n d -> d{ historySize = n }))
, Flag "funfolding-creation-threshold" (intSuffix (\n d -> d {ufCreationThreshold = n}))
@@ -2500,6 +2518,7 @@ fFlags = [
( "error-spans", Opt_ErrorSpans, nop ),
( "print-explicit-foralls", Opt_PrintExplicitForalls, nop ),
( "strictness", Opt_Strictness, nop ),
+ ( "late-dmd-anal", Opt_LateDmdAnal, nop ),
( "specialise", Opt_Specialise, nop ),
( "float-in", Opt_FloatIn, nop ),
( "static-argument-transformation", Opt_StaticArgumentTransformation, nop ),
@@ -2566,7 +2585,7 @@ fFlags = [
fLangFlags :: [FlagSpec ExtensionFlag]
fLangFlags = [
( "th", Opt_TemplateHaskell,
- \on -> deprecatedForExtension "TemplateHaskell" on
+ \on -> deprecatedForExtension "TemplateHaskell" on
>> checkTemplateHaskellOk on ),
( "fi", Opt_ForeignFunctionInterface,
deprecatedForExtension "ForeignFunctionInterface" ),
@@ -2658,7 +2677,7 @@ xFlags = [
( "TypeOperators", Opt_TypeOperators, nop ),
( "ExplicitNamespaces", Opt_ExplicitNamespaces, nop ),
( "RecursiveDo", Opt_RecursiveDo, nop ), -- Enables 'mdo' and 'rec'
- ( "DoRec", Opt_RecursiveDo,
+ ( "DoRec", Opt_RecursiveDo,
deprecatedForExtension "RecursiveDo" ),
( "Arrows", Opt_Arrows, nop ),
( "ParallelArrays", Opt_ParallelArrays, nop ),
@@ -2671,6 +2690,7 @@ xFlags = [
deprecatedForExtension "NamedFieldPuns" ),
( "DisambiguateRecordFields", Opt_DisambiguateRecordFields, nop ),
( "OverloadedStrings", Opt_OverloadedStrings, nop ),
+ ( "NumDecimals", Opt_NumDecimals, nop),
( "OverloadedLists", Opt_OverloadedLists, nop),
( "GADTs", Opt_GADTs, nop ),
( "GADTSyntax", Opt_GADTSyntax, nop ),
diff --git a/compiler/main/GhcMake.hs b/compiler/main/GhcMake.hs
index c43b18a62a..8a14a0c132 100644
--- a/compiler/main/GhcMake.hs
+++ b/compiler/main/GhcMake.hs
@@ -294,7 +294,7 @@ load how_much = do
let
main_mod = mainModIs dflags
a_root_is_Main = any ((==main_mod).ms_mod) mod_graph
- do_linking = a_root_is_Main || no_hs_main || ghcLink dflags == LinkDynLib
+ do_linking = a_root_is_Main || no_hs_main || ghcLink dflags == LinkDynLib || ghcLink dflags == LinkStaticLib
when (ghcLink dflags == LinkBinary
&& isJust ofile && not do_linking) $
diff --git a/compiler/main/GhcMonad.hs b/compiler/main/GhcMonad.hs
index 66034e0b50..68b4e2b2a2 100644
--- a/compiler/main/GhcMonad.hs
+++ b/compiler/main/GhcMonad.hs
@@ -97,6 +97,10 @@ data Session = Session !(IORef HscEnv)
instance Functor Ghc where
fmap f m = Ghc $ \s -> f `fmap` unGhc m s
+instance Applicative Ghc where
+ pure = return
+ g <*> m = do f <- g; a <- m; return (f a)
+
instance Monad Ghc where
return a = Ghc $ \_ -> return a
m >>= g = Ghc $ \s -> do a <- unGhc m s; unGhc (g a) s
@@ -157,6 +161,10 @@ liftGhcT m = GhcT $ \_ -> m
instance Functor m => Functor (GhcT m) where
fmap f m = GhcT $ \s -> f `fmap` unGhcT m s
+instance Applicative m => Applicative (GhcT m) where
+ pure x = GhcT $ \_ -> pure x
+ g <*> m = GhcT $ \s -> unGhcT g s <*> unGhcT m s
+
instance Monad m => Monad (GhcT m) where
return x = GhcT $ \_ -> return x
m >>= k = GhcT $ \s -> do a <- unGhcT m s; unGhcT (k a) s
diff --git a/compiler/main/HscTypes.lhs b/compiler/main/HscTypes.lhs
index e022ae3eae..33dbba2c21 100644
--- a/compiler/main/HscTypes.lhs
+++ b/compiler/main/HscTypes.lhs
@@ -931,7 +931,7 @@ data ModGuts
mg_tcs :: ![TyCon], -- ^ TyCons declared in this module
-- (includes TyCons for classes)
mg_insts :: ![ClsInst], -- ^ Class instances declared in this module
- mg_fam_insts :: ![FamInst],
+ mg_fam_insts :: ![FamInst],
-- ^ Family instances declared in this module
mg_rules :: ![CoreRule], -- ^ Before the core pipeline starts, contains
-- See Note [Overall plumbing for rules] in Rules.lhs
@@ -1071,7 +1071,7 @@ data InteractiveContext
ic_fix_env :: FixityEnv,
-- ^ Fixities declared in let statements
-
+
ic_int_print :: Name,
-- ^ The function that is used for printing results
-- of expressions in ghci and -e mode.
@@ -1534,7 +1534,7 @@ lookupType dflags hpt pte name
return x
| otherwise
= lookupNameEnv pte name
- where
+ where
mod = ASSERT2( isExternalName name, ppr name ) nameModule name
this_pkg = thisPackage dflags
@@ -1794,10 +1794,19 @@ data Usage
usg_safe :: IsSafeImport
-- ^ Was this module imported as a safe import
} -- ^ Module from the current package
+ -- | A file upon which the module depends, e.g. a CPP #include, or using TH's
+ -- 'addDependentFile'
| UsageFile {
usg_file_path :: FilePath,
- usg_mtime :: UTCTime
- -- ^ External file dependency. From a CPP #include or TH addDependentFile. Should be absolute.
+ -- ^ External file dependency. From a CPP #include or TH
+ -- addDependentFile. Should be absolute.
+ usg_file_hash :: Fingerprint
+ -- ^ 'Fingerprint' of the file contents.
+
+ -- Note: We don't consider things like modification timestamps
+ -- here, because there's no reason to recompile if the actual
+ -- contents don't change. This previously lead to odd
+ -- recompilation behaviors; see #8114
}
deriving( Eq )
-- The export list field is (Just v) if we depend on the export list:
@@ -1814,13 +1823,13 @@ data Usage
-- depend on their export lists
instance Binary Usage where
- put_ bh usg@UsagePackageModule{} = do
+ put_ bh usg@UsagePackageModule{} = do
putByte bh 0
put_ bh (usg_mod usg)
put_ bh (usg_mod_hash usg)
put_ bh (usg_safe usg)
- put_ bh usg@UsageHomeModule{} = do
+ put_ bh usg@UsageHomeModule{} = do
putByte bh 1
put_ bh (usg_mod_name usg)
put_ bh (usg_mod_hash usg)
@@ -1828,10 +1837,10 @@ instance Binary Usage where
put_ bh (usg_entities usg)
put_ bh (usg_safe usg)
- put_ bh usg@UsageFile{} = do
+ put_ bh usg@UsageFile{} = do
putByte bh 2
put_ bh (usg_file_path usg)
- put_ bh (usg_mtime usg)
+ put_ bh (usg_file_hash usg)
get bh = do
h <- getByte bh
@@ -1850,9 +1859,9 @@ instance Binary Usage where
return UsageHomeModule { usg_mod_name = nm, usg_mod_hash = mod,
usg_exports = exps, usg_entities = ents, usg_safe = safe }
2 -> do
- fp <- get bh
- mtime <- get bh
- return UsageFile { usg_file_path = fp, usg_mtime = mtime }
+ fp <- get bh
+ hash <- get bh
+ return UsageFile { usg_file_path = fp, usg_file_hash = hash }
i -> error ("Binary.get(Usage): " ++ show i)
\end{code}
@@ -2457,4 +2466,3 @@ emptyModBreaks = ModBreaks
, modBreaks_decls = array (0,-1) []
}
\end{code}
-
diff --git a/compiler/main/Packages.lhs b/compiler/main/Packages.lhs
index cc8dfe3eb7..fb832ff2e3 100644
--- a/compiler/main/Packages.lhs
+++ b/compiler/main/Packages.lhs
@@ -867,16 +867,19 @@ getPackageLibraryPath dflags pkgs =
collectLibraryPaths :: [PackageConfig] -> [FilePath]
collectLibraryPaths ps = nub (filter notNull (concatMap libraryDirs ps))
--- | Find all the link options in these and the preload packages
-getPackageLinkOpts :: DynFlags -> [PackageId] -> IO [String]
+-- | Find all the link options in these and the preload packages,
+-- returning (package hs lib options, extra library options, other flags)
+getPackageLinkOpts :: DynFlags -> [PackageId] -> IO ([String], [String], [String])
getPackageLinkOpts dflags pkgs =
collectLinkOpts dflags `fmap` getPreloadPackagesAnd dflags pkgs
-collectLinkOpts :: DynFlags -> [PackageConfig] -> [String]
-collectLinkOpts dflags ps = concat (map all_opts ps)
- where
- libs p = packageHsLibs dflags p ++ extraLibraries p
- all_opts p = map ("-l" ++) (libs p) ++ ldOptions p
+collectLinkOpts :: DynFlags -> [PackageConfig] -> ([String], [String], [String])
+collectLinkOpts dflags ps =
+ (
+ concatMap (map ("-l" ++) . packageHsLibs dflags) ps,
+ concatMap (map ("-l" ++) . extraLibraries) ps,
+ concatMap ldOptions ps
+ )
packageHsLibs :: DynFlags -> PackageConfig -> [String]
packageHsLibs dflags p = map (mkDynName . addSuffix) (hsLibraries p)
diff --git a/compiler/main/SysTools.lhs b/compiler/main/SysTools.lhs
index d43826a046..6fe29a99c4 100644
--- a/compiler/main/SysTools.lhs
+++ b/compiler/main/SysTools.lhs
@@ -15,7 +15,7 @@ module SysTools (
runUnlit, runCpp, runCc, -- [Option] -> IO ()
runPp, -- [Option] -> IO ()
runSplit, -- [Option] -> IO ()
- runAs, runLink, -- [Option] -> IO ()
+ runAs, runLink, runLibtool, -- [Option] -> IO ()
runMkDLL,
runWindres,
runLlvmOpt,
@@ -261,6 +261,7 @@ initSysTools mbMinusB
split_script = installed cGHC_SPLIT_PGM
windres_path <- getSetting "windres command"
+ libtool_path <- getSetting "libtool command"
tmpdir <- getTemporaryDirectory
@@ -331,6 +332,7 @@ initSysTools mbMinusB
sPgm_T = touch_path,
sPgm_sysman = top_dir ++ "/ghc/rts/parallel/SysMan",
sPgm_windres = windres_path,
+ sPgm_libtool = libtool_path,
sPgm_lo = (lo_prog,[]),
sPgm_lc = (lc_prog,[]),
-- Hans: this isn't right in general, but you can
@@ -717,6 +719,15 @@ runLink dflags args = do
mb_env <- getGccEnv args2
runSomethingFiltered dflags id "Linker" p args2 mb_env
+runLibtool :: DynFlags -> [Option] -> IO ()
+runLibtool dflags args = do
+ linkargs <- neededLinkArgs `fmap` getLinkerInfo dflags
+ let args1 = map Option (getOpts dflags opt_l)
+ args2 = [Option "-static"] ++ args1 ++ args ++ linkargs
+ libtool = pgm_libtool dflags
+ mb_env <- getGccEnv args2
+ runSomethingFiltered dflags id "Linker" libtool args2 mb_env
+
runMkDLL :: DynFlags -> [Option] -> IO ()
runMkDLL dflags args = do
let (p,args0) = pgm_dll dflags
@@ -1220,7 +1231,8 @@ linkDynLib dflags0 o_files dep_packages
pkgs
_ ->
filter ((/= rtsPackageId) . packageConfigId) pkgs
- let pkg_link_opts = collectLinkOpts dflags pkgs_no_rts
+ let pkg_link_opts = let (package_hs_libs, extra_libs, other_flags) = collectLinkOpts dflags pkgs_no_rts
+ in package_hs_libs ++ extra_libs ++ other_flags
-- probably _stub.o files
let extra_ld_inputs = ldInputs dflags
@@ -1315,6 +1327,7 @@ linkDynLib dflags0 o_files dep_packages
++ map Option pkg_lib_path_opts
++ map Option pkg_link_opts
)
+ OSiOS -> throwGhcExceptionIO (ProgramError "dynamic libraries are not supported on iOS target")
_ -> do
-------------------------------------------------------------------
-- Making a DSO
diff --git a/compiler/main/TidyPgm.lhs b/compiler/main/TidyPgm.lhs
index be4c683276..7b3695dbed 100644
--- a/compiler/main/TidyPgm.lhs
+++ b/compiler/main/TidyPgm.lhs
@@ -815,12 +815,7 @@ dffvLetBndr vanilla_unfold id
= case src of
InlineRhs | vanilla_unfold -> dffvExpr rhs
| otherwise -> return ()
- InlineWrapper v -> insert v
_ -> dffvExpr rhs
- -- For a wrapper, externalise the wrapper id rather than the
- -- fvs of the rhs. The two usually come down to the same thing
- -- but I've seen cases where we had a wrapper id $w but a
- -- rhs where $w had been inlined; see Trac #3922
go_unf (DFunUnfolding { df_bndrs = bndrs, df_args = args })
= extendScopeList bndrs $ mapM_ dffvExpr args
diff --git a/compiler/parser/Parser.y.pp b/compiler/parser/Parser.y.pp
index 9d087068bf..489b5affa4 100644
--- a/compiler/parser/Parser.y.pp
+++ b/compiler/parser/Parser.y.pp
@@ -2249,8 +2249,8 @@ hintExplicitForall span = do
forall <- extension explicitForallEnabled
rulePrag <- extension inRulePrag
unless (forall || rulePrag) $ parseErrorSDoc span $ vcat
- [ text "Illegal symbol '∀' in type"
+ [ text "Illegal symbol '\x2200' in type" -- U+2200 FOR ALL
, text "Perhaps you intended -XRankNTypes or similar flag"
- , text "to enable explicit-forall syntax: ∀ <tvs>. <type>"
+ , text "to enable explicit-forall syntax: \x2200 <tvs>. <type>"
]
}
diff --git a/compiler/rename/RnEnv.lhs b/compiler/rename/RnEnv.lhs
index d73b537af0..73475daa5d 100644
--- a/compiler/rename/RnEnv.lhs
+++ b/compiler/rename/RnEnv.lhs
@@ -780,7 +780,7 @@ lookupImpDeprec iface gre
Note [Used names with interface not loaded]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-It's (just) possible to to find a used
+It's (just) possible to find a used
Name whose interface hasn't been loaded:
a) It might be a WiredInName; in that case we may not load
diff --git a/compiler/rename/RnNames.lhs b/compiler/rename/RnNames.lhs
index 203e1e271c..cdd53d199b 100644
--- a/compiler/rename/RnNames.lhs
+++ b/compiler/rename/RnNames.lhs
@@ -41,6 +41,7 @@ import Data.Map ( Map )
import qualified Data.Map as Map
import Data.List ( partition, (\\), find )
import qualified Data.Set as Set
+import System.FilePath ((</>))
import System.IO
\end{code}
@@ -1468,7 +1469,7 @@ printMinimalImports imports_w_usage
; this_mod <- getModule
; dflags <- getDynFlags
; liftIO $
- do { h <- openFile (mkFilename this_mod) WriteMode
+ do { h <- openFile (mkFilename dflags this_mod) WriteMode
; 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
@@ -1477,7 +1478,11 @@ printMinimalImports imports_w_usage
-- not import Blag( Blag.f, Blag.g )!
}
where
- mkFilename this_mod = moduleNameString (moduleName this_mod) ++ ".imports"
+ mkFilename dflags this_mod
+ | Just d <- dumpDir dflags = d </> basefn
+ | otherwise = basefn
+ where
+ basefn = moduleNameString (moduleName this_mod) ++ ".imports"
mk_minimal (L l decl, used, unused)
| null unused
diff --git a/compiler/rename/RnPat.lhs b/compiler/rename/RnPat.lhs
index 205dde1969..90a83d6a8e 100644
--- a/compiler/rename/RnPat.lhs
+++ b/compiler/rename/RnPat.lhs
@@ -10,7 +10,6 @@ general, all of these functions return a renamed thing, and a set of
free variables.
\begin{code}
-{-# OPTIONS -fno-warn-tabs #-}
-- The above warning supression flag is a temporary kludge.
-- While working on this module you are encouraged to remove it and
-- detab the module (please do the detabbing in a separate patch). See
@@ -27,8 +26,8 @@ module RnPat (-- main entry points
rnHsRecFields1, HsRecFieldContext(..),
- -- Literals
- rnLit, rnOverLit,
+ -- Literals
+ rnLit, rnOverLit,
-- Pattern Error messages that are also used elsewhere
checkTupSize, patSigErr
@@ -39,13 +38,13 @@ module RnPat (-- main entry points
import {-# SOURCE #-} RnExpr ( rnLExpr )
#ifdef GHCI
import {-# SOURCE #-} TcSplice ( runQuasiQuotePat )
-#endif /* GHCI */
+#endif /* GHCI */
#include "HsVersions.h"
import HsSyn
import TcRnMonad
-import TcHsSyn ( hsOverLitName )
+import TcHsSyn ( hsOverLitName )
import RnEnv
import RnTypes
import DynFlags
@@ -55,21 +54,22 @@ import NameSet
import RdrName
import BasicTypes
import Util
-import ListSetOps ( removeDups )
+import ListSetOps ( removeDups )
import Outputable
import SrcLoc
import FastString
-import Literal ( inCharRange )
-import Control.Monad ( when )
+import Literal ( inCharRange )
import TysWiredIn ( nilDataCon )
import DataCon ( dataConName )
+import Control.Monad ( when )
+import Data.Ratio
\end{code}
%*********************************************************
-%* *
- The CpsRn Monad
-%* *
+%* *
+ The CpsRn Monad
+%* *
%*********************************************************
Note [CpsRn monad]
@@ -77,7 +77,7 @@ Note [CpsRn monad]
The CpsRn monad uses continuation-passing style to support this
style of programming:
- do { ...
+ do { ...
; ns <- bindNames rs
; ...blah... }
@@ -96,7 +96,7 @@ p1 scope over p2,p3.
\begin{code}
newtype CpsRn b = CpsRn { unCpsRn :: forall r. (b -> RnM (r, FreeVars))
-> RnM (r, FreeVars) }
- -- See Note [CpsRn monad]
+ -- See Note [CpsRn monad]
instance Monad CpsRn where
return x = CpsRn (\k -> k x)
@@ -144,9 +144,9 @@ pattern, because it never occurs in a constructed position. See
Trac #7336.
%*********************************************************
-%* *
- Name makers
-%* *
+%* *
+ Name makers
+%* *
%*********************************************************
Externally abstract type of name makers,
@@ -154,13 +154,13 @@ which is how you go from a RdrName to a Name
\begin{code}
data NameMaker
- = LamMk -- Lambdas
- Bool -- True <=> report unused bindings
- -- (even if True, the warning only comes out
- -- if -fwarn-unused-matches is on)
+ = LamMk -- Lambdas
+ Bool -- True <=> report unused bindings
+ -- (even if True, the warning only comes out
+ -- if -fwarn-unused-matches is on)
| LetMk -- Let bindings, incl top level
- -- Do *not* check for unused bindings
+ -- Do *not* check for unused bindings
TopLevelFlag
MiniFixityEnv
@@ -186,21 +186,21 @@ rnHsSigCps sig
newPatName :: NameMaker -> Located RdrName -> CpsRn Name
newPatName (LamMk report_unused) rdr_name
= CpsRn (\ thing_inside ->
- do { name <- newLocalBndrRn rdr_name
- ; (res, fvs) <- bindLocalName name (thing_inside name)
- ; when report_unused $ warnUnusedMatches [name] fvs
- ; return (res, name `delFV` fvs) })
+ do { name <- newLocalBndrRn rdr_name
+ ; (res, fvs) <- bindLocalName name (thing_inside name)
+ ; when report_unused $ warnUnusedMatches [name] fvs
+ ; return (res, name `delFV` fvs) })
newPatName (LetMk is_top fix_env) rdr_name
= CpsRn (\ thing_inside ->
do { name <- case is_top of
NotTopLevel -> newLocalBndrRn rdr_name
TopLevel -> newTopSrcBinder rdr_name
- ; bindLocalName name $ -- Do *not* use bindLocalNameFV here
- -- See Note [View pattern usage]
+ ; bindLocalName name $ -- Do *not* use bindLocalNameFV here
+ -- See Note [View pattern usage]
addLocalFixities fix_env [name] $
- thing_inside name })
-
+ thing_inside name })
+
-- Note: the bindLocalName is somewhat suspicious
-- because it binds a top-level name as a local name.
-- however, this binding seems to work, and it only exists for
@@ -219,9 +219,9 @@ report unused variables at the binding level. So we must use bindLocalName
here, *not* bindLocalNameFV. Trac #3943.
%*********************************************************
-%* *
- External entry points
-%* *
+%* *
+ External entry points
+%* *
%*********************************************************
There are various entry points to renaming patterns, depending on
@@ -230,8 +230,8 @@ There are various entry points to renaming patterns, depending on
(e.g., in a case or lambda, but not in a let or at the top-level,
because of the way mutually recursive bindings are handled)
(3) whether the a type signature in the pattern can bind
- lexically-scoped type variables (for unpacking existential
- type vars in data constructors)
+ lexically-scoped type variables (for unpacking existential
+ type vars in data constructors)
(4) whether we do duplicate and unused variable checking
(5) whether there are fixity declarations associated with the names
bound by the patterns that need to be brought into scope with them.
@@ -251,18 +251,18 @@ rnPats :: HsMatchContext Name -- for error messages
-> ([LPat Name] -> RnM (a, FreeVars))
-> RnM (a, FreeVars)
rnPats ctxt pats thing_inside
- = do { envs_before <- getRdrEnvs
+ = do { envs_before <- getRdrEnvs
- -- (1) rename the patterns, bringing into scope all of the term variables
- -- (2) then do the thing inside.
- ; unCpsRn (rnLPatsAndThen (matchNameMaker ctxt) pats) $ \ pats' -> do
+ -- (1) rename the patterns, bringing into scope all of the term variables
+ -- (2) then do the thing inside.
+ ; unCpsRn (rnLPatsAndThen (matchNameMaker ctxt) pats) $ \ pats' -> do
{ -- Check for duplicated and shadowed names
- -- Must do this *after* renaming the patterns
- -- See Note [Collect binders only after renaming] in HsUtils
+ -- Must do this *after* renaming the patterns
+ -- See Note [Collect binders only after renaming] in HsUtils
-- Because we don't bind the vars all at once, we can't
- -- check incrementally for duplicates;
- -- Nor can we check incrementally for shadowing, else we'll
- -- complain *twice* about duplicates e.g. f (x,x) = ...
+ -- check incrementally for duplicates;
+ -- Nor can we check incrementally for shadowing, else we'll
+ -- complain *twice* about duplicates e.g. f (x,x) = ...
; addErrCtxt doc_pat $
checkDupAndShadowedNames envs_before $
collectPatsBinders pats'
@@ -274,7 +274,7 @@ rnPat :: HsMatchContext Name -- for error messages
-> LPat RdrName
-> (LPat Name -> RnM (a, FreeVars))
-> RnM (a, FreeVars) -- Variables bound by pattern do not
- -- appear in the result FreeVars
+ -- appear in the result FreeVars
rnPat ctxt pat thing_inside
= rnPats ctxt [pat] (\pats' -> let [pat'] = pats' in thing_inside pat')
@@ -283,7 +283,7 @@ applyNameMaker mk rdr = do { (n, _fvs) <- runCps (newPatName mk rdr); return n }
-- ----------- Entry point 2: rnBindPat -------------------
-- Binds local names; in a recursive scope that involves other bound vars
--- e.g let { (x, Just y) = e1; ... } in ...
+-- e.g let { (x, Just y) = e1; ... } in ...
-- * does NOT allows type sig to bind type vars
-- * local namemaker
-- * no unused and duplicate checking
@@ -299,9 +299,9 @@ rnBindPat name_maker pat = runCps (rnLPatAndThen name_maker pat)
%*********************************************************
-%* *
- The main event
-%* *
+%* *
+ The main event
+%* *
%*********************************************************
\begin{code}
@@ -356,9 +356,9 @@ rnPatAndThen mk (LitPat lit)
rnPatAndThen _ (NPat lit mb_neg _eq)
= do { lit' <- liftCpsFV $ rnOverLit lit
; mb_neg' <- liftCpsFV $ case mb_neg of
- Nothing -> return (Nothing, emptyFVs)
- Just _ -> do { (neg, fvs) <- lookupSyntaxName negateName
- ; return (Just neg, fvs) }
+ Nothing -> return (Nothing, emptyFVs)
+ Just _ -> do { (neg, fvs) <- lookupSyntaxName negateName
+ ; return (Just neg, fvs) }
; eq' <- liftCpsFV $ lookupSyntaxName eqName
; return (NPat lit' mb_neg' eq') }
@@ -368,7 +368,7 @@ rnPatAndThen mk (NPlusKPat rdr lit _ _)
; minus <- liftCpsFV $ lookupSyntaxName minusName
; ge <- liftCpsFV $ lookupSyntaxName geName
; return (NPlusKPat (L (nameSrcSpan new_name) new_name) lit' ge minus) }
- -- The Report says that n+k patterns must be in Integral
+ -- The Report says that n+k patterns must be in Integral
rnPatAndThen mk (AsPat rdr pat)
= do { new_name <- newPatName mk rdr
@@ -418,7 +418,7 @@ rnPatAndThen mk (QuasiQuotePat qq)
= do { pat <- liftCps $ runQuasiQuotePat qq
; L _ pat' <- rnLPatAndThen mk pat
; return pat' }
-#endif /* GHCI */
+#endif /* GHCI */
rnPatAndThen _ pat = pprPanic "rnLPatAndThen" (ppr pat)
@@ -430,27 +430,27 @@ rnConPatAndThen :: NameMaker
-> CpsRn (Pat Name)
rnConPatAndThen mk con (PrefixCon pats)
- = do { con' <- lookupConCps con
- ; pats' <- rnLPatsAndThen mk pats
- ; return (ConPatIn con' (PrefixCon pats')) }
+ = do { con' <- lookupConCps con
+ ; pats' <- rnLPatsAndThen mk pats
+ ; return (ConPatIn con' (PrefixCon pats')) }
rnConPatAndThen mk con (InfixCon pat1 pat2)
- = do { con' <- lookupConCps con
- ; pat1' <- rnLPatAndThen mk pat1
- ; pat2' <- rnLPatAndThen mk pat2
- ; fixity <- liftCps $ lookupFixityRn (unLoc con')
- ; liftCps $ mkConOpPatRn con' fixity pat1' pat2' }
+ = do { con' <- lookupConCps con
+ ; pat1' <- rnLPatAndThen mk pat1
+ ; pat2' <- rnLPatAndThen mk pat2
+ ; fixity <- liftCps $ lookupFixityRn (unLoc con')
+ ; liftCps $ mkConOpPatRn con' fixity pat1' pat2' }
rnConPatAndThen mk con (RecCon rpats)
- = do { con' <- lookupConCps con
- ; rpats' <- rnHsRecPatsAndThen mk con' rpats
- ; return (ConPatIn con' (RecCon rpats')) }
+ = do { con' <- lookupConCps con
+ ; rpats' <- rnHsRecPatsAndThen mk con' rpats
+ ; return (ConPatIn con' (RecCon rpats')) }
--------------------
rnHsRecPatsAndThen :: NameMaker
- -> Located Name -- Constructor
- -> HsRecFields RdrName (LPat RdrName)
- -> CpsRn (HsRecFields Name (LPat Name))
+ -> Located Name -- Constructor
+ -> HsRecFields RdrName (LPat RdrName)
+ -> CpsRn (HsRecFields Name (LPat Name))
rnHsRecPatsAndThen mk (L _ con) hs_rec_fields@(HsRecFields { rec_dotdot = dd })
= do { flds <- liftCpsFV $ rnHsRecFields1 (HsRecFieldPat con) VarPat hs_rec_fields
; flds' <- mapM rn_field (flds `zip` [1..])
@@ -460,7 +460,7 @@ rnHsRecPatsAndThen mk (L _ con) hs_rec_fields@(HsRecFields { rec_dotdot = dd })
(hsRecFieldArg fld)
; return (fld { hsRecFieldArg = arg' }) }
- -- Suppress unused-match reporting for fields introduced by ".."
+ -- Suppress unused-match reporting for fields introduced by ".."
nested_mk Nothing mk _ = mk
nested_mk (Just _) mk@(LetMk {}) _ = mk
nested_mk (Just n) (LamMk report_unused) n' = LamMk (report_unused && (n' <= n))
@@ -468,9 +468,9 @@ rnHsRecPatsAndThen mk (L _ con) hs_rec_fields@(HsRecFields { rec_dotdot = dd })
%************************************************************************
-%* *
- Record fields
-%* *
+%* *
+ Record fields
+%* *
%************************************************************************
\begin{code}
@@ -504,21 +504,21 @@ rnHsRecFields1 ctxt mk_arg (HsRecFields { rec_flds = flds, rec_dotdot = dotdot }
; return (all_flds, mkFVs (getFieldIds all_flds)) }
where
mb_con = case ctxt of
- HsRecFieldCon con | not (isUnboundName con) -> Just con
- HsRecFieldPat con | not (isUnboundName con) -> Just con
- _other -> Nothing
- -- The unbound name test is because if the constructor
- -- isn't in scope the constructor lookup will add an error
- -- add an error, but still return an unbound name.
- -- We don't want that to screw up the dot-dot fill-in stuff.
+ HsRecFieldCon con | not (isUnboundName con) -> Just con
+ HsRecFieldPat con | not (isUnboundName con) -> Just con
+ _other -> Nothing
+ -- The unbound name test is because if the constructor
+ -- isn't in scope the constructor lookup will add an error
+ -- add an error, but still return an unbound name.
+ -- We don't want that to screw up the dot-dot fill-in stuff.
doc = case mb_con of
Nothing -> ptext (sLit "constructor field name")
Just con -> ptext (sLit "field of constructor") <+> quotes (ppr con)
rn_fld pun_ok parent (HsRecField { hsRecFieldId = fld
- , hsRecFieldArg = arg
- , hsRecPun = pun })
+ , hsRecFieldArg = arg
+ , hsRecPun = pun })
= do { fld'@(L loc fld_nm) <- wrapLocM (lookupSubBndrOcc True parent doc) fld
; arg' <- if pun
then do { checkErr pun_ok (badPun fld)
@@ -528,31 +528,31 @@ rnHsRecFields1 ctxt mk_arg (HsRecFields { rec_flds = flds, rec_dotdot = dotdot }
, hsRecFieldArg = arg'
, hsRecPun = pun }) }
- rn_dotdot :: Maybe Int -- See Note [DotDot fields] in HsPat
- -> Maybe Name -- The constructor (Nothing for an update
- -- or out of scope constructor)
- -> [HsRecField Name (Located arg)] -- Explicit fields
- -> RnM [HsRecField Name (Located arg)] -- Filled in .. fields
+ rn_dotdot :: Maybe Int -- See Note [DotDot fields] in HsPat
+ -> Maybe Name -- The constructor (Nothing for an update
+ -- or out of scope constructor)
+ -> [HsRecField Name (Located arg)] -- Explicit fields
+ -> RnM [HsRecField Name (Located arg)] -- Filled in .. fields
rn_dotdot Nothing _mb_con _flds -- No ".." at all
= return []
rn_dotdot (Just {}) Nothing _flds -- ".." on record update
= do { addErr (badDotDot ctxt); return [] }
rn_dotdot (Just n) (Just con) flds -- ".." on record construction / pat match
= ASSERT( n == length flds )
- do { loc <- getSrcSpanM -- Rather approximate
+ do { loc <- getSrcSpanM -- Rather approximate
; dd_flag <- xoptM Opt_RecordWildCards
; checkErr dd_flag (needFlagDotDot ctxt)
- ; (rdr_env, lcl_env) <- getRdrEnvs
+ ; (rdr_env, lcl_env) <- getRdrEnvs
; con_fields <- lookupConstructorFields con
; let present_flds = getFieldIds flds
parent_tc = find_tycon rdr_env con
-- For constructor uses (but not patterns)
-- the arg should be in scope (unqualified)
- -- ignoring the record field itself
- -- Eg. data R = R { x,y :: Int }
+ -- ignoring the record field itself
+ -- Eg. data R = R { x,y :: Int }
-- f x = R { .. } -- Should expand to R {x=x}, not R{x=x,y=y}
- arg_in_scope fld
+ arg_in_scope fld
= rdr `elemLocalRdrEnv` lcl_env
|| notNull [ gre | gre <- lookupGRE_RdrName rdr rdr_env
, case gre_par gre of
@@ -576,8 +576,8 @@ rnHsRecFields1 ctxt mk_arg (HsRecFields { rec_flds = flds, rec_dotdot = dotdot }
, hsRecFieldArg = L loc (mk_arg arg_rdr)
, hsRecPun = False }
| gre <- dot_dot_gres
- , let fld = gre_name gre
- arg_rdr = mkRdrUnqual (nameOccName fld) ] }
+ , let fld = gre_name gre
+ arg_rdr = mkRdrUnqual (nameOccName fld) ] }
check_disambiguation :: Bool -> Maybe Name -> RnM Parent
-- When disambiguation is on,
@@ -592,7 +592,7 @@ rnHsRecFields1 ctxt mk_arg (HsRecFields { rec_flds = flds, rec_dotdot = dotdot }
-- That's the parent to use for looking up record fields.
find_tycon env con
= case lookupGRE_Name env con of
- [GRE { gre_par = ParentIs p }] -> p
+ [GRE { gre_par = ParentIs p }] -> p
gres -> pprPanic "find_tycon" (ppr con $$ ppr gres)
dup_flds :: [[RdrName]]
@@ -606,20 +606,20 @@ getFieldIds flds = map (unLoc . hsRecFieldId) flds
needFlagDotDot :: HsRecFieldContext -> SDoc
needFlagDotDot ctxt = vcat [ptext (sLit "Illegal `..' in record") <+> pprRFC ctxt,
- ptext (sLit "Use -XRecordWildCards to permit this")]
+ ptext (sLit "Use -XRecordWildCards to permit this")]
badDotDot :: HsRecFieldContext -> SDoc
badDotDot ctxt = ptext (sLit "You cannot use `..' in a record") <+> pprRFC ctxt
badPun :: Located RdrName -> SDoc
badPun fld = vcat [ptext (sLit "Illegal use of punning for field") <+> quotes (ppr fld),
- ptext (sLit "Use -XNamedFieldPuns to permit this")]
+ ptext (sLit "Use -XNamedFieldPuns to permit this")]
dupFieldErr :: HsRecFieldContext -> [RdrName] -> SDoc
dupFieldErr ctxt dups
= hsep [ptext (sLit "duplicate field name"),
quotes (ppr (head dups)),
- ptext (sLit "in record"), pprRFC ctxt]
+ ptext (sLit "in record"), pprRFC ctxt]
pprRFC :: HsRecFieldContext -> SDoc
pprRFC (HsRecFieldCon {}) = ptext (sLit "construction")
@@ -629,9 +629,9 @@ pprRFC (HsRecFieldUpd {}) = ptext (sLit "update")
%************************************************************************
-%* *
+%* *
\subsubsection{Literals}
-%* *
+%* *
%************************************************************************
When literals occur we have to make sure
@@ -643,28 +643,40 @@ rnLit :: HsLit -> RnM ()
rnLit (HsChar c) = checkErr (inCharRange c) (bogusCharError c)
rnLit _ = return ()
+-- Turn a Fractional-looking literal which happens to be an integer into an
+-- Integer-looking literal.
+generalizeOverLitVal :: OverLitVal -> OverLitVal
+generalizeOverLitVal (HsFractional (FL {fl_value=val}))
+ | denominator val == 1 = HsIntegral (numerator val)
+generalizeOverLitVal lit = lit
+
rnOverLit :: HsOverLit t -> RnM (HsOverLit Name, FreeVars)
-rnOverLit lit@(OverLit {ol_val=val})
- = do { let std_name = hsOverLitName val
- ; (from_thing_name, fvs) <- lookupSyntaxName std_name
- ; let rebindable = case from_thing_name of
- HsVar v -> v /= std_name
- _ -> panic "rnOverLit"
- ; return (lit { ol_witness = from_thing_name
- , ol_rebindable = rebindable }, fvs) }
+rnOverLit origLit
+ = do { opt_NumDecimals <- xoptM Opt_NumDecimals
+ ; let { lit@(OverLit {ol_val=val})
+ | opt_NumDecimals = origLit {ol_val = generalizeOverLitVal (ol_val origLit)}
+ | otherwise = origLit
+ }
+ ; let std_name = hsOverLitName val
+ ; (from_thing_name, fvs) <- lookupSyntaxName std_name
+ ; let rebindable = case from_thing_name of
+ HsVar v -> v /= std_name
+ _ -> panic "rnOverLit"
+ ; return (lit { ol_witness = from_thing_name
+ , ol_rebindable = rebindable }, fvs) }
\end{code}
%************************************************************************
-%* *
+%* *
\subsubsection{Errors}
-%* *
+%* *
%************************************************************************
\begin{code}
patSigErr :: Outputable a => a -> SDoc
patSigErr ty
= (ptext (sLit "Illegal signature in pattern:") <+> ppr ty)
- $$ nest 4 (ptext (sLit "Use -XScopedTypeVariables to permit it"))
+ $$ nest 4 (ptext (sLit "Use -XScopedTypeVariables to permit it"))
bogusCharError :: Char -> SDoc
bogusCharError c
diff --git a/compiler/simplCore/OccurAnal.lhs b/compiler/simplCore/OccurAnal.lhs
index 13e468f685..75d5364f63 100644
--- a/compiler/simplCore/OccurAnal.lhs
+++ b/compiler/simplCore/OccurAnal.lhs
@@ -880,7 +880,7 @@ reOrderNodes depth bndr_set weak_fvs (node : nodes) binds
| Just inl_source <- isStableCoreUnfolding_maybe (idUnfolding bndr)
= case inl_source of
- InlineWrapper {} -> 10 -- Note [INLINE pragmas]
+ InlineWrapper -> 10 -- Note [INLINE pragmas]
_other -> 3 -- Data structures are more important than this
-- so that dictionary/method recursion unravels
-- Note that this case hits all InlineRule things, so we
@@ -1643,7 +1643,7 @@ When the scrutinee is a GlobalId we must take care in two ways
i) In order to *know* whether 'x' occurs free in the RHS, we need its
occurrence info. BUT, we don't gather occurrence info for
GlobalIds. That's the reason for the (small) occ_gbl_scrut env in
- OccEnv is for: it says "gather occurrence info for these.
+ OccEnv is for: it says "gather occurrence info for these".
ii) We must call localiseId on 'x' first, in case it's a GlobalId, or
has an External Name. See, for example, SimplEnv Note [Global Ids in
diff --git a/compiler/simplCore/SimplCore.lhs b/compiler/simplCore/SimplCore.lhs
index 62e167a79e..a3101f715e 100644
--- a/compiler/simplCore/SimplCore.lhs
+++ b/compiler/simplCore/SimplCore.lhs
@@ -121,6 +121,7 @@ getCoreToDo dflags
cse = gopt Opt_CSE dflags
spec_constr = gopt Opt_SpecConstr dflags
liberate_case = gopt Opt_LiberateCase dflags
+ late_dmd_anal = gopt Opt_LateDmdAnal dflags
static_args = gopt Opt_StaticArgumentTransformation dflags
rules_on = gopt Opt_EnableRewriteRules dflags
eta_expand_on = gopt Opt_DoLambdaEtaExpansion dflags
@@ -294,7 +295,15 @@ getCoreToDo dflags
maybe_rule_check (Phase 0),
-- Final clean-up simplification:
- simpl_phase 0 ["final"] max_iter
+ simpl_phase 0 ["final"] max_iter,
+
+ runWhen late_dmd_anal $ CoreDoPasses [
+ CoreDoStrictness,
+ CoreDoWorkerWrapper,
+ simpl_phase 0 ["post-late-ww"] max_iter
+ ],
+
+ maybe_rule_check (Phase 0)
]
\end{code}
diff --git a/compiler/simplCore/SimplEnv.lhs b/compiler/simplCore/SimplEnv.lhs
index 333eba7f14..5f1013def8 100644
--- a/compiler/simplCore/SimplEnv.lhs
+++ b/compiler/simplCore/SimplEnv.lhs
@@ -722,7 +722,7 @@ See Note [Loop breaking and RULES] in OccAnal.
\begin{code}
addBndrRules :: SimplEnv -> InBndr -> OutBndr -> (SimplEnv, OutBndr)
--- Rules are added back in to to the bin
+-- Rules are added back into the bin
addBndrRules env in_id out_id
| isEmptySpecInfo old_rules = (env, out_id)
| otherwise = (modifyInScope env final_id, final_id)
diff --git a/compiler/simplCore/Simplify.lhs b/compiler/simplCore/Simplify.lhs
index f0f894d744..d006f7f6eb 100644
--- a/compiler/simplCore/Simplify.lhs
+++ b/compiler/simplCore/Simplify.lhs
@@ -30,7 +30,6 @@ import Demand ( StrictSig(..), dmdTypeDepth )
import PprCore ( pprParendExpr, pprCoreExpr )
import CoreUnfold
import CoreUtils
-import qualified CoreSubst
import CoreArity
import Rules ( lookupRule, getRules )
import TysPrim ( realWorldStatePrimTy )
@@ -737,8 +736,7 @@ simplUnfolding env top_lvl id _
, uf_src = src, uf_guidance = guide })
| isStableSource src
= do { expr' <- simplExpr rule_env expr
- ; let src' = CoreSubst.substUnfoldingSource (mkCoreSubst (text "inline-unf") env) src
- is_top_lvl = isTopLevel top_lvl
+ ; let is_top_lvl = isTopLevel top_lvl
; case guide of
UnfWhen sat_ok _ -- Happens for INLINE things
-> let guide' = UnfWhen sat_ok (inlineBoringOk expr')
@@ -747,14 +745,14 @@ simplUnfolding env top_lvl id _
-- for dfuns for single-method classes; see
-- Note [Single-method classes] in TcInstDcls.
-- A test case is Trac #4138
- in return (mkCoreUnfolding src' is_top_lvl expr' arity guide')
+ in return (mkCoreUnfolding src is_top_lvl expr' arity guide')
-- See Note [Top-level flag on inline rules] in CoreUnfold
_other -- Happens for INLINABLE things
-> let bottoming = isBottomingId id
in bottoming `seq` -- See Note [Force bottoming field]
do dflags <- getDynFlags
- return (mkUnfolding dflags src' is_top_lvl bottoming expr')
+ return (mkUnfolding dflags src is_top_lvl bottoming expr')
-- If the guidance is UnfIfGoodArgs, this is an INLINABLE
-- unfolding, and we need to make sure the guidance is kept up
-- to date with respect to any changes in the unfolding.
diff --git a/compiler/specialise/SpecConstr.lhs b/compiler/specialise/SpecConstr.lhs
index a5df7d52bc..0518367658 100644
--- a/compiler/specialise/SpecConstr.lhs
+++ b/compiler/specialise/SpecConstr.lhs
@@ -560,7 +560,7 @@ 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
+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.
diff --git a/compiler/stranal/WorkWrap.lhs b/compiler/stranal/WorkWrap.lhs
index e697dfe1ff..cc4010503b 100644
--- a/compiler/stranal/WorkWrap.lhs
+++ b/compiler/stranal/WorkWrap.lhs
@@ -11,7 +11,7 @@
-- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSpaces
-- for details
-module WorkWrap ( wwTopBinds, mkWrapper ) where
+module WorkWrap ( wwTopBinds ) where
import CoreSyn
import CoreUnfold ( certainlyWillInline, mkInlineUnfolding, mkWwInlineRule )
@@ -19,7 +19,6 @@ import CoreUtils ( exprType, exprIsHNF )
import CoreArity ( exprArity )
import Var
import Id
-import Type ( Type )
import IdInfo
import UniqSupply
import BasicTypes
@@ -358,7 +357,7 @@ splitFun dflags fn_id fn_info wrap_dmds res_info rhs
-- The inl_inline is bound to be False, else we would not be
-- making a wrapper
- wrap_id = fn_id `setIdUnfolding` mkWwInlineRule work_id wrap_rhs arity
+ wrap_id = fn_id `setIdUnfolding` mkWwInlineRule wrap_rhs arity
`setInlinePragma` wrap_prag
`setIdOccInfo` NoOccInfo
-- Zap any loop-breaker-ness, to avoid bleating from Lint
@@ -390,6 +389,9 @@ get_one_shots (Lam b e)
| otherwise = get_one_shots e
get_one_shots (Tick _ e) = get_one_shots e
get_one_shots _ = noOneShotInfo
+
+noOneShotInfo :: [Bool]
+noOneShotInfo = repeat False
\end{code}
Note [Thunk splitting]
@@ -446,27 +448,3 @@ splitThunk dflags fn_id rhs = do
(_, wrap_fn, work_fn) <- mkWWstr dflags [fn_id]
return [ (fn_id, Let (NonRec fn_id rhs) (wrap_fn (work_fn (Var fn_id)))) ]
\end{code}
-
-
-%************************************************************************
-%* *
-\subsection{The worker wrapper core}
-%* *
-%************************************************************************
-
-@mkWrapper@ is called when importing a function. We have the type of
-the function and the name of its worker, and we want to make its body (the wrapper).
-
-\begin{code}
-mkWrapper :: DynFlags
- -> Type -- Wrapper type
- -> StrictSig -- Wrapper strictness info
- -> UniqSM (Id -> CoreExpr) -- Wrapper body, missing worker Id
-
-mkWrapper dflags fun_ty (StrictSig (DmdType _ demands res_info)) = do
- (_, wrap_fn, _) <- mkWwBodies dflags fun_ty demands res_info noOneShotInfo
- return wrap_fn
-
-noOneShotInfo :: [Bool]
-noOneShotInfo = repeat False
-\end{code}
diff --git a/compiler/typecheck/TcDeriv.lhs b/compiler/typecheck/TcDeriv.lhs
index 0a691651fb..144678e4dd 100644
--- a/compiler/typecheck/TcDeriv.lhs
+++ b/compiler/typecheck/TcDeriv.lhs
@@ -1477,7 +1477,7 @@ mkNewTypeEqn orig dflags tvs
ptext (sLit "GeneralizedNewtypeDeriving on this class;") $$
ptext (sLit "the last parameter of") <+>
quotes (ppr (className cls)) <+>
- ptext (sLit "is at role N")
+ ptext (sLit "is at role Nominal")
\end{code}
diff --git a/compiler/typecheck/TcErrors.lhs b/compiler/typecheck/TcErrors.lhs
index 4023311d3a..307e922633 100644
--- a/compiler/typecheck/TcErrors.lhs
+++ b/compiler/typecheck/TcErrors.lhs
@@ -500,7 +500,7 @@ solve it.
\begin{code}
mkIrredErr :: ReportErrCtxt -> [Ct] -> TcM ErrMsg
mkIrredErr ctxt cts
- = do { (ctxt, binds_msg) <- relevantBindings ctxt ct1
+ = do { (ctxt, binds_msg) <- relevantBindings True ctxt ct1
; mkErrorMsg ctxt ct1 (msg $$ binds_msg) }
where
(ct1:_) = cts
@@ -516,7 +516,8 @@ mkHoleError ctxt ct@(CHoleCan { cc_occ = occ })
msg = vcat [ hang (ptext (sLit "Found hole") <+> quotes (ppr occ))
2 (ptext (sLit "with type:") <+> pprType (ctEvPred (cc_ev ct)))
, ppUnless (null tyvars_msg) (ptext (sLit "Where:") <+> vcat tyvars_msg) ]
- ; (ctxt, binds_doc) <- relevantBindings ctxt ct
+ ; (ctxt, binds_doc) <- relevantBindings False ctxt ct
+ -- The 'False' means "don't filter the bindings; see Trac #8191
; mkErrorMsg ctxt ct (msg $$ binds_doc) }
where
loc_msg tv
@@ -532,7 +533,7 @@ mkHoleError _ ct = pprPanic "mkHoleError" (ppr ct)
----------------
mkIPErr :: ReportErrCtxt -> [Ct] -> TcM ErrMsg
mkIPErr ctxt cts
- = do { (ctxt, bind_msg) <- relevantBindings ctxt ct1
+ = do { (ctxt, bind_msg) <- relevantBindings True ctxt ct1
; mkErrorMsg ctxt ct1 (msg $$ bind_msg) }
where
(ct1:_) = cts
@@ -583,7 +584,7 @@ mkEqErr1 :: ReportErrCtxt -> Ct -> TcM ErrMsg
-- Wanted constraints only!
mkEqErr1 ctxt ct
| isGiven ev
- = do { (ctxt, binds_msg) <- relevantBindings ctxt ct
+ = do { (ctxt, binds_msg) <- relevantBindings True ctxt ct
; let (given_loc, given_msg) = mk_given (cec_encl ctxt)
; dflags <- getDynFlags
; mkEqErr_help dflags ctxt (given_msg $$ binds_msg)
@@ -591,7 +592,7 @@ mkEqErr1 ctxt ct
Nothing ty1 ty2 }
| otherwise -- Wanted or derived
- = do { (ctxt, binds_msg) <- relevantBindings ctxt ct
+ = do { (ctxt, binds_msg) <- relevantBindings True ctxt ct
; (ctxt, tidy_orig) <- zonkTidyOrigin ctxt (ctLocOrigin (cc_loc ct))
; let (is_oriented, wanted_msg) = mk_wanted_extra tidy_orig
; dflags <- getDynFlags
@@ -931,7 +932,7 @@ mk_dict_err :: ReportErrCtxt -> (Ct, ClsInstLookupResult)
mk_dict_err ctxt (ct, (matches, unifiers, safe_haskell))
| null matches -- No matches but perhaps several unifiers
= do { let (is_ambig, ambig_msg) = mkAmbigMsg ct
- ; (ctxt, binds_msg) <- relevantBindings ctxt ct
+ ; (ctxt, binds_msg) <- relevantBindings True ctxt ct
; traceTc "mk_dict_err" (ppr ct $$ ppr is_ambig $$ ambig_msg)
; return (ctxt, cannot_resolve_msg is_ambig binds_msg ambig_msg) }
@@ -1171,17 +1172,25 @@ getSkolemInfo (implic:implics) tv
-- careful to zonk the Id's type first, so it has to be in the monad.
-- We must be careful to pass it a zonked type variable, too.
-relevantBindings :: ReportErrCtxt -> Ct
+relevantBindings :: Bool -- True <=> filter by tyvar; False <=> no filtering
+ -- See Trac #8191
+ -> ReportErrCtxt -> Ct
-> TcM (ReportErrCtxt, SDoc)
-relevantBindings ctxt ct
- = do { (tidy_env', docs) <- go (cec_tidy ctxt) (6, emptyVarSet)
- (reverse (tcl_bndrs lcl_env))
+relevantBindings want_filtering ctxt ct
+ = do { dflags <- getDynFlags
+ ; (tidy_env', docs, discards)
+ <- go (cec_tidy ctxt) (maxRelevantBinds dflags)
+ emptyVarSet [] False
+ (reverse (tcl_bndrs lcl_env))
-- The 'reverse' makes us work from outside in
- -- Blargh; maybe have a flag for this "6"
; traceTc "relevantBindings" (ppr [id | TcIdBndr id _ <- tcl_bndrs lcl_env])
; let doc = hang (ptext (sLit "Relevant bindings include"))
- 2 (vcat docs)
+ 2 (vcat docs $$ max_msg)
+ max_msg | discards
+ = ptext (sLit "(Some bindings suppressed; use -fmax-relevant-binds=N or -fno-max-relevant-binds)")
+ | otherwise = empty
+
; if null docs
then return (ctxt, empty)
else do { traceTc "rb" doc
@@ -1190,28 +1199,38 @@ relevantBindings ctxt ct
lcl_env = ctLocEnv (cc_loc ct)
ct_tvs = tyVarsOfCt ct
- go :: TidyEnv -> (Int, TcTyVarSet)
- -> [TcIdBinder] -> TcM (TidyEnv, [SDoc])
- go tidy_env (_,_) []
- = return (tidy_env, [])
- go tidy_env (n_left,tvs_seen) (TcIdBndr id _ : tc_bndrs)
- | n_left <= 0, ct_tvs `subVarSet` tvs_seen
- = -- We have run out of n_left, and we
- -- already have bindings mentioning all of ct_tvs
- go tidy_env (n_left,tvs_seen) tc_bndrs
- | otherwise
+ run_out :: Maybe Int -> Bool
+ run_out Nothing = False
+ run_out (Just n) = n <= 0
+
+ dec_max :: Maybe Int -> Maybe Int
+ dec_max = fmap (\n -> n - 1)
+
+ go :: TidyEnv -> Maybe Int -> TcTyVarSet -> [SDoc] -> Bool
+ -> [TcIdBinder]
+ -> TcM (TidyEnv, [SDoc], Bool) -- The bool says if we filtered any out
+ -- because of lack of fuel
+ go tidy_env _ _ docs discards []
+ = return (tidy_env, reverse docs, discards)
+ go tidy_env n_left tvs_seen docs discards (TcIdBndr id _ : tc_bndrs)
= do { (tidy_env', tidy_ty) <- zonkTidyTcType tidy_env (idType id)
; let id_tvs = tyVarsOfType tidy_ty
doc = sep [ pprPrefixOcc id <+> dcolon <+> ppr tidy_ty
, nest 2 (parens (ptext (sLit "bound at")
<+> ppr (getSrcLoc id)))]
- ; if id_tvs `intersectsVarSet` ct_tvs
- && (n_left > 0 || not (id_tvs `subVarSet` tvs_seen))
- -- Either we n_left is big enough,
- -- or this binding mentions a new type variable
- then do { (env', docs) <- go tidy_env' (n_left - 1, tvs_seen `unionVarSet` id_tvs) tc_bndrs
- ; return (env', doc:docs) }
- else go tidy_env (n_left, tvs_seen) tc_bndrs }
+ new_seen = tvs_seen `unionVarSet` id_tvs
+
+ ; if (want_filtering && id_tvs `disjointVarSet` ct_tvs)
+ -- We want to filter out this binding anyway
+ then go tidy_env n_left tvs_seen docs discards tc_bndrs
+
+ else if run_out n_left && id_tvs `subVarSet` tvs_seen
+ -- We've run out of n_left fuel and this binding only
+ -- mentions aleady-seen type variables, so discard it
+ then go tidy_env n_left tvs_seen docs True tc_bndrs
+
+ -- Keep this binding, decrement fuel
+ else go tidy_env' (dec_max n_left) new_seen (doc:docs) discards tc_bndrs }
-----------------------
warnDefaulting :: Cts -> Type -> TcM ()
diff --git a/compiler/typecheck/TcRnTypes.lhs b/compiler/typecheck/TcRnTypes.lhs
index 43b4f36aa2..94787eb39b 100644
--- a/compiler/typecheck/TcRnTypes.lhs
+++ b/compiler/typecheck/TcRnTypes.lhs
@@ -916,12 +916,13 @@ data Ct
cc_loc :: CtLoc
}
- | CNonCanonical { -- See Note [NonCanonical Semantics]
+ | CNonCanonical { -- See Note [NonCanonical Semantics]
cc_ev :: CtEvidence,
cc_loc :: CtLoc
}
- | CHoleCan {
+ | CHoleCan { -- Treated as an "insoluble" constraint
+ -- See Note [Insoluble constraints]
cc_ev :: CtEvidence,
cc_loc :: CtLoc,
cc_occ :: OccName -- The name of this hole
diff --git a/compiler/typecheck/TcSimplify.lhs b/compiler/typecheck/TcSimplify.lhs
index b17f3950a4..b39bc85669 100644
--- a/compiler/typecheck/TcSimplify.lhs
+++ b/compiler/typecheck/TcSimplify.lhs
@@ -816,29 +816,34 @@ defaultTyVar the_tv
approximateWC :: WantedConstraints -> Cts
-- Postcondition: Wanted or Derived Cts
+-- See Note [ApproximateWC]
approximateWC wc
= float_wc emptyVarSet wc
where
float_wc :: TcTyVarSet -> WantedConstraints -> Cts
- float_wc skols (WC { wc_flat = flats, wc_impl = implics })
- = do_bag (float_flat skols) flats `unionBags`
- do_bag (float_implic skols) implics
-
+ float_wc trapping_tvs (WC { wc_flat = flats, wc_impl = implics })
+ = filterBag is_floatable flats `unionBags`
+ do_bag (float_implic new_trapping_tvs) implics
+ where
+ new_trapping_tvs = fixVarSet grow trapping_tvs
+ is_floatable ct = tyVarsOfCt ct `disjointVarSet` new_trapping_tvs
+
+ grow tvs = foldrBag grow_one tvs flats
+ grow_one ct tvs | ct_tvs `intersectsVarSet` tvs = tvs `unionVarSet` ct_tvs
+ | otherwise = tvs
+ where
+ ct_tvs = tyVarsOfCt ct
+
float_implic :: TcTyVarSet -> Implication -> Cts
- float_implic skols imp
+ float_implic trapping_tvs imp
| hasEqualities (ic_given imp) -- Don't float out of equalities
= emptyCts -- cf floatEqualities
- | otherwise -- See Note [approximateWC]
- = float_wc skols' (ic_wanted imp)
+ | otherwise -- See Note [ApproximateWC]
+ = float_wc new_trapping_tvs (ic_wanted imp)
where
- skols' = skols `extendVarSetList` ic_skols imp `extendVarSetList` ic_fsks imp
+ new_trapping_tvs = trapping_tvs `extendVarSetList` ic_skols imp
+ `extendVarSetList` ic_fsks imp
- float_flat :: TcTyVarSet -> Ct -> Cts
- float_flat skols ct
- | tyVarsOfCt ct `disjointVarSet` skols
- = singleCt ct
- | otherwise = emptyCts
-
do_bag :: (a -> Bag c) -> Bag a -> Bag c
do_bag f = foldrBag (unionBags.f) emptyBag
\end{code}
@@ -849,23 +854,43 @@ approximateWC takes a constraint, typically arising from the RHS of a
let-binding whose type we are *inferring*, and extracts from it some
*flat* constraints that we might plausibly abstract over. Of course
the top-level flat constraints are plausible, but we also float constraints
-out from inside, if the are not captured by skolems.
-
-However we do *not* float anything out if the implication binds equality
-constriants, because that defeats the OutsideIn story. Consider
- data T a where
- TInt :: T Int
- MkT :: T a
-
- f TInt = 3::Int
-
-We get the implication (a ~ Int => res ~ Int), where so far we've decided
- f :: T a -> res
-We don't want to float (res~Int) out because then we'll infer
- f :: T a -> Int
-which is only on of the possible types. (GHC 7.6 accidentally *did*
-float out of such implications, which meant it would happily infer
-non-principal types.)
+out from inside, if they are not captured by skolems.
+
+The same function is used when doing type-class defaulting (see the call
+to applyDefaultingRules) to extract constraints that that might be defaulted.
+
+There are two caveats:
+
+1. We do *not* float anything out if the implication binds equality
+ constraints, because that defeats the OutsideIn story. Consider
+ data T a where
+ TInt :: T Int
+ MkT :: T a
+
+ f TInt = 3::Int
+
+ We get the implication (a ~ Int => res ~ Int), where so far we've decided
+ f :: T a -> res
+ We don't want to float (res~Int) out because then we'll infer
+ f :: T a -> Int
+ which is only on of the possible types. (GHC 7.6 accidentally *did*
+ float out of such implications, which meant it would happily infer
+ non-principal types.)
+
+2. We do not float out an inner constraint that shares a type variable
+ (transitively) with one that is trapped by a skolem. Eg
+ forall a. F a ~ beta, Integral beta
+ We don't want to float out (Integral beta). Doing so would be bad
+ when defaulting, because then we'll default beta:=Integer, and that
+ makes the error message much worse; we'd get
+ Can't solve F a ~ Integer
+ rather than
+ Can't solve Integral (F a)
+
+ Moreover, floating out these "contaminated" constraints doesn't help
+ when generalising either. If we generalise over (Integral b), we still
+ can't solve the retained implication (forall a. F a ~ b). Indeed,
+ arguably that too would be a harder error to understand.
Note [DefaultTyVar]
~~~~~~~~~~~~~~~~~~~
diff --git a/compiler/typecheck/TcTyClsDecls.lhs b/compiler/typecheck/TcTyClsDecls.lhs
index 0cd4f2d5a9..70e72f593f 100644
--- a/compiler/typecheck/TcTyClsDecls.lhs
+++ b/compiler/typecheck/TcTyClsDecls.lhs
@@ -2147,8 +2147,8 @@ inaccessibleCoAxBranch tc fi
badRoleAnnot :: Name -> Role -> Role -> SDoc
badRoleAnnot var annot inferred
= hang (ptext (sLit "Role mismatch on variable") <+> ppr var <> colon)
- 2 (sep [ ptext (sLit "Annotation says"), ppr annot
- , ptext (sLit "but role"), ppr inferred
+ 2 (sep [ ptext (sLit "Annotation says"), pprFullRole annot
+ , ptext (sLit "but role"), pprFullRole inferred
, ptext (sLit "is required") ])
\end{code}
diff --git a/compiler/types/CoAxiom.lhs b/compiler/types/CoAxiom.lhs
index e507607cd3..ed1a68432b 100644
--- a/compiler/types/CoAxiom.lhs
+++ b/compiler/types/CoAxiom.lhs
@@ -26,12 +26,13 @@ module CoAxiom (
coAxBranchLHS, coAxBranchRHS, coAxBranchSpan, coAxBranchIncomps,
placeHolderIncomps,
- Role(..)
+ Role(..), pprFullRole
) where
import {-# SOURCE #-} TypeRep ( Type )
import {-# SOURCE #-} TyCon ( TyCon )
import Outputable
+import FastString
import Name
import Unique
import Var
@@ -440,6 +441,11 @@ This is defined here to avoid circular dependencies.
data Role = Nominal | Representational | Phantom
deriving (Eq, Data.Data, Data.Typeable)
+pprFullRole :: Role -> SDoc
+pprFullRole Nominal = ptext (sLit "Nominal")
+pprFullRole Representational = ptext (sLit "Representational")
+pprFullRole Phantom = ptext (sLit "Phantom")
+
instance Outputable Role where
ppr Nominal = char 'N'
ppr Representational = char 'R'
diff --git a/compiler/types/InstEnv.lhs b/compiler/types/InstEnv.lhs
index 31a1bfb8df..826537db17 100644
--- a/compiler/types/InstEnv.lhs
+++ b/compiler/types/InstEnv.lhs
@@ -535,7 +535,7 @@ lookupInstEnv' ie cls tys
= find ((item, map (lookup_tv subst) tpl_tvs) : ms) us rest
-- Does not match, so next check whether the things unify
- -- See Note [Overlapping instances] above
+ -- See Note [Overlapping instances] and Note [Incoherent Instances]
| Incoherent _ <- oflag
= find ms us rest
@@ -625,12 +625,19 @@ insert_overlapping new_item (item:items)
-- Keep new one
| old_beats_new = item : items
-- Keep old one
+ | incoherent new_item = item : items -- note [Incoherent instances]
+ -- Keep old one
+ | incoherent item = new_item : items
+ -- Keep new one
| otherwise = item : insert_overlapping new_item items
-- Keep both
where
new_beats_old = new_item `beats` item
old_beats_new = item `beats` new_item
+ incoherent (inst, _) = case is_flag inst of Incoherent _ -> True
+ _ -> False
+
(instA, _) `beats` (instB, _)
= overlap_ok &&
isJust (tcMatchTys (mkVarSet (is_tvs instB)) (is_tys instB) (is_tys instA))
@@ -646,6 +653,52 @@ insert_overlapping new_item (item:items)
_ -> True
\end{code}
+Note [Incoherent instances]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+For some classes, the choise of a particular instance does not matter, any one
+is good. E.g. consider
+
+ class D a b where { opD :: a -> b -> String }
+ instance D Int b where ...
+ instance D a Int where ...
+
+ g (x::Int) = opD x x
+
+For such classes this should work (without having to add an "instance D Int
+Int", and using -XOverlappingInstances, which would then work). This is what
+-XIncoherentInstances is for: Telling GHC "I don't care which instance you use;
+if you can use one, use it."
+
+
+Should this logic only work when all candidates have the incoherent flag, or
+even when all but one have it? The right choice is the latter, which can be
+justified by comparing the behaviour with how -XIncoherentInstances worked when
+it was only about the unify-check (note [Overlapping instances]):
+
+Example:
+ class C a b c where foo :: (a,b,c)
+ instance C [a] b Int
+ instance [incoherent] [Int] b c
+ instance [incoherent] C a Int c
+Thanks to the incoherent flags,
+ foo :: ([a],b,Int)
+works: Only instance one matches, the others just unify, but are marked
+incoherent.
+
+So I can write
+ (foo :: ([a],b,Int)) :: ([Int], Int, Int).
+but if that works then I really want to be able to write
+ foo :: ([Int], Int, Int)
+as well. Now all three instances from above match. None is more specific than
+another, so none is ruled out by the normal overlapping rules. One of them is
+not incoherent, but we still want this to compile. Hence the
+"all-but-one-logic".
+
+The implementation is in insert_overlapping, where we remove matching
+incoherent instances as long as there are are others.
+
+
%************************************************************************
%* *
diff --git a/compiler/types/TypeRep.lhs b/compiler/types/TypeRep.lhs
index e557a6cbb5..cb5b8f0f18 100644
--- a/compiler/types/TypeRep.lhs
+++ b/compiler/types/TypeRep.lhs
@@ -691,7 +691,7 @@ pprTcApp p pp tc tys
pprTypeApp :: TyCon -> [Type] -> SDoc
pprTypeApp tc tys
= ppr_type_name_app TopPrec ppr_type (getName tc) (ppr tc) tys
- -- We have to to use ppr on the TyCon (not its name)
+ -- We have to use ppr on the TyCon (not its name)
-- so that we get promotion quotes in the right place
pprTypeNameApp :: Prec -> (Prec -> a -> SDoc) -> Name -> [a] -> SDoc
diff --git a/compiler/types/Unify.lhs b/compiler/types/Unify.lhs
index 35f4ef5576..4b5d2ea63d 100644
--- a/compiler/types/Unify.lhs
+++ b/compiler/types/Unify.lhs
@@ -383,19 +383,28 @@ failure.
tcUnifyTysFG ("fine-grained") returns one of three results: success, occurs-check
failure ("MaybeApart"), or general failure ("SurelyApart").
+See also Trac #8162.
+
+It's worth noting that unification in the presence of infinite types is not
+complete. This means that, sometimes, a closed type family does not reduce
+when it should. See test case indexed-types/should_fail/Overlap15 for an
+example.
+
Note [The substitution in MaybeApart]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The constructor MaybeApart carries data with it, typically a TvSubstEnv. Why?
Because consider unifying these:
-(a, a, a) ~ (Int, F Bool, Bool)
+(a, a, Int) ~ (b, [b], Bool)
-If we go left-to-right, we start with [a |-> Int]. Then, on the middle terms,
-we apply the subst we have so far and discover that Int is maybeApart from
-F Bool. But, we can't stop there! Because if we continue, we discover that
-Int is SurelyApart from Bool, and therefore the types are apart. This has
-practical consequences for the ability for closed type family applications
-to reduce. See test case indexed-types/should_compile/Overlap14.
+If we go left-to-right, we start with [a |-> b]. Then, on the middle terms, we
+apply the subst we have so far and discover that we need [b |-> [b]]. Because
+this fails the occurs check, we say that the types are MaybeApart (see above
+Note [Fine-grained unification]). But, we can't stop there! Because if we
+continue, we discover that Int is SurelyApart from Bool, and therefore the
+types are apart. This has practical consequences for the ability for closed
+type family applications to reduce. See test case
+indexed-types/should_compile/Overlap14.
Note [Unifying with skolems]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -405,7 +414,6 @@ may later be instantiated with a unifyable type. So, we return maybeApart
in these cases.
\begin{code}
--- See Note [Unification and apartness]
tcUnifyTys :: (TyVar -> BindFlag)
-> [Type] -> [Type]
-> Maybe TvSubst -- A regular one-shot (idempotent) substitution
@@ -419,7 +427,7 @@ tcUnifyTys bind_fn tys1 tys2
= Nothing
-- This type does double-duty. It is used in the UM (unifier monad) and to
--- return the final result.
+-- return the final result. See Note [Fine-grained unification]
type UnifyResult = UnifyResultM TvSubst
data UnifyResultM a = Unifiable a -- the subst that unifies the types
| MaybeApart a -- the subst has as much as we know
diff --git a/compiler/utils/FastString.lhs b/compiler/utils/FastString.lhs
index 25f98021f4..2800d8ab2e 100644
--- a/compiler/utils/FastString.lhs
+++ b/compiler/utils/FastString.lhs
@@ -530,7 +530,7 @@ nilFS = mkFastString ""
getFastStringTable :: IO [[FastString]]
getFastStringTable = do
tbl <- readIORef string_table
- buckets <- mapM (lookupTbl tbl) [0 .. hASH_TBL_SIZE]
+ buckets <- mapM (lookupTbl tbl) [0 .. hASH_TBL_SIZE-1]
return buckets
-- -----------------------------------------------------------------------------
diff --git a/compiler/utils/Fingerprint.hsc b/compiler/utils/Fingerprint.hsc
index 95f31c08bb..e0da2da567 100644
--- a/compiler/utils/Fingerprint.hsc
+++ b/compiler/utils/Fingerprint.hsc
@@ -1,5 +1,5 @@
-- ----------------------------------------------------------------------------
---
+--
-- (c) The University of Glasgow 2006
--
-- Fingerprints for recompilation checking and ABI versioning.
@@ -8,18 +8,26 @@
--
-- ----------------------------------------------------------------------------
-{-# OPTIONS_GHC -fno-warn-orphans #-}
module Fingerprint (
Fingerprint(..), fingerprint0,
readHexFingerprint,
fingerprintData,
- fingerprintString
+ fingerprintString,
+ -- Re-exported from GHC.Fingerprint for GHC >= 7.7, local otherwise
+ getFileHash
) where
#include "md5.h"
##include "HsVersions.h"
import Numeric ( readHex )
+#if __GLASGOW_HASKELL__ < 707
+-- Only needed for getFileHash below.
+import Foreign
+import Panic
+import System.IO
+import Control.Monad ( when )
+#endif
import GHC.Fingerprint
@@ -30,3 +38,32 @@ readHexFingerprint s = Fingerprint w1 w2
[(w1,"")] = readHex s1
[(w2,"")] = readHex (take 16 s2)
+
+#if __GLASGOW_HASKELL__ < 707
+-- Only use this if we're smaller than GHC 7.7, otherwise
+-- GHC.Fingerprint exports a better version of this function.
+
+-- | Computes the hash of a given file.
+-- It loads the full file into memory an does not work with files bigger than
+-- MAXINT.
+getFileHash :: FilePath -> IO Fingerprint
+getFileHash path = withBinaryFile path ReadMode $ \h -> do
+
+ fileSize <- toIntFileSize `fmap` hFileSize h
+
+ allocaBytes fileSize $ \bufPtr -> do
+ n <- hGetBuf h bufPtr fileSize
+ when (n /= fileSize) readFailedError
+ fingerprintData bufPtr fileSize
+
+ where
+ toIntFileSize :: Integer -> Int
+ toIntFileSize size
+ | size > fromIntegral (maxBound :: Int) = throwGhcException $
+ Sorry $ "Fingerprint.getFileHash: Tried to calculate hash of file "
+ ++ path ++ " with size > maxBound :: Int. This is not supported."
+ | otherwise = fromIntegral size
+
+ readFailedError = throwGhcException $
+ Panic $ "Fingerprint.getFileHash: hGetBuf failed on interface file"
+#endif
diff --git a/compiler/vectorise/Vectorise/Builtins/Base.hs b/compiler/vectorise/Vectorise/Builtins/Base.hs
index 4f07e6f8da..bcd85cb100 100644
--- a/compiler/vectorise/Vectorise/Builtins/Base.hs
+++ b/compiler/vectorise/Vectorise/Builtins/Base.hs
@@ -194,7 +194,7 @@ indexBuiltin fn f i bi
text "' is not yet implemented."
, text "This function does not appear in your source program, but it is needed"
, text "to compile your code in the backend. This is a known, current limitation"
- , text "of DPH. If you want it to to work you should send mail to cvs-ghc@haskell.org"
+ , text "of DPH. If you want it to work, you should send mail to ghc-commits@haskell.org"
, text "and ask what you can do to help (it might involve some GHC hacking)."])
where xs = f bi
@@ -213,5 +213,5 @@ lookupEnvBuiltin fn env n
text "' is not yet implemented."
, text "This function does not appear in your source program, but it is needed"
, text "to compile your code in the backend. This is a known, current limitation"
- , text "of DPH. If you want it to to work you should send mail to cvs-ghc@haskell.org"
+ , text "of DPH. If you want it to work, you should send mail to ghc-commits@haskell.org"
, text "and ask what you can do to help (it might involve some GHC hacking)."])
diff --git a/docs/storage-mgt/rp.tex b/docs/storage-mgt/rp.tex
index d6f04520fb..20e313ba43 100644
--- a/docs/storage-mgt/rp.tex
+++ b/docs/storage-mgt/rp.tex
@@ -255,7 +255,7 @@ of certain types of closures and their layout.
When building the runtime system, the @gcc@ compiler correctly figures out
the size of every structure on its own.
However,
-GHC simply reads @includes/Constants.h@ to to determine the size of
+GHC simply reads @includes/Constants.h@ to determine the size of
closures assumed by the runtime system.
Thus, we must change the constants used by the GHC itself (as opposed to
the runtime system). They are all found in @includes/Constants.h@.
diff --git a/docs/users_guide/7.8.1-notes.xml b/docs/users_guide/7.8.1-notes.xml
index 5d8f077d41..85d2f61053 100644
--- a/docs/users_guide/7.8.1-notes.xml
+++ b/docs/users_guide/7.8.1-notes.xml
@@ -93,10 +93,10 @@
<listitem>
<para>
- The LLVM backend now supports 128bit SIMD operations. This is
- now exploited in both the <literal>vector</literal> and
- <literal>dph</literal> packages, exposing a high level
- interface.
+ The LLVM backend now supports 128bit SIMD
+ operations. This is now exploited in both the
+ <literal>vector</literal> and <literal>dph</literal>
+ packages, exposing a high level interface.
TODO FIXME: reference.
</para>
@@ -121,17 +121,27 @@
<listitem>
<para>
+ GHC now has substantially better support for cross
+ compilation. In particular, GHC now has all the
+ necessary patches to support cross compilation to
+ Apple iOS, using the LLVM backend.
+
+ TODO FIXME: reference.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
PrimOps for comparing unboxed values now return
<literal>Int#</literal> instead of <literal>Bool</literal>.
New PrimOps' names end with <literal>$#</literal> for operators and
<literal>I#</literal> for ordinary names, e.g. <literal>==$#</literal>
compares <literal>Int#</literal>s for equality and
<literal>eqCharI#</literal> does the same for <literal>Char#</literal>s.
- Old PrimOps have been removed and turned into wrappers. If your
- code relied on removed PrimOps then importing
- <literal>GHC.PrimWrappers</literal> will make it work again (no
- need to add anything if your code already imports
- <literal>GHC.Exts</literal>).
+ Old PrimOps have been removed and turned into wrappers. See
+ <ulink url="http://ghc.haskell.org/trac/ghc/wiki/NewPrimopsInGHC7.8">
+ this GHC wiki page</ulink> for instructions how to update your
+ existing code.
</para>
</listitem>
@@ -161,11 +171,55 @@
<literal>NullaryTypeClasses</literal>, which
allows you to declare a type class without any
parameters.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ There is a new extension,
+ <literal>NumDecimals</literal>, which allows you
+ to specify an integer using compact "floating
+ literal" syntax. This lets you say things like
+ <literal>1.2e6 :: Integer</literal> instead of
+ <literal>1200000</literal>
+ </para>
+ </listitem>
+ </itemizedlist>
- TODO FIXME: example?
+ <itemizedlist>
+ <listitem>
+ <para>
+ There is a new extension,
+ <literal>NegativeLiterals</literal>, which will
+ cause GHC to interpret the expression
+ <literal>-123</literal> as <literal>fromIntegral
+ (-123)</literal>. Haskell 98 and Haskell 2010 both
+ specify that it should instead desugar to
+ <literal>negate (fromIntegral 123)</literal>
</para>
</listitem>
</itemizedlist>
+
+ <itemizedlist>
+ <listitem>
+ <para>
+ The <literal>IncoherentInstances</literal>
+ extension has seen a behavioral change, and is
+ now 'liberated' and less conservative during
+ instance resolution. This allows more programs to
+ compile than before.
+ </para>
+ <para>
+ Now, <literal>IncoherentInstances</literal> will
+ always pick an arbitrary matching instance, if
+ multiple ones exist.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+
</sect3>
<sect3>
@@ -173,12 +227,38 @@
<itemizedlist>
<listitem>
<para>
+ GHC can now build both static and dynamic object
+ files at the same time in a single compilation
+ pass, when given the
+ <literal>-dynamic-too</literal> flag. This will
+ produce both a statically-linkable
+ <literal>.o</literal> object file, and a
+ dynamically-linkable <literal>.dyn_o</literal>
+ file. The output suffix of the dynamic objects can
+ be controlled by the flag
+ <literal>-dynosuf</literal>.
+ </para>
+
+ <para>
+ Note that GHC still builds statically by default.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
GHC now supports a <literal>--show-options</literal> flag,
which will dump all of the flags it supports to standard out.
</para>
</listitem>
<listitem>
<para>
+ GHC now supports warning about overflow of integer
+ literals, enabled by
+ <literal>-fwarn-overflowed-literals</literal>. It
+ is enabled by default
+ </para>
+ </listitem>
+ <listitem>
+ <para>
It's now possible to switch the system linker on Linux
(between GNU gold and GNU ld) at runtime without problem.
</para>
@@ -212,6 +292,13 @@
TODO FIXME: reference.
</para>
</listitem>
+ <listitem>
+ <para>
+ The new <literal>:shows paths</literal> command
+ shows the current working directory and the
+ current search path for Haskell modules.
+ </para>
+ </listitem>
</itemizedlist>
</sect3>
@@ -231,6 +318,23 @@
<itemizedlist>
<listitem>
<para>
+ The RTS linker can now unload object code at
+ runtime (when using the GHC API
+ <literal>ObjLink</literal> module.) Previously,
+ GHC would not unload the old object file, causing
+ a gradual memory leak as more objects were loaded
+ over time.
+ </para>
+
+ <para>
+ Note that this change in unloading behavior
+ <emphasis>only</emphasis> affects statically
+ linked binaries, and not dynamic ones.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
The performance of <literal>StablePtr</literal>s and
<literal>StableName</literal>s has been improved.
</para>
diff --git a/docs/users_guide/flags.xml b/docs/users_guide/flags.xml
index ba4b0b13b0..648180c184 100644
--- a/docs/users_guide/flags.xml
+++ b/docs/users_guide/flags.xml
@@ -796,6 +796,12 @@
<entry><option>-XNoNegativeLiterals</option></entry>
</row>
<row>
+ <entry><option>-XNumDecimals</option></entry>
+ <entry>Enable support for 'fractional' integer literals</entry>
+ <entry>dynamic</entry>
+ <entry><option>-XNoNumDecimals</option></entry>
+ </row>
+ <row>
<entry><option>-XNoTraditionalRecordSyntax</option></entry>
<entry>Disable support for traditional record syntax (as supported by Haskell 98) <literal>C {f = x}</literal></entry>
<entry>dynamic</entry>
@@ -1495,7 +1501,7 @@
<sect2>
<title>Optimisation levels</title>
- <para><xref linkend="options-optimise"/></para>
+ <para>These options are described in more detail in <xref linkend="options-optimise"/></para>
<informaltable>
<tgroup cols="4" align="left" colsep="1" rowsep="1">
@@ -1525,10 +1531,10 @@
</informaltable>
</sect2>
- <sect2>
+ <sect2 id="options-f-compact">
<title>Individual optimisations</title>
- <para><xref linkend="options-f"/></para>
+ <para>These options are described in more detail in <xref linkend="options-f"/>.</para>
<informaltable>
<tgroup cols="4" align="left" colsep="1" rowsep="1">
@@ -1552,7 +1558,7 @@
<entry><option>-fcse</option></entry>
<entry>Turn on common sub-expression elimination. Implied by <option>-O</option>.</entry>
<entry>dynamic</entry>
- <entry>-fno-cse</entry>
+ <entry><option>-fno-cse</option></entry>
</row>
<row>
@@ -1628,14 +1634,14 @@
<entry><option>-ffloat-in</option></entry>
<entry>Turn on the float-in transformation. Implied by <option>-O</option>.</entry>
<entry>dynamic</entry>
- <entry>-fno-float-in</entry>
+ <entry><option>-fno-float-in</option></entry>
</row>
<row>
<entry><option>-ffull-laziness</option></entry>
<entry>Turn on full laziness (floating bindings outwards). Implied by <option>-O</option>.</entry>
<entry>dynamic</entry>
- <entry>-fno-full-laziness</entry>
+ <entry><option>-fno-full-laziness</option></entry>
</row>
<row>
@@ -1667,14 +1673,21 @@
</row>
<row>
- <entry><option>-fmax-simplifier-iterations</option></entry>
+ <entry><option>-fmax-relevant-bindings=N</option></entry>
+ <entry>Set the maximum number of bindings to display in type error messages (default 6).</entry>
+ <entry>dynamic</entry>
+ <entry><option>-fno-max-relevant-bindings</option></entry>
+ </row>
+
+ <row>
+ <entry><option>-fmax-simplifier-iterations=N</option></entry>
<entry>Set the max iterations for the simplifier</entry>
<entry>dynamic</entry>
<entry>-</entry>
</row>
<row>
- <entry><option>-fmax-worker-args</option></entry>
+ <entry><option>-fmax-worker-args=N</option></entry>
<entry>If a worker has that many arguments, none will be
unpacked anymore (default: 10)</entry>
<entry>dynamic</entry>
@@ -1738,7 +1751,7 @@
<entry><option>-fspec-constr</option></entry>
<entry>Turn on the SpecConstr transformation. Implied by <option>-O2</option>.</entry>
<entry>dynamic</entry>
- <entry>-fno-spec-constr</entry>
+ <entry><option>-fno-spec-constr</option></entry>
</row>
<row>
@@ -1761,14 +1774,14 @@
<entry><option>-fspecialise</option></entry>
<entry>Turn on specialisation of overloaded functions. Implied by <option>-O</option>.</entry>
<entry>dynamic</entry>
- <entry>-fno-specialise</entry>
+ <entry><option>-fno-specialise</option></entry>
</row>
<row>
<entry><option>-fstrictness</option></entry>
<entry>Turn on strictness analysis. Implied by <option>-O</option>.</entry>
<entry>dynamic</entry>
- <entry>-fno-strictness</entry>
+ <entry><option>-fno-strictness</option></entry>
</row>
<row>
@@ -1783,7 +1796,7 @@
<entry><option>-fstatic-argument-transformation</option></entry>
<entry>Turn on the static argument transformation. Implied by <option>-O2</option>.</entry>
<entry>dynamic</entry>
- <entry>-fno-static-argument-transformation</entry>
+ <entry><option>-fno-static-argument-transformation</option></entry>
</row>
<row>
@@ -2085,6 +2098,15 @@
<entry>-</entry>
</row>
<row>
+ <entry><option>-staticlib</option></entry>
+ <entry>On Darwin/OS X/iOS only, generate a standalone static library
+ (as opposed to an executable).
+ This is the usual way to compile for iOS.
+ </entry>
+ <entry>dynamic</entry>
+ <entry>-</entry>
+ </row>
+ <row>
<entry><option>-fPIC</option></entry>
<entry>Generate position-independent code (where available)</entry>
<entry>dynamic</entry>
@@ -2097,6 +2119,24 @@
<entry>-</entry>
</row>
<row>
+ <entry><option>-dynamic-too</option></entry>
+ <entry>Build dynamic object files <emphasis>as well as</emphasis> static object files during compilation</entry>
+ <entry>static</entry>
+ <entry>-</entry>
+ </row>
+ <row>
+ <entry><option>-dyno</option></entry>
+ <entry>Set the output path for the <emphasis>dynamically</emphasis> linked objects</entry>
+ <entry>static</entry>
+ <entry>-</entry>
+ </row>
+ <row>
+ <entry><option>-dynosuf</option></entry>
+ <entry>Set the output suffix for dynamic object files</entry>
+ <entry>static</entry>
+ <entry>-</entry>
+ </row>
+ <row>
<entry><option>-dynload</option></entry>
<entry>Selects one of a number of modes for finding shared
libraries at runtime.</entry>
@@ -2105,14 +2145,14 @@
</row>
<row>
<entry><option>-framework</option> <replaceable>name</replaceable></entry>
- <entry>On Darwin/MacOS X only, link in the framework <replaceable>name</replaceable>.
+ <entry>On Darwin/OS X/iOS only, link in the framework <replaceable>name</replaceable>.
This option corresponds to the <option>-framework</option> option for Apple's Linker.</entry>
<entry>dynamic</entry>
<entry>-</entry>
</row>
<row>
<entry><option>-framework-path</option> <replaceable>name</replaceable></entry>
- <entry>On Darwin/MacOS X only, add <replaceable>dir</replaceable> to the list of
+ <entry>On Darwin/OS X/iOS only, add <replaceable>dir</replaceable> to the list of
directories searched for frameworks.
This option corresponds to the <option>-F</option> option for Apple's Linker.</entry>
<entry>dynamic</entry>
@@ -2223,7 +2263,7 @@
<entry>Set the install name (via <literal>-install_name</literal> passed to Apple's
linker), specifying the full install path of the library file. Any libraries
or executables that link with it later will pick up that path as their
- runtime search location for it. (Darwin/MacOS X only)</entry>
+ runtime search location for it. (Darwin/OS X only)</entry>
<entry>dynamic</entry>
<entry>-</entry>
</row>
@@ -2351,6 +2391,13 @@
<entry>dynamic</entry>
<entry>-</entry>
</row>
+ <row>
+ <entry><option>-pgmlibtool</option> <replaceable>cmd</replaceable></entry>
+ <entry>Use <replaceable>cmd</replaceable> as the command for libtool
+ (with <option>-staticlib</option> only).</entry>
+ <entry>dynamic</entry>
+ <entry>-</entry>
+ </row>
</tbody>
</tgroup>
</informaltable>
diff --git a/docs/users_guide/ghci.xml b/docs/users_guide/ghci.xml
index df483e81f3..7792da21e9 100644
--- a/docs/users_guide/ghci.xml
+++ b/docs/users_guide/ghci.xml
@@ -2154,7 +2154,9 @@ maybe :: b -> (a -> b) -> Maybe a -> b
&lsquo;<literal>&tilde;</literal>&rsquo; symbol at the
beginning of <replaceable>dir</replaceable> will be replaced
by the contents of the environment variable
- <literal>HOME</literal>.</para>
+ <literal>HOME</literal>.
+ See also the <literal>:show paths</literal> command for
+ showing the current working directory.</para>
<para>NOTE: changing directories causes all currently loaded
modules to be unloaded. This is because the search path is
@@ -2922,6 +2924,19 @@ bar
</varlistentry>
<varlistentry>
+ <term>
+ <literal>:show paths</literal>
+ <indexterm><primary><literal>:show paths</literal></primary></indexterm>
+ </term>
+ <listitem>
+ <para>Show the current working directory (as set via
+ <literal>:cd</literal> command), as well as the list of
+ directories searched for source files (as set by the
+ <option>-i</option> option).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>
<literal>:show language</literal>
<indexterm><primary><literal>:show language</literal></primary></indexterm>
diff --git a/docs/users_guide/glasgow_exts.xml b/docs/users_guide/glasgow_exts.xml
index 0b16156595..46e4cbdb01 100644
--- a/docs/users_guide/glasgow_exts.xml
+++ b/docs/users_guide/glasgow_exts.xml
@@ -446,15 +446,37 @@ Indeed, the bindings can even be recursive.
The literal <literal>-123</literal> is, according to
Haskell98 and Haskell 2010, desugared as
<literal>negate (fromInteger 123)</literal>.
+ The language extension <option>-XNegativeLiterals</option>
+ means that it is instead desugared as
+ <literal>fromInteger (-123)</literal>.
</para>
<para>
- The language extension <option>-XNegativeLiterals</option>
- means that it is instead desugared as
- <literal>fromInteger (-123)</literal>.
+ 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 <literal>negate (fromInteger 128)</literal> will elicit an
+ unexpected integer-literal-overflow message.
</para>
</sect2>
+ <sect2 id="num-decimals">
+ <title>Fractional looking integer literals</title>
+ <para>
+ Haskell 2010 and Haskell 98 define floating literals with
+ the syntax <literal>1.2e6</literal>. These literals have the
+ type <literal>Fractional a => Fractional</literal>.
+ </para>
+
+ <para>
+ The language extension <option>-XNumLiterals</option> allows
+ you to also use the floating literal syntax for instances of
+ <literal>Integral</literal>, and have values like
+ <literal>(1.2e6 :: Num a => a)</literal>
+ </para>
+ </sect2>
+
+
<!-- ====================== HIERARCHICAL MODULES ======================= -->
@@ -4483,21 +4505,33 @@ and <option>-XIncoherentInstances</option>
<indexterm><primary>-XIncoherentInstances
</primary></indexterm>, as this section discusses. Both these
flags are dynamic flags, and can be set on a per-module basis, using
-an <literal>OPTIONS_GHC</literal> pragma if desired (<xref linkend="source-file-options"/>).</para>
+an <literal>LANGUAGE</literal> pragma if desired (<xref linkend="language-pragma"/>).</para>
<para>
The <option>-XOverlappingInstances</option> flag instructs GHC to loosen
the instance resolution described in <xref linkend="instance-resolution"/>, by
-allowing more than one instance to match, <emphasis>provided there is a most specific one</emphasis>.
+allowing more than one instance to match, <emphasis>provided there is a most
+specific one</emphasis>. The <option>-XIncoherentInstances</option> flag
+further loosens the resolution, by allowing more than one instance to match,
+irespective of whether there is a most specific one.
+</para>
+
+<para>
For example, consider
<programlisting>
- instance context1 => C Int a where ... -- (A)
+ instance context1 => C Int b where ... -- (A)
instance context2 => C a Bool where ... -- (B)
- instance context3 => C Int [a] where ... -- (C)
+ instance context3 => C a [b] where ... -- (C)
instance context4 => C Int [Int] where ... -- (D)
</programlisting>
-The constraint <literal>C Int [Int]</literal> matches instances (A),
-(C) and (D), but the last is more specific, and hence is chosen. If there is no
-most-specific match, the program is rejected.
+compiled with <option>-XOverlappingInstances</option> enabled. The constraint
+<literal>C Int [Int]</literal> matches instances (A), (C) and (D), but the last
+is more specific, and hence is chosen.
+</para>
+<para>If (D) did not exist then (A) and (C) would still be matched, but neither is
+most specific. In that case, the program would be rejected even with
+<option>-XOverlappingInstances</option>. With
+<option>-XIncoherentInstances</option> enabled, it would be accepted and (A) or
+(C) would be chosen arbitrarily.
</para>
<para>
An instance declaration is <emphasis>more specific</emphasis> than another iff
@@ -4512,15 +4546,15 @@ However, GHC is conservative about committing to an overlapping instance. For e
f x = ...
</programlisting>
Suppose that from the RHS of <literal>f</literal> we get the constraint
-<literal>C Int [b]</literal>. But
+<literal>C b [b]</literal>. But
GHC does not commit to instance (C), because in a particular
call of <literal>f</literal>, <literal>b</literal> might be instantiate
to <literal>Int</literal>, in which case instance (D) would be more specific still.
So GHC rejects the program.</para>
<para>
-If, however, you add the flag <option>-XIncoherentInstances</option>,
-GHC will instead pick (C), without complaining about
-the problem of subsequent instantiations.
+If, however, you add the flag <option>-XIncoherentInstances</option> when
+compiling the module that contians (D), GHC will instead pick (C), without
+complaining about the problem of subsequent instantiations.
</para>
<para>
Notice that we gave a type signature to <literal>f</literal>, so GHC had to
@@ -4530,7 +4564,7 @@ it instead. In this case, GHC will refrain from
simplifying the constraint <literal>C Int [b]</literal> (for the same reason
as before) but, rather than rejecting the program, it will infer the type
<programlisting>
- f :: C Int [b] => [b] -> [b]
+ f :: C b [b] => [b] -> [b]
</programlisting>
That postpones the question of which instance to pick to the
call site for <literal>f</literal>
@@ -4628,6 +4662,10 @@ some other constraint. But if the instance declaration was compiled with
<option>-XIncoherentInstances</option>, GHC will skip the "does-it-unify?"
check for that declaration.
</para></listitem>
+<listitem><para>
+If two instance declarations are matched and either is compiled with
+<option>-XIncoherentInstances</option>, then that declaration is ignored.
+</para></listitem>
</itemizedlist>
These rules make it possible for a library author to design a library that relies on
overlapping instances without the library client having to know.
diff --git a/docs/users_guide/phases.xml b/docs/users_guide/phases.xml
index 90489e84d2..acb53a73d9 100644
--- a/docs/users_guide/phases.xml
+++ b/docs/users_guide/phases.xml
@@ -137,6 +137,17 @@
linkend="options-linker" />.</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>-pgmlibtool</option> <replaceable>cmd</replaceable>
+ <indexterm><primary><option>-pgmlibtool</option></primary></indexterm>
+ </term>
+ <listitem>
+ <para>Use <replaceable>cmd</replaceable> as the libtool command
+ (when using <option>-staticlib</option> only).</para>
+ </listitem>
+ </varlistentry>
</variablelist>
</sect2>
@@ -721,7 +732,7 @@ $ cat foo.hspp</screen>
<indexterm><primary><option>-framework</option></primary></indexterm>
</term>
<listitem>
- <para>On Darwin/MacOS X only, link in the framework <replaceable>name</replaceable>.
+ <para>On Darwin/OS X/iOS only, link in the framework <replaceable>name</replaceable>.
This option corresponds to the <option>-framework</option> option for Apple's Linker.
Please note that frameworks and packages are two different things - frameworks don't
contain any haskell code. Rather, they are Apple's way of packaging shared libraries.
@@ -733,6 +744,21 @@ $ cat foo.hspp</screen>
<varlistentry>
<term>
+ <option>-staticlib</option>
+ <indexterm><primary><option>-staticlib</option></primary></indexterm>
+ </term>
+ <listitem>
+ <para>On Darwin/OS X/iOS only, link all passed files into a static library suitable
+ for linking into an iOS (when using a cross-compiler) or Mac Xcode project. To control
+ the name, use the <option>-o</option> <replaceable>name</replaceable> option as usual.
+ The default name is <literal>liba.a</literal>.
+ This should nearly always be passed when compiling for iOS with a cross-compiler.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
<option>-L</option><replaceable>dir</replaceable>
<indexterm><primary><option>-L</option></primary></indexterm>
</term>
@@ -749,7 +775,7 @@ $ cat foo.hspp</screen>
<indexterm><primary><option>-framework-path</option></primary></indexterm>
</term>
<listitem>
- <para>On Darwin/MacOS X only, prepend the directory <replaceable>dir</replaceable> to
+ <para>On Darwin/OS X/iOS only, prepend the directory <replaceable>dir</replaceable> to
the framework directories path. This option corresponds to the <option>-F</option>
option for Apple's Linker (<option>-F</option> already means something else for GHC).</para>
</listitem>
@@ -1189,7 +1215,7 @@ $ cat foo.hspp</screen>
</indexterm>
</term>
<listitem>
- <para>On Darwin/MacOS X, dynamic libraries are stamped at build time with an
+ <para>On Darwin/OS X, dynamic libraries are stamped at build time with an
"install name", which is the ultimate install path of the library file.
Any libraries or executables that subsequently link against it will pick
up that path as their runtime search location for it. By default, ghc sets
diff --git a/docs/users_guide/separate_compilation.xml b/docs/users_guide/separate_compilation.xml
index 84f6684307..2f8b9d6f33 100644
--- a/docs/users_guide/separate_compilation.xml
+++ b/docs/users_guide/separate_compilation.xml
@@ -600,23 +600,30 @@ $ ghc -c parse/Foo.hs parse/Bar.hs gurgle/Bumble.hs -odir `uname -m`
</listitem>
</varlistentry>
- <varlistentry>
- <term>
+ <varlistentry>
+ <term>
<option>-ddump-minimal-imports</option>
<indexterm><primary><option>-ddump-minimal-imports</option></primary></indexterm>
</term>
- <listitem>
- <para>Dump to the file "M.imports" (where M is the module
- being compiled) a "minimal" set of import declarations.
- You can safely replace all the import declarations in
- "M.hs" with those found in "M.imports". Why would you
- want to do that? Because the "minimal" imports (a) import
- everything explicitly, by name, and (b) import nothing
- that is not required. It can be quite painful to maintain
- this property by hand, so this flag is intended to reduce
- the labour.</para>
- </listitem>
- </varlistentry>
+ <listitem>
+ <para>Dump to the file
+ <filename><replaceable>M</replaceable>.imports</filename>
+ (where <replaceable>M</replaceable> is the name of the
+ module being compiled) a "minimal" set of import
+ declarations. The directory where the
+ <filename>.imports</filename> files are created can be
+ controlled via the <option>-dumpdir</option>
+ option.</para> <para>You can safely replace all the import
+ declarations in
+ <filename><replaceable>M</replaceable>.hs</filename> with
+ those found in its respective <filename>.imports</filename>
+ file. Why would you want to do that? Because the
+ "minimal" imports (a) import everything explicitly, by
+ name, and (b) import nothing that is not required. It can
+ be quite painful to maintain this property by hand, so
+ this flag is intended to reduce the labour.</para>
+ </listitem>
+ </varlistentry>
<varlistentry>
<term>
diff --git a/docs/users_guide/using.xml b/docs/users_guide/using.xml
index 7540279504..4440eec7dd 100644
--- a/docs/users_guide/using.xml
+++ b/docs/users_guide/using.xml
@@ -1885,12 +1885,59 @@ f "2" = 2
them explicitly (indeed, doing so could lead to unexpected
results). A flag <option>-fwombat</option> can be negated by
saying <option>-fno-wombat</option>. The flags below are off
- by default, except where noted below.
+ by default, except where noted below. See <xref linkend="options-f-compact"/>
+ for a compact list.
</para>
<variablelist>
<varlistentry>
<term>
+ <option>-favoid-vect</option>
+ <indexterm><primary><option></option></primary></indexterm>
+ </term>
+ <listitem>
+ <para>Part of <link linkend="dph">Data Parallel Haskell
+ (DPH)</link>.</para>
+
+ <para><emphasis>Off by default.</emphasis> Enable the
+ <emphasis>vectorisation</emphasis> avoidance optimisation. This
+ optimisation only works when used in combination with the
+ <option>-fvectorise</option> transformation.</para>
+
+ <para>While vectorisation of code using DPH is often a big win, it
+ can also produce worse results for some kinds of code. This
+ optimisation modifies the vectorisation transformation to try to
+ determine if a function would be better of unvectorised and if
+ so, do just that.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>-fcase-merge</option>
+ <indexterm><primary><option></option></primary></indexterm>
+ </term>
+ <listitem>
+ <para><emphasis>On by default.</emphasis>
+ Merge immediately-nested case expressions that scrutinse the same variable. Example
+<programlisting>
+ case x of
+ Red -> e1
+ _ -> case x of
+ Blue -> e2
+ Green -> e3
+==>
+ case x of
+ Red -> e1
+ Blue -> e2
+ Green -> e2
+</programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
<option>-fcse</option>
<indexterm><primary><option>-fcse</option></primary></indexterm>
</term>
@@ -1904,170 +1951,88 @@ f "2" = 2
<varlistentry>
<term>
- <option>-fstrictness</option>
+ <option>-fdicts-cheap</option>
<indexterm><primary><option></option></primary></indexterm>
</term>
<listitem>
- <para> <emphasis>On by default.</emphasis>.
- Switch on the strictness analyser. There is a very old paper about GHC's
- strictness analyser, <ulink url="http://research.microsoft.com/en-us/um/people/simonpj/papers/simple-strictnes-analyser.ps.gz">
- Measuring the effectiveness of a simple strictness analyser</ulink>,
- but the current one is quite a bit different.
- </para>
-
- <para>The strictness analyser figures out when arguments and
- variables in a function can be treated 'strictly' (that is they
- are always evaluated in the function at some point). This allow
- GHC to apply certain optimisations such as unboxing that
- otherwise don't apply as they change the semantics of the program
- when applied to lazy arguments.
+ <para>A very experimental flag that makes dictionary-valued
+ expressions seem cheap to the optimiser.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
- <option>-funbox-strict-fields</option>:
- <indexterm><primary><option>-funbox-strict-fields</option></primary></indexterm>
- <indexterm><primary>strict constructor fields</primary></indexterm>
- <indexterm><primary>constructor fields, strict</primary></indexterm>
+ <option>-fdo-lambda-eta-expansion</option>
+ <indexterm><primary><option></option></primary></indexterm>
</term>
<listitem>
- <para>This option causes all constructor fields which are marked
- strict (i.e. &ldquo;!&rdquo;) to be unpacked if possible. It is
- equivalent to adding an <literal>UNPACK</literal> pragma to every
- strict constructor field (see <xref linkend="unpack-pragma"/>).
+ <para><emphasis>On by default.</emphasis>
+ Eta-expand let-bindings to increase their arity.
</para>
-
- <para>This option is a bit of a sledgehammer: it might sometimes
- make things worse. Selectively unboxing fields by using
- <literal>UNPACK</literal> pragmas might be better. An alternative
- is to use <option>-funbox-strict-fields</option> to turn on
- unboxing by default but disable it for certain constructor
- fields using the <literal>NOUNPACK</literal> pragma (see
- <xref linkend="nounpack-pragma"/>).</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
- <option>-funbox-small-strict-fields</option>:
- <indexterm><primary><option>-funbox-small-strict-fields</option></primary></indexterm>
- <indexterm><primary>strict constructor fields</primary></indexterm>
- <indexterm><primary>constructor fields, strict</primary></indexterm>
+ <option>-fdo-eta-reduction</option>
+ <indexterm><primary><option></option></primary></indexterm>
</term>
<listitem>
- <para><emphasis>On by default.</emphasis>. This option
- causes all constructor fields which are marked strict
- (i.e. &ldquo;!&rdquo;) and which representation is smaller
- or equal to the size of a pointer to be unpacked, if
- possible. It is equivalent to adding an
- <literal>UNPACK</literal> pragma (see <xref
- linkend="unpack-pragma"/>) to every strict constructor
- field that fulfils the size restriction.
- </para>
-
- <para>For example, the constructor fields in the following
- data types
-<programlisting>
-data A = A !Int
-data B = B !A
-newtype C = C B
-data D = D !C
-</programlisting>
- would all be represented by a single
- <literal>Int#</literal> (see <xref linkend="primitives"/>)
- value with
- <option>-funbox-small-strict-fields</option> enabled.
- </para>
-
- <para>This option is less of a sledgehammer than
- <option>-funbox-strict-fields</option>: it should rarely make things
- worse. If you use <option>-funbox-small-strict-fields</option>
- to turn on unboxing by default you can disable it for certain
- constructor fields using the <literal>NOUNPACK</literal> pragma (see
- <xref linkend="nounpack-pragma"/>).</para>
-
- <para>
- Note that for consistency <literal>Double</literal>,
- <literal>Word64</literal>, and <literal>Int64</literal> constructor
- fields are unpacked on 32-bit platforms, even though they are
- technically larger than a pointer on those platforms.
+ <para><emphasis>On by default.</emphasis>
+ Eta-reduce lambda expressions, if doing so gets rid of a whole
+ group of lambdas.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
- <option>-fspec-constr</option>
- <indexterm><primary><option>-fspec-constr</option></primary></indexterm>
+ <option>-feager-blackholing</option>
+ <indexterm><primary><option></option></primary></indexterm>
</term>
<listitem>
- <para><emphasis>Off by default, but enabled by -O2.</emphasis>
- Turn on call-pattern specialisation; see
- <ulink url="http://research.microsoft.com/en-us/um/people/simonpj/papers/spec-constr/index.htm">
- Call-pattern specialisation for Haskell programs</ulink>.
- </para>
-
- <para>This optimisation specializes recursive functions according to
- their argument "shapes". This is best explained by example so
- consider:
-<programlisting>
-last :: [a] -> a
-last [] = error "last"
-last (x : []) = x
-last (x : xs) = last xs
-</programlisting>
- In this code, once we pass the initial check for an empty list we
- know that in the recursive case this pattern match is redundant. As
- such <option>-fspec-constr</option> will transform the above code
- to:
-<programlisting>
-last :: [a] -> a
-last [] = error "last"
-last (x : xs) = last' x xs
- where
- last' x [] = x
- last' x (y : ys) = last' y ys
-</programlisting>
- </para>
-
- <para>As well avoid unnecessary pattern matching it also helps avoid
- unnecessary allocation. This applies when a argument is strict in
- the recursive call to itself but not on the initial entry. As
- strict recursive branch of the function is created similar to the
- above example.
+ <para>Usually GHC black-holes a thunk only when it switches
+ threads. This flag makes it do so as soon as the thunk is
+ entered. See <ulink url="http://research.microsoft.com/en-us/um/people/simonpj/papers/parallel/">
+ Haskell on a shared-memory multiprocessor</ulink>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
- <option>-fspecialise</option>
- <indexterm><primary><option>-fspecialise</option></primary></indexterm>
+ <option>-fexcess-precision</option>
+ <indexterm><primary><option>-fexcess-precision</option></primary></indexterm>
</term>
<listitem>
- <para><emphasis>On by default.</emphasis>
- Specialise each type-class-overloaded function defined in this
- module for the types at which it is called in this module. Also
- specialise imported functions that have an INLINABLE pragma
- (<xref linkend="inlinable-pragma"/>) for the types at which they
- are called in this module.
+ <para>When this option is given, intermediate floating
+ point values can have a <emphasis>greater</emphasis>
+ precision/range than the final type. Generally this is a
+ good thing, but some programs may rely on the exact
+ precision/range of
+ <literal>Float</literal>/<literal>Double</literal> values
+ and should not use this option for their compilation.</para>
+
+ <para>
+ Note that the 32-bit x86 native code generator only
+ supports excess-precision mode, so neither
+ <option>-fexcess-precision</option> nor
+ <option>-fno-excess-precision</option> has any effect.
+ This is a known bug, see <xref linkend="bugs-ghc" />.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
- <option>-fstatic-argument-transformation</option>
- <indexterm><primary><option>-fstatic-argument-transformation</option></primary></indexterm>
+ <option>-fexpose-all-unfoldings</option>
+ <indexterm><primary><option></option></primary></indexterm>
</term>
<listitem>
- <para>Turn on the static argument transformation, which turns a
- recursive function into a non-recursive one with a local
- recursive loop. See Chapter 7 of
- <ulink url="http://research.microsoft.com/en-us/um/people/simonpj/papers/santos-thesis.ps.gz">
- Andre Santos's PhD thesis</ulink>
+ <para>An experimental flag to expose all unfoldings, even for very
+ large or recursive functions. This allows for all functions to be
+ inlined while usually GHC would avoid inlining larger functions.
</para>
</listitem>
</varlistentry>
@@ -2130,50 +2095,45 @@ last (x : xs) = last' x xs
<varlistentry>
<term>
- <option>-fdo-lambda-eta-expansion</option>
- <indexterm><primary><option></option></primary></indexterm>
+ <option>--ffun-to-thunk</option>
+ <indexterm><primary><option>-fignore-asserts</option></primary></indexterm>
</term>
<listitem>
- <para><emphasis>On by default.</emphasis>
- Eta-expand let-bindings to increase their arity.
+ <para>Worker-wrapper removes unused arguments, but usually we
+ do not remove them all, lest it turn a function closure into a thunk,
+ thereby perhaps causing extra allocation (since let-no-escape can't happen)
+ and/or a space leak. This flag
+ allows worker/wrapper to remove <emphasis>all</emphasis> value lambdas.
+ Off by default.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
- <option>-fdo-eta-reduction</option>
- <indexterm><primary><option></option></primary></indexterm>
+ <option>-fignore-asserts</option>
+ <indexterm><primary><option>-fignore-asserts</option></primary></indexterm>
</term>
<listitem>
- <para><emphasis>On by default.</emphasis>
- Eta-reduce lambda expressions, if doing so gets rid of a whole
- group of lambdas.
+ <para>Causes GHC to ignore uses of the function
+ <literal>Exception.assert</literal> in source code (in
+ other words, rewriting <literal>Exception.assert p
+ e</literal> to <literal>e</literal> (see <xref
+ linkend="assertions"/>). This flag is turned on by
+ <option>-O</option>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
- <option>-fcase-merge</option>
- <indexterm><primary><option></option></primary></indexterm>
+ <option>-fignore-interface-pragmas</option>
+ <indexterm><primary><option>-fignore-interface-pragmas</option></primary></indexterm>
</term>
<listitem>
- <para><emphasis>On by default.</emphasis>
- Merge immediately-nested case expressions that scrutinse the same variable. Example
-<programlisting>
- case x of
- Red -> e1
- _ -> case x of
- Blue -> e2
- Green -> e3
-==>
- case x of
- Red -> e1
- Blue -> e2
- Green -> e2
-</programlisting>
- </para>
+ <para>Tells GHC to ignore all inessential information when reading interface files.
+ That is, even if <filename>M.hi</filename> contains unfolding or strictness information
+ for a function, GHC will ignore that information.</para>
</listitem>
</varlistentry>
@@ -2195,26 +2155,25 @@ last (x : xs) = last' x xs
<varlistentry>
<term>
- <option>-fdicts-cheap</option>
- <indexterm><primary><option></option></primary></indexterm>
+ <option>-fliberate-case-threshold=N</option>
+ <indexterm><primary><option>-fliberate-case-threshold</option></primary></indexterm>
</term>
<listitem>
- <para>A very experimental flag that makes dictionary-valued
- expressions seem cheap to the optimiser.
+ <para>Set the size threshold for the liberate-case transformation.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
- <option>-feager-blackholing</option>
- <indexterm><primary><option></option></primary></indexterm>
+ <option>-fmax-relevant-bindings=N</option>
+ <indexterm><primary><option>-fmax-relevant-bindings</option></primary></indexterm>
</term>
<listitem>
- <para>Usually GHC black-holes a thunk only when it switches
- threads. This flag makes it do so as soon as the thunk is
- entered. See <ulink url="http://research.microsoft.com/en-us/um/people/simonpj/papers/parallel/">
- Haskell on a shared-memory multiprocessor</ulink>.
+ <para>The type checker sometimes displays a fragment of the type environment
+ in error messages, but only up to some maximum number, set by this flag.
+ The default is 6. Turning it off with <option>-fno-max-relevant-bindings</option>
+ gives an unlimited number.
</para>
</listitem>
</varlistentry>
@@ -2236,6 +2195,42 @@ last (x : xs) = last' x xs
<varlistentry>
<term>
+ <option>-fomit-interface-pragmas</option>
+ <indexterm><primary><option>-fomit-interface-pragmas</option></primary></indexterm>
+ </term>
+ <listitem>
+ <para>Tells GHC to omit all inessential information from the
+ interface file generated for the module being compiled (say M).
+ This means that a module importing M will see only the
+ <emphasis>types</emphasis> of the functions that M exports, but
+ not their unfoldings, strictness info, etc. Hence, for example,
+ no function exported by M will be inlined into an importing module.
+ The benefit is that modules that import M will need to be
+ recompiled less often (only when M's exports change their type, not
+ when they change their implementation).</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>-fomit-yields</option>
+ <indexterm><primary><option>-fomit-yields</option></primary></indexterm>
+ </term>
+ <listitem>
+ <para><emphasis>On by default.</emphasis> Tells GHC to omit
+ heap checks when no allocation is being performed. While this improves
+ binary sizes by about 5%, it also means that threads run in
+ tight non-allocating loops will not get preempted in a timely
+ fashion. If it is important to always be able to interrupt such
+ threads, you should turn this optimization off. Consider also
+ recompiling all libraries with this optimization turned off, if you
+ need to guarantee interruptibility.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
<option>-fpedantic-bottoms</option>
<indexterm><primary><option>-fpedantic-bottoms</option></primary></indexterm>
</term>
@@ -2251,6 +2246,38 @@ last (x : xs) = last' x xs
<varlistentry>
<term>
+ <option>-fregs-graph</option>
+ <indexterm><primary><option></option></primary></indexterm>
+ </term>
+ <listitem>
+ <para><emphasis>Off by default, but enabled by -O2. Only applies in
+ combination with the native code generator.</emphasis>
+ Use the graph colouring register allocator for register allocation
+ in the native code generator. By default, GHC uses a simpler,
+ faster linear register allocator. The downside being that the
+ linear register allocator usually generates worse code.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>-fregs-iterative</option>
+ <indexterm><primary><option></option></primary></indexterm>
+ </term>
+ <listitem>
+ <para><emphasis>Off by default, only applies in combination with
+ the native code generator.</emphasis>
+ Use the iterative coalescing graph colouring register allocator for
+ register allocation in the native code generator. This is the same
+ register allocator as the <option>-freg-graph</option> one but also
+ enables iterative coalescing during register allocation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
<option>-fsimpl-tick-factor=<replaceable>n</replaceable></option>
<indexterm><primary><option>-fsimpl-tick-factor</option></primary></indexterm>
</term>
@@ -2332,19 +2359,6 @@ last (x : xs) = last' x xs
<varlistentry>
<term>
- <option>-fexpose-all-unfoldings</option>
- <indexterm><primary><option></option></primary></indexterm>
- </term>
- <listitem>
- <para>An experimental flag to expose all unfoldings, even for very
- large or recursive functions. This allows for all functions to be
- inlined while usually GHC would avoid inlining larger functions.
- </para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term>
<option>-fvectorise</option>
<indexterm><primary><option></option></primary></indexterm>
</term>
@@ -2363,142 +2377,170 @@ last (x : xs) = last' x xs
<varlistentry>
<term>
- <option>-favoid-vect</option>
- <indexterm><primary><option></option></primary></indexterm>
+ <option>-fspec-constr</option>
+ <indexterm><primary><option>-fspec-constr</option></primary></indexterm>
</term>
<listitem>
- <para>Part of <link linkend="dph">Data Parallel Haskell
- (DPH)</link>.</para>
+ <para><emphasis>Off by default, but enabled by -O2.</emphasis>
+ Turn on call-pattern specialisation; see
+ <ulink url="http://research.microsoft.com/en-us/um/people/simonpj/papers/spec-constr/index.htm">
+ Call-pattern specialisation for Haskell programs</ulink>.
+ </para>
- <para><emphasis>Off by default.</emphasis> Enable the
- <emphasis>vectorisation</emphasis> avoidance optimisation. This
- optimisation only works when used in combination with the
- <option>-fvectorise</option> transformation.</para>
+ <para>This optimisation specializes recursive functions according to
+ their argument "shapes". This is best explained by example so
+ consider:
+<programlisting>
+last :: [a] -> a
+last [] = error "last"
+last (x : []) = x
+last (x : xs) = last xs
+</programlisting>
+ In this code, once we pass the initial check for an empty list we
+ know that in the recursive case this pattern match is redundant. As
+ such <option>-fspec-constr</option> will transform the above code
+ to:
+<programlisting>
+last :: [a] -> a
+last [] = error "last"
+last (x : xs) = last' x xs
+ where
+ last' x [] = x
+ last' x (y : ys) = last' y ys
+</programlisting>
+ </para>
- <para>While vectorisation of code using DPH is often a big win, it
- can also produce worse results for some kinds of code. This
- optimisation modifies the vectorisation transformation to try to
- determine if a function would be better of unvectorised and if
- so, do just that.</para>
+ <para>As well avoid unnecessary pattern matching it also helps avoid
+ unnecessary allocation. This applies when a argument is strict in
+ the recursive call to itself but not on the initial entry. As
+ strict recursive branch of the function is created similar to the
+ above example.
+ </para>
</listitem>
</varlistentry>
<varlistentry>
<term>
- <option>-fregs-graph</option>
- <indexterm><primary><option></option></primary></indexterm>
+ <option>-fspecialise</option>
+ <indexterm><primary><option>-fspecialise</option></primary></indexterm>
</term>
<listitem>
- <para><emphasis>Off by default, but enabled by -O2. Only applies in
- combination with the native code generator.</emphasis>
- Use the graph colouring register allocator for register allocation
- in the native code generator. By default, GHC uses a simpler,
- faster linear register allocator. The downside being that the
- linear register allocator usually generates worse code.
+ <para><emphasis>On by default.</emphasis>
+ Specialise each type-class-overloaded function defined in this
+ module for the types at which it is called in this module. Also
+ specialise imported functions that have an INLINABLE pragma
+ (<xref linkend="inlinable-pragma"/>) for the types at which they
+ are called in this module.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
- <option>-fregs-iterative</option>
- <indexterm><primary><option></option></primary></indexterm>
+ <option>-fstatic-argument-transformation</option>
+ <indexterm><primary><option>-fstatic-argument-transformation</option></primary></indexterm>
</term>
<listitem>
- <para><emphasis>Off by default, only applies in combination with
- the native code generator.</emphasis>
- Use the iterative coalescing graph colouring register allocator for
- register allocation in the native code generator. This is the same
- register allocator as the <option>-freg-graph</option> one but also
- enables iterative coalescing during register allocation.
+ <para>Turn on the static argument transformation, which turns a
+ recursive function into a non-recursive one with a local
+ recursive loop. See Chapter 7 of
+ <ulink url="http://research.microsoft.com/en-us/um/people/simonpj/papers/santos-thesis.ps.gz">
+ Andre Santos's PhD thesis</ulink>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
- <option>-fexcess-precision</option>
- <indexterm><primary><option>-fexcess-precision</option></primary></indexterm>
+ <option>-fstrictness</option>
+ <indexterm><primary><option></option></primary></indexterm>
</term>
<listitem>
- <para>When this option is given, intermediate floating
- point values can have a <emphasis>greater</emphasis>
- precision/range than the final type. Generally this is a
- good thing, but some programs may rely on the exact
- precision/range of
- <literal>Float</literal>/<literal>Double</literal> values
- and should not use this option for their compilation.</para>
+ <para> <emphasis>On by default.</emphasis>.
+ Switch on the strictness analyser. There is a very old paper about GHC's
+ strictness analyser, <ulink url="http://research.microsoft.com/en-us/um/people/simonpj/papers/simple-strictnes-analyser.ps.gz">
+ Measuring the effectiveness of a simple strictness analyser</ulink>,
+ but the current one is quite a bit different.
+ </para>
- <para>
- Note that the 32-bit x86 native code generator only
- supports excess-precision mode, so neither
- <option>-fexcess-precision</option> nor
- <option>-fno-excess-precision</option> has any effect.
- This is a known bug, see <xref linkend="bugs-ghc" />.
+ <para>The strictness analyser figures out when arguments and
+ variables in a function can be treated 'strictly' (that is they
+ are always evaluated in the function at some point). This allow
+ GHC to apply certain optimisations such as unboxing that
+ otherwise don't apply as they change the semantics of the program
+ when applied to lazy arguments.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
- <option>-fignore-asserts</option>
- <indexterm><primary><option>-fignore-asserts</option></primary></indexterm>
+ <option>-funbox-strict-fields</option>:
+ <indexterm><primary><option>-funbox-strict-fields</option></primary></indexterm>
+ <indexterm><primary>strict constructor fields</primary></indexterm>
+ <indexterm><primary>constructor fields, strict</primary></indexterm>
</term>
<listitem>
- <para>Causes GHC to ignore uses of the function
- <literal>Exception.assert</literal> in source code (in
- other words, rewriting <literal>Exception.assert p
- e</literal> to <literal>e</literal> (see <xref
- linkend="assertions"/>). This flag is turned on by
- <option>-O</option>.
+ <para>This option causes all constructor fields which are marked
+ strict (i.e. &ldquo;!&rdquo;) to be unpacked if possible. It is
+ equivalent to adding an <literal>UNPACK</literal> pragma to every
+ strict constructor field (see <xref linkend="unpack-pragma"/>).
</para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>
- <option>-fignore-interface-pragmas</option>
- <indexterm><primary><option>-fignore-interface-pragmas</option></primary></indexterm>
- </term>
- <listitem>
- <para>Tells GHC to ignore all inessential information when reading interface files.
- That is, even if <filename>M.hi</filename> contains unfolding or strictness information
- for a function, GHC will ignore that information.</para>
+ <para>This option is a bit of a sledgehammer: it might sometimes
+ make things worse. Selectively unboxing fields by using
+ <literal>UNPACK</literal> pragmas might be better. An alternative
+ is to use <option>-funbox-strict-fields</option> to turn on
+ unboxing by default but disable it for certain constructor
+ fields using the <literal>NOUNPACK</literal> pragma (see
+ <xref linkend="nounpack-pragma"/>).</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
- <option>-fomit-interface-pragmas</option>
- <indexterm><primary><option>-fomit-interface-pragmas</option></primary></indexterm>
+ <option>-funbox-small-strict-fields</option>:
+ <indexterm><primary><option>-funbox-small-strict-fields</option></primary></indexterm>
+ <indexterm><primary>strict constructor fields</primary></indexterm>
+ <indexterm><primary>constructor fields, strict</primary></indexterm>
</term>
<listitem>
- <para>Tells GHC to omit all inessential information from the
- interface file generated for the module being compiled (say M).
- This means that a module importing M will see only the
- <emphasis>types</emphasis> of the functions that M exports, but
- not their unfoldings, strictness info, etc. Hence, for example,
- no function exported by M will be inlined into an importing module.
- The benefit is that modules that import M will need to be
- recompiled less often (only when M's exports change their type, not
- when they change their implementation).</para>
- </listitem>
- </varlistentry>
+ <para><emphasis>On by default.</emphasis>. This option
+ causes all constructor fields which are marked strict
+ (i.e. &ldquo;!&rdquo;) and which representation is smaller
+ or equal to the size of a pointer to be unpacked, if
+ possible. It is equivalent to adding an
+ <literal>UNPACK</literal> pragma (see <xref
+ linkend="unpack-pragma"/>) to every strict constructor
+ field that fulfils the size restriction.
+ </para>
- <varlistentry>
- <term>
- <option>-fomit-yields</option>
- <indexterm><primary><option>-fomit-yields</option></primary></indexterm>
- </term>
- <listitem>
- <para><emphasis>On by default.</emphasis> Tells GHC to omit
- heap checks when no allocation is being performed. While this improves
- binary sizes by about 5%, it also means that threads run in
- tight non-allocating loops will not get preempted in a timely
- fashion. If it is important to always be able to interrupt such
- threads, you should turn this optimization off. Consider also
- recompiling all libraries with this optimization turned off, if you
- need to guarantee interruptibility.
+ <para>For example, the constructor fields in the following
+ data types
+<programlisting>
+data A = A !Int
+data B = B !A
+newtype C = C B
+data D = D !C
+</programlisting>
+ would all be represented by a single
+ <literal>Int#</literal> (see <xref linkend="primitives"/>)
+ value with
+ <option>-funbox-small-strict-fields</option> enabled.
+ </para>
+
+ <para>This option is less of a sledgehammer than
+ <option>-funbox-strict-fields</option>: it should rarely make things
+ worse. If you use <option>-funbox-small-strict-fields</option>
+ to turn on unboxing by default you can disable it for certain
+ constructor fields using the <literal>NOUNPACK</literal> pragma (see
+ <xref linkend="nounpack-pragma"/>).</para>
+
+ <para>
+ Note that for consistency <literal>Double</literal>,
+ <literal>Word64</literal>, and <literal>Int64</literal> constructor
+ fields are unpacked on 32-bit platforms, even though they are
+ technically larger than a pointer on those platforms.
</para>
</listitem>
</varlistentry>
diff --git a/ghc/InteractiveUI.hs b/ghc/InteractiveUI.hs
index fd034eaf7d..68380b3c04 100644
--- a/ghc/InteractiveUI.hs
+++ b/ghc/InteractiveUI.hs
@@ -246,7 +246,8 @@ defFullHelpText =
" :info[!] [<name> ...] display information about the given names\n" ++
" (!: do not filter instances)\n" ++
" :issafe [<mod>] display safe haskell information of module <mod>\n" ++
- " :kind <type> show the kind of <type>\n" ++
+ " :kind[!] <type> show the kind of <type>\n" ++
+ " (!: also print the normalised type)\n" ++
" :load [*]<module> ... load module(s) and their dependents\n" ++
" :main [<arguments> ...] run the main function with the given arguments\n" ++
" :module [+/-] [*]<mod> ... set the context for expression evaluation\n" ++
@@ -315,6 +316,7 @@ defFullHelpText =
" :show linker show current linker state\n" ++
" :show modules show the currently loaded modules\n" ++
" :show packages show the currently active package flags\n" ++
+ " :show paths show the currently active search paths\n" ++
" :show language show the currently active language flags\n" ++
" :show <setting> show value of <setting>, which is one of\n" ++
" [args, prog, prompt, editor, stop]\n" ++
@@ -958,7 +960,7 @@ lookupCommand' str' = do
ghci_cmds <- ghci_commands `fmap` getGHCiState
let{ (str, cmds) = case str' of
':' : rest -> (rest, ghci_cmds) -- "::" selects a builtin command
- _ -> (str', ghci_cmds ++ macros) } -- otherwise prefer macros
+ _ -> (str', macros ++ ghci_cmds) } -- otherwise prefer macros
-- look for exact match first, then the first prefix match
return $ case [ c | c <- cmds, str == cmdName c ] of
c:_ -> Just c
@@ -2156,6 +2158,7 @@ showCmd str = do
["breaks"] -> showBkptTable
["context"] -> showContext
["packages"] -> showPackages
+ ["paths"] -> showPaths
["languages"] -> showLanguages -- backwards compat
["language"] -> showLanguages
["lang"] -> showLanguages -- useful abbreviation
@@ -2263,6 +2266,19 @@ showPackages = do
showFlag (TrustPackage p) = text $ " -trust " ++ p
showFlag (DistrustPackage p) = text $ " -distrust " ++ p
+showPaths :: GHCi ()
+showPaths = do
+ dflags <- getDynFlags
+ liftIO $ do
+ cwd <- getCurrentDirectory
+ putStrLn $ showSDoc dflags $
+ text "current working directory: " $$
+ nest 2 (text cwd)
+ let ipaths = importPaths dflags
+ putStrLn $ showSDoc dflags $
+ text ("module import search paths:"++if null ipaths then " none" else "") $$
+ nest 2 (vcat (map text ipaths))
+
showLanguages :: GHCi ()
showLanguages = getDynFlags >>= liftIO . showLanguages' False
@@ -2423,7 +2439,7 @@ completeShowOptions = wrapCompleter flagWordBreakChars $ \w -> do
return (filter (w `isPrefixOf`) opts)
where opts = ["args", "prog", "prompt", "prompt2", "editor", "stop",
"modules", "bindings", "linker", "breaks",
- "context", "packages", "language", "imports"]
+ "context", "packages", "paths", "language", "imports"]
completeShowiOptions = wrapCompleter flagWordBreakChars $ \w -> do
return (filter (w `isPrefixOf`) ["language"])
diff --git a/ghc/ghc-bin.cabal.in b/ghc/ghc-bin.cabal.in
index 36fc9d4e71..4841cb9232 100644
--- a/ghc/ghc-bin.cabal.in
+++ b/ghc/ghc-bin.cabal.in
@@ -50,7 +50,4 @@ Executable ghc
FlexibleInstances,
MagicHash
- Extensions: CPP, PatternGuards
- if impl(ghc >= 7.1)
- Extensions: NondecreasingIndentation
-
+ Extensions: CPP, PatternGuards, NondecreasingIndentation
diff --git a/includes/stg/SMP.h b/includes/stg/SMP.h
index be28911fee..07ea522328 100644
--- a/includes/stg/SMP.h
+++ b/includes/stg/SMP.h
@@ -368,9 +368,12 @@ load_load_barrier(void) {
/* ---------------------------------------------------------------------- */
#else /* !THREADED_RTS */
-#define write_barrier() /* nothing */
-#define store_load_barrier() /* nothing */
-#define load_load_barrier() /* nothing */
+EXTERN_INLINE void write_barrier(void);
+EXTERN_INLINE void store_load_barrier(void);
+EXTERN_INLINE void load_load_barrier(void);
+EXTERN_INLINE void write_barrier () {} /* nothing */
+EXTERN_INLINE void store_load_barrier() {} /* nothing */
+EXTERN_INLINE void load_load_barrier () {} /* nothing */
#if !IN_STG_CODE || IN_STGCRUN
INLINE_HEADER StgWord
diff --git a/libraries/Cabal b/libraries/Cabal
-Subproject 5fa5c41cd9d2c9b4b543312af6919fe3d858865
+Subproject 9f374ab45e62924506b992db9157c970c7259a0
diff --git a/libraries/bin-package-db/Distribution/InstalledPackageInfo/Binary.hs b/libraries/bin-package-db/Distribution/InstalledPackageInfo/Binary.hs
index 476897ef30..27e23d8959 100644
--- a/libraries/bin-package-db/Distribution/InstalledPackageInfo/Binary.hs
+++ b/libraries/bin-package-db/Distribution/InstalledPackageInfo/Binary.hs
@@ -11,7 +11,7 @@
-- Module : Distribution.InstalledPackageInfo.Binary
-- Copyright : (c) The University of Glasgow 2009
--
--- Maintainer : cvs-ghc@haskell.org
+-- Maintainer : ghc-devs@haskell.org
-- Portability : portable
--
@@ -131,7 +131,8 @@ instance Binary License where
put AllRightsReserved = do putWord8 6
put OtherLicense = do putWord8 7
put (Apache v) = do putWord8 8; put v
- put (UnknownLicense str) = do putWord8 9; put str
+ put (AGPL v) = do putWord8 9; put v
+ put (UnknownLicense str) = do putWord8 10; put str
get = do
n <- getWord8
@@ -145,6 +146,7 @@ instance Binary License where
6 -> return AllRightsReserved
7 -> return OtherLicense
8 -> do v <- get; return (Apache v)
+ 9 -> do v <- get; return (AGPL v)
_ -> do str <- get; return (UnknownLicense str)
instance Binary Version where
diff --git a/libraries/bin-package-db/bin-package-db.cabal b/libraries/bin-package-db/bin-package-db.cabal
index 67c7f658db..c308b60052 100644
--- a/libraries/bin-package-db/bin-package-db.cabal
+++ b/libraries/bin-package-db/bin-package-db.cabal
@@ -1,7 +1,7 @@
name: bin-package-db
version: 0.0.0.0
license: BSD3
-maintainer: cvs-ghc@haskell.org
+maintainer: ghc-devs@haskell.org
bug-reports: glasgow-haskell-bugs@haskell.org
synopsis: A binary format for the package database
cabal-version: >=1.6
@@ -18,7 +18,7 @@ Library {
build-depends: base >= 4 && < 5
build-depends: binary >= 0.5 && < 0.8,
- Cabal >= 1.8 && < 1.18
+ Cabal >= 1.18 && < 1.19
extensions: CPP
}
diff --git a/libraries/binary b/libraries/binary
-Subproject 4d890e4465a0494e5fd80fbcf1fb339d8bd5800
+Subproject 2799c25d85b4627200f2e4dcb30d2128488780c
diff --git a/libraries/bytestring b/libraries/bytestring
-Subproject 9692aaf0bf9b203f9249a1414637328fd31fc04
+Subproject 7d5b516ad0937b7cdc29798db33a37a598123b6
diff --git a/libraries/containers b/libraries/containers
-Subproject 41bc140a140143fa517df4c1a08365474cde4d1
+Subproject 154cd539a22e4d82ff56fec2d8ad38855f78513
diff --git a/libraries/haskeline b/libraries/haskeline
-Subproject 40bcd6ac30577d1d240166674d1e328ac52c1fd
+Subproject 495b00b4f125c0b4e7f1e966cd961eae89cffdc
diff --git a/libraries/time b/libraries/time
-Subproject 12ba4321d34d646cf9040ad12810c4257d26ade
+Subproject d4f019b2c6a332be5443b5bf88d0c7fef91523c
diff --git a/mk/config.mk.in b/mk/config.mk.in
index 1129cc2e41..0c2003b680 100644
--- a/mk/config.mk.in
+++ b/mk/config.mk.in
@@ -161,9 +161,9 @@ GhcUnregisterised=@Unregisterised@
#
# Target platforms supported:
# i386, powerpc
-# AIX is not supported
+# IOS and AIX are not supported
ArchSupportsNCG=$(strip $(patsubst $(TargetArch_CPP), YES, $(findstring $(TargetArch_CPP), i386 x86_64 powerpc sparc)))
-OsSupportsNCG=$(strip $(patsubst $(TargetOS_CPP), YES, $(patsubst aix,,$(TargetOS_CPP))))
+OsSupportsNCG=$(strip $(patsubst $(TargetOS_CPP), YES, $(patsubst ios,,$(patsubst aix,,$(TargetOS_CPP)))))
GhcWithNativeCodeGen := $(strip\
$(if $(filter YESYESNO,\
@@ -185,7 +185,7 @@ ArchSupportsGHCi=$(strip $(patsubst $(TargetArch_CPP), YES, $(findstring $(Targe
ifeq "$(OsSupportsGHCi)$(ArchSupportsGHCi)" "YESYES"
GhcWithInterpreter=YES
-else
+else
GhcWithInterpreter=$(if $(findstring YES,$(DYNAMIC_GHC_PROGRAMS)),YES,NO)
endif
@@ -249,7 +249,7 @@ BuildSharedLibs=$(strip $(if $(findstring dyn,$(GhcLibWays)),YES,NO))
# In addition, the RTS is built in some further variations. Ways that
# make sense here:
-#
+#
# thr : threaded
# thr_p : threaded profiled
# debug : debugging (compile with -g for the C compiler, and -DDEBUG)
@@ -262,7 +262,7 @@ BuildSharedLibs=$(strip $(if $(findstring dyn,$(GhcLibWays)),YES,NO))
GhcRTSWays=l
# Usually want the debug version
-GhcRTSWays += debug
+GhcRTSWays += debug
# We always have the threaded versions, but note that SMP support may be disabled
# (see GhcWithSMP).
@@ -391,7 +391,7 @@ BIN_DIST_PREP_TAR_BZ2 = $(BIN_DIST_PREP_TAR).bz2
BIN_DIST_TAR_BZ2 = $(BIN_DIST_NAME)-$(TARGETPLATFORM).tar.bz2
# -----------------------------------------------------------------------------
-# Utilities programs: flags
+# Utilities programs: flags
# If you want to give any standard flags to pretty much any utility
# (see utils.mk for a complete list), by adding a line here
@@ -399,7 +399,7 @@ BIN_DIST_TAR_BZ2 = $(BIN_DIST_NAME)-$(TARGETPLATFORM).tar.bz2
# SRC_P_OPTS += ...
#
# where P is the utility. For example, to add -O to all Haskell
-# compilations,
+# compilations,
#
# SRC_HC_OPTS += -O
@@ -407,7 +407,7 @@ BIN_DIST_TAR_BZ2 = $(BIN_DIST_NAME)-$(TARGETPLATFORM).tar.bz2
# SRC_HC_OPTS includes flags to be added to *every* Haskell
# compilation. Setting SRC_HC_OPTS is a good way to set the default
# optimisation level (-O) and heap size (-H<size>).
-#
+#
# SRC_HC_OPTS is *not* for adding flags that are required to make your
# build work. Examples:
#
@@ -628,7 +628,7 @@ FIND = @FindCmd@
# Sigh - the autoconf macro for INSTALL will subst a relative path to the fallback
# install-sh script (if chosen). This not terribly useful to us, so we convert
# it into an abs. path.
-#
+#
INSTALL = @INSTALL@
INSTALL := $(subst .././install-sh,$(TOP)/install-sh,$(INSTALL))
@@ -664,7 +664,7 @@ LdHasBuildId = @LdHasBuildId@
# and compiler/main/DriverPipeline.hs.
LdHasNoCompactUnwind = @LdHasNoCompactUnwind@
-# On MSYS, building with SplitObjs=YES fails with
+# On MSYS, building with SplitObjs=YES fails with
# ar: Bad file number
# see #3201. We need to specify a smaller max command-line size
# to work around it. 32767 doesn't work; 30000 does, but says
@@ -726,7 +726,7 @@ GHC_PKG = @GhcPkgCmd@
# Happy
#
HAPPY = @HappyCmd@
-HAPPY_VERSION = @HappyVersion@
+HAPPY_VERSION = @HappyVersion@
#
# Options to pass to Happy when we're going to compile the output with GHC
#
@@ -736,7 +736,7 @@ SRC_HAPPY_OPTS = -agc --strict
# Alex
#
ALEX = @AlexCmd@
-ALEX_VERSION = @AlexVersion@
+ALEX_VERSION = @AlexVersion@
Alex3 = @Alex3@
#
# Options to pass to Alex when we're going to compile the output with GHC
@@ -763,7 +763,7 @@ endif
#
################################################################################
-#
+#
# It is possible to configure the compiler and prelude to support 31-bit
# integers, suitable for a back-end and RTS using a tag bit on a 32-bit
# architecture. Currently the only useful output from this option is external Core
diff --git a/rts/CheckUnload.c b/rts/CheckUnload.c
new file mode 100644
index 0000000000..a758b06db3
--- /dev/null
+++ b/rts/CheckUnload.c
@@ -0,0 +1,303 @@
+/* ----------------------------------------------------------------------------
+ *
+ * (c) The GHC Team, 2013-
+ *
+ * Check whether dynamically-loaded object code can be safely
+ * unloaded, by searching for references to it from the heap and RTS
+ * data structures.
+ *
+ * --------------------------------------------------------------------------*/
+
+#include "PosixSource.h"
+#include "Rts.h"
+
+#include "RtsUtils.h"
+#include "Hash.h"
+#include "LinkerInternals.h"
+#include "CheckUnload.h"
+#include "sm/Storage.h"
+#include "sm/GCThread.h"
+
+//
+// Code that we unload may be referenced from:
+// - info pointers in heap objects and stack frames
+// - pointers to static objects from the heap
+// - StablePtrs to static objects
+//
+// We can find live static objects after a major GC, so we don't have
+// to look at every closure pointer in the heap. However, we do have
+// to look at every info pointer. So this is like a heap census
+// traversal: we look at the header of every object, but not its
+// contents.
+//
+// On the assumption that there aren't many different info pointers in
+// a typical heap, we insert addresses into a hash table. The
+// first time we see an address, we check it against the pending
+// unloadable objects and if it lies within any of them, we mark that
+// object as referenced so that it won't get unloaded in this round.
+//
+
+static void checkAddress (HashTable *addrs, void *addr)
+{
+ ObjectCode *oc;
+
+ if (!lookupHashTable(addrs, (W_)addr)) {
+ insertHashTable(addrs, (W_)addr, addr);
+
+ for (oc = unloaded_objects; oc; oc = oc->next) {
+ if ((W_)addr >= (W_)oc->image &&
+ (W_)addr < (W_)oc->image + oc->fileSize) {
+ oc->referenced = 1;
+ break;
+ }
+ }
+ }
+}
+
+static void searchStackChunk (HashTable *addrs, StgPtr sp, StgPtr stack_end)
+{
+ StgPtr p;
+ const StgRetInfoTable *info;
+
+ p = sp;
+ while (p < stack_end) {
+ info = get_ret_itbl((StgClosure *)p);
+
+ switch (info->i.type) {
+ case RET_SMALL:
+ case RET_BIG:
+ checkAddress(addrs, (void*)info);
+ break;
+
+ default:
+ break;
+ }
+
+ p += stack_frame_sizeW((StgClosure*)p);
+ }
+}
+
+
+static void searchHeapBlocks (HashTable *addrs, bdescr *bd)
+{
+ StgPtr p;
+ StgInfoTable *info;
+ nat size;
+ rtsBool prim;
+
+ for (; bd != NULL; bd = bd->link) {
+
+ if (bd->flags & BF_PINNED) {
+ // Assume that objects in PINNED blocks cannot refer to
+ continue;
+ }
+
+ p = bd->start;
+ while (p < bd->free) {
+ info = get_itbl((StgClosure *)p);
+ prim = rtsFalse;
+
+ switch (info->type) {
+
+ case THUNK:
+ size = thunk_sizeW_fromITBL(info);
+ break;
+
+ case THUNK_1_1:
+ case THUNK_0_2:
+ case THUNK_2_0:
+ size = sizeofW(StgThunkHeader) + 2;
+ break;
+
+ case THUNK_1_0:
+ case THUNK_0_1:
+ case THUNK_SELECTOR:
+ size = sizeofW(StgThunkHeader) + 1;
+ break;
+
+ case CONSTR:
+ case FUN:
+ case FUN_1_0:
+ case FUN_0_1:
+ case FUN_1_1:
+ case FUN_0_2:
+ case FUN_2_0:
+ case CONSTR_1_0:
+ case CONSTR_0_1:
+ case CONSTR_1_1:
+ case CONSTR_0_2:
+ case CONSTR_2_0:
+ size = sizeW_fromITBL(info);
+ break;
+
+ case IND_PERM:
+ case BLACKHOLE:
+ case BLOCKING_QUEUE:
+ prim = rtsTrue;
+ size = sizeW_fromITBL(info);
+ break;
+
+ case IND:
+ // Special case/Delicate Hack: INDs don't normally
+ // appear, since we're doing this heap census right
+ // after GC. However, GarbageCollect() also does
+ // resurrectThreads(), which can update some
+ // blackholes when it calls raiseAsync() on the
+ // resurrected threads. So we know that any IND will
+ // be the size of a BLACKHOLE.
+ prim = rtsTrue;
+ size = BLACKHOLE_sizeW();
+ break;
+
+ case BCO:
+ prim = rtsTrue;
+ size = bco_sizeW((StgBCO *)p);
+ break;
+
+ case MVAR_CLEAN:
+ case MVAR_DIRTY:
+ case TVAR:
+ case WEAK:
+ case PRIM:
+ case MUT_PRIM:
+ case MUT_VAR_CLEAN:
+ case MUT_VAR_DIRTY:
+ prim = rtsTrue;
+ size = sizeW_fromITBL(info);
+ break;
+
+ case AP:
+ prim = rtsTrue;
+ size = ap_sizeW((StgAP *)p);
+ break;
+
+ case PAP:
+ prim = rtsTrue;
+ size = pap_sizeW((StgPAP *)p);
+ break;
+
+ case AP_STACK:
+ {
+ StgAP_STACK *ap = (StgAP_STACK *)p;
+ prim = rtsTrue;
+ size = ap_stack_sizeW(ap);
+ searchStackChunk(addrs, (StgPtr)ap->payload,
+ (StgPtr)ap->payload + ap->size);
+ break;
+ }
+
+ case ARR_WORDS:
+ prim = rtsTrue;
+ size = arr_words_sizeW((StgArrWords*)p);
+ break;
+
+ case MUT_ARR_PTRS_CLEAN:
+ case MUT_ARR_PTRS_DIRTY:
+ case MUT_ARR_PTRS_FROZEN:
+ case MUT_ARR_PTRS_FROZEN0:
+ prim = rtsTrue;
+ size = mut_arr_ptrs_sizeW((StgMutArrPtrs *)p);
+ break;
+
+ case TSO:
+ prim = rtsTrue;
+ size = sizeofW(StgTSO);
+ break;
+
+ case STACK: {
+ StgStack *stack = (StgStack*)p;
+ prim = rtsTrue;
+ searchStackChunk(addrs, stack->sp,
+ stack->stack + stack->stack_size);
+ size = stack_sizeW(stack);
+ break;
+ }
+
+ case TREC_CHUNK:
+ prim = rtsTrue;
+ size = sizeofW(StgTRecChunk);
+ break;
+
+ default:
+ barf("heapCensus, unknown object: %d", info->type);
+ }
+
+ if (!prim) {
+ checkAddress(addrs,info);
+ }
+
+ p += size;
+ }
+ }
+}
+
+//
+// Check whether we can unload any object code. This is called at the
+// appropriate point during a GC, where all the heap data is nice and
+// packed together and we have a linked list of the static objects.
+//
+// The check involves a complete heap traversal, but you only pay for
+// this (a) when you have called unloadObj(), and (b) at a major GC,
+// which is much more expensive than the traversal we're doing here.
+//
+void checkUnload (StgClosure *static_objects)
+{
+ nat g, n;
+ HashTable *addrs;
+ StgClosure* p;
+ const StgInfoTable *info;
+ ObjectCode *oc, *prev;
+ gen_workspace *ws;
+ StgClosure* link;
+
+ if (unloaded_objects == NULL) return;
+
+ // Mark every unloadable object as unreferenced initially
+ for (oc = unloaded_objects; oc; oc = oc->next) {
+ IF_DEBUG(linker, debugBelch("Checking whether to unload %s\n",
+ oc->fileName));
+ oc->referenced = rtsFalse;
+ }
+
+ addrs = allocHashTable();
+
+ for (p = static_objects; p != END_OF_STATIC_LIST; p = link) {
+ checkAddress(addrs, p);
+ info = get_itbl(p);
+ link = *STATIC_LINK(info, p);
+ }
+
+ for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
+ searchHeapBlocks (addrs, generations[g].blocks);
+ searchHeapBlocks (addrs, generations[g].large_objects);
+
+ for (n = 0; n < n_capabilities; n++) {
+ ws = &gc_threads[n]->gens[g];
+ searchHeapBlocks(addrs, ws->todo_bd);
+ searchHeapBlocks(addrs, ws->part_list);
+ searchHeapBlocks(addrs, ws->scavd_list);
+ }
+ }
+
+ // Look through the unloadable objects, and any object that is still
+ // marked as unreferenced can be physically unloaded, because we
+ // have no references to it.
+ prev = NULL;
+ for (oc = unloaded_objects; oc; prev = oc, oc = oc->next) {
+ if (oc->referenced == 0) {
+ if (prev == NULL) {
+ unloaded_objects = oc->next;
+ } else {
+ prev->next = oc->next;
+ }
+ IF_DEBUG(linker, debugBelch("Unloading object file %s\n",
+ oc->fileName));
+ freeObjectCode(oc);
+ } else {
+ IF_DEBUG(linker, debugBelch("Object file still in use: %s\n",
+ oc->fileName));
+ }
+ }
+
+ freeHashTable(addrs, NULL);
+}
diff --git a/rts/CheckUnload.h b/rts/CheckUnload.h
new file mode 100644
index 0000000000..7d2e5b1321
--- /dev/null
+++ b/rts/CheckUnload.h
@@ -0,0 +1,20 @@
+/* ----------------------------------------------------------------------------
+ *
+ * (c) The GHC Team, 2013-
+ *
+ * Check whether dynamically-loaded object code can be safely
+ * unloaded, by searching for references to it from the heap and RTS
+ * data structures.
+ *
+ * --------------------------------------------------------------------------*/
+
+#ifndef CHECKUNLOAD_H
+#define CHECKUNLOAD_H
+
+#include "BeginPrivate.h"
+
+void checkUnload (StgClosure *static_objects);
+
+#include "EndPrivate.h"
+
+#endif // CHECKUNLOAD_H
diff --git a/rts/Linker.c b/rts/Linker.c
index 92194dfda8..6490242322 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -137,16 +137,6 @@
#include <sys/tls.h>
#endif
-// Defining this as 'int' rather than 'const int' means that we don't get
-// warnings like
-// error: function might be possible candidate for attribute ‘noreturn’
-// from gcc:
-#ifdef DYNAMIC_GHC_PROGRAMS
-int dynamicGhcPrograms = 1;
-#else
-int dynamicGhcPrograms = 0;
-#endif
-
/* Hash table mapping symbol names to Symbol */
static /*Str*/HashTable *symhash;
@@ -156,6 +146,10 @@ static /*Str*/HashTable *stablehash;
/* List of currently loaded objects */
ObjectCode *objects = NULL; /* initially empty */
+/* List of objects that have been unloaded via unloadObj(), but are waiting
+ to be actually freed via checkUnload() */
+ObjectCode *unloaded_objects = NULL; /* initially empty */
+
static HsInt loadOc( ObjectCode* oc );
static ObjectCode* mkOc( pathchar *path, char *image, int imageSize,
char *archiveMemberName
@@ -229,6 +223,8 @@ static void machoInitSymbolsWithoutUnderscore( void );
#endif
#endif
+static void freeProddableBlocks (ObjectCode *oc);
+
/* on x86_64 we have a problem with relocating symbol references in
* code that was compiled without -fPIC. By default, the small memory
* model is used, which assumes that symbol references can fit in a
@@ -1521,6 +1517,9 @@ initLinker( void )
linker_init_done = 1;
}
+ objects = NULL;
+ unloaded_objects = NULL;
+
#if defined(THREADED_RTS) && (defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO))
initMutex(&dl_mutex);
#endif
@@ -2047,6 +2046,48 @@ mmap_again:
}
#endif // USE_MMAP
+
+void freeObjectCode (ObjectCode *oc)
+{
+#ifdef USE_MMAP
+ int pagesize, size, r;
+
+ pagesize = getpagesize();
+ size = ROUND_UP(oc->fileSize, pagesize);
+
+ r = munmap(oc->image, size);
+ if (r == -1) {
+ sysErrorBelch("munmap");
+ }
+
+#if defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH) || defined(arm_HOST_ARCH)
+#if !defined(x86_64_HOST_ARCH) || !defined(mingw32_HOST_OS)
+ if (!USE_CONTIGUOUS_MMAP)
+ {
+ munmap(oc->symbol_extras,
+ ROUND_UP(sizeof(SymbolExtra) * oc->n_symbol_extras, pagesize));
+ }
+#endif
+#endif
+
+#else
+
+ stgFree(oc->image);
+
+#if defined(powerpc_HOST_ARCH) || defined(x86_64_HOST_ARCH) || defined(arm_HOST_ARCH)
+#if !defined(x86_64_HOST_ARCH) || !defined(mingw32_HOST_OS)
+ stgFree(oc->symbol_extras);
+#endif
+#endif
+
+#endif
+
+ stgFree(oc->fileName);
+ stgFree(oc->archiveMemberName);
+ stgFree(oc);
+}
+
+
static ObjectCode*
mkOc( pathchar *path, char *image, int imageSize,
char *archiveMemberName
@@ -2143,10 +2184,6 @@ loadArchive( pathchar *path )
IF_DEBUG(linker, debugBelch("loadArchive: start\n"));
IF_DEBUG(linker, debugBelch("loadArchive: Loading archive `%" PATH_FMT" '\n", path));
- if (dynamicGhcPrograms) {
- barf("loadArchive called, but using dynamic GHC (%s)", path);
- }
-
gnuFileIndex = NULL;
gnuFileIndexSize = 0;
@@ -2538,10 +2575,6 @@ loadObj( pathchar *path )
#endif
IF_DEBUG(linker, debugBelch("loadObj %" PATH_FMT "\n", path));
- if (dynamicGhcPrograms) {
- barf("loadObj called, but using dynamic GHC (%s)", path);
- }
-
initLinker();
/* debugBelch("loadObj %s\n", path ); */
@@ -2749,7 +2782,7 @@ resolveObjs( void )
HsInt
unloadObj( pathchar *path )
{
- ObjectCode *oc, *prev;
+ ObjectCode *oc, *prev, *next;
HsBool unloadedAnyObj = HS_BOOL_FALSE;
ASSERT(symhash != NULL);
@@ -2757,8 +2790,12 @@ unloadObj( pathchar *path )
initLinker();
+ IF_DEBUG(linker, debugBelch("unloadObj: %s\n", path));
+
prev = NULL;
- for (oc = objects; oc; prev = oc, oc = oc->next) {
+ for (oc = objects; oc; prev = oc, oc = next) {
+ next = oc->next;
+
if (!pathcmp(oc->fileName,path)) {
/* Remove all the mappings for the symbols within this
@@ -2778,22 +2815,27 @@ unloadObj( pathchar *path )
} else {
prev->next = oc->next;
}
+ oc->next = unloaded_objects;
+ unloaded_objects = oc;
- // We're going to leave this in place, in case there are
- // any pointers from the heap into it:
- // #ifdef mingw32_HOST_OS
- // If uncommenting, note that currently oc->image is
- // not the right address to free on Win64, as we added
- // 4 bytes of padding at the start
- // VirtualFree(oc->image);
- // #else
- // stgFree(oc->image);
- // #endif
- stgFree(oc->fileName);
- stgFree(oc->archiveMemberName);
+ // The data itself and a few other bits (oc->fileName,
+ // oc->archiveMemberName) are kept until freeObjectCode(),
+ // which is only called when it has been determined that
+ // it is safe to unload the object.
stgFree(oc->symbols);
- stgFree(oc->sections);
- stgFree(oc);
+
+ {
+ Section *s, *nexts;
+
+ for (s = oc->sections; s != NULL; s = nexts) {
+ nexts = s->next;
+ stgFree(s);
+ }
+ }
+
+ freeProddableBlocks(oc);
+
+ oc->status = OBJECT_UNLOADED;
/* This could be a member of an archive so continue
* unloading other members. */
@@ -2843,6 +2885,17 @@ checkProddableBlock (ObjectCode *oc, void *addr, size_t size )
barf("checkProddableBlock: invalid fixup in runtime linker: %p", addr);
}
+static void freeProddableBlocks (ObjectCode *oc)
+{
+ ProddableBlock *pb, *next;
+
+ for (pb = oc->proddables; pb != NULL; pb = next) {
+ next = pb->next;
+ stgFree(pb);
+ }
+ oc->proddables = NULL;
+}
+
/* -----------------------------------------------------------------------------
* Section management.
*/
@@ -2931,6 +2984,7 @@ static int ocAllocateSymbolExtras( ObjectCode* oc, int count, int first )
memcpy(new, oc->image, oc->fileSize);
munmap(oc->image, n);
oc->image = new;
+ oc->fileSize = n + (sizeof(SymbolExtra) * count);
oc->symbol_extras = (SymbolExtra *) (oc->image + n);
}
else
@@ -3710,7 +3764,7 @@ ocGetNames_PEi386 ( ObjectCode* oc )
* => I suspect we've been incorrectly handling .bss sections in (relocatable)
* object files up until now. This turned out to bite us with ghc-6.4.1's use
* of gcc-3.4.x, which has started to emit initially-zeroed-out local 'static'
- * variable decls into to the .bss section. (The specific function in Q which
+ * variable decls into the .bss section. (The specific function in Q which
* triggered this is libraries/base/cbits/dirUtils.c:__hscore_getFolderPath())
*/
if (sectab_i->VirtualSize == 0 && sectab_i->SizeOfRawData == 0) continue;
diff --git a/rts/LinkerInternals.h b/rts/LinkerInternals.h
index 864e0d1f2f..753279d547 100644
--- a/rts/LinkerInternals.h
+++ b/rts/LinkerInternals.h
@@ -9,7 +9,11 @@
#ifndef LINKERINTERNALS_H
#define LINKERINTERNALS_H
-typedef enum { OBJECT_LOADED, OBJECT_RESOLVED } OStatus;
+typedef enum {
+ OBJECT_LOADED,
+ OBJECT_RESOLVED,
+ OBJECT_UNLOADED
+} OStatus;
/* Indication of section kinds for loaded objects. Needed by
the GC for deciding whether or not a pointer on the stack
@@ -82,6 +86,9 @@ typedef struct _ObjectCode {
/* ptr to malloc'd lump of memory holding the obj file */
char* image;
+ /* flag used when deciding whether to unload an object file */
+ int referenced;
+
#ifdef darwin_HOST_OS
/* record by how much image has been deliberately misaligned
after allocation, so that we can use realloc */
@@ -121,7 +128,10 @@ typedef struct _ObjectCode {
)
extern ObjectCode *objects;
+extern ObjectCode *unloaded_objects;
void exitLinker( void );
+void freeObjectCode (ObjectCode *oc);
+
#endif /* LINKERINTERNALS_H */
diff --git a/rts/StgCRun.c b/rts/StgCRun.c
index a45c52fd02..940e16dec1 100644
--- a/rts/StgCRun.c
+++ b/rts/StgCRun.c
@@ -116,7 +116,7 @@ StgWord8 *win32AllocStack(void)
#ifdef i386_HOST_ARCH
-#ifdef darwin_HOST_OS
+#if defined(darwin_HOST_OS) || defined(ios_HOST_OS)
#define STG_GLOBAL ".globl "
#define STG_HIDDEN ".private_extern "
#else
diff --git a/rts/ghc-frontpanel.glade b/rts/ghc-frontpanel.glade
deleted file mode 100644
index 9b73afce47..0000000000
--- a/rts/ghc-frontpanel.glade
+++ /dev/null
@@ -1,1622 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
-
-<glade-interface>
-
-<widget class="GtkWindow" id="GHC Front Panel">
- <property name="visible">True</property>
- <property name="title" translatable="yes">GHC Front Panel</property>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_NONE</property>
- <property name="modal">False</property>
- <property name="default_width">450</property>
- <property name="default_height">600</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">False</property>
- <property name="decorated">True</property>
- <property name="skip_taskbar_hint">False</property>
- <property name="skip_pager_hint">False</property>
- <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
- <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
- <property name="focus_on_map">True</property>
-
- <child>
- <widget class="GtkVBox" id="vbox1">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkHBox" id="hbox1">
- <property name="border_width">10</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">10</property>
-
- <child>
- <widget class="GtkVBox" id="vbox4">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">10</property>
-
- <child>
- <widget class="GtkFrame" id="frame3">
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="label_yalign">0.5</property>
- <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
-
- <child>
- <widget class="GtkHBox" id="hbox3">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkLabel" id="label40">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Mb</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVRuler" id="map_ruler">
- <property name="visible">True</property>
- <property name="metric">GTK_PIXELS</property>
- <property name="lower">0</property>
- <property name="upper">10</property>
- <property name="position">1.40845072269</property>
- <property name="max_size">10</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkDrawingArea" id="memmap">
- <property name="visible">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label1">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Memory Map</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">label_item</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkFrame" id="frame8">
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="label_yalign">0.5</property>
- <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
-
- <child>
- <widget class="GtkVBox" id="vbox14">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkTable" id="table4">
- <property name="visible">True</property>
- <property name="n_rows">2</property>
- <property name="n_columns">3</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">0</property>
- <property name="column_spacing">0</property>
-
- <child>
- <widget class="GtkVRuler" id="gen_ruler">
- <property name="visible">True</property>
- <property name="metric">GTK_PIXELS</property>
- <property name="lower">0</property>
- <property name="upper">10</property>
- <property name="position">1.69934999943</property>
- <property name="max_size">10</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="gen_hbox">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <placeholder/>
- </child>
-
- <child>
- <placeholder/>
- </child>
-
- <child>
- <placeholder/>
- </child>
- </widget>
- <packing>
- <property name="left_attach">2</property>
- <property name="right_attach">3</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options">fill</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkDrawingArea" id="generations">
- <property name="visible">True</property>
- </widget>
- <packing>
- <property name="left_attach">2</property>
- <property name="right_attach">3</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options">fill</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label39">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Mb</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options"></property>
- <property name="y_options"></property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label41">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Generations</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">label_item</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkFrame" id="frame7">
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="label_yalign">0.5</property>
- <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
-
- <child>
- <widget class="GtkTable" id="table3">
- <property name="border_width">2</property>
- <property name="visible">True</property>
- <property name="n_rows">3</property>
- <property name="n_columns">3</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">0</property>
- <property name="column_spacing">0</property>
-
- <child>
- <widget class="GtkHRuler" id="res_hruler">
- <property name="visible">True</property>
- <property name="metric">GTK_PIXELS</property>
- <property name="lower">0</property>
- <property name="upper">10</property>
- <property name="position">8.35443019867</property>
- <property name="max_size">10</property>
- </widget>
- <packing>
- <property name="left_attach">2</property>
- <property name="right_attach">3</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="y_options">fill</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVRuler" id="res_vruler">
- <property name="visible">True</property>
- <property name="metric">GTK_PIXELS</property>
- <property name="lower">0</property>
- <property name="upper">10</property>
- <property name="position">9.69925022125</property>
- <property name="max_size">10</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options">fill</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkDrawingArea" id="res_drawingarea">
- <property name="visible">True</property>
- </widget>
- <packing>
- <property name="left_attach">2</property>
- <property name="right_attach">3</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options">fill</property>
- <property name="y_options">fill</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label37">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Secs</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">2</property>
- <property name="right_attach">3</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options"></property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label38">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Mb</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options"></property>
- <property name="y_options"></property>
- </packing>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label42">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Residency</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">label_item</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox5">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">10</property>
-
- <child>
- <widget class="GtkFrame" id="frame5">
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="label_yalign">0.5</property>
- <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
-
- <child>
- <widget class="GtkVBox" id="vbox6">
- <property name="border_width">5</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <placeholder/>
- </child>
-
- <child>
- <placeholder/>
- </child>
-
- <child>
- <widget class="GtkTable" id="table1">
- <property name="visible">True</property>
- <property name="n_rows">4</property>
- <property name="n_columns">3</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">0</property>
- <property name="column_spacing">7</property>
-
- <child>
- <widget class="GtkLabel" id="label12">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Allocated</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_RIGHT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">1</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label13">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Live</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_RIGHT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">1</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label14">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Allocation Rate</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_RIGHT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">1</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="x_options"></property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label15">
- <property name="visible">True</property>
- <property name="label" translatable="yes"> Footprint</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_RIGHT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">1</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label16">
- <property name="visible">True</property>
- <property name="label" translatable="yes">M/sec</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">2</property>
- <property name="right_attach">3</property>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="x_options"></property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label17">
- <property name="visible">True</property>
- <property name="label" translatable="yes">M</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">7.45058015283e-09</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">2</property>
- <property name="right_attach">3</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label18">
- <property name="visible">True</property>
- <property name="label" translatable="yes">M</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">7.45058015283e-09</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">2</property>
- <property name="right_attach">3</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label19">
- <property name="visible">True</property>
- <property name="label" translatable="yes">M</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">7.45058015283e-09</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">2</property>
- <property name="right_attach">3</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="live_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">1</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="allocated_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">1</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="footprint_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">1</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="alloc_rate_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes"></property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">1</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label43">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Stats</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">label_item</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkFrame" id="frame9">
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="label_yalign">0.5</property>
- <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
-
- <child>
- <widget class="GtkTable" id="table5">
- <property name="border_width">6</property>
- <property name="visible">True</property>
- <property name="n_rows">9</property>
- <property name="n_columns">2</property>
- <property name="homogeneous">False</property>
- <property name="row_spacing">0</property>
- <property name="column_spacing">10</property>
-
- <child>
- <widget class="GtkLabel" id="label20">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Running</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">1</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label21">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Blocked on I/O (Read)</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">1</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label22">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Blocked on MVar</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">1</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label24">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Blocked on throwTo</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">1</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">4</property>
- <property name="bottom_attach">5</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label26">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Blocked on Black Hole</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">1</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">5</property>
- <property name="bottom_attach">6</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label25">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Sleeping</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">1</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">6</property>
- <property name="bottom_attach">7</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label27">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Blocked on I/O (Write)</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">1</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options"></property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="running_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">label28</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">0</property>
- <property name="bottom_attach">1</property>
- <property name="x_options"></property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="blockread_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">label29</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">1</property>
- <property name="bottom_attach">2</property>
- <property name="x_options"></property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="blockwrite_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">label30</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">2</property>
- <property name="bottom_attach">3</property>
- <property name="x_options"></property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="blockmvar_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">label31</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">3</property>
- <property name="bottom_attach">4</property>
- <property name="x_options"></property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="blockthrowto_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">label32</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">4</property>
- <property name="bottom_attach">5</property>
- <property name="x_options"></property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="blockbh_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">label33</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">5</property>
- <property name="bottom_attach">6</property>
- <property name="x_options"></property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="sleeping_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">label34</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">6</property>
- <property name="bottom_attach">7</property>
- <property name="x_options"></property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHSeparator" id="hseparator1">
- <property name="visible">True</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">7</property>
- <property name="bottom_attach">8</property>
- <property name="x_options">fill</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHSeparator" id="hseparator2">
- <property name="visible">True</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">7</property>
- <property name="bottom_attach">8</property>
- <property name="x_options">fill</property>
- <property name="y_options">fill</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label35">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Total</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">1</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">0</property>
- <property name="right_attach">1</property>
- <property name="top_attach">8</property>
- <property name="bottom_attach">9</property>
- <property name="x_options">fill</property>
- <property name="y_options"></property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="total_label">
- <property name="visible">True</property>
- <property name="label" translatable="yes">label36</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="left_attach">1</property>
- <property name="right_attach">2</property>
- <property name="top_attach">8</property>
- <property name="bottom_attach">9</property>
- <property name="x_options"></property>
- <property name="y_options"></property>
- </packing>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label44">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Threads</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">label_item</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkFrame" id="frame6">
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="label_yalign">0.5</property>
- <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
-
- <child>
- <widget class="GtkVBox" id="vbox7">
- <property name="border_width">5</property>
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">10</property>
-
- <child>
- <widget class="GtkVBox" id="vbox9">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkRadioButton" id="cont_radio">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Continuous</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">True</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <signal name="clicked" handler="on_cont_radio_clicked"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkRadioButton" id="stop_before_radio">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Stop before GC</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <property name="group">cont_radio</property>
- <signal name="clicked" handler="on_stop_before_radio_clicked"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkRadioButton" id="stop_after_radio">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Stop after GC</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <property name="group">cont_radio</property>
- <signal name="clicked" handler="on_stop_after_radio_clicked"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkRadioButton" id="stop_both_radio">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Stop before &amp; after GC</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <property name="group">cont_radio</property>
- <signal name="clicked" handler="on_stop_both_radio_clicked"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkVBox" id="vbox8">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkButton" id="stop_but">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Stop</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="on_stop_but_clicked"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkButton" id="continue_but">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Continue</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="on_continue_but_clicked"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label45">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Updates</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">label_item</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkButton" id="quit_but">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Quit</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="on_quit_but_clicked"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="pack_type">GTK_PACK_END</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="pack_type">GTK_PACK_END</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkStatusbar" id="statusbar">
- <property name="visible">True</property>
- <property name="has_resize_grip">True</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- </child>
-</widget>
-
-</glade-interface>
diff --git a/rts/ghc.mk b/rts/ghc.mk
index 4cc8e8de34..10e6cd5288 100644
--- a/rts/ghc.mk
+++ b/rts/ghc.mk
@@ -333,10 +333,6 @@ rts/RtsUtils_CC_OPTS += -DTargetVendor=\"$(TargetVendor_CPP)\"
rts/RtsUtils_CC_OPTS += -DGhcUnregisterised=\"$(GhcUnregisterised)\"
rts/RtsUtils_CC_OPTS += -DGhcEnableTablesNextToCode=\"$(GhcEnableTablesNextToCode)\"
-ifeq "$(DYNAMIC_GHC_PROGRAMS)" "YES"
-rts/Linker_CC_OPTS += -DDYNAMIC_GHC_PROGRAMS
-endif
-
# Compile various performance-critical pieces *without* -fPIC -dynamic
# even when building a shared library. If we don't do this, then the
# GC runs about 50% slower on x86 due to the overheads of PIC. The
diff --git a/rts/posix/OSMem.c b/rts/posix/OSMem.c
index 26aebc2b44..5486a15616 100644
--- a/rts/posix/OSMem.c
+++ b/rts/posix/OSMem.c
@@ -112,6 +112,27 @@ my_mmap (void *addr, W_ size)
} else {
vm_protect(mach_task_self(),(vm_address_t)ret,size,FALSE,VM_PROT_READ|VM_PROT_WRITE);
}
+#elif linux_HOST_OS
+ ret = mmap(addr, size, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_PRIVATE, -1, 0);
+ if (ret == (void *)-1 && errno == EPERM) {
+ // Linux may return EPERM if it tried to give us
+ // a chunk of address space below mmap_min_addr,
+ // See Trac #7500.
+ if (addr != 0) {
+ // Try again with no hint address.
+ // It's not clear that this can ever actually help,
+ // but since our alternative is to abort, we may as well try.
+ ret = mmap(0, size, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_PRIVATE, -1, 0);
+ }
+ if (ret == (void *)-1 && errno == EPERM) {
+ // Linux is not willing to give us any mapping,
+ // so treat this as an out-of-memory condition
+ // (really out of virtual address space).
+ errno = ENOMEM;
+ }
+ }
#else
ret = mmap(addr, size, PROT_READ | PROT_WRITE,
MAP_ANON | MAP_PRIVATE, -1, 0);
diff --git a/rts/sm/GC.c b/rts/sm/GC.c
index d0446281ab..8bbdda2266 100644
--- a/rts/sm/GC.c
+++ b/rts/sm/GC.c
@@ -47,6 +47,7 @@
#include "RaiseAsync.h"
#include "Papi.h"
#include "Stable.h"
+#include "CheckUnload.h"
#include <string.h> // for memset()
#include <unistd.h>
@@ -661,6 +662,10 @@ GarbageCollect (nat collect_gen,
resetNurseries();
+ if (major_gc) {
+ checkUnload (gct->scavenged_static_objects);
+ }
+
// mark the garbage collected CAFs as dead
#if 0 && defined(DEBUG) // doesn't work at the moment
if (major_gc) { gcCAFs(); }
diff --git a/settings.in b/settings.in
index 25699acc57..9f9654c689 100644
--- a/settings.in
+++ b/settings.in
@@ -14,6 +14,7 @@
("touch command", "@SettingsTouchCommand@"),
("dllwrap command", "@SettingsDllWrapCommand@"),
("windres command", "@SettingsWindresCommand@"),
+ ("libtool command", "@SettingsLibtoolCommand@"),
("perl command", "@SettingsPerlCommand@"),
("target os", "@HaskellTargetOs@"),
("target arch", "@HaskellTargetArch@"),
diff --git a/sync-all b/sync-all
index 24b8e734ab..85a697af52 100755
--- a/sync-all
+++ b/sync-all
@@ -316,10 +316,6 @@ sub gitall {
}
}
- # Some extra packages like 'async' may be external URLs,
- # e.g. git://... or http://...
- my $is_external_url = $remotepath =~ m/^(git:\/\/|https:\/\/|http:\/\/)/;
-
open RESUME, "> resume.tmp";
print RESUME "$localpath\n";
print RESUME "$doing\n";
@@ -328,12 +324,12 @@ sub gitall {
# We can't create directories on GitHub, so we translate
# "packages/foo" into "package-foo".
- if ($is_github_repo && !defined($is_external_url)) {
+ if ($is_github_repo) {
$remotepath =~ s/\//-/;
}
# Construct the path for this package in the repo we pulled from
- $path = $is_external_url ? $remotepath : "$repo_base/$remotepath";
+ $path = "$repo_base/$remotepath";
if ($command eq "get") {
next if $remotepath eq "-"; # "git submodule init/update" will get this later
@@ -786,7 +782,7 @@ sub main {
$tags{"-"} = 1;
$tags{"dph"} = 1;
- if ($OSNAME =~ /^(MSWin32|Cygwin)$/) {
+ if ($OSNAME =~ /^(MSWin32|Cygwin|msys)$/) {
$tags{"windows"} = 1;
}
@@ -1012,6 +1008,28 @@ Please remove it (e.g. "rm -r libraries/time"), and then run
EOF
}
+ message "== Checking for obsolete Git repo URL";
+ my $repo_url = &readgit(".", 'config', '--get', 'remote.origin.url');
+ if ($repo_url =~ /^http:\/\/darcs.haskell.org/) {
+ print <<EOF;
+============================
+ATTENTION!
+
+You seem to be using obsolete Git repository URLs.
+
+Please run
+
+ ./sync-all -r git://git.haskell.org remote set-url
+
+or (in case port 9418/tcp is filtered by your firewall)
+
+ ./sync-all -r http://git.haskell.org remote set-url
+
+to update your local checkout to use the new Git URLs.
+============================
+EOF
+ }
+
$? = $ec;
}
diff --git a/utils/dll-split/Main.hs b/utils/dll-split/Main.hs
index 336b6d9b26..c0e370641c 100644
--- a/utils/dll-split/Main.hs
+++ b/utils/dll-split/Main.hs
@@ -38,7 +38,7 @@ doit depfile startModule expectedReachableMods
in putStrLn (name ++ ": " ++ unwords ms)
putStrLn ("Reachable modules from " ++ moduleName startModule
++ " out of date")
- putStrLn "Please fix it, or building DLLs on Widnows may break (#7780)"
+ putStrLn "Please fix compiler/ghc.mk, or building DLLs on Windows may break (#7780)"
tellSet "Redundant modules" redundant
tellSet "Extra modules" extra
exitFailure
diff --git a/utils/genprimopcode/Main.hs b/utils/genprimopcode/Main.hs
index 8729d4c73c..333a2d3e46 100644
--- a/utils/genprimopcode/Main.hs
+++ b/utils/genprimopcode/Main.hs
@@ -125,7 +125,7 @@ gen_hs_source (Info defaults entries) =
++ "-- |\n"
++ "-- Module : GHC.Prim\n"
++ "-- \n"
- ++ "-- Maintainer : cvs-ghc@haskell.org\n"
+ ++ "-- Maintainer : ghc-devs@haskell.org\n"
++ "-- Stability : internal\n"
++ "-- Portability : non-portable (GHC extensions)\n"
++ "--\n"
diff --git a/utils/ghc-cabal/Main.hs b/utils/ghc-cabal/Main.hs
index 9a76d6b93d..7d1d9bcc92 100644
--- a/utils/ghc-cabal/Main.hs
+++ b/utils/ghc-cabal/Main.hs
@@ -167,7 +167,7 @@ doCopy directory distDir
(installDirTemplates lbi)
progs = withPrograms lbi
stripProgram' = stripProgram {
- programFindLocation = \_ -> return (Just strip) }
+ programFindLocation = \_ _ -> return (Just strip) }
progs' <- configureProgram verbosity stripProgram' progs
let lbi' = lbi {
@@ -205,12 +205,13 @@ doRegister directory distDir ghc ghcpkg topdir
progs = withPrograms lbi
ghcpkgconf = topdir </> "package.conf.d"
ghcProgram' = ghcProgram {
- programPostConf = \_ _ -> return ["-B" ++ topdir],
- programFindLocation = \_ -> return (Just ghc) }
+ programPostConf = \_ cp -> return cp { programDefaultArgs = ["-B" ++ topdir] },
+ programFindLocation = \_ _ -> return (Just ghc) }
ghcPkgProgram' = ghcPkgProgram {
- programPostConf = \_ _ -> return $ ["--global-package-db", ghcpkgconf]
- ++ ["--force" | not (null myDestDir) ],
- programFindLocation = \_ -> return (Just ghcpkg) }
+ programPostConf = \_ cp -> return cp { programDefaultArgs =
+ ["--global-package-db", ghcpkgconf]
+ ++ ["--force" | not (null myDestDir) ] },
+ programFindLocation = \_ _ -> return (Just ghcpkg) }
configurePrograms ps conf = foldM (flip (configureProgram verbosity)) conf ps
progs' <- configurePrograms [ghcProgram', ghcPkgProgram'] progs
diff --git a/utils/ghc-cabal/ghc-cabal.cabal b/utils/ghc-cabal/ghc-cabal.cabal
index 864620487d..10d6e0a9e4 100644
--- a/utils/ghc-cabal/ghc-cabal.cabal
+++ b/utils/ghc-cabal/ghc-cabal.cabal
@@ -17,7 +17,7 @@ Executable ghc-cabal
Build-Depends: base >= 3 && < 5,
bytestring >= 0.10 && < 0.11,
- Cabal >= 1.10 && < 1.18,
+ Cabal >= 1.18 && < 1.19,
directory >= 1.1 && < 1.3,
filepath >= 1.2 && < 1.4
diff --git a/validate b/validate
index 170bb2db25..95425d3770 100755
--- a/validate
+++ b/validate
@@ -1,21 +1,37 @@
#!/bin/sh
-# Flags:
-# --no-clean: don't make clean first, just carry on from
-# a previous interrupted validation run
-# --testsuite-only: don't build the compiler, just run
-# the test suite
-# --hpc: build stage2 with -fhpc, and see how much of the
-# compiler the test suite covers.
-# 2008-07-01: 63% slower than the default.
-# HTML generated here: testsuite/hpc_output/hpc_index.html
-# --normal: Default settings
-# --fast: Omit dyn way, omit binary distribution
-# --slow: Build stage2 with -DDEBUG.
-# 2008-07-01: 14% slower than the default.
-
set -e
+show_help () {
+ cat <<EOF
+Usage: $0 [FLAGS]...
+
+Validate GHC source tree against testsuite; see
+http://ghc.haskell.org/trac/ghc/wiki/TestingPatches for more
+information.
+
+Flags:
+ --no-clean don't make clean first, just carry on from
+ a previous interrupted validation run
+ --testsuite-only don't build the compiler, just run the test suite
+ --hpc build stage2 with -fhpc, and see how much of the
+ compiler the test suite covers.
+ 2008-07-01: 63% slower than the default.
+ HTML generated here: testsuite/hpc_output/hpc_index.html
+ --normal Default settings
+ --fast Omit dyn way, omit binary distribution
+ --slow Build stage2 with -DDEBUG.
+ 2008-07-01: 14% slower than the default.
+ --help shows this usage help.
+
+ Set environment variable 'CPUS' to number of cores, to exploit
+ multiple cpu cores, e.g.
+
+ CPUS=8 ./validate
+
+EOF
+}
+
no_clean=0
testsuite_only=0
hpc=NO
@@ -42,8 +58,12 @@ do
--normal)
speed=NORMAL
;;
+ --help)
+ show_help
+ exit 0;;
*)
- echo "Bad argument: $1" >&2
+ echo "$0: unrecognized argument '$1'" >&2
+ echo "Try '$0 --help' for more information." >&2
exit 1;;
esac
shift