Extracted 'generateBooleanOperation'

Generate magic instruction for '&&, ||' in condition as well
This commit is contained in:
Svetlana Isakova
2014-06-20 18:44:53 +04:00
parent 4279da12f5
commit 9d4aad3bbc
5 changed files with 76 additions and 78 deletions
@@ -335,29 +335,8 @@ public class JetControlFlowProcessor {
JetExpression left = expression.getLeft();
JetExpression right = expression.getRight();
if (operationType == ANDAND) {
generateInstructions(left, IN_CONDITION);
Label resultLabel = builder.createUnboundLabel();
builder.jumpOnFalse(resultLabel, expression, builder.getBoundValue(left));
if (right != null) {
generateInstructions(right, IN_CONDITION);
}
builder.bindLabel(resultLabel);
if (!context.inCondition()) {
predefinedOperation(expression, AND);
}
}
else if (operationType == OROR) {
generateInstructions(left, IN_CONDITION);
Label resultLabel = builder.createUnboundLabel();
builder.jumpOnTrue(resultLabel, expression, builder.getBoundValue(left));
if (right != null) {
generateInstructions(right, IN_CONDITION);
}
builder.bindLabel(resultLabel);
if (!context.inCondition()) {
predefinedOperation(expression, OR);
}
if (operationType == ANDAND || operationType == OROR) {
generateBooleanOperation(expression);
}
else if (operationType == EQ) {
visitAssignment(left, getDeferredValue(right), expression);
@@ -402,6 +381,27 @@ public class JetControlFlowProcessor {
}
}
private void generateBooleanOperation(JetBinaryExpression expression) {
IElementType operationType = expression.getOperationReference().getReferencedNameElementType();
JetExpression left = expression.getLeft();
JetExpression right = expression.getRight();
Label resultLabel = builder.createUnboundLabel();
generateInstructions(left, IN_CONDITION);
if (operationType == ANDAND) {
builder.jumpOnFalse(resultLabel, expression, builder.getBoundValue(left));
}
else {
builder.jumpOnTrue(resultLabel, expression, builder.getBoundValue(left));
}
if (right != null) {
generateInstructions(right, IN_CONDITION);
}
builder.bindLabel(resultLabel);
JetControlFlowBuilder.PredefinedOperation operation = operationType == ANDAND ? AND : OR;
builder.predefinedOperation(expression, operation, elementsToValues(Arrays.asList(left, right)));
}
private Function0<PseudoValue> getValueAsFunction(final PseudoValue value) {
return new Function0<PseudoValue>() {
@Override
@@ -421,12 +421,6 @@ public class JetControlFlowProcessor {
};
}
private void predefinedOperation(JetBinaryExpression expression, JetControlFlowBuilder.PredefinedOperation operation) {
builder.predefinedOperation(
expression, operation, elementsToValues(Arrays.asList(expression.getLeft(), expression.getRight()))
);
}
private void generateBothArgumentsAndMark(JetBinaryExpression expression) {
JetExpression left = JetPsiUtil.deparenthesize(expression.getLeft());
if (left != null) {
@@ -40,48 +40,50 @@ L3:
r(3) -> <v6>
mark(if (a && b) 5 else 6)
r(a) -> <v7>
jf(L4|<v7>) NEXT:[jf(L5), r(b) -> <v8>]
jf(L4|<v7>) NEXT:[magic(a && b|<v7>, <v8>) -> <v9>, r(b) -> <v8>]
r(b) -> <v8>
L4:
jf(L5) NEXT:[r(6) -> <v10>, r(5) -> <v9>] PREV:[jf(L4|<v7>), r(b) -> <v8>]
r(5) -> <v9>
jmp(L6) NEXT:[merge(if (a && b) 5 else 6|<v9>, <v10>) -> <v11>]
magic(a && b|<v7>, <v8>) -> <v9> PREV:[jf(L4|<v7>), r(b) -> <v8>]
jf(L5|<v9>) NEXT:[r(6) -> <v11>, r(5) -> <v10>]
r(5) -> <v10>
jmp(L6) NEXT:[merge(if (a && b) 5 else 6|<v10>, <v11>) -> <v12>]
L5:
r(6) -> <v10> PREV:[jf(L5)]
r(6) -> <v11> PREV:[jf(L5|<v9>)]
L6:
merge(if (a && b) 5 else 6|<v9>, <v10>) -> <v11> PREV:[jmp(L6), r(6) -> <v10>]
r(7) -> <v12>
merge(if (a && b) 5 else 6|<v10>, <v11>) -> <v12> PREV:[jmp(L6), r(6) -> <v11>]
r(7) -> <v13>
mark(if (a || b) 8 else 9)
r(a) -> <v13>
jt(L7|<v13>) NEXT:[r(b) -> <v14>, jf(L8)]
r(b) -> <v14>
r(a) -> <v14>
jt(L7|<v14>) NEXT:[r(b) -> <v15>, magic(a || b|<v14>, <v15>) -> <v16>]
r(b) -> <v15>
L7:
jf(L8) NEXT:[r(9) -> <v16>, r(8) -> <v15>] PREV:[jt(L7|<v13>), r(b) -> <v14>]
r(8) -> <v15>
jmp(L9) NEXT:[merge(if (a || b) 8 else 9|<v15>, <v16>) -> <v17>]
magic(a || b|<v14>, <v15>) -> <v16> PREV:[jt(L7|<v14>), r(b) -> <v15>]
jf(L8|<v16>) NEXT:[r(9) -> <v18>, r(8) -> <v17>]
r(8) -> <v17>
jmp(L9) NEXT:[merge(if (a || b) 8 else 9|<v17>, <v18>) -> <v19>]
L8:
r(9) -> <v16> PREV:[jf(L8)]
r(9) -> <v18> PREV:[jf(L8|<v16>)]
L9:
merge(if (a || b) 8 else 9|<v15>, <v16>) -> <v17> PREV:[jmp(L9), r(9) -> <v16>]
r(10) -> <v18>
merge(if (a || b) 8 else 9|<v17>, <v18>) -> <v19> PREV:[jmp(L9), r(9) -> <v18>]
r(10) -> <v20>
mark(if (a) 11)
r(a) -> <v19>
jf(L10|<v19>) NEXT:[read (Unit), r(11) -> <v20>]
r(11) -> <v20>
jmp(L11) NEXT:[r(12) -> <v21>]
r(a) -> <v21>
jf(L10|<v21>) NEXT:[read (Unit), r(11) -> <v22>]
r(11) -> <v22>
jmp(L11) NEXT:[r(12) -> <v23>]
L10:
read (Unit) PREV:[jf(L10|<v19>)]
read (Unit) PREV:[jf(L10|<v21>)]
L11:
r(12) -> <v21> PREV:[jmp(L11), read (Unit)]
r(12) -> <v23> PREV:[jmp(L11), read (Unit)]
mark(if (a) else 13)
r(a) -> <v22>
jf(L12|<v22>) NEXT:[r(13) -> <v23>, read (Unit)]
r(a) -> <v24>
jf(L12|<v24>) NEXT:[r(13) -> <v25>, read (Unit)]
read (Unit)
jmp(L13) NEXT:[r(14) -> <v24>]
jmp(L13) NEXT:[r(14) -> <v26>]
L12:
r(13) -> <v23> PREV:[jf(L12|<v22>)]
r(13) -> <v25> PREV:[jf(L12|<v24>)]
L13:
r(14) -> <v24> PREV:[jmp(L13), r(13) -> <v23>]
r(14) -> <v26> PREV:[jmp(L13), r(13) -> <v25>]
L1:
1 <END> NEXT:[<SINK>]
error:
@@ -17,7 +17,7 @@ fun lazyBooleans(a : Boolean, b : Boolean) : Unit {
14
}
---------------------
a <v2> NEW()
a <v2> NEW()
1 <v3> NEW()
{ 1 } <v3> COPY
2 <v4> NEW()
@@ -26,23 +26,25 @@ if (a) { 1 } else { 2 }
3 <v6> NEW()
a <v7> NEW()
b <v8> NEW()
5 <v9> NEW()
6 <v10> NEW()
if (a && b) 5 else 6 <v11> NEW(<v9>, <v10>)
7 <v12> NEW()
a <v13> NEW()
b <v14> NEW()
8 <v15> NEW()
9 <v16> NEW()
if (a || b) 8 else 9 <v17> NEW(<v15>, <v16>)
10 <v18> NEW()
a <v19> NEW()
11 <v20> NEW()
if (a) 11 <v20> COPY
12 <v21> NEW()
a <v22> NEW()
13 <v23> NEW()
if (a) else 13 <v23> COPY
14 <v24> NEW()
{ if (a) { 1 } else { 2 } 3 if (a && b) 5 else 6 7 if (a || b) 8 else 9 10 if (a) 11 12 if (a) else 13 14 } <v24> COPY
a && b <v9> NEW(<v7>, <v8>)
5 <v10> NEW()
6 <v11> NEW()
if (a && b) 5 else 6 <v12> NEW(<v10>, <v11>)
7 <v13> NEW()
a <v14> NEW()
b <v15> NEW()
a || b <v16> NEW(<v14>, <v15>)
8 <v17> NEW()
9 <v18> NEW()
if (a || b) 8 else 9 <v19> NEW(<v17>, <v18>)
10 <v20> NEW()
a <v21> NEW()
11 <v22> NEW()
if (a) 11 <v22> COPY
12 <v23> NEW()
a <v24> NEW()
13 <v25> NEW()
if (a) else 13 <v25> COPY
14 <v26> NEW()
{ if (a) { 1 } else { 2 } 3 if (a && b) 5 else 6 7 if (a || b) 8 else 9 10 if (a) 11 12 if (a) else 13 14 } <v26> COPY
=====================
@@ -138,7 +138,7 @@ fun tf() : Int {
}
fun failtest(a : Int) : Int {
if (fail() || <!UNREACHABLE_CODE!>true<!>) <!UNREACHABLE_CODE!>{
if (fail() <!UNREACHABLE_CODE!>|| true<!>) <!UNREACHABLE_CODE!>{
}<!>
<!UNREACHABLE_CODE!>return 1<!>
+1 -1
View File
@@ -136,7 +136,7 @@ fun tf() : Int {
}
fun failtest(<warning>a</warning> : Int) : Int {
if (fail() || <warning>true</warning>) <warning>{
if (fail() <warning>|| true</warning>) <warning>{
}</warning>
<warning>return 1</warning>