Skip to content

Commit 5274dac

Browse files
pettyjamesmdain
authored andcommitted
Reuse more variables in row constructors
Updates RowConstructorCodeGenerator to reuse variables within the same method scope instead of just locally within the same row constructor instance. This can significantly reduce the generated code size for complex expressions involving multiple row constructors within them.
1 parent b47ed02 commit 5274dac

File tree

1 file changed

+12
-12
lines changed

1 file changed

+12
-12
lines changed

core/trino-main/src/main/java/io/trino/sql/gen/RowConstructorCodeGenerator.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@
2828
import io.trino.sql.relational.RowExpression;
2929
import io.trino.sql.relational.SpecialForm;
3030

31-
import java.util.HashMap;
3231
import java.util.List;
33-
import java.util.Map;
3432

3533
import static io.airlift.bytecode.ParameterizedType.type;
3634
import static io.airlift.bytecode.expression.BytecodeExpressions.constantFalse;
@@ -70,15 +68,12 @@ public BytecodeNode generateExpression(BytecodeGeneratorContext context)
7068
Scope scope = context.getScope();
7169
List<Type> types = rowType.getTypeParameters();
7270

73-
Variable fieldBlocks = scope.createTempVariable(Block[].class);
71+
Variable fieldBlocks = scope.getOrCreateTempVariable(Block[].class);
7472
block.append(fieldBlocks.set(newArray(type(Block[].class), arguments.size())));
75-
// Cache local variable declarations per java type on stack for reuse
76-
Map<Class<?>, Variable> javaTypeTempVariables = new HashMap<>();
7773

78-
Variable blockBuilder = scope.createTempVariable(BlockBuilder.class);
74+
Variable blockBuilder = scope.getOrCreateTempVariable(BlockBuilder.class);
7975
for (int i = 0; i < arguments.size(); ++i) {
8076
Type fieldType = types.get(i);
81-
Variable field = javaTypeTempVariables.computeIfAbsent(fieldType.getJavaType(), scope::createTempVariable);
8277

8378
block.append(blockBuilder.set(constantType(binder, fieldType).invoke(
8479
"createBlockBuilder",
@@ -89,16 +84,20 @@ public BytecodeNode generateExpression(BytecodeGeneratorContext context)
8984
block.comment("Clean wasNull and Generate + " + i + "-th field of row");
9085
block.append(context.wasNull().set(constantFalse()));
9186
block.append(context.generate(arguments.get(i)));
87+
Variable field = scope.getOrCreateTempVariable(fieldType.getJavaType());
9288
block.putVariable(field);
9389
block.append(new IfStatement()
9490
.condition(context.wasNull())
9591
.ifTrue(blockBuilder.invoke("appendNull", BlockBuilder.class).pop())
9692
.ifFalse(constantType(binder, fieldType).writeValue(blockBuilder, field).pop()));
93+
scope.releaseTempVariableForReuse(field);
9794

9895
block.append(fieldBlocks.setElement(i, blockBuilder.invoke("build", Block.class)));
9996
}
97+
scope.releaseTempVariableForReuse(blockBuilder);
10098

10199
block.append(newInstance(SqlRow.class, constantInt(0), fieldBlocks));
100+
scope.releaseTempVariableForReuse(fieldBlocks);
102101
block.append(context.wasNull().set(constantFalse()));
103102
return block;
104103
}
@@ -112,29 +111,30 @@ private BytecodeNode generateExpressionForLargeRows(BytecodeGeneratorContext con
112111
Scope scope = context.getScope();
113112
List<Type> types = rowType.getTypeParameters();
114113

115-
Variable fieldBuilders = scope.createTempVariable(BlockBuilder[].class);
114+
Variable fieldBuilders = scope.getOrCreateTempVariable(BlockBuilder[].class);
116115
block.append(fieldBuilders.set(invokeStatic(RowConstructorCodeGenerator.class, "createFieldBlockBuildersForSingleRow", BlockBuilder[].class, constantType(binder, rowType))));
117116

118-
// Cache local variable declarations per java type on stack for reuse
119-
Map<Class<?>, Variable> javaTypeTempVariables = new HashMap<>();
120-
Variable blockBuilder = scope.createTempVariable(BlockBuilder.class);
117+
Variable blockBuilder = scope.getOrCreateTempVariable(BlockBuilder.class);
121118
for (int i = 0; i < arguments.size(); ++i) {
122119
Type fieldType = types.get(i);
123-
Variable field = javaTypeTempVariables.computeIfAbsent(fieldType.getJavaType(), scope::createTempVariable);
124120

125121
block.append(blockBuilder.set(fieldBuilders.getElement(constantInt(i))));
126122

127123
block.comment("Clean wasNull and Generate + " + i + "-th field of row");
128124
block.append(context.wasNull().set(constantFalse()));
129125
block.append(context.generate(arguments.get(i)));
126+
Variable field = scope.getOrCreateTempVariable(fieldType.getJavaType());
130127
block.putVariable(field);
131128
block.append(new IfStatement()
132129
.condition(context.wasNull())
133130
.ifTrue(blockBuilder.invoke("appendNull", BlockBuilder.class).pop())
134131
.ifFalse(constantType(binder, fieldType).writeValue(blockBuilder, field).pop()));
132+
scope.releaseTempVariableForReuse(field);
135133
}
134+
scope.releaseTempVariableForReuse(blockBuilder);
136135

137136
block.append(invokeStatic(RowConstructorCodeGenerator.class, "createSqlRowFromFieldBuildersForSingleRow", SqlRow.class, fieldBuilders));
137+
scope.releaseTempVariableForReuse(fieldBuilders);
138138
block.append(context.wasNull().set(constantFalse()));
139139
return block;
140140
}

0 commit comments

Comments
 (0)