<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Aptos;
panose-1:2 11 0 4 2 2 2 2 2 4;}
@font-face
{font-family:Consolas;
panose-1:2 11 6 9 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
font-size:11.0pt;
font-family:"Aptos",sans-serif;}
.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;
mso-ligatures:none;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
--></style>
</head>
<body lang="EN-US" link="blue" vlink="purple" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<div id="mail-editor-reference-message-container">
<div>
<div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<p class="MsoNormal">Here is lifted version of the same code, where 11 more synthetic blocks are necessary to exit the exception regions correctly:</p>
<p class="MsoNormal"> </p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas">func @"nestedCatch" (%0 : int)void -> {</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> branch ^block_1;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_1:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> %1 : java.lang.reflect.code.op.CoreOp$ExceptionRegion = exception.region.enter ^block_2 ^block_27;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_2:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> %2 : java.lang.reflect.code.op.CoreOp$ExceptionRegion = exception.region.enter ^block_3 ^block_20;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_3:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> %3 : int = constant @"0";</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> %4 : boolean = eq %0 %3;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> cbranch %4 ^block_4 ^block_7;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_4:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> exception.region.exit %2 ^block_5;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_5:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> exception.region.exit %1 ^block_6;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_6:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> return;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_7:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> exception.region.exit %2 ^block_8;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_8:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> exception.region.exit %1 ^block_9;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_9:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> %5 : java.lang.reflect.code.op.CoreOp$ExceptionRegion = exception.region.enter ^block_10 ^block_27;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_10:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> %6 : java.lang.reflect.code.op.CoreOp$ExceptionRegion = exception.region.enter ^block_11 ^block_19;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_11:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> %7 : int = constant @"1";</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> %8 : boolean = eq %0 %7;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> cbranch %8 ^block_12 ^block_15;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_12:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> exception.region.exit %6 ^block_13;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_13:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> exception.region.exit %5 ^block_14;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_14:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> branch ^block_1;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_15:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> exception.region.exit %6 ^block_16;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_16:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> exception.region.exit %5 ^block_17;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_17:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> %9 : java.lang.reflect.code.op.CoreOp$ExceptionRegion = exception.region.enter ^block_18 ^block_27;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_18:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> exception.region.exit %9 ^block_24;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_19(%10 : java.lang.NullPointerException):</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> exception.region.exit %5 ^block_21(%10);</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_20(%11 : java.lang.NullPointerException):</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> exception.region.exit %1 ^block_21(%11);</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_21(%12 : java.lang.NullPointerException):</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> %13 : java.lang.reflect.code.op.CoreOp$ExceptionRegion = exception.region.enter ^block_22 ^block_27;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_22:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> invoke %12 @"java.lang.NullPointerException::printStackTrace()void";</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> exception.region.exit %13 ^block_23;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_23:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> branch ^block_24;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_24:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> %14 : java.lang.reflect.code.op.CoreOp$ExceptionRegion = exception.region.enter ^block_25 ^block_27;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_25:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> invoke @"javaapplication6.NewClass10::doSomething()void";</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> exception.region.exit %14 ^block_26;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_26:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> branch ^block_1;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_27(%15 : java.lang.RuntimeException):</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> invoke %15 @"java.lang.RuntimeException::printStackTrace()void";</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> branch ^block_1;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas">};</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span></p>
</div>
</blockquote>
<p>> While this looks more correct, I don't really get the exception region exits in block_7 and block_8 (only to be re-entered again).
</p>
<p>That is exactly the complexity I'm talking about. A fragmented exception region mandatory dominated by its entry cause it to split similar to what SSA does to multiple-assigned variables.</p>
<p>> The second exception region has the handler at block_19 and block_20.</p>
<p><span style="font-size:11.0pt">Yes, that is also enforced by the current model spec. A NPE thrown and handled in in block_19 needs to first leave
</span><span style="font-size:9.0pt;font-family:Consolas">exception.region.exit %5</span><span style="font-size:11.0pt">, while in block_20 it leaves a different region entry and in block_21 it is technically out of the regions. I don't think the lifting algorithm
is optimal, however proposed change clearing the exception stack when thrown will definitely remove this synthetic "leaving the exception region" blocks.</span><span style="font-size:11.0pt"><o:p></o:p></span></p>
<p>> My feeling is that these little discrepancies add up quite a lot... if we could see that e.g. we leave the regions in 7 and 8 only to reenter them again in 9 and 10, then surely we can omit these redundant blocks (given they don't seem to be reachable
from anywhere else). Also, the duplication between block 19 and 20 is annoying as well.</p>
<p>You may try to implement it as a post-lift compaction transform or try to embed some optimizations it into the lift, however the complexity is like an attempt to lift locals into variables directly in SSA form. That is why I'm proposing to remove the "single
dominant exception entry" condition from the spec and replace it with the condition that entries to an exception region form a dominant set, dominating to the exits from the region.
</p>
<p><o:p> </o:p></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<p class="MsoNormal">With proposed changes the above example model may look like this:</p>
<p class="MsoNormal"> </p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas">func @"nestedCatch" (%0 : int)void -> {</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> %1 : java.lang.reflect.code.op.CoreOp$ExceptionRegion<java.lang.RuntimeException> = exception.region ^block_13;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> %2 : java.lang.reflect.code.op.CoreOp$ExceptionRegion<java.lang.NullPointerException> = exception.region ^block_9;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> branch ^block_1;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_1:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> exception.region.enter %1 %2 ^block_2; // entering nested try blocks
</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_2:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> %3 : int = constant @"0";</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> %4 : boolean = eq %0 %3;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> cbranch %4 ^block_3 ^block_5;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_3:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> exception.region.exit %2 %1 ^block_4; // leaving nested try blocks</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_4:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> return;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_5:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> %5 : int = constant @"1";</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> %6 : boolean = eq %0 %5;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> cbranch %6 ^block_6 ^block_8;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_6:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> exception.region.exit %2 %1 ^block_7; ; // leaving nested try blocks</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_7:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> branch ^block_1;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_8:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> exception.region.exit %2 ^block_11; // leaving only the inner NPE try block</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_9(%7 : java.lang.NullPointerException):</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> exception.region.enter %1 ^block_10; // re-entering the outer try block</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_10:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> invoke %7 @"java.lang.NullPointerException::printStackTrace()void";</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> branch ^block_11;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_11:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> invoke @"javaapplication6.NewClass10::doSomething()void";</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> exception.region.exit %1 ^block_12; // leaving the outer try block</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_12:</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> branch ^block_1;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> </span>
</p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> ^block_13(%8 : java.lang.RuntimeException):</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> invoke %8 @"java.lang.RuntimeException::printStackTrace()void";</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas"> branch ^block_1;</span></p>
<p class="MsoNormal"><span style="font-size:9.0pt;font-family:Consolas">};</span></p>
<p class="MsoNormal"> </p>
</div>
</blockquote>
<p>> This does look better - but in part also because some of the problems highlighted above have been addressed? (e.g. more sharing of code paths, avoid duplicted exception region...)</p>
<p>Yes, the exception regions can be deduplicated, because they are no more single-entry dominant the exits.</p>
<p>Thanks,</p>
<p>Adam</p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<div id="mail-editor-reference-message-container">
<div>
<div>
<div>
<div>
<p class="MsoNormal"> </p>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</div>
</body>
</html>