Optimize primitive comparison operators codegen

They're no longer generated via intrinsics
This commit is contained in:
Alexander Udalov
2012-11-28 19:42:29 +04:00
parent fad9169005
commit fd0251729b
3 changed files with 23 additions and 19 deletions
@@ -517,4 +517,11 @@ public class AsmUtil {
v.invokestatic("jet/runtime/Intrinsics", assertMethodToCall, "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)V"); v.invokestatic("jet/runtime/Intrinsics", assertMethodToCall, "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)V");
} }
} }
public static Type comparisonOperandType(Type left, Type right) {
if (left == Type.DOUBLE_TYPE || right == Type.DOUBLE_TYPE) return Type.DOUBLE_TYPE;
if (left == Type.FLOAT_TYPE || right == Type.FLOAT_TYPE) return Type.FLOAT_TYPE;
if (left == Type.LONG_TYPE || right == Type.LONG_TYPE) return Type.LONG_TYPE;
return Type.INT_TYPE;
}
} }
@@ -2311,7 +2311,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
} }
else if (opToken == JetTokens.LT || opToken == JetTokens.LTEQ || else if (opToken == JetTokens.LT || opToken == JetTokens.LTEQ ||
opToken == JetTokens.GT || opToken == JetTokens.GTEQ) { opToken == JetTokens.GT || opToken == JetTokens.GTEQ) {
return generateCompareTo(expression); return generateComparison(expression);
} }
else if (opToken == JetTokens.ELVIS) { else if (opToken == JetTokens.ELVIS) {
return generateElvis(expression); return generateElvis(expression);
@@ -2519,25 +2519,29 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
return StackValue.onStack(exprType); return StackValue.onStack(exprType);
} }
private StackValue generateCompareTo(JetBinaryExpression expression) { private StackValue generateComparison(JetBinaryExpression expression) {
DeclarationDescriptor target = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference()); DeclarationDescriptor target = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference());
assert target instanceof FunctionDescriptor : "compareTo target should be a function: " + target; assert target instanceof FunctionDescriptor : "compareTo target should be a function: " + target;
FunctionDescriptor descriptor = (FunctionDescriptor) target; FunctionDescriptor descriptor = (FunctionDescriptor) target;
StackValue receiver = gen(expression.getLeft()); JetExpression left = expression.getLeft();
JetExpression right = expression.getRight();
StackValue receiver = gen(left);
Callable callable = resolveToCallable(descriptor, false); Callable callable = resolveToCallable(descriptor, false);
StackValue result; Type type;
if (callable instanceof IntrinsicMethod) { if (callable instanceof IntrinsicMethod) {
result = ((IntrinsicMethod) callable).generate( // Compare two primitive values
this, v, Type.INT_TYPE, expression, Collections.singletonList(expression.getRight()), receiver, state); type = comparisonOperandType(expressionType(left), expressionType(right));
receiver.put(type, v);
gen(right, type);
} else { } else {
result = invokeOperation(expression, descriptor, (CallableMethod) callable); type = Type.INT_TYPE;
StackValue result = invokeOperation(expression, descriptor, (CallableMethod) callable);
result.put(type, v);
v.iconst(0);
} }
return StackValue.cmp(expression.getOperationToken(), type);
result.put(Type.INT_TYPE, v);
v.iconst(0);
return StackValue.cmp(expression.getOperationToken(), Type.INT_TYPE);
} }
private StackValue generateAssignmentExpression(JetBinaryExpression expression) { private StackValue generateAssignmentExpression(JetBinaryExpression expression) {
@@ -28,7 +28,7 @@ import org.jetbrains.jet.lang.psi.JetExpression;
import java.util.List; import java.util.List;
import static org.jetbrains.jet.codegen.AsmUtil.isPrimitive; import static org.jetbrains.jet.codegen.AsmUtil.comparisonOperandType;
/** /**
* @author alex.tkachman * @author alex.tkachman
@@ -71,11 +71,4 @@ public class CompareTo implements IntrinsicMethod {
} }
return StackValue.onStack(Type.INT_TYPE); return StackValue.onStack(Type.INT_TYPE);
} }
private static Type comparisonOperandType(Type left, Type right) {
if (left == Type.DOUBLE_TYPE || right == Type.DOUBLE_TYPE) return Type.DOUBLE_TYPE;
if (left == Type.FLOAT_TYPE || right == Type.FLOAT_TYPE) return Type.FLOAT_TYPE;
if (left == Type.LONG_TYPE || right == Type.LONG_TYPE) return Type.LONG_TYPE;
return Type.INT_TYPE;
}
} }