Skip to content

Commit ae12d7c

Browse files
rakudramaCommit Queue
authored andcommitted
Reapply "[dart2js] Do some load elimination in simplifier"
This reverts commit 3f2befe. Change-Id: I551b1dcc058b833bf208164eb787aaad68b9341b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/433267 Reviewed-by: Nate Biggs <[email protected]> Commit-Queue: Stephen Adams <[email protected]>
1 parent 7b42aae commit ae12d7c

File tree

1 file changed

+52
-0
lines changed

1 file changed

+52
-0
lines changed

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

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1821,9 +1821,61 @@ 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+
1859+
// TODO(https://github.com/dart-lang/sdk/issues/26775): dart2js has a bug
1860+
// with using the same mixin twice, the fields are not separated, so can
1861+
// occur here twice. If we already have an index, one of them is wrong.
1862+
if (fieldCache[member] != null) index = -1;
1863+
1864+
fieldCache[member] = index;
1865+
});
1866+
1867+
if (fieldCache[field] == null) {
1868+
// The field should not be missing but it might be possible (1) with
1869+
// unsound optimizations due to 'trusted' checks (-O3), and (2) attempting
1870+
// to compile an abstract class generative constructor (a bit unclear why
1871+
// this happens, see b/422944368).
1872+
return fieldCache[field] = -1;
1873+
}
1874+
return fieldCache[field]!;
1875+
}
1876+
1877+
Map<ClassEntity, Map<FieldEntity, int>>? _indexOfFieldInAllocatorCache;
1878+
18271879
@override
18281880
HInstruction visitGetLength(HGetLength node) {
18291881
HInstruction receiver = node.receiver;

0 commit comments

Comments
 (0)