Sophie

Sophie

distrib > Fedora > 14 > i386 > by-pkgid > 8d1ef08c9e0d44c69764afc615a03d0d > files > 1644

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>cmm/CmmBrokenBlock.hs</title>
<link type='text/css' rel='stylesheet' href='hscolour.css' />
</head>
<body>
<pre><a name="line-1"></a>
<a name="line-2"></a><span class='hs-keyword'>module</span> <span class='hs-conid'>CmmBrokenBlock</span> <span class='hs-layout'>(</span>
<a name="line-3"></a>  <span class='hs-conid'>BrokenBlock</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span>
<a name="line-4"></a>  <span class='hs-conid'>BlockEntryInfo</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span>
<a name="line-5"></a>  <span class='hs-conid'>FinalStmt</span><span class='hs-layout'>(</span><span class='hs-keyglyph'>..</span><span class='hs-layout'>)</span><span class='hs-layout'>,</span>
<a name="line-6"></a>  <span class='hs-varid'>breakBlock</span><span class='hs-layout'>,</span>
<a name="line-7"></a>  <span class='hs-varid'>cmmBlockFromBrokenBlock</span><span class='hs-layout'>,</span>
<a name="line-8"></a>  <span class='hs-varid'>blocksToBlockEnv</span><span class='hs-layout'>,</span>
<a name="line-9"></a>  <span class='hs-varid'>adaptBlockToFormat</span><span class='hs-layout'>,</span>
<a name="line-10"></a>  <span class='hs-varid'>selectContinuations</span><span class='hs-layout'>,</span>
<a name="line-11"></a>  <span class='hs-conid'>ContFormat</span><span class='hs-layout'>,</span>
<a name="line-12"></a>  <span class='hs-varid'>makeContinuationEntries</span>
<a name="line-13"></a>  <span class='hs-layout'>)</span> <span class='hs-keyword'>where</span>
<a name="line-14"></a>
<a name="line-15"></a><span class='hs-cpp'>#include "HsVersions.h"</span>
<a name="line-16"></a>
<a name="line-17"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>BlockId</span>
<a name="line-18"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Cmm</span>
<a name="line-19"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CmmUtils</span>
<a name="line-20"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CLabel</span>
<a name="line-21"></a>
<a name="line-22"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>CgUtils</span> <span class='hs-layout'>(</span><span class='hs-varid'>callerSaveVolatileRegs</span><span class='hs-layout'>)</span>
<a name="line-23"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>ClosureInfo</span>
<a name="line-24"></a>
<a name="line-25"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Maybes</span>
<a name="line-26"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Data</span><span class='hs-varop'>.</span><span class='hs-conid'>List</span>
<a name="line-27"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Panic</span>
<a name="line-28"></a><span class='hs-keyword'>import</span> <span class='hs-conid'>Unique</span>
<a name="line-29"></a>
<a name="line-30"></a><span class='hs-comment'>-- This module takes a 'CmmBasicBlock' which might have 'CmmCall'</span>
<a name="line-31"></a><span class='hs-comment'>-- statements in it with 'CmmSafe' set and breaks it up at each such call.</span>
<a name="line-32"></a><span class='hs-comment'>-- It also collects information about the block for later use</span>
<a name="line-33"></a><span class='hs-comment'>-- by the CPS algorithm.</span>
<a name="line-34"></a>
<a name="line-35"></a><span class='hs-comment'>-----------------------------------------------------------------------------</span>
<a name="line-36"></a><span class='hs-comment'>-- Data structures</span>
<a name="line-37"></a><span class='hs-comment'>-----------------------------------------------------------------------------</span>
<a name="line-38"></a>
<a name="line-39"></a><a name="BrokenBlock"></a><span class='hs-comment'>-- |Similar to a 'CmmBlock' with a little extra information</span>
<a name="line-40"></a><a name="BrokenBlock"></a><span class='hs-comment'>-- to help the CPS analysis.</span>
<a name="line-41"></a><a name="BrokenBlock"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>BrokenBlock</span>
<a name="line-42"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>BrokenBlock</span> <span class='hs-layout'>{</span>
<a name="line-43"></a>      <span class='hs-varid'>brokenBlockId</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>BlockId</span><span class='hs-layout'>,</span> <span class='hs-comment'>-- ^ The block's label like a 'CmmBasicBlock'</span>
<a name="line-44"></a>      <span class='hs-varid'>brokenBlockEntry</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>BlockEntryInfo</span><span class='hs-layout'>,</span>
<a name="line-45"></a>                                <span class='hs-comment'>-- ^ Ways this block can be entered</span>
<a name="line-46"></a>
<a name="line-47"></a>      <span class='hs-varid'>brokenBlockStmts</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>CmmStmt</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>,</span>
<a name="line-48"></a>                                <span class='hs-comment'>-- ^ Body like a CmmBasicBlock</span>
<a name="line-49"></a>                                <span class='hs-comment'>-- (but without the last statement)</span>
<a name="line-50"></a>
<a name="line-51"></a>      <span class='hs-varid'>brokenBlockTargets</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>BlockId</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>,</span>
<a name="line-52"></a>                                <span class='hs-comment'>-- ^ Blocks that this block could</span>
<a name="line-53"></a>                                <span class='hs-comment'>-- branch to either by conditional</span>
<a name="line-54"></a>                                <span class='hs-comment'>-- branches or via the last statement</span>
<a name="line-55"></a>
<a name="line-56"></a>      <span class='hs-varid'>brokenBlockExit</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>FinalStmt</span>
<a name="line-57"></a>                                <span class='hs-comment'>-- ^ The final statement of the block</span>
<a name="line-58"></a>    <span class='hs-layout'>}</span>
<a name="line-59"></a>
<a name="line-60"></a><a name="BlockEntryInfo"></a><span class='hs-comment'>-- | How a block could be entered</span>
<a name="line-61"></a><a name="BlockEntryInfo"></a><span class='hs-comment'>-- See Note [An example of CPS conversion]</span>
<a name="line-62"></a><a name="BlockEntryInfo"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>BlockEntryInfo</span>
<a name="line-63"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>FunctionEntry</span> <span class='hs-conid'>CmmInfo</span> <span class='hs-conid'>CLabel</span> <span class='hs-conid'>CmmFormals</span>
<a name="line-64"></a>      <span class='hs-comment'>-- ^ Block is the beginning of a function, parameters are:</span>
<a name="line-65"></a>      <span class='hs-comment'>--   1. Function header info</span>
<a name="line-66"></a>      <span class='hs-comment'>--   2. The function name</span>
<a name="line-67"></a>      <span class='hs-comment'>--   3. Aguments to function</span>
<a name="line-68"></a>      <span class='hs-comment'>-- Only the formal parameters are live</span>
<a name="line-69"></a>
<a name="line-70"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>ContinuationEntry</span> <span class='hs-conid'>CmmFormals</span> <span class='hs-conid'>C_SRT</span> <span class='hs-conid'>Bool</span>
<a name="line-71"></a>      <span class='hs-comment'>-- ^ Return point of a function call, parameters are:</span>
<a name="line-72"></a>      <span class='hs-comment'>--   1. return values (argument to continuation)</span>
<a name="line-73"></a>      <span class='hs-comment'>--   2. SRT for the continuation's info table</span>
<a name="line-74"></a>      <span class='hs-comment'>--   3. True &lt;=&gt; GC block so ignore stack size</span>
<a name="line-75"></a>      <span class='hs-comment'>-- Live variables, other than</span>
<a name="line-76"></a>      <span class='hs-comment'>-- the return values, are on the stack</span>
<a name="line-77"></a>
<a name="line-78"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>ControlEntry</span>
<a name="line-79"></a>      <span class='hs-comment'>-- ^ Any other kind of block.  Only entered due to control flow.</span>
<a name="line-80"></a>
<a name="line-81"></a>  <span class='hs-comment'>-- TODO: Consider adding ProcPointEntry</span>
<a name="line-82"></a>  <span class='hs-comment'>-- no return values, but some live might end up as</span>
<a name="line-83"></a>  <span class='hs-comment'>-- params or possibly in the frame</span>
<a name="line-84"></a>
<a name="line-85"></a><span class='hs-comment'>{-	Note [An example of CPS conversion]
<a name="line-86"></a>
<a name="line-87"></a>This is NR's and SLPJ's guess about how things might work;
<a name="line-88"></a>it may not be consistent with the actual code (particularly
<a name="line-89"></a>in the matter of what's in parameters and what's on the stack).
<a name="line-90"></a>
<a name="line-91"></a>f(x,y) {
<a name="line-92"></a>   if x&gt;2 then goto L
<a name="line-93"></a>   x = x+1
<a name="line-94"></a>L: if x&gt;1 then y = g(y)
<a name="line-95"></a>        else x = x+1 ;
<a name="line-96"></a>   return( x+y )
<a name="line-97"></a>}
<a name="line-98"></a>	BECOMES
<a name="line-99"></a>
<a name="line-100"></a>f(x,y) {   // FunctionEntry
<a name="line-101"></a>   if x&gt;2 then goto L
<a name="line-102"></a>   x = x+1
<a name="line-103"></a>L: 	   // ControlEntry
<a name="line-104"></a>   if x&gt;1 then push x; push f1; jump g(y)
<a name="line-105"></a>        else x=x+1; jump f2(x, y)
<a name="line-106"></a>}
<a name="line-107"></a>
<a name="line-108"></a>f1(y) {    // ContinuationEntry
<a name="line-109"></a>  pop x; jump f2(x, y);
<a name="line-110"></a>}
<a name="line-111"></a>  
<a name="line-112"></a>f2(x, y) { // ProcPointEntry
<a name="line-113"></a>  return (z+y);
<a name="line-114"></a>}
<a name="line-115"></a>
<a name="line-116"></a>-}</span>
<a name="line-117"></a>
<a name="line-118"></a><a name="ContFormat"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>ContFormat</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>ContFormat</span> <span class='hs-conid'>HintedCmmFormals</span> <span class='hs-conid'>C_SRT</span> <span class='hs-conid'>Bool</span>
<a name="line-119"></a>      <span class='hs-comment'>-- ^ Arguments</span>
<a name="line-120"></a>      <span class='hs-comment'>--   1. return values (argument to continuation)</span>
<a name="line-121"></a>      <span class='hs-comment'>--   2. SRT for the continuation's info table</span>
<a name="line-122"></a>      <span class='hs-comment'>--   3. True &lt;=&gt; GC block so ignore stack size</span>
<a name="line-123"></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-124"></a>
<a name="line-125"></a><a name="FinalStmt"></a><span class='hs-comment'>-- | Final statement in a 'BlokenBlock'.</span>
<a name="line-126"></a><a name="FinalStmt"></a><span class='hs-comment'>-- Constructors and arguments match those in 'Cmm',</span>
<a name="line-127"></a><a name="FinalStmt"></a><span class='hs-comment'>-- but are restricted to branches, returns, jumps, calls and switches</span>
<a name="line-128"></a><a name="FinalStmt"></a><span class='hs-keyword'>data</span> <span class='hs-conid'>FinalStmt</span>
<a name="line-129"></a>  <span class='hs-keyglyph'>=</span> <span class='hs-conid'>FinalBranch</span> <span class='hs-conid'>BlockId</span>
<a name="line-130"></a>    <span class='hs-comment'>-- ^ Same as 'CmmBranch'.  Target must be a ControlEntry</span>
<a name="line-131"></a>
<a name="line-132"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>FinalReturn</span> <span class='hs-conid'>HintedCmmActuals</span>
<a name="line-133"></a>    <span class='hs-comment'>-- ^ Same as 'CmmReturn'. Parameter is the return values.</span>
<a name="line-134"></a>
<a name="line-135"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>FinalJump</span> <span class='hs-conid'>CmmExpr</span> <span class='hs-conid'>HintedCmmActuals</span>
<a name="line-136"></a>    <span class='hs-comment'>-- ^ Same as 'CmmJump'.  Parameters:</span>
<a name="line-137"></a>    <span class='hs-comment'>--   1. The function to call,</span>
<a name="line-138"></a>    <span class='hs-comment'>--   2. Arguments of the call</span>
<a name="line-139"></a>
<a name="line-140"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>FinalCall</span> <span class='hs-conid'>BlockId</span> <span class='hs-conid'>CmmCallTarget</span> <span class='hs-conid'>HintedCmmFormals</span> <span class='hs-conid'>HintedCmmActuals</span>
<a name="line-141"></a>              <span class='hs-conid'>C_SRT</span>   <span class='hs-conid'>CmmReturnInfo</span> <span class='hs-conid'>Bool</span>
<a name="line-142"></a>      <span class='hs-comment'>-- ^ Same as 'CmmCallee' followed by 'CmmGoto'.  Parameters:</span>
<a name="line-143"></a>      <span class='hs-comment'>--   1. Target of the 'CmmGoto' (must be a 'ContinuationEntry')</span>
<a name="line-144"></a>      <span class='hs-comment'>--   2. The function to call</span>
<a name="line-145"></a>      <span class='hs-comment'>--   3. Results from call (redundant with ContinuationEntry)</span>
<a name="line-146"></a>      <span class='hs-comment'>--   4. Arguments to call</span>
<a name="line-147"></a>      <span class='hs-comment'>--   5. SRT for the continuation's info table</span>
<a name="line-148"></a>      <span class='hs-comment'>--   6. Does the function return?</span>
<a name="line-149"></a>      <span class='hs-comment'>--   7. True &lt;=&gt; GC block so ignore stack size</span>
<a name="line-150"></a>
<a name="line-151"></a>  <span class='hs-keyglyph'>|</span> <span class='hs-conid'>FinalSwitch</span> <span class='hs-conid'>CmmExpr</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Maybe</span> <span class='hs-conid'>BlockId</span><span class='hs-keyglyph'>]</span>
<a name="line-152"></a>      <span class='hs-comment'>-- ^ Same as a 'CmmSwitch'.  Paremeters:</span>
<a name="line-153"></a>      <span class='hs-comment'>--   1. Scrutinee (zero based)</span>
<a name="line-154"></a>      <span class='hs-comment'>--   2. Targets</span>
<a name="line-155"></a>
<a name="line-156"></a><span class='hs-comment'>-----------------------------------------------------------------------------</span>
<a name="line-157"></a><span class='hs-comment'>-- Operations for broken blocks</span>
<a name="line-158"></a><span class='hs-comment'>-----------------------------------------------------------------------------</span>
<a name="line-159"></a>
<a name="line-160"></a><span class='hs-comment'>-- Naively breaking at *every* CmmCall leads to sub-optimal code.</span>
<a name="line-161"></a><span class='hs-comment'>-- In particular, a CmmCall followed by a CmmBranch would result</span>
<a name="line-162"></a><span class='hs-comment'>-- in a continuation that has the single CmmBranch statement in it.</span>
<a name="line-163"></a><span class='hs-comment'>-- It would be better have the CmmCall directly return to the block</span>
<a name="line-164"></a><span class='hs-comment'>-- that the branch jumps to.</span>
<a name="line-165"></a><span class='hs-comment'>--</span>
<a name="line-166"></a><span class='hs-comment'>-- This requires the target of the branch to look like the parameter</span>
<a name="line-167"></a><span class='hs-comment'>-- format that the CmmCall is expecting.  If other CmmCall/CmmBranch</span>
<a name="line-168"></a><span class='hs-comment'>-- sequences go to the same place they might not be expecting the</span>
<a name="line-169"></a><span class='hs-comment'>-- same format.  So this transformation uses the following solution.</span>
<a name="line-170"></a><span class='hs-comment'>-- First the blocks are broken up but none of the blocks are marked</span>
<a name="line-171"></a><span class='hs-comment'>-- as continuations yet.  This is the 'breakBlock' function.</span>
<a name="line-172"></a><span class='hs-comment'>-- Second, the blocks "vote" on what other blocks need to be continuations</span>
<a name="line-173"></a><span class='hs-comment'>-- and how they should be layed out.  Plurality wins, but other selection</span>
<a name="line-174"></a><span class='hs-comment'>-- methods could be selected at a later time.</span>
<a name="line-175"></a><span class='hs-comment'>-- This is the 'selectContinuations' function.</span>
<a name="line-176"></a><span class='hs-comment'>-- Finally, the blocks are upgraded to 'ContEntry' continuations</span>
<a name="line-177"></a><span class='hs-comment'>-- based on the results with the 'makeContinuationEntries' function,</span>
<a name="line-178"></a><span class='hs-comment'>-- and the blocks that didn't get the format they wanted for their</span>
<a name="line-179"></a><span class='hs-comment'>-- targets get a small adaptor block created for them by</span>
<a name="line-180"></a><span class='hs-comment'>-- the 'adaptBlockToFormat' function.</span>
<a name="line-181"></a><span class='hs-comment'>-- could be </span>
<a name="line-182"></a>
<a name="line-183"></a><span class='hs-comment'>{-
<a name="line-184"></a>UNUSED: 2008-12-29
<a name="line-185"></a>
<a name="line-186"></a>breakProc ::
<a name="line-187"></a>    [BlockId]                   -- ^ Any GC blocks that should be special
<a name="line-188"></a>    -&gt; [[Unique]]               -- ^ An infinite list of uniques
<a name="line-189"></a>                                -- to create names of the new blocks with
<a name="line-190"></a>    -&gt; CmmInfo                  -- ^ Info table for the procedure
<a name="line-191"></a>    -&gt; CLabel                   -- ^ Name of the procedure
<a name="line-192"></a>    -&gt; CmmFormals               -- ^ Parameters of the procedure
<a name="line-193"></a>    -&gt; [CmmBasicBlock]          -- ^ Blocks of the procecure
<a name="line-194"></a>                                -- (First block is the entry block)
<a name="line-195"></a>    -&gt; [BrokenBlock]
<a name="line-196"></a>
<a name="line-197"></a>breakProc gc_block_idents uniques info ident params blocks =
<a name="line-198"></a>    let
<a name="line-199"></a>        (adaptor_uniques : block_uniques) = uniques
<a name="line-200"></a>
<a name="line-201"></a>        broken_blocks :: ([(BlockId, ContFormat)], [BrokenBlock])
<a name="line-202"></a>        broken_blocks =
<a name="line-203"></a>            let new_blocks =
<a name="line-204"></a>                    zipWith3 (breakBlock gc_block_idents)
<a name="line-205"></a>                             block_uniques
<a name="line-206"></a>                             blocks
<a name="line-207"></a>                             (FunctionEntry info ident params :
<a name="line-208"></a>                              repeat ControlEntry)
<a name="line-209"></a>            in (concatMap fst new_blocks, concatMap snd new_blocks)
<a name="line-210"></a>
<a name="line-211"></a>        selected = selectContinuations (fst broken_blocks)
<a name="line-212"></a>
<a name="line-213"></a>    in map (makeContinuationEntries selected) $
<a name="line-214"></a>       concat $
<a name="line-215"></a>       zipWith (adaptBlockToFormat selected)
<a name="line-216"></a>               adaptor_uniques
<a name="line-217"></a>               (snd broken_blocks)
<a name="line-218"></a>-}</span>
<a name="line-219"></a>
<a name="line-220"></a><span class='hs-comment'>-----------------------------------------------------------------------------</span>
<a name="line-221"></a><span class='hs-comment'>-- | Takes a 'CmmBasicBlock' and breaks it up into a list of 'BrokenBlock'</span>
<a name="line-222"></a><span class='hs-comment'>-- by splitting on each 'CmmCall' in the 'CmmBasicBlock'.</span>
<a name="line-223"></a>
<a name="line-224"></a><a name="breakBlock"></a><span class='hs-definition'>breakBlock</span> <span class='hs-keyglyph'>::</span>
<a name="line-225"></a>    <span class='hs-keyglyph'>[</span><span class='hs-conid'>BlockId</span><span class='hs-keyglyph'>]</span>                   <span class='hs-comment'>-- ^ Any GC blocks that should be special</span>
<a name="line-226"></a>    <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>Unique</span><span class='hs-keyglyph'>]</span>                 <span class='hs-comment'>-- ^ An infinite list of uniques</span>
<a name="line-227"></a>                                <span class='hs-comment'>-- to create names of the new blocks with</span>
<a name="line-228"></a>    <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CmmBasicBlock</span>            <span class='hs-comment'>-- ^ Input block to break apart</span>
<a name="line-229"></a>    <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>BlockEntryInfo</span>           <span class='hs-comment'>-- ^ Info for the first created 'BrokenBlock'</span>
<a name="line-230"></a>    <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-conid'>BlockId</span><span class='hs-layout'>,</span> <span class='hs-conid'>ContFormat</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>,</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>BrokenBlock</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span>
<a name="line-231"></a><span class='hs-definition'>breakBlock</span> <span class='hs-varid'>gc_block_idents</span> <span class='hs-varid'>uniques</span> <span class='hs-layout'>(</span><span class='hs-conid'>BasicBlock</span> <span class='hs-varid'>ident</span> <span class='hs-varid'>stmts</span><span class='hs-layout'>)</span> <span class='hs-varid'>entry</span> <span class='hs-keyglyph'>=</span>
<a name="line-232"></a>    <span class='hs-varid'>breakBlock'</span> <span class='hs-varid'>uniques</span> <span class='hs-varid'>ident</span> <span class='hs-varid'>entry</span> <span class='hs-conid'>[]</span> <span class='hs-conid'>[]</span> <span class='hs-varid'>stmts</span>
<a name="line-233"></a>    <span class='hs-keyword'>where</span>
<a name="line-234"></a>      <span class='hs-varid'>breakBlock'</span> <span class='hs-varid'>uniques</span> <span class='hs-varid'>current_id</span> <span class='hs-varid'>entry</span> <span class='hs-varid'>exits</span> <span class='hs-varid'>accum_stmts</span> <span class='hs-varid'>stmts</span> <span class='hs-keyglyph'>=</span>
<a name="line-235"></a>          <span class='hs-keyword'>case</span> <span class='hs-varid'>stmts</span> <span class='hs-keyword'>of</span>
<a name="line-236"></a>            <span class='hs-conid'>[]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>panic</span> <span class='hs-str'>"block doesn't end in jump, goto, return or switch"</span>
<a name="line-237"></a>
<a name="line-238"></a>            <span class='hs-comment'>-- Last statement.  Make the 'BrokenBlock'</span>
<a name="line-239"></a>            <span class='hs-keyglyph'>[</span><span class='hs-conid'>CmmJump</span> <span class='hs-varid'>target</span> <span class='hs-varid'>arguments</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span>
<a name="line-240"></a>                <span class='hs-layout'>(</span><span class='hs-conid'>[]</span><span class='hs-layout'>,</span>
<a name="line-241"></a>                 <span class='hs-keyglyph'>[</span><span class='hs-conid'>BrokenBlock</span> <span class='hs-varid'>current_id</span> <span class='hs-varid'>entry</span> <span class='hs-varid'>accum_stmts</span>
<a name="line-242"></a>                              <span class='hs-varid'>exits</span>
<a name="line-243"></a>                              <span class='hs-layout'>(</span><span class='hs-conid'>FinalJump</span> <span class='hs-varid'>target</span> <span class='hs-varid'>arguments</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span>
<a name="line-244"></a>            <span class='hs-keyglyph'>[</span><span class='hs-conid'>CmmReturn</span> <span class='hs-varid'>arguments</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span>
<a name="line-245"></a>                <span class='hs-layout'>(</span><span class='hs-conid'>[]</span><span class='hs-layout'>,</span>
<a name="line-246"></a>                 <span class='hs-keyglyph'>[</span><span class='hs-conid'>BrokenBlock</span> <span class='hs-varid'>current_id</span> <span class='hs-varid'>entry</span> <span class='hs-varid'>accum_stmts</span>
<a name="line-247"></a>                             <span class='hs-varid'>exits</span>
<a name="line-248"></a>                             <span class='hs-layout'>(</span><span class='hs-conid'>FinalReturn</span> <span class='hs-varid'>arguments</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span>
<a name="line-249"></a>            <span class='hs-keyglyph'>[</span><span class='hs-conid'>CmmBranch</span> <span class='hs-varid'>target</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span>
<a name="line-250"></a>                <span class='hs-layout'>(</span><span class='hs-conid'>[]</span><span class='hs-layout'>,</span>
<a name="line-251"></a>                 <span class='hs-keyglyph'>[</span><span class='hs-conid'>BrokenBlock</span> <span class='hs-varid'>current_id</span> <span class='hs-varid'>entry</span> <span class='hs-varid'>accum_stmts</span>
<a name="line-252"></a>                             <span class='hs-layout'>(</span><span class='hs-varid'>target</span><span class='hs-conop'>:</span><span class='hs-varid'>exits</span><span class='hs-layout'>)</span>
<a name="line-253"></a>                             <span class='hs-layout'>(</span><span class='hs-conid'>FinalBranch</span> <span class='hs-varid'>target</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span>
<a name="line-254"></a>            <span class='hs-keyglyph'>[</span><span class='hs-conid'>CmmSwitch</span> <span class='hs-varid'>expr</span> <span class='hs-varid'>targets</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span>
<a name="line-255"></a>                <span class='hs-layout'>(</span><span class='hs-conid'>[]</span><span class='hs-layout'>,</span>
<a name="line-256"></a>                 <span class='hs-keyglyph'>[</span><span class='hs-conid'>BrokenBlock</span> <span class='hs-varid'>current_id</span> <span class='hs-varid'>entry</span> <span class='hs-varid'>accum_stmts</span>
<a name="line-257"></a>                             <span class='hs-layout'>(</span><span class='hs-varid'>mapMaybe</span> <span class='hs-varid'>id</span> <span class='hs-varid'>targets</span> <span class='hs-varop'>++</span> <span class='hs-varid'>exits</span><span class='hs-layout'>)</span>
<a name="line-258"></a>                             <span class='hs-layout'>(</span><span class='hs-conid'>FinalSwitch</span> <span class='hs-varid'>expr</span> <span class='hs-varid'>targets</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span>
<a name="line-259"></a>
<a name="line-260"></a>            <span class='hs-comment'>-- These shouldn't happen in the middle of a block.</span>
<a name="line-261"></a>            <span class='hs-comment'>-- They would cause dead code.</span>
<a name="line-262"></a>            <span class='hs-layout'>(</span><span class='hs-conid'>CmmJump</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span><span class='hs-conop'>:</span><span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>panic</span> <span class='hs-str'>"jump in middle of block"</span>
<a name="line-263"></a>            <span class='hs-layout'>(</span><span class='hs-conid'>CmmReturn</span> <span class='hs-keyword'>_</span><span class='hs-conop'>:</span><span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>panic</span> <span class='hs-str'>"return in middle of block"</span>
<a name="line-264"></a>            <span class='hs-layout'>(</span><span class='hs-conid'>CmmBranch</span> <span class='hs-keyword'>_</span><span class='hs-conop'>:</span><span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>panic</span> <span class='hs-str'>"branch in middle of block"</span>
<a name="line-265"></a>            <span class='hs-layout'>(</span><span class='hs-conid'>CmmSwitch</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span><span class='hs-conop'>:</span><span class='hs-keyword'>_</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>panic</span> <span class='hs-str'>"switch in middle of block"</span>
<a name="line-266"></a>
<a name="line-267"></a>            <span class='hs-comment'>-- Detect this special case to remain an inverse of</span>
<a name="line-268"></a>            <span class='hs-comment'>-- 'cmmBlockFromBrokenBlock'</span>
<a name="line-269"></a>            <span class='hs-keyglyph'>[</span><span class='hs-conid'>CmmCall</span> <span class='hs-varid'>target</span> <span class='hs-varid'>results</span> <span class='hs-varid'>arguments</span> <span class='hs-layout'>(</span><span class='hs-conid'>CmmSafe</span> <span class='hs-varid'>srt</span><span class='hs-layout'>)</span> <span class='hs-varid'>ret</span><span class='hs-layout'>,</span>
<a name="line-270"></a>             <span class='hs-conid'>CmmBranch</span> <span class='hs-varid'>next_id</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span>
<a name="line-271"></a>                <span class='hs-layout'>(</span><span class='hs-keyglyph'>[</span><span class='hs-varid'>cont_info</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>,</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>block</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span>
<a name="line-272"></a>                <span class='hs-keyword'>where</span>
<a name="line-273"></a>                  <span class='hs-varid'>cont_info</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>next_id</span><span class='hs-layout'>,</span>
<a name="line-274"></a>                               <span class='hs-conid'>ContFormat</span> <span class='hs-varid'>results</span> <span class='hs-varid'>srt</span>
<a name="line-275"></a>                                              <span class='hs-layout'>(</span><span class='hs-varid'>ident</span> <span class='hs-varop'>`elem`</span> <span class='hs-varid'>gc_block_idents</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-276"></a>                  <span class='hs-varid'>block</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>do_call</span> <span class='hs-varid'>current_id</span> <span class='hs-varid'>entry</span> <span class='hs-varid'>accum_stmts</span> <span class='hs-varid'>exits</span> <span class='hs-varid'>next_id</span>
<a name="line-277"></a>                                <span class='hs-varid'>target</span> <span class='hs-varid'>results</span> <span class='hs-varid'>arguments</span> <span class='hs-varid'>srt</span> <span class='hs-varid'>ret</span>
<a name="line-278"></a>
<a name="line-279"></a>            <span class='hs-comment'>-- Break the block on safe calls (the main job of this function)</span>
<a name="line-280"></a>            <span class='hs-layout'>(</span><span class='hs-conid'>CmmCall</span> <span class='hs-varid'>target</span> <span class='hs-varid'>results</span> <span class='hs-varid'>arguments</span> <span class='hs-layout'>(</span><span class='hs-conid'>CmmSafe</span> <span class='hs-varid'>srt</span><span class='hs-layout'>)</span> <span class='hs-varid'>ret</span> <span class='hs-conop'>:</span> <span class='hs-varid'>stmts</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span>
<a name="line-281"></a>                <span class='hs-layout'>(</span><span class='hs-varid'>cont_info</span> <span class='hs-conop'>:</span> <span class='hs-varid'>cont_infos</span><span class='hs-layout'>,</span> <span class='hs-varid'>block</span> <span class='hs-conop'>:</span> <span class='hs-varid'>blocks</span><span class='hs-layout'>)</span>
<a name="line-282"></a>                <span class='hs-keyword'>where</span>
<a name="line-283"></a>                  <span class='hs-varid'>next_id</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>BlockId</span> <span class='hs-varop'>$</span> <span class='hs-varid'>head</span> <span class='hs-varid'>uniques</span>
<a name="line-284"></a>                  <span class='hs-varid'>block</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>do_call</span> <span class='hs-varid'>current_id</span> <span class='hs-varid'>entry</span> <span class='hs-varid'>accum_stmts</span> <span class='hs-varid'>exits</span> <span class='hs-varid'>next_id</span>
<a name="line-285"></a>                                  <span class='hs-varid'>target</span> <span class='hs-varid'>results</span> <span class='hs-varid'>arguments</span> <span class='hs-varid'>srt</span> <span class='hs-varid'>ret</span>
<a name="line-286"></a>
<a name="line-287"></a>                  <span class='hs-varid'>cont_info</span> <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-varid'>next_id</span><span class='hs-layout'>,</span>	<span class='hs-comment'>-- Entry convention for the </span>
<a name="line-288"></a>					<span class='hs-comment'>-- continuation of the call</span>
<a name="line-289"></a>                               <span class='hs-conid'>ContFormat</span> <span class='hs-varid'>results</span> <span class='hs-varid'>srt</span>
<a name="line-290"></a>                                              <span class='hs-layout'>(</span><span class='hs-varid'>ident</span> <span class='hs-varop'>`elem`</span> <span class='hs-varid'>gc_block_idents</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-291"></a>
<a name="line-292"></a>			<span class='hs-comment'>-- Break up the part after the call</span>
<a name="line-293"></a>                  <span class='hs-layout'>(</span><span class='hs-varid'>cont_infos</span><span class='hs-layout'>,</span> <span class='hs-varid'>blocks</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>breakBlock'</span> <span class='hs-layout'>(</span><span class='hs-varid'>tail</span> <span class='hs-varid'>uniques</span><span class='hs-layout'>)</span> <span class='hs-varid'>next_id</span>
<a name="line-294"></a>                                         <span class='hs-conid'>ControlEntry</span> <span class='hs-conid'>[]</span> <span class='hs-conid'>[]</span> <span class='hs-varid'>stmts</span>
<a name="line-295"></a>
<a name="line-296"></a>            <span class='hs-comment'>-- Unsafe calls don't need a continuation</span>
<a name="line-297"></a>            <span class='hs-comment'>-- but they do need to be expanded</span>
<a name="line-298"></a>            <span class='hs-layout'>(</span><span class='hs-conid'>CmmCall</span> <span class='hs-varid'>target</span> <span class='hs-varid'>results</span> <span class='hs-varid'>arguments</span> <span class='hs-conid'>CmmUnsafe</span> <span class='hs-varid'>ret</span> <span class='hs-conop'>:</span> <span class='hs-varid'>stmts</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span>
<a name="line-299"></a>                <span class='hs-varid'>breakBlock'</span> <span class='hs-varid'>remaining_uniques</span> <span class='hs-varid'>current_id</span> <span class='hs-varid'>entry</span> <span class='hs-varid'>exits</span>
<a name="line-300"></a>                            <span class='hs-layout'>(</span><span class='hs-varid'>accum_stmts</span> <span class='hs-varop'>++</span>
<a name="line-301"></a>                             <span class='hs-varid'>arg_stmts</span> <span class='hs-varop'>++</span>
<a name="line-302"></a>                             <span class='hs-varid'>caller_save</span> <span class='hs-varop'>++</span>
<a name="line-303"></a>                             <span class='hs-keyglyph'>[</span><span class='hs-conid'>CmmCall</span> <span class='hs-varid'>target</span> <span class='hs-varid'>results</span> <span class='hs-varid'>new_args</span> <span class='hs-conid'>CmmUnsafe</span> <span class='hs-varid'>ret</span><span class='hs-keyglyph'>]</span> <span class='hs-varop'>++</span>
<a name="line-304"></a>                             <span class='hs-varid'>caller_load</span><span class='hs-layout'>)</span>
<a name="line-305"></a>                            <span class='hs-varid'>stmts</span>
<a name="line-306"></a>                <span class='hs-keyword'>where</span>
<a name="line-307"></a>                  <span class='hs-layout'>(</span><span class='hs-varid'>remaining_uniques</span><span class='hs-layout'>,</span> <span class='hs-varid'>arg_stmts</span><span class='hs-layout'>,</span> <span class='hs-varid'>new_args</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span>
<a name="line-308"></a>                      <span class='hs-varid'>loadArgsIntoTemps</span> <span class='hs-varid'>uniques</span> <span class='hs-varid'>arguments</span>
<a name="line-309"></a>                  <span class='hs-layout'>(</span><span class='hs-varid'>caller_save</span><span class='hs-layout'>,</span> <span class='hs-varid'>caller_load</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>callerSaveVolatileRegs</span> <span class='hs-layout'>(</span><span class='hs-conid'>Just</span> <span class='hs-conid'>[]</span><span class='hs-layout'>)</span>
<a name="line-310"></a>
<a name="line-311"></a>            <span class='hs-comment'>-- Default case.  Just keep accumulating statements</span>
<a name="line-312"></a>            <span class='hs-comment'>-- and branch targets.</span>
<a name="line-313"></a>            <span class='hs-layout'>(</span><span class='hs-varid'>s</span> <span class='hs-conop'>:</span> <span class='hs-varid'>stmts</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span>
<a name="line-314"></a>                <span class='hs-varid'>breakBlock'</span> <span class='hs-varid'>uniques</span> <span class='hs-varid'>current_id</span> <span class='hs-varid'>entry</span>
<a name="line-315"></a>                            <span class='hs-layout'>(</span><span class='hs-varid'>cond_branch_target</span> <span class='hs-varid'>s</span><span class='hs-varop'>++</span><span class='hs-varid'>exits</span><span class='hs-layout'>)</span>
<a name="line-316"></a>                            <span class='hs-layout'>(</span><span class='hs-varid'>accum_stmts</span><span class='hs-varop'>++</span><span class='hs-keyglyph'>[</span><span class='hs-varid'>s</span><span class='hs-keyglyph'>]</span><span class='hs-layout'>)</span>
<a name="line-317"></a>                            <span class='hs-varid'>stmts</span>
<a name="line-318"></a>
<a name="line-319"></a>      <span class='hs-varid'>do_call</span> <span class='hs-varid'>current_id</span> <span class='hs-varid'>entry</span> <span class='hs-varid'>accum_stmts</span> <span class='hs-varid'>exits</span> <span class='hs-varid'>next_id</span>
<a name="line-320"></a>              <span class='hs-varid'>target</span> <span class='hs-varid'>results</span> <span class='hs-varid'>arguments</span> <span class='hs-varid'>srt</span> <span class='hs-varid'>ret</span> <span class='hs-keyglyph'>=</span>
<a name="line-321"></a>          <span class='hs-conid'>BrokenBlock</span> <span class='hs-varid'>current_id</span> <span class='hs-varid'>entry</span> <span class='hs-varid'>accum_stmts</span> <span class='hs-layout'>(</span><span class='hs-varid'>next_id</span><span class='hs-conop'>:</span><span class='hs-varid'>exits</span><span class='hs-layout'>)</span>
<a name="line-322"></a>                      <span class='hs-layout'>(</span><span class='hs-conid'>FinalCall</span> <span class='hs-varid'>next_id</span> <span class='hs-varid'>target</span> <span class='hs-varid'>results</span> <span class='hs-varid'>arguments</span> <span class='hs-varid'>srt</span> <span class='hs-varid'>ret</span>
<a name="line-323"></a>                                     <span class='hs-layout'>(</span><span class='hs-varid'>current_id</span> <span class='hs-varop'>`elem`</span> <span class='hs-varid'>gc_block_idents</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-324"></a>
<a name="line-325"></a>      <span class='hs-varid'>cond_branch_target</span> <span class='hs-layout'>(</span><span class='hs-conid'>CmmCondBranch</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>target</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>target</span><span class='hs-keyglyph'>]</span>
<a name="line-326"></a>      <span class='hs-varid'>cond_branch_target</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>[]</span>
<a name="line-327"></a>
<a name="line-328"></a><span class='hs-comment'>-----------------------------------------------------------------------------</span>
<a name="line-329"></a>
<a name="line-330"></a><a name="selectContinuations"></a><span class='hs-definition'>selectContinuations</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-conid'>BlockId</span><span class='hs-layout'>,</span> <span class='hs-conid'>ContFormat</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-conid'>BlockId</span><span class='hs-layout'>,</span> <span class='hs-conid'>ContFormat</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span>
<a name="line-331"></a><span class='hs-definition'>selectContinuations</span> <span class='hs-varid'>needed_continuations</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>formats</span>
<a name="line-332"></a>    <span class='hs-keyword'>where</span>
<a name="line-333"></a>      <span class='hs-varid'>formats</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>map</span> <span class='hs-varid'>select_format</span> <span class='hs-varid'>format_groups</span>
<a name="line-334"></a>      <span class='hs-varid'>format_groups</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>groupBy</span> <span class='hs-varid'>by_target</span> <span class='hs-varid'>needed_continuations</span>
<a name="line-335"></a>      <span class='hs-varid'>by_target</span> <span class='hs-varid'>x</span> <span class='hs-varid'>y</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>fst</span> <span class='hs-varid'>x</span> <span class='hs-varop'>==</span> <span class='hs-varid'>fst</span> <span class='hs-varid'>y</span>
<a name="line-336"></a>
<a name="line-337"></a>      <span class='hs-varid'>select_format</span> <span class='hs-varid'>formats</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>winner</span>
<a name="line-338"></a>          <span class='hs-keyword'>where</span>
<a name="line-339"></a>            <span class='hs-varid'>winner</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>head</span> <span class='hs-varop'>$</span> <span class='hs-varid'>head</span> <span class='hs-varop'>$</span> <span class='hs-varid'>sortBy</span> <span class='hs-varid'>more_votes</span> <span class='hs-varid'>format_votes</span>
<a name="line-340"></a>            <span class='hs-varid'>format_votes</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>groupBy</span> <span class='hs-varid'>by_format</span> <span class='hs-varid'>formats</span>
<a name="line-341"></a>            <span class='hs-varid'>by_format</span> <span class='hs-varid'>x</span> <span class='hs-varid'>y</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>snd</span> <span class='hs-varid'>x</span> <span class='hs-varop'>==</span> <span class='hs-varid'>snd</span> <span class='hs-varid'>y</span>
<a name="line-342"></a>            <span class='hs-varid'>more_votes</span> <span class='hs-varid'>x</span> <span class='hs-varid'>y</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>compare</span> <span class='hs-layout'>(</span><span class='hs-varid'>length</span> <span class='hs-varid'>y</span><span class='hs-layout'>)</span> <span class='hs-layout'>(</span><span class='hs-varid'>length</span> <span class='hs-varid'>x</span><span class='hs-layout'>)</span>
<a name="line-343"></a>              <span class='hs-comment'>-- sort so the most votes goes *first*</span>
<a name="line-344"></a>              <span class='hs-comment'>-- (thus the order of x and y is reversed)</span>
<a name="line-345"></a>
<a name="line-346"></a><a name="makeContinuationEntries"></a><span class='hs-definition'>makeContinuationEntries</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-conid'>BlockId</span><span class='hs-layout'>,</span> <span class='hs-conid'>ContFormat</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span>
<a name="line-347"></a>                        <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>BrokenBlock</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>BrokenBlock</span>
<a name="line-348"></a><span class='hs-definition'>makeContinuationEntries</span> <span class='hs-varid'>formats</span>
<a name="line-349"></a>                        <span class='hs-varid'>block</span><span class='hs-keyglyph'>@</span><span class='hs-layout'>(</span><span class='hs-conid'>BrokenBlock</span> <span class='hs-varid'>ident</span> <span class='hs-sel'>_entry</span> <span class='hs-varid'>stmts</span> <span class='hs-varid'>targets</span> <span class='hs-varid'>exit</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span>
<a name="line-350"></a>    <span class='hs-keyword'>case</span> <span class='hs-varid'>lookup</span> <span class='hs-varid'>ident</span> <span class='hs-varid'>formats</span> <span class='hs-keyword'>of</span>
<a name="line-351"></a>      <span class='hs-conid'>Nothing</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-varid'>block</span>
<a name="line-352"></a>      <span class='hs-conid'>Just</span> <span class='hs-layout'>(</span><span class='hs-conid'>ContFormat</span> <span class='hs-varid'>formals</span> <span class='hs-varid'>srt</span> <span class='hs-varid'>is_gc</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>-&gt;</span>
<a name="line-353"></a>          <span class='hs-conid'>BrokenBlock</span> <span class='hs-varid'>ident</span> <span class='hs-layout'>(</span><span class='hs-conid'>ContinuationEntry</span> <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-varid'>hintlessCmm</span> <span class='hs-varid'>formals</span><span class='hs-layout'>)</span> <span class='hs-varid'>srt</span> <span class='hs-varid'>is_gc</span><span class='hs-layout'>)</span>
<a name="line-354"></a>                      <span class='hs-varid'>stmts</span> <span class='hs-varid'>targets</span> <span class='hs-varid'>exit</span>
<a name="line-355"></a>
<a name="line-356"></a><a name="adaptBlockToFormat"></a><span class='hs-definition'>adaptBlockToFormat</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-layout'>(</span><span class='hs-conid'>BlockId</span><span class='hs-layout'>,</span> <span class='hs-conid'>ContFormat</span><span class='hs-layout'>)</span><span class='hs-keyglyph'>]</span>
<a name="line-357"></a>                   <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>Unique</span>
<a name="line-358"></a>                   <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>BrokenBlock</span>
<a name="line-359"></a>                   <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>BrokenBlock</span><span class='hs-keyglyph'>]</span>
<a name="line-360"></a><span class='hs-definition'>adaptBlockToFormat</span> <span class='hs-varid'>formats</span> <span class='hs-varid'>unique</span>
<a name="line-361"></a>                   <span class='hs-varid'>block</span><span class='hs-keyglyph'>@</span><span class='hs-layout'>(</span><span class='hs-conid'>BrokenBlock</span> <span class='hs-varid'>ident</span> <span class='hs-varid'>entry</span> <span class='hs-varid'>stmts</span> <span class='hs-varid'>targets</span>
<a name="line-362"></a>                                      <span class='hs-layout'>(</span><span class='hs-conid'>FinalCall</span> <span class='hs-varid'>next</span> <span class='hs-varid'>target</span> <span class='hs-varid'>formals</span>
<a name="line-363"></a>                                                 <span class='hs-varid'>actuals</span> <span class='hs-varid'>srt</span> <span class='hs-varid'>ret</span> <span class='hs-varid'>is_gc</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span>
<a name="line-364"></a>    <span class='hs-keyword'>if</span> <span class='hs-varid'>format_formals</span> <span class='hs-varop'>==</span> <span class='hs-varid'>formals</span> <span class='hs-varop'>&amp;&amp;</span>
<a name="line-365"></a>       <span class='hs-varid'>format_srt</span> <span class='hs-varop'>==</span> <span class='hs-varid'>srt</span> <span class='hs-varop'>&amp;&amp;</span>
<a name="line-366"></a>       <span class='hs-varid'>format_is_gc</span> <span class='hs-varop'>==</span> <span class='hs-varid'>is_gc</span>
<a name="line-367"></a>    <span class='hs-keyword'>then</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>block</span><span class='hs-keyglyph'>]</span> <span class='hs-comment'>-- Woohoo! This block got the continuation format it wanted</span>
<a name="line-368"></a>    <span class='hs-keyword'>else</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>adaptor_block</span><span class='hs-layout'>,</span> <span class='hs-varid'>revised_block</span><span class='hs-keyglyph'>]</span>
<a name="line-369"></a>           <span class='hs-comment'>-- This block didn't get the format it wanted for the</span>
<a name="line-370"></a>           <span class='hs-comment'>-- continuation, so we have to build an adaptor.</span>
<a name="line-371"></a>    <span class='hs-keyword'>where</span>
<a name="line-372"></a>      <span class='hs-layout'>(</span><span class='hs-conid'>ContFormat</span> <span class='hs-varid'>format_formals</span> <span class='hs-varid'>format_srt</span> <span class='hs-varid'>format_is_gc</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span>
<a name="line-373"></a>          <span class='hs-varid'>maybe</span> <span class='hs-varid'>unknown_block</span> <span class='hs-varid'>id</span> <span class='hs-varop'>$</span> <span class='hs-varid'>lookup</span> <span class='hs-varid'>next</span> <span class='hs-varid'>formats</span>
<a name="line-374"></a>      <span class='hs-varid'>unknown_block</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>panic</span> <span class='hs-str'>"unknown block in adaptBlockToFormat"</span>
<a name="line-375"></a>
<a name="line-376"></a>      <span class='hs-varid'>revised_block</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>BrokenBlock</span> <span class='hs-varid'>ident</span> <span class='hs-varid'>entry</span> <span class='hs-varid'>stmts</span> <span class='hs-varid'>revised_targets</span> <span class='hs-varid'>revised_exit</span>
<a name="line-377"></a>      <span class='hs-varid'>revised_targets</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>adaptor_ident</span> <span class='hs-conop'>:</span> <span class='hs-varid'>delete</span> <span class='hs-varid'>next</span> <span class='hs-varid'>targets</span>
<a name="line-378"></a>      <span class='hs-varid'>revised_exit</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>FinalCall</span>
<a name="line-379"></a>                       <span class='hs-varid'>adaptor_ident</span> <span class='hs-comment'>-- The only part that changed</span>
<a name="line-380"></a>                       <span class='hs-varid'>target</span> <span class='hs-varid'>formals</span> <span class='hs-varid'>actuals</span> <span class='hs-varid'>srt</span> <span class='hs-varid'>ret</span> <span class='hs-varid'>is_gc</span>
<a name="line-381"></a>
<a name="line-382"></a>      <span class='hs-varid'>adaptor_block</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mk_adaptor_block</span> <span class='hs-varid'>adaptor_ident</span>
<a name="line-383"></a>                  <span class='hs-layout'>(</span><span class='hs-conid'>ContinuationEntry</span> <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-varid'>hintlessCmm</span> <span class='hs-varid'>formals</span><span class='hs-layout'>)</span> <span class='hs-varid'>srt</span> <span class='hs-varid'>is_gc</span><span class='hs-layout'>)</span> <span class='hs-varid'>next</span>
<a name="line-384"></a>      <span class='hs-varid'>adaptor_ident</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>BlockId</span> <span class='hs-varid'>unique</span>
<a name="line-385"></a>
<a name="line-386"></a>      <span class='hs-varid'>mk_adaptor_block</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>BlockId</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>BlockEntryInfo</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>BlockId</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>BrokenBlock</span>
<a name="line-387"></a>      <span class='hs-varid'>mk_adaptor_block</span> <span class='hs-varid'>ident</span> <span class='hs-varid'>entry</span> <span class='hs-varid'>next</span> <span class='hs-keyglyph'>=</span>
<a name="line-388"></a>          <span class='hs-conid'>BrokenBlock</span> <span class='hs-varid'>ident</span> <span class='hs-varid'>entry</span> <span class='hs-conid'>[]</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>next</span><span class='hs-keyglyph'>]</span> <span class='hs-varid'>exit</span>
<a name="line-389"></a>              <span class='hs-keyword'>where</span>
<a name="line-390"></a>                <span class='hs-varid'>exit</span> <span class='hs-keyglyph'>=</span> <span class='hs-conid'>FinalJump</span>
<a name="line-391"></a>                         <span class='hs-layout'>(</span><span class='hs-conid'>CmmLit</span> <span class='hs-layout'>(</span><span class='hs-conid'>CmmLabel</span> <span class='hs-layout'>(</span><span class='hs-varid'>mkReturnPtLabel</span> <span class='hs-layout'>(</span><span class='hs-varid'>getUnique</span> <span class='hs-varid'>next</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span>
<a name="line-392"></a>                         <span class='hs-layout'>(</span><span class='hs-varid'>map</span> <span class='hs-varid'>formal_to_actual</span> <span class='hs-varid'>format_formals</span><span class='hs-layout'>)</span>
<a name="line-393"></a>
<a name="line-394"></a>                <span class='hs-varid'>formal_to_actual</span> <span class='hs-layout'>(</span><span class='hs-conid'>CmmHinted</span> <span class='hs-varid'>reg</span> <span class='hs-varid'>hint</span><span class='hs-layout'>)</span>
<a name="line-395"></a>                     <span class='hs-keyglyph'>=</span> <span class='hs-layout'>(</span><span class='hs-conid'>CmmHinted</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'>reg</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>hint</span><span class='hs-layout'>)</span>
<a name="line-396"></a>                <span class='hs-comment'>-- TODO: Check if NoHint is right.  We're</span>
<a name="line-397"></a>                <span class='hs-comment'>-- jumping to a C-- function not a foreign one</span>
<a name="line-398"></a>                <span class='hs-comment'>-- so it might always be right.</span>
<a name="line-399"></a><span class='hs-definition'>adaptBlockToFormat</span> <span class='hs-keyword'>_</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>block</span> <span class='hs-keyglyph'>=</span> <span class='hs-keyglyph'>[</span><span class='hs-varid'>block</span><span class='hs-keyglyph'>]</span>
<a name="line-400"></a>
<a name="line-401"></a><a name="cmmBlockFromBrokenBlock"></a><span class='hs-comment'>-----------------------------------------------------------------------------</span>
<a name="line-402"></a><span class='hs-comment'>-- | Convert from a BrokenBlock back to an equivalent CmmBasicBlock</span>
<a name="line-403"></a><span class='hs-comment'>-- Needed by liveness analysis</span>
<a name="line-404"></a><span class='hs-definition'>cmmBlockFromBrokenBlock</span> <span class='hs-keyglyph'>::</span> <span class='hs-conid'>BrokenBlock</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>CmmBasicBlock</span>
<a name="line-405"></a><span class='hs-definition'>cmmBlockFromBrokenBlock</span> <span class='hs-layout'>(</span><span class='hs-conid'>BrokenBlock</span> <span class='hs-varid'>ident</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>stmts</span> <span class='hs-keyword'>_</span> <span class='hs-varid'>exit</span><span class='hs-layout'>)</span> <span class='hs-keyglyph'>=</span>
<a name="line-406"></a>    <span class='hs-conid'>BasicBlock</span> <span class='hs-varid'>ident</span> <span class='hs-layout'>(</span><span class='hs-varid'>stmts</span><span class='hs-varop'>++</span><span class='hs-varid'>exit_stmt</span><span class='hs-layout'>)</span>
<a name="line-407"></a>    <span class='hs-keyword'>where</span>
<a name="line-408"></a>      <span class='hs-varid'>exit_stmt</span> <span class='hs-keyglyph'>=</span>
<a name="line-409"></a>          <span class='hs-keyword'>case</span> <span class='hs-varid'>exit</span> <span class='hs-keyword'>of</span>
<a name="line-410"></a>            <span class='hs-conid'>FinalBranch</span> <span class='hs-varid'>target</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>CmmBranch</span> <span class='hs-varid'>target</span><span class='hs-keyglyph'>]</span>
<a name="line-411"></a>            <span class='hs-conid'>FinalReturn</span> <span class='hs-varid'>arguments</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>CmmReturn</span> <span class='hs-varid'>arguments</span><span class='hs-keyglyph'>]</span>
<a name="line-412"></a>            <span class='hs-conid'>FinalJump</span> <span class='hs-varid'>target</span> <span class='hs-varid'>arguments</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>CmmJump</span> <span class='hs-varid'>target</span> <span class='hs-varid'>arguments</span><span class='hs-keyglyph'>]</span>
<a name="line-413"></a>            <span class='hs-conid'>FinalSwitch</span> <span class='hs-varid'>expr</span> <span class='hs-varid'>targets</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>CmmSwitch</span> <span class='hs-varid'>expr</span> <span class='hs-varid'>targets</span><span class='hs-keyglyph'>]</span>
<a name="line-414"></a>            <span class='hs-conid'>FinalCall</span> <span class='hs-varid'>branch_target</span> <span class='hs-varid'>call_target</span> <span class='hs-varid'>results</span> <span class='hs-varid'>arguments</span> <span class='hs-varid'>srt</span> <span class='hs-varid'>ret</span> <span class='hs-keyword'>_</span> <span class='hs-keyglyph'>-&gt;</span>
<a name="line-415"></a>                <span class='hs-keyglyph'>[</span><span class='hs-conid'>CmmCall</span> <span class='hs-varid'>call_target</span> <span class='hs-varid'>results</span> <span class='hs-varid'>arguments</span> <span class='hs-layout'>(</span><span class='hs-conid'>CmmSafe</span> <span class='hs-varid'>srt</span><span class='hs-layout'>)</span> <span class='hs-varid'>ret</span><span class='hs-layout'>,</span>
<a name="line-416"></a>                 <span class='hs-conid'>CmmBranch</span> <span class='hs-varid'>branch_target</span><span class='hs-keyglyph'>]</span>
<a name="line-417"></a>
<a name="line-418"></a><a name="blocksToBlockEnv"></a><span class='hs-comment'>-----------------------------------------------------------------------------</span>
<a name="line-419"></a><span class='hs-comment'>-- | Build a mapping so we can lookup a 'BrokenBlock' by its 'BlockId'</span>
<a name="line-420"></a><span class='hs-definition'>blocksToBlockEnv</span> <span class='hs-keyglyph'>::</span> <span class='hs-keyglyph'>[</span><span class='hs-conid'>BrokenBlock</span><span class='hs-keyglyph'>]</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-conid'>BlockEnv</span> <span class='hs-conid'>BrokenBlock</span>
<a name="line-421"></a><span class='hs-definition'>blocksToBlockEnv</span> <span class='hs-varid'>blocks</span> <span class='hs-keyglyph'>=</span> <span class='hs-varid'>mkBlockEnv</span> <span class='hs-varop'>$</span> <span class='hs-varid'>map</span> <span class='hs-layout'>(</span><span class='hs-keyglyph'>\</span><span class='hs-varid'>b</span> <span class='hs-keyglyph'>-&gt;</span> <span class='hs-layout'>(</span><span class='hs-varid'>brokenBlockId</span> <span class='hs-varid'>b</span><span class='hs-layout'>,</span> <span class='hs-varid'>b</span><span class='hs-layout'>)</span><span class='hs-layout'>)</span> <span class='hs-varid'>blocks</span>
</pre></body>
</html>