Search in sources :

Example 16 with ForLoop

use of io.airlift.bytecode.control.ForLoop in project trino by trinodb.

the class AccumulatorCompiler method generateAddOrRemoveInputWindowIndex.

private static void generateAddOrRemoveInputWindowIndex(ClassDefinition definition, List<FieldDefinition> stateField, List<Boolean> argumentNullable, List<FieldDefinition> lambdaProviderFields, MethodHandle inputFunction, String generatedFunctionName, CallSiteBinder callSiteBinder) {
    // TODO: implement masking based on maskChannel field once Window Functions support DISTINCT arguments to the functions.
    Parameter index = arg("index", WindowIndex.class);
    Parameter startPosition = arg("startPosition", int.class);
    Parameter endPosition = arg("endPosition", int.class);
    MethodDefinition method = definition.declareMethod(a(PUBLIC), generatedFunctionName, type(void.class), ImmutableList.of(index, startPosition, endPosition));
    Scope scope = method.getScope();
    Variable position = scope.declareVariable(int.class, "position");
    Binding binding = callSiteBinder.bind(inputFunction);
    BytecodeExpression invokeInputFunction = invokeDynamic(BOOTSTRAP_METHOD, ImmutableList.of(binding.getBindingId()), generatedFunctionName, binding.getType(), getInvokeFunctionOnWindowIndexParameters(scope, argumentNullable.size(), lambdaProviderFields, stateField, index, position));
    method.getBody().append(new ForLoop().initialize(position.set(startPosition)).condition(BytecodeExpressions.lessThanOrEqual(position, endPosition)).update(position.increment()).body(new IfStatement().condition(anyParametersAreNull(argumentNullable, index, position)).ifFalse(invokeInputFunction))).ret();
}
Also used : Binding(io.trino.sql.gen.Binding) IfStatement(io.airlift.bytecode.control.IfStatement) Variable(io.airlift.bytecode.Variable) Scope(io.airlift.bytecode.Scope) ForLoop(io.airlift.bytecode.control.ForLoop) MethodDefinition(io.airlift.bytecode.MethodDefinition) Parameter(io.airlift.bytecode.Parameter) BytecodeExpression(io.airlift.bytecode.expression.BytecodeExpression)

Example 17 with ForLoop

use of io.airlift.bytecode.control.ForLoop in project trino by trinodb.

the class AccumulatorCompiler method generateInputForLoop.

private static BytecodeBlock generateInputForLoop(Variable arguments, List<FieldDefinition> stateField, List<Boolean> argumentNullable, MethodHandle inputFunction, Scope scope, List<Variable> parameterVariables, List<FieldDefinition> lambdaProviderFields, Variable masksBlock, CallSiteBinder callSiteBinder, boolean grouped) {
    // For-loop over rows
    Variable positionVariable = scope.declareVariable(int.class, "position");
    Variable rowsVariable = scope.declareVariable(int.class, "rows");
    BytecodeBlock block = new BytecodeBlock().append(arguments).invokeVirtual(Page.class, "getPositionCount", int.class).putVariable(rowsVariable).initializeVariable(positionVariable);
    BytecodeNode loopBody = generateInvokeInputFunction(scope, stateField, positionVariable, parameterVariables, lambdaProviderFields, inputFunction, callSiteBinder, grouped);
    // Wrap with null checks
    for (int parameterIndex = 0; parameterIndex < parameterVariables.size(); parameterIndex++) {
        if (!argumentNullable.get(parameterIndex)) {
            Variable variableDefinition = parameterVariables.get(parameterIndex);
            loopBody = new IfStatement("if(!%s.isNull(position))", variableDefinition.getName()).condition(new BytecodeBlock().getVariable(variableDefinition).getVariable(positionVariable).invokeInterface(Block.class, "isNull", boolean.class, int.class)).ifFalse(loopBody);
        }
    }
    loopBody = new IfStatement("if(testMask(%s, position))", masksBlock.getName()).condition(new BytecodeBlock().getVariable(masksBlock).getVariable(positionVariable).invokeStatic(CompilerOperations.class, "testMask", boolean.class, Block.class, int.class)).ifTrue(loopBody);
    ForLoop forLoop = new ForLoop().initialize(new BytecodeBlock().putVariable(positionVariable, 0)).condition(new BytecodeBlock().getVariable(positionVariable).getVariable(rowsVariable).invokeStatic(CompilerOperations.class, "lessThan", boolean.class, int.class, int.class)).update(new BytecodeBlock().incrementVariable(positionVariable, (byte) 1)).body(loopBody);
    block.append(new IfStatement("if(!maskGuaranteedToFilterAllRows(%s, %s))", rowsVariable.getName(), masksBlock.getName()).condition(new BytecodeBlock().getVariable(rowsVariable).getVariable(masksBlock).invokeStatic(AggregationUtils.class, "maskGuaranteedToFilterAllRows", boolean.class, int.class, Block.class)).ifFalse(forLoop));
    return block;
}
Also used : IfStatement(io.airlift.bytecode.control.IfStatement) Variable(io.airlift.bytecode.Variable) ForLoop(io.airlift.bytecode.control.ForLoop) CompilerOperations(io.trino.sql.gen.CompilerOperations) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) Block(io.trino.spi.block.Block) GroupByIdBlock(io.trino.operator.GroupByIdBlock) BytecodeNode(io.airlift.bytecode.BytecodeNode)

Example 18 with ForLoop

use of io.airlift.bytecode.control.ForLoop in project trino by trinodb.

the class PageFunctionCompiler method generateProcessMethod.

private static MethodDefinition generateProcessMethod(ClassDefinition classDefinition, FieldDefinition blockBuilder, FieldDefinition session, FieldDefinition page, FieldDefinition selectedPositions, FieldDefinition nextIndexOrPosition, FieldDefinition result) {
    MethodDefinition method = classDefinition.declareMethod(a(PUBLIC), "process", type(boolean.class), ImmutableList.of());
    Scope scope = method.getScope();
    Variable thisVariable = method.getThis();
    BytecodeBlock body = method.getBody();
    Variable from = scope.declareVariable("from", body, thisVariable.getField(nextIndexOrPosition));
    Variable to = scope.declareVariable("to", body, add(thisVariable.getField(selectedPositions).invoke("getOffset", int.class), thisVariable.getField(selectedPositions).invoke("size", int.class)));
    Variable positions = scope.declareVariable(int[].class, "positions");
    Variable index = scope.declareVariable(int.class, "index");
    IfStatement ifStatement = new IfStatement().condition(thisVariable.getField(selectedPositions).invoke("isList", boolean.class));
    body.append(ifStatement);
    ifStatement.ifTrue(new BytecodeBlock().append(positions.set(thisVariable.getField(selectedPositions).invoke("getPositions", int[].class))).append(new ForLoop("positions loop").initialize(index.set(from)).condition(lessThan(index, to)).update(index.increment()).body(new BytecodeBlock().append(thisVariable.invoke("evaluate", void.class, thisVariable.getField(session), thisVariable.getField(page), positions.getElement(index))))));
    ifStatement.ifFalse(new ForLoop("range based loop").initialize(index.set(from)).condition(lessThan(index, to)).update(index.increment()).body(new BytecodeBlock().append(thisVariable.invoke("evaluate", void.class, thisVariable.getField(session), thisVariable.getField(page), index))));
    body.comment("result = this.blockBuilder.build(); return true;").append(thisVariable.setField(result, thisVariable.getField(blockBuilder).invoke("build", Block.class))).push(true).retBoolean();
    return method;
}
Also used : IfStatement(io.airlift.bytecode.control.IfStatement) Variable(io.airlift.bytecode.Variable) Scope(io.airlift.bytecode.Scope) ForLoop(io.airlift.bytecode.control.ForLoop) MethodDefinition(io.airlift.bytecode.MethodDefinition) BytecodeBlock(io.airlift.bytecode.BytecodeBlock)

Example 19 with ForLoop

use of io.airlift.bytecode.control.ForLoop in project trino by trinodb.

the class PageFunctionCompiler method generatePageFilterMethod.

private static MethodDefinition generatePageFilterMethod(ClassDefinition classDefinition, FieldDefinition selectedPositionsField) {
    Parameter session = arg("session", ConnectorSession.class);
    Parameter page = arg("page", Page.class);
    MethodDefinition method = classDefinition.declareMethod(a(PUBLIC), "filter", type(SelectedPositions.class), ImmutableList.<Parameter>builder().add(session).add(page).build());
    Scope scope = method.getScope();
    Variable thisVariable = method.getThis();
    BytecodeBlock body = method.getBody();
    Variable positionCount = scope.declareVariable("positionCount", body, page.invoke("getPositionCount", int.class));
    body.append(new IfStatement("grow selectedPositions if necessary").condition(lessThan(thisVariable.getField(selectedPositionsField).length(), positionCount)).ifTrue(thisVariable.setField(selectedPositionsField, newArray(type(boolean[].class), positionCount))));
    Variable selectedPositions = scope.declareVariable("selectedPositions", body, thisVariable.getField(selectedPositionsField));
    Variable position = scope.declareVariable(int.class, "position");
    body.append(new ForLoop().initialize(position.set(constantInt(0))).condition(lessThan(position, positionCount)).update(position.increment()).body(selectedPositions.setElement(position, thisVariable.invoke("filter", boolean.class, session, page, position))));
    body.append(invokeStatic(PageFilter.class, "positionsArrayToSelectedPositions", SelectedPositions.class, selectedPositions, positionCount).ret());
    return method;
}
Also used : IfStatement(io.airlift.bytecode.control.IfStatement) Variable(io.airlift.bytecode.Variable) Scope(io.airlift.bytecode.Scope) ForLoop(io.airlift.bytecode.control.ForLoop) MethodDefinition(io.airlift.bytecode.MethodDefinition) SelectedPositions(io.trino.operator.project.SelectedPositions) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) Parameter(io.airlift.bytecode.Parameter)

Example 20 with ForLoop

use of io.airlift.bytecode.control.ForLoop in project trino by trinodb.

the class JoinCompiler method generateConstructor.

private static void generateConstructor(ClassDefinition classDefinition, List<Integer> joinChannels, FieldDefinition sizeField, FieldDefinition instanceSizeField, List<FieldDefinition> channelFields, List<FieldDefinition> joinChannelFields, FieldDefinition hashChannelField) {
    Parameter channels = arg("channels", type(List.class, type(List.class, Block.class)));
    Parameter hashChannel = arg("hashChannel", type(OptionalInt.class));
    MethodDefinition constructorDefinition = classDefinition.declareConstructor(a(PUBLIC), channels, hashChannel);
    Variable thisVariable = constructorDefinition.getThis();
    Variable blockIndex = constructorDefinition.getScope().declareVariable(int.class, "blockIndex");
    BytecodeBlock constructor = constructorDefinition.getBody().comment("super();").append(thisVariable).invokeConstructor(Object.class);
    constructor.comment("this.size = INSTANCE_SIZE").append(thisVariable.setField(sizeField, getStatic(instanceSizeField)));
    constructor.comment("Set channel fields");
    for (int index = 0; index < channelFields.size(); index++) {
        BytecodeExpression channel = channels.invoke("get", Object.class, constantInt(index)).cast(type(List.class, Block.class));
        constructor.append(thisVariable.setField(channelFields.get(index), channel));
        BytecodeBlock loopBody = new BytecodeBlock();
        constructor.comment("for(blockIndex = 0; blockIndex < channel.size(); blockIndex++) { size += channel.get(i).getRetainedSizeInBytes() }").append(new ForLoop().initialize(blockIndex.set(constantInt(0))).condition(new BytecodeBlock().append(blockIndex).append(channel.invoke("size", int.class)).invokeStatic(CompilerOperations.class, "lessThan", boolean.class, int.class, int.class)).update(new BytecodeBlock().incrementVariable(blockIndex, (byte) 1)).body(loopBody));
        loopBody.append(thisVariable).append(thisVariable).getField(sizeField).append(channel.invoke("get", Object.class, blockIndex).cast(type(Block.class)).invoke("getRetainedSizeInBytes", long.class)).longAdd().putField(sizeField);
    }
    constructor.comment("Set join channel fields");
    for (int index = 0; index < joinChannelFields.size(); index++) {
        BytecodeExpression joinChannel = channels.invoke("get", Object.class, constantInt(joinChannels.get(index))).cast(type(List.class, Block.class));
        constructor.append(thisVariable.setField(joinChannelFields.get(index), joinChannel));
    }
    constructor.comment("Set hashChannel");
    constructor.append(new IfStatement().condition(hashChannel.invoke("isPresent", boolean.class)).ifTrue(thisVariable.setField(hashChannelField, channels.invoke("get", Object.class, hashChannel.invoke("getAsInt", int.class)))).ifFalse(thisVariable.setField(hashChannelField, constantNull(hashChannelField.getType()))));
    constructor.ret();
}
Also used : IfStatement(io.airlift.bytecode.control.IfStatement) Variable(io.airlift.bytecode.Variable) ForLoop(io.airlift.bytecode.control.ForLoop) MethodDefinition(io.airlift.bytecode.MethodDefinition) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) Parameter(io.airlift.bytecode.Parameter) BytecodeBlock(io.airlift.bytecode.BytecodeBlock) Block(io.trino.spi.block.Block) LongArrayList(it.unimi.dsi.fastutil.longs.LongArrayList) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) OptionalInt(java.util.OptionalInt) BytecodeExpression(io.airlift.bytecode.expression.BytecodeExpression)

Aggregations

Variable (io.airlift.bytecode.Variable)20 ForLoop (io.airlift.bytecode.control.ForLoop)20 IfStatement (io.airlift.bytecode.control.IfStatement)20 BytecodeBlock (io.airlift.bytecode.BytecodeBlock)18 MethodDefinition (io.airlift.bytecode.MethodDefinition)16 Parameter (io.airlift.bytecode.Parameter)14 Scope (io.airlift.bytecode.Scope)14 BytecodeNode (io.airlift.bytecode.BytecodeNode)10 ClassDefinition (io.airlift.bytecode.ClassDefinition)8 VariableInstruction.incrementVariable (io.airlift.bytecode.instruction.VariableInstruction.incrementVariable)8 Block (io.prestosql.spi.block.Block)7 Block (io.trino.spi.block.Block)7 ImmutableList (com.google.common.collect.ImmutableList)5 List (java.util.List)5 BytecodeExpression (io.airlift.bytecode.expression.BytecodeExpression)4 Signature.typeVariable (io.prestosql.spi.function.Signature.typeVariable)4 CallSiteBinder (io.prestosql.sql.gen.CallSiteBinder)4 Signature.typeVariable (io.trino.metadata.Signature.typeVariable)4 CallSiteBinder (io.trino.sql.gen.CallSiteBinder)4 ArrayList (java.util.ArrayList)4