use of io.airlift.bytecode.control.IfStatement in project hetu-core by openlookeng.
the class JoinCompiler method generateHashPositionMethod.
private static void generateHashPositionMethod(ClassDefinition classDefinition, CallSiteBinder callSiteBinder, List<Type> joinChannelTypes, List<FieldDefinition> joinChannelFields, FieldDefinition hashChannelField) {
Parameter blockIndex = arg("blockIndex", int.class);
Parameter blockPosition = arg("blockPosition", int.class);
MethodDefinition hashPositionMethod = classDefinition.declareMethod(a(PUBLIC), "hashPosition", type(long.class), blockIndex, blockPosition);
Variable thisVariable = hashPositionMethod.getThis();
BytecodeExpression hashChannel = thisVariable.getField(hashChannelField);
BytecodeExpression bigintType = constantType(callSiteBinder, BigintType.BIGINT);
IfStatement ifStatement = new IfStatement();
ifStatement.condition(notEqual(hashChannel, constantNull(hashChannelField.getType())));
ifStatement.ifTrue(bigintType.invoke("getLong", long.class, hashChannel.invoke("get", Object.class, blockIndex).cast(Block.class), blockPosition).ret());
hashPositionMethod.getBody().append(ifStatement);
Variable resultVariable = hashPositionMethod.getScope().declareVariable(long.class, "result");
hashPositionMethod.getBody().push(0L).putVariable(resultVariable);
for (int index = 0; index < joinChannelTypes.size(); index++) {
BytecodeExpression type = constantType(callSiteBinder, joinChannelTypes.get(index));
BytecodeExpression block = hashPositionMethod.getThis().getField(joinChannelFields.get(index)).invoke("get", Object.class, blockIndex).cast(Block.class);
hashPositionMethod.getBody().getVariable(resultVariable).push(31L).append(OpCode.LMUL).append(typeHashCode(type, block, blockPosition)).append(OpCode.LADD).putVariable(resultVariable);
}
hashPositionMethod.getBody().getVariable(resultVariable).retLong();
}
use of io.airlift.bytecode.control.IfStatement in project hetu-core by openlookeng.
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;
}
use of io.airlift.bytecode.control.IfStatement in project hetu-core by openlookeng.
the class SwitchCodeGenerator method generateExpression.
@Override
public BytecodeNode generateExpression(FunctionHandle functionHandle, BytecodeGeneratorContext generatorContext, Type returnType, List<RowExpression> arguments) {
// TODO: compile as
/*
hashCode = hashCode(<value>)
// all constant expressions before a non-constant
switch (hashCode) {
case ...:
if (<value> == <constant1>) {
...
}
else if (<value> == <constant2>) {
...
}
else if (...) {
}
case ...:
...
}
if (<value> == <non-constant1>) {
...
}
else if (<value> == <non-constant2>) {
...
}
...
// repeat with next sequence of constant expressions
*/
Scope scope = generatorContext.getScope();
// process value, else, and all when clauses
RowExpression value = arguments.get(0);
BytecodeNode valueBytecode = generatorContext.generate(value);
BytecodeNode elseValue;
List<RowExpression> whenClauses;
RowExpression last = arguments.get(arguments.size() - 1);
if (last instanceof SpecialForm && ((SpecialForm) last).getForm() == WHEN) {
whenClauses = arguments.subList(1, arguments.size());
elseValue = new BytecodeBlock().append(generatorContext.wasNull().set(constantTrue())).pushJavaDefault(returnType.getJavaType());
} else {
whenClauses = arguments.subList(1, arguments.size() - 1);
elseValue = generatorContext.generate(last);
}
// determine the type of the value and result
Class<?> valueType = value.getType().getJavaType();
// evaluate the value and store it in a variable
LabelNode nullValue = new LabelNode("nullCondition");
Variable tempVariable = scope.createTempVariable(valueType);
BytecodeBlock block = new BytecodeBlock().append(valueBytecode).append(BytecodeUtils.ifWasNullClearPopAndGoto(scope, nullValue, void.class, valueType)).putVariable(tempVariable);
BytecodeNode getTempVariableNode = VariableInstruction.loadVariable(tempVariable);
// build the statements
elseValue = new BytecodeBlock().visitLabel(nullValue).append(elseValue);
// reverse list because current if statement builder doesn't support if/else so we need to build the if statements bottom up
for (RowExpression clause : Lists.reverse(whenClauses)) {
Preconditions.checkArgument(clause instanceof SpecialForm && ((SpecialForm) clause).getForm() == WHEN);
RowExpression operand = ((SpecialForm) clause).getArguments().get(0);
RowExpression result = ((SpecialForm) clause).getArguments().get(1);
// call equals(value, operand)
FunctionHandle equalsFunction = generatorContext.getFunctionManager().resolveOperatorFunctionHandle(EQUAL, fromTypes(value.getType(), operand.getType()));
// TODO: what if operand is null? It seems that the call will return "null" (which is cleared below)
// and the code only does the right thing because the value in the stack for that scenario is
// Java's default for boolean == false
// This code should probably be checking for wasNull after the call and "failing" the equality
// check if wasNull is true
BytecodeNode equalsCall = generatorContext.generateCall(EQUAL.name(), generatorContext.getFunctionManager().getBuiltInScalarFunctionImplementation(equalsFunction), ImmutableList.of(generatorContext.generate(operand, Optional.empty()), getTempVariableNode));
BytecodeBlock condition = new BytecodeBlock().append(equalsCall).append(generatorContext.wasNull().set(constantFalse()));
elseValue = new IfStatement("when").condition(condition).ifTrue(generatorContext.generate(result)).ifFalse(elseValue);
}
return block.append(elseValue);
}
use of io.airlift.bytecode.control.IfStatement in project hetu-core by openlookeng.
the class BytecodeUtils method boxPrimitiveIfNecessary.
public static BytecodeNode boxPrimitiveIfNecessary(Scope scope, Class<?> type) {
checkArgument(!type.isPrimitive(), "cannot box into primitive type");
if (!Primitives.isWrapperType(type)) {
return NOP;
}
BytecodeBlock notNull = new BytecodeBlock().comment("box primitive");
Class<?> expectedCurrentStackType;
if (type == Long.class) {
notNull.invokeStatic(Long.class, "valueOf", Long.class, long.class);
expectedCurrentStackType = long.class;
} else if (type == Double.class) {
notNull.invokeStatic(Double.class, "valueOf", Double.class, double.class);
expectedCurrentStackType = double.class;
} else if (type == Boolean.class) {
notNull.invokeStatic(Boolean.class, "valueOf", Boolean.class, boolean.class);
expectedCurrentStackType = boolean.class;
} else {
throw new UnsupportedOperationException("not yet implemented: " + type);
}
BytecodeBlock condition = new BytecodeBlock().append(scope.getVariable("wasNull"));
BytecodeBlock wasNull = new BytecodeBlock().pop(expectedCurrentStackType).pushNull().checkCast(type);
return new IfStatement().condition(condition).ifTrue(wasNull).ifFalse(notNull);
}
use of io.airlift.bytecode.control.IfStatement in project hetu-core by openlookeng.
the class CoalesceCodeGenerator method generateExpression.
@Override
public BytecodeNode generateExpression(FunctionHandle functionHandle, 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;
}
Aggregations