Skip to content

Commit ff583f2

Browse files
rakudramaCommit Queue
authored andcommitted
[dart2js] Do some load elimination in simplifier
Doing load elimination of final fields earlier generates more opportunities for GVN. This helps when the same value is 'boxed' in a wrapper object and the 'unboxed' multiple times. Change-Id: Id3a2b392a7563bae7a4cd1f8b2763c5ac1b377b5 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/432502 Commit-Queue: Stephen Adams <[email protected]> Reviewed-by: Mayank Patke <[email protected]> Reviewed-by: Nate Biggs <[email protected]>
1 parent e2d6df2 commit ff583f2

File tree

1 file changed

+38
-0
lines changed

1 file changed

+38
-0
lines changed

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

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1821,9 +1821,47 @@ class SsaInstructionSimplifier extends HBaseVisitor<HInstruction>
18211821
}
18221822
}
18231823

1824+
// HFieldGet of a final field from an allocator can be replaced with the
1825+
// field's value.
1826+
//
1827+
// Load Elimination is more powerful as it can handle non-final fields, but
1828+
// doing this earlier in the simplifier generates more opportunities for the
1829+
// first GVN pass.
1830+
if (receiver is HCreate && !node.isAssignable) {
1831+
int index = _indexOfFieldInAllocatorInputs(
1832+
receiver.element,
1833+
node.element,
1834+
);
1835+
if (index >= 0) return receiver.inputs[index];
1836+
}
1837+
18241838
return node;
18251839
}
18261840

1841+
int _indexOfFieldInAllocatorInputs(ClassEntity cls, FieldEntity field) {
1842+
final classCache = _indexOfFieldInAllocatorCache ??= {};
1843+
final fieldCache = classCache[cls] ??= {};
1844+
final index = fieldCache[field];
1845+
if (index != null) return index;
1846+
1847+
int argumentIndex = 0;
1848+
_closedWorld.elementEnvironment.forEachInstanceField(cls, (
1849+
_,
1850+
FieldEntity member,
1851+
) {
1852+
FieldAnalysisData fieldData = _closedWorld.fieldAnalysis.getFieldData(
1853+
member,
1854+
);
1855+
int index = (fieldData.isElided || fieldData.isInitializedInAllocator)
1856+
? -1
1857+
: argumentIndex++;
1858+
fieldCache[member] = index;
1859+
});
1860+
return fieldCache[field]!;
1861+
}
1862+
1863+
Map<ClassEntity, Map<FieldEntity, int>>? _indexOfFieldInAllocatorCache;
1864+
18271865
@override
18281866
HInstruction visitGetLength(HGetLength node) {
18291867
HInstruction receiver = node.receiver;

0 commit comments

Comments
 (0)