Search in sources :

Example 1 with IfStatement

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

the class NullIfCodeGenerator method generateExpression.

@Override
public BytecodeNode generateExpression(Signature signature, BytecodeGeneratorContext generatorContext, Type returnType, List<RowExpression> arguments) {
    Scope scope = generatorContext.getScope();
    RowExpression first = arguments.get(0);
    RowExpression second = arguments.get(1);
    LabelNode notMatch = new LabelNode("notMatch");
    // push first arg on the stack
    BytecodeBlock block = new BytecodeBlock().comment("check if first arg is null").append(generatorContext.generate(first)).append(BytecodeUtils.ifWasNullPopAndGoto(scope, notMatch, void.class));
    Type firstType = first.getType();
    Type secondType = second.getType();
    // if (equal(cast(first as <common type>), cast(second as <common type>))
    Signature equalsSignature = generatorContext.getRegistry().resolveOperator(OperatorType.EQUAL, ImmutableList.of(firstType, secondType));
    ScalarFunctionImplementation equalsFunction = generatorContext.getRegistry().getScalarFunctionImplementation(equalsSignature);
    BytecodeNode equalsCall = generatorContext.generateCall(equalsSignature.getName(), equalsFunction, ImmutableList.of(cast(generatorContext, new BytecodeBlock().dup(firstType.getJavaType()), firstType, equalsSignature.getArgumentTypes().get(0)), cast(generatorContext, generatorContext.generate(second), secondType, equalsSignature.getArgumentTypes().get(1))));
    BytecodeBlock conditionBlock = new BytecodeBlock().append(equalsCall).append(BytecodeUtils.ifWasNullClearPopAndGoto(scope, notMatch, void.class, boolean.class));
    // if first and second are equal, return null
    BytecodeBlock trueBlock = new BytecodeBlock().append(generatorContext.wasNull().set(constantTrue())).pop(first.getType().getJavaType()).pushJavaDefault(first.getType().getJavaType());
    // else return first (which is still on the stack
    block.append(new IfStatement().condition(conditionBlock).ifTrue(trueBlock).ifFalse(notMatch));
    return block;
}
Also used : LabelNode(com.facebook.presto.bytecode.instruction.LabelNode) ScalarFunctionImplementation(com.facebook.presto.operator.scalar.ScalarFunctionImplementation) IfStatement(com.facebook.presto.bytecode.control.IfStatement) OperatorType(com.facebook.presto.spi.function.OperatorType) Type(com.facebook.presto.spi.type.Type) Scope(com.facebook.presto.bytecode.Scope) TypeSignature(com.facebook.presto.spi.type.TypeSignature) Signature(com.facebook.presto.metadata.Signature) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) RowExpression(com.facebook.presto.sql.relational.RowExpression) BytecodeNode(com.facebook.presto.bytecode.BytecodeNode)

Example 2 with IfStatement

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

the class OrCodeGenerator 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("OR").setDescription("OR");
    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(new BytecodeBlock().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 leftIsFalse = new LabelNode("leftIsFalse");
    ifLeftIsNull.ifFalse(new BytecodeBlock().comment("if left is true, push true, and goto end").ifFalseGoto(leftIsFalse).push(true).gotoLabel(end).comment("left was false; push left null flag on the stack (false)").visitLabel(leftIsFalse).push(false));
    block.append(ifLeftIsNull);
    // At this point we know the left expression was either NULL or FALSE.  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...").condition(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 true, pop left null flag off stack, push true and goto end").ifFalseGoto(rightIsTrue).pop(boolean.class).push(true).gotoLabel(end).comment("right was false; store left null flag (on stack) in wasNull variable, and push false").visitLabel(rightIsTrue).putVariable(wasNull).push(false);
    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 3 with IfStatement

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

the class PageProcessorCompiler method generateProjectRLEMethod.

private MethodDefinition generateProjectRLEMethod(ClassDefinition classDefinition, String methodName, RowExpression projection, MethodDefinition projectionMethod, MethodDefinition projectColumnar) {
    Parameter session = arg("session", ConnectorSession.class);
    Parameter page = arg("page", Page.class);
    Parameter selectedPositions = arg("selectedPositions", int[].class);
    Parameter pageBuilder = arg("pageBuilder", PageBuilder.class);
    Parameter projectionIndex = arg("projectionIndex", int.class);
    List<Parameter> params = ImmutableList.<Parameter>builder().add(session).add(page).add(selectedPositions).add(pageBuilder).add(projectionIndex).build();
    MethodDefinition method = classDefinition.declareMethod(a(PRIVATE), methodName, type(Block.class), params);
    BytecodeBlock body = method.getBody();
    Scope scope = method.getScope();
    Variable thisVariable = method.getThis();
    List<Integer> inputChannels = getInputChannels(projection);
    if (inputChannels.size() != 1 || !determinismEvaluator.isDeterministic(projection)) {
        body.append(thisVariable.invoke(projectColumnar, params).ret());
        return method;
    }
    Variable inputBlock = scope.declareVariable("inputBlock", body, page.invoke("getBlock", Block.class, constantInt(getOnlyElement(inputChannels))));
    body.append(new IfStatement().condition(inputBlock.instanceOf(RunLengthEncodedBlock.class)).ifFalse(thisVariable.invoke(projectColumnar, params).ret()));
    Variable valueBlock = scope.declareVariable("valueBlock", body, inputBlock.cast(RunLengthEncodedBlock.class).invoke("getValue", Block.class));
    Variable blockBuilder = scope.declareVariable("blockBuilder", body, pageBuilder.invoke("getBlockBuilder", BlockBuilder.class, projectionIndex));
    body.append(invokeProject(thisVariable, session, singletonList(valueBlock), constantInt(0), pageBuilder, projectionIndex, projectionMethod));
    Variable outputValueBlock = scope.declareVariable("outputValueBlock", body, blockBuilder.invoke("build", Block.class));
    body.append(newInstance(RunLengthEncodedBlock.class, outputValueBlock, selectedPositions.length()).ret());
    return method;
}
Also used : IfStatement(com.facebook.presto.bytecode.control.IfStatement) Variable(com.facebook.presto.bytecode.Variable) Scope(com.facebook.presto.bytecode.Scope) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) Parameter(com.facebook.presto.bytecode.Parameter) Block(com.facebook.presto.spi.block.Block) DictionaryBlock(com.facebook.presto.spi.block.DictionaryBlock) LazyBlock(com.facebook.presto.spi.block.LazyBlock) RunLengthEncodedBlock(com.facebook.presto.spi.block.RunLengthEncodedBlock) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) RunLengthEncodedBlock(com.facebook.presto.spi.block.RunLengthEncodedBlock) BlockBuilder(com.facebook.presto.spi.block.BlockBuilder)

Example 4 with IfStatement

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

the class CursorProcessorCompiler method generateProcessMethod.

private static void generateProcessMethod(ClassDefinition classDefinition, int projections) {
    Parameter session = arg("session", ConnectorSession.class);
    Parameter cursor = arg("cursor", RecordCursor.class);
    Parameter count = arg("count", int.class);
    Parameter pageBuilder = arg("pageBuilder", PageBuilder.class);
    MethodDefinition method = classDefinition.declareMethod(a(PUBLIC), "process", type(int.class), session, cursor, count, pageBuilder);
    Scope scope = method.getScope();
    Variable completedPositionsVariable = scope.declareVariable(int.class, "completedPositions");
    method.getBody().comment("int completedPositions = 0;").putVariable(completedPositionsVariable, 0);
    //
    // for loop loop body
    //
    LabelNode done = new LabelNode("done");
    ForLoop forLoop = new ForLoop().initialize(NOP).condition(new BytecodeBlock().comment("completedPositions < count").getVariable(completedPositionsVariable).getVariable(count).invokeStatic(CompilerOperations.class, "lessThan", boolean.class, int.class, int.class)).update(new BytecodeBlock().comment("completedPositions++").incrementVariable(completedPositionsVariable, (byte) 1));
    BytecodeBlock forLoopBody = new BytecodeBlock().comment("if (pageBuilder.isFull()) break;").append(new BytecodeBlock().getVariable(pageBuilder).invokeVirtual(PageBuilder.class, "isFull", boolean.class).ifTrueGoto(done)).comment("if (!cursor.advanceNextPosition()) break;").append(new BytecodeBlock().getVariable(cursor).invokeInterface(RecordCursor.class, "advanceNextPosition", boolean.class).ifFalseGoto(done));
    forLoop.body(forLoopBody);
    // if (filter(cursor))
    IfStatement ifStatement = new IfStatement();
    ifStatement.condition().append(method.getThis()).getVariable(session).getVariable(cursor).invokeVirtual(classDefinition.getType(), "filter", type(boolean.class), type(ConnectorSession.class), type(RecordCursor.class));
    // pageBuilder.declarePosition();
    ifStatement.ifTrue().getVariable(pageBuilder).invokeVirtual(PageBuilder.class, "declarePosition", void.class);
    // this.project_43(session, cursor, pageBuilder.getBlockBuilder(42)));
    for (int projectionIndex = 0; projectionIndex < projections; projectionIndex++) {
        ifStatement.ifTrue().append(method.getThis()).getVariable(session).getVariable(cursor);
        // pageBuilder.getBlockBuilder(0)
        ifStatement.ifTrue().getVariable(pageBuilder).push(projectionIndex).invokeVirtual(PageBuilder.class, "getBlockBuilder", BlockBuilder.class, int.class);
        // project(block..., blockBuilder)gen
        ifStatement.ifTrue().invokeVirtual(classDefinition.getType(), "project_" + projectionIndex, type(void.class), type(ConnectorSession.class), type(RecordCursor.class), type(BlockBuilder.class));
    }
    forLoopBody.append(ifStatement);
    method.getBody().append(forLoop).visitLabel(done).comment("return completedPositions;").getVariable(completedPositionsVariable).retInt();
}
Also used : LabelNode(com.facebook.presto.bytecode.instruction.LabelNode) IfStatement(com.facebook.presto.bytecode.control.IfStatement) Variable(com.facebook.presto.bytecode.Variable) RecordCursor(com.facebook.presto.spi.RecordCursor) Scope(com.facebook.presto.bytecode.Scope) ForLoop(com.facebook.presto.bytecode.control.ForLoop) MethodDefinition(com.facebook.presto.bytecode.MethodDefinition) BytecodeBlock(com.facebook.presto.bytecode.BytecodeBlock) Parameter(com.facebook.presto.bytecode.Parameter) ConnectorSession(com.facebook.presto.spi.ConnectorSession) BlockBuilder(com.facebook.presto.spi.block.BlockBuilder)

Example 5 with IfStatement

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

the class DereferenceCodeGenerator method generateExpression.

@Override
public BytecodeNode generateExpression(Signature signature, BytecodeGeneratorContext generator, Type returnType, List<RowExpression> arguments) {
    checkArgument(arguments.size() == 2);
    CallSiteBinder callSiteBinder = generator.getCallSiteBinder();
    BytecodeBlock block = new BytecodeBlock().comment("DEREFERENCE").setDescription("DEREFERENCE");
    Variable wasNull = generator.wasNull();
    Variable rowBlock = generator.getScope().createTempVariable(Block.class);
    int index = (int) ((ConstantExpression) arguments.get(1)).getValue();
    // clear the wasNull flag before evaluating the row value
    block.putVariable(wasNull, false);
    block.append(generator.generate(arguments.get(0))).putVariable(rowBlock);
    IfStatement ifRowBlockIsNull = new IfStatement("if row block is null...").condition(wasNull);
    Class<?> javaType = returnType.getJavaType();
    LabelNode end = new LabelNode("end");
    ifRowBlockIsNull.ifTrue().comment("if row block is null, push null to the stack and goto 'end' label (return)").putVariable(wasNull, true).pushJavaDefault(javaType).gotoLabel(end);
    block.append(ifRowBlockIsNull);
    IfStatement ifFieldIsNull = new IfStatement("if row field is null...");
    ifFieldIsNull.condition().comment("call rowBlock.isNull(index)").append(rowBlock).push(index).invokeInterface(Block.class, "isNull", boolean.class, int.class);
    ifFieldIsNull.ifTrue().comment("if the field is null, push null to stack").putVariable(wasNull, true).pushJavaDefault(javaType);
    BytecodeExpression value = constantType(callSiteBinder, returnType).getValue(rowBlock, constantInt(index));
    ifFieldIsNull.ifFalse().comment("otherwise call type.getTYPE(rowBlock, index)").append(value).putVariable(wasNull, false);
    block.append(ifFieldIsNull).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) BytecodeExpression(com.facebook.presto.bytecode.expression.BytecodeExpression)

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