Search in sources :

Example 21 with LabelNode

use of com.facebook.presto.bytecode.instruction.LabelNode in project presto by prestodb.

the class InCodeGenerator method buildInCase.

private static BytecodeBlock buildInCase(BytecodeGeneratorContext generatorContext, Scope scope, Type type, LabelNode caseLabel, LabelNode matchLabel, LabelNode noMatchLabel, Collection<BytecodeNode> testValues, boolean checkForNulls) {
    // caseWasNull is set to true the first time a null in `testValues` is encountered
    Variable caseWasNull = null;
    if (checkForNulls) {
        caseWasNull = scope.createTempVariable(boolean.class);
    }
    BytecodeBlock caseBlock = new BytecodeBlock().visitLabel(caseLabel);
    if (checkForNulls) {
        caseBlock.putVariable(caseWasNull, false);
    }
    LabelNode elseLabel = new LabelNode("else");
    BytecodeBlock elseBlock = new BytecodeBlock().visitLabel(elseLabel);
    Variable wasNull = generatorContext.wasNull();
    if (checkForNulls) {
        elseBlock.append(wasNull.set(caseWasNull));
    }
    elseBlock.gotoLabel(noMatchLabel);
    ScalarFunctionImplementation operator = generatorContext.getRegistry().getScalarFunctionImplementation(internalOperator(EQUAL, BOOLEAN, ImmutableList.of(type, type)));
    Binding equalsFunction = generatorContext.getCallSiteBinder().bind(operator.getMethodHandle());
    BytecodeNode elseNode = elseBlock;
    for (BytecodeNode testNode : testValues) {
        LabelNode testLabel = new LabelNode("test");
        IfStatement test = new IfStatement();
        test.condition().visitLabel(testLabel).dup(type.getJavaType()).append(testNode);
        if (checkForNulls) {
            IfStatement wasNullCheck = new IfStatement("if wasNull, set caseWasNull to true, clear wasNull, pop 2 values of type, and goto next test value");
            wasNullCheck.condition(wasNull);
            wasNullCheck.ifTrue(new BytecodeBlock().append(caseWasNull.set(constantTrue())).append(wasNull.set(constantFalse())).pop(type.getJavaType()).pop(type.getJavaType()).gotoLabel(elseLabel));
            test.condition().append(wasNullCheck);
        }
        test.condition().append(invoke(equalsFunction, EQUAL.name()));
        test.ifTrue().gotoLabel(matchLabel);
        test.ifFalse(elseNode);
        elseNode = test;
        elseLabel = testLabel;
    }
    caseBlock.append(elseNode);
    return caseBlock;
}
Also used : LabelNode(com.facebook.presto.bytecode.instruction.LabelNode) ScalarFunctionImplementation(com.facebook.presto.operator.scalar.ScalarFunctionImplementation) IfStatement(com.facebook.presto.bytecode.control.IfStatement) Variable(com.facebook.presto.bytecode.Variable) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) BytecodeNode(com.facebook.presto.bytecode.BytecodeNode)

Example 22 with LabelNode

use of com.facebook.presto.bytecode.instruction.LabelNode in project presto by prestodb.

the class BytecodeUtils method generateInvocation.

public static BytecodeNode generateInvocation(Scope scope, String name, ScalarFunctionImplementation function, Optional<BytecodeNode> instance, List<BytecodeNode> arguments, Binding binding) {
    MethodType methodType = binding.getType();
    Class<?> returnType = methodType.returnType();
    Class<?> unboxedReturnType = Primitives.unwrap(returnType);
    LabelNode end = new LabelNode("end");
    BytecodeBlock block = new BytecodeBlock().setDescription("invoke " + name);
    List<Class<?>> stackTypes = new ArrayList<>();
    if (function.getInstanceFactory().isPresent()) {
        checkArgument(instance.isPresent());
    }
    // Index of current parameter in the MethodHandle
    int currentParameterIndex = 0;
    // Index of parameter (without @IsNull) in Presto function
    int realParameterIndex = 0;
    boolean boundInstance = false;
    while (currentParameterIndex < methodType.parameterArray().length) {
        Class<?> type = methodType.parameterArray()[currentParameterIndex];
        stackTypes.add(type);
        if (function.getInstanceFactory().isPresent() && !boundInstance) {
            checkState(type.equals(function.getInstanceFactory().get().type().returnType()), "Mismatched type for instance parameter");
            block.append(instance.get());
            boundInstance = true;
        } else if (type == ConnectorSession.class) {
            block.append(scope.getVariable("session"));
        } else {
            block.append(arguments.get(realParameterIndex));
            if (!function.getNullableArguments().get(realParameterIndex)) {
                checkArgument(!Primitives.isWrapperType(type), "Non-nullable argument must not be primitive wrapper type");
                block.append(ifWasNullPopAndGoto(scope, end, unboxedReturnType, Lists.reverse(stackTypes)));
            } else {
                if (function.getNullFlags().get(realParameterIndex)) {
                    if (type == Void.class) {
                        block.append(boxPrimitiveIfNecessary(scope, type));
                    }
                    block.append(scope.getVariable("wasNull"));
                    stackTypes.add(boolean.class);
                    currentParameterIndex++;
                } else {
                    block.append(boxPrimitiveIfNecessary(scope, type));
                }
                block.append(scope.getVariable("wasNull").set(constantFalse()));
            }
            realParameterIndex++;
        }
        currentParameterIndex++;
    }
    block.append(invoke(binding, name));
    if (function.isNullable()) {
        block.append(unboxPrimitiveIfNecessary(scope, returnType));
    }
    block.visitLabel(end);
    return block;
}
Also used : LabelNode(com.facebook.presto.bytecode.instruction.LabelNode) MethodType(java.lang.invoke.MethodType) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) ArrayList(java.util.ArrayList) ConnectorSession(com.facebook.presto.spi.ConnectorSession)

Example 23 with LabelNode

use of com.facebook.presto.bytecode.instruction.LabelNode in project presto by prestodb.

the class JoinCompiler method generateRowEqualsRowMethod.

private static void generateRowEqualsRowMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, List<Type> joinChannelTypes) {
    Parameter leftPosition = arg("leftPosition", int.class);
    Parameter leftPage = arg("leftPage", Page.class);
    Parameter rightPosition = arg("rightPosition", int.class);
    Parameter rightPage = arg("rightPage", Page.class);
    MethodDefinition rowEqualsRowMethod = classDefinition.declareMethod(a(PUBLIC), "rowEqualsRow", type(boolean.class), leftPosition, leftPage, rightPosition, rightPage);
    for (int index = 0; index < joinChannelTypes.size(); index++) {
        BytecodeExpression type = constantType(callSiteBinder, joinChannelTypes.get(index));
        BytecodeExpression leftBlock = leftPage.invoke("getBlock", Block.class, constantInt(index));
        BytecodeExpression rightBlock = rightPage.invoke("getBlock", Block.class, constantInt(index));
        LabelNode checkNextField = new LabelNode("checkNextField");
        rowEqualsRowMethod.getBody().append(typeEquals(type, leftBlock, leftPosition, rightBlock, rightPosition)).ifTrueGoto(checkNextField).push(false).retBoolean().visitLabel(checkNextField);
    }
    rowEqualsRowMethod.getBody().push(true).retInt();
}
Also used : LabelNode(com.facebook.presto.bytecode.instruction.LabelNode) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) Parameter(com.facebook.presto.bytecode.Parameter) BytecodeExpression(com.facebook.presto.bytecode.expression.BytecodeExpression)

Example 24 with LabelNode

use of com.facebook.presto.bytecode.instruction.LabelNode in project presto by prestodb.

the class JoinCompiler method generatePositionEqualsRowMethod.

private static void generatePositionEqualsRowMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, List<Type> joinChannelTypes, List<FieldDefinition> joinChannelFields, boolean ignoreNulls) {
    Parameter leftBlockIndex = arg("leftBlockIndex", int.class);
    Parameter leftBlockPosition = arg("leftBlockPosition", int.class);
    Parameter rightPosition = arg("rightPosition", int.class);
    Parameter rightPage = arg("rightPage", Page.class);
    MethodDefinition positionEqualsRowMethod = classDefinition.declareMethod(a(PUBLIC), ignoreNulls ? "positionEqualsRowIgnoreNulls" : "positionEqualsRow", type(boolean.class), leftBlockIndex, leftBlockPosition, rightPosition, rightPage);
    Variable thisVariable = positionEqualsRowMethod.getThis();
    for (int index = 0; index < joinChannelTypes.size(); index++) {
        BytecodeExpression type = constantType(callSiteBinder, joinChannelTypes.get(index));
        BytecodeExpression leftBlock = thisVariable.getField(joinChannelFields.get(index)).invoke("get", Object.class, leftBlockIndex).cast(Block.class);
        BytecodeExpression rightBlock = rightPage.invoke("getBlock", Block.class, constantInt(index));
        BytecodeNode equalityCondition;
        if (ignoreNulls) {
            equalityCondition = typeEqualsIgnoreNulls(type, leftBlock, leftBlockPosition, rightBlock, rightPosition);
        } else {
            equalityCondition = typeEquals(type, leftBlock, leftBlockPosition, rightBlock, rightPosition);
        }
        LabelNode checkNextField = new LabelNode("checkNextField");
        positionEqualsRowMethod.getBody().append(equalityCondition).ifTrueGoto(checkNextField).push(false).retBoolean().visitLabel(checkNextField);
    }
    positionEqualsRowMethod.getBody().push(true).retInt();
}
Also used : LabelNode(com.facebook.presto.bytecode.instruction.LabelNode) Variable(com.facebook.presto.bytecode.Variable) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) Parameter(com.facebook.presto.bytecode.Parameter) BytecodeNode(com.facebook.presto.bytecode.BytecodeNode) BytecodeExpression(com.facebook.presto.bytecode.expression.BytecodeExpression)

Aggregations

LabelNode (com.facebook.presto.bytecode.instruction.LabelNode)24 BytecodeBlock (com.facebook.presto.bytecode.BytecodeBlock)18 Variable (com.facebook.presto.bytecode.Variable)14 MethodDefinition (com.facebook.presto.bytecode.MethodDefinition)9 IfStatement (com.facebook.presto.bytecode.control.IfStatement)9 BytecodeNode (com.facebook.presto.bytecode.BytecodeNode)8 Parameter (com.facebook.presto.bytecode.Parameter)7 Scope (com.facebook.presto.bytecode.Scope)7 BytecodeExpression (com.facebook.presto.bytecode.expression.BytecodeExpression)5 RowExpression (com.facebook.presto.sql.relational.RowExpression)4 Signature (com.facebook.presto.metadata.Signature)3 Type (com.facebook.presto.spi.type.Type)3 ForLoop (com.facebook.presto.bytecode.control.ForLoop)2 ScalarFunctionImplementation (com.facebook.presto.operator.scalar.ScalarFunctionImplementation)2 ConnectorSession (com.facebook.presto.spi.ConnectorSession)2 ImmutableList (com.google.common.collect.ImmutableList)2 FieldDefinition (com.facebook.presto.bytecode.FieldDefinition)1 LookupSwitch (com.facebook.presto.bytecode.control.LookupSwitch)1 JumpInstruction (com.facebook.presto.bytecode.instruction.JumpInstruction)1 RecordCursor (com.facebook.presto.spi.RecordCursor)1