Sophie

Sophie

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

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/CgExpr.lhs</title>
<link type='text/css' rel='stylesheet' href='hscolour.css' />
</head>
<body>
%
% (c) The University of Glasgow 2006
% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
%

\begin{code}
<pre><a name="line-1"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>CgExpr</span> <span class='hs-layout'>(</span> <span class='hs-varid'>cgExpr</span> <span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
<a name="line-2"></a>
<a name="line-3"></a><span class='hs-cpp'>#include "HsVersions.h"</span>
<a name="line-4"></a>
<a name="line-5"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Constants</span>
<a name="line-6"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>StgSyn</span>
<a name="line-7"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CgMonad</span>
<a name="line-8"></a>
<a name="line-9"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CostCentre</span>
<a name="line-10"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>SMRep</span>
<a name="line-11"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CoreSyn</span>
<a name="line-12"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CgProf</span>
<a name="line-13"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CgHeapery</span>
<a name="line-14"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CgBindery</span>
<a name="line-15"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CgCase</span>
<a name="line-16"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CgClosure</span>
<a name="line-17"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CgCon</span>
<a name="line-18"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CgLetNoEscape</span>
<a name="line-19"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CgTailCall</span>
<a name="line-20"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CgInfoTbls</span>
<a name="line-21"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CgForeignCall</span>
<a name="line-22"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CgPrimOp</span>
<a name="line-23"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CgHpc</span>
<a name="line-24"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CgUtils</span>
<a name="line-25"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>ClosureInfo</span>
<a name="line-26"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Cmm</span>
<a name="line-27"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CmmUtils</span>
<a name="line-28"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>VarSet</span>
<a name="line-29"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Literal</span>
<a name="line-30"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>PrimOp</span>
<a name="line-31"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Id</span>
<a name="line-32"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>TyCon</span>
<a name="line-33"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Type</span>
<a name="line-34"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Maybes</span>
<a name="line-35"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>ListSetOps</span>
<a name="line-36"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>BasicTypes</span>
<a name="line-37"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Util</span>
<a name="line-38"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Outputable</span>
</pre>\end{code}

This module provides the support code for @StgToAbstractC@ to deal
with STG {\em expressions}.  See also @CgClosure@, which deals
with closures, and @CgCon@, which deals with constructors.

\begin{code}
<pre><a name="line-1"></a><a name="cgExpr"></a><span class='hs-definition'>cgExpr</span>	<span class='hs-keyglyph'>::</span> <span class='hs-conid'>StgExpr</span>		<span class='hs-comment'>-- input</span>
<a name="line-2"></a>	<span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Code</span>			<span class='hs-comment'>-- output</span>
</pre>\end{code}

%********************************************************
%*							*
%*		Tail calls				*
%*							*
%********************************************************

``Applications'' mean {\em tail calls}, a service provided by module
@CgTailCall@.  This includes literals, which show up as
@(STGApp (StgLitArg 42) [])@.

\begin{code}
<pre><a name="line-1"></a><a name="cgExpr"></a><span class='hs-definition'>cgExpr</span> <span class='hs-layout'>(</span><span class='hs-conid'>StgApp</span> <span class='hs-varid'>fun</span> <span class='hs-varid'>args</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cgTailCall</span> <span class='hs-varid'>fun</span> <span class='hs-varid'>args</span>
</pre>\end{code}

%********************************************************
%*							*
%*		STG ConApps  (for inline versions)	*
%*							*
%********************************************************

\begin{code}
<pre><a name="line-1"></a><a name="cgExpr"></a><span class='hs-definition'>cgExpr</span> <span class='hs-layout'>(</span><span class='hs-conid'>StgConApp</span> <span class='hs-varid'>con</span> <span class='hs-varid'>args</span><span class='hs-layout'>)</span>
<a name="line-2"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>	<span class='hs-layout'>{</span> <span class='hs-varid'>amodes</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>getArgAmodes</span> <span class='hs-varid'>args</span>
<a name="line-3"></a>	<span class='hs-layout'>;</span> <span class='hs-varid'>cgReturnDataCon</span> <span class='hs-varid'>con</span> <span class='hs-varid'>amodes</span> <span class='hs-layout'>}</span>
</pre>\end{code}

Literals are similar to constructors; they return by putting
themselves in an appropriate register and returning to the address on
top of the stack.

\begin{code}
<pre><a name="line-1"></a><a name="cgExpr"></a><span class='hs-definition'>cgExpr</span> <span class='hs-layout'>(</span><span class='hs-conid'>StgLit</span> <span class='hs-varid'>lit</span><span class='hs-layout'>)</span>
<a name="line-2"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>  <span class='hs-layout'>{</span> <span class='hs-varid'>cmm_lit</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>cgLit</span> <span class='hs-varid'>lit</span>
<a name="line-3"></a>	<span class='hs-layout'>;</span> <span class='hs-varid'>performPrimReturn</span> <span class='hs-varid'>rep</span> <span class='hs-layout'>(</span><span class='hs-conid'>CmmLit</span> <span class='hs-varid'>cmm_lit</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span>
<a name="line-4"></a>  <span class='hs-keyword'>where</span>
<a name="line-5"></a>    <span class='hs-varid'>rep</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>typeCgRep</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>literalType</span> <span class='hs-varid'>lit</span><span class='hs-layout'>)</span>
</pre>\end{code}


%********************************************************
%*							*
%* 	PrimOps and foreign calls.
%*							*
%********************************************************

NOTE about "safe" foreign calls: a safe foreign call is never compiled
inline in a case expression.  When we see

	case (ccall ...) of { ... }

We generate a proper return address for the alternatives and push the
stack frame before doing the call, so that in the event that the call
re-enters the RTS the stack is in a sane state.

\begin{code}
<pre><a name="line-1"></a><a name="cgExpr"></a><span class='hs-definition'>cgExpr</span> <span class='hs-layout'>(</span><span class='hs-conid'>StgOpApp</span> <span class='hs-layout'>(</span><span class='hs-conid'>StgFCallOp</span> <span class='hs-varid'>fcall</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-varid'>stg_args</span> <span class='hs-varid'>res_ty</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>
<a name="line-2"></a>    <span class='hs-comment'>{-
<a name="line-3"></a>	First, copy the args into temporaries.  We're going to push
<a name="line-4"></a>	a return address right before doing the call, so the args
<a name="line-5"></a>	must be out of the way.
<a name="line-6"></a>    -}</span>
<a name="line-7"></a>    <span class='hs-varid'>reps_n_amodes</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>getArgAmodes</span> <span class='hs-varid'>stg_args</span>
<a name="line-8"></a>    <span class='hs-keyword'>let</span> 
<a name="line-9"></a>	<span class='hs-comment'>-- Get the *non-void* args, and jiggle them with shimForeignCall</span>
<a name="line-10"></a>	<span class='hs-varid'>arg_exprs</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyglyph'>[</span> <span class='hs-layout'>(</span><span class='hs-varid'>shimForeignCallArg</span> <span class='hs-varid'>stg_arg</span> <span class='hs-varid'>expr</span><span class='hs-layout'>,</span> <span class='hs-varid'>stg_arg</span><span class='hs-layout'>)</span>
<a name="line-11"></a>		    <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-varid'>stg_arg</span><span class='hs-layout'>,</span> <span class='hs-layout'>(</span><span class='hs-varid'>rep</span><span class='hs-layout'>,</span><span class='hs-varid'>expr</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>stg_args</span> <span class='hs-varop'>`zip`</span> <span class='hs-varid'>reps_n_amodes</span><span class='hs-layout'>,</span> 
<a name="line-12"></a>		      <span class='hs-varid'>nonVoidArg</span> <span class='hs-varid'>rep</span><span class='hs-keyglyph'>]</span>
<a name="line-13"></a>
<a name="line-14"></a>    <span class='hs-varid'>arg_tmps</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>sequence</span> <span class='hs-keyglyph'>[</span> <span class='hs-varid'>assignTemp</span> <span class='hs-varid'>arg</span>
<a name="line-15"></a>                         <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-varid'>arg</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'>arg_exprs</span><span class='hs-keyglyph'>]</span>
<a name="line-16"></a>    <span class='hs-keyword'>let</span>	<span class='hs-varid'>arg_hints</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>zipWith</span> <span class='hs-conid'>CmmHinted</span> <span class='hs-varid'>arg_tmps</span> <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-layout'>(</span><span class='hs-varid'>typeForeignHint</span><span class='hs-varop'>.</span><span class='hs-varid'>stgArgType</span><span class='hs-layout'>)</span> <span class='hs-varid'>stg_args</span><span class='hs-layout'>)</span>
<a name="line-17"></a>    <span class='hs-comment'>{-
<a name="line-18"></a>	Now, allocate some result regs.
<a name="line-19"></a>    -}</span>
<a name="line-20"></a>    <span class='hs-layout'>(</span><span class='hs-varid'>res_reps</span><span class='hs-layout'>,</span><span class='hs-varid'>res_regs</span><span class='hs-layout'>,</span><span class='hs-varid'>res_hints</span><span class='hs-layout'>)</span>  <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>newUnboxedTupleRegs</span> <span class='hs-varid'>res_ty</span>
<a name="line-21"></a>    <span class='hs-varid'>ccallReturnUnboxedTuple</span> <span class='hs-layout'>(</span><span class='hs-varid'>zip</span> <span class='hs-varid'>res_reps</span> <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-layout'>(</span><span class='hs-conid'>CmmReg</span> <span class='hs-varop'>.</span> <span class='hs-conid'>CmmLocal</span><span class='hs-layout'>)</span> <span class='hs-varid'>res_regs</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varop'>$</span>
<a name="line-22"></a>	<span class='hs-varid'>emitForeignCall</span> <span class='hs-layout'>(</span><span class='hs-varid'>zipWith</span> <span class='hs-conid'>CmmHinted</span> <span class='hs-varid'>res_regs</span> <span class='hs-varid'>res_hints</span><span class='hs-layout'>)</span> <span class='hs-varid'>fcall</span> 
<a name="line-23"></a>	   <span class='hs-varid'>arg_hints</span> <span class='hs-varid'>emptyVarSet</span><span class='hs-comment'>{-no live vars-}</span>
<a name="line-24"></a>      
<a name="line-25"></a><span class='hs-comment'>-- tagToEnum# is special: we need to pull the constructor out of the table,</span>
<a name="line-26"></a><span class='hs-comment'>-- and perform an appropriate return.</span>
<a name="line-27"></a>
<a name="line-28"></a><span class='hs-definition'>cgExpr</span> <span class='hs-layout'>(</span><span class='hs-conid'>StgOpApp</span> <span class='hs-layout'>(</span><span class='hs-conid'>StgPrimOp</span> <span class='hs-conid'>TagToEnumOp</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>arg</span><span class='hs-keyglyph'>]</span> <span class='hs-varid'>res_ty</span><span class='hs-layout'>)</span> 
<a name="line-29"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ASSERT</span><span class='hs-layout'>(</span><span class='hs-varid'>isEnumerationTyCon</span> <span class='hs-varid'>tycon</span><span class='hs-layout'>)</span>
<a name="line-30"></a>    <span class='hs-keyword'>do</span>	<span class='hs-layout'>{</span> <span class='hs-layout'>(</span><span class='hs-sel'>_rep</span><span class='hs-layout'>,</span><span class='hs-varid'>amode</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>getArgAmode</span> <span class='hs-varid'>arg</span>
<a name="line-31"></a>	<span class='hs-layout'>;</span> <span class='hs-varid'>amode'</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>assignTemp</span> <span class='hs-varid'>amode</span>	<span class='hs-comment'>-- We're going to use it twice,</span>
<a name="line-32"></a>					<span class='hs-comment'>-- so save in a temp if non-trivial</span>
<a name="line-33"></a>	<span class='hs-layout'>;</span> <span class='hs-varid'>stmtC</span> <span class='hs-layout'>(</span><span class='hs-conid'>CmmAssign</span> <span class='hs-varid'>nodeReg</span> <span class='hs-layout'>(</span><span class='hs-varid'>tagToClosure</span> <span class='hs-varid'>tycon</span> <span class='hs-varid'>amode'</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-34"></a>	<span class='hs-layout'>;</span> <span class='hs-varid'>performReturn</span> <span class='hs-varid'>emitReturnInstr</span> <span class='hs-layout'>}</span>
<a name="line-35"></a>   <span class='hs-keyword'>where</span>
<a name="line-36"></a>	  <span class='hs-comment'>-- If you're reading this code in the attempt to figure</span>
<a name="line-37"></a>	  <span class='hs-comment'>-- out why the compiler panic'ed here, it is probably because</span>
<a name="line-38"></a>	  <span class='hs-comment'>-- you used tagToEnum# in a non-monomorphic setting, e.g., </span>
<a name="line-39"></a>	  <span class='hs-comment'>--         intToTg :: Enum a =&gt; Int -&gt; a ; intToTg (I# x#) = tagToEnum# x#</span>
<a name="line-40"></a>	  <span class='hs-comment'>-- That won't work.</span>
<a name="line-41"></a>	<span class='hs-varid'>tycon</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>tyConAppTyCon</span> <span class='hs-varid'>res_ty</span>
<a name="line-42"></a>
<a name="line-43"></a>
<a name="line-44"></a><span class='hs-definition'>cgExpr</span> <span class='hs-layout'>(</span><span class='hs-conid'>StgOpApp</span> <span class='hs-layout'>(</span><span class='hs-conid'>StgPrimOp</span> <span class='hs-varid'>primop</span><span class='hs-layout'>)</span> <span class='hs-varid'>args</span> <span class='hs-varid'>res_ty</span><span class='hs-layout'>)</span>
<a name="line-45"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>primOpOutOfLine</span> <span class='hs-varid'>primop</span>
<a name="line-46"></a>	<span class='hs-keyglyph'>=</span> <span class='hs-varid'>tailCallPrimOp</span> <span class='hs-varid'>primop</span> <span class='hs-varid'>args</span>
<a name="line-47"></a>
<a name="line-48"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>ReturnsPrim</span> <span class='hs-conid'>VoidRep</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>result_info</span>
<a name="line-49"></a>	<span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <span class='hs-varid'>cgPrimOp</span> <span class='hs-conid'>[]</span> <span class='hs-varid'>primop</span> <span class='hs-varid'>args</span> <span class='hs-varid'>emptyVarSet</span>
<a name="line-50"></a>	     <span class='hs-varid'>performReturn</span> <span class='hs-varid'>emitReturnInstr</span>
<a name="line-51"></a>
<a name="line-52"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>ReturnsPrim</span> <span class='hs-varid'>rep</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>result_info</span>
<a name="line-53"></a>	<span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <span class='hs-varid'>res</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>newTemp</span> <span class='hs-layout'>(</span><span class='hs-varid'>typeCmmType</span> <span class='hs-varid'>res_ty</span><span class='hs-layout'>)</span>
<a name="line-54"></a>             <span class='hs-varid'>cgPrimOp</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>res</span><span class='hs-keyglyph'>]</span> <span class='hs-varid'>primop</span> <span class='hs-varid'>args</span> <span class='hs-varid'>emptyVarSet</span>
<a name="line-55"></a>	     <span class='hs-varid'>performPrimReturn</span> <span class='hs-layout'>(</span><span class='hs-varid'>primRepToCgRep</span> <span class='hs-varid'>rep</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-conid'>CmmReg</span> <span class='hs-layout'>(</span><span class='hs-conid'>CmmLocal</span> <span class='hs-varid'>res</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-56"></a>
<a name="line-57"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>ReturnsAlg</span> <span class='hs-varid'>tycon</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>result_info</span><span class='hs-layout'>,</span> <span class='hs-varid'>isUnboxedTupleTyCon</span> <span class='hs-varid'>tycon</span>
<a name="line-58"></a>	<span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <span class='hs-layout'>(</span><span class='hs-varid'>reps</span><span class='hs-layout'>,</span> <span class='hs-varid'>regs</span><span class='hs-layout'>,</span> <span class='hs-sel'>_hints</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>newUnboxedTupleRegs</span> <span class='hs-varid'>res_ty</span>
<a name="line-59"></a>	     <span class='hs-varid'>cgPrimOp</span> <span class='hs-varid'>regs</span> <span class='hs-varid'>primop</span> <span class='hs-varid'>args</span> <span class='hs-varid'>emptyVarSet</span><span class='hs-comment'>{-no live vars-}</span>
<a name="line-60"></a>	     <span class='hs-varid'>returnUnboxedTuple</span> <span class='hs-layout'>(</span><span class='hs-varid'>zip</span> <span class='hs-varid'>reps</span> <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-layout'>(</span><span class='hs-conid'>CmmReg</span> <span class='hs-varop'>.</span> <span class='hs-conid'>CmmLocal</span><span class='hs-layout'>)</span> <span class='hs-varid'>regs</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-61"></a>
<a name="line-62"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>ReturnsAlg</span> <span class='hs-varid'>tycon</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>result_info</span><span class='hs-layout'>,</span> <span class='hs-varid'>isEnumerationTyCon</span> <span class='hs-varid'>tycon</span>
<a name="line-63"></a>	<span class='hs-comment'>-- c.f. cgExpr (...TagToEnumOp...)</span>
<a name="line-64"></a>	<span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <span class='hs-varid'>tag_reg</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>newTemp</span> <span class='hs-varid'>bWord</span>	<span class='hs-comment'>-- The tag is a word</span>
<a name="line-65"></a>	     <span class='hs-varid'>cgPrimOp</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>tag_reg</span><span class='hs-keyglyph'>]</span> <span class='hs-varid'>primop</span> <span class='hs-varid'>args</span> <span class='hs-varid'>emptyVarSet</span>
<a name="line-66"></a>	     <span class='hs-varid'>stmtC</span> <span class='hs-layout'>(</span><span class='hs-conid'>CmmAssign</span> <span class='hs-varid'>nodeReg</span>
<a name="line-67"></a>                    <span class='hs-layout'>(</span><span class='hs-varid'>tagToClosure</span> <span class='hs-varid'>tycon</span>
<a name="line-68"></a>                     <span class='hs-layout'>(</span><span class='hs-conid'>CmmReg</span> <span class='hs-layout'>(</span><span class='hs-conid'>CmmLocal</span> <span class='hs-varid'>tag_reg</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-69"></a>	     <span class='hs-varid'>performReturn</span> <span class='hs-varid'>emitReturnInstr</span>
<a name="line-70"></a>  <span class='hs-keyword'>where</span>
<a name="line-71"></a>	<span class='hs-varid'>result_info</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>getPrimOpResultInfo</span> <span class='hs-varid'>primop</span>
<a name="line-72"></a>
<a name="line-73"></a><span class='hs-definition'>cgExpr</span> <span class='hs-layout'>(</span><span class='hs-conid'>StgOpApp</span> <span class='hs-layout'>(</span><span class='hs-conid'>StgPrimCallOp</span> <span class='hs-varid'>primcall</span><span class='hs-layout'>)</span> <span class='hs-varid'>args</span> <span class='hs-sel'>_res_ty</span><span class='hs-layout'>)</span>
<a name="line-74"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>tailCallPrimCall</span> <span class='hs-varid'>primcall</span> <span class='hs-varid'>args</span>
</pre>\end{code}

%********************************************************
%*							*
%*		Case expressions			*
%*							*
%********************************************************
Case-expression conversion is complicated enough to have its own
module, @CgCase@.
\begin{code}
<pre><a name="line-1"></a>
<a name="line-2"></a><a name="cgExpr"></a><span class='hs-definition'>cgExpr</span> <span class='hs-layout'>(</span><span class='hs-conid'>StgCase</span> <span class='hs-varid'>expr</span> <span class='hs-varid'>live_vars</span> <span class='hs-varid'>save_vars</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>srt</span> <span class='hs-varid'>alt_type</span> <span class='hs-varid'>alts</span><span class='hs-layout'>)</span>
<a name="line-3"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>setSRT</span> <span class='hs-varid'>srt</span> <span class='hs-varop'>$</span> <span class='hs-varid'>cgCase</span> <span class='hs-varid'>expr</span> <span class='hs-varid'>live_vars</span> <span class='hs-varid'>save_vars</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>alt_type</span> <span class='hs-varid'>alts</span>
</pre>\end{code}


%********************************************************
%*							*
%* 		Let and letrec				*
%*							*
%********************************************************
\subsection[let-and-letrec-codegen]{Converting @StgLet@ and @StgLetrec@}

\begin{code}
<pre><a name="line-1"></a><a name="cgExpr"></a><span class='hs-definition'>cgExpr</span> <span class='hs-layout'>(</span><span class='hs-conid'>StgLet</span> <span class='hs-layout'>(</span><span class='hs-conid'>StgNonRec</span> <span class='hs-varid'>name</span> <span class='hs-varid'>rhs</span><span class='hs-layout'>)</span> <span class='hs-varid'>expr</span><span class='hs-layout'>)</span>
<a name="line-2"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cgRhs</span> <span class='hs-varid'>name</span> <span class='hs-varid'>rhs</span>	<span class='hs-varop'>`thenFC`</span> <span class='hs-keyglyph'>\</span> <span class='hs-layout'>(</span><span class='hs-varid'>name</span><span class='hs-layout'>,</span> <span class='hs-varid'>info</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span>
<a name="line-3"></a>    <span class='hs-varid'>addBindC</span> <span class='hs-varid'>name</span> <span class='hs-varid'>info</span> 	<span class='hs-varop'>`thenC`</span>
<a name="line-4"></a>    <span class='hs-varid'>cgExpr</span> <span class='hs-varid'>expr</span>
<a name="line-5"></a>
<a name="line-6"></a><span class='hs-definition'>cgExpr</span> <span class='hs-layout'>(</span><span class='hs-conid'>StgLet</span> <span class='hs-layout'>(</span><span class='hs-conid'>StgRec</span> <span class='hs-varid'>pairs</span><span class='hs-layout'>)</span> <span class='hs-varid'>expr</span><span class='hs-layout'>)</span>
<a name="line-7"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fixC</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span> <span class='hs-varid'>new_bindings</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>addBindsC</span> <span class='hs-varid'>new_bindings</span> <span class='hs-varop'>`thenC`</span>
<a name="line-8"></a>			    <span class='hs-varid'>listFCs</span> <span class='hs-keyglyph'>[</span> <span class='hs-varid'>cgRhs</span> <span class='hs-varid'>b</span> <span class='hs-varid'>e</span> <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-varid'>b</span><span class='hs-layout'>,</span><span class='hs-varid'>e</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>pairs</span> <span class='hs-keyglyph'>]</span>
<a name="line-9"></a>    <span class='hs-layout'>)</span> <span class='hs-varop'>`thenFC`</span> <span class='hs-keyglyph'>\</span> <span class='hs-varid'>new_bindings</span> <span class='hs-keyglyph'>-&gt;</span>
<a name="line-10"></a>
<a name="line-11"></a>    <span class='hs-varid'>addBindsC</span> <span class='hs-varid'>new_bindings</span> <span class='hs-varop'>`thenC`</span>
<a name="line-12"></a>    <span class='hs-varid'>cgExpr</span> <span class='hs-varid'>expr</span>
</pre>\end{code}

\begin{code}
<pre><a name="line-1"></a><a name="cgExpr"></a><span class='hs-definition'>cgExpr</span> <span class='hs-layout'>(</span><span class='hs-conid'>StgLetNoEscape</span> <span class='hs-varid'>live_in_whole_let</span> <span class='hs-varid'>live_in_rhss</span> <span class='hs-varid'>bindings</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span>
<a name="line-2"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>	<span class='hs-layout'>{</span>  	<span class='hs-comment'>-- Figure out what volatile variables to save</span>
<a name="line-3"></a>	<span class='hs-layout'>;</span> <span class='hs-varid'>nukeDeadBindings</span> <span class='hs-varid'>live_in_whole_let</span>
<a name="line-4"></a>	<span class='hs-layout'>;</span> <span class='hs-layout'>(</span><span class='hs-varid'>save_assts</span><span class='hs-layout'>,</span> <span class='hs-varid'>rhs_eob_info</span><span class='hs-layout'>,</span> <span class='hs-varid'>maybe_cc_slot</span><span class='hs-layout'>)</span> 
<a name="line-5"></a>		<span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>saveVolatileVarsAndRegs</span> <span class='hs-varid'>live_in_rhss</span>
<a name="line-6"></a>
<a name="line-7"></a>	<span class='hs-comment'>-- Save those variables right now!</span>
<a name="line-8"></a>	<span class='hs-layout'>;</span> <span class='hs-varid'>emitStmts</span> <span class='hs-varid'>save_assts</span>
<a name="line-9"></a>
<a name="line-10"></a>	<span class='hs-comment'>-- Produce code for the rhss</span>
<a name="line-11"></a>	<span class='hs-comment'>-- and add suitable bindings to the environment</span>
<a name="line-12"></a>	<span class='hs-layout'>;</span> <span class='hs-varid'>cgLetNoEscapeBindings</span> <span class='hs-varid'>live_in_rhss</span> <span class='hs-varid'>rhs_eob_info</span> 
<a name="line-13"></a>			 	<span class='hs-varid'>maybe_cc_slot</span> <span class='hs-varid'>bindings</span>
<a name="line-14"></a>
<a name="line-15"></a>	<span class='hs-comment'>-- Do the body</span>
<a name="line-16"></a>	<span class='hs-layout'>;</span> <span class='hs-varid'>setEndOfBlockInfo</span> <span class='hs-varid'>rhs_eob_info</span> <span class='hs-layout'>(</span><span class='hs-varid'>cgExpr</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span>
</pre>\end{code}


%********************************************************
%*							*
%*		SCC Expressions				*
%*							*
%********************************************************

SCC expressions are treated specially. They set the current cost
centre.

\begin{code}
<pre><a name="line-1"></a><a name="cgExpr"></a><span class='hs-definition'>cgExpr</span> <span class='hs-layout'>(</span><span class='hs-conid'>StgSCC</span> <span class='hs-varid'>cc</span> <span class='hs-varid'>expr</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <span class='hs-varid'>emitSetCCC</span> <span class='hs-varid'>cc</span><span class='hs-layout'>;</span> <span class='hs-varid'>cgExpr</span> <span class='hs-varid'>expr</span>
</pre>\end{code}

%********************************************************
%*                                                     *
%*             Hpc Tick Boxes                          *
%*                                                     *
%********************************************************

\begin{code}
<pre><a name="line-1"></a><a name="cgExpr"></a><span class='hs-definition'>cgExpr</span> <span class='hs-layout'>(</span><span class='hs-conid'>StgTick</span> <span class='hs-varid'>m</span> <span class='hs-varid'>n</span> <span class='hs-varid'>expr</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span> <span class='hs-varid'>cgTickBox</span> <span class='hs-varid'>m</span> <span class='hs-varid'>n</span><span class='hs-layout'>;</span> <span class='hs-varid'>cgExpr</span> <span class='hs-varid'>expr</span>
</pre>\end{code}

%********************************************************
%*                                                     *
%*             Anything else                           *
%*                                                     *
%********************************************************

\begin{code}
<pre><a name="line-1"></a><a name="cgExpr"></a><span class='hs-definition'>cgExpr</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>panic</span> <span class='hs-str'>"cgExpr"</span>
</pre>\end{code}

%********************************************************
%*							*
%*		Non-top-level bindings			*
%*							*
%********************************************************
\subsection[non-top-level-bindings]{Converting non-top-level bindings}

We rely on the support code in @CgCon@ (to do constructors) and
in @CgClosure@ (to do closures).

\begin{code}
<pre><a name="line-1"></a><a name="cgRhs"></a><span class='hs-definition'>cgRhs</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Id</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StgRhs</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>FCode</span> <span class='hs-layout'>(</span><span class='hs-conid'>Id</span><span class='hs-layout'>,</span> <span class='hs-conid'>CgIdInfo</span><span class='hs-layout'>)</span>
<a name="line-2"></a>	<span class='hs-comment'>-- the Id is passed along so a binding can be set up</span>
<a name="line-3"></a>
<a name="line-4"></a><span class='hs-definition'>cgRhs</span> <span class='hs-varid'>name</span> <span class='hs-layout'>(</span><span class='hs-conid'>StgRhsCon</span> <span class='hs-varid'>maybe_cc</span> <span class='hs-varid'>con</span> <span class='hs-varid'>args</span><span class='hs-layout'>)</span>
<a name="line-5"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>	<span class='hs-layout'>{</span> <span class='hs-varid'>amodes</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>getArgAmodes</span> <span class='hs-varid'>args</span>
<a name="line-6"></a>	<span class='hs-layout'>;</span> <span class='hs-varid'>idinfo</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>buildDynCon</span> <span class='hs-varid'>name</span> <span class='hs-varid'>maybe_cc</span> <span class='hs-varid'>con</span> <span class='hs-varid'>amodes</span>
<a name="line-7"></a>	<span class='hs-layout'>;</span> <span class='hs-varid'>returnFC</span> <span class='hs-layout'>(</span><span class='hs-varid'>name</span><span class='hs-layout'>,</span> <span class='hs-varid'>idinfo</span><span class='hs-layout'>)</span> <span class='hs-layout'>}</span>
<a name="line-8"></a>
<a name="line-9"></a><span class='hs-definition'>cgRhs</span> <span class='hs-varid'>name</span> <span class='hs-layout'>(</span><span class='hs-conid'>StgRhsClosure</span> <span class='hs-varid'>cc</span> <span class='hs-varid'>bi</span> <span class='hs-varid'>fvs</span> <span class='hs-varid'>upd_flag</span> <span class='hs-varid'>srt</span> <span class='hs-varid'>args</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span>
<a name="line-10"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>setSRT</span> <span class='hs-varid'>srt</span> <span class='hs-varop'>$</span> <span class='hs-varid'>mkRhsClosure</span> <span class='hs-varid'>name</span> <span class='hs-varid'>cc</span> <span class='hs-varid'>bi</span> <span class='hs-varid'>fvs</span> <span class='hs-varid'>upd_flag</span> <span class='hs-varid'>args</span> <span class='hs-varid'>body</span>
</pre>\end{code}

mkRhsClosure looks for two special forms of the right-hand side:
	a) selector thunks.
	b) AP thunks

If neither happens, it just calls mkClosureLFInfo.  You might think
that mkClosureLFInfo should do all this, but it seems wrong for the
latter to look at the structure of an expression

Selectors
~~~~~~~~~
We look at the body of the closure to see if it's a selector---turgid,
but nothing deep.  We are looking for a closure of {\em exactly} the
form:

...  = [the_fv] \ u [] ->
	 case the_fv of
	   con a_1 ... a_n -> a_i


\begin{code}
<pre><a name="line-1"></a><a name="mkRhsClosure"></a><span class='hs-definition'>mkRhsClosure</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Id</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CostCentreStack</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StgBinderInfo</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-keyglyph'>-&gt;</span> <span class='hs-conid'>UpdateFlag</span> <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-keyglyph'>-&gt;</span> <span class='hs-conid'>GenStgExpr</span> <span class='hs-conid'>Id</span> <span class='hs-conid'>Id</span>
<a name="line-3"></a>             <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>FCode</span> <span class='hs-layout'>(</span><span class='hs-conid'>Id</span><span class='hs-layout'>,</span> <span class='hs-conid'>CgIdInfo</span><span class='hs-layout'>)</span>
<a name="line-4"></a><span class='hs-definition'>mkRhsClosure</span>	<span class='hs-varid'>bndr</span> <span class='hs-varid'>cc</span> <span class='hs-varid'>bi</span>
<a name="line-5"></a>		<span class='hs-keyglyph'>[</span><span class='hs-varid'>the_fv</span><span class='hs-keyglyph'>]</span>   		<span class='hs-comment'>-- Just one free var</span>
<a name="line-6"></a>		<span class='hs-varid'>upd_flag</span>		<span class='hs-comment'>-- Updatable thunk</span>
<a name="line-7"></a>		<span class='hs-conid'>[]</span>			<span class='hs-comment'>-- A thunk</span>
<a name="line-8"></a>		<span class='hs-varid'>body</span><span class='hs-keyglyph'>@</span><span class='hs-layout'>(</span><span class='hs-conid'>StgCase</span> <span class='hs-layout'>(</span><span class='hs-conid'>StgApp</span> <span class='hs-varid'>scrutinee</span> <span class='hs-keyglyph'>[</span><span class='hs-comment'>{-no args-}</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span>
<a name="line-9"></a>		      <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>srt</span>   <span class='hs-comment'>-- ignore uniq, etc.</span>
<a name="line-10"></a>		      <span class='hs-layout'>(</span><span class='hs-conid'>AlgAlt</span> <span class='hs-keyword'>_</span><span class='hs-layout'>)</span>
<a name="line-11"></a>		      <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-conid'>DataAlt</span> <span class='hs-varid'>con</span><span class='hs-layout'>,</span> <span class='hs-varid'>params</span><span class='hs-layout'>,</span> <span class='hs-sel'>_use_mask</span><span class='hs-layout'>,</span>
<a name="line-12"></a>			    <span class='hs-layout'>(</span><span class='hs-conid'>StgApp</span> <span class='hs-varid'>selectee</span> <span class='hs-keyglyph'>[</span><span class='hs-comment'>{-no args-}</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span>
<a name="line-13"></a>  <span class='hs-keyglyph'>|</span>  <span class='hs-varid'>the_fv</span> <span class='hs-varop'>==</span> <span class='hs-varid'>scrutinee</span>		<span class='hs-comment'>-- Scrutinee is the only free variable</span>
<a name="line-14"></a>  <span class='hs-varop'>&amp;&amp;</span> <span class='hs-varid'>maybeToBool</span> <span class='hs-varid'>maybe_offset</span>		<span class='hs-comment'>-- Selectee is a component of the tuple</span>
<a name="line-15"></a>  <span class='hs-varop'>&amp;&amp;</span> <span class='hs-varid'>offset_into_int</span> <span class='hs-varop'>&lt;=</span> <span class='hs-varid'>mAX_SPEC_SELECTEE_SIZE</span>	<span class='hs-comment'>-- Offset is small enough</span>
<a name="line-16"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-comment'>-- NOT TRUE: ASSERT(is_single_constructor)</span>
<a name="line-17"></a>    <span class='hs-comment'>-- The simplifier may have statically determined that the single alternative</span>
<a name="line-18"></a>    <span class='hs-comment'>-- is the only possible case and eliminated the others, even if there are</span>
<a name="line-19"></a>    <span class='hs-comment'>-- other constructors in the datatype.  It's still ok to make a selector</span>
<a name="line-20"></a>    <span class='hs-comment'>-- thunk in this case, because we *know* which constructor the scrutinee</span>
<a name="line-21"></a>    <span class='hs-comment'>-- will evaluate to.</span>
<a name="line-22"></a>    <span class='hs-varid'>setSRT</span> <span class='hs-varid'>srt</span> <span class='hs-varop'>$</span> <span class='hs-varid'>cgStdRhsClosure</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>cc</span> <span class='hs-varid'>bi</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>the_fv</span><span class='hs-keyglyph'>]</span> <span class='hs-conid'>[]</span> <span class='hs-varid'>body</span> <span class='hs-varid'>lf_info</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>StgVarArg</span> <span class='hs-varid'>the_fv</span><span class='hs-keyglyph'>]</span>
<a name="line-23"></a>  <span class='hs-keyword'>where</span>
<a name="line-24"></a>    <span class='hs-varid'>lf_info</span> 		  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkSelectorLFInfo</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>offset_into_int</span>
<a name="line-25"></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-26"></a>    <span class='hs-layout'>(</span><span class='hs-keyword'>_</span><span class='hs-layout'>,</span> <span class='hs-varid'>params_w_offsets</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>layOutDynConstr</span> <span class='hs-varid'>con</span> <span class='hs-layout'>(</span><span class='hs-varid'>addIdReps</span> <span class='hs-varid'>params</span><span class='hs-layout'>)</span>
<a name="line-27"></a>			<span class='hs-comment'>-- Just want the layout</span>
<a name="line-28"></a>    <span class='hs-varid'>maybe_offset</span>	  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>assocMaybe</span> <span class='hs-varid'>params_w_offsets</span> <span class='hs-varid'>selectee</span>
<a name="line-29"></a>    <span class='hs-conid'>Just</span> <span class='hs-varid'>the_offset</span> 	  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>maybe_offset</span>
<a name="line-30"></a>    <span class='hs-varid'>offset_into_int</span>       <span class='hs-keyglyph'>=</span> <span class='hs-varid'>the_offset</span> <span class='hs-comment'>-</span> <span class='hs-varid'>fixedHdrSize</span>
</pre>\end{code}

Ap thunks
~~~~~~~~~

A more generic AP thunk of the form

	x = [ x_1...x_n ] \.. [] -> x_1 ... x_n

A set of these is compiled statically into the RTS, so we just use
those.  We could extend the idea to thunks where some of the x_i are
global ids (and hence not free variables), but this would entail
generating a larger thunk.  It might be an option for non-optimising
compilation, though.

We only generate an Ap thunk if all the free variables are pointers,
for semi-obvious reasons.

\begin{code}
<pre><a name="line-1"></a><a name="mkRhsClosure"></a><span class='hs-definition'>mkRhsClosure</span>    <span class='hs-varid'>bndr</span> <span class='hs-varid'>cc</span> <span class='hs-varid'>bi</span>
<a name="line-2"></a>		<span class='hs-varid'>fvs</span>
<a name="line-3"></a>		<span class='hs-varid'>upd_flag</span>
<a name="line-4"></a>		<span class='hs-conid'>[]</span>			<span class='hs-comment'>-- No args; a thunk</span>
<a name="line-5"></a>		<span class='hs-varid'>body</span><span class='hs-keyglyph'>@</span><span class='hs-layout'>(</span><span class='hs-conid'>StgApp</span> <span class='hs-varid'>fun_id</span> <span class='hs-varid'>args</span><span class='hs-layout'>)</span>
<a name="line-6"></a>
<a name="line-7"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-varid'>args</span> <span class='hs-varop'>`lengthIs`</span> <span class='hs-layout'>(</span><span class='hs-varid'>arity</span><span class='hs-comment'>-</span><span class='hs-num'>1</span><span class='hs-layout'>)</span>
<a name="line-8"></a> 	<span class='hs-varop'>&amp;&amp;</span> <span class='hs-varid'>all</span> <span class='hs-varid'>isFollowableArg</span> <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-varid'>idCgRep</span> <span class='hs-varid'>fvs</span><span class='hs-layout'>)</span> 
<a name="line-9"></a> 	<span class='hs-varop'>&amp;&amp;</span> <span class='hs-varid'>isUpdatable</span> <span class='hs-varid'>upd_flag</span>
<a name="line-10"></a> 	<span class='hs-varop'>&amp;&amp;</span> <span class='hs-varid'>arity</span> <span class='hs-varop'>&lt;=</span> <span class='hs-varid'>mAX_SPEC_AP_SIZE</span> 
<a name="line-11"></a>
<a name="line-12"></a> 		   <span class='hs-comment'>-- Ha! an Ap thunk</span>
<a name="line-13"></a>	<span class='hs-keyglyph'>=</span> <span class='hs-varid'>cgStdRhsClosure</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>cc</span> <span class='hs-varid'>bi</span> <span class='hs-varid'>fvs</span> <span class='hs-conid'>[]</span> <span class='hs-varid'>body</span> <span class='hs-varid'>lf_info</span> <span class='hs-varid'>payload</span>
<a name="line-14"></a>
<a name="line-15"></a>   <span class='hs-keyword'>where</span>
<a name="line-16"></a>	<span class='hs-varid'>lf_info</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkApLFInfo</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>upd_flag</span> <span class='hs-varid'>arity</span>
<a name="line-17"></a>	<span class='hs-comment'>-- the payload has to be in the correct order, hence we can't</span>
<a name="line-18"></a> 	<span class='hs-comment'>-- just use the fvs.</span>
<a name="line-19"></a>	<span class='hs-varid'>payload</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>StgVarArg</span> <span class='hs-varid'>fun_id</span> <span class='hs-conop'>:</span> <span class='hs-varid'>args</span>
<a name="line-20"></a>	<span class='hs-varid'>arity</span> 	<span class='hs-keyglyph'>=</span> <span class='hs-varid'>length</span> <span class='hs-varid'>fvs</span>
</pre>\end{code}

The default case
~~~~~~~~~~~~~~~~
\begin{code}
<pre><a name="line-1"></a><a name="mkRhsClosure"></a><span class='hs-definition'>mkRhsClosure</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>cc</span> <span class='hs-varid'>bi</span> <span class='hs-varid'>fvs</span> <span class='hs-varid'>upd_flag</span> <span class='hs-varid'>args</span> <span class='hs-varid'>body</span>
<a name="line-2"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>cgRhsClosure</span> <span class='hs-varid'>bndr</span> <span class='hs-varid'>cc</span> <span class='hs-varid'>bi</span> <span class='hs-varid'>fvs</span> <span class='hs-varid'>upd_flag</span> <span class='hs-varid'>args</span> <span class='hs-varid'>body</span>
</pre>\end{code}


%********************************************************
%*							*
%*		Let-no-escape bindings
%*							*
%********************************************************
\begin{code}
<pre><a name="line-1"></a><a name="cgLetNoEscapeBindings"></a><span class='hs-definition'>cgLetNoEscapeBindings</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>StgLiveVars</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>EndOfBlockInfo</span>
<a name="line-2"></a>                      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Maybe</span> <span class='hs-conid'>VirtualSpOffset</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>GenStgBinding</span> <span class='hs-conid'>Id</span> <span class='hs-conid'>Id</span>
<a name="line-3"></a>                      <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Code</span>
<a name="line-4"></a><span class='hs-definition'>cgLetNoEscapeBindings</span> <span class='hs-varid'>live_in_rhss</span> <span class='hs-varid'>rhs_eob_info</span> <span class='hs-varid'>maybe_cc_slot</span> 
<a name="line-5"></a>	<span class='hs-layout'>(</span><span class='hs-conid'>StgNonRec</span> <span class='hs-varid'>binder</span> <span class='hs-varid'>rhs</span><span class='hs-layout'>)</span>
<a name="line-6"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>	<span class='hs-layout'>{</span> <span class='hs-layout'>(</span><span class='hs-varid'>binder</span><span class='hs-layout'>,</span><span class='hs-varid'>info</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>cgLetNoEscapeRhs</span> <span class='hs-varid'>live_in_rhss</span> <span class='hs-varid'>rhs_eob_info</span> 
<a name="line-7"></a>					    <span class='hs-varid'>maybe_cc_slot</span> 	
<a name="line-8"></a>					    <span class='hs-conid'>NonRecursive</span> <span class='hs-varid'>binder</span> <span class='hs-varid'>rhs</span> 
<a name="line-9"></a>	<span class='hs-layout'>;</span> <span class='hs-varid'>addBindC</span> <span class='hs-varid'>binder</span> <span class='hs-varid'>info</span> <span class='hs-layout'>}</span>
<a name="line-10"></a>
<a name="line-11"></a><span class='hs-definition'>cgLetNoEscapeBindings</span> <span class='hs-varid'>live_in_rhss</span> <span class='hs-varid'>rhs_eob_info</span> <span class='hs-varid'>maybe_cc_slot</span> <span class='hs-layout'>(</span><span class='hs-conid'>StgRec</span> <span class='hs-varid'>pairs</span><span class='hs-layout'>)</span>
<a name="line-12"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-keyword'>do</span>	<span class='hs-layout'>{</span> <span class='hs-varid'>new_bindings</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>fixC</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span> <span class='hs-varid'>new_bindings</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyword'>do</span>
<a name="line-13"></a>		<span class='hs-layout'>{</span> <span class='hs-varid'>addBindsC</span> <span class='hs-varid'>new_bindings</span>
<a name="line-14"></a>		<span class='hs-layout'>;</span> <span class='hs-varid'>listFCs</span> <span class='hs-keyglyph'>[</span> <span class='hs-varid'>cgLetNoEscapeRhs</span> <span class='hs-varid'>full_live_in_rhss</span> 
<a name="line-15"></a>				<span class='hs-varid'>rhs_eob_info</span> <span class='hs-varid'>maybe_cc_slot</span> <span class='hs-conid'>Recursive</span> <span class='hs-varid'>b</span> <span class='hs-varid'>e</span> 
<a name="line-16"></a>			  <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-varid'>b</span><span class='hs-layout'>,</span><span class='hs-varid'>e</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>pairs</span> <span class='hs-keyglyph'>]</span> <span class='hs-layout'>}</span><span class='hs-layout'>)</span>
<a name="line-17"></a>
<a name="line-18"></a>	<span class='hs-layout'>;</span> <span class='hs-varid'>addBindsC</span> <span class='hs-varid'>new_bindings</span> <span class='hs-layout'>}</span>
<a name="line-19"></a>  <span class='hs-keyword'>where</span>
<a name="line-20"></a>    <span class='hs-comment'>-- We add the binders to the live-in-rhss set so that we don't</span>
<a name="line-21"></a>    <span class='hs-comment'>-- delete the bindings for the binder from the environment!</span>
<a name="line-22"></a>    <span class='hs-varid'>full_live_in_rhss</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>live_in_rhss</span> <span class='hs-varop'>`unionVarSet`</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkVarSet</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>b</span> <span class='hs-keyglyph'>|</span> <span class='hs-layout'>(</span><span class='hs-varid'>b</span><span class='hs-layout'>,</span><span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>pairs</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span>
<a name="line-23"></a>
<a name="line-24"></a><a name="cgLetNoEscapeRhs"></a><span class='hs-definition'>cgLetNoEscapeRhs</span>
<a name="line-25"></a>    <span class='hs-keyglyph'>::</span> <span class='hs-conid'>StgLiveVars</span>	<span class='hs-comment'>-- Live in rhss</span>
<a name="line-26"></a>    <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>EndOfBlockInfo</span>
<a name="line-27"></a>    <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Maybe</span> <span class='hs-conid'>VirtualSpOffset</span>
<a name="line-28"></a>    <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>RecFlag</span>
<a name="line-29"></a>    <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Id</span>
<a name="line-30"></a>    <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>StgRhs</span>
<a name="line-31"></a>    <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>FCode</span> <span class='hs-layout'>(</span><span class='hs-conid'>Id</span><span class='hs-layout'>,</span> <span class='hs-conid'>CgIdInfo</span><span class='hs-layout'>)</span>
<a name="line-32"></a>
<a name="line-33"></a><span class='hs-definition'>cgLetNoEscapeRhs</span> <span class='hs-varid'>full_live_in_rhss</span> <span class='hs-varid'>rhs_eob_info</span> <span class='hs-varid'>maybe_cc_slot</span> <span class='hs-varid'>rec</span> <span class='hs-varid'>binder</span>
<a name="line-34"></a>		 <span class='hs-layout'>(</span><span class='hs-conid'>StgRhsClosure</span> <span class='hs-varid'>cc</span> <span class='hs-varid'>bi</span> <span class='hs-keyword'>_</span> <span class='hs-sel'>_upd_flag</span> <span class='hs-varid'>srt</span> <span class='hs-varid'>args</span> <span class='hs-varid'>body</span><span class='hs-layout'>)</span>
<a name="line-35"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-comment'>-- We could check the update flag, but currently we don't switch it off</span>
<a name="line-36"></a>    <span class='hs-comment'>-- for let-no-escaped things, so we omit the check too!</span>
<a name="line-37"></a>    <span class='hs-comment'>-- case upd_flag of</span>
<a name="line-38"></a>    <span class='hs-comment'>--     Updatable -&gt; panic "cgLetNoEscapeRhs"	-- Nothing to update!</span>
<a name="line-39"></a>    <span class='hs-comment'>--     other     -&gt; cgLetNoEscapeClosure binder cc bi live_in_whole_let live_in_rhss args body</span>
<a name="line-40"></a>    <span class='hs-varid'>setSRT</span> <span class='hs-varid'>srt</span> <span class='hs-varop'>$</span> <span class='hs-varid'>cgLetNoEscapeClosure</span> <span class='hs-varid'>binder</span> <span class='hs-varid'>cc</span> <span class='hs-varid'>bi</span> <span class='hs-varid'>full_live_in_rhss</span> <span class='hs-varid'>rhs_eob_info</span>
<a name="line-41"></a>	<span class='hs-varid'>maybe_cc_slot</span> <span class='hs-varid'>rec</span> <span class='hs-varid'>args</span> <span class='hs-varid'>body</span>
<a name="line-42"></a>
<a name="line-43"></a><span class='hs-comment'>-- For a constructor RHS we want to generate a single chunk of code which</span>
<a name="line-44"></a><span class='hs-comment'>-- can be jumped to from many places, which will return the constructor.</span>
<a name="line-45"></a><span class='hs-comment'>-- It's easy; just behave as if it was an StgRhsClosure with a ConApp inside!</span>
<a name="line-46"></a><span class='hs-definition'>cgLetNoEscapeRhs</span> <span class='hs-varid'>full_live_in_rhss</span> <span class='hs-varid'>rhs_eob_info</span> <span class='hs-varid'>maybe_cc_slot</span> <span class='hs-varid'>rec</span> <span class='hs-varid'>binder</span>
<a name="line-47"></a>    	    	 <span class='hs-layout'>(</span><span class='hs-conid'>StgRhsCon</span> <span class='hs-varid'>cc</span> <span class='hs-varid'>con</span> <span class='hs-varid'>args</span><span class='hs-layout'>)</span>
<a name="line-48"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-varid'>setSRT</span> <span class='hs-conid'>NoSRT</span> <span class='hs-varop'>$</span> <span class='hs-varid'>cgLetNoEscapeClosure</span> <span class='hs-varid'>binder</span> <span class='hs-varid'>cc</span> <span class='hs-varid'>noBinderInfo</span><span class='hs-comment'>{-safe-}</span>
<a name="line-49"></a>			 <span class='hs-varid'>full_live_in_rhss</span> <span class='hs-varid'>rhs_eob_info</span> <span class='hs-varid'>maybe_cc_slot</span> <span class='hs-varid'>rec</span>
<a name="line-50"></a>	<span class='hs-conid'>[]</span> 	<span class='hs-comment'>--No args; the binder is data structure, not a function</span>
<a name="line-51"></a>	<span class='hs-layout'>(</span><span class='hs-conid'>StgConApp</span> <span class='hs-varid'>con</span> <span class='hs-varid'>args</span><span class='hs-layout'>)</span>
</pre>\end{code}

Little helper for primitives that return unboxed tuples.

\begin{code}
<pre><a name="line-1"></a><a name="newUnboxedTupleRegs"></a><span class='hs-definition'>newUnboxedTupleRegs</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>Type</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>FCode</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>[</span><span class='hs-conid'>CgRep</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>,</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>LocalReg</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>,</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>ForeignHint</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span>
<a name="line-2"></a><span class='hs-definition'>newUnboxedTupleRegs</span> <span class='hs-varid'>res_ty</span> <span class='hs-keyglyph'>=</span>
<a name="line-3"></a>   <span class='hs-keyword'>let</span>
<a name="line-4"></a>	<span class='hs-varid'>ty_args</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>tyConAppArgs</span> <span class='hs-layout'>(</span><span class='hs-varid'>repType</span> <span class='hs-varid'>res_ty</span><span class='hs-layout'>)</span>
<a name="line-5"></a>	<span class='hs-layout'>(</span><span class='hs-varid'>reps</span><span class='hs-layout'>,</span><span class='hs-varid'>hints</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>unzip</span> <span class='hs-keyglyph'>[</span> <span class='hs-layout'>(</span><span class='hs-varid'>rep</span><span class='hs-layout'>,</span> <span class='hs-varid'>typeForeignHint</span> <span class='hs-varid'>ty</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>|</span> <span class='hs-varid'>ty</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>ty_args</span><span class='hs-layout'>,</span>
<a name="line-6"></a>					   	    <span class='hs-keyword'>let</span> <span class='hs-varid'>rep</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>typeCgRep</span> <span class='hs-varid'>ty</span><span class='hs-layout'>,</span>
<a name="line-7"></a>					 	    <span class='hs-varid'>nonVoidArg</span> <span class='hs-varid'>rep</span> <span class='hs-keyglyph'>]</span>
<a name="line-8"></a>	<span class='hs-varid'>make_new_temp</span> <span class='hs-varid'>rep</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>newTemp</span> <span class='hs-layout'>(</span><span class='hs-varid'>argMachRep</span> <span class='hs-varid'>rep</span><span class='hs-layout'>)</span>
<a name="line-9"></a>   <span class='hs-keyword'>in</span> <span class='hs-keyword'>do</span>
<a name="line-10"></a>   <span class='hs-varid'>regs</span> <span class='hs-keyglyph'>&lt;-</span> <span class='hs-varid'>mapM</span> <span class='hs-varid'>make_new_temp</span> <span class='hs-varid'>reps</span>
<a name="line-11"></a>   <span class='hs-varid'>return</span> <span class='hs-layout'>(</span><span class='hs-varid'>reps</span><span class='hs-layout'>,</span><span class='hs-varid'>regs</span><span class='hs-layout'>,</span><span class='hs-varid'>hints</span><span class='hs-layout'>)</span>
</pre>\end{code}
</body>
</html>