use of com.facebook.presto.bytecode.CallSiteBinder in project presto by prestodb.
the class CursorProcessorCompiler method generateMethods.
@Override
public void generateMethods(SqlFunctionProperties sqlFunctionProperties, ClassDefinition classDefinition, CallSiteBinder callSiteBinder, RowExpression filter, List<RowExpression> projections) {
CachedInstanceBinder cachedInstanceBinder = new CachedInstanceBinder(classDefinition, callSiteBinder);
List<RowExpression> rowExpressions = ImmutableList.<RowExpression>builder().addAll(projections).add(filter).build();
Map<LambdaDefinitionExpression, CompiledLambda> compiledLambdaMap = generateMethodsForLambda(classDefinition, callSiteBinder, cachedInstanceBinder, rowExpressions, metadata, sqlFunctionProperties, sessionFunctions, "");
Map<VariableReferenceExpression, CommonSubExpressionFields> cseFields = ImmutableMap.of();
RowExpressionCompiler compiler = new RowExpressionCompiler(classDefinition, callSiteBinder, cachedInstanceBinder, fieldReferenceCompiler(cseFields), metadata, sqlFunctionProperties, sessionFunctions, compiledLambdaMap);
if (isOptimizeCommonSubExpressions) {
Map<Integer, Map<RowExpression, VariableReferenceExpression>> commonSubExpressionsByLevel = collectCSEByLevel(rowExpressions);
if (!commonSubExpressionsByLevel.isEmpty()) {
cseFields = declareCommonSubExpressionFields(classDefinition, commonSubExpressionsByLevel);
compiler = new RowExpressionCompiler(classDefinition, callSiteBinder, cachedInstanceBinder, fieldReferenceCompiler(cseFields), metadata, sqlFunctionProperties, sessionFunctions, compiledLambdaMap);
generateCommonSubExpressionMethods(classDefinition, compiler, commonSubExpressionsByLevel, cseFields);
Map<RowExpression, VariableReferenceExpression> commonSubExpressions = commonSubExpressionsByLevel.values().stream().flatMap(m -> m.entrySet().stream()).collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue));
projections = rewriteRowExpressionsWithCSE(projections, commonSubExpressions);
filter = rewriteRowExpressionsWithCSE(ImmutableList.of(filter), commonSubExpressions).get(0);
}
}
generateProcessMethod(classDefinition, projections.size(), cseFields);
generateFilterMethod(classDefinition, compiler, filter);
for (int i = 0; i < projections.size(); i++) {
String methodName = "project_" + i;
generateProjectMethod(classDefinition, compiler, methodName, projections.get(i));
}
MethodDefinition constructorDefinition = classDefinition.declareConstructor(a(PUBLIC));
BytecodeBlock constructorBody = constructorDefinition.getBody();
Variable thisVariable = constructorDefinition.getThis();
constructorBody.comment("super();").append(thisVariable).invokeConstructor(Object.class);
initializeCommonSubExpressionFields(cseFields.values(), thisVariable, constructorBody);
cachedInstanceBinder.generateInitializations(thisVariable, constructorBody);
constructorBody.ret();
}
use of com.facebook.presto.bytecode.CallSiteBinder in project presto by prestodb.
the class PageFunctionCompiler method compileFilterInternal.
private Supplier<PageFilter> compileFilterInternal(SqlFunctionProperties sqlFunctionProperties, Map<SqlFunctionId, SqlInvokedFunction> sessionFunctions, RowExpression filter, boolean isOptimizeCommonSubExpression, Optional<String> classNameSuffix) {
requireNonNull(filter, "filter is null");
PageFieldsToInputParametersRewriter.Result result = rewritePageFieldsToInputParameters(filter);
CallSiteBinder callSiteBinder = new CallSiteBinder();
ClassDefinition classDefinition = defineFilterClass(sqlFunctionProperties, sessionFunctions, result.getRewrittenExpression(), result.getInputChannels(), callSiteBinder, isOptimizeCommonSubExpression, classNameSuffix);
Class<? extends PageFilter> functionClass;
try {
functionClass = defineClass(classDefinition, PageFilter.class, callSiteBinder.getBindings(), getClass().getClassLoader());
} catch (PrestoException prestoException) {
throw prestoException;
} catch (Exception e) {
throw new PrestoException(COMPILER_ERROR, filter.toString(), e.getCause());
}
return () -> {
try {
return functionClass.getConstructor().newInstance();
} catch (ReflectiveOperationException e) {
throw new PrestoException(COMPILER_ERROR, e);
}
};
}
use of com.facebook.presto.bytecode.CallSiteBinder in project presto by prestodb.
the class PageFunctionCompiler method definePageProjectWorkClass.
private ClassDefinition definePageProjectWorkClass(SqlFunctionProperties sqlFunctionProperties, Map<SqlFunctionId, SqlInvokedFunction> sessionFunctions, List<RowExpression> projections, CallSiteBinder callSiteBinder, boolean isOptimizeCommonSubExpression, Optional<String> classNameSuffix) {
ClassDefinition classDefinition = new ClassDefinition(a(PUBLIC, FINAL), generateProjectionWorkClassName(classNameSuffix), type(Object.class), type(Work.class));
FieldDefinition blockBuilderFields = classDefinition.declareField(a(PRIVATE), "blockBuilders", type(List.class, BlockBuilder.class));
FieldDefinition propertiesField = classDefinition.declareField(a(PRIVATE), "properties", SqlFunctionProperties.class);
FieldDefinition pageField = classDefinition.declareField(a(PRIVATE), "page", Page.class);
FieldDefinition selectedPositionsField = classDefinition.declareField(a(PRIVATE), "selectedPositions", SelectedPositions.class);
FieldDefinition nextIndexOrPositionField = classDefinition.declareField(a(PRIVATE), "nextIndexOrPosition", int.class);
FieldDefinition resultField = classDefinition.declareField(a(PRIVATE), "result", List.class);
CachedInstanceBinder cachedInstanceBinder = new CachedInstanceBinder(classDefinition, callSiteBinder);
// process
generateProcessMethod(classDefinition, blockBuilderFields, projections.size(), propertiesField, pageField, selectedPositionsField, nextIndexOrPositionField, resultField);
// getResult
MethodDefinition method = classDefinition.declareMethod(a(PUBLIC), "getResult", type(Object.class), ImmutableList.of());
method.getBody().append(method.getThis().getField(resultField)).ret(Object.class);
Map<LambdaDefinitionExpression, CompiledLambda> compiledLambdaMap = generateMethodsForLambda(classDefinition, callSiteBinder, cachedInstanceBinder, projections, metadata, sqlFunctionProperties, sessionFunctions, "");
// cse
Map<VariableReferenceExpression, CommonSubExpressionFields> cseFields = ImmutableMap.of();
RowExpressionCompiler compiler = new RowExpressionCompiler(classDefinition, callSiteBinder, cachedInstanceBinder, new FieldAndVariableReferenceCompiler(callSiteBinder, cseFields), metadata, sqlFunctionProperties, sessionFunctions, compiledLambdaMap);
if (isOptimizeCommonSubExpression) {
Map<Integer, Map<RowExpression, VariableReferenceExpression>> commonSubExpressionsByLevel = collectCSEByLevel(projections);
if (!commonSubExpressionsByLevel.isEmpty()) {
cseFields = declareCommonSubExpressionFields(classDefinition, commonSubExpressionsByLevel);
compiler = new RowExpressionCompiler(classDefinition, callSiteBinder, cachedInstanceBinder, new FieldAndVariableReferenceCompiler(callSiteBinder, cseFields), metadata, sqlFunctionProperties, sessionFunctions, compiledLambdaMap);
generateCommonSubExpressionMethods(classDefinition, compiler, commonSubExpressionsByLevel, cseFields);
Map<RowExpression, VariableReferenceExpression> commonSubExpressions = commonSubExpressionsByLevel.values().stream().flatMap(m -> m.entrySet().stream()).collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue));
projections = projections.stream().map(projection -> rewriteExpressionWithCSE(projection, commonSubExpressions)).collect(toImmutableList());
if (log.isDebugEnabled()) {
log.debug("Extracted %d common sub-expressions", commonSubExpressions.size());
commonSubExpressions.entrySet().forEach(entry -> log.debug("\t%s = %s", entry.getValue(), entry.getKey()));
log.debug("Rewrote %d projections: %s", projections.size(), Joiner.on(", ").join(projections));
}
}
}
// evaluate
generateEvaluateMethod(classDefinition, compiler, projections, blockBuilderFields, cseFields);
// constructor
Parameter blockBuilders = arg("blockBuilders", type(List.class, BlockBuilder.class));
Parameter properties = arg("properties", SqlFunctionProperties.class);
Parameter page = arg("page", Page.class);
Parameter selectedPositions = arg("selectedPositions", SelectedPositions.class);
MethodDefinition constructorDefinition = classDefinition.declareConstructor(a(PUBLIC), blockBuilders, properties, page, selectedPositions);
BytecodeBlock body = constructorDefinition.getBody();
Variable thisVariable = constructorDefinition.getThis();
body.comment("super();").append(thisVariable).invokeConstructor(Object.class).append(thisVariable.setField(blockBuilderFields, invokeStatic(ImmutableList.class, "copyOf", ImmutableList.class, blockBuilders.cast(Collection.class)))).append(thisVariable.setField(propertiesField, properties)).append(thisVariable.setField(pageField, page)).append(thisVariable.setField(selectedPositionsField, selectedPositions)).append(thisVariable.setField(nextIndexOrPositionField, selectedPositions.invoke("getOffset", int.class))).append(thisVariable.setField(resultField, constantNull(Block.class)));
initializeCommonSubExpressionFields(cseFields.values(), thisVariable, body);
cachedInstanceBinder.generateInitializations(thisVariable, body);
body.ret();
return classDefinition;
}
use of com.facebook.presto.bytecode.CallSiteBinder in project presto by prestodb.
the class RowConstructorCodeGenerator method generateExpression.
@Override
public BytecodeNode generateExpression(BytecodeGeneratorContext context, Type rowType, List<RowExpression> arguments, Optional<Variable> outputBlockVariable) {
BytecodeBlock block = new BytecodeBlock().setDescription("Constructor for " + rowType.toString());
CallSiteBinder binder = context.getCallSiteBinder();
Scope scope = context.getScope();
List<Type> types = rowType.getTypeParameters();
block.comment("Create new RowBlockBuilder; beginBlockEntry;");
Variable blockBuilder = scope.createTempVariable(BlockBuilder.class);
Variable singleRowBlockWriter = scope.createTempVariable(BlockBuilder.class);
block.append(blockBuilder.set(constantType(binder, rowType).invoke("createBlockBuilder", BlockBuilder.class, constantNull(BlockBuilderStatus.class), constantInt(1))));
block.append(singleRowBlockWriter.set(blockBuilder.invoke("beginBlockEntry", BlockBuilder.class)));
for (int i = 0; i < arguments.size(); ++i) {
Type fieldType = types.get(i);
Variable field = scope.createTempVariable(fieldType.getJavaType());
block.comment("Clean wasNull and Generate + " + i + "-th field of row");
block.append(context.wasNull().set(constantFalse()));
block.append(context.generate(arguments.get(i), Optional.empty()));
block.putVariable(field);
block.append(new IfStatement().condition(context.wasNull()).ifTrue(singleRowBlockWriter.invoke("appendNull", BlockBuilder.class).pop()).ifFalse(constantType(binder, fieldType).writeValue(singleRowBlockWriter, field).pop()));
}
block.comment("closeEntry; slice the SingleRowBlock; wasNull = false;");
block.append(blockBuilder.invoke("closeEntry", BlockBuilder.class).pop());
block.append(constantType(binder, rowType).invoke("getObject", Object.class, blockBuilder.cast(Block.class), constantInt(0)).cast(Block.class));
block.append(context.wasNull().set(constantFalse()));
outputBlockVariable.ifPresent(output -> block.append(generateWrite(context, rowType, output)));
return block;
}
use of com.facebook.presto.bytecode.CallSiteBinder in project presto by prestodb.
the class RowExpressionPredicateCompiler method compilePredicateInternal.
private Supplier<Predicate> compilePredicateInternal(SqlFunctionProperties sqlFunctionProperties, Map<SqlFunctionId, SqlInvokedFunction> sessionFunctions, RowExpression predicate) {
requireNonNull(predicate, "predicate is null");
PageFieldsToInputParametersRewriter.Result result = rewritePageFieldsToInputParameters(predicate);
int[] inputChannels = result.getInputChannels().getInputChannels().stream().mapToInt(Integer::intValue).toArray();
CallSiteBinder callSiteBinder = new CallSiteBinder();
ClassDefinition classDefinition = definePredicateClass(sqlFunctionProperties, sessionFunctions, result.getRewrittenExpression(), inputChannels, callSiteBinder);
Class<? extends Predicate> predicateClass;
try {
predicateClass = defineClass(classDefinition, Predicate.class, callSiteBinder.getBindings(), getClass().getClassLoader());
} catch (Exception e) {
throw new PrestoException(COMPILER_ERROR, predicate.toString(), e.getCause());
}
return () -> {
try {
return predicateClass.getConstructor().newInstance();
} catch (ReflectiveOperationException e) {
throw new PrestoException(COMPILER_ERROR, e);
}
};
}
Aggregations