-setFBTypeInfo fb info = info { fbTypeInfo = fb }
-setArgUsageInfo au info = info { argUsageInfo = au }
-setUpdateInfo ud info = info { updateInfo = ud }
-setDemandInfo dd info = info { demandInfo = dd }
-setStrictnessInfo st info = info { strictnessInfo = st }
-setSpecInfo sp info = info { specInfo = sp }
-setArityInfo ar info = info { arityInfo = ar }
-setInlinePragInfo pr info = info { inlinePragInfo = pr }
-setUnfoldingInfo uf info = info { unfoldingInfo = uf }
+setWorkerInfo info wk = wk `seq` info { workerInfo = wk }
+setSpecInfo info sp = PSEQ sp (info { specInfo = sp })
+setInlinePragInfo info pr = pr `seq` info { inlinePragInfo = pr }
+setOccInfo info oc = oc `seq` info { occInfo = oc }
+setStrictnessInfo info st = st `seq` info { strictnessInfo = st }
+ -- Try to avoid spack leaks by seq'ing
+
+setUnfoldingInfo info uf
+ | isEvaldUnfolding uf && isStrict (demandInfo info)
+ -- If the unfolding is a value, the demand info may
+ -- go pear-shaped, so we nuke it. Example:
+ -- let x = (a,b) in
+ -- case x of (p,q) -> h p q x
+ -- Here x is certainly demanded. But after we've nuked
+ -- the case, we'll get just
+ -- let x = (a,b) in h a b x
+ -- and now x is not demanded (I'm assuming h is lazy)
+ -- This really happens. The solution here is a bit ad hoc...
+ = info { unfoldingInfo = uf, demandInfo = wwLazy }
+
+ | otherwise
+ -- We do *not* seq on the unfolding info, For some reason, doing so
+ -- actually increases residency significantly.
+ = info { unfoldingInfo = uf }
+
+setUpdateInfo info ud = info { updateInfo = ud }
+setDemandInfo info dd = info { demandInfo = dd }
+setArityInfo info ar = info { arityInfo = ar }
+setCafInfo info cf = info { cafInfo = cf }
+setCprInfo info cp = info { cprInfo = cp }
+setLBVarInfo info lb = info { lbvarInfo = lb }
+
+setNoDiscardInfo info = case flavourInfo info of
+ VanillaId -> info { flavourInfo = NoDiscardId }
+ other -> info
+zapSpecPragInfo info = case flavourInfo info of
+ SpecPragmaId -> info { flavourInfo = VanillaId }
+ other -> info