<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> <head> <!-- Generated by HsColour, http://www.cs.york.ac.uk/fp/darcs/hscolour/ --> <title>simplCore/FloatOut.lhs</title> <link type='text/css' rel='stylesheet' href='hscolour.css' /> </head> <body> % % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 % \section[FloatOut]{Float bindings outwards (towards the top level)} ``Long-distance'' floating of bindings towards the top level. \begin{code} <pre><a name="line-1"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>FloatOut</span> <span class='hs-layout'>(</span> <span class='hs-varid'>floatOutwards</span> <span class='hs-layout'>)</span> <span class='hs-keyword'>where</span> <a name="line-2"></a> <a name="line-3"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CoreSyn</span> <a name="line-4"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CoreUtils</span> <a name="line-5"></a> <a name="line-6"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>DynFlags</span> <span class='hs-layout'>(</span> <span class='hs-conid'>DynFlags</span><span class='hs-layout'>,</span> <span class='hs-conid'>DynFlag</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-conid'>FloatOutSwitches</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span> <span class='hs-layout'>)</span> <a name="line-7"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>ErrUtils</span> <span class='hs-layout'>(</span> <span class='hs-varid'>dumpIfSet_dyn</span> <span class='hs-layout'>)</span> <a name="line-8"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CostCentre</span> <span class='hs-layout'>(</span> <span class='hs-varid'>dupifyCC</span><span class='hs-layout'>,</span> <span class='hs-conid'>CostCentre</span> <span class='hs-layout'>)</span> <a name="line-9"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Id</span> <span class='hs-layout'>(</span> <span class='hs-conid'>Id</span><span class='hs-layout'>,</span> <span class='hs-varid'>idType</span> <span class='hs-layout'>)</span> <a name="line-10"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Type</span> <span class='hs-layout'>(</span> <span class='hs-varid'>isUnLiftedType</span> <span class='hs-layout'>)</span> <a name="line-11"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>SetLevels</span> <span class='hs-layout'>(</span> <span class='hs-conid'>Level</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-conid'>LevelledExpr</span><span class='hs-layout'>,</span> <span class='hs-conid'>LevelledBind</span><span class='hs-layout'>,</span> <a name="line-12"></a> <span class='hs-varid'>setLevels</span><span class='hs-layout'>,</span> <span class='hs-varid'>isTopLvl</span><span class='hs-layout'>,</span> <span class='hs-varid'>tOP_LEVEL</span> <span class='hs-layout'>)</span> <a name="line-13"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>UniqSupply</span> <span class='hs-layout'>(</span> <span class='hs-conid'>UniqSupply</span> <span class='hs-layout'>)</span> <a name="line-14"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Bag</span> <a name="line-15"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Util</span> <a name="line-16"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Maybes</span> <a name="line-17"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>UniqFM</span> <a name="line-18"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Outputable</span> <a name="line-19"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>FastString</span> </pre>\end{code} ----------------- Overall game plan ----------------- The Big Main Idea is: To float out sub-expressions that can thereby get outside a non-one-shot value lambda, and hence may be shared. To achieve this we may need to do two thing: a) Let-bind the sub-expression: f (g x) ==> let lvl = f (g x) in lvl Now we can float the binding for 'lvl'. b) More than that, we may need to abstract wrt a type variable \x -> ... /\a -> let v = ...a... in .... Here the binding for v mentions 'a' but not 'x'. So we abstract wrt 'a', to give this binding for 'v': vp = /\a -> ...a... v = vp a Now the binding for vp can float out unimpeded. I can't remember why this case seemed important enough to deal with, but I certainly found cases where important floats didn't happen if we did not abstract wrt tyvars. With this in mind we can also achieve another goal: lambda lifting. We can make an arbitrary (function) binding float to top level by abstracting wrt *all* local variables, not just type variables, leaving a binding that can be floated right to top level. Whether or not this happens is controlled by a flag. Random comments ~~~~~~~~~~~~~~~ At the moment we never float a binding out to between two adjacent lambdas. For example: @ \x y -> let t = x+x in ... ===> \x -> let t = x+x in \y -> ... @ Reason: this is less efficient in the case where the original lambda is never partially applied. But there's a case I've seen where this might not be true. Consider: @ elEm2 x ys = elem' x ys where elem' _ [] = False elem' x (y:ys) = x==y || elem' x ys @ It turns out that this generates a subexpression of the form @ \deq x ys -> let eq = eqFromEqDict deq in ... @ vwhich might usefully be separated to @ \deq -> let eq = eqFromEqDict deq in \xy -> ... @ Well, maybe. We don't do this at the moment. %************************************************************************ %* * \subsection[floatOutwards]{@floatOutwards@: let-floating interface function} %* * %************************************************************************ \begin{code} <pre><a name="line-1"></a><a name="floatOutwards"></a><span class='hs-definition'>floatOutwards</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>FloatOutSwitches</span> <a name="line-2"></a> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>DynFlags</span> <a name="line-3"></a> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>UniqSupply</span> <a name="line-4"></a> <span class='hs-keyglyph'>-></span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>CoreBind</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>IO</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>CoreBind</span><span class='hs-keyglyph'>]</span> <a name="line-5"></a> <a name="line-6"></a><span class='hs-definition'>floatOutwards</span> <span class='hs-varid'>float_sws</span> <span class='hs-varid'>dflags</span> <span class='hs-varid'>us</span> <span class='hs-varid'>pgm</span> <a name="line-7"></a> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <span class='hs-layout'>{</span> <a name="line-8"></a> <span class='hs-keyword'>let</span> <span class='hs-layout'>{</span> <span class='hs-varid'>annotated_w_levels</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>setLevels</span> <span class='hs-varid'>float_sws</span> <span class='hs-varid'>pgm</span> <span class='hs-varid'>us</span> <span class='hs-layout'>;</span> <a name="line-9"></a> <span class='hs-layout'>(</span><span class='hs-varid'>fss</span><span class='hs-layout'>,</span> <span class='hs-varid'>binds_s'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>unzip</span> <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-varid'>floatTopBind</span> <span class='hs-varid'>annotated_w_levels</span><span class='hs-layout'>)</span> <a name="line-10"></a> <span class='hs-layout'>}</span> <span class='hs-layout'>;</span> <a name="line-11"></a> <a name="line-12"></a> <span class='hs-varid'>dumpIfSet_dyn</span> <span class='hs-varid'>dflags</span> <span class='hs-conid'>Opt_D_verbose_core2core</span> <span class='hs-str'>"Levels added:"</span> <a name="line-13"></a> <span class='hs-layout'>(</span><span class='hs-varid'>vcat</span> <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-varid'>ppr</span> <span class='hs-varid'>annotated_w_levels</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>;</span> <a name="line-14"></a> <a name="line-15"></a> <span class='hs-keyword'>let</span> <span class='hs-layout'>{</span> <span class='hs-layout'>(</span><span class='hs-varid'>tlets</span><span class='hs-layout'>,</span> <span class='hs-varid'>ntlets</span><span class='hs-layout'>,</span> <span class='hs-varid'>lams</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>get_stats</span> <span class='hs-layout'>(</span><span class='hs-varid'>sum_stats</span> <span class='hs-varid'>fss</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span><span class='hs-layout'>;</span> <a name="line-16"></a> <a name="line-17"></a> <span class='hs-varid'>dumpIfSet_dyn</span> <span class='hs-varid'>dflags</span> <span class='hs-conid'>Opt_D_dump_simpl_stats</span> <span class='hs-str'>"FloatOut stats:"</span> <a name="line-18"></a> <span class='hs-layout'>(</span><span class='hs-varid'>hcat</span> <span class='hs-keyglyph'>[</span> <span class='hs-varid'>int</span> <span class='hs-varid'>tlets</span><span class='hs-layout'>,</span> <span class='hs-varid'>ptext</span> <span class='hs-layout'>(</span><span class='hs-varid'>sLit</span> <span class='hs-str'>" Lets floated to top level; "</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <a name="line-19"></a> <span class='hs-varid'>int</span> <span class='hs-varid'>ntlets</span><span class='hs-layout'>,</span> <span class='hs-varid'>ptext</span> <span class='hs-layout'>(</span><span class='hs-varid'>sLit</span> <span class='hs-str'>" Lets floated elsewhere; from "</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <a name="line-20"></a> <span class='hs-varid'>int</span> <span class='hs-varid'>lams</span><span class='hs-layout'>,</span> <span class='hs-varid'>ptext</span> <span class='hs-layout'>(</span><span class='hs-varid'>sLit</span> <span class='hs-str'>" Lambda groups"</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span><span class='hs-layout'>;</span> <a name="line-21"></a> <a name="line-22"></a> <span class='hs-varid'>return</span> <span class='hs-layout'>(</span><span class='hs-varid'>concat</span> <span class='hs-varid'>binds_s'</span><span class='hs-layout'>)</span> <a name="line-23"></a> <span class='hs-layout'>}</span> <a name="line-24"></a> <a name="line-25"></a><a name="floatTopBind"></a><span class='hs-definition'>floatTopBind</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>LevelledBind</span> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-conid'>FloatStats</span><span class='hs-layout'>,</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>CoreBind</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span> <a name="line-26"></a><span class='hs-definition'>floatTopBind</span> <span class='hs-varid'>bind</span> <a name="line-27"></a> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-layout'>(</span><span class='hs-varid'>floatBind</span> <span class='hs-varid'>bind</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span> <span class='hs-layout'>(</span><span class='hs-varid'>fs</span><span class='hs-layout'>,</span> <span class='hs-varid'>floats</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <a name="line-28"></a> <span class='hs-layout'>(</span><span class='hs-varid'>fs</span><span class='hs-layout'>,</span> <span class='hs-varid'>bagToList</span> <span class='hs-layout'>(</span><span class='hs-varid'>flattenFloats</span> <span class='hs-varid'>floats</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <a name="line-29"></a> <span class='hs-layout'>}</span> </pre>\end{code} %************************************************************************ %* * \subsection[FloatOut-Bind]{Floating in a binding (the business end)} %* * %************************************************************************ \begin{code} <pre><a name="line-1"></a><a name="floatBind"></a><span class='hs-definition'>floatBind</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>LevelledBind</span> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-conid'>FloatStats</span><span class='hs-layout'>,</span> <span class='hs-conid'>FloatBinds</span><span class='hs-layout'>)</span> <a name="line-2"></a> <a name="line-3"></a><span class='hs-definition'>floatBind</span> <span class='hs-layout'>(</span><span class='hs-conid'>NonRec</span> <span class='hs-layout'>(</span><span class='hs-conid'>TB</span> <span class='hs-varid'>name</span> <span class='hs-varid'>level</span><span class='hs-layout'>)</span> <span class='hs-varid'>rhs</span><span class='hs-layout'>)</span> <a name="line-4"></a> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-layout'>(</span><span class='hs-varid'>floatRhs</span> <span class='hs-varid'>level</span> <span class='hs-varid'>rhs</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span> <span class='hs-layout'>(</span><span class='hs-varid'>fs</span><span class='hs-layout'>,</span> <span class='hs-varid'>rhs_floats</span><span class='hs-layout'>,</span> <span class='hs-varid'>rhs'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <a name="line-5"></a> <span class='hs-layout'>(</span><span class='hs-varid'>fs</span><span class='hs-layout'>,</span> <span class='hs-varid'>rhs_floats</span> <span class='hs-varop'>`plusFloats`</span> <span class='hs-varid'>unitFloat</span> <span class='hs-varid'>level</span> <span class='hs-layout'>(</span><span class='hs-conid'>NonRec</span> <span class='hs-varid'>name</span> <span class='hs-varid'>rhs'</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span> <a name="line-6"></a> <a name="line-7"></a><span class='hs-definition'>floatBind</span> <span class='hs-varid'>bind</span><span class='hs-keyglyph'>@</span><span class='hs-layout'>(</span><span class='hs-conid'>Rec</span> <span class='hs-varid'>pairs</span><span class='hs-layout'>)</span> <a name="line-8"></a> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-layout'>(</span><span class='hs-varid'>unzip3</span> <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-varid'>do_pair</span> <span class='hs-varid'>pairs</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span> <span class='hs-layout'>(</span><span class='hs-varid'>fss</span><span class='hs-layout'>,</span> <span class='hs-varid'>rhss_floats</span><span class='hs-layout'>,</span> <span class='hs-varid'>new_pairs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <a name="line-9"></a> <span class='hs-keyword'>let</span> <span class='hs-varid'>rhs_floats</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldr1</span> <span class='hs-varid'>plusFloats</span> <span class='hs-varid'>rhss_floats</span> <span class='hs-keyword'>in</span> <a name="line-10"></a> <a name="line-11"></a> <span class='hs-keyword'>if</span> <span class='hs-varid'>not</span> <span class='hs-layout'>(</span><span class='hs-varid'>isTopLvl</span> <span class='hs-varid'>bind_dest_lvl</span><span class='hs-layout'>)</span> <span class='hs-keyword'>then</span> <a name="line-12"></a> <span class='hs-comment'>-- Find which bindings float out at least one lambda beyond this one</span> <a name="line-13"></a> <span class='hs-comment'>-- These ones can't mention the binders, because they couldn't </span> <a name="line-14"></a> <span class='hs-comment'>-- be escaping a major level if so.</span> <a name="line-15"></a> <span class='hs-comment'>-- The ones that are not going further can join the letrec;</span> <a name="line-16"></a> <span class='hs-comment'>-- they may not be mutually recursive but the occurrence analyser will</span> <a name="line-17"></a> <span class='hs-comment'>-- find that out.</span> <a name="line-18"></a> <span class='hs-keyword'>case</span> <span class='hs-layout'>(</span><span class='hs-varid'>partitionByMajorLevel</span> <span class='hs-varid'>bind_dest_lvl</span> <span class='hs-varid'>rhs_floats</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span> <span class='hs-layout'>(</span><span class='hs-varid'>floats'</span><span class='hs-layout'>,</span> <span class='hs-varid'>heres</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <a name="line-19"></a> <span class='hs-layout'>(</span><span class='hs-varid'>sum_stats</span> <span class='hs-varid'>fss</span><span class='hs-layout'>,</span> <a name="line-20"></a> <span class='hs-varid'>floats'</span> <span class='hs-varop'>`plusFloats`</span> <span class='hs-varid'>unitFloat</span> <span class='hs-varid'>bind_dest_lvl</span> <a name="line-21"></a> <span class='hs-layout'>(</span><span class='hs-conid'>Rec</span> <span class='hs-layout'>(</span><span class='hs-varid'>floatsToBindPairs</span> <span class='hs-varid'>heres</span> <span class='hs-varid'>new_pairs</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span> <a name="line-22"></a> <span class='hs-keyword'>else</span> <a name="line-23"></a> <span class='hs-comment'>-- In a recursive binding, *destined for* the top level</span> <a name="line-24"></a> <span class='hs-comment'>-- (only), the rhs floats may contain references to the </span> <a name="line-25"></a> <span class='hs-comment'>-- bound things. For example</span> <a name="line-26"></a> <span class='hs-comment'>-- f = ...(let v = ...f... in b) ...</span> <a name="line-27"></a> <span class='hs-comment'>-- might get floated to</span> <a name="line-28"></a> <span class='hs-comment'>-- v = ...f...</span> <a name="line-29"></a> <span class='hs-comment'>-- f = ... b ...</span> <a name="line-30"></a> <span class='hs-comment'>-- and hence we must (pessimistically) make all the floats recursive</span> <a name="line-31"></a> <span class='hs-comment'>-- with the top binding. Later dependency analysis will unravel it.</span> <a name="line-32"></a> <span class='hs-comment'>--</span> <a name="line-33"></a> <span class='hs-comment'>-- This can only happen for bindings destined for the top level,</span> <a name="line-34"></a> <span class='hs-comment'>-- because only then will partitionByMajorLevel allow through a binding</span> <a name="line-35"></a> <span class='hs-comment'>-- that only differs in its minor level</span> <a name="line-36"></a> <span class='hs-layout'>(</span><span class='hs-varid'>sum_stats</span> <span class='hs-varid'>fss</span><span class='hs-layout'>,</span> <span class='hs-varid'>unitFloat</span> <span class='hs-varid'>tOP_LEVEL</span> <a name="line-37"></a> <span class='hs-layout'>(</span><span class='hs-conid'>Rec</span> <span class='hs-layout'>(</span><span class='hs-varid'>floatsToBindPairs</span> <span class='hs-layout'>(</span><span class='hs-varid'>flattenFloats</span> <span class='hs-varid'>rhs_floats</span><span class='hs-layout'>)</span> <span class='hs-varid'>new_pairs</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <a name="line-38"></a> <span class='hs-layout'>}</span> <a name="line-39"></a> <span class='hs-keyword'>where</span> <a name="line-40"></a> <span class='hs-varid'>bind_dest_lvl</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>getBindLevel</span> <span class='hs-varid'>bind</span> <a name="line-41"></a> <a name="line-42"></a> <span class='hs-varid'>do_pair</span> <span class='hs-layout'>(</span><span class='hs-conid'>TB</span> <span class='hs-varid'>name</span> <span class='hs-varid'>level</span><span class='hs-layout'>,</span> <span class='hs-varid'>rhs</span><span class='hs-layout'>)</span> <a name="line-43"></a> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-layout'>(</span><span class='hs-varid'>floatRhs</span> <span class='hs-varid'>level</span> <span class='hs-varid'>rhs</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span> <span class='hs-layout'>(</span><span class='hs-varid'>fs</span><span class='hs-layout'>,</span> <span class='hs-varid'>rhs_floats</span><span class='hs-layout'>,</span> <span class='hs-varid'>rhs'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <a name="line-44"></a> <span class='hs-layout'>(</span><span class='hs-varid'>fs</span><span class='hs-layout'>,</span> <span class='hs-varid'>rhs_floats</span><span class='hs-layout'>,</span> <span class='hs-layout'>(</span><span class='hs-varid'>name</span><span class='hs-layout'>,</span> <span class='hs-varid'>rhs'</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <a name="line-45"></a> <span class='hs-layout'>}</span> </pre>\end{code} %************************************************************************ \subsection[FloatOut-Expr]{Floating in expressions} %* * %************************************************************************ \begin{code} <pre><a name="line-1"></a><a name="floatExpr"></a><span class='hs-definition'>floatExpr</span><span class='hs-layout'>,</span> <span class='hs-varid'>floatRhs</span><span class='hs-layout'>,</span> <span class='hs-varid'>floatCaseAlt</span> <a name="line-2"></a> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Level</span> <a name="line-3"></a> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>LevelledExpr</span> <a name="line-4"></a> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-conid'>FloatStats</span><span class='hs-layout'>,</span> <span class='hs-conid'>FloatBinds</span><span class='hs-layout'>,</span> <span class='hs-conid'>CoreExpr</span><span class='hs-layout'>)</span> <a name="line-5"></a> <a name="line-6"></a><a name="floatCaseAlt"></a><span class='hs-definition'>floatCaseAlt</span> <span class='hs-varid'>lvl</span> <span class='hs-varid'>arg</span> <span class='hs-comment'>-- Used rec rhss, and case-alternative rhss</span> <a name="line-7"></a> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-layout'>(</span><span class='hs-varid'>floatExpr</span> <span class='hs-varid'>lvl</span> <span class='hs-varid'>arg</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span> <span class='hs-layout'>(</span><span class='hs-varid'>fsa</span><span class='hs-layout'>,</span> <span class='hs-varid'>floats</span><span class='hs-layout'>,</span> <span class='hs-varid'>arg'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <a name="line-8"></a> <span class='hs-keyword'>case</span> <span class='hs-layout'>(</span><span class='hs-varid'>partitionByMajorLevel</span> <span class='hs-varid'>lvl</span> <span class='hs-varid'>floats</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span> <span class='hs-layout'>(</span><span class='hs-varid'>floats'</span><span class='hs-layout'>,</span> <span class='hs-varid'>heres</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <a name="line-9"></a> <span class='hs-comment'>-- Dump bindings that aren't going to escape from a lambda;</span> <a name="line-10"></a> <span class='hs-comment'>-- in particular, we must dump the ones that are bound by </span> <a name="line-11"></a> <span class='hs-comment'>-- the rec or case alternative</span> <a name="line-12"></a> <span class='hs-layout'>(</span><span class='hs-varid'>fsa</span><span class='hs-layout'>,</span> <span class='hs-varid'>floats'</span><span class='hs-layout'>,</span> <span class='hs-varid'>install</span> <span class='hs-varid'>heres</span> <span class='hs-varid'>arg'</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span><span class='hs-layout'>}</span> <a name="line-13"></a> <a name="line-14"></a><a name="floatRhs"></a><span class='hs-definition'>floatRhs</span> <span class='hs-varid'>lvl</span> <span class='hs-varid'>arg</span> <span class='hs-comment'>-- Used for nested non-rec rhss, and fn args</span> <a name="line-15"></a> <span class='hs-comment'>-- See Note [Floating out of RHS]</span> <a name="line-16"></a> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-layout'>(</span><span class='hs-varid'>floatExpr</span> <span class='hs-varid'>lvl</span> <span class='hs-varid'>arg</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span> <span class='hs-layout'>(</span><span class='hs-varid'>fsa</span><span class='hs-layout'>,</span> <span class='hs-varid'>floats</span><span class='hs-layout'>,</span> <span class='hs-varid'>arg'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <a name="line-17"></a> <span class='hs-keyword'>if</span> <span class='hs-varid'>exprIsCheap</span> <span class='hs-varid'>arg'</span> <span class='hs-keyword'>then</span> <a name="line-18"></a> <span class='hs-layout'>(</span><span class='hs-varid'>fsa</span><span class='hs-layout'>,</span> <span class='hs-varid'>floats</span><span class='hs-layout'>,</span> <span class='hs-varid'>arg'</span><span class='hs-layout'>)</span> <a name="line-19"></a> <span class='hs-keyword'>else</span> <a name="line-20"></a> <span class='hs-keyword'>case</span> <span class='hs-layout'>(</span><span class='hs-varid'>partitionByMajorLevel</span> <span class='hs-varid'>lvl</span> <span class='hs-varid'>floats</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span> <span class='hs-layout'>(</span><span class='hs-varid'>floats'</span><span class='hs-layout'>,</span> <span class='hs-varid'>heres</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <a name="line-21"></a> <span class='hs-layout'>(</span><span class='hs-varid'>fsa</span><span class='hs-layout'>,</span> <span class='hs-varid'>floats'</span><span class='hs-layout'>,</span> <span class='hs-varid'>install</span> <span class='hs-varid'>heres</span> <span class='hs-varid'>arg'</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span><span class='hs-layout'>}</span> <a name="line-22"></a> <a name="line-23"></a><span class='hs-comment'>-- Note [Floating out of RHSs]</span> <a name="line-24"></a><span class='hs-comment'>-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~</span> <a name="line-25"></a><span class='hs-comment'>-- Dump bindings that aren't going to escape from a lambda</span> <a name="line-26"></a><span class='hs-comment'>-- This isn't a scoping issue (the binder isn't in scope in the RHS </span> <a name="line-27"></a><span class='hs-comment'>-- of a non-rec binding)</span> <a name="line-28"></a><span class='hs-comment'>-- Rather, it is to avoid floating the x binding out of</span> <a name="line-29"></a><span class='hs-comment'>-- f (let x = e in b)</span> <a name="line-30"></a><span class='hs-comment'>-- unnecessarily. But we first test for values or trival rhss,</span> <a name="line-31"></a><span class='hs-comment'>-- because (in particular) we don't want to insert new bindings between</span> <a name="line-32"></a><span class='hs-comment'>-- the "=" and the "\". E.g.</span> <a name="line-33"></a><span class='hs-comment'>-- f = \x -> let <bind> in <body></span> <a name="line-34"></a><span class='hs-comment'>-- We do not want</span> <a name="line-35"></a><span class='hs-comment'>-- f = let <bind> in \x -> <body></span> <a name="line-36"></a><span class='hs-comment'>-- (a) The simplifier will immediately float it further out, so we may</span> <a name="line-37"></a><span class='hs-comment'>-- as well do so right now; in general, keeping rhss as manifest </span> <a name="line-38"></a><span class='hs-comment'>-- values is good</span> <a name="line-39"></a><span class='hs-comment'>-- (b) If a float-in pass follows immediately, it might add yet more</span> <a name="line-40"></a><span class='hs-comment'>-- bindings just after the '='. And some of them might (correctly)</span> <a name="line-41"></a><span class='hs-comment'>-- be strict even though the 'let f' is lazy, because f, being a value,</span> <a name="line-42"></a><span class='hs-comment'>-- gets its demand-info zapped by the simplifier.</span> <a name="line-43"></a><span class='hs-comment'>--</span> <a name="line-44"></a><span class='hs-comment'>-- We use exprIsCheap because that is also what's used by the simplifier</span> <a name="line-45"></a><span class='hs-comment'>-- to decide whether to float a let out of a let</span> <a name="line-46"></a> <a name="line-47"></a><span class='hs-definition'>floatExpr</span> <span class='hs-keyword'>_</span> <span class='hs-layout'>(</span><span class='hs-conid'>Var</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>zeroStats</span><span class='hs-layout'>,</span> <span class='hs-varid'>emptyFloats</span><span class='hs-layout'>,</span> <span class='hs-conid'>Var</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> <a name="line-48"></a><span class='hs-definition'>floatExpr</span> <span class='hs-keyword'>_</span> <span class='hs-layout'>(</span><span class='hs-conid'>Type</span> <span class='hs-varid'>ty</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>zeroStats</span><span class='hs-layout'>,</span> <span class='hs-varid'>emptyFloats</span><span class='hs-layout'>,</span> <span class='hs-conid'>Type</span> <span class='hs-varid'>ty</span><span class='hs-layout'>)</span> <a name="line-49"></a><span class='hs-definition'>floatExpr</span> <span class='hs-keyword'>_</span> <span class='hs-layout'>(</span><span class='hs-conid'>Lit</span> <span class='hs-varid'>lit</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>zeroStats</span><span class='hs-layout'>,</span> <span class='hs-varid'>emptyFloats</span><span class='hs-layout'>,</span> <span class='hs-conid'>Lit</span> <span class='hs-varid'>lit</span><span class='hs-layout'>)</span> <a name="line-50"></a> <a name="line-51"></a><span class='hs-definition'>floatExpr</span> <span class='hs-varid'>lvl</span> <span class='hs-layout'>(</span><span class='hs-conid'>App</span> <span class='hs-varid'>e</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <a name="line-52"></a> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-layout'>(</span><span class='hs-varid'>floatExpr</span> <span class='hs-varid'>lvl</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span> <span class='hs-layout'>(</span><span class='hs-varid'>fse</span><span class='hs-layout'>,</span> <span class='hs-varid'>floats_e</span><span class='hs-layout'>,</span> <span class='hs-varid'>e'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <a name="line-53"></a> <span class='hs-keyword'>case</span> <span class='hs-layout'>(</span><span class='hs-varid'>floatRhs</span> <span class='hs-varid'>lvl</span> <span class='hs-varid'>a</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span> <span class='hs-layout'>(</span><span class='hs-varid'>fsa</span><span class='hs-layout'>,</span> <span class='hs-varid'>floats_a</span><span class='hs-layout'>,</span> <span class='hs-varid'>a'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <a name="line-54"></a> <span class='hs-layout'>(</span><span class='hs-varid'>fse</span> <span class='hs-varop'>`add_stats`</span> <span class='hs-varid'>fsa</span><span class='hs-layout'>,</span> <span class='hs-varid'>floats_e</span> <span class='hs-varop'>`plusFloats`</span> <span class='hs-varid'>floats_a</span><span class='hs-layout'>,</span> <span class='hs-conid'>App</span> <span class='hs-varid'>e'</span> <span class='hs-varid'>a'</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span><span class='hs-layout'>}</span> <a name="line-55"></a> <a name="line-56"></a><span class='hs-definition'>floatExpr</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>lam</span><span class='hs-keyglyph'>@</span><span class='hs-layout'>(</span><span class='hs-conid'>Lam</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <a name="line-57"></a> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>let</span> <a name="line-58"></a> <span class='hs-layout'>(</span><span class='hs-varid'>bndrs_w_lvls</span><span class='hs-layout'>,</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>collectBinders</span> <span class='hs-varid'>lam</span> <a name="line-59"></a> <span class='hs-varid'>bndrs</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>b</span> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>TB</span> <span class='hs-varid'>b</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>bndrs_w_lvls</span><span class='hs-keyglyph'>]</span> <a name="line-60"></a> <span class='hs-varid'>lvls</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>l</span> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>TB</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>l</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>bndrs_w_lvls</span><span class='hs-keyglyph'>]</span> <a name="line-61"></a> <a name="line-62"></a> <span class='hs-comment'>-- For the all-tyvar case we are prepared to pull </span> <a name="line-63"></a> <span class='hs-comment'>-- the lets out, to implement the float-out-of-big-lambda</span> <a name="line-64"></a> <span class='hs-comment'>-- transform; but otherwise we only float bindings that are</span> <a name="line-65"></a> <span class='hs-comment'>-- going to escape a value lambda.</span> <a name="line-66"></a> <span class='hs-comment'>-- In particular, for one-shot lambdas we don't float things</span> <a name="line-67"></a> <span class='hs-comment'>-- out; we get no saving by so doing.</span> <a name="line-68"></a> <span class='hs-varid'>partition_fn</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>all</span> <span class='hs-varid'>isTyVar</span> <span class='hs-varid'>bndrs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>partitionByLevel</span> <a name="line-69"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>partitionByMajorLevel</span> <a name="line-70"></a> <span class='hs-keyword'>in</span> <a name="line-71"></a> <span class='hs-keyword'>case</span> <span class='hs-layout'>(</span><span class='hs-varid'>floatExpr</span> <span class='hs-layout'>(</span><span class='hs-varid'>last</span> <span class='hs-varid'>lvls</span><span class='hs-layout'>)</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span> <span class='hs-layout'>(</span><span class='hs-varid'>fs</span><span class='hs-layout'>,</span> <span class='hs-varid'>floats</span><span class='hs-layout'>,</span> <span class='hs-varid'>body'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <a name="line-72"></a> <a name="line-73"></a> <span class='hs-comment'>-- Dump any bindings which absolutely cannot go any further</span> <a name="line-74"></a> <span class='hs-keyword'>case</span> <span class='hs-layout'>(</span><span class='hs-varid'>partition_fn</span> <span class='hs-layout'>(</span><span class='hs-varid'>head</span> <span class='hs-varid'>lvls</span><span class='hs-layout'>)</span> <span class='hs-varid'>floats</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span> <span class='hs-layout'>(</span><span class='hs-varid'>floats'</span><span class='hs-layout'>,</span> <span class='hs-varid'>heres</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <a name="line-75"></a> <a name="line-76"></a> <span class='hs-layout'>(</span><span class='hs-varid'>add_to_stats</span> <span class='hs-varid'>fs</span> <span class='hs-varid'>floats'</span><span class='hs-layout'>,</span> <span class='hs-varid'>floats'</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkLams</span> <span class='hs-varid'>bndrs</span> <span class='hs-layout'>(</span><span class='hs-varid'>install</span> <span class='hs-varid'>heres</span> <span class='hs-varid'>body'</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <a name="line-77"></a> <span class='hs-layout'>}</span><span class='hs-layout'>}</span> <a name="line-78"></a> <a name="line-79"></a><span class='hs-definition'>floatExpr</span> <span class='hs-varid'>lvl</span> <span class='hs-layout'>(</span><span class='hs-conid'>Note</span> <span class='hs-varid'>note</span><span class='hs-keyglyph'>@</span><span class='hs-layout'>(</span><span class='hs-conid'>SCC</span> <span class='hs-varid'>cc</span><span class='hs-layout'>)</span> <span class='hs-varid'>expr</span><span class='hs-layout'>)</span> <a name="line-80"></a> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-layout'>(</span><span class='hs-varid'>floatExpr</span> <span class='hs-varid'>lvl</span> <span class='hs-varid'>expr</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span> <span class='hs-layout'>(</span><span class='hs-varid'>fs</span><span class='hs-layout'>,</span> <span class='hs-varid'>floating_defns</span><span class='hs-layout'>,</span> <span class='hs-varid'>expr'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <a name="line-81"></a> <span class='hs-keyword'>let</span> <a name="line-82"></a> <span class='hs-comment'>-- Annotate bindings floated outwards past an scc expression</span> <a name="line-83"></a> <span class='hs-comment'>-- with the cc. We mark that cc as "duplicated", though.</span> <a name="line-84"></a> <a name="line-85"></a> <span class='hs-varid'>annotated_defns</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>wrapCostCentre</span> <span class='hs-layout'>(</span><span class='hs-varid'>dupifyCC</span> <span class='hs-varid'>cc</span><span class='hs-layout'>)</span> <span class='hs-varid'>floating_defns</span> <a name="line-86"></a> <span class='hs-keyword'>in</span> <a name="line-87"></a> <span class='hs-layout'>(</span><span class='hs-varid'>fs</span><span class='hs-layout'>,</span> <span class='hs-varid'>annotated_defns</span><span class='hs-layout'>,</span> <span class='hs-conid'>Note</span> <span class='hs-varid'>note</span> <span class='hs-varid'>expr'</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span> <a name="line-88"></a> <a name="line-89"></a><span class='hs-definition'>floatExpr</span> <span class='hs-keyword'>_</span> <span class='hs-layout'>(</span><span class='hs-conid'>Note</span> <span class='hs-conid'>InlineMe</span> <span class='hs-varid'>expr</span><span class='hs-layout'>)</span> <span class='hs-comment'>-- Other than SCCs</span> <a name="line-90"></a> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>zeroStats</span><span class='hs-layout'>,</span> <span class='hs-varid'>emptyFloats</span><span class='hs-layout'>,</span> <span class='hs-conid'>Note</span> <span class='hs-conid'>InlineMe</span> <span class='hs-layout'>(</span><span class='hs-varid'>unTag</span> <span class='hs-varid'>expr</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <a name="line-91"></a> <span class='hs-comment'>-- Do no floating at all inside INLINE.</span> <a name="line-92"></a> <span class='hs-comment'>-- The SetLevels pass did not clone the bindings, so it's</span> <a name="line-93"></a> <span class='hs-comment'>-- unsafe to do any floating, even if we dump the results</span> <a name="line-94"></a> <span class='hs-comment'>-- inside the Note (which is what we used to do).</span> <a name="line-95"></a> <a name="line-96"></a><span class='hs-definition'>floatExpr</span> <span class='hs-varid'>lvl</span> <span class='hs-layout'>(</span><span class='hs-conid'>Note</span> <span class='hs-varid'>note</span> <span class='hs-varid'>expr</span><span class='hs-layout'>)</span> <span class='hs-comment'>-- Other than SCCs</span> <a name="line-97"></a> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-layout'>(</span><span class='hs-varid'>floatExpr</span> <span class='hs-varid'>lvl</span> <span class='hs-varid'>expr</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span> <span class='hs-layout'>(</span><span class='hs-varid'>fs</span><span class='hs-layout'>,</span> <span class='hs-varid'>floating_defns</span><span class='hs-layout'>,</span> <span class='hs-varid'>expr'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <a name="line-98"></a> <span class='hs-layout'>(</span><span class='hs-varid'>fs</span><span class='hs-layout'>,</span> <span class='hs-varid'>floating_defns</span><span class='hs-layout'>,</span> <span class='hs-conid'>Note</span> <span class='hs-varid'>note</span> <span class='hs-varid'>expr'</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span> <a name="line-99"></a> <a name="line-100"></a><span class='hs-definition'>floatExpr</span> <span class='hs-varid'>lvl</span> <span class='hs-layout'>(</span><span class='hs-conid'>Cast</span> <span class='hs-varid'>expr</span> <span class='hs-varid'>co</span><span class='hs-layout'>)</span> <a name="line-101"></a> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-layout'>(</span><span class='hs-varid'>floatExpr</span> <span class='hs-varid'>lvl</span> <span class='hs-varid'>expr</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span> <span class='hs-layout'>(</span><span class='hs-varid'>fs</span><span class='hs-layout'>,</span> <span class='hs-varid'>floating_defns</span><span class='hs-layout'>,</span> <span class='hs-varid'>expr'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <a name="line-102"></a> <span class='hs-layout'>(</span><span class='hs-varid'>fs</span><span class='hs-layout'>,</span> <span class='hs-varid'>floating_defns</span><span class='hs-layout'>,</span> <span class='hs-conid'>Cast</span> <span class='hs-varid'>expr'</span> <span class='hs-varid'>co</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span> <a name="line-103"></a> <a name="line-104"></a><span class='hs-definition'>floatExpr</span> <span class='hs-varid'>lvl</span> <span class='hs-layout'>(</span><span class='hs-conid'>Let</span> <span class='hs-layout'>(</span><span class='hs-conid'>NonRec</span> <span class='hs-layout'>(</span><span class='hs-conid'>TB</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>bndr_lvl</span><span class='hs-layout'>)</span> <span class='hs-varid'>rhs</span><span class='hs-layout'>)</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span> <a name="line-105"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>isUnLiftedType</span> <span class='hs-layout'>(</span><span class='hs-varid'>idType</span> <span class='hs-varid'>bndr</span><span class='hs-layout'>)</span> <span class='hs-comment'>-- Treat unlifted lets just like a case</span> <a name="line-106"></a> <span class='hs-comment'>-- I.e. floatExpr for rhs, floatCaseAlt for body</span> <a name="line-107"></a> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>floatExpr</span> <span class='hs-varid'>lvl</span> <span class='hs-varid'>rhs</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span> <span class='hs-layout'>(</span><span class='hs-keyword'>_</span><span class='hs-layout'>,</span> <span class='hs-varid'>rhs_floats</span><span class='hs-layout'>,</span> <span class='hs-varid'>rhs'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <a name="line-108"></a> <span class='hs-keyword'>case</span> <span class='hs-varid'>floatCaseAlt</span> <span class='hs-varid'>bndr_lvl</span> <span class='hs-varid'>body</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span> <span class='hs-layout'>(</span><span class='hs-varid'>fs</span><span class='hs-layout'>,</span> <span class='hs-varid'>body_floats</span><span class='hs-layout'>,</span> <span class='hs-varid'>body'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <a name="line-109"></a> <span class='hs-layout'>(</span><span class='hs-varid'>fs</span><span class='hs-layout'>,</span> <span class='hs-varid'>rhs_floats</span> <span class='hs-varop'>`plusFloats`</span> <span class='hs-varid'>body_floats</span><span class='hs-layout'>,</span> <span class='hs-conid'>Let</span> <span class='hs-layout'>(</span><span class='hs-conid'>NonRec</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>rhs'</span><span class='hs-layout'>)</span> <span class='hs-varid'>body'</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span><span class='hs-layout'>}</span> <a name="line-110"></a> <a name="line-111"></a><span class='hs-definition'>floatExpr</span> <span class='hs-varid'>lvl</span> <span class='hs-layout'>(</span><span class='hs-conid'>Let</span> <span class='hs-varid'>bind</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span> <a name="line-112"></a> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-layout'>(</span><span class='hs-varid'>floatBind</span> <span class='hs-varid'>bind</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span> <span class='hs-layout'>(</span><span class='hs-varid'>fsb</span><span class='hs-layout'>,</span> <span class='hs-varid'>bind_floats</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <a name="line-113"></a> <span class='hs-keyword'>case</span> <span class='hs-layout'>(</span><span class='hs-varid'>floatExpr</span> <span class='hs-varid'>lvl</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span> <span class='hs-layout'>(</span><span class='hs-varid'>fse</span><span class='hs-layout'>,</span> <span class='hs-varid'>body_floats</span><span class='hs-layout'>,</span> <span class='hs-varid'>body'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <a name="line-114"></a> <span class='hs-layout'>(</span><span class='hs-varid'>add_stats</span> <span class='hs-varid'>fsb</span> <span class='hs-varid'>fse</span><span class='hs-layout'>,</span> <a name="line-115"></a> <span class='hs-varid'>bind_floats</span> <span class='hs-varop'>`plusFloats`</span> <span class='hs-varid'>body_floats</span><span class='hs-layout'>,</span> <a name="line-116"></a> <span class='hs-varid'>body'</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span><span class='hs-layout'>}</span> <a name="line-117"></a> <a name="line-118"></a><span class='hs-definition'>floatExpr</span> <span class='hs-varid'>lvl</span> <span class='hs-layout'>(</span><span class='hs-conid'>Case</span> <span class='hs-varid'>scrut</span> <span class='hs-layout'>(</span><span class='hs-conid'>TB</span> <span class='hs-varid'>case_bndr</span> <span class='hs-varid'>case_lvl</span><span class='hs-layout'>)</span> <span class='hs-varid'>ty</span> <span class='hs-varid'>alts</span><span class='hs-layout'>)</span> <a name="line-119"></a> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>floatExpr</span> <span class='hs-varid'>lvl</span> <span class='hs-varid'>scrut</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span> <span class='hs-layout'>(</span><span class='hs-varid'>fse</span><span class='hs-layout'>,</span> <span class='hs-varid'>fde</span><span class='hs-layout'>,</span> <span class='hs-varid'>scrut'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <a name="line-120"></a> <span class='hs-keyword'>case</span> <span class='hs-varid'>floatList</span> <span class='hs-varid'>float_alt</span> <span class='hs-varid'>alts</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span> <span class='hs-layout'>(</span><span class='hs-varid'>fsa</span><span class='hs-layout'>,</span> <span class='hs-varid'>fda</span><span class='hs-layout'>,</span> <span class='hs-varid'>alts'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <a name="line-121"></a> <span class='hs-layout'>(</span><span class='hs-varid'>add_stats</span> <span class='hs-varid'>fse</span> <span class='hs-varid'>fsa</span><span class='hs-layout'>,</span> <span class='hs-varid'>fda</span> <span class='hs-varop'>`plusFloats`</span> <span class='hs-varid'>fde</span><span class='hs-layout'>,</span> <span class='hs-conid'>Case</span> <span class='hs-varid'>scrut'</span> <span class='hs-varid'>case_bndr</span> <span class='hs-varid'>ty</span> <span class='hs-varid'>alts'</span><span class='hs-layout'>)</span> <a name="line-122"></a> <span class='hs-layout'>}</span><span class='hs-layout'>}</span> <a name="line-123"></a> <span class='hs-keyword'>where</span> <a name="line-124"></a> <span class='hs-comment'>-- Use floatCaseAlt for the alternatives, so that we</span> <a name="line-125"></a> <span class='hs-comment'>-- don't gratuitiously float bindings out of the RHSs</span> <a name="line-126"></a> <span class='hs-varid'>float_alt</span> <span class='hs-layout'>(</span><span class='hs-varid'>con</span><span class='hs-layout'>,</span> <span class='hs-varid'>bs</span><span class='hs-layout'>,</span> <span class='hs-varid'>rhs</span><span class='hs-layout'>)</span> <a name="line-127"></a> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-layout'>(</span><span class='hs-varid'>floatCaseAlt</span> <span class='hs-varid'>case_lvl</span> <span class='hs-varid'>rhs</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span> <span class='hs-layout'>(</span><span class='hs-varid'>fs</span><span class='hs-layout'>,</span> <span class='hs-varid'>rhs_floats</span><span class='hs-layout'>,</span> <span class='hs-varid'>rhs'</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <a name="line-128"></a> <span class='hs-layout'>(</span><span class='hs-varid'>fs</span><span class='hs-layout'>,</span> <span class='hs-varid'>rhs_floats</span><span class='hs-layout'>,</span> <span class='hs-layout'>(</span><span class='hs-varid'>con</span><span class='hs-layout'>,</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>b</span> <span class='hs-keyglyph'>|</span> <span class='hs-conid'>TB</span> <span class='hs-varid'>b</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>bs</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>,</span> <span class='hs-varid'>rhs'</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span> <a name="line-129"></a> <a name="line-130"></a> <a name="line-131"></a><a name="floatList"></a><span class='hs-definition'>floatList</span> <span class='hs-keyglyph'>::</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-conid'>FloatStats</span><span class='hs-layout'>,</span> <span class='hs-conid'>FloatBinds</span><span class='hs-layout'>,</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>a</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-conid'>FloatStats</span><span class='hs-layout'>,</span> <span class='hs-conid'>FloatBinds</span><span class='hs-layout'>,</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>b</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span> <a name="line-132"></a><span class='hs-definition'>floatList</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>[]</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>zeroStats</span><span class='hs-layout'>,</span> <span class='hs-varid'>emptyFloats</span><span class='hs-layout'>,</span> <span class='hs-conid'>[]</span><span class='hs-layout'>)</span> <a name="line-133"></a><span class='hs-definition'>floatList</span> <span class='hs-varid'>f</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span><span class='hs-conop'>:</span><span class='hs-keyword'>as</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>f</span> <span class='hs-varid'>a</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span> <span class='hs-layout'>(</span><span class='hs-varid'>fs_a</span><span class='hs-layout'>,</span> <span class='hs-varid'>binds_a</span><span class='hs-layout'>,</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <a name="line-134"></a> <span class='hs-keyword'>case</span> <span class='hs-varid'>floatList</span> <span class='hs-varid'>f</span> <span class='hs-keyword'>as</span> <span class='hs-keyword'>of</span> <span class='hs-layout'>{</span> <span class='hs-layout'>(</span><span class='hs-varid'>fs_as</span><span class='hs-layout'>,</span> <span class='hs-varid'>binds_as</span><span class='hs-layout'>,</span> <span class='hs-varid'>bs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <a name="line-135"></a> <span class='hs-layout'>(</span><span class='hs-varid'>fs_a</span> <span class='hs-varop'>`add_stats`</span> <span class='hs-varid'>fs_as</span><span class='hs-layout'>,</span> <span class='hs-varid'>binds_a</span> <span class='hs-varop'>`plusFloats`</span> <span class='hs-varid'>binds_as</span><span class='hs-layout'>,</span> <span class='hs-varid'>b</span><span class='hs-conop'>:</span><span class='hs-varid'>bs</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span><span class='hs-layout'>}</span> <a name="line-136"></a> <a name="line-137"></a><a name="getBindLevel"></a><span class='hs-definition'>getBindLevel</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Bind</span> <span class='hs-layout'>(</span><span class='hs-conid'>TaggedBndr</span> <span class='hs-conid'>Level</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Level</span> <a name="line-138"></a><span class='hs-definition'>getBindLevel</span> <span class='hs-layout'>(</span><span class='hs-conid'>NonRec</span> <span class='hs-layout'>(</span><span class='hs-conid'>TB</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>lvl</span><span class='hs-layout'>)</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>lvl</span> <a name="line-139"></a><span class='hs-definition'>getBindLevel</span> <span class='hs-layout'>(</span><span class='hs-conid'>Rec</span> <span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-layout'>(</span><span class='hs-conid'>TB</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>lvl</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-conop'>:</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>lvl</span> <a name="line-140"></a><span class='hs-definition'>getBindLevel</span> <span class='hs-layout'>(</span><span class='hs-conid'>Rec</span> <span class='hs-conid'>[]</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>panic</span> <span class='hs-str'>"getBindLevel Rec []"</span> <a name="line-141"></a> <a name="line-142"></a><a name="unTagBndr"></a><span class='hs-definition'>unTagBndr</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>TaggedBndr</span> <span class='hs-varid'>tag</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>CoreBndr</span> <a name="line-143"></a><span class='hs-definition'>unTagBndr</span> <span class='hs-layout'>(</span><span class='hs-conid'>TB</span> <span class='hs-varid'>b</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>b</span> <a name="line-144"></a> <a name="line-145"></a><a name="unTag"></a><span class='hs-definition'>unTag</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>TaggedExpr</span> <span class='hs-varid'>tag</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>CoreExpr</span> <a name="line-146"></a><span class='hs-definition'>unTag</span> <span class='hs-layout'>(</span><span class='hs-conid'>Var</span> <span class='hs-varid'>v</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Var</span> <span class='hs-varid'>v</span> <a name="line-147"></a><span class='hs-definition'>unTag</span> <span class='hs-layout'>(</span><span class='hs-conid'>Lit</span> <span class='hs-varid'>l</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Lit</span> <span class='hs-varid'>l</span> <a name="line-148"></a><span class='hs-definition'>unTag</span> <span class='hs-layout'>(</span><span class='hs-conid'>Type</span> <span class='hs-varid'>ty</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Type</span> <span class='hs-varid'>ty</span> <a name="line-149"></a><span class='hs-definition'>unTag</span> <span class='hs-layout'>(</span><span class='hs-conid'>Note</span> <span class='hs-varid'>n</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Note</span> <span class='hs-varid'>n</span> <span class='hs-layout'>(</span><span class='hs-varid'>unTag</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span> <a name="line-150"></a><span class='hs-definition'>unTag</span> <span class='hs-layout'>(</span><span class='hs-conid'>App</span> <span class='hs-varid'>e1</span> <span class='hs-varid'>e2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>App</span> <span class='hs-layout'>(</span><span class='hs-varid'>unTag</span> <span class='hs-varid'>e1</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>unTag</span> <span class='hs-varid'>e2</span><span class='hs-layout'>)</span> <a name="line-151"></a><span class='hs-definition'>unTag</span> <span class='hs-layout'>(</span><span class='hs-conid'>Lam</span> <span class='hs-varid'>b</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Lam</span> <span class='hs-layout'>(</span><span class='hs-varid'>unTagBndr</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>unTag</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span> <a name="line-152"></a><span class='hs-definition'>unTag</span> <span class='hs-layout'>(</span><span class='hs-conid'>Cast</span> <span class='hs-varid'>e</span> <span class='hs-varid'>co</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Cast</span> <span class='hs-layout'>(</span><span class='hs-varid'>unTag</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span> <span class='hs-varid'>co</span> <a name="line-153"></a><span class='hs-definition'>unTag</span> <span class='hs-layout'>(</span><span class='hs-conid'>Let</span> <span class='hs-layout'>(</span><span class='hs-conid'>Rec</span> <span class='hs-varid'>prs</span><span class='hs-layout'>)</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Let</span> <span class='hs-layout'>(</span><span class='hs-conid'>Rec</span> <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-varid'>unTagBndr</span> <span class='hs-varid'>b</span><span class='hs-layout'>,</span><span class='hs-varid'>unTag</span> <span class='hs-varid'>r</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-varid'>b</span><span class='hs-layout'>,</span> <span class='hs-varid'>r</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>prs</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>unTag</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span> <a name="line-154"></a><span class='hs-definition'>unTag</span> <span class='hs-layout'>(</span><span class='hs-conid'>Let</span> <span class='hs-layout'>(</span><span class='hs-conid'>NonRec</span> <span class='hs-varid'>b</span> <span class='hs-varid'>r</span><span class='hs-layout'>)</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Let</span> <span class='hs-layout'>(</span><span class='hs-conid'>NonRec</span> <span class='hs-layout'>(</span><span class='hs-varid'>unTagBndr</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>unTag</span> <span class='hs-varid'>r</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>unTag</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span> <a name="line-155"></a><span class='hs-definition'>unTag</span> <span class='hs-layout'>(</span><span class='hs-conid'>Case</span> <span class='hs-varid'>e</span> <span class='hs-varid'>b</span> <span class='hs-varid'>ty</span> <span class='hs-varid'>alts</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Case</span> <span class='hs-layout'>(</span><span class='hs-varid'>unTag</span> <span class='hs-varid'>e</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>unTagBndr</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-varid'>ty</span> <a name="line-156"></a> <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-varid'>c</span><span class='hs-layout'>,</span> <span class='hs-varid'>map</span> <span class='hs-varid'>unTagBndr</span> <span class='hs-varid'>bs</span><span class='hs-layout'>,</span> <span class='hs-varid'>unTag</span> <span class='hs-varid'>r</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-varid'>c</span><span class='hs-layout'>,</span><span class='hs-varid'>bs</span><span class='hs-layout'>,</span><span class='hs-varid'>r</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'><-</span> <span class='hs-varid'>alts</span><span class='hs-keyglyph'>]</span> </pre>\end{code} %************************************************************************ %* * \subsection{Utility bits for floating stats} %* * %************************************************************************ I didn't implement this with unboxed numbers. I don't want to be too strict in this stuff, as it is rarely turned on. (WDP 95/09) \begin{code} <pre><a name="line-1"></a><a name="FloatStats"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>FloatStats</span> <a name="line-2"></a> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>FlS</span> <span class='hs-conid'>Int</span> <span class='hs-comment'>-- Number of top-floats * lambda groups they've been past</span> <a name="line-3"></a> <span class='hs-conid'>Int</span> <span class='hs-comment'>-- Number of non-top-floats * lambda groups they've been past</span> <a name="line-4"></a> <span class='hs-conid'>Int</span> <span class='hs-comment'>-- Number of lambda (groups) seen</span> <a name="line-5"></a> <a name="line-6"></a><a name="get_stats"></a><span class='hs-definition'>get_stats</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>FloatStats</span> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-conid'>Int</span><span class='hs-layout'>,</span> <span class='hs-conid'>Int</span><span class='hs-layout'>,</span> <span class='hs-conid'>Int</span><span class='hs-layout'>)</span> <a name="line-7"></a><span class='hs-definition'>get_stats</span> <span class='hs-layout'>(</span><span class='hs-conid'>FlS</span> <span class='hs-varid'>a</span> <span class='hs-varid'>b</span> <span class='hs-varid'>c</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span><span class='hs-layout'>,</span> <span class='hs-varid'>b</span><span class='hs-layout'>,</span> <span class='hs-varid'>c</span><span class='hs-layout'>)</span> <a name="line-8"></a> <a name="line-9"></a><a name="zeroStats"></a><span class='hs-definition'>zeroStats</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>FloatStats</span> <a name="line-10"></a><span class='hs-definition'>zeroStats</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>FlS</span> <span class='hs-num'>0</span> <span class='hs-num'>0</span> <span class='hs-num'>0</span> <a name="line-11"></a> <a name="line-12"></a><a name="sum_stats"></a><span class='hs-definition'>sum_stats</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>FloatStats</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>FloatStats</span> <a name="line-13"></a><span class='hs-definition'>sum_stats</span> <span class='hs-varid'>xs</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldr</span> <span class='hs-varid'>add_stats</span> <span class='hs-varid'>zeroStats</span> <span class='hs-varid'>xs</span> <a name="line-14"></a> <a name="line-15"></a><a name="add_stats"></a><span class='hs-definition'>add_stats</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>FloatStats</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>FloatStats</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>FloatStats</span> <a name="line-16"></a><span class='hs-definition'>add_stats</span> <span class='hs-layout'>(</span><span class='hs-conid'>FlS</span> <span class='hs-varid'>a1</span> <span class='hs-varid'>b1</span> <span class='hs-varid'>c1</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>FlS</span> <span class='hs-varid'>a2</span> <span class='hs-varid'>b2</span> <span class='hs-varid'>c2</span><span class='hs-layout'>)</span> <a name="line-17"></a> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>FlS</span> <span class='hs-layout'>(</span><span class='hs-varid'>a1</span> <span class='hs-varop'>+</span> <span class='hs-varid'>a2</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>b1</span> <span class='hs-varop'>+</span> <span class='hs-varid'>b2</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>c1</span> <span class='hs-varop'>+</span> <span class='hs-varid'>c2</span><span class='hs-layout'>)</span> <a name="line-18"></a> <a name="line-19"></a><a name="add_to_stats"></a><span class='hs-definition'>add_to_stats</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>FloatStats</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>FloatBinds</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>FloatStats</span> <a name="line-20"></a><span class='hs-definition'>add_to_stats</span> <span class='hs-layout'>(</span><span class='hs-conid'>FlS</span> <span class='hs-varid'>a</span> <span class='hs-varid'>b</span> <span class='hs-varid'>c</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>FB</span> <span class='hs-varid'>tops</span> <span class='hs-varid'>others</span><span class='hs-layout'>)</span> <a name="line-21"></a> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>FlS</span> <span class='hs-layout'>(</span><span class='hs-varid'>a</span> <span class='hs-varop'>+</span> <span class='hs-varid'>lengthBag</span> <span class='hs-varid'>tops</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>b</span> <span class='hs-varop'>+</span> <span class='hs-varid'>lengthBag</span> <span class='hs-layout'>(</span><span class='hs-varid'>flattenMajor</span> <span class='hs-varid'>others</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>c</span> <span class='hs-varop'>+</span> <span class='hs-num'>1</span><span class='hs-layout'>)</span> </pre>\end{code} %************************************************************************ %* * \subsection{Utility bits for floating} %* * %************************************************************************ Note [Representation of FloatBinds] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The FloatBinds types is somewhat important. We can get very large numbers of floating bindings, often all destined for the top level. A typical example is x = [4,2,5,2,5, .... ] Then we get lots of small expressions like (fromInteger 4), which all get lifted to top level. The trouble is that (a) we partition these floating bindings *at every binding site* (b) SetLevels introduces a new bindings site for every float So we had better not look at each binding at each binding site! That is why MajorEnv is represented as a finite map. We keep the bindings destined for the *top* level separate, because we float them out even if they don't escape a *value* lambda; see partitionByMajorLevel. \begin{code} <pre><a name="line-1"></a><a name="FloatBind"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>FloatBind</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>CoreBind</span> <span class='hs-comment'>-- INVARIANT: a FloatBind is always lifted</span> <a name="line-2"></a> <a name="line-3"></a><a name="FloatBinds"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>FloatBinds</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>FB</span> <span class='hs-varop'>!</span><span class='hs-layout'>(</span><span class='hs-conid'>Bag</span> <span class='hs-conid'>FloatBind</span><span class='hs-layout'>)</span> <span class='hs-comment'>-- Destined for top level</span> <a name="line-4"></a> <span class='hs-varop'>!</span><span class='hs-conid'>MajorEnv</span> <span class='hs-comment'>-- Levels other than top</span> <a name="line-5"></a> <span class='hs-comment'>-- See Note [Representation of FloatBinds]</span> <a name="line-6"></a> <a name="line-7"></a><a name="MajorEnv"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>MajorEnv</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>UniqFM</span> <span class='hs-conid'>MinorEnv</span> <span class='hs-comment'>-- Keyed by major level</span> <a name="line-8"></a><a name="MinorEnv"></a><span class='hs-keyword'>type</span> <span class='hs-conid'>MinorEnv</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>UniqFM</span> <span class='hs-layout'>(</span><span class='hs-conid'>Bag</span> <span class='hs-conid'>FloatBind</span><span class='hs-layout'>)</span> <span class='hs-comment'>-- Keyed by minor level</span> <a name="line-9"></a> <a name="line-10"></a><a name="flattenFloats"></a><span class='hs-definition'>flattenFloats</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>FloatBinds</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Bag</span> <span class='hs-conid'>FloatBind</span> <a name="line-11"></a><span class='hs-definition'>flattenFloats</span> <span class='hs-layout'>(</span><span class='hs-conid'>FB</span> <span class='hs-varid'>tops</span> <span class='hs-varid'>others</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>tops</span> <span class='hs-varop'>`unionBags`</span> <span class='hs-varid'>flattenMajor</span> <span class='hs-varid'>others</span> <a name="line-12"></a> <a name="line-13"></a><a name="flattenMajor"></a><span class='hs-definition'>flattenMajor</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>MajorEnv</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Bag</span> <span class='hs-conid'>FloatBind</span> <a name="line-14"></a><span class='hs-definition'>flattenMajor</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldUFM</span> <span class='hs-layout'>(</span><span class='hs-varid'>unionBags</span> <span class='hs-varop'>.</span> <span class='hs-varid'>flattenMinor</span><span class='hs-layout'>)</span> <span class='hs-varid'>emptyBag</span> <a name="line-15"></a> <a name="line-16"></a><a name="flattenMinor"></a><span class='hs-definition'>flattenMinor</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>MinorEnv</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>Bag</span> <span class='hs-conid'>FloatBind</span> <a name="line-17"></a><span class='hs-definition'>flattenMinor</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldUFM</span> <span class='hs-varid'>unionBags</span> <span class='hs-varid'>emptyBag</span> <a name="line-18"></a> <a name="line-19"></a><a name="emptyFloats"></a><span class='hs-definition'>emptyFloats</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>FloatBinds</span> <a name="line-20"></a><span class='hs-definition'>emptyFloats</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>FB</span> <span class='hs-varid'>emptyBag</span> <span class='hs-varid'>emptyUFM</span> <a name="line-21"></a> <a name="line-22"></a><a name="unitFloat"></a><span class='hs-definition'>unitFloat</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Level</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>FloatBind</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>FloatBinds</span> <a name="line-23"></a><span class='hs-definition'>unitFloat</span> <span class='hs-conid'>InlineCtxt</span> <span class='hs-varid'>b</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>FB</span> <span class='hs-layout'>(</span><span class='hs-varid'>unitBag</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-varid'>emptyUFM</span> <a name="line-24"></a><span class='hs-definition'>unitFloat</span> <span class='hs-varid'>lvl</span><span class='hs-keyglyph'>@</span><span class='hs-layout'>(</span><span class='hs-conid'>Level</span> <span class='hs-varid'>major</span> <span class='hs-varid'>minor</span><span class='hs-layout'>)</span> <span class='hs-varid'>b</span> <a name="line-25"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>isTopLvl</span> <span class='hs-varid'>lvl</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>FB</span> <span class='hs-layout'>(</span><span class='hs-varid'>unitBag</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span> <span class='hs-varid'>emptyUFM</span> <a name="line-26"></a> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>FB</span> <span class='hs-varid'>emptyBag</span> <span class='hs-layout'>(</span><span class='hs-varid'>unitUFM</span> <span class='hs-varid'>major</span> <span class='hs-layout'>(</span><span class='hs-varid'>unitUFM</span> <span class='hs-varid'>minor</span> <span class='hs-layout'>(</span><span class='hs-varid'>unitBag</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <a name="line-27"></a> <a name="line-28"></a><a name="plusFloats"></a><span class='hs-definition'>plusFloats</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>FloatBinds</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>FloatBinds</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>FloatBinds</span> <a name="line-29"></a><span class='hs-definition'>plusFloats</span> <span class='hs-layout'>(</span><span class='hs-conid'>FB</span> <span class='hs-varid'>t1</span> <span class='hs-varid'>b1</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>FB</span> <span class='hs-varid'>t2</span> <span class='hs-varid'>b2</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>FB</span> <span class='hs-layout'>(</span><span class='hs-varid'>t1</span> <span class='hs-varop'>`unionBags`</span> <span class='hs-varid'>t2</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>b1</span> <span class='hs-varop'>`plusMajor`</span> <span class='hs-varid'>b2</span><span class='hs-layout'>)</span> <a name="line-30"></a> <a name="line-31"></a><a name="plusMajor"></a><span class='hs-definition'>plusMajor</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>MajorEnv</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>MajorEnv</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>MajorEnv</span> <a name="line-32"></a><span class='hs-definition'>plusMajor</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>plusUFM_C</span> <span class='hs-varid'>plusMinor</span> <a name="line-33"></a> <a name="line-34"></a><a name="plusMinor"></a><span class='hs-definition'>plusMinor</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>MinorEnv</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>MinorEnv</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>MinorEnv</span> <a name="line-35"></a><span class='hs-definition'>plusMinor</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>plusUFM_C</span> <span class='hs-varid'>unionBags</span> <a name="line-36"></a> <a name="line-37"></a><a name="floatsToBindPairs"></a><span class='hs-definition'>floatsToBindPairs</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Bag</span> <span class='hs-conid'>FloatBind</span> <span class='hs-keyglyph'>-></span> <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-conid'>Id</span><span class='hs-layout'>,</span><span class='hs-conid'>CoreExpr</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-></span> <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-conid'>Id</span><span class='hs-layout'>,</span><span class='hs-conid'>CoreExpr</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span> <a name="line-38"></a><span class='hs-definition'>floatsToBindPairs</span> <span class='hs-varid'>floats</span> <span class='hs-varid'>binds</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldrBag</span> <span class='hs-varid'>add</span> <span class='hs-varid'>binds</span> <span class='hs-varid'>floats</span> <a name="line-39"></a> <span class='hs-keyword'>where</span> <a name="line-40"></a> <span class='hs-varid'>add</span> <span class='hs-layout'>(</span><span class='hs-conid'>Rec</span> <span class='hs-varid'>pairs</span><span class='hs-layout'>)</span> <span class='hs-varid'>binds</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>pairs</span> <span class='hs-varop'>++</span> <span class='hs-varid'>binds</span> <a name="line-41"></a> <span class='hs-varid'>add</span> <span class='hs-layout'>(</span><span class='hs-conid'>NonRec</span> <span class='hs-varid'>binder</span> <span class='hs-varid'>rhs</span><span class='hs-layout'>)</span> <span class='hs-varid'>binds</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>binder</span><span class='hs-layout'>,</span><span class='hs-varid'>rhs</span><span class='hs-layout'>)</span> <span class='hs-conop'>:</span> <span class='hs-varid'>binds</span> <a name="line-42"></a> <a name="line-43"></a><a name="install"></a><span class='hs-definition'>install</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Bag</span> <span class='hs-conid'>FloatBind</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>CoreExpr</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>CoreExpr</span> <a name="line-44"></a><span class='hs-definition'>install</span> <span class='hs-varid'>defn_groups</span> <span class='hs-varid'>expr</span> <a name="line-45"></a> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>foldrBag</span> <span class='hs-varid'>install_group</span> <span class='hs-varid'>expr</span> <span class='hs-varid'>defn_groups</span> <a name="line-46"></a> <span class='hs-keyword'>where</span> <a name="line-47"></a> <span class='hs-varid'>install_group</span> <span class='hs-varid'>defns</span> <span class='hs-varid'>body</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Let</span> <span class='hs-varid'>defns</span> <span class='hs-varid'>body</span> <a name="line-48"></a> <a name="line-49"></a><a name="partitionByMajorLevel"></a><span class='hs-definition'>partitionByMajorLevel</span><span class='hs-layout'>,</span> <span class='hs-varid'>partitionByLevel</span> <a name="line-50"></a> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Level</span> <span class='hs-comment'>-- Partitioning level</span> <a name="line-51"></a> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>FloatBinds</span> <span class='hs-comment'>-- Defns to be divided into 2 piles...</span> <a name="line-52"></a> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-conid'>FloatBinds</span><span class='hs-layout'>,</span> <span class='hs-comment'>-- Defns with level strictly < partition level,</span> <a name="line-53"></a> <span class='hs-conid'>Bag</span> <span class='hs-conid'>FloatBind</span><span class='hs-layout'>)</span> <span class='hs-comment'>-- The rest</span> <a name="line-54"></a> <a name="line-55"></a><span class='hs-comment'>-- ---- partitionByMajorLevel ----</span> <a name="line-56"></a><span class='hs-comment'>-- Float it if we escape a value lambda, *or* if we get to the top level</span> <a name="line-57"></a><span class='hs-comment'>-- If we can get to the top level, say "yes" anyway. This means that</span> <a name="line-58"></a><span class='hs-comment'>-- x = f e</span> <a name="line-59"></a><span class='hs-comment'>-- transforms to</span> <a name="line-60"></a><span class='hs-comment'>-- lvl = e</span> <a name="line-61"></a><span class='hs-comment'>-- x = f lvl</span> <a name="line-62"></a><span class='hs-comment'>-- which is as it should be</span> <a name="line-63"></a> <a name="line-64"></a><span class='hs-definition'>partitionByMajorLevel</span> <span class='hs-conid'>InlineCtxt</span> <span class='hs-layout'>(</span><span class='hs-conid'>FB</span> <span class='hs-varid'>tops</span> <span class='hs-varid'>defns</span><span class='hs-layout'>)</span> <a name="line-65"></a> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-conid'>FB</span> <span class='hs-varid'>tops</span> <span class='hs-varid'>emptyUFM</span><span class='hs-layout'>,</span> <span class='hs-varid'>flattenMajor</span> <span class='hs-varid'>defns</span><span class='hs-layout'>)</span> <a name="line-66"></a> <a name="line-67"></a><span class='hs-definition'>partitionByMajorLevel</span> <span class='hs-layout'>(</span><span class='hs-conid'>Level</span> <span class='hs-varid'>major</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>FB</span> <span class='hs-varid'>tops</span> <span class='hs-varid'>defns</span><span class='hs-layout'>)</span> <a name="line-68"></a> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-conid'>FB</span> <span class='hs-varid'>tops</span> <span class='hs-varid'>outer</span><span class='hs-layout'>,</span> <span class='hs-varid'>heres</span> <span class='hs-varop'>`unionBags`</span> <span class='hs-varid'>flattenMajor</span> <span class='hs-varid'>inner</span><span class='hs-layout'>)</span> <a name="line-69"></a> <span class='hs-keyword'>where</span> <a name="line-70"></a> <span class='hs-layout'>(</span><span class='hs-varid'>outer</span><span class='hs-layout'>,</span> <span class='hs-varid'>mb_heres</span><span class='hs-layout'>,</span> <span class='hs-varid'>inner</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>splitUFM</span> <span class='hs-varid'>defns</span> <span class='hs-varid'>major</span> <a name="line-71"></a> <span class='hs-varid'>heres</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>mb_heres</span> <span class='hs-keyword'>of</span> <a name="line-72"></a> <span class='hs-conid'>Nothing</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>emptyBag</span> <a name="line-73"></a> <span class='hs-conid'>Just</span> <span class='hs-varid'>h</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>flattenMinor</span> <span class='hs-varid'>h</span> <a name="line-74"></a> <a name="line-75"></a><a name="partitionByLevel"></a><span class='hs-definition'>partitionByLevel</span> <span class='hs-conid'>InlineCtxt</span> <span class='hs-layout'>(</span><span class='hs-conid'>FB</span> <span class='hs-varid'>tops</span> <span class='hs-varid'>defns</span><span class='hs-layout'>)</span> <a name="line-76"></a> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-conid'>FB</span> <span class='hs-varid'>tops</span> <span class='hs-varid'>emptyUFM</span><span class='hs-layout'>,</span> <span class='hs-varid'>flattenMajor</span> <span class='hs-varid'>defns</span><span class='hs-layout'>)</span> <a name="line-77"></a> <a name="line-78"></a><span class='hs-definition'>partitionByLevel</span> <span class='hs-layout'>(</span><span class='hs-conid'>Level</span> <span class='hs-varid'>major</span> <span class='hs-varid'>minor</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>FB</span> <span class='hs-varid'>tops</span> <span class='hs-varid'>defns</span><span class='hs-layout'>)</span> <a name="line-79"></a> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-conid'>FB</span> <span class='hs-varid'>tops</span> <span class='hs-layout'>(</span><span class='hs-varid'>outer_maj</span> <span class='hs-varop'>`plusMajor`</span> <span class='hs-varid'>unitUFM</span> <span class='hs-varid'>major</span> <span class='hs-varid'>outer_min</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <a name="line-80"></a> <span class='hs-varid'>here_min</span> <span class='hs-varop'>`unionBags`</span> <span class='hs-varid'>flattenMinor</span> <span class='hs-varid'>inner_min</span> <a name="line-81"></a> <span class='hs-varop'>`unionBags`</span> <span class='hs-varid'>flattenMajor</span> <span class='hs-varid'>inner_maj</span><span class='hs-layout'>)</span> <a name="line-82"></a> <a name="line-83"></a> <span class='hs-keyword'>where</span> <a name="line-84"></a> <span class='hs-layout'>(</span><span class='hs-varid'>outer_maj</span><span class='hs-layout'>,</span> <span class='hs-varid'>mb_here_maj</span><span class='hs-layout'>,</span> <span class='hs-varid'>inner_maj</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>splitUFM</span> <span class='hs-varid'>defns</span> <span class='hs-varid'>major</span> <a name="line-85"></a> <span class='hs-layout'>(</span><span class='hs-varid'>outer_min</span><span class='hs-layout'>,</span> <span class='hs-varid'>mb_here_min</span><span class='hs-layout'>,</span> <span class='hs-varid'>inner_min</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>mb_here_maj</span> <span class='hs-keyword'>of</span> <a name="line-86"></a> <span class='hs-conid'>Nothing</span> <span class='hs-keyglyph'>-></span> <span class='hs-layout'>(</span><span class='hs-varid'>emptyUFM</span><span class='hs-layout'>,</span> <span class='hs-conid'>Nothing</span><span class='hs-layout'>,</span> <span class='hs-varid'>emptyUFM</span><span class='hs-layout'>)</span> <a name="line-87"></a> <span class='hs-conid'>Just</span> <span class='hs-varid'>min_defns</span> <span class='hs-keyglyph'>-></span> <span class='hs-varid'>splitUFM</span> <span class='hs-varid'>min_defns</span> <span class='hs-varid'>minor</span> <a name="line-88"></a> <span class='hs-varid'>here_min</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mb_here_min</span> <span class='hs-varop'>`orElse`</span> <span class='hs-varid'>emptyBag</span> <a name="line-89"></a> <a name="line-90"></a><a name="wrapCostCentre"></a><span class='hs-definition'>wrapCostCentre</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>CostCentre</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>FloatBinds</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>FloatBinds</span> <a name="line-91"></a><span class='hs-definition'>wrapCostCentre</span> <span class='hs-varid'>cc</span> <span class='hs-layout'>(</span><span class='hs-conid'>FB</span> <span class='hs-varid'>tops</span> <span class='hs-varid'>defns</span><span class='hs-layout'>)</span> <a name="line-92"></a> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>FB</span> <span class='hs-layout'>(</span><span class='hs-varid'>wrap_defns</span> <span class='hs-varid'>tops</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>mapUFM</span> <span class='hs-layout'>(</span><span class='hs-varid'>mapUFM</span> <span class='hs-varid'>wrap_defns</span><span class='hs-layout'>)</span> <span class='hs-varid'>defns</span><span class='hs-layout'>)</span> <a name="line-93"></a> <span class='hs-keyword'>where</span> <a name="line-94"></a> <span class='hs-varid'>wrap_defns</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mapBag</span> <span class='hs-varid'>wrap_one</span> <a name="line-95"></a> <span class='hs-varid'>wrap_one</span> <span class='hs-layout'>(</span><span class='hs-conid'>NonRec</span> <span class='hs-varid'>binder</span> <span class='hs-varid'>rhs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>NonRec</span> <span class='hs-varid'>binder</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkSCC</span> <span class='hs-varid'>cc</span> <span class='hs-varid'>rhs</span><span class='hs-layout'>)</span> <a name="line-96"></a> <span class='hs-varid'>wrap_one</span> <span class='hs-layout'>(</span><span class='hs-conid'>Rec</span> <span class='hs-varid'>pairs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Rec</span> <span class='hs-layout'>(</span><span class='hs-varid'>mapSnd</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkSCC</span> <span class='hs-varid'>cc</span><span class='hs-layout'>)</span> <span class='hs-varid'>pairs</span><span class='hs-layout'>)</span> </pre>\end{code} </body> </html>