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

Side by Side Diff: lib/compiler/implementation/ssa/nodes.dart

Issue 10139012: Refactor types in ssa nodes. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 8 years, 7 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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 interface HVisitor<R> { 5 interface HVisitor<R> {
6 R visitAdd(HAdd node); 6 R visitAdd(HAdd node);
7 R visitBitAnd(HBitAnd node); 7 R visitBitAnd(HBitAnd node);
8 R visitBitNot(HBitNot node); 8 R visitBitNot(HBitNot node);
9 R visitBitOr(HBitOr node); 9 R visitBitOr(HBitOr node);
10 R visitBitXor(HBitXor node); 10 R visitBitXor(HBitXor node);
(...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after
665 665
666 bool isValid() { 666 bool isValid() {
667 assert(isClosed()); 667 assert(isClosed());
668 HValidator validator = new HValidator(); 668 HValidator validator = new HValidator();
669 validator.visitBasicBlock(this); 669 validator.visitBasicBlock(this);
670 return validator.isValid; 670 return validator.isValid;
671 } 671 }
672 } 672 }
673 673
674 674
675 class HType {
676 final int flag;
677 const HType(int this.flag);
678
679 static final int FLAG_CONFLICTING = 0;
680 static final int FLAG_UNKNOWN = 1;
681 static final int FLAG_BOOLEAN = FLAG_UNKNOWN << 1;
682 static final int FLAG_INTEGER = FLAG_BOOLEAN << 1;
683 static final int FLAG_STRING = FLAG_INTEGER << 1;
684 static final int FLAG_READABLE_ARRAY = FLAG_STRING << 1;
685 // FLAG_WRITABLE_ARRAY implies FLAG_READABLE_ARRAY.
686 static final int FLAG_WRITEABLE_ARRAY = FLAG_READABLE_ARRAY << 1;
687 static final int FLAG_DOUBLE = FLAG_WRITEABLE_ARRAY << 1;
688 static final int FLAG_NON_PRIMITIVE = FLAG_DOUBLE << 1;
689
690 static final HType CONFLICTING = const HType(FLAG_CONFLICTING);
691 static final HType UNKNOWN = const HType(FLAG_UNKNOWN);
692 static final HType BOOLEAN = const HType(FLAG_BOOLEAN);
693 static final HType STRING = const HType(FLAG_STRING);
694 static final HType READABLE_ARRAY = const HType(FLAG_READABLE_ARRAY);
695 static final HType MUTABLE_ARRAY =
696 const HType(FLAG_READABLE_ARRAY | FLAG_WRITEABLE_ARRAY);
697 static final HType INTEGER = const HType(FLAG_INTEGER);
698 static final HType DOUBLE = const HType(FLAG_DOUBLE);
699 static final HType STRING_OR_ARRAY =
700 const HType(FLAG_STRING | FLAG_READABLE_ARRAY | FLAG_WRITEABLE_ARRAY);
701 static final HType NUMBER = const HType(FLAG_DOUBLE | FLAG_INTEGER);
702
703 bool isConflicting() => this === CONFLICTING;
704 bool isUnknown() => this === UNKNOWN;
705 bool isBoolean() => this === BOOLEAN;
706 bool isInteger() => this === INTEGER;
707 bool isDouble() => this === DOUBLE;
708 bool isString() => this === STRING;
709 bool isArray() => (this.flag & FLAG_READABLE_ARRAY) != 0;
710 bool isMutableArray() => this === MUTABLE_ARRAY;
711 bool isNumber() => (this.flag & (FLAG_INTEGER | FLAG_DOUBLE)) != 0;
712 bool isStringOrArray() =>
713 (this.flag & (FLAG_STRING | FLAG_READABLE_ARRAY)) != 0;
714 bool isNonPrimitive() => this.flag === FLAG_NON_PRIMITIVE;
715 /** A type is useful it is not unknown and not conflicting. */
716 bool isUseful() => this !== UNKNOWN && this !== CONFLICTING;
717
718 static HType getTypeFromFlag(int flag) {
719 if (flag === CONFLICTING.flag) return CONFLICTING;
720 if (flag === UNKNOWN.flag) return UNKNOWN;
721 if (flag === BOOLEAN.flag) return BOOLEAN;
722 if (flag === INTEGER.flag) return INTEGER;
723 if (flag === DOUBLE.flag) return DOUBLE;
724 if (flag === STRING.flag) return STRING;
725 if (flag === READABLE_ARRAY.flag) return READABLE_ARRAY;
726 if (flag === MUTABLE_ARRAY.flag) return MUTABLE_ARRAY;
727 if (flag === NUMBER.flag) return NUMBER;
728 if (flag === STRING_OR_ARRAY.flag) return STRING_OR_ARRAY;
729 unreachable();
730 }
731
732 String toString() {
733 if (isConflicting()) return 'conflicting';
734 if (isUnknown()) return 'unknown';
735 if (isBoolean()) return 'boolean';
736 if (isInteger()) return 'integer';
737 if (isDouble()) return 'double';
738 if (isString()) return 'string';
739 if (isMutableArray()) return 'mutable array';
740 if (isArray()) return 'array';
741 if (isNumber()) return 'number';
742 if (isStringOrArray()) return 'string or array';
743 unreachable();
744 }
745
746 HType combine(HType other) {
747 if (isUnknown()) return other;
748 if (other.isUnknown()) return this;
749 return getTypeFromFlag(this.flag & other.flag);
750 }
751 }
752
753 class HNonPrimitiveType extends HType {
754 final Type type;
755
756 // TODO(ngeoffray): Add a HPrimitiveType to get rid of the flag.
757 const HNonPrimitiveType(Type this.type) : super(HType.FLAG_NON_PRIMITIVE);
758
759 HType combine(HType other) {
760 if (other.isNonPrimitive()) {
761 HNonPrimitiveType temp = other;
762 if (this.type === temp.type) return this;
763 }
764 if (other.isUnknown()) return this;
765 return HType.CONFLICTING;
766 }
767
768 String toString() => type.toString();
769 Element lookupMember(SourceString name) {
770 ClassElement classElement = type.element;
771 return classElement.lookupMember(name);
772 }
773 }
774
775 class HInstruction implements Hashable { 675 class HInstruction implements Hashable {
776 Element sourceElement; 676 Element sourceElement;
777 677
778 final int id; 678 final int id;
779 static int idCounter; 679 static int idCounter;
780 680
781 final List<HInstruction> inputs; 681 final List<HInstruction> inputs;
782 final List<HInstruction> usedBy; 682 final List<HInstruction> usedBy;
783 683
784 HBasicBlock block; 684 HBasicBlock block;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
817 void setAllSideEffects() { flags |= ((1 << FLAG_CHANGES_COUNT) - 1); } 717 void setAllSideEffects() { flags |= ((1 << FLAG_CHANGES_COUNT) - 1); }
818 void clearAllSideEffects() { flags &= ~((1 << FLAG_CHANGES_COUNT) - 1); } 718 void clearAllSideEffects() { flags &= ~((1 << FLAG_CHANGES_COUNT) - 1); }
819 719
820 bool useGvn() => getFlag(FLAG_USE_GVN); 720 bool useGvn() => getFlag(FLAG_USE_GVN);
821 void setUseGvn() { setFlag(FLAG_USE_GVN); } 721 void setUseGvn() { setFlag(FLAG_USE_GVN); }
822 // Does this node potentially affect control flow. 722 // Does this node potentially affect control flow.
823 bool isControlFlow() => false; 723 bool isControlFlow() => false;
824 724
825 // All isFunctions work on the propagated types. 725 // All isFunctions work on the propagated types.
826 bool isArray() => propagatedType.isArray(); 726 bool isArray() => propagatedType.isArray();
727 bool isReadableArray() => propagatedType.isReadableArray();
827 bool isMutableArray() => propagatedType.isMutableArray(); 728 bool isMutableArray() => propagatedType.isMutableArray();
729 bool isExtendableArray() => propagatedType.isExtendableArray();
828 bool isBoolean() => propagatedType.isBoolean(); 730 bool isBoolean() => propagatedType.isBoolean();
829 bool isInteger() => propagatedType.isInteger(); 731 bool isInteger() => propagatedType.isInteger();
830 bool isDouble() => propagatedType.isDouble(); 732 bool isDouble() => propagatedType.isDouble();
831 bool isNumber() => propagatedType.isNumber(); 733 bool isNumber() => propagatedType.isNumber();
832 bool isString() => propagatedType.isString(); 734 bool isString() => propagatedType.isString();
833 bool isTypeUnknown() => propagatedType.isUnknown(); 735 bool isTypeUnknown() => propagatedType.isUnknown();
834 bool isStringOrArray() => propagatedType.isStringOrArray(); 736 bool isIndexablePrimitive() => propagatedType.isIndexablePrimitive();
835 bool isNonPrimitive() => propagatedType.isNonPrimitive(); 737 bool isNonPrimitive() => propagatedType.isNonPrimitive();
836 738
837 /** 739 /**
838 * This is the type the instruction is guaranteed to have. It does not 740 * This is the type the instruction is guaranteed to have. It does not
839 * take any propagation into account. 741 * take any propagation into account.
840 */ 742 */
841 HType get guaranteedType() => HType.UNKNOWN; 743 HType get guaranteedType() => HType.UNKNOWN;
842 bool hasGuaranteedType() => !guaranteedType.isUnknown(); 744 bool hasGuaranteedType() => !guaranteedType.isUnknown();
843 745
844 /** 746 /**
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after
1214 List<HInstruction> inputs) 1116 List<HInstruction> inputs)
1215 : super(selector, inputs); 1117 : super(selector, inputs);
1216 toString() => 'invoke interceptor: ${element.name}'; 1118 toString() => 'invoke interceptor: ${element.name}';
1217 accept(HVisitor visitor) => visitor.visitInvokeInterceptor(this); 1119 accept(HVisitor visitor) => visitor.visitInvokeInterceptor(this);
1218 1120
1219 bool isLengthGetter() { 1121 bool isLengthGetter() {
1220 return getter && name == const SourceString('length'); 1122 return getter && name == const SourceString('length');
1221 } 1123 }
1222 1124
1223 bool isLengthGetterOnStringOrArray() { 1125 bool isLengthGetterOnStringOrArray() {
1224 return isLengthGetter() 1126 return isLengthGetter() && inputs[1].isIndexablePrimitive();
1225 && inputs[1].isStringOrArray();
1226 } 1127 }
1227 1128
1228 String get builtinJsName() { 1129 String get builtinJsName() {
1229 if (isLengthGetterOnStringOrArray()) { 1130 if (isLengthGetterOnStringOrArray()) {
1230 return 'length'; 1131 return 'length';
1231 } else if (name == const SourceString('add') 1132 } else if (name == const SourceString('add')
1232 && inputs[1].isMutableArray()) { 1133 && inputs[1].isExtendableArray()) {
1233 return 'push'; 1134 return 'push';
1234 } else if (name == const SourceString('removeLast') 1135 } else if (name == const SourceString('removeLast')
1235 && inputs[1].isMutableArray()) { 1136 && inputs[1].isExtendableArray()) {
1236 return 'pop'; 1137 return 'pop';
1237 } 1138 }
1238 return null; 1139 return null;
1239 } 1140 }
1240 1141
1241 HType get guaranteedType() => HType.UNKNOWN; 1142 HType get guaranteedType() => HType.UNKNOWN;
1242 1143
1243 HType get likelyType() { 1144 HType get likelyType() {
1244 // In general a length getter or method returns an int. 1145 // In general a length getter or method returns an int.
1245 if (name == const SourceString('length')) return HType.INTEGER; 1146 if (name == const SourceString('length')) return HType.INTEGER;
1246 return HType.UNKNOWN; 1147 return HType.UNKNOWN;
1247 } 1148 }
1248 1149
1249 HType computeTypeFromInputTypes() { 1150 HType computeTypeFromInputTypes() {
1250 if (isLengthGetterOnStringOrArray()) return HType.INTEGER; 1151 if (isLengthGetterOnStringOrArray()) return HType.INTEGER;
1251 return HType.UNKNOWN; 1152 return HType.UNKNOWN;
1252 } 1153 }
1253 1154
1254 HType computeDesiredTypeForNonTargetInput(HInstruction input) { 1155 HType computeDesiredTypeForNonTargetInput(HInstruction input) {
1255 // If the first argument is a string or an array and we invoke methods 1156 // If the first argument is a string or an array and we invoke methods
1256 // on it that mutate it, then we want to restrict the incoming type to be 1157 // on it that mutate it, then we want to restrict the incoming type to be
1257 // a mutable array. 1158 // a mutable array.
1258 if (input == inputs[1] && input.isStringOrArray()) { 1159 if (input == inputs[1] && input.isIndexablePrimitive()) {
1259 if (name == const SourceString('add') 1160 if (name == const SourceString('add')
1260 || name == const SourceString('removeLast')) { 1161 || name == const SourceString('removeLast')) {
1261 return HType.MUTABLE_ARRAY; 1162 return HType.MUTABLE_ARRAY;
1262 } 1163 }
1263 } 1164 }
1264 return HType.UNKNOWN; 1165 return HType.UNKNOWN;
1265 } 1166 }
1266 1167
1267 void prepareGvn() { 1168 void prepareGvn() {
1268 if (isLengthGetterOnStringOrArray()) { 1169 if (isLengthGetterOnStringOrArray()) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1310 final DartString code; 1211 final DartString code;
1311 final HType foreignType; 1212 final HType foreignType;
1312 HForeign(this.code, DartString declaredType, List<HInstruction> inputs) 1213 HForeign(this.code, DartString declaredType, List<HInstruction> inputs)
1313 : foreignType = computeTypeFromDeclaredType(declaredType), 1214 : foreignType = computeTypeFromDeclaredType(declaredType),
1314 super(inputs); 1215 super(inputs);
1315 accept(HVisitor visitor) => visitor.visitForeign(this); 1216 accept(HVisitor visitor) => visitor.visitForeign(this);
1316 1217
1317 static HType computeTypeFromDeclaredType(DartString declaredType) { 1218 static HType computeTypeFromDeclaredType(DartString declaredType) {
1318 if (declaredType.slowToString() == 'bool') return HType.BOOLEAN; 1219 if (declaredType.slowToString() == 'bool') return HType.BOOLEAN;
1319 if (declaredType.slowToString() == 'int') return HType.INTEGER; 1220 if (declaredType.slowToString() == 'int') return HType.INTEGER;
1221 if (declaredType.slowToString() == 'double') return HType.DOUBLE;
1320 if (declaredType.slowToString() == 'num') return HType.NUMBER; 1222 if (declaredType.slowToString() == 'num') return HType.NUMBER;
1321 if (declaredType.slowToString() == 'String') return HType.STRING; 1223 if (declaredType.slowToString() == 'String') return HType.STRING;
1322 return HType.UNKNOWN; 1224 return HType.UNKNOWN;
1323 } 1225 }
1324 1226
1325 HType get guaranteedType() => foreignType; 1227 HType get guaranteedType() => foreignType;
1326 } 1228 }
1327 1229
1328 class HForeignNew extends HForeign { 1230 class HForeignNew extends HForeign {
1329 ClassElement element; 1231 ClassElement element;
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after
1860 // different known types, we'll return a conflict -- otherwise we'll 1762 // different known types, we'll return a conflict -- otherwise we'll
1861 // simply return an unknown type. 1763 // simply return an unknown type.
1862 HType computeInputsType(bool unknownWins) { 1764 HType computeInputsType(bool unknownWins) {
1863 HType candidateType = inputs[0].propagatedType; 1765 HType candidateType = inputs[0].propagatedType;
1864 bool seenUnknown = candidateType.isUnknown(); 1766 bool seenUnknown = candidateType.isUnknown();
1865 for (int i = 1, length = inputs.length; i < length; i++) { 1767 for (int i = 1, length = inputs.length; i < length; i++) {
1866 HType inputType = inputs[i].propagatedType; 1768 HType inputType = inputs[i].propagatedType;
1867 if (inputType.isUnknown()) { 1769 if (inputType.isUnknown()) {
1868 seenUnknown = true; 1770 seenUnknown = true;
1869 } else { 1771 } else {
1870 candidateType = candidateType.combine(inputType); 1772 // Phis need to combine the incoming types using the union operation.
1773 // For example, if one incoming edge has type integer and the other has
1774 // type double, then the phi is either an integer or double and thus has
1775 // type number.
1776 candidateType = candidateType.union(inputType);
1871 if (candidateType.isConflicting()) return HType.CONFLICTING; 1777 if (candidateType.isConflicting()) return HType.CONFLICTING;
1872 } 1778 }
1873 } 1779 }
1874 if (seenUnknown && unknownWins) return HType.UNKNOWN; 1780 if (seenUnknown && unknownWins) return HType.UNKNOWN;
1875 return candidateType; 1781 return candidateType;
1876 } 1782 }
1877 1783
1878 HType computeTypeFromInputTypes() { 1784 HType computeTypeFromInputTypes() {
1879 HType inputsType = computeInputsType(true); 1785 HType inputsType = computeInputsType(true);
1880 if (inputsType.isConflicting()) return HType.UNKNOWN; 1786 if (inputsType.isConflicting()) return HType.UNKNOWN;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1935 HType computeTypeFromInputTypes() { 1841 HType computeTypeFromInputTypes() {
1936 if (left.isNumber()) return HType.BOOLEAN; 1842 if (left.isNumber()) return HType.BOOLEAN;
1937 return HType.UNKNOWN; 1843 return HType.UNKNOWN;
1938 } 1844 }
1939 1845
1940 HType computeDesiredTypeForNonTargetInput(HInstruction input) { 1846 HType computeDesiredTypeForNonTargetInput(HInstruction input) {
1941 // For all relational operations exept HEquals, we expect to get numbers 1847 // For all relational operations exept HEquals, we expect to get numbers
1942 // only. With numbers the outgoing type is a boolean. If something else 1848 // only. With numbers the outgoing type is a boolean. If something else
1943 // is desired, then numbers are incorrect, though. 1849 // is desired, then numbers are incorrect, though.
1944 if (propagatedType.isUnknown() || propagatedType.isBoolean()) { 1850 if (propagatedType.isUnknown() || propagatedType.isBoolean()) {
1945 if (left.isTypeUnknown() || left.isNumber()) return HType.NUMBER; 1851 if (left.isTypeUnknown() || left.isNumber()) {
1852 return HType.NUMBER;
1853 }
1946 } 1854 }
1947 return HType.UNKNOWN; 1855 return HType.UNKNOWN;
1948 } 1856 }
1949 1857
1950 HType get likelyType() => HType.BOOLEAN; 1858 HType get likelyType() => HType.BOOLEAN;
1951 1859
1952 bool get builtin() => left.isNumber() && right.isNumber(); 1860 bool get builtin() => left.isNumber() && right.isNumber();
1953 // TODO(1603): the class should be marked as abstract. 1861 // TODO(1603): the class should be marked as abstract.
1954 abstract BinaryOperation get operation(); 1862 abstract BinaryOperation get operation();
1955 } 1863 }
(...skipping 14 matching lines...) Expand all
1970 if (builtin) return HType.BOOLEAN; 1878 if (builtin) return HType.BOOLEAN;
1971 return HType.UNKNOWN; 1879 return HType.UNKNOWN;
1972 } 1880 }
1973 1881
1974 HType computeDesiredTypeForNonTargetInput(HInstruction input) { 1882 HType computeDesiredTypeForNonTargetInput(HInstruction input) {
1975 if (input == left && right.propagatedType.isUseful()) { 1883 if (input == left && right.propagatedType.isUseful()) {
1976 // All our useful types have === semantics. But we don't want to 1884 // All our useful types have === semantics. But we don't want to
1977 // speculatively test for all possible types. Therefore we try to match 1885 // speculatively test for all possible types. Therefore we try to match
1978 // the two types. That is, if we see x == 3, then we speculatively test 1886 // the two types. That is, if we see x == 3, then we speculatively test
1979 // if x is a number and bailout if it isn't. 1887 // if x is a number and bailout if it isn't.
1980 if (right.isNumber()) return HType.NUMBER; // No need to be more precise. 1888 // If right is a number we don't need more than a number (no need to match
1889 // the exact type of right).
1890 if (right.isNumber()) return HType.NUMBER;
1981 // String equality testing is much more common than array equality 1891 // String equality testing is much more common than array equality
1982 // testing. 1892 // testing.
1983 if (right.isStringOrArray()) return HType.STRING; 1893 if (right.isIndexablePrimitive()) return HType.STRING;
1984 return right.propagatedType; 1894 return right.propagatedType;
1985 } 1895 }
1986 // String equality testing is much more common than array equality testing. 1896 // String equality testing is much more common than array equality testing.
1987 if (input == left && left.isStringOrArray()) { 1897 if (input == left && left.isIndexablePrimitive()) {
1988 return HType.READABLE_ARRAY; 1898 return HType.READABLE_ARRAY;
1989 } 1899 }
1990 // String equality testing is much more common than array equality testing. 1900 // String equality testing is much more common than array equality testing.
1991 if (input == right && right.isStringOrArray()) { 1901 if (input == right && right.isIndexablePrimitive()) {
1992 return HType.STRING; 1902 return HType.STRING;
1993 } 1903 }
1994 return HType.UNKNOWN; 1904 return HType.UNKNOWN;
1995 } 1905 }
1996 1906
1997 EqualsOperation get operation() => const EqualsOperation(); 1907 EqualsOperation get operation() => const EqualsOperation();
1998 int typeCode() => 19; 1908 int typeCode() => 19;
1999 bool typeEquals(other) => other is HEquals; 1909 bool typeEquals(other) => other is HEquals;
2000 bool dataEquals(HInstruction other) => true; 1910 bool dataEquals(HInstruction other) => true;
2001 } 1911 }
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
2130 } else { 2040 } else {
2131 setAllSideEffects(); 2041 setAllSideEffects();
2132 } 2042 }
2133 } 2043 }
2134 2044
2135 HInstruction get receiver() => inputs[1]; 2045 HInstruction get receiver() => inputs[1];
2136 HInstruction get index() => inputs[2]; 2046 HInstruction get index() => inputs[2];
2137 2047
2138 HType computeDesiredTypeForNonTargetInput(HInstruction input) { 2048 HType computeDesiredTypeForNonTargetInput(HInstruction input) {
2139 if (input == receiver && (index.isTypeUnknown() || index.isNumber())) { 2049 if (input == receiver && (index.isTypeUnknown() || index.isNumber())) {
2140 return HType.STRING_OR_ARRAY; 2050 return HType.INDEXABLE_PRIMITIVE;
2141 } 2051 }
2142 // The index should be an int when the receiver is a string or array. 2052 // The index should be an int when the receiver is a string or array.
2143 // However it turns out that inserting an integer check in the optimized 2053 // However it turns out that inserting an integer check in the optimized
2144 // version is cheaper than having another bailout case. This is true, 2054 // version is cheaper than having another bailout case. This is true,
2145 // because the integer check will simply throw if it fails. 2055 // because the integer check will simply throw if it fails.
2146 return HType.UNKNOWN; 2056 return HType.UNKNOWN;
2147 } 2057 }
2148 2058
2149 bool get builtin() => receiver.isStringOrArray() && index.isInteger(); 2059 bool get builtin() => receiver.isIndexablePrimitive() && index.isInteger();
2150 } 2060 }
2151 2061
2152 class HIndexAssign extends HInvokeStatic { 2062 class HIndexAssign extends HInvokeStatic {
2153 HIndexAssign(HStatic target, 2063 HIndexAssign(HStatic target,
2154 HInstruction receiver, 2064 HInstruction receiver,
2155 HInstruction index, 2065 HInstruction index,
2156 HInstruction value) 2066 HInstruction value)
2157 : super(Selector.INDEX_SET, 2067 : super(Selector.INDEX_SET,
2158 <HInstruction>[target, receiver, index, value]); 2068 <HInstruction>[target, receiver, index, value]);
2159 toString() => 'index assign operator'; 2069 toString() => 'index assign operator';
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
2322 final bool isAnd; 2232 final bool isAnd;
2323 final SubExpression left; 2233 final SubExpression left;
2324 final SubExpression right; 2234 final SubExpression right;
2325 final HBasicBlock joinBlock; 2235 final HBasicBlock joinBlock;
2326 HAndOrBlockInformation(this.isAnd, 2236 HAndOrBlockInformation(this.isAnd,
2327 this.left, 2237 this.left,
2328 this.right, 2238 this.right,
2329 this.joinBlock); 2239 this.joinBlock);
2330 bool accept(HBlockInformationVisitor visitor) => visitor.visitAndOrInfo(this); 2240 bool accept(HBlockInformationVisitor visitor) => visitor.visitAndOrInfo(this);
2331 } 2241 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/ssa/codegen.dart ('k') | lib/compiler/implementation/ssa/optimize.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698