Search in sources :

Example 11 with IfStatement

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

the class AndCodeGenerator method generateExpression.

@Override
public BytecodeNode generateExpression(Signature signature, BytecodeGeneratorContext generator, Type returnType, List<RowExpression> arguments) {
    Preconditions.checkArgument(arguments.size() == 2);
    Variable wasNull = generator.wasNull();
    BytecodeBlock block = new BytecodeBlock().comment("AND").setDescription("AND");
    BytecodeNode left = generator.generate(arguments.get(0));
    BytecodeNode right = generator.generate(arguments.get(1));
    block.append(left);
    IfStatement ifLeftIsNull = new IfStatement("if left wasNull...").condition(wasNull);
    LabelNode end = new LabelNode("end");
    ifLeftIsNull.ifTrue().comment("clear the null flag, pop left value off stack, and push left null flag on the stack (true)").append(wasNull.set(constantFalse())).pop(// discard left value
    arguments.get(0).getType().getJavaType()).push(true);
    LabelNode leftIsTrue = new LabelNode("leftIsTrue");
    ifLeftIsNull.ifFalse().comment("if left is false, push false, and goto end").ifTrueGoto(leftIsTrue).push(false).gotoLabel(end).comment("left was true; push left null flag on the stack (false)").visitLabel(leftIsTrue).push(false);
    block.append(ifLeftIsNull);
    // At this point we know the left expression was either NULL or TRUE.  The stack contains a single boolean
    // value for this expression which indicates if the left value was NULL.
    // eval right!
    block.append(right);
    IfStatement ifRightIsNull = new IfStatement("if right wasNull...");
    ifRightIsNull.condition().append(wasNull);
    // this leaves a single boolean on the stack which is ignored since the value in NULL
    ifRightIsNull.ifTrue().comment("right was null, pop the right value off the stack; wasNull flag remains set to TRUE").pop(arguments.get(1).getType().getJavaType());
    LabelNode rightIsTrue = new LabelNode("rightIsTrue");
    ifRightIsNull.ifFalse().comment("if right is false, pop left null flag off stack, push false and goto end").ifTrueGoto(rightIsTrue).pop(boolean.class).push(false).gotoLabel(end).comment("right was true; store left null flag (on stack) in wasNull variable, and push true").visitLabel(rightIsTrue).putVariable(wasNull).push(true);
    block.append(ifRightIsNull).visitLabel(end);
    return block;
}
Also used : LabelNode(com.facebook.presto.bytecode.instruction.LabelNode) 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 12 with IfStatement

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

the class BytecodeUtils method handleNullValue.

public static BytecodeNode handleNullValue(Scope scope, LabelNode label, Class<?> returnType, List<Class<?>> stackArgsToPop, boolean clearNullFlag) {
    Variable wasNull = scope.getVariable("wasNull");
    BytecodeBlock nullCheck = new BytecodeBlock().setDescription("ifWasNullGoto").append(wasNull);
    String clearComment = null;
    if (clearNullFlag) {
        nullCheck.append(wasNull.set(constantFalse()));
        clearComment = "clear wasNull";
    }
    BytecodeBlock isNull = new BytecodeBlock();
    for (Class<?> parameterType : stackArgsToPop) {
        isNull.pop(parameterType);
    }
    isNull.pushJavaDefault(returnType);
    String loadDefaultComment = null;
    if (returnType != void.class) {
        loadDefaultComment = format("loadJavaDefault(%s)", returnType.getName());
    }
    isNull.gotoLabel(label);
    String popComment = null;
    if (!stackArgsToPop.isEmpty()) {
        popComment = format("pop(%s)", Joiner.on(", ").join(stackArgsToPop));
    }
    return new IfStatement("if wasNull then %s", Joiner.on(", ").skipNulls().join(clearComment, popComment, loadDefaultComment, "goto " + label.getLabel())).condition(nullCheck).ifTrue(isNull);
}
Also used : IfStatement(com.facebook.presto.bytecode.control.IfStatement) Variable(com.facebook.presto.bytecode.Variable) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock)

Example 13 with IfStatement

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

the class CoalesceCodeGenerator method generateExpression.

@Override
public BytecodeNode generateExpression(Signature signature, BytecodeGeneratorContext generatorContext, Type returnType, List<RowExpression> arguments) {
    List<BytecodeNode> operands = new ArrayList<>();
    for (RowExpression expression : arguments) {
        operands.add(generatorContext.generate(expression));
    }
    Variable wasNull = generatorContext.wasNull();
    BytecodeNode nullValue = new BytecodeBlock().append(wasNull.set(constantTrue())).pushJavaDefault(returnType.getJavaType());
    // reverse list because current if statement builder doesn't support if/else so we need to build the if statements bottom up
    for (BytecodeNode operand : Lists.reverse(operands)) {
        IfStatement ifStatement = new IfStatement();
        ifStatement.condition().append(operand).append(wasNull);
        // if value was null, pop the null value, clear the null flag, and process the next operand
        ifStatement.ifTrue().pop(returnType.getJavaType()).append(wasNull.set(constantFalse())).append(nullValue);
        nullValue = ifStatement;
    }
    return nullValue;
}
Also used : IfStatement(com.facebook.presto.bytecode.control.IfStatement) Variable(com.facebook.presto.bytecode.Variable) ArrayList(java.util.ArrayList) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) RowExpression(com.facebook.presto.sql.relational.RowExpression) BytecodeNode(com.facebook.presto.bytecode.BytecodeNode)

Example 14 with IfStatement

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

the class AbstractMinMaxBy method generateInputMethod.

private void generateInputMethod(ClassDefinition definition, CallSiteBinder binder, MethodHandle compareMethod, Type keyType, Type valueType, Class<?> stateClass) {
    Parameter state = arg("state", stateClass);
    Parameter value = arg("value", Block.class);
    Parameter key = arg("key", Block.class);
    Parameter position = arg("position", int.class);
    MethodDefinition method = definition.declareMethod(a(PUBLIC, STATIC), "input", type(void.class), state, value, key, position);
    if (keyType.equals(UNKNOWN)) {
        method.getBody().ret();
        return;
    }
    SqlTypeBytecodeExpression keySqlType = constantType(binder, keyType);
    BytecodeBlock ifBlock = new BytecodeBlock().append(state.invoke("setFirst", void.class, keySqlType.getValue(key, position))).append(state.invoke("setFirstNull", void.class, constantBoolean(false))).append(state.invoke("setSecondNull", void.class, value.invoke("isNull", boolean.class, position)));
    if (!valueType.equals(UNKNOWN)) {
        SqlTypeBytecodeExpression valueSqlType = constantType(binder, valueType);
        ifBlock.append(new IfStatement().condition(value.invoke("isNull", boolean.class, position)).ifFalse(state.invoke("setSecond", void.class, valueSqlType.getValue(value, position))));
    }
    method.getBody().append(new IfStatement().condition(or(state.invoke("isFirstNull", boolean.class), and(not(key.invoke("isNull", boolean.class, position)), loadConstant(binder, compareMethod, MethodHandle.class).invoke("invokeExact", boolean.class, keySqlType.getValue(key, position), state.invoke("getFirst", keyType.getJavaType()))))).ifTrue(ifBlock)).ret();
}
Also used : IfStatement(com.facebook.presto.bytecode.control.IfStatement) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) Parameter(com.facebook.presto.bytecode.Parameter) Signature.orderableTypeParameter(com.facebook.presto.metadata.Signature.orderableTypeParameter) SqlTypeBytecodeExpression(com.facebook.presto.sql.gen.SqlTypeBytecodeExpression) MethodHandle(java.lang.invoke.MethodHandle)

Example 15 with IfStatement

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

the class AbstractMinMaxBy method generateCombineMethod.

private void generateCombineMethod(ClassDefinition definition, CallSiteBinder binder, MethodHandle compareMethod, Type keyType, Type valueType, Class<?> stateClass) {
    Parameter state = arg("state", stateClass);
    Parameter otherState = arg("otherState", stateClass);
    MethodDefinition method = definition.declareMethod(a(PUBLIC, STATIC), "combine", type(void.class), state, otherState);
    if (keyType.equals(UNKNOWN)) {
        method.getBody().ret();
        return;
    }
    Class<?> keyJavaType = keyType.getJavaType();
    BytecodeBlock ifBlock = new BytecodeBlock().append(state.invoke("setFirst", void.class, otherState.invoke("getFirst", keyJavaType))).append(state.invoke("setFirstNull", void.class, otherState.invoke("isFirstNull", boolean.class))).append(state.invoke("setSecondNull", void.class, otherState.invoke("isSecondNull", boolean.class)));
    if (!valueType.equals(UNKNOWN)) {
        ifBlock.append(state.invoke("setSecond", void.class, otherState.invoke("getSecond", valueType.getJavaType())));
    }
    method.getBody().append(new IfStatement().condition(or(state.invoke("isFirstNull", boolean.class), and(not(otherState.invoke("isFirstNull", boolean.class)), loadConstant(binder, compareMethod, MethodHandle.class).invoke("invokeExact", boolean.class, otherState.invoke("getFirst", keyJavaType), state.invoke("getFirst", keyJavaType))))).ifTrue(ifBlock)).ret();
}
Also used : IfStatement(com.facebook.presto.bytecode.control.IfStatement) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) Parameter(com.facebook.presto.bytecode.Parameter) Signature.orderableTypeParameter(com.facebook.presto.metadata.Signature.orderableTypeParameter) MethodHandle(java.lang.invoke.MethodHandle)

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