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

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

Issue 10116023: Don't rely on any speculative type in the bailout version. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. 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 891 matching lines...) Expand 10 before | Expand all | Expand 10 after
902 * 902 *
903 * Note that the [propagatedType] may only be set to [HType.CONFLICTING] with 903 * Note that the [propagatedType] may only be set to [HType.CONFLICTING] with
904 * speculative types (as otherwise the instruction either sets the output 904 * speculative types (as otherwise the instruction either sets the output
905 * type to [HType.UNKNOWN] or a specific type. 905 * type to [HType.UNKNOWN] or a specific type.
906 */ 906 */
907 HType propagatedType = HType.UNKNOWN; 907 HType propagatedType = HType.UNKNOWN;
908 908
909 /** 909 /**
910 * Some instructions have a good idea of their return type, but cannot 910 * Some instructions have a good idea of their return type, but cannot
911 * guarantee the type. The [likelyType] does not need to be more specialized 911 * guarantee the type. The [likelyType] does not need to be more specialized
912 * than the [propagatedType]. 912 * than the [propagatedType].
913 * 913 *
914 * Examples: the [likelyType] of [:x == y:] is a boolean. In most cases this 914 * Examples: the [likelyType] of [:x == y:] is a boolean. In most cases this
915 * cannot be guaranteed, but when merging types we still want to use this 915 * cannot be guaranteed, but when merging types we still want to use this
916 * information. 916 * information.
917 * 917 *
918 * Similarily the [HAdd] instruction is likely a number. Note that, even if 918 * Similarily the [HAdd] instruction is likely a number. Note that, even if
919 * the [propagatedType] is already set to integer, the [likelyType] still 919 * the [propagatedType] is already set to integer, the [likelyType] still
920 * might just return the number type. 920 * might just return the number type.
921 */ 921 */
922 HType get likelyType() => propagatedType; 922 HType get likelyType() => propagatedType;
923 923
924 /** 924 /**
925 * Compute the type of the instruction by propagating the input types through 925 * Compute the type of the instruction by propagating the input types through
926 * the instruction. 926 * the instruction.
927 * 927 *
928 * By default just copy the guaranteed type. 928 * By default just copy the guaranteed type.
929 */ 929 */
930 HType computeTypeFromInputTypes() => guaranteedType; 930 HType computeTypeFromInputTypes() => guaranteedType;
931 931
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1060 class HCheck extends HInstruction { 1060 class HCheck extends HInstruction {
1061 HCheck(inputs) : super(inputs); 1061 HCheck(inputs) : super(inputs);
1062 1062
1063 // TODO(floitsch): make class abstract instead of adding an abstract method. 1063 // TODO(floitsch): make class abstract instead of adding an abstract method.
1064 abstract accept(HVisitor visitor); 1064 abstract accept(HVisitor visitor);
1065 1065
1066 bool isControlFlow() => true; 1066 bool isControlFlow() => true;
1067 } 1067 }
1068 1068
1069 class HTypeGuard extends HInstruction { 1069 class HTypeGuard extends HInstruction {
1070 int state; 1070 final int state;
1071 HTypeGuard(int this.state, List<HInstruction> env) : super(env); 1071 final HType guardedType;
1072 bool isOn = false;
1073 HTypeGuard(this.guardedType, this.state, List<HInstruction> env) : super(env);
1072 1074
1073 void prepareGvn() { 1075 void prepareGvn() {
1074 assert(!hasSideEffects()); 1076 assert(!hasSideEffects());
1075 setUseGvn(); 1077 setUseGvn();
1076 } 1078 }
1077 1079
1078 HInstruction get guarded() => inputs.last(); 1080 HInstruction get guarded() => inputs.last();
1079 1081
1082 HType computeTypeFromInputTypes() {
1083 return isOn ? guardedType : guarded.propagatedType;
1084 }
1085
1086 HType get guaranteedType() => isOn ? guardedType : HType.UNKNOWN;
1087
1080 bool isControlFlow() => true; 1088 bool isControlFlow() => true;
1081 1089
1082 accept(HVisitor visitor) => visitor.visitTypeGuard(this); 1090 accept(HVisitor visitor) => visitor.visitTypeGuard(this);
1083 int typeCode() => 1; 1091 int typeCode() => 1;
1084 bool typeEquals(other) => other is HTypeGuard; 1092 bool typeEquals(other) => other is HTypeGuard;
1085 bool dataEquals(HTypeGuard other) => propagatedType == other.propagatedType; 1093 bool dataEquals(HTypeGuard other) => guardedType == other.guardedType;
1086 } 1094 }
1087 1095
1088 class HBoundsCheck extends HCheck { 1096 class HBoundsCheck extends HCheck {
1089 HBoundsCheck(length, index) : super(<HInstruction>[length, index]); 1097 HBoundsCheck(length, index) : super(<HInstruction>[length, index]);
1090 1098
1091 HInstruction get length() => inputs[0]; 1099 HInstruction get length() => inputs[0];
1092 HInstruction get index() => inputs[1]; 1100 HInstruction get index() => inputs[1];
1093 1101
1094 void prepareGvn() { 1102 void prepareGvn() {
1095 assert(!hasSideEffects()); 1103 assert(!hasSideEffects());
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
1411 HType computeDesiredTypeForNonTargetInput(HInstruction input) { 1419 HType computeDesiredTypeForNonTargetInput(HInstruction input) {
1412 // If the desired output type should be an integer we want to get two 1420 // If the desired output type should be an integer we want to get two
1413 // integers as arguments. 1421 // integers as arguments.
1414 if (propagatedType.isInteger()) return HType.INTEGER; 1422 if (propagatedType.isInteger()) return HType.INTEGER;
1415 // If the outgoing type should be a number we can get that if both inputs 1423 // If the outgoing type should be a number we can get that if both inputs
1416 // are numbers. If we don't know the outgoing type we try to make it a 1424 // are numbers. If we don't know the outgoing type we try to make it a
1417 // number. 1425 // number.
1418 if (propagatedType.isUnknown() || propagatedType.isNumber()) { 1426 if (propagatedType.isUnknown() || propagatedType.isNumber()) {
1419 return HType.NUMBER; 1427 return HType.NUMBER;
1420 } 1428 }
1429 // Even if the desired outgoing type is not a number we still want the
1430 // second argument to be a number if the first one is a number. This will
1431 // not help for the outgoing type, but at least the binary arithmetic
1432 // operation will not have type problems.
1433 // TODO(floitsch): normally we shouldn't request a number, but simply
1434 // throw an IllegalArgumentException if it isn't. This would be similar
1435 // to the array case.
1436 if (input == right && left.isNumber()) return HType.NUMBER;
1421 return HType.UNKNOWN; 1437 return HType.UNKNOWN;
1422 } 1438 }
1423 1439
1424 HType get likelyType() { 1440 HType get likelyType() {
1425 if (left.isTypeUnknown()) return HType.NUMBER; 1441 if (left.isTypeUnknown()) return HType.NUMBER;
1426 return HType.UNKNOWN; 1442 return HType.UNKNOWN;
1427 } 1443 }
1428 1444
1429 // TODO(1603): The class should be marked as abstract. 1445 // TODO(1603): The class should be marked as abstract.
1430 abstract BinaryOperation get operation(); 1446 abstract BinaryOperation get operation();
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after
2000 2016
2001 HType computeDesiredTypeForNonTargetInput(HInstruction input) { 2017 HType computeDesiredTypeForNonTargetInput(HInstruction input) {
2002 if (input == left && right.propagatedType.isUseful()) { 2018 if (input == left && right.propagatedType.isUseful()) {
2003 // All our useful types have === semantics. But we don't want to 2019 // All our useful types have === semantics. But we don't want to
2004 // speculatively test for all possible types. Therefore we try to match 2020 // speculatively test for all possible types. Therefore we try to match
2005 // the two types. That is, if we see x == 3, then we speculatively test 2021 // the two types. That is, if we see x == 3, then we speculatively test
2006 // if x is a number and bailout if it isn't. 2022 // if x is a number and bailout if it isn't.
2007 if (right.isNumber()) return HType.NUMBER; // No need to be more precise. 2023 if (right.isNumber()) return HType.NUMBER; // No need to be more precise.
2008 // String equality testing is much more common than array equality 2024 // String equality testing is much more common than array equality
2009 // testing. 2025 // testing.
2010 if (right.isStringOrArray()) return HType.STRING; 2026 if (right.isStringOrArray()) return HType.STRING;
2011 return right.propagatedType; 2027 return right.propagatedType;
2012 } 2028 }
2013 // String equality testing is much more common than array equality testing. 2029 // String equality testing is much more common than array equality testing.
2014 if (input == left && left.isStringOrArray()) { 2030 if (input == left && left.isStringOrArray()) {
2015 return HType.READABLE_ARRAY; 2031 return HType.READABLE_ARRAY;
2016 } 2032 }
2017 // String equality testing is much more common than array equality testing. 2033 // String equality testing is much more common than array equality testing.
2018 if (input == right && right.isStringOrArray()) { 2034 if (input == right && right.isStringOrArray()) {
2019 return HType.STRING; 2035 return HType.STRING;
2020 } 2036 }
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
2226 class HIfBlockInformation { 2242 class HIfBlockInformation {
2227 final HIf branch; 2243 final HIf branch;
2228 final SubGraph thenGraph; 2244 final SubGraph thenGraph;
2229 final SubGraph elseGraph; 2245 final SubGraph elseGraph;
2230 final HBasicBlock joinBlock; 2246 final HBasicBlock joinBlock;
2231 HIfBlockInformation(this.branch, 2247 HIfBlockInformation(this.branch,
2232 this.thenGraph, 2248 this.thenGraph,
2233 this.elseGraph, 2249 this.elseGraph,
2234 this.joinBlock); 2250 this.joinBlock);
2235 } 2251 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/ssa/bailout.dart ('k') | lib/compiler/implementation/ssa/optimize.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698