<?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 <=> 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>2 then goto L <a name="line-93"></a> x = x+1 <a name="line-94"></a>L: if x>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>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>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 <=> 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 <=> 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> -> [[Unique]] -- ^ An infinite list of uniques <a name="line-189"></a> -- to create names of the new blocks with <a name="line-190"></a> -> CmmInfo -- ^ Info table for the procedure <a name="line-191"></a> -> CLabel -- ^ Name of the procedure <a name="line-192"></a> -> CmmFormals -- ^ Parameters of the procedure <a name="line-193"></a> -> [CmmBasicBlock] -- ^ Blocks of the procecure <a name="line-194"></a> -- (First block is the entry block) <a name="line-195"></a> -> [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'>-></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'>-></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'>-></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'>-></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'>-></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'>-></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'>-></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'>-></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'>-></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'>-></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'>-></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'>-></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'>-></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'>-></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'>-></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'>-></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'>-></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'>-></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'>-></span> <span class='hs-conid'>BrokenBlock</span> <span class='hs-keyglyph'>-></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'>-></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'>-></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'>-></span> <span class='hs-conid'>Unique</span> <a name="line-358"></a> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>BrokenBlock</span> <a name="line-359"></a> <span class='hs-keyglyph'>-></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'>&&</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'>&&</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'>-></span> <span class='hs-conid'>BlockEntryInfo</span> <span class='hs-keyglyph'>-></span> <span class='hs-conid'>BlockId</span> <span class='hs-keyglyph'>-></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'>-></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'>-></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'>-></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'>-></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'>-></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'>-></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'>-></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'>-></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>