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

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

Issue 10119010: Start propagating non-primitive types in the backend, and fold instructions that know about the typ… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 8 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 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 return result; 147 return result;
148 } 148 }
149 149
150 static HType mapConstantTypeToSsaType(Constant constant) { 150 static HType mapConstantTypeToSsaType(Constant constant) {
151 if (constant.isNull()) return HType.UNKNOWN; 151 if (constant.isNull()) return HType.UNKNOWN;
152 if (constant.isBool()) return HType.BOOLEAN; 152 if (constant.isBool()) return HType.BOOLEAN;
153 if (constant.isInt()) return HType.INTEGER; 153 if (constant.isInt()) return HType.INTEGER;
154 if (constant.isDouble()) return HType.DOUBLE; 154 if (constant.isDouble()) return HType.DOUBLE;
155 if (constant.isString()) return HType.STRING; 155 if (constant.isString()) return HType.STRING;
156 if (constant.isList()) return HType.READABLE_ARRAY; 156 if (constant.isList()) return HType.READABLE_ARRAY;
157 if (constant.isMap()) {
158 MapConstant map = constant;
159 return new HNonPrimitiveType(map.type);
160 }
157 return HType.UNKNOWN; 161 return HType.UNKNOWN;
158 } 162 }
159 163
160 HConstant addConstant(Constant constant) { 164 HConstant addConstant(Constant constant) {
161 HConstant result = constants[constant]; 165 HConstant result = constants[constant];
162 if (result === null) { 166 if (result === null) {
163 HType type = mapConstantTypeToSsaType(constant); 167 HType type = mapConstantTypeToSsaType(constant);
164 result = new HConstant.internal(constant, type); 168 result = new HConstant.internal(constant, type);
165 entry.addAtExit(result); 169 entry.addAtExit(result);
166 constants[constant] = result; 170 constants[constant] = result;
(...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 667
664 static final int FLAG_CONFLICTING = 0; 668 static final int FLAG_CONFLICTING = 0;
665 static final int FLAG_UNKNOWN = 1; 669 static final int FLAG_UNKNOWN = 1;
666 static final int FLAG_BOOLEAN = FLAG_UNKNOWN << 1; 670 static final int FLAG_BOOLEAN = FLAG_UNKNOWN << 1;
667 static final int FLAG_INTEGER = FLAG_BOOLEAN << 1; 671 static final int FLAG_INTEGER = FLAG_BOOLEAN << 1;
668 static final int FLAG_STRING = FLAG_INTEGER << 1; 672 static final int FLAG_STRING = FLAG_INTEGER << 1;
669 static final int FLAG_READABLE_ARRAY = FLAG_STRING << 1; 673 static final int FLAG_READABLE_ARRAY = FLAG_STRING << 1;
670 // FLAG_WRITABLE_ARRAY implies FLAG_READABLE_ARRAY. 674 // FLAG_WRITABLE_ARRAY implies FLAG_READABLE_ARRAY.
671 static final int FLAG_WRITEABLE_ARRAY = FLAG_READABLE_ARRAY << 1; 675 static final int FLAG_WRITEABLE_ARRAY = FLAG_READABLE_ARRAY << 1;
672 static final int FLAG_DOUBLE = FLAG_WRITEABLE_ARRAY << 1; 676 static final int FLAG_DOUBLE = FLAG_WRITEABLE_ARRAY << 1;
677 static final int FLAG_NON_PRIMITIVE = FLAG_DOUBLE << 1;
673 678
674 static final HType CONFLICTING = const HType(FLAG_CONFLICTING); 679 static final HType CONFLICTING = const HType(FLAG_CONFLICTING);
675 static final HType UNKNOWN = const HType(FLAG_UNKNOWN); 680 static final HType UNKNOWN = const HType(FLAG_UNKNOWN);
676 static final HType BOOLEAN = const HType(FLAG_BOOLEAN); 681 static final HType BOOLEAN = const HType(FLAG_BOOLEAN);
677 static final HType STRING = const HType(FLAG_STRING); 682 static final HType STRING = const HType(FLAG_STRING);
678 static final HType READABLE_ARRAY = const HType(FLAG_READABLE_ARRAY); 683 static final HType READABLE_ARRAY = const HType(FLAG_READABLE_ARRAY);
679 static final HType MUTABLE_ARRAY = 684 static final HType MUTABLE_ARRAY =
680 const HType(FLAG_READABLE_ARRAY | FLAG_WRITEABLE_ARRAY); 685 const HType(FLAG_READABLE_ARRAY | FLAG_WRITEABLE_ARRAY);
681 static final HType INTEGER = const HType(FLAG_INTEGER); 686 static final HType INTEGER = const HType(FLAG_INTEGER);
682 static final HType DOUBLE = const HType(FLAG_DOUBLE); 687 static final HType DOUBLE = const HType(FLAG_DOUBLE);
683 static final HType STRING_OR_ARRAY = 688 static final HType STRING_OR_ARRAY =
684 const HType(FLAG_STRING | FLAG_READABLE_ARRAY | FLAG_WRITEABLE_ARRAY); 689 const HType(FLAG_STRING | FLAG_READABLE_ARRAY | FLAG_WRITEABLE_ARRAY);
685 static final HType NUMBER = const HType(FLAG_DOUBLE | FLAG_INTEGER); 690 static final HType NUMBER = const HType(FLAG_DOUBLE | FLAG_INTEGER);
686 691
687 bool isConflicting() => this === CONFLICTING; 692 bool isConflicting() => this === CONFLICTING;
688 bool isUnknown() => this === UNKNOWN; 693 bool isUnknown() => this === UNKNOWN;
689 bool isBoolean() => this === BOOLEAN; 694 bool isBoolean() => this === BOOLEAN;
690 bool isInteger() => this === INTEGER; 695 bool isInteger() => this === INTEGER;
691 bool isDouble() => this === DOUBLE; 696 bool isDouble() => this === DOUBLE;
692 bool isString() => this === STRING; 697 bool isString() => this === STRING;
693 bool isArray() => (this.flag & FLAG_READABLE_ARRAY) != 0; 698 bool isArray() => (this.flag & FLAG_READABLE_ARRAY) != 0;
694 bool isMutableArray() => this === MUTABLE_ARRAY; 699 bool isMutableArray() => this === MUTABLE_ARRAY;
695 bool isNumber() => (this.flag & (FLAG_INTEGER | FLAG_DOUBLE)) != 0; 700 bool isNumber() => (this.flag & (FLAG_INTEGER | FLAG_DOUBLE)) != 0;
696 bool isStringOrArray() => 701 bool isStringOrArray() =>
697 (this.flag & (FLAG_STRING | FLAG_READABLE_ARRAY)) != 0; 702 (this.flag & (FLAG_STRING | FLAG_READABLE_ARRAY)) != 0;
703 bool isNonPrimitive() => this.flag === FLAG_NON_PRIMITIVE;
698 /** A type is useful it is not unknown and not conflicting. */ 704 /** A type is useful it is not unknown and not conflicting. */
699 bool isUseful() => this !== UNKNOWN && this !== CONFLICTING; 705 bool isUseful() => this !== UNKNOWN && this !== CONFLICTING;
700 706
701 static HType getTypeFromFlag(int flag) { 707 static HType getTypeFromFlag(int flag) {
702 if (flag === CONFLICTING.flag) return CONFLICTING; 708 if (flag === CONFLICTING.flag) return CONFLICTING;
703 if (flag === UNKNOWN.flag) return UNKNOWN; 709 if (flag === UNKNOWN.flag) return UNKNOWN;
704 if (flag === BOOLEAN.flag) return BOOLEAN; 710 if (flag === BOOLEAN.flag) return BOOLEAN;
705 if (flag === INTEGER.flag) return INTEGER; 711 if (flag === INTEGER.flag) return INTEGER;
706 if (flag === DOUBLE.flag) return DOUBLE; 712 if (flag === DOUBLE.flag) return DOUBLE;
707 if (flag === STRING.flag) return STRING; 713 if (flag === STRING.flag) return STRING;
708 if (flag === READABLE_ARRAY.flag) return READABLE_ARRAY; 714 if (flag === READABLE_ARRAY.flag) return READABLE_ARRAY;
709 if (flag === MUTABLE_ARRAY.flag) return MUTABLE_ARRAY; 715 if (flag === MUTABLE_ARRAY.flag) return MUTABLE_ARRAY;
710 if (flag === NUMBER.flag) return NUMBER; 716 if (flag === NUMBER.flag) return NUMBER;
711 if (flag === STRING_OR_ARRAY.flag) return STRING_OR_ARRAY; 717 if (flag === STRING_OR_ARRAY.flag) return STRING_OR_ARRAY;
712 assert(false); 718 unreachable();
713 } 719 }
714 720
715 String toString() { 721 String toString() {
716 if (isConflicting()) return 'conflicting'; 722 if (isConflicting()) return 'conflicting';
717 if (isUnknown()) return 'unknown'; 723 if (isUnknown()) return 'unknown';
718 if (isBoolean()) return 'boolean'; 724 if (isBoolean()) return 'boolean';
719 if (isInteger()) return 'integer'; 725 if (isInteger()) return 'integer';
720 if (isDouble()) return 'double'; 726 if (isDouble()) return 'double';
721 if (isString()) return 'string'; 727 if (isString()) return 'string';
722 if (isMutableArray()) return 'mutable array'; 728 if (isMutableArray()) return 'mutable array';
723 if (isArray()) return 'array'; 729 if (isArray()) return 'array';
724 if (isNumber()) return 'number'; 730 if (isNumber()) return 'number';
725 if (isStringOrArray()) return 'string or array'; 731 if (isStringOrArray()) return 'string or array';
726 unreachable(); 732 unreachable();
727 } 733 }
728 734
729 HType combine(HType other) { 735 HType combine(HType other) {
730 if (isUnknown()) return other; 736 if (isUnknown()) return other;
731 if (other.isUnknown()) return this; 737 if (other.isUnknown()) return this;
732 return getTypeFromFlag(this.flag & other.flag); 738 return getTypeFromFlag(this.flag & other.flag);
733 } 739 }
734 } 740 }
735 741
742 class HNonPrimitiveType extends HType {
743 final Type type;
744
745 // TODO(ngeoffray): Add a HPrimitiveType to get rid of the flag.
746 const HNonPrimitiveType(Type this.type) : super(HType.FLAG_NON_PRIMITIVE);
747
748 HType combine(HType other) {
749 if (other.isNonPrimitive()) {
750 HNonPrimitiveType temp = other;
751 if (this.type === temp.type) return this;
752 }
753 if (other.isUnknown()) return this;
754 return CONFLICTING;
755 }
756
757 String toString() => type.toString();
758 Element lookupMember(SourceString name) => type.element.lookupMember(name);
759 }
760
736 class HInstruction implements Hashable { 761 class HInstruction implements Hashable {
737 Element sourceElement; 762 Element sourceElement;
738 763
739 final int id; 764 final int id;
740 static int idCounter; 765 static int idCounter;
741 766
742 final List<HInstruction> inputs; 767 final List<HInstruction> inputs;
743 final List<HInstruction> usedBy; 768 final List<HInstruction> usedBy;
744 769
745 HBasicBlock block; 770 HBasicBlock block;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
786 // All isFunctions work on the propagated types. 811 // All isFunctions work on the propagated types.
787 bool isArray() => propagatedType.isArray(); 812 bool isArray() => propagatedType.isArray();
788 bool isMutableArray() => propagatedType.isMutableArray(); 813 bool isMutableArray() => propagatedType.isMutableArray();
789 bool isBoolean() => propagatedType.isBoolean(); 814 bool isBoolean() => propagatedType.isBoolean();
790 bool isInteger() => propagatedType.isInteger(); 815 bool isInteger() => propagatedType.isInteger();
791 bool isDouble() => propagatedType.isDouble(); 816 bool isDouble() => propagatedType.isDouble();
792 bool isNumber() => propagatedType.isNumber(); 817 bool isNumber() => propagatedType.isNumber();
793 bool isString() => propagatedType.isString(); 818 bool isString() => propagatedType.isString();
794 bool isTypeUnknown() => propagatedType.isUnknown(); 819 bool isTypeUnknown() => propagatedType.isUnknown();
795 bool isStringOrArray() => propagatedType.isStringOrArray(); 820 bool isStringOrArray() => propagatedType.isStringOrArray();
821 bool isNonPrimitive() => propagatedType.isNonPrimitive();
796 822
797 /** 823 /**
798 * This is the type the instruction is guaranteed to have. It does not 824 * This is the type the instruction is guaranteed to have. It does not
799 * take any propagation into account. 825 * take any propagation into account.
800 */ 826 */
801 HType get guaranteedType() => HType.UNKNOWN; 827 HType get guaranteedType() => HType.UNKNOWN;
802 bool hasGuaranteedType() => !guaranteedType.isUnknown(); 828 bool hasGuaranteedType() => !guaranteedType.isUnknown();
803 829
804 /** 830 /**
805 * The [propagatedType] is the type the instruction is assumed to have. 831 * The [propagatedType] is the type the instruction is assumed to have.
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
928 } 954 }
929 } 955 }
930 this.block = null; 956 this.block = null;
931 assert(isValid()); 957 assert(isValid());
932 } 958 }
933 959
934 bool isConstant() => false; 960 bool isConstant() => false;
935 bool isConstantNull() => false; 961 bool isConstantNull() => false;
936 bool isConstantNumber() => false; 962 bool isConstantNumber() => false;
937 bool isConstantString() => false; 963 bool isConstantString() => false;
964 bool isConstantList() => false;
965 bool isConstantMap() => false;
938 966
939 bool isValid() { 967 bool isValid() {
940 HValidator validator = new HValidator(); 968 HValidator validator = new HValidator();
941 validator.currentBlock = block; 969 validator.currentBlock = block;
942 validator.visitInstruction(this); 970 validator.visitInstruction(this);
943 return validator.isValid; 971 return validator.isValid;
944 } 972 }
945 973
946 /** 974 /**
947 * The code for computing a bailout environment, and the code 975 * The code for computing a bailout environment, and the code
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1061 */ 1089 */
1062 final Selector selector; 1090 final Selector selector;
1063 HInvoke(Selector this.selector, List<HInstruction> inputs) : super(inputs); 1091 HInvoke(Selector this.selector, List<HInstruction> inputs) : super(inputs);
1064 static final int ARGUMENTS_OFFSET = 1; 1092 static final int ARGUMENTS_OFFSET = 1;
1065 1093
1066 // TODO(floitsch): make class abstract instead of adding an abstract method. 1094 // TODO(floitsch): make class abstract instead of adding an abstract method.
1067 abstract accept(HVisitor visitor); 1095 abstract accept(HVisitor visitor);
1068 } 1096 }
1069 1097
1070 class HInvokeDynamic extends HInvoke { 1098 class HInvokeDynamic extends HInvoke {
1099 Element element;
1071 SourceString name; 1100 SourceString name;
1072 HInvokeDynamic(Selector selector, this.name, List<HInstruction> inputs) 1101 HInvokeDynamic(
1073 : super(selector, inputs); 1102 Selector selector, this.element, this.name, List<HInstruction> inputs)
1103 : super(selector, inputs);
1074 toString() => 'invoke dynamic: $name'; 1104 toString() => 'invoke dynamic: $name';
1075 HInstruction get receiver() => inputs[0]; 1105 HInstruction get receiver() => inputs[0];
1076 1106
1077 // TODO(floitsch): make class abstract instead of adding an abstract method. 1107 // TODO(floitsch): make class abstract instead of adding an abstract method.
1078 abstract accept(HVisitor visitor); 1108 abstract accept(HVisitor visitor);
1079 } 1109 }
1080 1110
1081 class HInvokeClosure extends HInvokeDynamic { 1111 class HInvokeClosure extends HInvokeDynamic {
1082 Element element;
1083 HInvokeClosure(Selector selector, List<HInstruction> inputs) 1112 HInvokeClosure(Selector selector, List<HInstruction> inputs)
1084 : super(selector, const SourceString('call'), inputs); 1113 : super(selector, null, const SourceString('call'), inputs);
1085 accept(HVisitor visitor) => visitor.visitInvokeClosure(this); 1114 accept(HVisitor visitor) => visitor.visitInvokeClosure(this);
1086 } 1115 }
1087 1116
1088 class HInvokeDynamicMethod extends HInvokeDynamic { 1117 class HInvokeDynamicMethod extends HInvokeDynamic {
1089 HInvokeDynamicMethod(Selector selector, 1118 HInvokeDynamicMethod(Selector selector,
1090 SourceString methodName, 1119 SourceString methodName,
1091 List<HInstruction> inputs) 1120 List<HInstruction> inputs)
1092 : super(selector, methodName, inputs); 1121 : super(selector, null, methodName, inputs);
1093 toString() => 'invoke dynamic method: $name'; 1122 toString() => 'invoke dynamic method: $name';
1094 accept(HVisitor visitor) => visitor.visitInvokeDynamicMethod(this); 1123 accept(HVisitor visitor) => visitor.visitInvokeDynamicMethod(this);
1095 } 1124 }
1096 1125
1097 class HInvokeDynamicField extends HInvokeDynamic { 1126 class HInvokeDynamicField extends HInvokeDynamic {
1098 Element element;
1099 HInvokeDynamicField(Selector selector, 1127 HInvokeDynamicField(Selector selector,
1100 Element this.element, 1128 Element element,
1101 SourceString name, 1129 SourceString name,
1102 List<HInstruction>inputs) 1130 List<HInstruction>inputs)
1103 : super(selector, name, inputs); 1131 : super(selector, element, name, inputs);
1104 toString() => 'invoke dynamic field: $name'; 1132 toString() => 'invoke dynamic field: $name';
1105 1133
1106 // TODO(floitsch): make class abstract instead of adding an abstract method. 1134 // TODO(floitsch): make class abstract instead of adding an abstract method.
1107 abstract accept(HVisitor visitor); 1135 abstract accept(HVisitor visitor);
1108 } 1136 }
1109 1137
1110 class HInvokeDynamicGetter extends HInvokeDynamicField { 1138 class HInvokeDynamicGetter extends HInvokeDynamicField {
1111 HInvokeDynamicGetter(selector, element, name, receiver) 1139 HInvokeDynamicGetter(selector, element, name, receiver)
1112 : super(selector, element, name, [receiver]); 1140 : super(selector, element, name, [receiver]);
1113 toString() => 'invoke dynamic getter: $name'; 1141 toString() => 'invoke dynamic getter: $name';
1114 accept(HVisitor visitor) => visitor.visitInvokeDynamicGetter(this); 1142 accept(HVisitor visitor) => visitor.visitInvokeDynamicGetter(this);
1115 } 1143 }
1116 1144
1117 class HInvokeDynamicSetter extends HInvokeDynamicField { 1145 class HInvokeDynamicSetter extends HInvokeDynamicField {
1118 HInvokeDynamicSetter(selector, element, name, receiver, value) 1146 HInvokeDynamicSetter(selector, element, name, receiver, value)
1119 : super(selector, element, name, [receiver, value]); 1147 : super(selector, element, name, [receiver, value]);
1120 toString() => 'invoke dynamic setter: $name'; 1148 toString() => 'invoke dynamic setter: $name';
1121 accept(HVisitor visitor) => visitor.visitInvokeDynamicSetter(this); 1149 accept(HVisitor visitor) => visitor.visitInvokeDynamicSetter(this);
1122 } 1150 }
1123 1151
1124 class HInvokeStatic extends HInvoke { 1152 class HInvokeStatic extends HInvoke {
1153 final HType concreteType;
1125 /** The first input must be the target. */ 1154 /** The first input must be the target. */
1126 HInvokeStatic(selector, inputs) : super(selector, inputs); 1155 HInvokeStatic(selector, inputs, [this.concreteType = HType.UNKNOWN])
1156 : super(selector, inputs);
1127 toString() => 'invoke static: ${element.name}'; 1157 toString() => 'invoke static: ${element.name}';
1128 accept(HVisitor visitor) => visitor.visitInvokeStatic(this); 1158 accept(HVisitor visitor) => visitor.visitInvokeStatic(this);
1129 Element get element() => target.element; 1159 Element get element() => target.element;
1130 HStatic get target() => inputs[0]; 1160 HStatic get target() => inputs[0];
1131 1161
1132 bool isArrayConstructor() { 1162 HType get guaranteedType() => concreteType;
1133 // TODO(ngeoffray): This is not the right way to do the check,
1134 // nor the right place. We need to move it to a phase.
1135 return (element.isFactoryConstructor()
1136 && element.enclosingElement.name.slowToString() == 'List');
1137 }
1138
1139 HType get guaranteedType() {
1140 if (isArrayConstructor()) {
1141 return HType.MUTABLE_ARRAY;
1142 }
1143 return HType.UNKNOWN;
1144 }
1145 1163
1146 HType computeDesiredTypeForInput(HInstruction input) { 1164 HType computeDesiredTypeForInput(HInstruction input) {
1147 // TODO(floitsch): we want the target to be a function. 1165 // TODO(floitsch): we want the target to be a function.
1148 if (input == target) return HType.UNKNOWN; 1166 if (input == target) return HType.UNKNOWN;
1149 return computeDesiredTypeForNonTargetInput(input); 1167 return computeDesiredTypeForNonTargetInput(input);
1150 } 1168 }
1151 1169
1152 HType computeDesiredTypeForNonTargetInput(HInstruction input) { 1170 HType computeDesiredTypeForNonTargetInput(HInstruction input) {
1153 return HType.UNKNOWN; 1171 return HType.UNKNOWN;
1154 } 1172 }
(...skipping 12 matching lines...) Expand all
1167 final bool getter; 1185 final bool getter;
1168 1186
1169 HInvokeInterceptor(Selector selector, 1187 HInvokeInterceptor(Selector selector,
1170 SourceString this.name, 1188 SourceString this.name,
1171 bool this.getter, 1189 bool this.getter,
1172 List<HInstruction> inputs) 1190 List<HInstruction> inputs)
1173 : super(selector, inputs); 1191 : super(selector, inputs);
1174 toString() => 'invoke interceptor: ${element.name}'; 1192 toString() => 'invoke interceptor: ${element.name}';
1175 accept(HVisitor visitor) => visitor.visitInvokeInterceptor(this); 1193 accept(HVisitor visitor) => visitor.visitInvokeInterceptor(this);
1176 1194
1195 bool isLengthGetter() {
1196 return getter && name == const SourceString('length');
1197 }
1198
1177 bool isLengthGetterOnStringOrArray() { 1199 bool isLengthGetterOnStringOrArray() {
1178 return getter 1200 return isLengthGetter()
1179 && name == const SourceString('length')
1180 && inputs[1].isStringOrArray(); 1201 && inputs[1].isStringOrArray();
1181 } 1202 }
1182 1203
1183 String get builtinJsName() { 1204 String get builtinJsName() {
1184 if (isLengthGetterOnStringOrArray()) { 1205 if (isLengthGetterOnStringOrArray()) {
1185 return 'length'; 1206 return 'length';
1186 } else if (name == const SourceString('add') 1207 } else if (name == const SourceString('add')
1187 && inputs[1].isMutableArray()) { 1208 && inputs[1].isMutableArray()) {
1188 return 'push'; 1209 return 'push';
1189 } else if (name == const SourceString('removeLast') 1210 } else if (name == const SourceString('removeLast')
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after
1733 toString() => 'literal: $constant'; 1754 toString() => 'literal: $constant';
1734 accept(HVisitor visitor) => visitor.visitConstant(this); 1755 accept(HVisitor visitor) => visitor.visitConstant(this);
1735 1756
1736 HType get guaranteedType() => constantType; 1757 HType get guaranteedType() => constantType;
1737 1758
1738 bool isConstant() => true; 1759 bool isConstant() => true;
1739 bool isConstantBoolean() => constant.isBool(); 1760 bool isConstantBoolean() => constant.isBool();
1740 bool isConstantNull() => constant.isNull(); 1761 bool isConstantNull() => constant.isNull();
1741 bool isConstantNumber() => constant.isNum(); 1762 bool isConstantNumber() => constant.isNum();
1742 bool isConstantString() => constant.isString(); 1763 bool isConstantString() => constant.isString();
1764 bool isConstantList() => constant.isList();
1765 bool isConstantMap() => constant.isMap();
1743 1766
1744 // Maybe avoid this if the literal is big? 1767 // Maybe avoid this if the literal is big?
1745 bool isCodeMotionInvariant() => true; 1768 bool isCodeMotionInvariant() => true;
1746 } 1769 }
1747 1770
1748 class HNot extends HInstruction { 1771 class HNot extends HInstruction {
1749 HNot(HInstruction value) : super(<HInstruction>[value]); 1772 HNot(HInstruction value) : super(<HInstruction>[value]);
1750 void prepareGvn() { 1773 void prepareGvn() {
1751 assert(!hasSideEffects()); 1774 assert(!hasSideEffects());
1752 setUseGvn(); 1775 setUseGvn();
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after
2274 final bool isAnd; 2297 final bool isAnd;
2275 final SubExpression left; 2298 final SubExpression left;
2276 final SubExpression right; 2299 final SubExpression right;
2277 final HBasicBlock joinBlock; 2300 final HBasicBlock joinBlock;
2278 HAndOrBlockInformation(this.isAnd, 2301 HAndOrBlockInformation(this.isAnd,
2279 this.left, 2302 this.left,
2280 this.right, 2303 this.right,
2281 this.joinBlock); 2304 this.joinBlock);
2282 bool accept(HBlockInformationVisitor visitor) => visitor.visitAndOrInfo(this); 2305 bool accept(HBlockInformationVisitor visitor) => visitor.visitAndOrInfo(this);
2283 } 2306 }
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