119
120
class Transform extends ReactiveFunctionTransform<ReactiveScopeDependencies | null> {
121
lastUsage: Map<DeclarationId, InstructionId>;
122
+ temporaries: Map<DeclarationId, DeclarationId> = new Map();
123
124
constructor(lastUsage: Map<DeclarationId, InstructionId>) {
125
super();
216
current.lvalues.add(
217
instr.instruction.lvalue.identifier.declarationId,
218
);
219
+ if (instr.instruction.value.kind === 'LoadLocal') {
220
+ this.temporaries.set(
221
+ instr.instruction.lvalue.identifier.declarationId,
222
+ instr.instruction.value.place.identifier.declarationId,
223
+ );
224
+ }
225
}
226
break;
227
}
243
)) {
244
current.lvalues.add(lvalue.identifier.declarationId);
245
}
246
+ this.temporaries.set(
247
+ instr.instruction.value.lvalue.place.identifier
248
+ .declarationId,
249
+ this.temporaries.get(
250
+ instr.instruction.value.value.identifier.declarationId,
251
+ ) ?? instr.instruction.value.value.identifier.declarationId,
252
+ );
253
} else {
254
log(
255
`Reset scope @${current.block.scope.id} from StoreLocal in [${instr.instruction.id}]`,
274
case 'scope': {
275
if (
276
current !== null &&
263
- canMergeScopes(current.block, instr) &&
277
+ canMergeScopes(current.block, instr, this.temporaries) &&
278
areLValuesLastUsedByScope(
279
instr.scope,
280
current.lvalues,
440
function canMergeScopes(
441
current: ReactiveScopeBlock,
442
next: ReactiveScopeBlock,
443
+ temporaries: Map<DeclarationId, DeclarationId>,
444
): boolean {
445
// Don't merge scopes with reassignments
446
if (
480
(next.scope.dependencies.size !== 0 &&
481
[...next.scope.dependencies].every(
482
dep =>
483
+ dep.path.length === 0 &&
484
isAlwaysInvalidatingType(dep.identifier.type) &&
485
Iterable_some(
486
current.scope.declarations.values(),
487
decl =>
472
- decl.identifier.declarationId === dep.identifier.declarationId,
488
+ decl.identifier.declarationId === dep.identifier.declarationId ||
489
+ decl.identifier.declarationId ===
490
+ temporaries.get(dep.identifier.declarationId),
491
),
492
))
493
) {
495
return true;
496
}
497
log(` cannot merge scopes:`);
480
- log(` ${printReactiveScopeSummary(current.scope)}`);
481
- log(` ${printReactiveScopeSummary(next.scope)}`);
498
+ log(
499
+ ` ${printReactiveScopeSummary(current.scope)} ${[...current.scope.declarations.values()].map(decl => decl.identifier.declarationId)}`,
500
+ );
501
+ log(
502
+ ` ${printReactiveScopeSummary(next.scope)} ${[...next.scope.dependencies].map(dep => `${dep.identifier.declarationId} ${temporaries.get(dep.identifier.declarationId) ?? dep.identifier.declarationId}`)}`,
503
+ );
504
return false;
505
}
506