mirror of
https://github.com/konsoletyper/teavm.git
synced 2024-11-27 01:30:35 +08:00
Fix bug in escape analysis. See #271
This commit is contained in:
parent
812aa5a682
commit
4b6193baca
@ -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);
|
||||
}
|
||||
|
@ -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";
|
||||
|
@ -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
|
@ -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
|
Loading…
Reference in New Issue
Block a user