use of com.facebook.presto.bytecode.Access.PRIVATE in project presto by prestodb.
the class ConcatFunction method generateConcat.
private static Class<?> generateConcat(int arity) {
ClassDefinition definition = new ClassDefinition(a(PUBLIC, FINAL), CompilerUtils.makeClassName("Concat" + arity + "ScalarFunction"), type(Object.class));
// Generate constructor
definition.declareDefaultConstructor(a(PRIVATE));
// Generate concat()
List<Parameter> parameters = IntStream.range(0, arity).mapToObj(i -> arg("arg" + i, Slice.class)).collect(toImmutableList());
MethodDefinition method = definition.declareMethod(a(PUBLIC, STATIC), "concat", type(Slice.class), parameters);
Scope scope = method.getScope();
BytecodeBlock body = method.getBody();
Variable length = scope.declareVariable(int.class, "length");
body.append(length.set(constantInt(0)));
for (int i = 0; i < arity; ++i) {
body.append(length.set(generateCheckedAdd(length, parameters.get(i).invoke("length", int.class))));
}
Variable result = scope.declareVariable(Slice.class, "result");
body.append(result.set(invokeStatic(Slices.class, "allocate", Slice.class, length)));
Variable position = scope.declareVariable(int.class, "position");
body.append(position.set(constantInt(0)));
for (int i = 0; i < arity; ++i) {
body.append(result.invoke("setBytes", void.class, position, parameters.get(i)));
body.append(position.set(add(position, parameters.get(i).invoke("length", int.class))));
}
body.getVariable(result).retObject();
return defineClass(definition, Object.class, ImmutableMap.of(), new DynamicClassLoader(ConcatFunction.class.getClassLoader()));
}
use of com.facebook.presto.bytecode.Access.PRIVATE in project presto by prestodb.
the class CommonSubExpressionRewriter method removeRedundantCSE.
private static Map<Integer, Map<RowExpression, Integer>> removeRedundantCSE(Map<Integer, Set<RowExpression>> cseByLevel, Map<RowExpression, Integer> expressionCount) {
Map<Integer, Map<RowExpression, Integer>> results = new HashMap<>();
int startCSELevel = cseByLevel.keySet().stream().reduce(Math::max).get();
int stopCSELevel = cseByLevel.keySet().stream().reduce(Math::min).get();
for (int i = startCSELevel; i > stopCSELevel; i--) {
if (!cseByLevel.containsKey(i)) {
continue;
}
Map<RowExpression, Integer> expressions = cseByLevel.get(i).stream().filter(expression -> expressionCount.get(expression) > 0).collect(toImmutableMap(identity(), expressionCount::get));
if (!expressions.isEmpty()) {
results.put(i, expressions);
}
for (RowExpression expression : expressions.keySet()) {
int expressionOccurrence = expressionCount.get(expression);
subExpressions(expression).stream().filter(subExpression -> !subExpression.equals(expression)).forEach(subExpression -> {
if (expressionCount.containsKey(subExpression)) {
expressionCount.put(subExpression, expressionCount.get(subExpression) - expressionOccurrence);
}
});
}
}
Map<RowExpression, Integer> expressions = cseByLevel.get(stopCSELevel).stream().filter(expression -> expressionCount.get(expression) > 0).collect(toImmutableMap(identity(), expression -> expressionCount.get(expression) + 1));
if (!expressions.isEmpty()) {
results.put(stopCSELevel, expressions);
}
return results;
}
use of com.facebook.presto.bytecode.Access.PRIVATE 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.Access.PRIVATE in project presto by prestodb.
the class AbstractGreatestLeast method generate.
private Class<?> generate(List<Class<?>> javaTypes, Type type, MethodHandle compareMethod) {
checkCondition(javaTypes.size() <= 127, NOT_SUPPORTED, "Too many arguments for function call %s()", getSignature().getNameSuffix());
String javaTypeName = javaTypes.stream().map(Class::getSimpleName).collect(joining());
ClassDefinition definition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName(javaTypeName + "$" + getSignature().getNameSuffix()), type(Object.class));
definition.declareDefaultConstructor(a(PRIVATE));
List<Parameter> parameters = IntStream.range(0, javaTypes.size()).mapToObj(i -> arg("arg" + i, javaTypes.get(i))).collect(toImmutableList());
MethodDefinition method = definition.declareMethod(a(PUBLIC, STATIC), getSignature().getNameSuffix(), type(javaTypes.get(0)), parameters);
Scope scope = method.getScope();
BytecodeBlock body = method.getBody();
CallSiteBinder binder = new CallSiteBinder();
if (type.getTypeSignature().getBase().equals(StandardTypes.DOUBLE)) {
for (Parameter parameter : parameters) {
body.append(parameter);
body.append(invoke(binder.bind(CHECK_NOT_NAN.bindTo(getSignature().getNameSuffix())), "checkNotNaN"));
}
}
Variable value = scope.declareVariable(javaTypes.get(0), "value");
body.append(value.set(parameters.get(0)));
for (int i = 1; i < javaTypes.size(); i++) {
body.append(new IfStatement().condition(new BytecodeBlock().append(parameters.get(i)).append(value).append(invoke(binder.bind(compareMethod), "compare"))).ifTrue(value.set(parameters.get(i))));
}
body.append(value.ret());
return defineClass(definition, Object.class, binder.getBindings(), new DynamicClassLoader(getClass().getClassLoader()));
}
use of com.facebook.presto.bytecode.Access.PRIVATE in project presto by prestodb.
the class ConcatFunction method generateConcat.
private static Class<?> generateConcat(TypeSignature type, int arity) {
checkCondition(arity <= 254, NOT_SUPPORTED, "Too many arguments for string concatenation");
ClassDefinition definition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName(type.getBase() + "_concat" + arity + "ScalarFunction"), type(Object.class));
// Generate constructor
definition.declareDefaultConstructor(a(PRIVATE));
// Generate concat()
List<Parameter> parameters = IntStream.range(0, arity).mapToObj(i -> arg("arg" + i, Slice.class)).collect(toImmutableList());
MethodDefinition method = definition.declareMethod(a(PUBLIC, STATIC), "concat", type(Slice.class), parameters);
Scope scope = method.getScope();
BytecodeBlock body = method.getBody();
Variable result = scope.declareVariable(Slice.class, "result");
body.append(invokeStatic(ConcatFunction.class, "concat", Slice.class, BytecodeExpressions.newArray(ParameterizedType.type(Slice[].class), parameters))).retObject();
return defineClass(definition, Object.class, ImmutableMap.of(), new DynamicClassLoader(ConcatFunction.class.getClassLoader()));
}
Aggregations