Search in sources :

Example 16 with BytecodeNode

use of io.airlift.bytecode.BytecodeNode in project trino by trinodb.

the class IsNullCodeGenerator method generateExpression.

@Override
public BytecodeNode generateExpression(BytecodeGeneratorContext generatorContext) {
    if (argument.getType().equals(UNKNOWN)) {
        return loadBoolean(true);
    }
    BytecodeNode value = generatorContext.generate(argument);
    // evaluate the expression, pop the produced value, and load the null flag
    Variable wasNull = generatorContext.wasNull();
    BytecodeBlock block = new BytecodeBlock().comment("is null").append(value).pop(argument.getType().getJavaType()).append(wasNull);
    // clear the null flag
    block.append(wasNull.set(constantFalse()));
    return block;
}
Also used : Variable(io.airlift.bytecode.Variable) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) BytecodeNode(io.airlift.bytecode.BytecodeNode)

Example 17 with BytecodeNode

use of io.airlift.bytecode.BytecodeNode in project trino by trinodb.

the class JoinCompiler method generatePositionEqualsRowMethod.

private 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++) {
        Type type = 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(callSiteBinder, type, leftBlock, leftBlockPosition, rightBlock, rightPosition);
        } else {
            equalityCondition = typeEquals(callSiteBinder, 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(io.airlift.bytecode.instruction.LabelNode) SqlTypeBytecodeExpression.constantType(io.trino.sql.gen.SqlTypeBytecodeExpression.constantType) Type(io.trino.spi.type.Type) BigintType(io.trino.spi.type.BigintType) Variable(io.airlift.bytecode.Variable) MethodDefinition(io.airlift.bytecode.MethodDefinition) Parameter(io.airlift.bytecode.Parameter) BytecodeNode(io.airlift.bytecode.BytecodeNode) BytecodeExpression(io.airlift.bytecode.expression.BytecodeExpression)

Example 18 with BytecodeNode

use of io.airlift.bytecode.BytecodeNode in project trino by trinodb.

the class JoinCompiler method generateCompareSortChannelPositionsMethod.

private void generateCompareSortChannelPositionsMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, List<Type> types, List<FieldDefinition> channelFields, Optional<Integer> sortChannel) {
    Parameter leftBlockIndex = arg("leftBlockIndex", int.class);
    Parameter leftBlockPosition = arg("leftBlockPosition", int.class);
    Parameter rightBlockIndex = arg("rightBlockIndex", int.class);
    Parameter rightBlockPosition = arg("rightBlockPosition", int.class);
    MethodDefinition compareMethod = classDefinition.declareMethod(a(PUBLIC), "compareSortChannelPositions", type(int.class), leftBlockIndex, leftBlockPosition, rightBlockIndex, rightBlockPosition);
    if (sortChannel.isEmpty()) {
        compareMethod.getBody().append(newInstance(UnsupportedOperationException.class)).throwObject();
        return;
    }
    Variable thisVariable = compareMethod.getThis();
    int index = sortChannel.get();
    BytecodeExpression leftBlock = thisVariable.getField(channelFields.get(index)).invoke("get", Object.class, leftBlockIndex).cast(Block.class);
    BytecodeExpression rightBlock = thisVariable.getField(channelFields.get(index)).invoke("get", Object.class, rightBlockIndex).cast(Block.class);
    // choice of placing unordered values first or last does not matter for this code
    MethodHandle comparisonOperator = typeOperators.getComparisonUnorderedLastOperator(types.get(index), simpleConvention(FAIL_ON_NULL, BLOCK_POSITION, BLOCK_POSITION));
    BytecodeNode comparison = invokeDynamic(BOOTSTRAP_METHOD, ImmutableList.of(callSiteBinder.bind(comparisonOperator).getBindingId()), "comparison", long.class, leftBlock, leftBlockPosition, rightBlock, rightBlockPosition).cast(int.class).ret();
    compareMethod.getBody().append(comparison);
}
Also used : Variable(io.airlift.bytecode.Variable) MethodDefinition(io.airlift.bytecode.MethodDefinition) Parameter(io.airlift.bytecode.Parameter) BytecodeNode(io.airlift.bytecode.BytecodeNode) BytecodeExpression(io.airlift.bytecode.expression.BytecodeExpression) MethodHandle(java.lang.invoke.MethodHandle)

Example 19 with BytecodeNode

use of io.airlift.bytecode.BytecodeNode in project trino by trinodb.

the class JoinFilterFunctionCompiler method generateFilterMethod.

private void generateFilterMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, CachedInstanceBinder cachedInstanceBinder, Map<LambdaDefinitionExpression, CompiledLambda> compiledLambdaMap, RowExpression filter, int leftBlocksSize, FieldDefinition sessionField) {
    // int leftPosition, Page leftPage, int rightPosition, Page rightPage
    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 method = classDefinition.declareMethod(a(PUBLIC), "filter", type(boolean.class), ImmutableList.<Parameter>builder().add(leftPosition).add(leftPage).add(rightPosition).add(rightPage).build());
    method.comment("filter: %s", filter.toString());
    BytecodeBlock body = method.getBody();
    Scope scope = method.getScope();
    Variable wasNullVariable = scope.declareVariable("wasNull", body, constantFalse());
    scope.declareVariable("session", body, method.getThis().getField(sessionField));
    RowExpressionCompiler compiler = new RowExpressionCompiler(callSiteBinder, cachedInstanceBinder, fieldReferenceCompiler(callSiteBinder, leftPosition, leftPage, rightPosition, rightPage, leftBlocksSize), functionManager, compiledLambdaMap);
    BytecodeNode visitorBody = compiler.compile(filter, scope);
    Variable result = scope.declareVariable(boolean.class, "result");
    body.append(visitorBody).putVariable(result).append(new IfStatement().condition(wasNullVariable).ifTrue(constantFalse().ret()).ifFalse(result.ret()));
}
Also used : IfStatement(io.airlift.bytecode.control.IfStatement) Variable(io.airlift.bytecode.Variable) Scope(io.airlift.bytecode.Scope) MethodDefinition(io.airlift.bytecode.MethodDefinition) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) Parameter(io.airlift.bytecode.Parameter) BytecodeNode(io.airlift.bytecode.BytecodeNode)

Example 20 with BytecodeNode

use of io.airlift.bytecode.BytecodeNode in project trino by trinodb.

the class SwitchCodeGenerator method generateExpression.

@Override
public BytecodeNode generateExpression(BytecodeGeneratorContext generatorContext) {
    // TODO: compile as
    /*
            hashCode = hashCode(<value>)

            // all constant expressions before a non-constant
            switch (hashCode) {
                case ...:
                    if (<value> == <constant1>) {
                       ...
                    }
                    else if (<value> == <constant2>) {
                       ...
                    }
                    else if (...) {
                    }
                case ...:
                    ...
            }

            if (<value> == <non-constant1>) {
                ...
            }
            else if (<value> == <non-constant2>) {
                ...
            }
            ...

            // repeat with next sequence of constant expressions
         */
    Scope scope = generatorContext.getScope();
    // process value, else, and all when clauses
    BytecodeNode valueBytecode = generatorContext.generate(value);
    BytecodeNode elseValue;
    if (this.elseValue.isEmpty()) {
        elseValue = new BytecodeBlock().append(generatorContext.wasNull().set(constantTrue())).pushJavaDefault(returnType.getJavaType());
    } else {
        elseValue = generatorContext.generate(this.elseValue.get());
    }
    // determine the type of the value and result
    Class<?> valueType = value.getType().getJavaType();
    // evaluate the value and store it in a variable
    LabelNode nullValue = new LabelNode("nullCondition");
    Variable tempVariable = scope.createTempVariable(valueType);
    BytecodeBlock block = new BytecodeBlock().append(valueBytecode).append(BytecodeUtils.ifWasNullClearPopAndGoto(scope, nullValue, void.class, valueType)).putVariable(tempVariable);
    BytecodeNode getTempVariableNode = VariableInstruction.loadVariable(tempVariable);
    // build the statements
    elseValue = new BytecodeBlock().visitLabel(nullValue).append(elseValue);
    // reverse list because current if statement builder doesn't support if/else so we need to build the if statements bottom up
    for (int i = whenClauses.size() - 1; i >= 0; i--) {
        SpecialForm clause = whenClauses.get(i);
        RowExpression operand = clause.getArguments().get(0);
        RowExpression result = clause.getArguments().get(1);
        // call equals(value, operand)
        // TODO: what if operand is null? It seems that the call will return "null" (which is cleared below)
        // and the code only does the right thing because the value in the stack for that scenario is
        // Java's default for boolean == false
        // This code should probably be checking for wasNull after the call and "failing" the equality
        // check if wasNull is true
        BytecodeNode equalsCall = generatorContext.generateCall(equalsFunctions.get(i), ImmutableList.of(generatorContext.generate(operand), getTempVariableNode));
        BytecodeBlock condition = new BytecodeBlock().append(equalsCall).append(generatorContext.wasNull().set(constantFalse()));
        elseValue = new IfStatement("when").condition(condition).ifTrue(generatorContext.generate(result)).ifFalse(elseValue);
    }
    return block.append(elseValue);
}
Also used : LabelNode(io.airlift.bytecode.instruction.LabelNode) IfStatement(io.airlift.bytecode.control.IfStatement) Variable(io.airlift.bytecode.Variable) Scope(io.airlift.bytecode.Scope) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) RowExpression(io.trino.sql.relational.RowExpression) BytecodeNode(io.airlift.bytecode.BytecodeNode) SpecialForm(io.trino.sql.relational.SpecialForm)

Aggregations

BytecodeNode (io.airlift.bytecode.BytecodeNode)42 Variable (io.airlift.bytecode.Variable)37 BytecodeBlock (io.airlift.bytecode.BytecodeBlock)29 IfStatement (io.airlift.bytecode.control.IfStatement)26 MethodDefinition (io.airlift.bytecode.MethodDefinition)22 Parameter (io.airlift.bytecode.Parameter)20 Scope (io.airlift.bytecode.Scope)19 LabelNode (io.airlift.bytecode.instruction.LabelNode)15 ForLoop (io.airlift.bytecode.control.ForLoop)10 BytecodeExpression (io.airlift.bytecode.expression.BytecodeExpression)9 ClassDefinition (io.airlift.bytecode.ClassDefinition)8 VariableInstruction.incrementVariable (io.airlift.bytecode.instruction.VariableInstruction.incrementVariable)8 RowExpression (io.prestosql.spi.relation.RowExpression)6 ArrayList (java.util.ArrayList)6 ImmutableList (com.google.common.collect.ImmutableList)5 Block (io.prestosql.spi.block.Block)5 BuiltInScalarFunctionImplementation (io.prestosql.spi.function.BuiltInScalarFunctionImplementation)5 Block (io.trino.spi.block.Block)5 FunctionHandle (io.prestosql.spi.function.FunctionHandle)4 Signature.typeVariable (io.prestosql.spi.function.Signature.typeVariable)4