Sophie

Sophie

distrib > Fedora > 14 > x86_64 > by-pkgid > 8d1ef08c9e0d44c69764afc615a03d0d > files > 1641

ghc-ghc-devel-6.12.3-5.fc14.i686.rpm

<?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>codeGen/ClosureInfo.lhs</title>
<link type='text/css' rel='stylesheet' href='hscolour.css' />
</head>
<body>
%
% (c) The University of Glasgow 2006
% (c) The Univserity of Glasgow 1992-2004
%

	Data structures which describe closures, and
	operations over those data structures

		Nothing monadic in here

Much of the rationale for these things is in the ``details'' part of
the STG paper.

\begin{code}
<pre><a name="line-1"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>ClosureInfo</span> <span class='hs-layout'>(</span>
<a name="line-2"></a>	<span class='hs-conid'>ClosureInfo</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'>LambdaFormInfo</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span>	<span class='hs-comment'>-- would be abstract but</span>
<a name="line-3"></a>	<span class='hs-conid'>StandardFormInfo</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span>			<span class='hs-comment'>-- mkCmmInfo looks inside</span>
<a name="line-4"></a>        <span class='hs-conid'>SMRep</span><span class='hs-layout'>,</span>
<a name="line-5"></a>
<a name="line-6"></a>	<span class='hs-conid'>ArgDescr</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'>Liveness</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-conid'>C_SRT</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>needsSRT</span><span class='hs-layout'>,</span>
<a name="line-8"></a>
<a name="line-9"></a>	<span class='hs-varid'>mkLFThunk</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkLFReEntrant</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkConLFInfo</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkSelectorLFInfo</span><span class='hs-layout'>,</span>
<a name="line-10"></a>	<span class='hs-varid'>mkApLFInfo</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkLFImported</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkLFArgument</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkLFLetNoEscape</span><span class='hs-layout'>,</span>
<a name="line-11"></a>
<a name="line-12"></a>	<span class='hs-varid'>mkClosureInfo</span><span class='hs-layout'>,</span> <span class='hs-varid'>mkConInfo</span><span class='hs-layout'>,</span> <span class='hs-varid'>maybeIsLFCon</span><span class='hs-layout'>,</span>
<a name="line-13"></a>
<a name="line-14"></a>	<span class='hs-varid'>closureSize</span><span class='hs-layout'>,</span> <span class='hs-varid'>closureNonHdrSize</span><span class='hs-layout'>,</span>
<a name="line-15"></a>	<span class='hs-varid'>closureGoodStuffSize</span><span class='hs-layout'>,</span> <span class='hs-varid'>closurePtrsSize</span><span class='hs-layout'>,</span>
<a name="line-16"></a>	<span class='hs-varid'>slopSize</span><span class='hs-layout'>,</span> 
<a name="line-17"></a>
<a name="line-18"></a>	<span class='hs-varid'>infoTableLabelFromCI</span><span class='hs-layout'>,</span>
<a name="line-19"></a>	<span class='hs-varid'>closureLabelFromCI</span><span class='hs-layout'>,</span>
<a name="line-20"></a>	<span class='hs-varid'>isLFThunk</span><span class='hs-layout'>,</span> <span class='hs-varid'>closureUpdReqd</span><span class='hs-layout'>,</span>
<a name="line-21"></a>	<span class='hs-varid'>closureNeedsUpdSpace</span><span class='hs-layout'>,</span> <span class='hs-varid'>closureIsThunk</span><span class='hs-layout'>,</span>
<a name="line-22"></a>	<span class='hs-varid'>closureSingleEntry</span><span class='hs-layout'>,</span> <span class='hs-varid'>closureReEntrant</span><span class='hs-layout'>,</span> <span class='hs-varid'>isConstrClosure_maybe</span><span class='hs-layout'>,</span>
<a name="line-23"></a>	<span class='hs-varid'>closureFunInfo</span><span class='hs-layout'>,</span>	<span class='hs-varid'>isStandardFormThunk</span><span class='hs-layout'>,</span> <span class='hs-varid'>isKnownFun</span><span class='hs-layout'>,</span>
<a name="line-24"></a>        <span class='hs-varid'>funTag</span><span class='hs-layout'>,</span> <span class='hs-varid'>funTagLFInfo</span><span class='hs-layout'>,</span> <span class='hs-varid'>tagForArity</span><span class='hs-layout'>,</span>
<a name="line-25"></a>
<a name="line-26"></a>	<span class='hs-varid'>enterIdLabel</span><span class='hs-layout'>,</span> <span class='hs-varid'>enterLocalIdLabel</span><span class='hs-layout'>,</span> <span class='hs-varid'>enterReturnPtLabel</span><span class='hs-layout'>,</span>
<a name="line-27"></a>
<a name="line-28"></a>	<span class='hs-varid'>nodeMustPointToIt</span><span class='hs-layout'>,</span> 
<a name="line-29"></a>	<span class='hs-conid'>CallMethod</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>getCallMethod</span><span class='hs-layout'>,</span>
<a name="line-30"></a>
<a name="line-31"></a>	<span class='hs-varid'>blackHoleOnEntry</span><span class='hs-layout'>,</span>
<a name="line-32"></a>
<a name="line-33"></a>	<span class='hs-varid'>staticClosureRequired</span><span class='hs-layout'>,</span>
<a name="line-34"></a>	<span class='hs-varid'>getClosureType</span><span class='hs-layout'>,</span>
<a name="line-35"></a>
<a name="line-36"></a>	<span class='hs-varid'>isToplevClosure</span><span class='hs-layout'>,</span>
<a name="line-37"></a>	<span class='hs-varid'>closureValDescr</span><span class='hs-layout'>,</span> <span class='hs-varid'>closureTypeDescr</span><span class='hs-layout'>,</span>	<span class='hs-comment'>-- profiling</span>
<a name="line-38"></a>
<a name="line-39"></a>	<span class='hs-varid'>isStaticClosure</span><span class='hs-layout'>,</span>
<a name="line-40"></a>	<span class='hs-varid'>cafBlackHoleClosureInfo</span><span class='hs-layout'>,</span>
<a name="line-41"></a>
<a name="line-42"></a>	<span class='hs-varid'>staticClosureNeedsLink</span><span class='hs-layout'>,</span>
<a name="line-43"></a>    <span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
<a name="line-44"></a>
<a name="line-45"></a><span class='hs-cpp'>#include "../includes/MachDeps.h"</span>
<a name="line-46"></a><span class='hs-cpp'>#include "HsVersions.h"</span>
<a name="line-47"></a>
<a name="line-48"></a><span class='hs-comment'>--import CgUtils</span>
<a name="line-49"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>StgSyn</span>
<a name="line-50"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>SMRep</span>
<a name="line-51"></a>
<a name="line-52"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CLabel</span>
<a name="line-53"></a>
<a name="line-54"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Unique</span>
<a name="line-55"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>StaticFlags</span>
<a name="line-56"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Var</span>
<a name="line-57"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Id</span>
<a name="line-58"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>IdInfo</span>
<a name="line-59"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>DataCon</span>
<a name="line-60"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Name</span>
<a name="line-61"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Type</span>
<a name="line-62"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>TypeRep</span>
<a name="line-63"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>TcType</span>
<a name="line-64"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>TyCon</span>
<a name="line-65"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>BasicTypes</span>
<a name="line-66"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>FastString</span>
<a name="line-67"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Outputable</span>
<a name="line-68"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Constants</span>
<a name="line-69"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>DynFlags</span>
</pre>\end{code}


%************************************************************************
%*									*
\subsection[ClosureInfo-datatypes]{Data types for closure information}
%*									*
%************************************************************************

Information about a closure, from the code generator's point of view.

A ClosureInfo decribes the info pointer of a closure.  It has
enough information 
  a) to construct the info table itself
  b) to allocate a closure containing that info pointer (i.e.
	it knows the info table label)

We make a ClosureInfo for
	- each let binding (both top level and not)
	- each data constructor (for its shared static and
		dynamic info tables)

\begin{code}
<pre><a name="line-1"></a><a name="ClosureInfo"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>ClosureInfo</span>
<a name="line-2"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ClosureInfo</span> <span class='hs-layout'>{</span>
<a name="line-3"></a>	<span class='hs-varid'>closureName</span>   <span class='hs-keyglyph'>::</span> <span class='hs-varop'>!</span><span class='hs-conid'>Name</span><span class='hs-layout'>,</span>		  <span class='hs-comment'>-- The thing bound to this closure</span>
<a name="line-4"></a>	<span class='hs-varid'>closureLFInfo</span> <span class='hs-keyglyph'>::</span> <span class='hs-varop'>!</span><span class='hs-conid'>LambdaFormInfo</span><span class='hs-layout'>,</span> <span class='hs-comment'>-- NOTE: not an LFCon (see below)</span>
<a name="line-5"></a>	<span class='hs-varid'>closureSMRep</span>  <span class='hs-keyglyph'>::</span> <span class='hs-varop'>!</span><span class='hs-conid'>SMRep</span><span class='hs-layout'>,</span>	  <span class='hs-comment'>-- representation used by storage mgr</span>
<a name="line-6"></a>	<span class='hs-varid'>closureSRT</span>    <span class='hs-keyglyph'>::</span> <span class='hs-varop'>!</span><span class='hs-conid'>C_SRT</span><span class='hs-layout'>,</span>	  <span class='hs-comment'>-- What SRT applies to this closure</span>
<a name="line-7"></a>	<span class='hs-varid'>closureType</span>   <span class='hs-keyglyph'>::</span> <span class='hs-varop'>!</span><span class='hs-conid'>Type</span><span class='hs-layout'>,</span>		  <span class='hs-comment'>-- Type of closure (ToDo: remove)</span>
<a name="line-8"></a>	<span class='hs-varid'>closureDescr</span>  <span class='hs-keyglyph'>::</span> <span class='hs-varop'>!</span><span class='hs-conid'>String</span>	  <span class='hs-comment'>-- closure description (for profiling)</span>
<a name="line-9"></a>    <span class='hs-layout'>}</span>
<a name="line-10"></a>
<a name="line-11"></a>  <span class='hs-comment'>-- Constructor closures don't have a unique info table label (they use</span>
<a name="line-12"></a>  <span class='hs-comment'>-- the constructor's info table), and they don't have an SRT.</span>
<a name="line-13"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>ConInfo</span> <span class='hs-layout'>{</span>
<a name="line-14"></a>	<span class='hs-varid'>closureCon</span>       <span class='hs-keyglyph'>::</span> <span class='hs-varop'>!</span><span class='hs-conid'>DataCon</span><span class='hs-layout'>,</span>
<a name="line-15"></a>	<span class='hs-varid'>closureSMRep</span>     <span class='hs-keyglyph'>::</span> <span class='hs-varop'>!</span><span class='hs-conid'>SMRep</span>
<a name="line-16"></a>    <span class='hs-layout'>}</span>
<a name="line-17"></a>
<a name="line-18"></a><span class='hs-comment'>-- C_SRT is what StgSyn.SRT gets translated to... </span>
<a name="line-19"></a><span class='hs-comment'>-- we add a label for the table, and expect only the 'offset/length' form</span>
<a name="line-20"></a>
<a name="line-21"></a><a name="C_SRT"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>C_SRT</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>NoC_SRT</span>
<a name="line-22"></a>	   <span class='hs-keyglyph'>|</span> <span class='hs-conid'>C_SRT</span> <span class='hs-varop'>!</span><span class='hs-conid'>CLabel</span> <span class='hs-varop'>!</span><span class='hs-conid'>WordOff</span> <span class='hs-varop'>!</span><span class='hs-conid'>StgHalfWord</span> <span class='hs-comment'>{-bitmap or escape-}</span>
<a name="line-23"></a>           <span class='hs-keyword'>deriving</span> <span class='hs-layout'>(</span><span class='hs-conid'>Eq</span><span class='hs-layout'>)</span>
<a name="line-24"></a>
<a name="line-25"></a><a name="needsSRT"></a><span class='hs-definition'>needsSRT</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>C_SRT</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-26"></a><span class='hs-definition'>needsSRT</span> <span class='hs-conid'>NoC_SRT</span>       <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
<a name="line-27"></a><span class='hs-definition'>needsSRT</span> <span class='hs-layout'>(</span><span class='hs-conid'>C_SRT</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-28"></a>
<a name="line-29"></a><span class='hs-keyword'>instance</span> <span class='hs-conid'>Outputable</span> <span class='hs-conid'>C_SRT</span> <span class='hs-keyword'>where</span>
<a name="line-30"></a>  <span class='hs-varid'>ppr</span> <span class='hs-layout'>(</span><span class='hs-conid'>NoC_SRT</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>ptext</span> <span class='hs-layout'>(</span><span class='hs-varid'>sLit</span> <span class='hs-str'>"_no_srt_"</span><span class='hs-layout'>)</span>
<a name="line-31"></a>  <span class='hs-varid'>ppr</span> <span class='hs-layout'>(</span><span class='hs-conid'>C_SRT</span> <span class='hs-varid'>label</span> <span class='hs-varid'>off</span> <span class='hs-varid'>bitmap</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>parens</span> <span class='hs-layout'>(</span><span class='hs-varid'>ppr</span> <span class='hs-varid'>label</span> <span class='hs-varop'>&lt;&gt;</span> <span class='hs-varid'>comma</span> <span class='hs-varop'>&lt;&gt;</span> <span class='hs-varid'>ppr</span> <span class='hs-varid'>off</span> <span class='hs-varop'>&lt;&gt;</span> <span class='hs-varid'>comma</span> <span class='hs-varop'>&lt;&gt;</span> <span class='hs-varid'>text</span> <span class='hs-layout'>(</span><span class='hs-varid'>show</span> <span class='hs-varid'>bitmap</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
</pre>\end{code}

%************************************************************************
%*									*
\subsubsection[LambdaFormInfo-datatype]{@LambdaFormInfo@: source-derivable info}
%*									*
%************************************************************************

Information about an identifier, from the code generator's point of
view.  Every identifier is bound to a LambdaFormInfo in the
environment, which gives the code generator enough info to be able to
tail call or return that identifier.

Note that a closure is usually bound to an identifier, so a
ClosureInfo contains a LambdaFormInfo.

\begin{code}
<pre><a name="line-1"></a><a name="LambdaFormInfo"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>LambdaFormInfo</span>
<a name="line-2"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>LFReEntrant</span>		<span class='hs-comment'>-- Reentrant closure (a function)</span>
<a name="line-3"></a>	<span class='hs-conid'>TopLevelFlag</span>	<span class='hs-comment'>-- True if top level</span>
<a name="line-4"></a>	<span class='hs-varop'>!</span><span class='hs-conid'>Int</span>		<span class='hs-comment'>-- Arity. Invariant: always &gt; 0</span>
<a name="line-5"></a>	<span class='hs-varop'>!</span><span class='hs-conid'>Bool</span>		<span class='hs-comment'>-- True &lt;=&gt; no fvs</span>
<a name="line-6"></a>	<span class='hs-conid'>ArgDescr</span>	<span class='hs-comment'>-- Argument descriptor (should reall be in ClosureInfo)</span>
<a name="line-7"></a>
<a name="line-8"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>LFCon</span>		<span class='hs-comment'>-- A saturated constructor application</span>
<a name="line-9"></a>	<span class='hs-conid'>DataCon</span>		<span class='hs-comment'>-- The constructor</span>
<a name="line-10"></a>
<a name="line-11"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>LFThunk</span>		<span class='hs-comment'>-- Thunk (zero arity)</span>
<a name="line-12"></a>	<span class='hs-conid'>TopLevelFlag</span>
<a name="line-13"></a>	<span class='hs-varop'>!</span><span class='hs-conid'>Bool</span>		<span class='hs-comment'>-- True &lt;=&gt; no free vars</span>
<a name="line-14"></a>	<span class='hs-varop'>!</span><span class='hs-conid'>Bool</span>		<span class='hs-comment'>-- True &lt;=&gt; updatable (i.e., *not* single-entry)</span>
<a name="line-15"></a>	<span class='hs-conid'>StandardFormInfo</span>
<a name="line-16"></a>	<span class='hs-varop'>!</span><span class='hs-conid'>Bool</span>		<span class='hs-comment'>-- True &lt;=&gt; *might* be a function type</span>
<a name="line-17"></a>
<a name="line-18"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>LFUnknown</span>		<span class='hs-comment'>-- Used for function arguments and imported things.</span>
<a name="line-19"></a>			<span class='hs-comment'>--  We know nothing about  this closure.  Treat like</span>
<a name="line-20"></a>			<span class='hs-comment'>-- updatable "LFThunk"...</span>
<a name="line-21"></a>			<span class='hs-comment'>-- Imported things which we do know something about use</span>
<a name="line-22"></a>			<span class='hs-comment'>-- one of the other LF constructors (eg LFReEntrant for</span>
<a name="line-23"></a>			<span class='hs-comment'>-- known functions)</span>
<a name="line-24"></a>	<span class='hs-varop'>!</span><span class='hs-conid'>Bool</span>		<span class='hs-comment'>-- True &lt;=&gt; *might* be a function type</span>
<a name="line-25"></a>
<a name="line-26"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>LFLetNoEscape</span>	<span class='hs-comment'>-- See LetNoEscape module for precise description of</span>
<a name="line-27"></a>			<span class='hs-comment'>-- these "lets".</span>
<a name="line-28"></a>	<span class='hs-varop'>!</span><span class='hs-conid'>Int</span>		<span class='hs-comment'>-- arity;</span>
<a name="line-29"></a>
<a name="line-30"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>LFBlackHole</span>		<span class='hs-comment'>-- Used for the closures allocated to hold the result</span>
<a name="line-31"></a>			<span class='hs-comment'>-- of a CAF.  We want the target of the update frame to</span>
<a name="line-32"></a>			<span class='hs-comment'>-- be in the heap, so we make a black hole to hold it.</span>
<a name="line-33"></a>        <span class='hs-conid'>CLabel</span>          <span class='hs-comment'>-- Flavour (info label, eg CAF_BLACKHOLE_info).</span>
<a name="line-34"></a>
<a name="line-35"></a>
<a name="line-36"></a><span class='hs-comment'>-------------------------</span>
<a name="line-37"></a><span class='hs-comment'>-- An ArgDsecr describes the argument pattern of a function</span>
<a name="line-38"></a>
<a name="line-39"></a><a name="ArgDescr"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>ArgDescr</span>
<a name="line-40"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ArgSpec</span>		<span class='hs-comment'>-- Fits one of the standard patterns</span>
<a name="line-41"></a>	<span class='hs-varop'>!</span><span class='hs-conid'>StgHalfWord</span>	<span class='hs-comment'>-- RTS type identifier ARG_P, ARG_N, ...</span>
<a name="line-42"></a>
<a name="line-43"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>ArgGen</span>	 	<span class='hs-comment'>-- General case</span>
<a name="line-44"></a>	<span class='hs-conid'>Liveness</span>	<span class='hs-comment'>-- Details about the arguments</span>
<a name="line-45"></a>
<a name="line-46"></a>
<a name="line-47"></a><span class='hs-comment'>-------------------------</span>
<a name="line-48"></a><span class='hs-comment'>-- We represent liveness bitmaps as a Bitmap (whose internal</span>
<a name="line-49"></a><span class='hs-comment'>-- representation really is a bitmap).  These are pinned onto case return</span>
<a name="line-50"></a><span class='hs-comment'>-- vectors to indicate the state of the stack for the garbage collector.</span>
<a name="line-51"></a><span class='hs-comment'>-- </span>
<a name="line-52"></a><span class='hs-comment'>-- In the compiled program, liveness bitmaps that fit inside a single</span>
<a name="line-53"></a><span class='hs-comment'>-- word (StgWord) are stored as a single word, while larger bitmaps are</span>
<a name="line-54"></a><span class='hs-comment'>-- stored as a pointer to an array of words. </span>
<a name="line-55"></a>
<a name="line-56"></a><a name="Liveness"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>Liveness</span>
<a name="line-57"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>SmallLiveness</span>	<span class='hs-comment'>-- Liveness info that fits in one word</span>
<a name="line-58"></a>	<span class='hs-conid'>StgWord</span>		<span class='hs-comment'>-- Here's the bitmap</span>
<a name="line-59"></a>
<a name="line-60"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>BigLiveness</span>		<span class='hs-comment'>-- Liveness info witha a multi-word bitmap</span>
<a name="line-61"></a>	<span class='hs-conid'>CLabel</span>		<span class='hs-comment'>-- Label for the bitmap</span>
<a name="line-62"></a>
<a name="line-63"></a>
<a name="line-64"></a><span class='hs-comment'>-------------------------</span>
<a name="line-65"></a><span class='hs-comment'>-- StandardFormInfo tells whether this thunk has one of </span>
<a name="line-66"></a><span class='hs-comment'>-- a small number of standard forms</span>
<a name="line-67"></a>
<a name="line-68"></a><a name="StandardFormInfo"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>StandardFormInfo</span>
<a name="line-69"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>NonStandardThunk</span>
<a name="line-70"></a>	<span class='hs-comment'>-- Not of of the standard forms</span>
<a name="line-71"></a>
<a name="line-72"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>SelectorThunk</span>
<a name="line-73"></a>	<span class='hs-comment'>-- A SelectorThunk is of form</span>
<a name="line-74"></a>	<span class='hs-comment'>--      case x of</span>
<a name="line-75"></a>	<span class='hs-comment'>--	       con a1,..,an -&gt; ak</span>
<a name="line-76"></a>	<span class='hs-comment'>-- and the constructor is from a single-constr type.</span>
<a name="line-77"></a>       <span class='hs-conid'>WordOff</span>             	<span class='hs-comment'>-- 0-origin offset of ak within the "goods" of </span>
<a name="line-78"></a>			<span class='hs-comment'>-- constructor (Recall that the a1,...,an may be laid</span>
<a name="line-79"></a>			<span class='hs-comment'>-- out in the heap in a non-obvious order.)</span>
<a name="line-80"></a>
<a name="line-81"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>ApThunk</span> 
<a name="line-82"></a>	<span class='hs-comment'>-- An ApThunk is of form</span>
<a name="line-83"></a>	<span class='hs-comment'>--	x1 ... xn</span>
<a name="line-84"></a>	<span class='hs-comment'>-- The code for the thunk just pushes x2..xn on the stack and enters x1.</span>
<a name="line-85"></a>	<span class='hs-comment'>-- There are a few of these (for 1 &lt;= n &lt;= MAX_SPEC_AP_SIZE) pre-compiled</span>
<a name="line-86"></a>	<span class='hs-comment'>-- in the RTS to save space.</span>
<a name="line-87"></a>	<span class='hs-conid'>Int</span>		<span class='hs-comment'>-- Arity, n</span>
</pre>\end{code}

%************************************************************************
%*									*
\subsection[ClosureInfo-construction]{Functions which build LFInfos}
%*									*
%************************************************************************

\begin{code}
<pre><a name="line-1"></a><a name="mkLFReEntrant"></a><span class='hs-definition'>mkLFReEntrant</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>TopLevelFlag</span>	<span class='hs-comment'>-- True of top level</span>
<a name="line-2"></a>	      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Id</span><span class='hs-keyglyph'>]</span>		<span class='hs-comment'>-- Free vars</span>
<a name="line-3"></a>	      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Id</span><span class='hs-keyglyph'>]</span> 		<span class='hs-comment'>-- Args</span>
<a name="line-4"></a>	      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>ArgDescr</span>	<span class='hs-comment'>-- Argument descriptor</span>
<a name="line-5"></a>	      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>LambdaFormInfo</span>
<a name="line-6"></a>
<a name="line-7"></a><span class='hs-definition'>mkLFReEntrant</span> <span class='hs-varid'>top</span> <span class='hs-varid'>fvs</span> <span class='hs-varid'>args</span> <span class='hs-varid'>arg_descr</span> 
<a name="line-8"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>LFReEntrant</span> <span class='hs-varid'>top</span> <span class='hs-layout'>(</span><span class='hs-varid'>length</span> <span class='hs-varid'>args</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>null</span> <span class='hs-varid'>fvs</span><span class='hs-layout'>)</span> <span class='hs-varid'>arg_descr</span>
<a name="line-9"></a>
<a name="line-10"></a><a name="mkLFThunk"></a><span class='hs-definition'>mkLFThunk</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>TopLevelFlag</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Var</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>UpdateFlag</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>LambdaFormInfo</span>
<a name="line-11"></a><span class='hs-definition'>mkLFThunk</span> <span class='hs-varid'>thunk_ty</span> <span class='hs-varid'>top</span> <span class='hs-varid'>fvs</span> <span class='hs-varid'>upd_flag</span>
<a name="line-12"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ASSERT2</span><span class='hs-layout'>(</span> <span class='hs-varid'>not</span> <span class='hs-layout'>(</span><span class='hs-varid'>isUpdatable</span> <span class='hs-varid'>upd_flag</span><span class='hs-layout'>)</span> <span class='hs-varop'>||</span> <span class='hs-varid'>not</span> <span class='hs-layout'>(</span><span class='hs-varid'>isUnLiftedType</span> <span class='hs-varid'>thunk_ty</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span> <span class='hs-varid'>ppr</span> <span class='hs-varid'>thunk_ty</span> <span class='hs-varop'>$$</span> <span class='hs-varid'>ppr</span> <span class='hs-varid'>fvs</span> <span class='hs-layout'>)</span>
<a name="line-13"></a>    <span class='hs-conid'>LFThunk</span> <span class='hs-varid'>top</span> <span class='hs-layout'>(</span><span class='hs-varid'>null</span> <span class='hs-varid'>fvs</span><span class='hs-layout'>)</span> 
<a name="line-14"></a>	    <span class='hs-layout'>(</span><span class='hs-varid'>isUpdatable</span> <span class='hs-varid'>upd_flag</span><span class='hs-layout'>)</span>
<a name="line-15"></a>	    <span class='hs-conid'>NonStandardThunk</span> 
<a name="line-16"></a>	    <span class='hs-layout'>(</span><span class='hs-varid'>might_be_a_function</span> <span class='hs-varid'>thunk_ty</span><span class='hs-layout'>)</span>
<a name="line-17"></a>
<a name="line-18"></a><a name="might_be_a_function"></a><span class='hs-definition'>might_be_a_function</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-19"></a><span class='hs-comment'>-- Return False only if we are *sure* it's a data type</span>
<a name="line-20"></a><span class='hs-comment'>-- Look through newtypes etc as much as poss</span>
<a name="line-21"></a><span class='hs-definition'>might_be_a_function</span> <span class='hs-varid'>ty</span>
<a name="line-22"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>splitTyConApp_maybe</span> <span class='hs-layout'>(</span><span class='hs-varid'>repType</span> <span class='hs-varid'>ty</span><span class='hs-layout'>)</span> <span class='hs-keyword'>of</span>
<a name="line-23"></a>	<span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-varid'>tc</span><span class='hs-layout'>,</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>not</span> <span class='hs-layout'>(</span><span class='hs-varid'>isDataTyCon</span> <span class='hs-varid'>tc</span><span class='hs-layout'>)</span>
<a name="line-24"></a>	<span class='hs-conid'>Nothing</span>	     <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>True</span>
</pre>\end{code}

@mkConLFInfo@ is similar, for constructors.

\begin{code}
<pre><a name="line-1"></a><a name="mkConLFInfo"></a><span class='hs-definition'>mkConLFInfo</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>DataCon</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>LambdaFormInfo</span>
<a name="line-2"></a><span class='hs-definition'>mkConLFInfo</span> <span class='hs-varid'>con</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>LFCon</span> <span class='hs-varid'>con</span>
<a name="line-3"></a>
<a name="line-4"></a><a name="maybeIsLFCon"></a><span class='hs-definition'>maybeIsLFCon</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>LambdaFormInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Maybe</span> <span class='hs-conid'>DataCon</span>
<a name="line-5"></a><span class='hs-definition'>maybeIsLFCon</span> <span class='hs-layout'>(</span><span class='hs-conid'>LFCon</span> <span class='hs-varid'>con</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Just</span> <span class='hs-varid'>con</span>
<a name="line-6"></a><span class='hs-definition'>maybeIsLFCon</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Nothing</span>
<a name="line-7"></a>
<a name="line-8"></a><a name="mkSelectorLFInfo"></a><span class='hs-definition'>mkSelectorLFInfo</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Id</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>WordOff</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>LambdaFormInfo</span>
<a name="line-9"></a><span class='hs-definition'>mkSelectorLFInfo</span> <span class='hs-varid'>id</span> <span class='hs-varid'>offset</span> <span class='hs-varid'>updatable</span>
<a name="line-10"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>LFThunk</span> <span class='hs-conid'>NotTopLevel</span> <span class='hs-conid'>False</span> <span class='hs-varid'>updatable</span> <span class='hs-layout'>(</span><span class='hs-conid'>SelectorThunk</span> <span class='hs-varid'>offset</span><span class='hs-layout'>)</span> 
<a name="line-11"></a>	<span class='hs-layout'>(</span><span class='hs-varid'>might_be_a_function</span> <span class='hs-layout'>(</span><span class='hs-varid'>idType</span> <span class='hs-varid'>id</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-12"></a>
<a name="line-13"></a><a name="mkApLFInfo"></a><span class='hs-definition'>mkApLFInfo</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Id</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>UpdateFlag</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>LambdaFormInfo</span>
<a name="line-14"></a><span class='hs-definition'>mkApLFInfo</span> <span class='hs-varid'>id</span> <span class='hs-varid'>upd_flag</span> <span class='hs-varid'>arity</span>
<a name="line-15"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>LFThunk</span> <span class='hs-conid'>NotTopLevel</span> <span class='hs-layout'>(</span><span class='hs-varid'>arity</span> <span class='hs-varop'>==</span> <span class='hs-num'>0</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>isUpdatable</span> <span class='hs-varid'>upd_flag</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>ApThunk</span> <span class='hs-varid'>arity</span><span class='hs-layout'>)</span>
<a name="line-16"></a>	<span class='hs-layout'>(</span><span class='hs-varid'>might_be_a_function</span> <span class='hs-layout'>(</span><span class='hs-varid'>idType</span> <span class='hs-varid'>id</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
</pre>\end{code}

Miscellaneous LF-infos.

\begin{code}
<pre><a name="line-1"></a><a name="mkLFArgument"></a><span class='hs-definition'>mkLFArgument</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Id</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>LambdaFormInfo</span>
<a name="line-2"></a><span class='hs-definition'>mkLFArgument</span> <span class='hs-varid'>id</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>LFUnknown</span> <span class='hs-layout'>(</span><span class='hs-varid'>might_be_a_function</span> <span class='hs-layout'>(</span><span class='hs-varid'>idType</span> <span class='hs-varid'>id</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-3"></a>
<a name="line-4"></a><a name="mkLFLetNoEscape"></a><span class='hs-definition'>mkLFLetNoEscape</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>LambdaFormInfo</span>
<a name="line-5"></a><span class='hs-definition'>mkLFLetNoEscape</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>LFLetNoEscape</span>
<a name="line-6"></a>
<a name="line-7"></a><a name="mkLFImported"></a><span class='hs-definition'>mkLFImported</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Id</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>LambdaFormInfo</span>
<a name="line-8"></a><span class='hs-definition'>mkLFImported</span> <span class='hs-varid'>id</span>
<a name="line-9"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>idArity</span> <span class='hs-varid'>id</span> <span class='hs-keyword'>of</span>
<a name="line-10"></a>      <span class='hs-varid'>n</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>n</span> <span class='hs-varop'>&gt;</span> <span class='hs-num'>0</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>LFReEntrant</span> <span class='hs-conid'>TopLevel</span> <span class='hs-varid'>n</span> <span class='hs-conid'>True</span> <span class='hs-layout'>(</span><span class='hs-varid'>panic</span> <span class='hs-str'>"arg_descr"</span><span class='hs-layout'>)</span>  <span class='hs-comment'>-- n &gt; 0</span>
<a name="line-11"></a>      <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>mkLFArgument</span> <span class='hs-varid'>id</span> <span class='hs-comment'>-- Not sure of exact arity</span>
</pre>\end{code}

\begin{code}
<pre><a name="line-1"></a><a name="isLFThunk"></a><span class='hs-definition'>isLFThunk</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>LambdaFormInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-2"></a><span class='hs-definition'>isLFThunk</span> <span class='hs-layout'>(</span><span class='hs-conid'>LFThunk</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-3"></a><span class='hs-definition'>isLFThunk</span> <span class='hs-layout'>(</span><span class='hs-conid'>LFBlackHole</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>      <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-4"></a>	<span class='hs-comment'>-- return True for a blackhole: this function is used to determine</span>
<a name="line-5"></a>	<span class='hs-comment'>-- whether to use the thunk header in SMP mode, and a blackhole</span>
<a name="line-6"></a>	<span class='hs-comment'>-- must have one.</span>
<a name="line-7"></a><span class='hs-definition'>isLFThunk</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
</pre>\end{code}

%************************************************************************
%*									*
	Building ClosureInfos
%*									*
%************************************************************************

\begin{code}
<pre><a name="line-1"></a><a name="mkClosureInfo"></a><span class='hs-definition'>mkClosureInfo</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Bool</span>		<span class='hs-comment'>-- Is static</span>
<a name="line-2"></a>	      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Id</span>
<a name="line-3"></a>	      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>LambdaFormInfo</span> 
<a name="line-4"></a>	      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span>	<span class='hs-comment'>-- Total and pointer words</span>
<a name="line-5"></a>	      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>C_SRT</span>
<a name="line-6"></a>	      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>String</span>		<span class='hs-comment'>-- String descriptor</span>
<a name="line-7"></a>	      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>ClosureInfo</span>
<a name="line-8"></a><span class='hs-definition'>mkClosureInfo</span> <span class='hs-varid'>is_static</span> <span class='hs-varid'>id</span> <span class='hs-varid'>lf_info</span> <span class='hs-varid'>tot_wds</span> <span class='hs-varid'>ptr_wds</span> <span class='hs-varid'>srt_info</span> <span class='hs-varid'>descr</span>
<a name="line-9"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ClosureInfo</span> <span class='hs-layout'>{</span> <span class='hs-varid'>closureName</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>name</span><span class='hs-layout'>,</span> 
<a name="line-10"></a>		  <span class='hs-varid'>closureLFInfo</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>lf_info</span><span class='hs-layout'>,</span>
<a name="line-11"></a>		  <span class='hs-varid'>closureSMRep</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>sm_rep</span><span class='hs-layout'>,</span> 
<a name="line-12"></a>		  <span class='hs-varid'>closureSRT</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>srt_info</span><span class='hs-layout'>,</span>
<a name="line-13"></a>		  <span class='hs-varid'>closureType</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>idType</span> <span class='hs-varid'>id</span><span class='hs-layout'>,</span>
<a name="line-14"></a>		  <span class='hs-varid'>closureDescr</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>descr</span> <span class='hs-layout'>}</span>
<a name="line-15"></a>  <span class='hs-keyword'>where</span>
<a name="line-16"></a>    <span class='hs-varid'>name</span>   <span class='hs-keyglyph'>=</span> <span class='hs-varid'>idName</span> <span class='hs-varid'>id</span>
<a name="line-17"></a>    <span class='hs-varid'>sm_rep</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>chooseSMRep</span> <span class='hs-varid'>is_static</span> <span class='hs-varid'>lf_info</span> <span class='hs-varid'>tot_wds</span> <span class='hs-varid'>ptr_wds</span>
<a name="line-18"></a>
<a name="line-19"></a><a name="mkConInfo"></a><span class='hs-definition'>mkConInfo</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Bool</span>	<span class='hs-comment'>-- Is static</span>
<a name="line-20"></a>	  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>DataCon</span>	
<a name="line-21"></a>	  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span>	<span class='hs-comment'>-- Total and pointer words</span>
<a name="line-22"></a>	  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>ClosureInfo</span>
<a name="line-23"></a><span class='hs-definition'>mkConInfo</span> <span class='hs-varid'>is_static</span> <span class='hs-varid'>data_con</span> <span class='hs-varid'>tot_wds</span> <span class='hs-varid'>ptr_wds</span>
<a name="line-24"></a>   <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ConInfo</span> <span class='hs-layout'>{</span>	<span class='hs-varid'>closureSMRep</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>sm_rep</span><span class='hs-layout'>,</span>
<a name="line-25"></a>		<span class='hs-varid'>closureCon</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>data_con</span> <span class='hs-layout'>}</span>
<a name="line-26"></a>  <span class='hs-keyword'>where</span>
<a name="line-27"></a>    <span class='hs-varid'>sm_rep</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>chooseSMRep</span> <span class='hs-varid'>is_static</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkConLFInfo</span> <span class='hs-varid'>data_con</span><span class='hs-layout'>)</span> <span class='hs-varid'>tot_wds</span> <span class='hs-varid'>ptr_wds</span>
</pre>\end{code}

%************************************************************************
%*									*
\subsection[ClosureInfo-sizes]{Functions about closure {\em sizes}}
%*									*
%************************************************************************

\begin{code}
<pre><a name="line-1"></a><a name="closureSize"></a><span class='hs-definition'>closureSize</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>ClosureInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>WordOff</span>
<a name="line-2"></a><span class='hs-definition'>closureSize</span> <span class='hs-varid'>cl_info</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>hdr_size</span> <span class='hs-varop'>+</span> <span class='hs-varid'>closureNonHdrSize</span> <span class='hs-varid'>cl_info</span>
<a name="line-3"></a>  <span class='hs-keyword'>where</span> <span class='hs-varid'>hdr_size</span>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>closureIsThunk</span> <span class='hs-varid'>cl_info</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>thunkHdrSize</span>
<a name="line-4"></a>  		  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>      	   <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fixedHdrSize</span>
<a name="line-5"></a>	<span class='hs-comment'>-- All thunks use thunkHdrSize, even if they are non-updatable.</span>
<a name="line-6"></a>	<span class='hs-comment'>-- this is because we don't have separate closure types for</span>
<a name="line-7"></a>	<span class='hs-comment'>-- updatable vs. non-updatable thunks, so the GC can't tell the</span>
<a name="line-8"></a>	<span class='hs-comment'>-- difference.  If we ever have significant numbers of non-</span>
<a name="line-9"></a>	<span class='hs-comment'>-- updatable thunks, it might be worth fixing this.</span>
<a name="line-10"></a>
<a name="line-11"></a><a name="closureNonHdrSize"></a><span class='hs-definition'>closureNonHdrSize</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>ClosureInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>WordOff</span>
<a name="line-12"></a><span class='hs-definition'>closureNonHdrSize</span> <span class='hs-varid'>cl_info</span>
<a name="line-13"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>tot_wds</span> <span class='hs-varop'>+</span> <span class='hs-varid'>computeSlopSize</span> <span class='hs-varid'>tot_wds</span> <span class='hs-varid'>cl_info</span>
<a name="line-14"></a>  <span class='hs-keyword'>where</span>
<a name="line-15"></a>    <span class='hs-varid'>tot_wds</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>closureGoodStuffSize</span> <span class='hs-varid'>cl_info</span>
<a name="line-16"></a>
<a name="line-17"></a><a name="closureGoodStuffSize"></a><span class='hs-definition'>closureGoodStuffSize</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>ClosureInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>WordOff</span>
<a name="line-18"></a><span class='hs-definition'>closureGoodStuffSize</span> <span class='hs-varid'>cl_info</span>
<a name="line-19"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>let</span> <span class='hs-layout'>(</span><span class='hs-varid'>ptrs</span><span class='hs-layout'>,</span> <span class='hs-varid'>nonptrs</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>sizes_from_SMRep</span> <span class='hs-layout'>(</span><span class='hs-varid'>closureSMRep</span> <span class='hs-varid'>cl_info</span><span class='hs-layout'>)</span>
<a name="line-20"></a>    <span class='hs-keyword'>in</span>	<span class='hs-varid'>ptrs</span> <span class='hs-varop'>+</span> <span class='hs-varid'>nonptrs</span>
<a name="line-21"></a>
<a name="line-22"></a><a name="closurePtrsSize"></a><span class='hs-definition'>closurePtrsSize</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>ClosureInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>WordOff</span>
<a name="line-23"></a><span class='hs-definition'>closurePtrsSize</span> <span class='hs-varid'>cl_info</span>
<a name="line-24"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>let</span> <span class='hs-layout'>(</span><span class='hs-varid'>ptrs</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'>sizes_from_SMRep</span> <span class='hs-layout'>(</span><span class='hs-varid'>closureSMRep</span> <span class='hs-varid'>cl_info</span><span class='hs-layout'>)</span>
<a name="line-25"></a>    <span class='hs-keyword'>in</span>	<span class='hs-varid'>ptrs</span>
<a name="line-26"></a>
<a name="line-27"></a><a name="sizes_from_SMRep"></a><span class='hs-comment'>-- not exported:</span>
<a name="line-28"></a><span class='hs-definition'>sizes_from_SMRep</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>SMRep</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-conid'>WordOff</span><span class='hs-layout'>,</span><span class='hs-conid'>WordOff</span><span class='hs-layout'>)</span>
<a name="line-29"></a><span class='hs-definition'>sizes_from_SMRep</span> <span class='hs-layout'>(</span><span class='hs-conid'>GenericRep</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>ptrs</span> <span class='hs-varid'>nonptrs</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>   <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>ptrs</span><span class='hs-layout'>,</span> <span class='hs-varid'>nonptrs</span><span class='hs-layout'>)</span>
<a name="line-30"></a><span class='hs-definition'>sizes_from_SMRep</span> <span class='hs-conid'>BlackHoleRep</span>			 <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-num'>0</span><span class='hs-layout'>,</span> <span class='hs-num'>0</span><span class='hs-layout'>)</span>
</pre>\end{code}

Computing slop size.  WARNING: this looks dodgy --- it has deep
knowledge of what the storage manager does with the various
representations...

Slop Requirements: every thunk gets an extra padding word in the
header, which takes the the updated value.

\begin{code}
<pre><a name="line-1"></a><a name="slopSize"></a><span class='hs-definition'>slopSize</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>ClosureInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>WordOff</span>
<a name="line-2"></a><span class='hs-definition'>slopSize</span> <span class='hs-varid'>cl_info</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>computeSlopSize</span> <span class='hs-varid'>payload_size</span> <span class='hs-varid'>cl_info</span>
<a name="line-3"></a>  <span class='hs-keyword'>where</span> <span class='hs-varid'>payload_size</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>closureGoodStuffSize</span> <span class='hs-varid'>cl_info</span>
<a name="line-4"></a>
<a name="line-5"></a><a name="computeSlopSize"></a><span class='hs-definition'>computeSlopSize</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>WordOff</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>ClosureInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>WordOff</span>
<a name="line-6"></a><span class='hs-definition'>computeSlopSize</span> <span class='hs-varid'>payload_size</span> <span class='hs-varid'>cl_info</span>
<a name="line-7"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>max</span> <span class='hs-num'>0</span> <span class='hs-layout'>(</span><span class='hs-varid'>minPayloadSize</span> <span class='hs-varid'>smrep</span> <span class='hs-varid'>updatable</span> <span class='hs-comment'>-</span> <span class='hs-varid'>payload_size</span><span class='hs-layout'>)</span>
<a name="line-8"></a>  <span class='hs-keyword'>where</span>
<a name="line-9"></a>	<span class='hs-varid'>smrep</span>        <span class='hs-keyglyph'>=</span> <span class='hs-varid'>closureSMRep</span> <span class='hs-varid'>cl_info</span>
<a name="line-10"></a>	<span class='hs-varid'>updatable</span>    <span class='hs-keyglyph'>=</span> <span class='hs-varid'>closureNeedsUpdSpace</span> <span class='hs-varid'>cl_info</span>
<a name="line-11"></a>
<a name="line-12"></a><a name="closureNeedsUpdSpace"></a><span class='hs-comment'>-- we leave space for an update if either (a) the closure is updatable</span>
<a name="line-13"></a><span class='hs-comment'>-- or (b) it is a static thunk.  This is because a static thunk needs</span>
<a name="line-14"></a><span class='hs-comment'>-- a static link field in a predictable place (after the slop), regardless</span>
<a name="line-15"></a><span class='hs-comment'>-- of whether it is updatable or not.</span>
<a name="line-16"></a><span class='hs-definition'>closureNeedsUpdSpace</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>ClosureInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-17"></a><span class='hs-definition'>closureNeedsUpdSpace</span> <span class='hs-layout'>(</span><span class='hs-conid'>ClosureInfo</span> <span class='hs-layout'>{</span> <span class='hs-varid'>closureLFInfo</span> <span class='hs-keyglyph'>=</span> 
<a name="line-18"></a>					<span class='hs-conid'>LFThunk</span> <span class='hs-conid'>TopLevel</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-layout'>}</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-19"></a><span class='hs-definition'>closureNeedsUpdSpace</span> <span class='hs-varid'>cl_info</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>closureUpdReqd</span> <span class='hs-varid'>cl_info</span>
<a name="line-20"></a>
<a name="line-21"></a><a name="minPayloadSize"></a><span class='hs-definition'>minPayloadSize</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>SMRep</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>WordOff</span>
<a name="line-22"></a><span class='hs-definition'>minPayloadSize</span> <span class='hs-varid'>smrep</span> <span class='hs-varid'>updatable</span>
<a name="line-23"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>smrep</span> <span class='hs-keyword'>of</span>
<a name="line-24"></a>	<span class='hs-conid'>BlackHoleRep</span>		 		<span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>min_upd_size</span>
<a name="line-25"></a>	<span class='hs-conid'>GenericRep</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span>      <span class='hs-keyglyph'>|</span> <span class='hs-varid'>updatable</span>     <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>min_upd_size</span>
<a name="line-26"></a>	<span class='hs-conid'>GenericRep</span> <span class='hs-conid'>True</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span>                   <span class='hs-keyglyph'>-&gt;</span> <span class='hs-num'>0</span> <span class='hs-comment'>-- static</span>
<a name="line-27"></a>	<span class='hs-conid'>GenericRep</span> <span class='hs-conid'>False</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span>                  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>mIN_PAYLOAD_SIZE</span>
<a name="line-28"></a>          <span class='hs-comment'>--       ^^^^^___ dynamic</span>
<a name="line-29"></a>  <span class='hs-keyword'>where</span>
<a name="line-30"></a>   <span class='hs-varid'>min_upd_size</span> <span class='hs-keyglyph'>=</span>
<a name="line-31"></a>	<span class='hs-conid'>ASSERT</span><span class='hs-layout'>(</span><span class='hs-varid'>mIN_PAYLOAD_SIZE</span> <span class='hs-varop'>&lt;=</span> <span class='hs-varid'>sIZEOF_StgSMPThunkHeader</span><span class='hs-layout'>)</span>
<a name="line-32"></a>	<span class='hs-num'>0</span> 	<span class='hs-comment'>-- check that we already have enough</span>
<a name="line-33"></a>		<span class='hs-comment'>-- room for mIN_SIZE_NonUpdHeapObject,</span>
<a name="line-34"></a>		<span class='hs-comment'>-- due to the extra header word in SMP</span>
</pre>\end{code}

%************************************************************************
%*									*
\subsection[SMreps]{Choosing SM reps}
%*									*
%************************************************************************

\begin{code}
<pre><a name="line-1"></a><a name="chooseSMRep"></a><span class='hs-definition'>chooseSMRep</span>
<a name="line-2"></a>	<span class='hs-keyglyph'>::</span> <span class='hs-conid'>Bool</span>			<span class='hs-comment'>-- True &lt;=&gt; static closure</span>
<a name="line-3"></a>	<span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>LambdaFormInfo</span>
<a name="line-4"></a>	<span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>WordOff</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>WordOff</span>	<span class='hs-comment'>-- Tot wds, ptr wds</span>
<a name="line-5"></a>	<span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>SMRep</span>
<a name="line-6"></a>
<a name="line-7"></a><span class='hs-definition'>chooseSMRep</span> <span class='hs-varid'>is_static</span> <span class='hs-varid'>lf_info</span> <span class='hs-varid'>tot_wds</span> <span class='hs-varid'>ptr_wds</span>
<a name="line-8"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>let</span>
<a name="line-9"></a>	 <span class='hs-varid'>nonptr_wds</span>   <span class='hs-keyglyph'>=</span> <span class='hs-varid'>tot_wds</span> <span class='hs-comment'>-</span> <span class='hs-varid'>ptr_wds</span>
<a name="line-10"></a>	 <span class='hs-varid'>closure_type</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>getClosureType</span> <span class='hs-varid'>is_static</span> <span class='hs-varid'>ptr_wds</span> <span class='hs-varid'>lf_info</span>
<a name="line-11"></a>    <span class='hs-keyword'>in</span>
<a name="line-12"></a>    <span class='hs-conid'>GenericRep</span> <span class='hs-varid'>is_static</span> <span class='hs-varid'>ptr_wds</span> <span class='hs-varid'>nonptr_wds</span> <span class='hs-varid'>closure_type</span>	
<a name="line-13"></a>
<a name="line-14"></a><span class='hs-comment'>-- We *do* get non-updatable top-level thunks sometimes.  eg. f = g</span>
<a name="line-15"></a><span class='hs-comment'>-- gets compiled to a jump to g (if g has non-zero arity), instead of</span>
<a name="line-16"></a><span class='hs-comment'>-- messing around with update frames and PAPs.  We set the closure type</span>
<a name="line-17"></a><span class='hs-comment'>-- to FUN_STATIC in this case.</span>
<a name="line-18"></a>
<a name="line-19"></a><a name="getClosureType"></a><span class='hs-definition'>getClosureType</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Bool</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>WordOff</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>LambdaFormInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>ClosureType</span>
<a name="line-20"></a><span class='hs-definition'>getClosureType</span> <span class='hs-varid'>is_static</span> <span class='hs-varid'>ptr_wds</span> <span class='hs-varid'>lf_info</span>
<a name="line-21"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>lf_info</span> <span class='hs-keyword'>of</span>
<a name="line-22"></a>	<span class='hs-conid'>LFCon</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>is_static</span> <span class='hs-varop'>&amp;&amp;</span> <span class='hs-varid'>ptr_wds</span> <span class='hs-varop'>==</span> <span class='hs-num'>0</span>	<span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>ConstrNoCaf</span>
<a name="line-23"></a>		  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>			<span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Constr</span>
<a name="line-24"></a>  	<span class='hs-conid'>LFReEntrant</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> 			<span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Fun</span>
<a name="line-25"></a>	<span class='hs-conid'>LFThunk</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-layout'>(</span><span class='hs-conid'>SelectorThunk</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyword'>_</span> 	<span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>ThunkSelector</span>
<a name="line-26"></a>	<span class='hs-conid'>LFThunk</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> 			<span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Thunk</span>
<a name="line-27"></a>	<span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>panic</span> <span class='hs-str'>"getClosureType"</span>
</pre>\end{code}

%************************************************************************
%*									*
\subsection[ClosureInfo-4-questions]{Four major questions about @ClosureInfo@}
%*									*
%************************************************************************

Be sure to see the stg-details notes about these...

\begin{code}
<pre><a name="line-1"></a><a name="nodeMustPointToIt"></a><span class='hs-definition'>nodeMustPointToIt</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>LambdaFormInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-2"></a><span class='hs-definition'>nodeMustPointToIt</span> <span class='hs-layout'>(</span><span class='hs-conid'>LFReEntrant</span> <span class='hs-varid'>top</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>no_fvs</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>
<a name="line-3"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>not</span> <span class='hs-varid'>no_fvs</span> <span class='hs-varop'>||</span>   <span class='hs-comment'>-- Certainly if it has fvs we need to point to it</span>
<a name="line-4"></a>    <span class='hs-varid'>isNotTopLevel</span> <span class='hs-varid'>top</span>
<a name="line-5"></a>		    <span class='hs-comment'>-- If it is not top level we will point to it</span>
<a name="line-6"></a>		    <span class='hs-comment'>--   We can have a \r closure with no_fvs which</span>
<a name="line-7"></a>		    <span class='hs-comment'>--   is not top level as special case cgRhsClosure</span>
<a name="line-8"></a>		    <span class='hs-comment'>--   has been dissabled in favour of let floating</span>
<a name="line-9"></a>
<a name="line-10"></a>		<span class='hs-comment'>-- For lex_profiling we also access the cost centre for a</span>
<a name="line-11"></a>		<span class='hs-comment'>-- non-inherited function i.e. not top level</span>
<a name="line-12"></a>		<span class='hs-comment'>-- the  not top  case above ensures this is ok.</span>
<a name="line-13"></a>
<a name="line-14"></a><span class='hs-definition'>nodeMustPointToIt</span> <span class='hs-layout'>(</span><span class='hs-conid'>LFCon</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-15"></a>
<a name="line-16"></a>	<span class='hs-comment'>-- Strictly speaking, the above two don't need Node to point</span>
<a name="line-17"></a>	<span class='hs-comment'>-- to it if the arity = 0.  But this is a *really* unlikely</span>
<a name="line-18"></a>	<span class='hs-comment'>-- situation.  If we know it's nil (say) and we are entering</span>
<a name="line-19"></a>	<span class='hs-comment'>-- it. Eg: let x = [] in x then we will certainly have inlined</span>
<a name="line-20"></a>	<span class='hs-comment'>-- x, since nil is a simple atom.  So we gain little by not</span>
<a name="line-21"></a>	<span class='hs-comment'>-- having Node point to known zero-arity things.  On the other</span>
<a name="line-22"></a>	<span class='hs-comment'>-- hand, we do lose something; Patrick's code for figuring out</span>
<a name="line-23"></a>	<span class='hs-comment'>-- when something has been updated but not entered relies on</span>
<a name="line-24"></a>	<span class='hs-comment'>-- having Node point to the result of an update.  SLPJ</span>
<a name="line-25"></a>	<span class='hs-comment'>-- 27/11/92.</span>
<a name="line-26"></a>
<a name="line-27"></a><span class='hs-definition'>nodeMustPointToIt</span> <span class='hs-layout'>(</span><span class='hs-conid'>LFThunk</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>no_fvs</span> <span class='hs-varid'>updatable</span> <span class='hs-conid'>NonStandardThunk</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>
<a name="line-28"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>updatable</span> <span class='hs-varop'>||</span> <span class='hs-varid'>not</span> <span class='hs-varid'>no_fvs</span> <span class='hs-varop'>||</span> <span class='hs-varid'>opt_SccProfilingOn</span>
<a name="line-29"></a>	  <span class='hs-comment'>-- For the non-updatable (single-entry case):</span>
<a name="line-30"></a>	  <span class='hs-comment'>--</span>
<a name="line-31"></a>	  <span class='hs-comment'>-- True if has fvs (in which case we need access to them, and we</span>
<a name="line-32"></a>	  <span class='hs-comment'>--		    should black-hole it)</span>
<a name="line-33"></a>	  <span class='hs-comment'>-- or profiling (in which case we need to recover the cost centre</span>
<a name="line-34"></a>	  <span class='hs-comment'>--		 from inside it)</span>
<a name="line-35"></a>
<a name="line-36"></a><span class='hs-definition'>nodeMustPointToIt</span> <span class='hs-layout'>(</span><span class='hs-conid'>LFThunk</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>
<a name="line-37"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>  <span class='hs-comment'>-- Node must point to any standard-form thunk</span>
<a name="line-38"></a>
<a name="line-39"></a><span class='hs-definition'>nodeMustPointToIt</span> <span class='hs-layout'>(</span><span class='hs-conid'>LFUnknown</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>     <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-40"></a><span class='hs-definition'>nodeMustPointToIt</span> <span class='hs-layout'>(</span><span class='hs-conid'>LFBlackHole</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>   <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>    <span class='hs-comment'>-- BH entry may require Node to point</span>
<a name="line-41"></a><span class='hs-definition'>nodeMustPointToIt</span> <span class='hs-layout'>(</span><span class='hs-conid'>LFLetNoEscape</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span> 
</pre>\end{code}

The entry conventions depend on the type of closure being entered,
whether or not it has free variables, and whether we're running
sequentially or in parallel.

\begin{tabular}{lllll}
Closure Characteristics & Parallel & Node Req'd & Argument Passing & Enter Via \\
Unknown 			& no & yes & stack	& node \\
Known fun ($\ge$ 1 arg), no fvs 	& no & no  & registers 	& fast entry (enough args) \\
\ & \ & \ & \ 						& slow entry (otherwise) \\
Known fun ($\ge$ 1 arg), fvs	& no & yes & registers 	& fast entry (enough args) \\
0 arg, no fvs @\r,\s@ 		& no & no  & n/a 	& direct entry \\
0 arg, no fvs @\u@ 		& no & yes & n/a 	& node \\
0 arg, fvs @\r,\s@ 		& no & yes & n/a 	& direct entry \\
0 arg, fvs @\u@ 		& no & yes & n/a 	& node \\

Unknown 			& yes & yes & stack	& node \\
Known fun ($\ge$ 1 arg), no fvs 	& yes & no  & registers & fast entry (enough args) \\
\ & \ & \ & \ 						& slow entry (otherwise) \\
Known fun ($\ge$ 1 arg), fvs	& yes & yes & registers & node \\
0 arg, no fvs @\r,\s@ 		& yes & no  & n/a 	& direct entry \\
0 arg, no fvs @\u@ 		& yes & yes & n/a 	& node \\
0 arg, fvs @\r,\s@ 		& yes & yes & n/a 	& node \\
0 arg, fvs @\u@ 		& yes & yes & n/a 	& node\\
\end{tabular}

When black-holing, single-entry closures could also be entered via node
(rather than directly) to catch double-entry.

\begin{code}
<pre><a name="line-1"></a><a name="CallMethod"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>CallMethod</span>
<a name="line-2"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>EnterIt</span>				<span class='hs-comment'>-- no args, not a function</span>
<a name="line-3"></a>
<a name="line-4"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>JumpToIt</span> <span class='hs-conid'>CLabel</span>			<span class='hs-comment'>-- no args, not a function, but we</span>
<a name="line-5"></a>					<span class='hs-comment'>-- know what its entry code is</span>
<a name="line-6"></a>
<a name="line-7"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>ReturnIt</span>				<span class='hs-comment'>-- it's a function, but we have</span>
<a name="line-8"></a>					<span class='hs-comment'>-- zero args to apply to it, so just</span>
<a name="line-9"></a>					<span class='hs-comment'>-- return it.</span>
<a name="line-10"></a>
<a name="line-11"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>ReturnCon</span> <span class='hs-conid'>DataCon</span>			<span class='hs-comment'>-- It's a data constructor, just return it</span>
<a name="line-12"></a>
<a name="line-13"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>SlowCall</span>				<span class='hs-comment'>-- Unknown fun, or known fun with</span>
<a name="line-14"></a>					<span class='hs-comment'>-- too few args.</span>
<a name="line-15"></a>
<a name="line-16"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>DirectEntry</span> 			<span class='hs-comment'>-- Jump directly, with args in regs</span>
<a name="line-17"></a>	<span class='hs-conid'>CLabel</span> 				<span class='hs-comment'>--   The code label</span>
<a name="line-18"></a>	<span class='hs-conid'>Int</span> 				<span class='hs-comment'>--   Its arity</span>
<a name="line-19"></a>
<a name="line-20"></a><a name="getCallMethod"></a><span class='hs-definition'>getCallMethod</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>DynFlags</span>
<a name="line-21"></a>              <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Name</span>		<span class='hs-comment'>-- Function being applied</span>
<a name="line-22"></a>              <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CafInfo</span>        <span class='hs-comment'>-- Can it refer to CAF's?</span>
<a name="line-23"></a>	      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>LambdaFormInfo</span>	<span class='hs-comment'>-- Its info</span>
<a name="line-24"></a>	      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span>		<span class='hs-comment'>-- Number of available arguments</span>
<a name="line-25"></a>	      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CallMethod</span>
<a name="line-26"></a>
<a name="line-27"></a><span class='hs-definition'>getCallMethod</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>lf_info</span> <span class='hs-keyword'>_</span>
<a name="line-28"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>nodeMustPointToIt</span> <span class='hs-varid'>lf_info</span> <span class='hs-varop'>&amp;&amp;</span> <span class='hs-varid'>opt_Parallel</span>
<a name="line-29"></a>  <span class='hs-keyglyph'>=</span>	<span class='hs-comment'>-- If we're parallel, then we must always enter via node.  </span>
<a name="line-30"></a>	<span class='hs-comment'>-- The reason is that the closure may have been 	</span>
<a name="line-31"></a>	<span class='hs-comment'>-- fetched since we allocated it.</span>
<a name="line-32"></a>    <span class='hs-conid'>EnterIt</span>
<a name="line-33"></a>
<a name="line-34"></a><span class='hs-definition'>getCallMethod</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>name</span> <span class='hs-varid'>caf</span> <span class='hs-layout'>(</span><span class='hs-conid'>LFReEntrant</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>arity</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-varid'>n_args</span>
<a name="line-35"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>n_args</span> <span class='hs-varop'>==</span> <span class='hs-num'>0</span>    <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ASSERT</span><span class='hs-layout'>(</span> <span class='hs-varid'>arity</span> <span class='hs-varop'>/=</span> <span class='hs-num'>0</span> <span class='hs-layout'>)</span>
<a name="line-36"></a>		     <span class='hs-conid'>ReturnIt</span>	<span class='hs-comment'>-- No args at all</span>
<a name="line-37"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>n_args</span> <span class='hs-varop'>&lt;</span> <span class='hs-varid'>arity</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>SlowCall</span>	<span class='hs-comment'>-- Not enough args</span>
<a name="line-38"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>      <span class='hs-keyglyph'>=</span> <span class='hs-conid'>DirectEntry</span> <span class='hs-layout'>(</span><span class='hs-varid'>enterIdLabel</span> <span class='hs-varid'>name</span> <span class='hs-varid'>caf</span><span class='hs-layout'>)</span> <span class='hs-varid'>arity</span>
<a name="line-39"></a>
<a name="line-40"></a><span class='hs-definition'>getCallMethod</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-layout'>(</span><span class='hs-conid'>LFCon</span> <span class='hs-varid'>con</span><span class='hs-layout'>)</span> <span class='hs-varid'>n_args</span>
<a name="line-41"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>opt_SccProfilingOn</span>     <span class='hs-comment'>-- when profiling, we must always enter</span>
<a name="line-42"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>EnterIt</span>                <span class='hs-comment'>-- a closure when we use it, so that the closure</span>
<a name="line-43"></a>                           <span class='hs-comment'>-- can be recorded as used for LDV profiling.</span>
<a name="line-44"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>
<a name="line-45"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ASSERT</span><span class='hs-layout'>(</span> <span class='hs-varid'>n_args</span> <span class='hs-varop'>==</span> <span class='hs-num'>0</span> <span class='hs-layout'>)</span>
<a name="line-46"></a>    <span class='hs-conid'>ReturnCon</span> <span class='hs-varid'>con</span>
<a name="line-47"></a>
<a name="line-48"></a><span class='hs-definition'>getCallMethod</span> <span class='hs-varid'>dflags</span> <span class='hs-varid'>name</span> <span class='hs-varid'>caf</span> <span class='hs-layout'>(</span><span class='hs-conid'>LFThunk</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>updatable</span> <span class='hs-varid'>std_form_info</span> <span class='hs-varid'>is_fun</span><span class='hs-layout'>)</span> <span class='hs-varid'>n_args</span>
<a name="line-49"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>is_fun</span> 	<span class='hs-comment'>-- it *might* be a function, so we must "call" it (which is</span>
<a name="line-50"></a>                <span class='hs-comment'>-- always safe)</span>
<a name="line-51"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>SlowCall</span>	<span class='hs-comment'>-- We cannot just enter it [in eval/apply, the entry code</span>
<a name="line-52"></a>		<span class='hs-comment'>-- is the fast-entry code]</span>
<a name="line-53"></a>
<a name="line-54"></a>  <span class='hs-comment'>-- Since is_fun is False, we are *definitely* looking at a data value</span>
<a name="line-55"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>updatable</span> <span class='hs-varop'>||</span> <span class='hs-varid'>doingTickyProfiling</span> <span class='hs-varid'>dflags</span> <span class='hs-comment'>-- to catch double entry</span>
<a name="line-56"></a>      <span class='hs-comment'>{- OLD: || opt_SMP
<a name="line-57"></a>	 I decided to remove this, because in SMP mode it doesn't matter
<a name="line-58"></a>	 if we enter the same thunk multiple times, so the optimisation
<a name="line-59"></a>	 of jumping directly to the entry code is still valid.  --SDM
<a name="line-60"></a>	-}</span>
<a name="line-61"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>EnterIt</span>
<a name="line-62"></a>    <span class='hs-comment'>-- We used to have ASSERT( n_args == 0 ), but actually it is</span>
<a name="line-63"></a>    <span class='hs-comment'>-- possible for the optimiser to generate</span>
<a name="line-64"></a>    <span class='hs-comment'>--   let bot :: Int = error Int "urk"</span>
<a name="line-65"></a>    <span class='hs-comment'>--   in (bot `cast` unsafeCoerce Int (Int -&gt; Int)) 3</span>
<a name="line-66"></a>    <span class='hs-comment'>-- This happens as a result of the case-of-error transformation</span>
<a name="line-67"></a>    <span class='hs-comment'>-- So the right thing to do is just to enter the thing</span>
<a name="line-68"></a>
<a name="line-69"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>	<span class='hs-comment'>-- Jump direct to code for single-entry thunks</span>
<a name="line-70"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ASSERT</span><span class='hs-layout'>(</span> <span class='hs-varid'>n_args</span> <span class='hs-varop'>==</span> <span class='hs-num'>0</span> <span class='hs-layout'>)</span>
<a name="line-71"></a>    <span class='hs-conid'>JumpToIt</span> <span class='hs-layout'>(</span><span class='hs-varid'>thunkEntryLabel</span> <span class='hs-varid'>name</span> <span class='hs-varid'>caf</span> <span class='hs-varid'>std_form_info</span> <span class='hs-varid'>updatable</span><span class='hs-layout'>)</span>
<a name="line-72"></a>
<a name="line-73"></a><span class='hs-definition'>getCallMethod</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-layout'>(</span><span class='hs-conid'>LFUnknown</span> <span class='hs-conid'>True</span><span class='hs-layout'>)</span> <span class='hs-keyword'>_</span>
<a name="line-74"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>SlowCall</span> <span class='hs-comment'>-- Might be a function</span>
<a name="line-75"></a>
<a name="line-76"></a><span class='hs-definition'>getCallMethod</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>name</span> <span class='hs-keyword'>_</span> <span class='hs-layout'>(</span><span class='hs-conid'>LFUnknown</span> <span class='hs-conid'>False</span><span class='hs-layout'>)</span> <span class='hs-varid'>n_args</span>
<a name="line-77"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>n_args</span> <span class='hs-varop'>&gt;</span> <span class='hs-num'>0</span> 
<a name="line-78"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>WARN</span><span class='hs-layout'>(</span> <span class='hs-conid'>True</span><span class='hs-layout'>,</span> <span class='hs-varid'>ppr</span> <span class='hs-varid'>name</span> <span class='hs-varop'>&lt;+&gt;</span> <span class='hs-varid'>ppr</span> <span class='hs-varid'>n_args</span> <span class='hs-layout'>)</span> 
<a name="line-79"></a>    <span class='hs-conid'>SlowCall</span>	<span class='hs-comment'>-- Note [Unsafe coerce complications]</span>
<a name="line-80"></a>
<a name="line-81"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>
<a name="line-82"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>EnterIt</span> <span class='hs-comment'>-- Not a function</span>
<a name="line-83"></a>
<a name="line-84"></a><span class='hs-definition'>getCallMethod</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-layout'>(</span><span class='hs-conid'>LFBlackHole</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyword'>_</span>
<a name="line-85"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>SlowCall</span>	<span class='hs-comment'>-- Presumably the black hole has by now</span>
<a name="line-86"></a>		<span class='hs-comment'>-- been updated, but we don't know with</span>
<a name="line-87"></a>		<span class='hs-comment'>-- what, so we slow call it</span>
<a name="line-88"></a>
<a name="line-89"></a><span class='hs-definition'>getCallMethod</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>name</span> <span class='hs-keyword'>_</span> <span class='hs-layout'>(</span><span class='hs-conid'>LFLetNoEscape</span> <span class='hs-num'>0</span><span class='hs-layout'>)</span> <span class='hs-keyword'>_</span>
<a name="line-90"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>JumpToIt</span> <span class='hs-layout'>(</span><span class='hs-varid'>enterReturnPtLabel</span> <span class='hs-layout'>(</span><span class='hs-varid'>nameUnique</span> <span class='hs-varid'>name</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-91"></a>
<a name="line-92"></a><span class='hs-definition'>getCallMethod</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>name</span> <span class='hs-keyword'>_</span> <span class='hs-layout'>(</span><span class='hs-conid'>LFLetNoEscape</span> <span class='hs-varid'>arity</span><span class='hs-layout'>)</span> <span class='hs-varid'>n_args</span>
<a name="line-93"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>n_args</span> <span class='hs-varop'>==</span> <span class='hs-varid'>arity</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>DirectEntry</span> <span class='hs-layout'>(</span><span class='hs-varid'>enterReturnPtLabel</span> <span class='hs-layout'>(</span><span class='hs-varid'>nameUnique</span> <span class='hs-varid'>name</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>arity</span>
<a name="line-94"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>pprPanic</span> <span class='hs-str'>"let-no-escape: "</span> <span class='hs-layout'>(</span><span class='hs-varid'>ppr</span> <span class='hs-varid'>name</span> <span class='hs-varop'>&lt;+&gt;</span> <span class='hs-varid'>ppr</span> <span class='hs-varid'>arity</span><span class='hs-layout'>)</span>
<a name="line-95"></a>
<a name="line-96"></a><a name="blackHoleOnEntry"></a><span class='hs-definition'>blackHoleOnEntry</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>DynFlags</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>ClosureInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-97"></a><span class='hs-comment'>-- Static closures are never themselves black-holed.</span>
<a name="line-98"></a><span class='hs-comment'>-- Updatable ones will be overwritten with a CAFList cell, which points to a </span>
<a name="line-99"></a><span class='hs-comment'>-- black hole;</span>
<a name="line-100"></a><span class='hs-comment'>-- Single-entry ones have no fvs to plug, and we trust they don't form part </span>
<a name="line-101"></a><span class='hs-comment'>-- of a loop.</span>
<a name="line-102"></a>
<a name="line-103"></a><span class='hs-definition'>blackHoleOnEntry</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>ConInfo</span><span class='hs-layout'>{</span><span class='hs-layout'>}</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
<a name="line-104"></a><span class='hs-definition'>blackHoleOnEntry</span> <span class='hs-varid'>dflags</span> <span class='hs-layout'>(</span><span class='hs-conid'>ClosureInfo</span> <span class='hs-layout'>{</span> <span class='hs-varid'>closureLFInfo</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>lf_info</span><span class='hs-layout'>,</span> <span class='hs-varid'>closureSMRep</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>rep</span> <span class='hs-layout'>}</span><span class='hs-layout'>)</span>
<a name="line-105"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>isStaticRep</span> <span class='hs-varid'>rep</span>
<a name="line-106"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>	<span class='hs-comment'>-- Never black-hole a static closure</span>
<a name="line-107"></a>
<a name="line-108"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>
<a name="line-109"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>lf_info</span> <span class='hs-keyword'>of</span>
<a name="line-110"></a>	<span class='hs-conid'>LFReEntrant</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span>	  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>False</span>
<a name="line-111"></a>	<span class='hs-conid'>LFLetNoEscape</span> <span class='hs-keyword'>_</span>		  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>False</span>
<a name="line-112"></a>	<span class='hs-conid'>LFThunk</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>no_fvs</span> <span class='hs-varid'>updatable</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span>
<a name="line-113"></a>	  <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>if</span> <span class='hs-varid'>updatable</span>
<a name="line-114"></a>	     <span class='hs-keyword'>then</span> <span class='hs-varid'>not</span> <span class='hs-varid'>opt_OmitBlackHoling</span>
<a name="line-115"></a>	     <span class='hs-keyword'>else</span> <span class='hs-varid'>doingTickyProfiling</span> <span class='hs-varid'>dflags</span> <span class='hs-varop'>||</span> <span class='hs-varid'>not</span> <span class='hs-varid'>no_fvs</span>
<a name="line-116"></a>                  <span class='hs-comment'>-- the former to catch double entry,</span>
<a name="line-117"></a>                  <span class='hs-comment'>-- and the latter to plug space-leaks.  KSW/SDM 1999-04.</span>
<a name="line-118"></a>
<a name="line-119"></a>	<span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>panic</span> <span class='hs-str'>"blackHoleOnEntry"</span>	<span class='hs-comment'>-- Should never happen</span>
<a name="line-120"></a>
<a name="line-121"></a><a name="isStandardFormThunk"></a><span class='hs-definition'>isStandardFormThunk</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>LambdaFormInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-122"></a><span class='hs-definition'>isStandardFormThunk</span> <span class='hs-layout'>(</span><span class='hs-conid'>LFThunk</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-layout'>(</span><span class='hs-conid'>SelectorThunk</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-123"></a><span class='hs-definition'>isStandardFormThunk</span> <span class='hs-layout'>(</span><span class='hs-conid'>LFThunk</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-layout'>(</span><span class='hs-conid'>ApThunk</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>	<span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-124"></a><span class='hs-definition'>isStandardFormThunk</span> <span class='hs-keyword'>_</span> 			<span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
<a name="line-125"></a>
<a name="line-126"></a><a name="isKnownFun"></a><span class='hs-definition'>isKnownFun</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>LambdaFormInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-127"></a><span class='hs-definition'>isKnownFun</span> <span class='hs-layout'>(</span><span class='hs-conid'>LFReEntrant</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-128"></a><span class='hs-definition'>isKnownFun</span> <span class='hs-layout'>(</span><span class='hs-conid'>LFLetNoEscape</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-129"></a><span class='hs-definition'>isKnownFun</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
</pre>\end{code}

Note [Unsafe coerce complications]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In some (badly-optimised) DPH code we see this
   Module X:    rr :: Int = error Int "Urk"
   Module Y:    ...((X.rr |> g) True) ...
     where g is an (unsafe) coercion of kind (Int ~ Bool->Bool), say

It's badly optimised, because knowing that 'X.rr' is bottom, we should
have dumped the application to True.  But it should still work. These
strange unsafe coercions arise from the case-of-error transformation:
	(case (error Int "foo") of { ... }) True
--->	(error Int "foo" |> g) True

Anyway, the net effect is that in STG-land, when casts are discarded,
we *can* see a value of type Int applied to an argument.  This only happens
if (a) the programmer made a mistake, or (b) the value of type Int is
actually bottom.

So it's wrong to trigger an ASSERT failure in this circumstance.  Instead
we now emit a WARN -- mainly to draw attention to a probably-badly-optimised
program fragment -- and do the conservative thing which is SlowCall.


-----------------------------------------------------------------------------
SRT-related stuff

\begin{code}
<pre><a name="line-1"></a><a name="staticClosureNeedsLink"></a><span class='hs-definition'>staticClosureNeedsLink</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>ClosureInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-2"></a><span class='hs-comment'>-- A static closure needs a link field to aid the GC when traversing</span>
<a name="line-3"></a><span class='hs-comment'>-- the static closure graph.  But it only needs such a field if either</span>
<a name="line-4"></a><span class='hs-comment'>-- 	a) it has an SRT</span>
<a name="line-5"></a><span class='hs-comment'>--	b) it's a constructor with one or more pointer fields</span>
<a name="line-6"></a><span class='hs-comment'>-- In case (b), the constructor's fields themselves play the role</span>
<a name="line-7"></a><span class='hs-comment'>-- of the SRT.</span>
<a name="line-8"></a><span class='hs-definition'>staticClosureNeedsLink</span> <span class='hs-layout'>(</span><span class='hs-conid'>ClosureInfo</span> <span class='hs-layout'>{</span> <span class='hs-varid'>closureSRT</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>srt</span> <span class='hs-layout'>}</span><span class='hs-layout'>)</span>
<a name="line-9"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>needsSRT</span> <span class='hs-varid'>srt</span>
<a name="line-10"></a><span class='hs-definition'>staticClosureNeedsLink</span> <span class='hs-layout'>(</span><span class='hs-conid'>ConInfo</span> <span class='hs-layout'>{</span> <span class='hs-varid'>closureSMRep</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>sm_rep</span><span class='hs-layout'>,</span> <span class='hs-varid'>closureCon</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>con</span> <span class='hs-layout'>}</span><span class='hs-layout'>)</span>
<a name="line-11"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>not</span> <span class='hs-layout'>(</span><span class='hs-varid'>isNullaryRepDataCon</span> <span class='hs-varid'>con</span><span class='hs-layout'>)</span> <span class='hs-varop'>&amp;&amp;</span> <span class='hs-varid'>not_nocaf_constr</span>
<a name="line-12"></a>  <span class='hs-keyword'>where</span>
<a name="line-13"></a>    <span class='hs-varid'>not_nocaf_constr</span> <span class='hs-keyglyph'>=</span> 
<a name="line-14"></a>	<span class='hs-keyword'>case</span> <span class='hs-varid'>sm_rep</span> <span class='hs-keyword'>of</span> 
<a name="line-15"></a>	   <span class='hs-conid'>GenericRep</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-conid'>ConstrNoCaf</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>False</span>
<a name="line-16"></a>	   <span class='hs-sel'>_other</span>			<span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>True</span>
</pre>\end{code}

Note [Entering error thunks]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Consider this

	fail :: Int
	fail = error Int "Urk"

	foo :: Bool -> Bool 
	foo True  y = (fail `cast` Bool -> Bool) y
	foo False y = False

This looks silly, but it can arise from case-of-error.  Even if it
does, we'd usually see that 'fail' is a bottoming function and would
discard the extra argument 'y'.  But even if that does not occur,
this program is still OK.  We will enter 'fail', which never returns.

The WARN is just to alert me to the fact that we aren't spotting that
'fail' is bottoming.

(We are careful never to make a funtion value look like a data type,
because we can't enter a function closure -- but that is not the 
problem here.)


Avoiding generating entries and info tables
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
At present, for every function we generate all of the following,
just in case.  But they aren't always all needed, as noted below:

[NB1: all of this applies only to *functions*.  Thunks always
have closure, info table, and entry code.]

[NB2: All are needed if the function is *exported*, just to play safe.]


* Fast-entry code  ALWAYS NEEDED

* Slow-entry code
	Needed iff (a) we have any un-saturated calls to the function
	OR	   (b) the function is passed as an arg
	OR	   (c) we're in the parallel world and the function has free vars
			[Reason: in parallel world, we always enter functions
			with free vars via the closure.]

* The function closure
	Needed iff (a) we have any un-saturated calls to the function
	OR	   (b) the function is passed as an arg
	OR	   (c) if the function has free vars (ie not top level)

  Why case (a) here?  Because if the arg-satis check fails,
  UpdatePAP stuffs a pointer to the function closure in the PAP.
  [Could be changed; UpdatePAP could stuff in a code ptr instead,
   but doesn't seem worth it.]

  [NB: these conditions imply that we might need the closure
  without the slow-entry code.  Here's how.

	f x y = let g w = ...x..y..w...
		in
		...(g t)...

  Here we need a closure for g which contains x and y,
  but since the calls are all saturated we just jump to the
  fast entry point for g, with R1 pointing to the closure for g.]


* Standard info table
	Needed iff (a) we have any un-saturated calls to the function
	OR	   (b) the function is passed as an arg
	OR 	   (c) the function has free vars (ie not top level)

	NB.  In the sequential world, (c) is only required so that the function closure has
	an info table to point to, to keep the storage manager happy.
	If (c) alone is true we could fake up an info table by choosing
	one of a standard family of info tables, whose entry code just
	bombs out.

	[NB In the parallel world (c) is needed regardless because
	we enter functions with free vars via the closure.]

	If (c) is retained, then we'll sometimes generate an info table
	(for storage mgr purposes) without slow-entry code.  Then we need
	to use an error label in the info table to substitute for the absent
	slow entry code.

\begin{code}
<pre><a name="line-1"></a><a name="staticClosureRequired"></a><span class='hs-definition'>staticClosureRequired</span>
<a name="line-2"></a>	<span class='hs-keyglyph'>::</span> <span class='hs-conid'>Name</span>
<a name="line-3"></a>	<span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StgBinderInfo</span>
<a name="line-4"></a>	<span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>LambdaFormInfo</span>
<a name="line-5"></a>	<span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-6"></a><span class='hs-definition'>staticClosureRequired</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>bndr_info</span>
<a name="line-7"></a>		      <span class='hs-layout'>(</span><span class='hs-conid'>LFReEntrant</span> <span class='hs-varid'>top_level</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>	<span class='hs-comment'>-- It's a function</span>
<a name="line-8"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ASSERT</span><span class='hs-layout'>(</span> <span class='hs-varid'>isTopLevel</span> <span class='hs-varid'>top_level</span> <span class='hs-layout'>)</span>
<a name="line-9"></a>	<span class='hs-comment'>-- Assumption: it's a top-level, no-free-var binding</span>
<a name="line-10"></a>	<span class='hs-varid'>not</span> <span class='hs-layout'>(</span><span class='hs-varid'>satCallsOnly</span> <span class='hs-varid'>bndr_info</span><span class='hs-layout'>)</span>
<a name="line-11"></a>
<a name="line-12"></a><span class='hs-definition'>staticClosureRequired</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
</pre>\end{code}

%************************************************************************
%*									*
\subsection[ClosureInfo-misc-funs]{Misc functions about @ClosureInfo@, etc.}
%*									*
%************************************************************************

\begin{code}
<pre><a name="line-1"></a>
<a name="line-2"></a><a name="isStaticClosure"></a><span class='hs-definition'>isStaticClosure</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>ClosureInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-3"></a><span class='hs-definition'>isStaticClosure</span> <span class='hs-varid'>cl_info</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>isStaticRep</span> <span class='hs-layout'>(</span><span class='hs-varid'>closureSMRep</span> <span class='hs-varid'>cl_info</span><span class='hs-layout'>)</span>
<a name="line-4"></a>
<a name="line-5"></a><a name="closureUpdReqd"></a><span class='hs-definition'>closureUpdReqd</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>ClosureInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-6"></a><span class='hs-definition'>closureUpdReqd</span> <span class='hs-conid'>ClosureInfo</span><span class='hs-layout'>{</span> <span class='hs-varid'>closureLFInfo</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>lf_info</span> <span class='hs-layout'>}</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>lfUpdatable</span> <span class='hs-varid'>lf_info</span>
<a name="line-7"></a><span class='hs-definition'>closureUpdReqd</span> <span class='hs-conid'>ConInfo</span><span class='hs-layout'>{</span><span class='hs-layout'>}</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
<a name="line-8"></a>
<a name="line-9"></a><a name="lfUpdatable"></a><span class='hs-definition'>lfUpdatable</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>LambdaFormInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-10"></a><span class='hs-definition'>lfUpdatable</span> <span class='hs-layout'>(</span><span class='hs-conid'>LFThunk</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>upd</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>upd</span>
<a name="line-11"></a><span class='hs-definition'>lfUpdatable</span> <span class='hs-layout'>(</span><span class='hs-conid'>LFBlackHole</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>	   <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-12"></a>	<span class='hs-comment'>-- Black-hole closures are allocated to receive the results of an</span>
<a name="line-13"></a>	<span class='hs-comment'>-- alg case with a named default... so they need to be updated.</span>
<a name="line-14"></a><span class='hs-definition'>lfUpdatable</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
<a name="line-15"></a>
<a name="line-16"></a><a name="closureIsThunk"></a><span class='hs-definition'>closureIsThunk</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>ClosureInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-17"></a><span class='hs-definition'>closureIsThunk</span> <span class='hs-conid'>ClosureInfo</span><span class='hs-layout'>{</span> <span class='hs-varid'>closureLFInfo</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>lf_info</span> <span class='hs-layout'>}</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>isLFThunk</span> <span class='hs-varid'>lf_info</span>
<a name="line-18"></a><span class='hs-definition'>closureIsThunk</span> <span class='hs-conid'>ConInfo</span><span class='hs-layout'>{</span><span class='hs-layout'>}</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
<a name="line-19"></a>
<a name="line-20"></a><a name="closureSingleEntry"></a><span class='hs-definition'>closureSingleEntry</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>ClosureInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-21"></a><span class='hs-definition'>closureSingleEntry</span> <span class='hs-layout'>(</span><span class='hs-conid'>ClosureInfo</span> <span class='hs-layout'>{</span> <span class='hs-varid'>closureLFInfo</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>LFThunk</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>upd</span> <span class='hs-keyword'>_</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'>not</span> <span class='hs-varid'>upd</span>
<a name="line-22"></a><span class='hs-definition'>closureSingleEntry</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
<a name="line-23"></a>
<a name="line-24"></a><a name="closureReEntrant"></a><span class='hs-definition'>closureReEntrant</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>ClosureInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-25"></a><span class='hs-definition'>closureReEntrant</span> <span class='hs-layout'>(</span><span class='hs-conid'>ClosureInfo</span> <span class='hs-layout'>{</span> <span class='hs-varid'>closureLFInfo</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>LFReEntrant</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-layout'>}</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>True</span>
<a name="line-26"></a><span class='hs-definition'>closureReEntrant</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
<a name="line-27"></a>
<a name="line-28"></a><a name="isConstrClosure_maybe"></a><span class='hs-definition'>isConstrClosure_maybe</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>ClosureInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Maybe</span> <span class='hs-conid'>DataCon</span>
<a name="line-29"></a><span class='hs-definition'>isConstrClosure_maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>ConInfo</span> <span class='hs-layout'>{</span> <span class='hs-varid'>closureCon</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>data_con</span> <span class='hs-layout'>}</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Just</span> <span class='hs-varid'>data_con</span>
<a name="line-30"></a><span class='hs-definition'>isConstrClosure_maybe</span> <span class='hs-keyword'>_</span> 				  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Nothing</span>
<a name="line-31"></a>
<a name="line-32"></a><a name="closureFunInfo"></a><span class='hs-definition'>closureFunInfo</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>ClosureInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>Int</span><span class='hs-layout'>,</span> <span class='hs-conid'>ArgDescr</span><span class='hs-layout'>)</span>
<a name="line-33"></a><span class='hs-definition'>closureFunInfo</span> <span class='hs-layout'>(</span><span class='hs-conid'>ClosureInfo</span> <span class='hs-layout'>{</span> <span class='hs-varid'>closureLFInfo</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>lf_info</span> <span class='hs-layout'>}</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>lfFunInfo</span> <span class='hs-varid'>lf_info</span>
<a name="line-34"></a><span class='hs-definition'>closureFunInfo</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Nothing</span>
<a name="line-35"></a>
<a name="line-36"></a><a name="lfFunInfo"></a><span class='hs-definition'>lfFunInfo</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>LambdaFormInfo</span> <span class='hs-keyglyph'>-&gt;</span>  <span class='hs-conid'>Maybe</span> <span class='hs-layout'>(</span><span class='hs-conid'>Int</span><span class='hs-layout'>,</span> <span class='hs-conid'>ArgDescr</span><span class='hs-layout'>)</span>
<a name="line-37"></a><span class='hs-definition'>lfFunInfo</span> <span class='hs-layout'>(</span><span class='hs-conid'>LFReEntrant</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>arity</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>arg_desc</span><span class='hs-layout'>)</span>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-varid'>arity</span><span class='hs-layout'>,</span> <span class='hs-varid'>arg_desc</span><span class='hs-layout'>)</span>
<a name="line-38"></a><span class='hs-definition'>lfFunInfo</span> <span class='hs-keyword'>_</span>                                 <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Nothing</span>
<a name="line-39"></a>
<a name="line-40"></a><a name="funTag"></a><span class='hs-definition'>funTag</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>ClosureInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span>
<a name="line-41"></a><span class='hs-definition'>funTag</span> <span class='hs-layout'>(</span><span class='hs-conid'>ClosureInfo</span> <span class='hs-layout'>{</span> <span class='hs-varid'>closureLFInfo</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>lf_info</span> <span class='hs-layout'>}</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>funTagLFInfo</span> <span class='hs-varid'>lf_info</span>
<a name="line-42"></a><span class='hs-definition'>funTag</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-num'>0</span>
<a name="line-43"></a>
<a name="line-44"></a><a name="funTagLFInfo"></a><span class='hs-comment'>-- maybe this should do constructor tags too?</span>
<a name="line-45"></a><span class='hs-definition'>funTagLFInfo</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>LambdaFormInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span>
<a name="line-46"></a><span class='hs-definition'>funTagLFInfo</span> <span class='hs-varid'>lf</span>
<a name="line-47"></a>    <span class='hs-comment'>-- A function is tagged with its arity</span>
<a name="line-48"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-varid'>arity</span><span class='hs-layout'>,</span><span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>lfFunInfo</span> <span class='hs-varid'>lf</span><span class='hs-layout'>,</span>
<a name="line-49"></a>    <span class='hs-conid'>Just</span> <span class='hs-varid'>tag</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>tagForArity</span> <span class='hs-varid'>arity</span>
<a name="line-50"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>tag</span>
<a name="line-51"></a>
<a name="line-52"></a>    <span class='hs-comment'>-- other closures (and unknown ones) are not tagged</span>
<a name="line-53"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>
<a name="line-54"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-num'>0</span>
<a name="line-55"></a>
<a name="line-56"></a><a name="tagForArity"></a><span class='hs-definition'>tagForArity</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Maybe</span> <span class='hs-conid'>Int</span>
<a name="line-57"></a><span class='hs-definition'>tagForArity</span> <span class='hs-varid'>i</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>i</span> <span class='hs-varop'>&lt;=</span> <span class='hs-varid'>mAX_PTR_TAG</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Just</span> <span class='hs-varid'>i</span>
<a name="line-58"></a>              <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>        <span class='hs-keyglyph'>=</span> <span class='hs-conid'>Nothing</span>
</pre>\end{code}

\begin{code}
<pre><a name="line-1"></a><a name="isToplevClosure"></a><span class='hs-definition'>isToplevClosure</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>ClosureInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span>
<a name="line-2"></a><span class='hs-definition'>isToplevClosure</span> <span class='hs-layout'>(</span><span class='hs-conid'>ClosureInfo</span> <span class='hs-layout'>{</span> <span class='hs-varid'>closureLFInfo</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>lf_info</span> <span class='hs-layout'>}</span><span class='hs-layout'>)</span>
<a name="line-3"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>lf_info</span> <span class='hs-keyword'>of</span>
<a name="line-4"></a>      <span class='hs-conid'>LFReEntrant</span> <span class='hs-conid'>TopLevel</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>True</span>
<a name="line-5"></a>      <span class='hs-conid'>LFThunk</span> <span class='hs-conid'>TopLevel</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span>   <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>True</span>
<a name="line-6"></a>      <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>False</span>
<a name="line-7"></a><span class='hs-definition'>isToplevClosure</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>False</span>
</pre>\end{code}

Label generation.

\begin{code}
<pre><a name="line-1"></a><a name="infoTableLabelFromCI"></a><span class='hs-definition'>infoTableLabelFromCI</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>ClosureInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CafInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CLabel</span>
<a name="line-2"></a><span class='hs-definition'>infoTableLabelFromCI</span> <span class='hs-layout'>(</span><span class='hs-conid'>ClosureInfo</span> <span class='hs-layout'>{</span> <span class='hs-varid'>closureName</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>name</span><span class='hs-layout'>,</span>
<a name="line-3"></a>				    <span class='hs-varid'>closureLFInfo</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>lf_info</span> <span class='hs-layout'>}</span><span class='hs-layout'>)</span> <span class='hs-varid'>caf</span>
<a name="line-4"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-varid'>lf_info</span> <span class='hs-keyword'>of</span>
<a name="line-5"></a>	<span class='hs-conid'>LFBlackHole</span> <span class='hs-varid'>info</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>info</span>
<a name="line-6"></a>
<a name="line-7"></a>	<span class='hs-conid'>LFThunk</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>upd_flag</span> <span class='hs-layout'>(</span><span class='hs-conid'>SelectorThunk</span> <span class='hs-varid'>offset</span><span class='hs-layout'>)</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> 
<a name="line-8"></a>		<span class='hs-varid'>mkSelectorInfoLabel</span> <span class='hs-varid'>upd_flag</span> <span class='hs-varid'>offset</span>
<a name="line-9"></a>
<a name="line-10"></a>	<span class='hs-conid'>LFThunk</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>upd_flag</span> <span class='hs-layout'>(</span><span class='hs-conid'>ApThunk</span> <span class='hs-varid'>arity</span><span class='hs-layout'>)</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> 
<a name="line-11"></a>		<span class='hs-varid'>mkApInfoTableLabel</span> <span class='hs-varid'>upd_flag</span> <span class='hs-varid'>arity</span>
<a name="line-12"></a>
<a name="line-13"></a>	<span class='hs-conid'>LFThunk</span><span class='hs-layout'>{</span><span class='hs-layout'>}</span>      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>mkLocalInfoTableLabel</span> <span class='hs-varid'>name</span> <span class='hs-varid'>caf</span>
<a name="line-14"></a>
<a name="line-15"></a>	<span class='hs-conid'>LFReEntrant</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>mkLocalInfoTableLabel</span> <span class='hs-varid'>name</span> <span class='hs-varid'>caf</span>
<a name="line-16"></a>
<a name="line-17"></a>	<span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>panic</span> <span class='hs-str'>"infoTableLabelFromCI"</span>
<a name="line-18"></a>
<a name="line-19"></a><span class='hs-definition'>infoTableLabelFromCI</span> <span class='hs-layout'>(</span><span class='hs-conid'>ConInfo</span> <span class='hs-layout'>{</span> <span class='hs-varid'>closureCon</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>con</span><span class='hs-layout'>,</span> 
<a name="line-20"></a>				<span class='hs-varid'>closureSMRep</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>rep</span> <span class='hs-layout'>}</span><span class='hs-layout'>)</span> <span class='hs-varid'>caf</span>
<a name="line-21"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>isStaticRep</span> <span class='hs-varid'>rep</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkStaticInfoTableLabel</span>  <span class='hs-varid'>name</span> <span class='hs-varid'>caf</span>
<a name="line-22"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>	    <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkConInfoTableLabel</span>     <span class='hs-varid'>name</span> <span class='hs-varid'>caf</span>
<a name="line-23"></a>  <span class='hs-keyword'>where</span>
<a name="line-24"></a>    <span class='hs-varid'>name</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>dataConName</span> <span class='hs-varid'>con</span>
<a name="line-25"></a>
<a name="line-26"></a><a name="closureLabelFromCI"></a><span class='hs-comment'>-- ClosureInfo for a closure (as opposed to a constructor) is always local</span>
<a name="line-27"></a><span class='hs-definition'>closureLabelFromCI</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>ClosureInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CafInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CLabel</span>
<a name="line-28"></a><span class='hs-definition'>closureLabelFromCI</span> <span class='hs-layout'>(</span><span class='hs-conid'>ClosureInfo</span> <span class='hs-layout'>{</span> <span class='hs-varid'>closureName</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>nm</span> <span class='hs-layout'>}</span><span class='hs-layout'>)</span> <span class='hs-varid'>caf</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkLocalClosureLabel</span> <span class='hs-varid'>nm</span> <span class='hs-varid'>caf</span>
<a name="line-29"></a><span class='hs-definition'>closureLabelFromCI</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>panic</span> <span class='hs-str'>"closureLabelFromCI"</span>
<a name="line-30"></a>
<a name="line-31"></a><span class='hs-comment'>-- thunkEntryLabel is a local help function, not exported.  It's used from both</span>
<a name="line-32"></a><span class='hs-comment'>-- entryLabelFromCI and getCallMethod.</span>
<a name="line-33"></a>
<a name="line-34"></a><a name="thunkEntryLabel"></a><span class='hs-definition'>thunkEntryLabel</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Name</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CafInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StandardFormInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Bool</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CLabel</span>
<a name="line-35"></a><span class='hs-definition'>thunkEntryLabel</span> <span class='hs-sel'>_thunk_id</span> <span class='hs-keyword'>_</span> <span class='hs-layout'>(</span><span class='hs-conid'>ApThunk</span> <span class='hs-varid'>arity</span><span class='hs-layout'>)</span> <span class='hs-varid'>is_updatable</span>
<a name="line-36"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>enterApLabel</span> <span class='hs-varid'>is_updatable</span> <span class='hs-varid'>arity</span>
<a name="line-37"></a><span class='hs-definition'>thunkEntryLabel</span> <span class='hs-sel'>_thunk_id</span> <span class='hs-keyword'>_</span> <span class='hs-layout'>(</span><span class='hs-conid'>SelectorThunk</span> <span class='hs-varid'>offset</span><span class='hs-layout'>)</span> <span class='hs-varid'>upd_flag</span>
<a name="line-38"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>enterSelectorLabel</span> <span class='hs-varid'>upd_flag</span> <span class='hs-varid'>offset</span>
<a name="line-39"></a><span class='hs-definition'>thunkEntryLabel</span> <span class='hs-varid'>thunk_id</span> <span class='hs-varid'>caf</span> <span class='hs-keyword'>_</span> <span class='hs-sel'>_is_updatable</span>
<a name="line-40"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>enterIdLabel</span> <span class='hs-varid'>thunk_id</span> <span class='hs-varid'>caf</span>
<a name="line-41"></a>
<a name="line-42"></a><a name="enterApLabel"></a><span class='hs-definition'>enterApLabel</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Bool</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CLabel</span>
<a name="line-43"></a><span class='hs-definition'>enterApLabel</span> <span class='hs-varid'>is_updatable</span> <span class='hs-varid'>arity</span>
<a name="line-44"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>tablesNextToCode</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkApInfoTableLabel</span> <span class='hs-varid'>is_updatable</span> <span class='hs-varid'>arity</span>
<a name="line-45"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>        <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkApEntryLabel</span> <span class='hs-varid'>is_updatable</span> <span class='hs-varid'>arity</span>
<a name="line-46"></a>
<a name="line-47"></a><a name="enterSelectorLabel"></a><span class='hs-definition'>enterSelectorLabel</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Bool</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Int</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CLabel</span>
<a name="line-48"></a><span class='hs-definition'>enterSelectorLabel</span> <span class='hs-varid'>upd_flag</span> <span class='hs-varid'>offset</span>
<a name="line-49"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>tablesNextToCode</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkSelectorInfoLabel</span> <span class='hs-varid'>upd_flag</span> <span class='hs-varid'>offset</span>
<a name="line-50"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>        <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkSelectorEntryLabel</span> <span class='hs-varid'>upd_flag</span> <span class='hs-varid'>offset</span>
<a name="line-51"></a>
<a name="line-52"></a><a name="enterIdLabel"></a><span class='hs-definition'>enterIdLabel</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Name</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CafInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CLabel</span>
<a name="line-53"></a><span class='hs-definition'>enterIdLabel</span> <span class='hs-varid'>id</span>
<a name="line-54"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>tablesNextToCode</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkInfoTableLabel</span> <span class='hs-varid'>id</span>
<a name="line-55"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>        <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkEntryLabel</span> <span class='hs-varid'>id</span>
<a name="line-56"></a>
<a name="line-57"></a><a name="enterLocalIdLabel"></a><span class='hs-definition'>enterLocalIdLabel</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Name</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CafInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CLabel</span>
<a name="line-58"></a><span class='hs-definition'>enterLocalIdLabel</span> <span class='hs-varid'>id</span>
<a name="line-59"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>tablesNextToCode</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkLocalInfoTableLabel</span> <span class='hs-varid'>id</span>
<a name="line-60"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>        <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkLocalEntryLabel</span> <span class='hs-varid'>id</span>
<a name="line-61"></a>
<a name="line-62"></a><a name="enterReturnPtLabel"></a><span class='hs-definition'>enterReturnPtLabel</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Unique</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CLabel</span>
<a name="line-63"></a><span class='hs-definition'>enterReturnPtLabel</span> <span class='hs-varid'>name</span>
<a name="line-64"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>tablesNextToCode</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkReturnInfoLabel</span> <span class='hs-varid'>name</span>
<a name="line-65"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>otherwise</span>        <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkReturnPtLabel</span> <span class='hs-varid'>name</span>
</pre>\end{code}


We need a black-hole closure info to pass to @allocDynClosure@ when we
want to allocate the black hole on entry to a CAF.  These are the only
ways to build an LFBlackHole, maintaining the invariant that it really
is a black hole and not something else.

\begin{code}
<pre><a name="line-1"></a><a name="cafBlackHoleClosureInfo"></a><span class='hs-definition'>cafBlackHoleClosureInfo</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>ClosureInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>ClosureInfo</span>
<a name="line-2"></a><span class='hs-definition'>cafBlackHoleClosureInfo</span> <span class='hs-layout'>(</span><span class='hs-conid'>ClosureInfo</span> <span class='hs-layout'>{</span> <span class='hs-varid'>closureName</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>nm</span><span class='hs-layout'>,</span>
<a name="line-3"></a>				       <span class='hs-varid'>closureType</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>ty</span> <span class='hs-layout'>}</span><span class='hs-layout'>)</span>
<a name="line-4"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ClosureInfo</span> <span class='hs-layout'>{</span> <span class='hs-varid'>closureName</span>   <span class='hs-keyglyph'>=</span> <span class='hs-varid'>nm</span><span class='hs-layout'>,</span>
<a name="line-5"></a>		  <span class='hs-varid'>closureLFInfo</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>LFBlackHole</span> <span class='hs-varid'>mkCAFBlackHoleInfoTableLabel</span><span class='hs-layout'>,</span>
<a name="line-6"></a>		  <span class='hs-varid'>closureSMRep</span>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>BlackHoleRep</span><span class='hs-layout'>,</span>
<a name="line-7"></a>		  <span class='hs-varid'>closureSRT</span>    <span class='hs-keyglyph'>=</span> <span class='hs-conid'>NoC_SRT</span><span class='hs-layout'>,</span>
<a name="line-8"></a>		  <span class='hs-varid'>closureType</span>   <span class='hs-keyglyph'>=</span> <span class='hs-varid'>ty</span><span class='hs-layout'>,</span>
<a name="line-9"></a>		  <span class='hs-varid'>closureDescr</span>  <span class='hs-keyglyph'>=</span> <span class='hs-str'>""</span> <span class='hs-layout'>}</span>
<a name="line-10"></a><span class='hs-definition'>cafBlackHoleClosureInfo</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>panic</span> <span class='hs-str'>"cafBlackHoleClosureInfo"</span>
</pre>\end{code}

%************************************************************************
%*									*
\subsection[ClosureInfo-Profiling-funs]{Misc functions about for profiling info.}
%*									*
%************************************************************************

Profiling requires two pieces of information to be determined for
each closure's info table --- description and type.

The description is stored directly in the @CClosureInfoTable@ when the
info table is built.

The type is determined from the type information stored with the @Id@
in the closure info using @closureTypeDescr@.

\begin{code}
<pre><a name="line-1"></a><a name="closureValDescr"></a><span class='hs-definition'>closureValDescr</span><span class='hs-layout'>,</span> <span class='hs-varid'>closureTypeDescr</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>ClosureInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>String</span>
<a name="line-2"></a><span class='hs-definition'>closureValDescr</span> <span class='hs-layout'>(</span><span class='hs-conid'>ClosureInfo</span> <span class='hs-layout'>{</span><span class='hs-varid'>closureDescr</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>descr</span><span class='hs-layout'>}</span><span class='hs-layout'>)</span> 
<a name="line-3"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>descr</span>
<a name="line-4"></a><span class='hs-definition'>closureValDescr</span> <span class='hs-layout'>(</span><span class='hs-conid'>ConInfo</span> <span class='hs-layout'>{</span><span class='hs-varid'>closureCon</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>con</span><span class='hs-layout'>}</span><span class='hs-layout'>)</span>
<a name="line-5"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>occNameString</span> <span class='hs-layout'>(</span><span class='hs-varid'>getOccName</span> <span class='hs-varid'>con</span><span class='hs-layout'>)</span>
<a name="line-6"></a>
<a name="line-7"></a><a name="closureTypeDescr"></a><span class='hs-definition'>closureTypeDescr</span> <span class='hs-layout'>(</span><span class='hs-conid'>ClosureInfo</span> <span class='hs-layout'>{</span> <span class='hs-varid'>closureType</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>ty</span> <span class='hs-layout'>}</span><span class='hs-layout'>)</span>
<a name="line-8"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>getTyDescription</span> <span class='hs-varid'>ty</span>
<a name="line-9"></a><span class='hs-definition'>closureTypeDescr</span> <span class='hs-layout'>(</span><span class='hs-conid'>ConInfo</span> <span class='hs-layout'>{</span> <span class='hs-varid'>closureCon</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>data_con</span> <span class='hs-layout'>}</span><span class='hs-layout'>)</span>
<a name="line-10"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>occNameString</span> <span class='hs-layout'>(</span><span class='hs-varid'>getOccName</span> <span class='hs-layout'>(</span><span class='hs-varid'>dataConTyCon</span> <span class='hs-varid'>data_con</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-11"></a>
<a name="line-12"></a><a name="getTyDescription"></a><span class='hs-definition'>getTyDescription</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>String</span>
<a name="line-13"></a><span class='hs-definition'>getTyDescription</span> <span class='hs-varid'>ty</span>
<a name="line-14"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>case</span> <span class='hs-layout'>(</span><span class='hs-varid'>tcSplitSigmaTy</span> <span class='hs-varid'>ty</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-keyword'>_</span><span class='hs-layout'>,</span> <span class='hs-keyword'>_</span><span class='hs-layout'>,</span> <span class='hs-varid'>tau_ty</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span>
<a name="line-15"></a>    <span class='hs-keyword'>case</span> <span class='hs-varid'>tau_ty</span> <span class='hs-keyword'>of</span>
<a name="line-16"></a>      <span class='hs-conid'>TyVarTy</span> <span class='hs-keyword'>_</span>	       	     <span class='hs-keyglyph'>-&gt;</span> <span class='hs-str'>"*"</span>
<a name="line-17"></a>      <span class='hs-conid'>AppTy</span> <span class='hs-varid'>fun</span> <span class='hs-keyword'>_</span>      	     <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>getTyDescription</span> <span class='hs-varid'>fun</span>
<a name="line-18"></a>      <span class='hs-conid'>FunTy</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>res</span>      	     <span class='hs-keyglyph'>-&gt;</span> <span class='hs-chr'>'-'</span> <span class='hs-conop'>:</span> <span class='hs-chr'>'&gt;'</span> <span class='hs-conop'>:</span> <span class='hs-varid'>fun_result</span> <span class='hs-varid'>res</span>
<a name="line-19"></a>      <span class='hs-conid'>TyConApp</span> <span class='hs-varid'>tycon</span> <span class='hs-keyword'>_</span> 	     <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>getOccString</span> <span class='hs-varid'>tycon</span>
<a name="line-20"></a>      <span class='hs-conid'>PredTy</span> <span class='hs-varid'>sty</span>	     <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>getPredTyDescription</span> <span class='hs-varid'>sty</span>
<a name="line-21"></a>      <span class='hs-conid'>ForAllTy</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>ty</span>          <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>getTyDescription</span> <span class='hs-varid'>ty</span>
<a name="line-22"></a>    <span class='hs-layout'>}</span>
<a name="line-23"></a>  <span class='hs-keyword'>where</span>
<a name="line-24"></a>    <span class='hs-varid'>fun_result</span> <span class='hs-layout'>(</span><span class='hs-conid'>FunTy</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>res</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-chr'>'&gt;'</span> <span class='hs-conop'>:</span> <span class='hs-varid'>fun_result</span> <span class='hs-varid'>res</span>
<a name="line-25"></a>    <span class='hs-varid'>fun_result</span> <span class='hs-varid'>other</span>	     <span class='hs-keyglyph'>=</span> <span class='hs-varid'>getTyDescription</span> <span class='hs-varid'>other</span>
<a name="line-26"></a>
<a name="line-27"></a><a name="getPredTyDescription"></a><span class='hs-definition'>getPredTyDescription</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>PredType</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>String</span>
<a name="line-28"></a><span class='hs-definition'>getPredTyDescription</span> <span class='hs-layout'>(</span><span class='hs-conid'>ClassP</span> <span class='hs-varid'>cl</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>getOccString</span> <span class='hs-varid'>cl</span>
<a name="line-29"></a><span class='hs-definition'>getPredTyDescription</span> <span class='hs-layout'>(</span><span class='hs-conid'>IParam</span> <span class='hs-varid'>ip</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>getOccString</span> <span class='hs-layout'>(</span><span class='hs-varid'>ipNameName</span> <span class='hs-varid'>ip</span><span class='hs-layout'>)</span>
<a name="line-30"></a><span class='hs-definition'>getPredTyDescription</span> <span class='hs-layout'>(</span><span class='hs-conid'>EqPred</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>panic</span> <span class='hs-str'>"getPredTyDescription EqPred"</span>
</pre>\end{code}
</body>
</html>