Fix bug in escape analysis. See #271

This commit is contained in:
Alexey Andreev 2017-05-08 18:44:58 +03:00
parent 812aa5a682
commit 4b6193baca
4 changed files with 71 additions and 4 deletions

View File

@ -126,13 +126,13 @@ public class EscapeAnalysis {
BitSet usedVars = getUsedVarsInBlock(livenessAnalyzer, block);
for (Phi phi : block.getPhis()) {
if (escapes(phi.getReceiver().getIndex())) {
queue.addLast(phi.getReceiver().getIndex());
queue.addLast(definitionClasses[phi.getReceiver().getIndex()]);
}
for (Incoming incoming : phi.getIncomings()) {
int var = incoming.getValue().getIndex();
graphBuilder.addEdge(var, phi.getReceiver().getIndex());
graphBuilder.addEdge(definitionClasses[var], definitionClasses[phi.getReceiver().getIndex()]);
if (escapes(var) || !sharedIncomingVars.add(var) || usedVars.get(var)) {
queue.addLast(var);
queue.addLast(definitionClasses[var]);
}
}
}
@ -143,7 +143,7 @@ public class EscapeAnalysis {
while (!queue.isEmpty()) {
int var = queue.removeFirst();
if (visited.add(var)) {
escapingVars[definitionClasses[var]] = true;
escapingVars[var] = true;
for (int successor : graph.outgoingEdges(var)) {
queue.addLast(successor);
}

View File

@ -72,6 +72,11 @@ public class ScalarReplacementTest {
doTest();
}
@Test
public void reachabilityByClasses() {
doTest();
}
private void doTest() {
String originalPath = PREFIX + name.getMethodName() + ".original.txt";
String expectedPath = PREFIX + name.getMethodName() + ".expected.txt";

View File

@ -0,0 +1,31 @@
var @this as this
$start
@cond := invokeStatic `Foo.cond()I`
if @cond == 0 then goto $then1 else goto $else1
$then1
@a1_then := new A
@foo1 := 23
field A.foo @a1_then := @foo1 as I
goto $joint1
$else1
@a1_else := new A
@foo2 := 42
field A.foo @a1_else := @foo2 as I
goto $joint1
$joint1
@a1 := phi @a1_then from $then1, @a1_else from $else1
@a2 := @a1
if @cond == 0 then goto $then2 else goto $else2
$then2
@a3_then := new A
goto $joint2
$else2
@a3_else := @a2
goto $joint2
$joint2
@a3 := phi @a3_then from $then2, @a3_else from $else2
invokeStatic `Foo.accept(LA;)V` @a3
return

View File

@ -0,0 +1,31 @@
var @this as this
$start
@cond := invokeStatic `Foo.cond()I`
if @cond == 0 then goto $then1 else goto $else1
$then1
@a1_then := new A
@foo1 := 23
field A.foo @a1_then := @foo1 as I
goto $joint1
$else1
@a1_else := new A
@foo2 := 42
field A.foo @a1_else := @foo2 as I
goto $joint1
$joint1
@a1 := phi @a1_then from $then1, @a1_else from $else1
@a2 := @a1
if @cond == 0 then goto $then2 else goto $else2
$then2
@a3_then := new A
goto $joint2
$else2
@a3_else := @a2
goto $joint2
$joint2
@a3 := phi @a3_then from $then2, @a3_else from $else2
invokeStatic `Foo.accept(LA;)V` @a3
return