Search in sources :

Example 21 with IfStatement

use of com.facebook.presto.bytecode.control.IfStatement in project presto by prestodb.

the class PageFunctionCompiler method generateCommonSubExpressionMethods.

private List<MethodDefinition> generateCommonSubExpressionMethods(ClassDefinition classDefinition, RowExpressionCompiler compiler, Map<Integer, Map<RowExpression, VariableReferenceExpression>> commonSubExpressionsByLevel, Map<VariableReferenceExpression, CommonSubExpressionFields> commonSubExpressionFieldsMap) {
    ImmutableList.Builder<MethodDefinition> methods = ImmutableList.builder();
    Parameter properties = arg("properties", SqlFunctionProperties.class);
    Parameter page = arg("page", Page.class);
    Parameter position = arg("position", int.class);
    int startLevel = commonSubExpressionsByLevel.keySet().stream().reduce(Math::min).get();
    int maxLevel = commonSubExpressionsByLevel.keySet().stream().reduce(Math::max).get();
    for (int i = startLevel; i <= maxLevel; i++) {
        if (commonSubExpressionsByLevel.containsKey(i)) {
            for (Map.Entry<RowExpression, VariableReferenceExpression> entry : commonSubExpressionsByLevel.get(i).entrySet()) {
                RowExpression cse = entry.getKey();
                Class<?> type = Primitives.wrap(cse.getType().getJavaType());
                VariableReferenceExpression cseVariable = entry.getValue();
                CommonSubExpressionFields cseFields = commonSubExpressionFieldsMap.get(cseVariable);
                MethodDefinition method = classDefinition.declareMethod(a(PRIVATE), "get" + cseVariable.getName(), type(cseFields.getResultType()), ImmutableList.<Parameter>builder().add(properties).add(page).add(position).build());
                method.comment("cse: %s", cse);
                Scope scope = method.getScope();
                BytecodeBlock body = method.getBody();
                Variable thisVariable = method.getThis();
                declareBlockVariables(ImmutableList.of(cse), page, scope, body);
                scope.declareVariable("wasNull", body, constantFalse());
                IfStatement ifStatement = new IfStatement().condition(thisVariable.getField(cseFields.getEvaluatedField())).ifFalse(new BytecodeBlock().append(thisVariable).append(compiler.compile(cse, scope, Optional.empty())).append(boxPrimitiveIfNecessary(scope, type)).putField(cseFields.getResultField()).append(thisVariable.setField(cseFields.getEvaluatedField(), constantBoolean(true))));
                body.append(ifStatement).append(thisVariable).getField(cseFields.getResultField()).retObject();
                methods.add(method);
            }
        }
    }
    return methods.build();
}
Also used : Variable(com.facebook.presto.bytecode.Variable) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ImmutableList(com.google.common.collect.ImmutableList) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) RowExpression(com.facebook.presto.spi.relation.RowExpression) IfStatement(com.facebook.presto.bytecode.control.IfStatement) CommonSubExpressionFields.initializeCommonSubExpressionFields(com.facebook.presto.sql.gen.CommonSubExpressionRewriter.CommonSubExpressionFields.initializeCommonSubExpressionFields) CommonSubExpressionFields.declareCommonSubExpressionFields(com.facebook.presto.sql.gen.CommonSubExpressionRewriter.CommonSubExpressionFields.declareCommonSubExpressionFields) CommonSubExpressionFields(com.facebook.presto.sql.gen.CommonSubExpressionRewriter.CommonSubExpressionFields) Scope(com.facebook.presto.bytecode.Scope) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) Parameter(com.facebook.presto.bytecode.Parameter) Map(java.util.Map) ImmutableMap.toImmutableMap(com.google.common.collect.ImmutableMap.toImmutableMap) ImmutableMap(com.google.common.collect.ImmutableMap) Collections.emptyMap(java.util.Collections.emptyMap)

Example 22 with IfStatement

use of com.facebook.presto.bytecode.control.IfStatement in project presto by prestodb.

the class RowConstructorCodeGenerator method generateExpression.

@Override
public BytecodeNode generateExpression(BytecodeGeneratorContext context, Type rowType, List<RowExpression> arguments, Optional<Variable> outputBlockVariable) {
    BytecodeBlock block = new BytecodeBlock().setDescription("Constructor for " + rowType.toString());
    CallSiteBinder binder = context.getCallSiteBinder();
    Scope scope = context.getScope();
    List<Type> types = rowType.getTypeParameters();
    block.comment("Create new RowBlockBuilder; beginBlockEntry;");
    Variable blockBuilder = scope.createTempVariable(BlockBuilder.class);
    Variable singleRowBlockWriter = scope.createTempVariable(BlockBuilder.class);
    block.append(blockBuilder.set(constantType(binder, rowType).invoke("createBlockBuilder", BlockBuilder.class, constantNull(BlockBuilderStatus.class), constantInt(1))));
    block.append(singleRowBlockWriter.set(blockBuilder.invoke("beginBlockEntry", BlockBuilder.class)));
    for (int i = 0; i < arguments.size(); ++i) {
        Type fieldType = types.get(i);
        Variable field = scope.createTempVariable(fieldType.getJavaType());
        block.comment("Clean wasNull and Generate + " + i + "-th field of row");
        block.append(context.wasNull().set(constantFalse()));
        block.append(context.generate(arguments.get(i), Optional.empty()));
        block.putVariable(field);
        block.append(new IfStatement().condition(context.wasNull()).ifTrue(singleRowBlockWriter.invoke("appendNull", BlockBuilder.class).pop()).ifFalse(constantType(binder, fieldType).writeValue(singleRowBlockWriter, field).pop()));
    }
    block.comment("closeEntry; slice the SingleRowBlock; wasNull = false;");
    block.append(blockBuilder.invoke("closeEntry", BlockBuilder.class).pop());
    block.append(constantType(binder, rowType).invoke("getObject", Object.class, blockBuilder.cast(Block.class), constantInt(0)).cast(Block.class));
    block.append(context.wasNull().set(constantFalse()));
    outputBlockVariable.ifPresent(output -> block.append(generateWrite(context, rowType, output)));
    return block;
}
Also used : IfStatement(com.facebook.presto.bytecode.control.IfStatement) SqlTypeBytecodeExpression.constantType(com.facebook.presto.sql.gen.SqlTypeBytecodeExpression.constantType) Type(com.facebook.presto.common.type.Type) Variable(com.facebook.presto.bytecode.Variable) Scope(com.facebook.presto.bytecode.Scope) CallSiteBinder(com.facebook.presto.bytecode.CallSiteBinder) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) Block(com.facebook.presto.common.block.Block) BlockBuilderStatus(com.facebook.presto.common.block.BlockBuilderStatus)

Example 23 with IfStatement

use of com.facebook.presto.bytecode.control.IfStatement in project presto by prestodb.

the class JoinCompiler method generatePositionEqualsRowWithPageMethod.

private static void generatePositionEqualsRowWithPageMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, List<Type> joinChannelTypes, List<FieldDefinition> joinChannelFields) {
    Parameter leftBlockIndex = arg("leftBlockIndex", int.class);
    Parameter leftBlockPosition = arg("leftBlockPosition", int.class);
    Parameter rightPosition = arg("rightPosition", int.class);
    Parameter page = arg("page", Page.class);
    Parameter rightChannels = arg("rightChannels", int[].class);
    MethodDefinition positionEqualsRowMethod = classDefinition.declareMethod(a(PUBLIC), "positionEqualsRow", type(boolean.class), leftBlockIndex, leftBlockPosition, rightPosition, page, rightChannels);
    Variable thisVariable = positionEqualsRowMethod.getThis();
    BytecodeBlock body = positionEqualsRowMethod.getBody();
    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 = page.invoke("getBlock", Block.class, rightChannels.getElement(index));
        body.append(new IfStatement().condition(typeEquals(type, leftBlock, leftBlockPosition, rightBlock, rightPosition)).ifFalse(constantFalse().ret()));
    }
    body.append(constantTrue().ret());
}
Also used : IfStatement(com.facebook.presto.bytecode.control.IfStatement) Variable(com.facebook.presto.bytecode.Variable) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) Parameter(com.facebook.presto.bytecode.Parameter) BytecodeExpression(com.facebook.presto.bytecode.expression.BytecodeExpression)

Example 24 with IfStatement

use of com.facebook.presto.bytecode.control.IfStatement in project presto by prestodb.

the class JoinCompiler method typeEquals.

private static BytecodeNode typeEquals(BytecodeExpression type, BytecodeExpression leftBlock, BytecodeExpression leftBlockPosition, BytecodeExpression rightBlock, BytecodeExpression rightBlockPosition) {
    IfStatement ifStatement = new IfStatement();
    ifStatement.condition().append(leftBlock.invoke("isNull", boolean.class, leftBlockPosition)).append(rightBlock.invoke("isNull", boolean.class, rightBlockPosition)).append(OpCode.IOR);
    ifStatement.ifTrue().append(leftBlock.invoke("isNull", boolean.class, leftBlockPosition)).append(rightBlock.invoke("isNull", boolean.class, rightBlockPosition)).append(OpCode.IAND);
    ifStatement.ifFalse().append(typeEqualsIgnoreNulls(type, leftBlock, leftBlockPosition, rightBlock, rightBlockPosition));
    return ifStatement;
}
Also used : IfStatement(com.facebook.presto.bytecode.control.IfStatement)

Example 25 with IfStatement

use of com.facebook.presto.bytecode.control.IfStatement in project presto by prestodb.

the class OrCodeGenerator method generateExpression.

@Override
public BytecodeNode generateExpression(BytecodeGeneratorContext generator, Type returnType, List<RowExpression> arguments, Optional<Variable> outputBlockVariable) {
    Preconditions.checkArgument(arguments.size() == 2);
    // We flatten the AND here.
    Deque<RowExpression> stack = new ArrayDeque<>();
    stack.push(arguments.get(1));
    stack.push(arguments.get(0));
    ImmutableList.Builder<RowExpression> flattenedArgs = ImmutableList.builder();
    do {
        RowExpression operand = stack.pop();
        if (operand instanceof SpecialFormExpression && ((SpecialFormExpression) operand).getForm() == SpecialFormExpression.Form.OR) {
            stack.push(((SpecialFormExpression) operand).getArguments().get(1));
            stack.push(((SpecialFormExpression) operand).getArguments().get(0));
        } else {
            flattenedArgs.add(operand);
        }
    } while (!stack.isEmpty());
    BytecodeBlock block = new BytecodeBlock().comment("OR").setDescription("OR");
    LabelNode trueLabel = new LabelNode("true");
    LabelNode endLabel = new LabelNode("end");
    Variable wasNull = generator.wasNull();
    Variable hasNulls = generator.getScope().createTempVariable(boolean.class);
    block.initializeVariable(hasNulls);
    for (RowExpression expression : flattenedArgs.build()) {
        block.comment("do { eval arg; if (wasNull) { hasNull = true; wasNull = false; } else if (true) goto ret_true; }").append(generator.generate(expression, Optional.empty()));
        IfStatement ifOperandIsNull = new IfStatement("if left wasNulll...").condition(wasNull);
        ifOperandIsNull.ifTrue().comment("clear the null flag and remember there was a null").putVariable(hasNulls, true).putVariable(wasNull, false).pop(boolean.class);
        ifOperandIsNull.ifFalse().ifTrueGoto(trueLabel);
        block.append(ifOperandIsNull);
    }
    // We evaluated all operands. So check if any of them was null
    IfStatement ifHasNulls = new IfStatement("hasNulls is true");
    ifHasNulls.condition().append(hasNulls);
    ifHasNulls.ifTrue().comment("at least one of the arguments is null and none of them is true. So set wasNull to true").putVariable(wasNull, true).push(false);
    ifHasNulls.ifFalse().push(false);
    block.append(ifHasNulls).gotoLabel(endLabel);
    block.visitLabel(trueLabel).comment("at least one of the args is true, clear wasNull and return true").push(true).gotoLabel(endLabel);
    block.visitLabel(endLabel);
    outputBlockVariable.ifPresent(output -> block.append(generateWrite(generator, returnType, output)));
    return block;
}
Also used : LabelNode(com.facebook.presto.bytecode.instruction.LabelNode) IfStatement(com.facebook.presto.bytecode.control.IfStatement) Variable(com.facebook.presto.bytecode.Variable) ImmutableList(com.google.common.collect.ImmutableList) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) RowExpression(com.facebook.presto.spi.relation.RowExpression) SpecialFormExpression(com.facebook.presto.spi.relation.SpecialFormExpression) ArrayDeque(java.util.ArrayDeque)

Aggregations

IfStatement (com.facebook.presto.bytecode.control.IfStatement)77 BytecodeBlock (com.facebook.presto.bytecode.BytecodeBlock)72 Variable (com.facebook.presto.bytecode.Variable)65 MethodDefinition (com.facebook.presto.bytecode.MethodDefinition)45 Scope (com.facebook.presto.bytecode.Scope)43 Parameter (com.facebook.presto.bytecode.Parameter)41 BytecodeNode (com.facebook.presto.bytecode.BytecodeNode)23 ForLoop (com.facebook.presto.bytecode.control.ForLoop)19 BytecodeExpression (com.facebook.presto.bytecode.expression.BytecodeExpression)19 LabelNode (com.facebook.presto.bytecode.instruction.LabelNode)19 ImmutableList (com.google.common.collect.ImmutableList)18 Block (com.facebook.presto.spi.block.Block)15 Block (com.facebook.presto.common.block.Block)13 ClassDefinition (com.facebook.presto.bytecode.ClassDefinition)10 Type (com.facebook.presto.common.type.Type)10 DictionaryBlock (com.facebook.presto.spi.block.DictionaryBlock)10 LazyBlock (com.facebook.presto.spi.block.LazyBlock)10 RunLengthEncodedBlock (com.facebook.presto.spi.block.RunLengthEncodedBlock)10 CallSiteBinder (com.facebook.presto.bytecode.CallSiteBinder)9 BlockBuilder (com.facebook.presto.common.block.BlockBuilder)9