Skip to content

Commit c5adfd2

Browse files
rakudramaCommit Queue
authored andcommitted
[dart2js] Trust refined types from Dart type promotion
Using the promoted type reduces the need for primitive receiver and argument checks, and can result in better code. The promoted type is 'used' by inserting pinned HTypeKnown instructions at the use site. The pinning can constrain code motion. Better inference in the optimizer (9505e95) relaxes most of these constraints. Change-Id: Ic9c0ebe7fd95b60382e2f66c49f69440b8b881d1 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/419484 Reviewed-by: Mayank Patke <[email protected]> Commit-Queue: Stephen Adams <[email protected]>
1 parent 4464f61 commit c5adfd2

File tree

2 files changed

+37
-6
lines changed

2 files changed

+37
-6
lines changed

pkg/compiler/lib/src/ssa/builder.dart

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4720,13 +4720,38 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
47204720
return;
47214721
}
47224722

4723-
Local local = _localsMap.getLocalVariable(node.variable);
4724-
stack.add(
4725-
localsHandler.readLocal(
4726-
local,
4727-
sourceInformation: _sourceInformationBuilder.buildGet(node),
4728-
),
4723+
final local = _localsMap.getLocalVariable(node.variable);
4724+
final readLocal = localsHandler.readLocal(
4725+
local,
4726+
sourceInformation: _sourceInformationBuilder.buildGet(node),
47294727
);
4728+
4729+
if (node.promotedType != null) {
4730+
// Use the prompted type by inserting a HTypeKnown refinement node.
4731+
//
4732+
// The front end does not tell us _why_ the type was promoted, so the
4733+
// HTypeKnown is pinned at the variable reference rather than at the
4734+
// control flow reponsible for the promotion. Pinning at the variable
4735+
// reference impairs code motion.
4736+
//
4737+
// Many of the promoted types are also refined by the optimizer (in
4738+
// SsaTypeConversionInserter, where controlling phis are handled). This
4739+
// causes a similar HTypeKnown to be inserted, but pinned at a location
4740+
// responsible the promotion. The optimizer-inserted HTypeKnown nodes
4741+
// dominate the nodes inserted here, allowing the nodes inserted here to
4742+
// be removed as redundant, sometimes lifting the code motion
4743+
// restriction. There is not an exact match between the front-end
4744+
// inference, so some of the promotions remain.
4745+
final trusted = _typeBuilder.trustPromotedType(
4746+
readLocal,
4747+
_getDartTypeIfValid(node.promotedType!),
4748+
);
4749+
if (trusted != readLocal) {
4750+
push(trusted);
4751+
return;
4752+
}
4753+
}
4754+
stack.add(readLocal);
47304755
}
47314756

47324757
void _handlePropertySet(

pkg/compiler/lib/src/ssa/type_builder.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ abstract class TypeBuilder {
4444
return mask;
4545
}
4646

47+
/// If needed, create a HTypeKnown to 'trust' the type of [original] when the
48+
/// language type promotion has refined the type to [type].
49+
HInstruction trustPromotedType(HInstruction original, DartType type) {
50+
return _trustType(original, type);
51+
}
52+
4753
/// Create an instruction to simply trust the provided type.
4854
HInstruction _trustType(HInstruction original, DartType type) {
4955
bool hasLateSentinel =

0 commit comments

Comments
 (0)