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 left = expression.getLeft();
JetExpression right = expression.getRight(); JetExpression right = expression.getRight();
if (operationType == ANDAND) { if (operationType == ANDAND || operationType == OROR) {
generateInstructions(left, IN_CONDITION); generateBooleanOperation(expression);
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);
}
} }
else if (operationType == EQ) { else if (operationType == EQ) {
visitAssignment(left, getDeferredValue(right), expression); 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) { private Function0<PseudoValue> getValueAsFunction(final PseudoValue value) {
return new Function0<PseudoValue>() { return new Function0<PseudoValue>() {
@Override @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) { private void generateBothArgumentsAndMark(JetBinaryExpression expression) {
JetExpression left = JetPsiUtil.deparenthesize(expression.getLeft()); JetExpression left = JetPsiUtil.deparenthesize(expression.getLeft());
if (left != null) { if (left != null) {
@@ -40,48 +40,50 @@ L3:
r(3) -> <v6> r(3) -> <v6>
mark(if (a && b) 5 else 6) mark(if (a && b) 5 else 6)
r(a) -> <v7> 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> r(b) -> <v8>
L4: L4:
jf(L5) NEXT:[r(6) -> <v10>, r(5) -> <v9>] PREV:[jf(L4|<v7>), r(b) -> <v8>] magic(a && b|<v7>, <v8>) -> <v9> PREV:[jf(L4|<v7>), r(b) -> <v8>]
r(5) -> <v9> jf(L5|<v9>) NEXT:[r(6) -> <v11>, r(5) -> <v10>]
jmp(L6) NEXT:[merge(if (a && b) 5 else 6|<v9>, <v10>) -> <v11>] r(5) -> <v10>
jmp(L6) NEXT:[merge(if (a && b) 5 else 6|<v10>, <v11>) -> <v12>]
L5: L5:
r(6) -> <v10> PREV:[jf(L5)] r(6) -> <v11> PREV:[jf(L5|<v9>)]
L6: L6:
merge(if (a && b) 5 else 6|<v9>, <v10>) -> <v11> PREV:[jmp(L6), r(6) -> <v10>] merge(if (a && b) 5 else 6|<v10>, <v11>) -> <v12> PREV:[jmp(L6), r(6) -> <v11>]
r(7) -> <v12> r(7) -> <v13>
mark(if (a || b) 8 else 9) mark(if (a || b) 8 else 9)
r(a) -> <v13> r(a) -> <v14>
jt(L7|<v13>) NEXT:[r(b) -> <v14>, jf(L8)] jt(L7|<v14>) NEXT:[r(b) -> <v15>, magic(a || b|<v14>, <v15>) -> <v16>]
r(b) -> <v14> r(b) -> <v15>
L7: L7:
jf(L8) NEXT:[r(9) -> <v16>, r(8) -> <v15>] PREV:[jt(L7|<v13>), r(b) -> <v14>] magic(a || b|<v14>, <v15>) -> <v16> PREV:[jt(L7|<v14>), r(b) -> <v15>]
r(8) -> <v15> jf(L8|<v16>) NEXT:[r(9) -> <v18>, r(8) -> <v17>]
jmp(L9) NEXT:[merge(if (a || b) 8 else 9|<v15>, <v16>) -> <v17>] r(8) -> <v17>
jmp(L9) NEXT:[merge(if (a || b) 8 else 9|<v17>, <v18>) -> <v19>]
L8: L8:
r(9) -> <v16> PREV:[jf(L8)] r(9) -> <v18> PREV:[jf(L8|<v16>)]
L9: L9:
merge(if (a || b) 8 else 9|<v15>, <v16>) -> <v17> PREV:[jmp(L9), r(9) -> <v16>] merge(if (a || b) 8 else 9|<v17>, <v18>) -> <v19> PREV:[jmp(L9), r(9) -> <v18>]
r(10) -> <v18> r(10) -> <v20>
mark(if (a) 11) mark(if (a) 11)
r(a) -> <v19> r(a) -> <v21>
jf(L10|<v19>) NEXT:[read (Unit), r(11) -> <v20>] jf(L10|<v21>) NEXT:[read (Unit), r(11) -> <v22>]
r(11) -> <v20> r(11) -> <v22>
jmp(L11) NEXT:[r(12) -> <v21>] jmp(L11) NEXT:[r(12) -> <v23>]
L10: L10:
read (Unit) PREV:[jf(L10|<v19>)] read (Unit) PREV:[jf(L10|<v21>)]
L11: L11:
r(12) -> <v21> PREV:[jmp(L11), read (Unit)] r(12) -> <v23> PREV:[jmp(L11), read (Unit)]
mark(if (a) else 13) mark(if (a) else 13)
r(a) -> <v22> r(a) -> <v24>
jf(L12|<v22>) NEXT:[r(13) -> <v23>, read (Unit)] jf(L12|<v24>) NEXT:[r(13) -> <v25>, read (Unit)]
read (Unit) read (Unit)
jmp(L13) NEXT:[r(14) -> <v24>] jmp(L13) NEXT:[r(14) -> <v26>]
L12: L12:
r(13) -> <v23> PREV:[jf(L12|<v22>)] r(13) -> <v25> PREV:[jf(L12|<v24>)]
L13: L13:
r(14) -> <v24> PREV:[jmp(L13), r(13) -> <v23>] r(14) -> <v26> PREV:[jmp(L13), r(13) -> <v25>]
L1: L1:
1 <END> NEXT:[<SINK>] 1 <END> NEXT:[<SINK>]
error: error:
@@ -26,23 +26,25 @@ if (a) { 1 } else { 2 }
3 <v6> NEW() 3 <v6> NEW()
a <v7> NEW() a <v7> NEW()
b <v8> NEW() b <v8> NEW()
5 <v9> NEW() a && b <v9> NEW(<v7>, <v8>)
6 <v10> NEW() 5 <v10> NEW()
if (a && b) 5 else 6 <v11> NEW(<v9>, <v10>) 6 <v11> NEW()
7 <v12> NEW() if (a && b) 5 else 6 <v12> NEW(<v10>, <v11>)
a <v13> NEW() 7 <v13> NEW()
b <v14> NEW() a <v14> NEW()
8 <v15> NEW() b <v15> NEW()
9 <v16> NEW() a || b <v16> NEW(<v14>, <v15>)
if (a || b) 8 else 9 <v17> NEW(<v15>, <v16>) 8 <v17> NEW()
10 <v18> NEW() 9 <v18> NEW()
a <v19> NEW() if (a || b) 8 else 9 <v19> NEW(<v17>, <v18>)
11 <v20> NEW() 10 <v20> NEW()
if (a) 11 <v20> COPY a <v21> NEW()
12 <v21> NEW() 11 <v22> NEW()
a <v22> NEW() if (a) 11 <v22> COPY
13 <v23> NEW() 12 <v23> NEW()
if (a) else 13 <v23> COPY a <v24> NEW()
14 <v24> NEW() 13 <v25> 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 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 { fun failtest(a : Int) : Int {
if (fail() || <!UNREACHABLE_CODE!>true<!>) <!UNREACHABLE_CODE!>{ if (fail() <!UNREACHABLE_CODE!>|| true<!>) <!UNREACHABLE_CODE!>{
}<!> }<!>
<!UNREACHABLE_CODE!>return 1<!> <!UNREACHABLE_CODE!>return 1<!>
+1 -1
View File
@@ -136,7 +136,7 @@ fun tf() : Int {
} }
fun failtest(<warning>a</warning> : Int) : Int { fun failtest(<warning>a</warning> : Int) : Int {
if (fail() || <warning>true</warning>) <warning>{ if (fail() <warning>|| true</warning>) <warning>{
}</warning> }</warning>
<warning>return 1</warning> <warning>return 1</warning>