Extracted 'generateBooleanOperation'
Generate magic instruction for '&&, ||' in condition as well
This commit is contained in:
@@ -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
|
||||
=====================
|
||||
|
||||
+1
-1
@@ -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<!>
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user