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

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

Issue 10668021: Distinguish statement and expression foreign code. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 8 years, 5 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
« no previous file with comments | « lib/compiler/implementation/ssa/codegen.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 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 946 matching lines...) Expand 10 before | Expand all | Expand 10 after
957 return validator.isValid; 957 return validator.isValid;
958 } 958 }
959 959
960 /** 960 /**
961 * The code for computing a bailout environment, and the code 961 * The code for computing a bailout environment, and the code
962 * generation must agree on what does not need to be captured, 962 * generation must agree on what does not need to be captured,
963 * so should always be generated at use site. 963 * so should always be generated at use site.
964 */ 964 */
965 bool isCodeMotionInvariant() => false; 965 bool isCodeMotionInvariant() => false;
966 966
967 bool isStatement() => false; 967 bool get isStatement() => false;
968 } 968 }
969 969
970 class HBoolify extends HInstruction { 970 class HBoolify extends HInstruction {
971 HBoolify(HInstruction value) : super(<HInstruction>[value]); 971 HBoolify(HInstruction value) : super(<HInstruction>[value]);
972 void prepareGvn() { 972 void prepareGvn() {
973 assert(!hasSideEffects()); 973 assert(!hasSideEffects());
974 setUseGvn(); 974 setUseGvn();
975 } 975 }
976 976
977 HType get guaranteedType() => HType.BOOLEAN; 977 HType get guaranteedType() => HType.BOOLEAN;
978 978
979 accept(HVisitor visitor) => visitor.visitBoolify(this); 979 accept(HVisitor visitor) => visitor.visitBoolify(this);
980 int typeCode() => 0; 980 int typeCode() => 0;
981 bool typeEquals(other) => other is HBoolify; 981 bool typeEquals(other) => other is HBoolify;
982 bool dataEquals(HInstruction other) => true; 982 bool dataEquals(HInstruction other) => true;
983 } 983 }
984 984
985 /** 985 /**
986 * A [HCheck] instruction is an instruction that might do a dynamic 986 * A [HCheck] instruction is an instruction that might do a dynamic
987 * check at runtime on another instruction. To have proper instruction 987 * check at runtime on another instruction. To have proper instruction
988 * dependencies in the graph, instructions that depend on the check 988 * dependencies in the graph, instructions that depend on the check
989 * being done reference the [HCheck] instruction instead of the 989 * being done reference the [HCheck] instruction instead of the
990 * instruction itself. 990 * instruction itself.
991 */ 991 */
992 abstract class HCheck extends HInstruction { 992 abstract class HCheck extends HInstruction {
993 HCheck(inputs) : super(inputs); 993 HCheck(inputs) : super(inputs);
994 HInstruction get checkedInput() => inputs[0]; 994 HInstruction get checkedInput() => inputs[0];
995 bool isStatement() => true; 995 final bool isStatement = true;
996 void prepareGvn() { 996 void prepareGvn() {
997 assert(!hasSideEffects()); 997 assert(!hasSideEffects());
998 setUseGvn(); 998 setUseGvn();
999 } 999 }
1000 } 1000 }
1001 1001
1002 class HTypeGuard extends HCheck { 1002 class HTypeGuard extends HCheck {
1003 final int state; 1003 final int state;
1004 final HType guardedType; 1004 final HType guardedType;
1005 bool isOn = false; 1005 bool isOn = false;
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1075 abstract toString(); 1075 abstract toString();
1076 } 1076 }
1077 1077
1078 class HControlFlow extends HInstruction { 1078 class HControlFlow extends HInstruction {
1079 HControlFlow(inputs) : super(inputs); 1079 HControlFlow(inputs) : super(inputs);
1080 abstract toString(); 1080 abstract toString();
1081 void prepareGvn() { 1081 void prepareGvn() {
1082 // Control flow does not have side-effects. 1082 // Control flow does not have side-effects.
1083 } 1083 }
1084 bool isControlFlow() => true; 1084 bool isControlFlow() => true;
1085 bool isStatement() => true; 1085 final bool isStatement = true;
1086 } 1086 }
1087 1087
1088 class HInvoke extends HInstruction { 1088 class HInvoke extends HInstruction {
1089 /** 1089 /**
1090 * The first argument must be the target: either an [HStatic] node, or 1090 * The first argument must be the target: either an [HStatic] node, or
1091 * the receiver of a method-call. The remaining inputs are the arguments 1091 * the receiver of a method-call. The remaining inputs are the arguments
1092 * to the invocation. 1092 * to the invocation.
1093 */ 1093 */
1094 final Selector selector; 1094 final Selector selector;
1095 HInvoke(Selector this.selector, List<HInstruction> inputs) : super(inputs); 1095 HInvoke(Selector this.selector, List<HInstruction> inputs) : super(inputs);
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
1280 1280
1281 HInstruction get receiver() => inputs[0]; 1281 HInstruction get receiver() => inputs[0];
1282 HInstruction get value() => inputs[1]; 1282 HInstruction get value() => inputs[1];
1283 accept(HVisitor visitor) => visitor.visitFieldSet(this); 1283 accept(HVisitor visitor) => visitor.visitFieldSet(this);
1284 1284
1285 void prepareGvn() { 1285 void prepareGvn() {
1286 // TODO(ngeoffray): implement more fine grained side effects. 1286 // TODO(ngeoffray): implement more fine grained side effects.
1287 setAllSideEffects(); 1287 setAllSideEffects();
1288 } 1288 }
1289 1289
1290 bool isStatement() => true; 1290 final bool isStatement = true;
1291 } 1291 }
1292 1292
1293 class HLocalGet extends HFieldGet { 1293 class HLocalGet extends HFieldGet {
1294 HLocalGet(Element element, HLocalValue local) : super(element, local); 1294 HLocalGet(Element element, HLocalValue local) : super(element, local);
1295 1295
1296 accept(HVisitor visitor) => visitor.visitLocalGet(this); 1296 accept(HVisitor visitor) => visitor.visitLocalGet(this);
1297 1297
1298 HLocalValue get local() => inputs[0]; 1298 HLocalValue get local() => inputs[0];
1299 1299
1300 void prepareGvn() { 1300 void prepareGvn() {
(...skipping 17 matching lines...) Expand all
1318 // TODO(floitsch): implement more fine grained side effects. 1318 // TODO(floitsch): implement more fine grained side effects.
1319 setAllSideEffects(); 1319 setAllSideEffects();
1320 } 1320 }
1321 } 1321 }
1322 1322
1323 class HForeign extends HInstruction { 1323 class HForeign extends HInstruction {
1324 final DartString code; 1324 final DartString code;
1325 final HType foreignType; 1325 final HType foreignType;
1326 HForeign(this.code, DartString declaredType, List<HInstruction> inputs) 1326 HForeign(this.code, DartString declaredType, List<HInstruction> inputs)
1327 : foreignType = computeTypeFromDeclaredType(declaredType), 1327 : foreignType = computeTypeFromDeclaredType(declaredType),
1328 isStatement = false,
1329 super(inputs);
1330 HForeign.statement(this.code, List<HInstruction> inputs)
1331 : foreignType = HType.UNKNOWN,
1332 isStatement = true,
1328 super(inputs); 1333 super(inputs);
1329 accept(HVisitor visitor) => visitor.visitForeign(this); 1334 accept(HVisitor visitor) => visitor.visitForeign(this);
1330 1335
1331 static HType computeTypeFromDeclaredType(DartString declaredType) { 1336 static HType computeTypeFromDeclaredType(DartString declaredType) {
1332 if (declaredType.slowToString() == 'bool') return HType.BOOLEAN; 1337 if (declaredType.slowToString() == 'bool') return HType.BOOLEAN;
1333 if (declaredType.slowToString() == 'int') return HType.INTEGER; 1338 if (declaredType.slowToString() == 'int') return HType.INTEGER;
1334 if (declaredType.slowToString() == 'double') return HType.DOUBLE; 1339 if (declaredType.slowToString() == 'double') return HType.DOUBLE;
1335 if (declaredType.slowToString() == 'num') return HType.NUMBER; 1340 if (declaredType.slowToString() == 'num') return HType.NUMBER;
1336 if (declaredType.slowToString() == 'String') return HType.STRING; 1341 if (declaredType.slowToString() == 'String') return HType.STRING;
1337 return HType.UNKNOWN; 1342 return HType.UNKNOWN;
1338 } 1343 }
1339 1344
1340 HType get guaranteedType() => foreignType; 1345 HType get guaranteedType() => foreignType;
1341 1346
1342 // Be conservative and treat all [HForeign] as statements, even 1347 final bool isStatement;
1343 // though some are just expressions.
1344 bool isStatement() => true;
1345 } 1348 }
1346 1349
1347 class HForeignNew extends HForeign { 1350 class HForeignNew extends HForeign {
1348 ClassElement element; 1351 ClassElement element;
1349 HForeignNew(this.element, List<HInstruction> inputs) 1352 HForeignNew(this.element, List<HInstruction> inputs)
1350 : super(const LiteralDartString("new"), 1353 : super(const LiteralDartString("new"),
1351 const LiteralDartString("Object"), inputs); 1354 const LiteralDartString("Object"), inputs);
1352 accept(HVisitor visitor) => visitor.visitForeignNew(this); 1355 accept(HVisitor visitor) => visitor.visitForeignNew(this);
1353 } 1356 }
1354 1357
(...skipping 788 matching lines...) Expand 10 before | Expand all | Expand 10 after
2143 2146
2144 class HStaticStore extends HInstruction { 2147 class HStaticStore extends HInstruction {
2145 Element element; 2148 Element element;
2146 HStaticStore(this.element, HInstruction value) : super(<HInstruction>[value]); 2149 HStaticStore(this.element, HInstruction value) : super(<HInstruction>[value]);
2147 toString() => 'static store ${element.name}'; 2150 toString() => 'static store ${element.name}';
2148 accept(HVisitor visitor) => visitor.visitStaticStore(this); 2151 accept(HVisitor visitor) => visitor.visitStaticStore(this);
2149 2152
2150 int typeCode() => 26; 2153 int typeCode() => 26;
2151 bool typeEquals(other) => other is HStaticStore; 2154 bool typeEquals(other) => other is HStaticStore;
2152 bool dataEquals(HStaticStore other) => element == other.element; 2155 bool dataEquals(HStaticStore other) => element == other.element;
2153 bool isStatement() => true; 2156 final bool isStatement = true;
2154 } 2157 }
2155 2158
2156 class HLiteralList extends HInstruction { 2159 class HLiteralList extends HInstruction {
2157 HLiteralList(inputs) : super(inputs); 2160 HLiteralList(inputs) : super(inputs);
2158 toString() => 'literal list'; 2161 toString() => 'literal list';
2159 accept(HVisitor visitor) => visitor.visitLiteralList(this); 2162 accept(HVisitor visitor) => visitor.visitLiteralList(this);
2160 2163
2161 HType get guaranteedType() => HType.MUTABLE_ARRAY; 2164 HType get guaranteedType() => HType.MUTABLE_ARRAY;
2162 2165
2163 void prepareGvn() { 2166 void prepareGvn() {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
2218 return HType.MUTABLE_ARRAY; 2221 return HType.MUTABLE_ARRAY;
2219 } 2222 }
2220 // The index should be an int when the receiver is a string or array. 2223 // The index should be an int when the receiver is a string or array.
2221 // However it turns out that inserting an integer check in the optimized 2224 // However it turns out that inserting an integer check in the optimized
2222 // version is cheaper than having another bailout case. This is true, 2225 // version is cheaper than having another bailout case. This is true,
2223 // because the integer check will simply throw if it fails. 2226 // because the integer check will simply throw if it fails.
2224 return HType.UNKNOWN; 2227 return HType.UNKNOWN;
2225 } 2228 }
2226 2229
2227 bool get builtin() => receiver.isMutableArray() && index.isInteger(); 2230 bool get builtin() => receiver.isMutableArray() && index.isInteger();
2228 bool isStatement() => !builtin; 2231 bool get isStatement() => !builtin;
2229 } 2232 }
2230 2233
2231 class HIs extends HInstruction { 2234 class HIs extends HInstruction {
2232 final Type typeExpression; 2235 final Type typeExpression;
2233 final bool nullOk; 2236 final bool nullOk;
2234 2237
2235 HIs.withTypeInfoCall(this.typeExpression, HInstruction expression, 2238 HIs.withTypeInfoCall(this.typeExpression, HInstruction expression,
2236 HInstruction typeInfo, [this.nullOk = false]) 2239 HInstruction typeInfo, [this.nullOk = false])
2237 : super(<HInstruction>[expression, typeInfo]); 2240 : super(<HInstruction>[expression, typeInfo]);
2238 2241
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2273 2276
2274 bool get isChecked() => kind != NO_CHECK; 2277 bool get isChecked() => kind != NO_CHECK;
2275 bool get isCheckedModeCheck() => kind == CHECKED_MODE_CHECK; 2278 bool get isCheckedModeCheck() => kind == CHECKED_MODE_CHECK;
2276 bool get isArgumentTypeCheck() => kind == ARGUMENT_TYPE_CHECK; 2279 bool get isArgumentTypeCheck() => kind == ARGUMENT_TYPE_CHECK;
2277 bool get isCastTypeCheck() => kind == CAST_TYPE_CHECK; 2280 bool get isCastTypeCheck() => kind == CAST_TYPE_CHECK;
2278 2281
2279 HType get guaranteedType() => type; 2282 HType get guaranteedType() => type;
2280 2283
2281 accept(HVisitor visitor) => visitor.visitTypeConversion(this); 2284 accept(HVisitor visitor) => visitor.visitTypeConversion(this);
2282 2285
2283 bool isStatement() => kind == ARGUMENT_TYPE_CHECK; 2286 bool get isStatement() => kind == ARGUMENT_TYPE_CHECK;
2284 bool isControlFlow() => kind == ARGUMENT_TYPE_CHECK; 2287 bool isControlFlow() => kind == ARGUMENT_TYPE_CHECK;
2285 2288
2286 int typeCode() => 28; 2289 int typeCode() => 28;
2287 bool typeEquals(HInstruction other) => other is HTypeConversion; 2290 bool typeEquals(HInstruction other) => other is HTypeConversion;
2288 bool dataEquals(HTypeConversion other) { 2291 bool dataEquals(HTypeConversion other) {
2289 return type == other.type && kind == other.kind; 2292 return type == other.type && kind == other.kind;
2290 } 2293 }
2291 } 2294 }
2292 2295
2293 class HStringConcat extends HInstruction { 2296 class HStringConcat extends HInstruction {
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
2624 HBasicBlock get start() => expression.start; 2627 HBasicBlock get start() => expression.start;
2625 HBasicBlock get end() { 2628 HBasicBlock get end() {
2626 // We don't create a switch block if there are no cases. 2629 // We don't create a switch block if there are no cases.
2627 assert(!statements.isEmpty()); 2630 assert(!statements.isEmpty());
2628 return statements.last().end; 2631 return statements.last().end;
2629 } 2632 }
2630 2633
2631 bool accept(HStatementInformationVisitor visitor) => 2634 bool accept(HStatementInformationVisitor visitor) =>
2632 visitor.visitSwitchInfo(this); 2635 visitor.visitSwitchInfo(this);
2633 } 2636 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/ssa/codegen.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698