Added 'sink' instruction to pseudocode

This commit is contained in:
svtk
2011-11-03 18:29:34 +04:00
parent bfb70330eb
commit 92a3fef06b
21 changed files with 255 additions and 84 deletions
@@ -20,4 +20,6 @@ public interface Instruction {
Collection<Instruction> getNextInstructions(); Collection<Instruction> getNextInstructions();
void accept(InstructionVisitor visitor); void accept(InstructionVisitor visitor);
boolean isDead();
} }
@@ -8,8 +8,8 @@ public class InstructionVisitor {
visitInstructionWithNext(instruction); visitInstructionWithNext(instruction);
} }
public void visitFunctionLiteralValue(LocalDeclarationInstruction instruction) { public void visitLocalDeclarationInstruction(LocalDeclarationInstruction instruction) {
visitReadValue(instruction); visitInstructionWithNext(instruction);
} }
public void visitUnconditionalJump(UnconditionalJumpInstruction instruction) { public void visitUnconditionalJump(UnconditionalJumpInstruction instruction) {
@@ -40,6 +40,10 @@ public class InstructionVisitor {
visitInstruction(instruction); visitInstruction(instruction);
} }
public void visitSubroutineSink(SubroutineSinkInstruction instruction) {
visitInstruction(instruction);
}
public void visitJump(AbstractJumpInstruction instruction) { public void visitJump(AbstractJumpInstruction instruction) {
visitInstruction(instruction); visitInstruction(instruction);
} }
@@ -70,11 +70,13 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
private final Pseudocode pseudocode; private final Pseudocode pseudocode;
private final Label error; private final Label error;
private final Label sink;
private final JetElement currentSubroutine; private final JetElement currentSubroutine;
private JetControlFlowInstructionsGeneratorWorker(@NotNull JetElement scopingElement, @NotNull JetElement currentSubroutine) { private JetControlFlowInstructionsGeneratorWorker(@NotNull JetElement scopingElement, @NotNull JetElement currentSubroutine) {
this.pseudocode = new Pseudocode(scopingElement); this.pseudocode = new Pseudocode(scopingElement);
this.error = pseudocode.createLabel("error"); this.error = pseudocode.createLabel("error");
this.sink = pseudocode.createLabel("sink");
this.currentSubroutine = currentSubroutine; this.currentSubroutine = currentSubroutine;
} }
@@ -183,6 +185,8 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
pseudocode.addExitInstruction(new SubroutineExitInstruction(subroutine, "<END>")); pseudocode.addExitInstruction(new SubroutineExitInstruction(subroutine, "<END>"));
bindLabel(error); bindLabel(error);
add(new SubroutineExitInstruction(subroutine, "<ERROR>")); add(new SubroutineExitInstruction(subroutine, "<ERROR>"));
bindLabel(sink);
pseudocode.addSinkInstruction(new SubroutineSinkInstruction(subroutine, "<SINK>"));
elementToBlockInfo.remove(subroutine); elementToBlockInfo.remove(subroutine);
allBlocks.pop(); allBlocks.pop();
} }
@@ -1,17 +1,22 @@
package org.jetbrains.jet.lang.cfg.pseudocode; package org.jetbrains.jet.lang.cfg.pseudocode;
import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetClass; import org.jetbrains.jet.lang.psi.JetClass;
import org.jetbrains.jet.lang.psi.JetDeclaration; import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetFunction; import org.jetbrains.jet.lang.psi.JetFunction;
import org.jetbrains.jet.lang.psi.JetObjectDeclaration; import org.jetbrains.jet.lang.psi.JetObjectDeclaration;
import java.util.ArrayList;
import java.util.Collection;
/** /**
* @author abreslav * @author abreslav
*/ */
public class LocalDeclarationInstruction extends ReadValueInstruction { public class LocalDeclarationInstruction extends InstructionWithNext {
private Pseudocode body; private final Pseudocode body;
private Instruction sink;
public LocalDeclarationInstruction(@NotNull JetDeclaration element, Pseudocode body) { public LocalDeclarationInstruction(@NotNull JetDeclaration element, Pseudocode body) {
super(element); super(element);
@@ -22,9 +27,21 @@ public class LocalDeclarationInstruction extends ReadValueInstruction {
return body; return body;
} }
@NotNull
@Override
public Collection<Instruction> getNextInstructions() {
ArrayList<Instruction> instructions = Lists.newArrayList(sink);
instructions.addAll(super.getNextInstructions());
return instructions;
}
public void setSink(SubroutineSinkInstruction sink) {
this.sink = outgoingEdgeTo(sink);
}
@Override @Override
public void accept(InstructionVisitor visitor) { public void accept(InstructionVisitor visitor) {
visitor.visitFunctionLiteralValue(this); visitor.visitLocalDeclarationInstruction(this);
} }
@Override @Override
@@ -59,6 +59,7 @@ public class Pseudocode {
private final JetElement correspondingElement; private final JetElement correspondingElement;
private SubroutineExitInstruction exitInstruction; private SubroutineExitInstruction exitInstruction;
private SubroutineSinkInstruction sinkInstruction;
private boolean postPrecessed = false; private boolean postPrecessed = false;
public Pseudocode(JetElement correspondingElement) { public Pseudocode(JetElement correspondingElement) {
@@ -84,7 +85,7 @@ public class Pseudocode {
public List<Instruction> getDeadInstructions() { public List<Instruction> getDeadInstructions() {
List<Instruction> deadInstructions = Lists.newArrayList(); List<Instruction> deadInstructions = Lists.newArrayList();
for (Instruction instruction : instructions) { for (Instruction instruction : instructions) {
if (((InstructionImpl)instruction).isDead()) { if (instruction.isDead()) {
deadInstructions.add(instruction); deadInstructions.add(instruction);
} }
} }
@@ -101,6 +102,12 @@ public class Pseudocode {
assert this.exitInstruction == null; assert this.exitInstruction == null;
this.exitInstruction = exitInstruction; this.exitInstruction = exitInstruction;
} }
public void addSinkInstruction(SubroutineSinkInstruction sinkInstruction) {
addInstruction(sinkInstruction);
assert this.sinkInstruction == null;
this.sinkInstruction = sinkInstruction;
}
public void addInstruction(Instruction instruction) { public void addInstruction(Instruction instruction) {
instructions.add(instruction); instructions.add(instruction);
@@ -112,6 +119,12 @@ public class Pseudocode {
return exitInstruction; return exitInstruction;
} }
@NotNull
public SubroutineSinkInstruction getSinkInstruction() {
return sinkInstruction;
}
@NotNull @NotNull
public SubroutineEnterInstruction getEnterInstruction() { public SubroutineEnterInstruction getEnterInstruction() {
return (SubroutineEnterInstruction) instructions.get(0); return (SubroutineEnterInstruction) instructions.get(0);
@@ -163,9 +176,10 @@ public class Pseudocode {
} }
@Override @Override
public void visitFunctionLiteralValue(LocalDeclarationInstruction instruction) { public void visitLocalDeclarationInstruction(LocalDeclarationInstruction instruction) {
instruction.getBody().postProcess(); instruction.getBody().postProcess();
super.visitFunctionLiteralValue(instruction); instruction.setSink(getSinkInstruction());
super.visitLocalDeclarationInstruction(instruction);
} }
@Override @Override
@@ -173,12 +187,18 @@ public class Pseudocode {
// Nothing // Nothing
} }
@Override
public void visitSubroutineSink(SubroutineSinkInstruction instruction) {
// Nothing
}
@Override @Override
public void visitInstruction(Instruction instruction) { public void visitInstruction(Instruction instruction) {
throw new UnsupportedOperationException(instruction.toString()); throw new UnsupportedOperationException(instruction.toString());
} }
}); });
} }
getExitInstruction().setSink(getSinkInstruction());
removeDeadInstructions(); removeDeadInstructions();
} }
@@ -188,7 +208,7 @@ public class Pseudocode {
while (hasRemovedInstruction) { while (hasRemovedInstruction) {
hasRemovedInstruction = false; hasRemovedInstruction = false;
for (Instruction instruction : instructions) { for (Instruction instruction : instructions) {
if (!(instruction instanceof SubroutineEnterInstruction || instruction instanceof SubroutineExitInstruction) && if (!(instruction instanceof SubroutineEnterInstruction || instruction instanceof SubroutineExitInstruction || instruction instanceof SubroutineSinkInstruction) &&
instruction.getPreviousInstructions().isEmpty() && !processedInstructions.contains(instruction)) { instruction.getPreviousInstructions().isEmpty() && !processedInstructions.contains(instruction)) {
hasRemovedInstruction = true; hasRemovedInstruction = true;
for (Instruction nextInstruction : instruction.getNextInstructions()) { for (Instruction nextInstruction : instruction.getNextInstructions()) {
@@ -12,6 +12,7 @@ import java.util.Collections;
public class SubroutineExitInstruction extends InstructionImpl { public class SubroutineExitInstruction extends InstructionImpl {
private final JetElement subroutine; private final JetElement subroutine;
private final String debugLabel; private final String debugLabel;
private SubroutineSinkInstruction sinkInstruction;
public SubroutineExitInstruction(@NotNull JetElement subroutine, @NotNull String debugLabel) { public SubroutineExitInstruction(@NotNull JetElement subroutine, @NotNull String debugLabel) {
this.subroutine = subroutine; this.subroutine = subroutine;
@@ -22,9 +23,16 @@ public class SubroutineExitInstruction extends InstructionImpl {
return subroutine; return subroutine;
} }
public void setSink(SubroutineSinkInstruction instruction) {
sinkInstruction = (SubroutineSinkInstruction) outgoingEdgeTo(instruction);
}
@NotNull @NotNull
@Override @Override
public Collection<Instruction> getNextInstructions() { public Collection<Instruction> getNextInstructions() {
if (sinkInstruction != null) {
return Collections.<Instruction>singleton(sinkInstruction);
}
return Collections.emptyList(); return Collections.emptyList();
} }
@@ -0,0 +1,40 @@
package org.jetbrains.jet.lang.cfg.pseudocode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetElement;
import java.util.Collection;
import java.util.Collections;
/**
* @author svtk
*/
public class SubroutineSinkInstruction extends InstructionImpl {
private final JetElement subroutine;
private final String debugLabel;
public SubroutineSinkInstruction(@NotNull JetElement subroutine, @NotNull String debugLabel) {
this.subroutine = subroutine;
this.debugLabel = debugLabel;
}
public JetElement getSubroutine() {
return subroutine;
}
@NotNull
@Override
public Collection<Instruction> getNextInstructions() {
return Collections.emptyList();
}
@Override
public void accept(InstructionVisitor visitor) {
visitor.visitSubroutineSink(this);
}
@Override
public String toString() {
return debugLabel;
}
}
@@ -16,26 +16,30 @@ class AnonymousInitializers() {
} }
--------------------- ---------------------
l0: l0:
<START> NEXT:[r(34)] PREV:[] <START> NEXT:[r(34)] PREV:[]
r(34) NEXT:[w(k)] PREV:[<START>] r(34) NEXT:[w(k)] PREV:[<START>]
w(k) NEXT:[r(12)] PREV:[r(34)] w(k) NEXT:[r(12)] PREV:[r(34)]
r(12) NEXT:[w($i)] PREV:[w(k)] r(12) NEXT:[w($i)] PREV:[w(k)]
w($i) NEXT:[r(13)] PREV:[r(12)] w($i) NEXT:[r(13)] PREV:[r(12)]
r(13) NEXT:[w($i)] PREV:[w($i)] r(13) NEXT:[w($i)] PREV:[w($i)]
w($i) NEXT:[<END>] PREV:[r(13)] w($i) NEXT:[<END>] PREV:[r(13)]
l1: l1:
<END> NEXT:[] PREV:[w($i)] <END> NEXT:[<SINK>] PREV:[w($i)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
== k == == k ==
val k = 34 val k = 34
--------------------- ---------------------
l0: l0:
<START> NEXT:[r(34)] PREV:[] <START> NEXT:[r(34)] PREV:[]
r(34) NEXT:[<END>] PREV:[<START>] r(34) NEXT:[<END>] PREV:[<START>]
l1: l1:
<END> NEXT:[] PREV:[r(34)] <END> NEXT:[<SINK>] PREV:[r(34)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
@@ -32,7 +32,9 @@ l0:
r(+=) NEXT:[w(a[10])] PREV:[r(1)] r(+=) NEXT:[w(a[10])] PREV:[r(1)]
w(a[10]) NEXT:[<END>] PREV:[r(+=)] w(a[10]) NEXT:[<END>] PREV:[r(+=)]
l1: l1:
<END> NEXT:[] PREV:[w(a[10])] <END> NEXT:[<SINK>] PREV:[w(a[10])]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
@@ -4,11 +4,13 @@ class Test {
} }
--------------------- ---------------------
l0: l0:
<START> NEXT:[<END>] PREV:[] <START> NEXT:[<END>] PREV:[]
l1: l1:
<END> NEXT:[] PREV:[<START>] <END> NEXT:[<SINK>] PREV:[<START>]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
== assignments == == assignments ==
fun assignments() : Unit { fun assignments() : Unit {
@@ -63,7 +65,9 @@ l5:
r(=) NEXT:[w(t.x)] PREV:[r(t)] r(=) NEXT:[w(t.x)] PREV:[r(t)]
w(t.x) NEXT:[<END>] PREV:[r(=)] w(t.x) NEXT:[<END>] PREV:[r(=)]
l1: l1:
<END> NEXT:[] PREV:[w(t.x)] <END> NEXT:[<SINK>] PREV:[w(t.x)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
+25 -13
View File
@@ -2,12 +2,14 @@
{1} {1}
--------------------- ---------------------
l2: l2:
<START> NEXT:[r(1)] PREV:[] <START> NEXT:[r(1)] PREV:[]
r(1) NEXT:[<END>] PREV:[<START>] r(1) NEXT:[<END>] PREV:[<START>]
l3: l3:
<END> NEXT:[] PREV:[r(1)] <END> NEXT:[<SINK>] PREV:[r(1)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
== f == == f ==
fun f(a : Boolean) : Unit { fun f(a : Boolean) : Unit {
@@ -41,7 +43,7 @@ l0:
r(foo(a, 3)) NEXT:[r(genfun)] PREV:[r(foo)] r(foo(a, 3)) NEXT:[r(genfun)] PREV:[r(foo)]
r(genfun) NEXT:[r(genfun<Any>())] PREV:[r(foo(a, 3))] r(genfun) NEXT:[r(genfun<Any>())] PREV:[r(foo(a, 3))]
r(genfun<Any>()) NEXT:[df({1})] PREV:[r(genfun)] r(genfun<Any>()) NEXT:[df({1})] PREV:[r(genfun)]
df({1}) NEXT:[r({1})] PREV:[r(genfun<Any>())] df({1}) NEXT:[<SINK>, r({1})] PREV:[r(genfun<Any>())]
r({1}) NEXT:[r(flfun)] PREV:[df({1})] r({1}) NEXT:[r(flfun)] PREV:[df({1})]
r(flfun) NEXT:[r(flfun {1})] PREV:[r({1})] r(flfun) NEXT:[r(flfun {1})] PREV:[r({1})]
r(flfun {1}) NEXT:[r(3)] PREV:[r(flfun)] r(flfun {1}) NEXT:[r(3)] PREV:[r(flfun)]
@@ -69,16 +71,20 @@ l4:
l5: l5:
r(a || false) NEXT:[<END>] PREV:[jt(l5), r(false)] r(a || false) NEXT:[<END>] PREV:[jt(l5), r(false)]
l1: l1:
<END> NEXT:[] PREV:[r(a || false)] <END> NEXT:[<SINK>] PREV:[r(a || false)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[df({1}), <END>]
l2: l2:
<START> NEXT:[r(1)] PREV:[] <START> NEXT:[r(1)] PREV:[]
r(1) NEXT:[<END>] PREV:[<START>] r(1) NEXT:[<END>] PREV:[<START>]
l3: l3:
<END> NEXT:[] PREV:[r(1)] <END> NEXT:[<SINK>] PREV:[r(1)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
== foo == == foo ==
fun foo(a : Boolean, b : Int) : Unit {} fun foo(a : Boolean, b : Int) : Unit {}
@@ -87,9 +93,11 @@ l0:
<START> NEXT:[read (Unit)] PREV:[] <START> NEXT:[read (Unit)] PREV:[]
read (Unit) NEXT:[<END>] PREV:[<START>] read (Unit) NEXT:[<END>] PREV:[<START>]
l1: l1:
<END> NEXT:[] PREV:[read (Unit)] <END> NEXT:[<SINK>] PREV:[read (Unit)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
== genfun == == genfun ==
fun genfun<T>() : Unit {} fun genfun<T>() : Unit {}
@@ -98,9 +106,11 @@ l0:
<START> NEXT:[read (Unit)] PREV:[] <START> NEXT:[read (Unit)] PREV:[]
read (Unit) NEXT:[<END>] PREV:[<START>] read (Unit) NEXT:[<END>] PREV:[<START>]
l1: l1:
<END> NEXT:[] PREV:[read (Unit)] <END> NEXT:[<SINK>] PREV:[read (Unit)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
== flfun == == flfun ==
fun flfun(f : fun () : Any) : Unit {} fun flfun(f : fun () : Any) : Unit {}
@@ -109,7 +119,9 @@ l0:
<START> NEXT:[read (Unit)] PREV:[] <START> NEXT:[read (Unit)] PREV:[]
read (Unit) NEXT:[<END>] PREV:[<START>] read (Unit) NEXT:[<END>] PREV:[<START>]
l1: l1:
<END> NEXT:[] PREV:[read (Unit)] <END> NEXT:[<SINK>] PREV:[read (Unit)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
@@ -5,7 +5,9 @@ l0:
<START> NEXT:[read (Unit)] PREV:[] <START> NEXT:[read (Unit)] PREV:[]
read (Unit) NEXT:[<END>] PREV:[<START>] read (Unit) NEXT:[<END>] PREV:[<START>]
l1: l1:
<END> NEXT:[] PREV:[read (Unit)] <END> NEXT:[<SINK>] PREV:[read (Unit)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
@@ -13,7 +13,9 @@ l0:
r(java.lang.RuntimeException()) NEXT:[jmp(error)] PREV:[r(RuntimeException())] r(java.lang.RuntimeException()) NEXT:[jmp(error)] PREV:[r(RuntimeException())]
jmp(error) NEXT:[<ERROR>] PREV:[r(java.lang.RuntimeException())] jmp(error) NEXT:[<ERROR>] PREV:[r(java.lang.RuntimeException())]
l1: l1:
<END> NEXT:[] PREV:[] <END> NEXT:[<SINK>] PREV:[]
error: error:
<ERROR> NEXT:[] PREV:[jmp(error)] <ERROR> NEXT:[] PREV:[jmp(error)]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
+56 -26
View File
@@ -14,9 +14,11 @@ l0:
l2: l2:
r(2) NEXT:[<END>] PREV:[jmp?(l2), r(1)] r(2) NEXT:[<END>] PREV:[jmp?(l2), r(1)]
l1: l1:
<END> NEXT:[] PREV:[r(2)] <END> NEXT:[<SINK>] PREV:[r(2)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
== t3 == == t3 ==
fun t3() { fun t3() {
@@ -48,9 +50,11 @@ l2:
l4: l4:
r(2) NEXT:[<END>] PREV:[jmp?(l2), read (Unit)] r(2) NEXT:[<END>] PREV:[jmp?(l2), read (Unit)]
l1: l1:
<END> NEXT:[] PREV:[ret l1, r(2)] <END> NEXT:[<SINK>] PREV:[ret l1, r(2)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
== anonymous_0 == == anonymous_0 ==
{ () => { () =>
@@ -72,9 +76,11 @@ l5:
read (Unit) NEXT:[<END>] PREV:[jf(l5)] read (Unit) NEXT:[<END>] PREV:[jf(l5)]
l4: l4:
l6: l6:
<END> NEXT:[] PREV:[ret l4, read (Unit)] <END> NEXT:[<SINK>] PREV:[ret l4, read (Unit)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
== t3 == == t3 ==
fun t3() { fun t3() {
@@ -91,25 +97,27 @@ fun t3() {
} }
--------------------- ---------------------
l0: l0:
<START> NEXT:[jmp?(l2)] PREV:[] <START> NEXT:[jmp?(l2)] PREV:[]
jmp?(l2) NEXT:[r(2), r(1)] PREV:[<START>] jmp?(l2) NEXT:[r(2), r(1)] PREV:[<START>]
r(1) NEXT:[df({ () => if (2 > 3) { retu..)] PREV:[jmp?(l2)] r(1) NEXT:[df({ () => if (2 > 3) { retu..)] PREV:[jmp?(l2)]
df({ () => df({ () =>
if (2 > 3) { if (2 > 3) {
return@ return@
} }
}) NEXT:[r({ () => if (2 > 3) { retur..)] PREV:[r(1)] }) NEXT:[<SINK>, r({ () => if (2 > 3) { retur..)] PREV:[r(1)]
r({ () => r({ () =>
if (2 > 3) { if (2 > 3) {
return@ return@
} }
}) NEXT:[r(2)] PREV:[df({ () => if (2 > 3) { retu..)] }) NEXT:[r(2)] PREV:[df({ () => if (2 > 3) { retu..)]
l2: l2:
r(2) NEXT:[<END>] PREV:[jmp?(l2), r({ () => if (2 > 3) { retur..)] r(2) NEXT:[<END>] PREV:[jmp?(l2), r({ () => if (2 > 3) { retur..)]
l1: l1:
<END> NEXT:[] PREV:[r(2)] <END> NEXT:[<SINK>] PREV:[r(2)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[df({ () => if (2 > 3) { retu..), <END>]
l3: l3:
<START> NEXT:[r(2)] PREV:[] <START> NEXT:[r(2)] PREV:[]
r(2) NEXT:[r(3)] PREV:[<START>] r(2) NEXT:[r(3)] PREV:[<START>]
@@ -123,9 +131,11 @@ l5:
read (Unit) NEXT:[<END>] PREV:[jf(l5)] read (Unit) NEXT:[<END>] PREV:[jf(l5)]
l4: l4:
l6: l6:
<END> NEXT:[] PREV:[ret l4, read (Unit)] <END> NEXT:[<SINK>] PREV:[ret l4, read (Unit)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
== anonymous_1 == == anonymous_1 ==
{ () => { () =>
@@ -157,9 +167,11 @@ l4:
l6: l6:
r(2) NEXT:[<END>] PREV:[jmp?(l4), read (Unit)] r(2) NEXT:[<END>] PREV:[jmp?(l4), read (Unit)]
l3: l3:
<END> NEXT:[] PREV:[ret l3, r(2)] <END> NEXT:[<SINK>] PREV:[ret l3, r(2)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
== t3 == == t3 ==
fun t3() { fun t3() {
@@ -176,7 +188,7 @@ fun t3() {
} }
--------------------- ---------------------
l0: l0:
<START> NEXT:[df({ () => try { 1 if (2 > 3..)] PREV:[] <START> NEXT:[df({ () => try { 1 if (2 > 3..)] PREV:[]
df({ () => df({ () =>
try { try {
1 1
@@ -186,7 +198,7 @@ l0:
} finally { } finally {
2 2
} }
}) NEXT:[r({ () => try { 1 if (2 > 3)..)] PREV:[<START>] }) NEXT:[<SINK>, r({ () => try { 1 if (2 > 3)..)] PREV:[<START>]
r({ () => r({ () =>
try { try {
1 1
@@ -196,11 +208,13 @@ l0:
} finally { } finally {
2 2
} }
}) NEXT:[<END>] PREV:[df({ () => try { 1 if (2 > 3..)] }) NEXT:[<END>] PREV:[df({ () => try { 1 if (2 > 3..)]
l1: l1:
<END> NEXT:[] PREV:[r({ () => try { 1 if (2 > 3)..)] <END> NEXT:[<SINK>] PREV:[r({ () => try { 1 if (2 > 3)..)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[df({ () => try { 1 if (2 > 3..), <END>]
l2: l2:
<START> NEXT:[jmp?(l4)] PREV:[] <START> NEXT:[jmp?(l4)] PREV:[]
jmp?(l4) NEXT:[r(2), r(1)] PREV:[<START>] jmp?(l4) NEXT:[r(2), r(1)] PREV:[<START>]
@@ -219,9 +233,11 @@ l4:
l6: l6:
r(2) NEXT:[<END>] PREV:[jmp?(l4), read (Unit)] r(2) NEXT:[<END>] PREV:[jmp?(l4), read (Unit)]
l3: l3:
<END> NEXT:[] PREV:[ret l3, r(2)] <END> NEXT:[<SINK>] PREV:[ret l3, r(2)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
== t3 == == t3 ==
fun t3() { fun t3() {
@@ -263,9 +279,11 @@ l8:
l3: l3:
read (Unit) NEXT:[<END>] PREV:[jf(l3), jmp(l3)] read (Unit) NEXT:[<END>] PREV:[jf(l3), jmp(l3)]
l1: l1:
<END> NEXT:[] PREV:[read (Unit)] <END> NEXT:[<SINK>] PREV:[read (Unit)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
== t3 == == t3 ==
fun t3() { fun t3() {
@@ -308,9 +326,11 @@ l4:
l2: l2:
r(2) NEXT:[<END>] PREV:[jmp?(l2), r(5)] r(2) NEXT:[<END>] PREV:[jmp?(l2), r(5)]
l1: l1:
<END> NEXT:[] PREV:[r(2)] <END> NEXT:[<SINK>] PREV:[r(2)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
== t3 == == t3 ==
fun t3() { fun t3() {
@@ -351,9 +371,11 @@ l4:
l2: l2:
r(2) NEXT:[<END>] PREV:[jmp?(l2), read (Unit)] r(2) NEXT:[<END>] PREV:[jmp?(l2), read (Unit)]
l1: l1:
<END> NEXT:[] PREV:[r(2)] <END> NEXT:[<SINK>] PREV:[r(2)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
== t3 == == t3 ==
fun t3(a : Int) { fun t3(a : Int) {
@@ -399,9 +421,11 @@ l8:
l2: l2:
read (Unit) NEXT:[<END>] PREV:[jmp?(l2), jmp?(l4)] read (Unit) NEXT:[<END>] PREV:[jmp?(l2), jmp?(l4)]
l1: l1:
<END> NEXT:[] PREV:[read (Unit)] <END> NEXT:[<SINK>] PREV:[read (Unit)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
== t3 == == t3 ==
fun t3(a : Int) { fun t3(a : Int) {
@@ -448,9 +472,11 @@ l3:
l2: l2:
r(2) NEXT:[<END>] PREV:[jmp?(l2), r(5)] r(2) NEXT:[<END>] PREV:[jmp?(l2), r(5)]
l1: l1:
<END> NEXT:[] PREV:[r(2)] <END> NEXT:[<SINK>] PREV:[r(2)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
== t3 == == t3 ==
fun t3(a : Int) { fun t3(a : Int) {
@@ -495,9 +521,11 @@ l3:
l2: l2:
r(2) NEXT:[<END>] PREV:[jmp?(l2), read (Unit)] r(2) NEXT:[<END>] PREV:[jmp?(l2), read (Unit)]
l1: l1:
<END> NEXT:[] PREV:[r(2)] <END> NEXT:[<SINK>] PREV:[r(2)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
== tf == == tf ==
fun tf() { fun tf() {
@@ -520,7 +548,9 @@ l2:
r(2) NEXT:[ret(*) l1] PREV:[jmp?(l2)] r(2) NEXT:[ret(*) l1] PREV:[jmp?(l2)]
ret(*) l1 NEXT:[<END>] PREV:[r(2)] ret(*) l1 NEXT:[<END>] PREV:[r(2)]
l1: l1:
<END> NEXT:[] PREV:[ret(*) l1, ret(*) l1] <END> NEXT:[<SINK>] PREV:[ret(*) l1, ret(*) l1]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
+6 -2
View File
@@ -23,9 +23,11 @@ l5:
l2: l2:
read (Unit) NEXT:[<END>] PREV:[jmp?(l2), jmp?(l4)] read (Unit) NEXT:[<END>] PREV:[jmp?(l2), jmp?(l4)]
l1: l1:
<END> NEXT:[] PREV:[read (Unit)] <END> NEXT:[<SINK>] PREV:[read (Unit)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
== doSmth == == doSmth ==
fun doSmth(i: Int) {} fun doSmth(i: Int) {}
@@ -34,7 +36,9 @@ l0:
<START> NEXT:[read (Unit)] PREV:[] <START> NEXT:[read (Unit)] PREV:[]
read (Unit) NEXT:[<END>] PREV:[<START>] read (Unit) NEXT:[<END>] PREV:[<START>]
l1: l1:
<END> NEXT:[] PREV:[read (Unit)] <END> NEXT:[<SINK>] PREV:[read (Unit)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
+9 -3
View File
@@ -42,9 +42,11 @@ l5:
r(doSmth) NEXT:[r(doSmth(r))] PREV:[r(r)] r(doSmth) NEXT:[r(doSmth(r))] PREV:[r(r)]
r(doSmth(r)) NEXT:[<END>] PREV:[r(doSmth)] r(doSmth(r)) NEXT:[<END>] PREV:[r(doSmth)]
l1: l1:
<END> NEXT:[] PREV:[r(doSmth(r))] <END> NEXT:[<SINK>] PREV:[r(doSmth(r))]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
== t2 == == t2 ==
fun t2(b: Boolean) { fun t2(b: Boolean) {
@@ -81,9 +83,11 @@ l4:
read (Unit) NEXT:[<END>] PREV:[jf(l4)] read (Unit) NEXT:[<END>] PREV:[jf(l4)]
l1: l1:
l5: l5:
<END> NEXT:[] PREV:[ret l1, ret l1, read (Unit)] <END> NEXT:[<SINK>] PREV:[ret l1, ret l1, read (Unit)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
== doSmth == == doSmth ==
fun doSmth(s: String) {} fun doSmth(s: String) {}
@@ -92,7 +96,9 @@ l0:
<START> NEXT:[read (Unit)] PREV:[] <START> NEXT:[read (Unit)] PREV:[]
read (Unit) NEXT:[<END>] PREV:[<START>] read (Unit) NEXT:[<END>] PREV:[<START>]
l1: l1:
<END> NEXT:[] PREV:[read (Unit)] <END> NEXT:[<SINK>] PREV:[read (Unit)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
@@ -66,7 +66,9 @@ l12:
l13: l13:
r(14) NEXT:[<END>] PREV:[jmp(l13), r(13)] r(14) NEXT:[<END>] PREV:[jmp(l13), r(13)]
l1: l1:
<END> NEXT:[] PREV:[r(14)] <END> NEXT:[<SINK>] PREV:[r(14)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
@@ -20,9 +20,11 @@ l4:
l3: l3:
read (Unit) NEXT:[<END>] PREV:[jf(l3)] read (Unit) NEXT:[<END>] PREV:[jf(l3)]
l1: l1:
<END> NEXT:[] PREV:[read (Unit)] <END> NEXT:[<SINK>] PREV:[read (Unit)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
== dowhile == == dowhile ==
fun dowhile() { fun dowhile() {
@@ -44,7 +46,9 @@ l5:
l3: l3:
* read (Unit) NEXT:[<END>] PREV:[] * read (Unit) NEXT:[<END>] PREV:[]
l1: l1:
<END> NEXT:[] PREV:[ret l1] <END> NEXT:[<SINK>] PREV:[ret l1]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
@@ -12,7 +12,9 @@ l0:
l2: l2:
r(false || (return false)) NEXT:[<END>] PREV:[jt(l2)] r(false || (return false)) NEXT:[<END>] PREV:[jt(l2)]
l1: l1:
<END> NEXT:[] PREV:[ret(*) l1, r(false || (return false))] <END> NEXT:[<SINK>] PREV:[ret(*) l1, r(false || (return false))]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
@@ -2,10 +2,12 @@
fun short() = 1 fun short() = 1
--------------------- ---------------------
l0: l0:
<START> NEXT:[r(1)] PREV:[] <START> NEXT:[r(1)] PREV:[]
r(1) NEXT:[<END>] PREV:[<START>] r(1) NEXT:[<END>] PREV:[<START>]
l1: l1:
<END> NEXT:[] PREV:[r(1)] <END> NEXT:[<SINK>] PREV:[r(1)]
error: error:
<ERROR> NEXT:[] PREV:[] <ERROR> NEXT:[] PREV:[]
sink:
<SINK> NEXT:[] PREV:[<END>]
===================== =====================
@@ -123,7 +123,7 @@ public class JetControlFlowTest extends JetLiteFixture {
//check edges directions //check edges directions
Collection<Instruction> instructions = pseudocode.getInstructions(); Collection<Instruction> instructions = pseudocode.getInstructions();
for (Instruction instruction : instructions) { for (Instruction instruction : instructions) {
if (!((InstructionImpl) instruction).isDead()) { if (!instruction.isDead()) {
for (Instruction nextInstruction : instruction.getNextInstructions()) { for (Instruction nextInstruction : instruction.getNextInstructions()) {
assertTrue("instruction '" + instruction + "' has '" + nextInstruction + "' among next instructions list, but not vice versa", assertTrue("instruction '" + instruction + "' has '" + nextInstruction + "' among next instructions list, but not vice versa",
nextInstruction.getPreviousInstructions().contains(instruction)); nextInstruction.getPreviousInstructions().contains(instruction));
@@ -170,7 +170,7 @@ public class JetControlFlowTest extends JetLiteFixture {
private static String formatInstruction(Instruction instruction, int maxLength) { private static String formatInstruction(Instruction instruction, int maxLength) {
String[] parts = instruction.toString().split("\n"); String[] parts = instruction.toString().split("\n");
String prefix = ((InstructionImpl)instruction).isDead() ? "* " : " "; String prefix = instruction.isDead() ? "* " : " ";
if (parts.length == 1) { if (parts.length == 1) {
return prefix + String.format("%1$-" + maxLength + "s", instruction); return prefix + String.format("%1$-" + maxLength + "s", instruction);
} }
@@ -266,7 +266,7 @@ public class JetControlFlowTest extends JetLiteFixture {
for (final Instruction fromInst : instructions) { for (final Instruction fromInst : instructions) {
fromInst.accept(new InstructionVisitor() { fromInst.accept(new InstructionVisitor() {
@Override @Override
public void visitFunctionLiteralValue(LocalDeclarationInstruction instruction) { public void visitLocalDeclarationInstruction(LocalDeclarationInstruction instruction) {
int index = count[0]; int index = count[0];
// instruction.getBody().dumpSubgraph(out, "subgraph cluster_" + index, count, "color=blue;\nlabel = \"f" + index + "\";", nodeToName); // instruction.getBody().dumpSubgraph(out, "subgraph cluster_" + index, count, "color=blue;\nlabel = \"f" + index + "\";", nodeToName);
printEdge(out, nodeToName.get(instruction), nodeToName.get(instruction.getBody().getInstructions().get(0)), null); printEdge(out, nodeToName.get(instruction), nodeToName.get(instruction.getBody().getInstructions().get(0)), null);