Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(468)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/ssa/optimize.dart

Issue 154353002: Fix for issue 16497 - fix load elimination aliasing for typed arrays (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of ssa; 5 part of ssa;
6 6
7 abstract class OptimizationPhase { 7 abstract class OptimizationPhase {
8 String get name; 8 String get name;
9 void visitGraph(HGraph graph); 9 void visitGraph(HGraph graph);
10 } 10 }
(...skipping 1688 matching lines...) Expand 10 before | Expand all | Expand 10 after
1699 <HInstruction, Map<HInstruction, HInstruction>> {}; 1699 <HInstruction, Map<HInstruction, HInstruction>> {};
1700 1700
1701 /** 1701 /**
1702 * Set of objects that we know don't escape the current function. 1702 * Set of objects that we know don't escape the current function.
1703 */ 1703 */
1704 final Setlet<HInstruction> nonEscapingReceivers = new Setlet<HInstruction>(); 1704 final Setlet<HInstruction> nonEscapingReceivers = new Setlet<HInstruction>();
1705 1705
1706 MemorySet(this.compiler); 1706 MemorySet(this.compiler);
1707 1707
1708 /** 1708 /**
1709 * Returns whether [first] and [second] may alias to the same 1709 * Returns whether [first] and [second] always alias to the same object.
1710 * object. 1710 */
1711 bool mustAlias(HInstruction first, HInstruction second) {
1712 return first == second;
1713 }
1714
1715 /**
1716 * Returns whether [first] and [second] may alias to the same object.
1711 */ 1717 */
1712 bool mayAlias(HInstruction first, HInstruction second) { 1718 bool mayAlias(HInstruction first, HInstruction second) {
1713 if (first == second) return true; 1719 if (mustAlias(first, second)) return true;
1714 if (isConcrete(first) && isConcrete(second)) return false; 1720 if (isConcrete(first) && isConcrete(second)) return false;
1715 if (nonEscapingReceivers.contains(first)) return false; 1721 if (nonEscapingReceivers.contains(first)) return false;
1716 if (nonEscapingReceivers.contains(second)) return false; 1722 if (nonEscapingReceivers.contains(second)) return false;
1723 // Typed arrays of different types might have a shared buffer.
1724 if (couldBeTypedArray(first) && couldBeTypedArray(second)) return true;
1717 TypeMask intersection = first.instructionType.intersection( 1725 TypeMask intersection = first.instructionType.intersection(
1718 second.instructionType, compiler); 1726 second.instructionType, compiler);
1719 if (intersection.isEmpty) return false; 1727 if (intersection.isEmpty) return false;
1720 return true; 1728 return true;
1721 } 1729 }
1722 1730
1723 bool isFinal(Element element) { 1731 bool isFinal(Element element) {
1724 return compiler.world.fieldNeverChanges(element); 1732 return compiler.world.fieldNeverChanges(element);
1725 } 1733 }
1726 1734
1727 bool isConcrete(HInstruction instruction) { 1735 bool isConcrete(HInstruction instruction) {
1728 return instruction is HForeignNew 1736 return instruction is HForeignNew
1729 || instruction is HConstant 1737 || instruction is HConstant
1730 || instruction is HLiteralList; 1738 || instruction is HLiteralList;
1731 } 1739 }
1732 1740
1741 bool couldBeTypedArray(HInstruction receiver) {
1742 return compiler.backend.couldBeTypedArray(receiver.instructionType);
1743 }
1744
1733 /** 1745 /**
1734 * Returns whether [receiver] escapes the current function. 1746 * Returns whether [receiver] escapes the current function.
1735 */ 1747 */
1736 bool escapes(HInstruction receiver) { 1748 bool escapes(HInstruction receiver) {
1737 return !nonEscapingReceivers.contains(receiver); 1749 return !nonEscapingReceivers.contains(receiver);
1738 } 1750 }
1739 1751
1740 void registerAllocation(HInstruction instruction) { 1752 void registerAllocation(HInstruction instruction) {
1741 nonEscapingReceivers.add(instruction); 1753 nonEscapingReceivers.add(instruction);
1742 } 1754 }
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1842 /** 1854 /**
1843 * Sets `receiver[index]` to contain [value]. Kills all potential 1855 * Sets `receiver[index]` to contain [value]. Kills all potential
1844 * places that may be affected by this update. 1856 * places that may be affected by this update.
1845 */ 1857 */
1846 void registerKeyedValueUpdate(HInstruction receiver, 1858 void registerKeyedValueUpdate(HInstruction receiver,
1847 HInstruction index, 1859 HInstruction index,
1848 HInstruction value) { 1860 HInstruction value) {
1849 nonEscapingReceivers.remove(value); 1861 nonEscapingReceivers.remove(value);
1850 keyedValues.forEach((key, values) { 1862 keyedValues.forEach((key, values) {
1851 if (mayAlias(receiver, key)) { 1863 if (mayAlias(receiver, key)) {
1864 // Typed arrays that are views of the same buffer may have different
1865 // offsets or element sizes, unless they are the same typed array.
1866 bool weakIndex = couldBeTypedArray(key) && !mustAlias(receiver, key);
1852 values.forEach((otherIndex, otherValue) { 1867 values.forEach((otherIndex, otherValue) {
1853 if (mayAlias(index, otherIndex)) values[otherIndex] = null; 1868 if (weakIndex || mayAlias(index, otherIndex)) {
1869 values[otherIndex] = null;
1870 }
1854 }); 1871 });
1855 } 1872 }
1856 }); 1873 });
1857 1874
1858 JavaScriptBackend backend = compiler.backend;
1859 // Typed arrays may narrow incoming values. 1875 // Typed arrays may narrow incoming values.
1860 if (backend.couldBeTypedArray(receiver.instructionType)) return; 1876 if (couldBeTypedArray(receiver)) return;
1861 1877
1862 Map<HInstruction, HInstruction> map = keyedValues.putIfAbsent( 1878 Map<HInstruction, HInstruction> map = keyedValues.putIfAbsent(
1863 receiver, () => <HInstruction, HInstruction> {}); 1879 receiver, () => <HInstruction, HInstruction> {});
1864 map[index] = value; 1880 map[index] = value;
1865 } 1881 }
1866 1882
1867 /** 1883 /**
1868 * Returns null if either [first] or [second] is null. Otherwise 1884 * Returns null if either [first] or [second] is null. Otherwise
1869 * returns [first] if [first] and [second] are equal. Otherwise 1885 * returns [first] if [first] and [second] are equal. Otherwise
1870 * creates or re-uses a phi in [block] that holds [first] and [second]. 1886 * creates or re-uses a phi in [block] that holds [first] and [second].
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1949 1965
1950 keyedValues.forEach((receiver, values) { 1966 keyedValues.forEach((receiver, values) {
1951 result.keyedValues[receiver] = 1967 result.keyedValues[receiver] =
1952 new Map<HInstruction, HInstruction>.from(values); 1968 new Map<HInstruction, HInstruction>.from(values);
1953 }); 1969 });
1954 1970
1955 result.nonEscapingReceivers.addAll(nonEscapingReceivers); 1971 result.nonEscapingReceivers.addAll(nonEscapingReceivers);
1956 return result; 1972 return result;
1957 } 1973 }
1958 } 1974 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698