Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,46 @@ private static BytecodeBlock generateInputForLoop(
.putVariable(rowsVariable)
.initializeVariable(positionVariable);

/*
It differentiates two cases: (1) when a block may have null positions and (2) when there is no null positions for performance reason.
The expected skeleton of generated code is:
if false or block.mayHaveNull() or ...
for position in 0..rows
if CompilerOperations.testMask(masksBlock, position) and !block0.isNull(position) and ...
this.state_0.input<invokedynamic>(this.state_0, block0, ..., position)
else
for position in 0..rows
if CompilerOperations.testMask(masksBlock, position)
this.state_0.input<invokedynamic>(this.state_0, block0, ..., position);

*/
ForLoop nullCheckLoop = generateInputLoopBody(true, scope, stateField, positionVariable, parameterVariables, lambdaProviderFields, inputFunction, callSiteBinder, grouped, argumentNullable, masksBlock, rowsVariable);
Comment thread
radek-kondziolka marked this conversation as resolved.
Outdated
ForLoop noNullCheckLoop = generateInputLoopBody(false, scope, stateField, positionVariable, parameterVariables, lambdaProviderFields, inputFunction, callSiteBinder, grouped, argumentNullable, masksBlock, rowsVariable);

// prepare mayHaveNull condition
BytecodeExpression mayHaveNullCondition = BytecodeExpressions.constantFalse();
for (int parameterIndex = 0; parameterIndex < parameterVariables.size(); parameterIndex++) {
if (!argumentNullable.get(parameterIndex)) {
Comment thread
radek-kondziolka marked this conversation as resolved.
Outdated
mayHaveNullCondition = BytecodeExpressions.or(mayHaveNullCondition, parameterVariables.get(parameterIndex).invoke("mayHaveNull", boolean.class));
}
}

IfStatement mayHaveNullIf = new IfStatement("if(%s)", mayHaveNullCondition).condition(mayHaveNullCondition)
Comment thread
radek-kondziolka marked this conversation as resolved.
Outdated
.ifFalse(noNullCheckLoop)
.ifTrue(nullCheckLoop);

block.append(new IfStatement("if(!maskGuaranteedToFilterAllRows(%s, %s))", rowsVariable.getName(), masksBlock.getName())
Comment thread
radek-kondziolka marked this conversation as resolved.
Outdated
.condition(new BytecodeBlock()
.getVariable(rowsVariable)
.getVariable(masksBlock)
.invokeStatic(AggregationUtils.class, "maskGuaranteedToFilterAllRows", boolean.class, int.class, Block.class))
.ifFalse(mayHaveNullIf));

return block;
}

private static ForLoop generateInputLoopBody(boolean isNullCheck, Scope scope, List<FieldDefinition> stateField, Variable positionVariable, List<Variable> parameterVariables, List<FieldDefinition> lambdaProviderFields, MethodHandle inputFunction, CallSiteBinder callSiteBinder, boolean grouped, List<Boolean> argumentNullable, Variable masksBlock, Variable rowsVariable)
{
BytecodeNode loopBody = generateInvokeInputFunction(
scope,
stateField,
Expand All @@ -520,15 +560,17 @@ private static BytecodeBlock generateInputForLoop(
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);
if (isNullCheck) {
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);
}
}
}

Expand All @@ -539,23 +581,14 @@ private static BytecodeBlock generateInputForLoop(
.invokeStatic(CompilerOperations.class, "testMask", boolean.class, Block.class, int.class))
.ifTrue(loopBody);

ForLoop forLoop = new ForLoop()
return 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;
}

private static BytecodeBlock generateInvokeInputFunction(
Expand Down