Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 library dart2js.ir_nodes; | 4 library dart2js.ir_nodes; |
| 5 | 5 |
| 6 import '../constants/values.dart' as values show ConstantValue; | 6 import '../constants/values.dart' as values show ConstantValue; |
| 7 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; | 7 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; |
| 8 import '../elements/elements.dart'; | 8 import '../elements/elements.dart'; |
| 9 import '../io/source_information.dart' show SourceInformation; | 9 import '../io/source_information.dart' show SourceInformation; |
| 10 import '../types/types.dart' show TypeMask; | 10 import '../types/types.dart' show TypeMask; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 89 this.hint = hint; | 89 this.hint = hint; |
| 90 } | 90 } |
| 91 } | 91 } |
| 92 | 92 |
| 93 /// True if the primitive can be removed, assuming it has no uses | 93 /// True if the primitive can be removed, assuming it has no uses |
| 94 /// (this getter does not check if there are any uses). | 94 /// (this getter does not check if there are any uses). |
| 95 /// | 95 /// |
| 96 /// False must be returned for primitives that may throw, diverge, or have | 96 /// False must be returned for primitives that may throw, diverge, or have |
| 97 /// observable side-effects. | 97 /// observable side-effects. |
| 98 bool get isSafeForElimination => true; | 98 bool get isSafeForElimination => true; |
| 99 | |
| 100 /// True if time-of-evaluation is irrelevant for the given primitive, | |
| 101 /// assuming its inputs are the same values. | |
| 102 bool get isSafeForReordering => true; | |
|
floitsch
2015/07/03 11:56:58
I would rather have the default be the safe "false
asgerf
2015/07/03 12:27:52
I agree, although I changed it to be abstract (no
| |
| 99 } | 103 } |
| 100 | 104 |
| 101 /// Operands to invocations and primitives are always variables. They point to | 105 /// Operands to invocations and primitives are always variables. They point to |
| 102 /// their definition and are doubly-linked into a list of occurrences. | 106 /// their definition and are doubly-linked into a list of occurrences. |
| 103 class Reference<T extends Definition<T>> { | 107 class Reference<T extends Definition<T>> { |
| 104 T definition; | 108 T definition; |
| 105 Reference<T> previous; | 109 Reference<T> previous; |
| 106 Reference<T> next; | 110 Reference<T> next; |
| 107 | 111 |
| 108 /// A pointer to the parent node. Is null until set by optimization passes. | 112 /// A pointer to the parent node. Is null until set by optimization passes. |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 259 final SourceInformation sourceInformation; | 263 final SourceInformation sourceInformation; |
| 260 | 264 |
| 261 InvokeStatic(this.target, | 265 InvokeStatic(this.target, |
| 262 this.selector, | 266 this.selector, |
| 263 List<Primitive> args, | 267 List<Primitive> args, |
| 264 Continuation cont, | 268 Continuation cont, |
| 265 [this.sourceInformation]) | 269 [this.sourceInformation]) |
| 266 : arguments = _referenceList(args), | 270 : arguments = _referenceList(args), |
| 267 continuation = new Reference<Continuation>(cont); | 271 continuation = new Reference<Continuation>(cont); |
| 268 | 272 |
| 273 InvokeStatic.byReference(this.target, | |
| 274 this.selector, | |
| 275 this.arguments, | |
| 276 this.continuation, | |
| 277 [this.sourceInformation]); | |
| 278 | |
| 269 accept(Visitor visitor) => visitor.visitInvokeStatic(this); | 279 accept(Visitor visitor) => visitor.visitInvokeStatic(this); |
| 270 } | 280 } |
| 271 | 281 |
| 272 /// Invoke a method on an object. | 282 /// Invoke a method on an object. |
| 273 /// | 283 /// |
| 274 /// This includes getters, setters, operators, and index getter/setters. | 284 /// This includes getters, setters, operators, and index getter/setters. |
| 275 /// | 285 /// |
| 276 /// Tearing off a method is treated like a getter invocation (getters and | 286 /// Tearing off a method is treated like a getter invocation (getters and |
| 277 /// tear-offs cannot be distinguished at compile-time). | 287 /// tear-offs cannot be distinguished at compile-time). |
| 278 /// | 288 /// |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 292 InvokeMethod(Primitive receiver, | 302 InvokeMethod(Primitive receiver, |
| 293 this.selector, | 303 this.selector, |
| 294 this.mask, | 304 this.mask, |
| 295 List<Primitive> arguments, | 305 List<Primitive> arguments, |
| 296 Continuation continuation, | 306 Continuation continuation, |
| 297 [this.sourceInformation]) | 307 [this.sourceInformation]) |
| 298 : this.receiver = new Reference<Primitive>(receiver), | 308 : this.receiver = new Reference<Primitive>(receiver), |
| 299 this.arguments = _referenceList(arguments), | 309 this.arguments = _referenceList(arguments), |
| 300 this.continuation = new Reference<Continuation>(continuation); | 310 this.continuation = new Reference<Continuation>(continuation); |
| 301 | 311 |
| 312 InvokeMethod.byReference(this.receiver, | |
| 313 this.selector, | |
| 314 this.mask, | |
| 315 this.arguments, | |
| 316 this.continuation, | |
| 317 [this.sourceInformation]); | |
| 318 | |
| 302 accept(Visitor visitor) => visitor.visitInvokeMethod(this); | 319 accept(Visitor visitor) => visitor.visitInvokeMethod(this); |
| 303 } | 320 } |
| 304 | 321 |
| 305 /// Invoke [target] on [receiver], bypassing dispatch and override semantics. | 322 /// Invoke [target] on [receiver], bypassing dispatch and override semantics. |
| 306 /// | 323 /// |
| 307 /// That is, if [receiver] is an instance of a class that overrides [target] | 324 /// That is, if [receiver] is an instance of a class that overrides [target] |
| 308 /// with a different implementation, the overriding implementation is bypassed | 325 /// with a different implementation, the overriding implementation is bypassed |
| 309 /// and [target]'s implementation is invoked. | 326 /// and [target]'s implementation is invoked. |
| 310 /// | 327 /// |
| 311 /// As with [InvokeMethod], this can be used to invoke a method, operator, | 328 /// As with [InvokeMethod], this can be used to invoke a method, operator, |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 498 /// | 515 /// |
| 499 /// let prim p = ![variable] in [body] | 516 /// let prim p = ![variable] in [body] |
| 500 /// | 517 /// |
| 501 class GetMutableVariable extends Primitive { | 518 class GetMutableVariable extends Primitive { |
| 502 final Reference<MutableVariable> variable; | 519 final Reference<MutableVariable> variable; |
| 503 | 520 |
| 504 GetMutableVariable(MutableVariable variable) | 521 GetMutableVariable(MutableVariable variable) |
| 505 : this.variable = new Reference<MutableVariable>(variable); | 522 : this.variable = new Reference<MutableVariable>(variable); |
| 506 | 523 |
| 507 accept(Visitor visitor) => visitor.visitGetMutableVariable(this); | 524 accept(Visitor visitor) => visitor.visitGetMutableVariable(this); |
| 525 | |
| 526 @override | |
| 527 bool get isSafeForReordering => false; | |
| 508 } | 528 } |
| 509 | 529 |
| 510 /// Assign a [MutableVariable]. | 530 /// Assign a [MutableVariable]. |
| 511 /// | 531 /// |
| 512 /// [MutableVariable]s can be seen as ref cells that are not first-class | 532 /// [MutableVariable]s can be seen as ref cells that are not first-class |
| 513 /// values. This can be seen as a dereferencing assignment: | 533 /// values. This can be seen as a dereferencing assignment: |
| 514 /// | 534 /// |
| 515 /// { [variable] := [value]; [body] } | 535 /// { [variable] := [value]; [body] } |
| 516 class SetMutableVariable extends Expression implements InteriorNode { | 536 class SetMutableVariable extends Expression implements InteriorNode { |
| 517 final Reference<MutableVariable> variable; | 537 final Reference<MutableVariable> variable; |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 617 // side effects. | 637 // side effects. |
| 618 bool objectIsNotNull = false; | 638 bool objectIsNotNull = false; |
| 619 | 639 |
| 620 GetField(Primitive object, this.field) | 640 GetField(Primitive object, this.field) |
| 621 : this.object = new Reference<Primitive>(object); | 641 : this.object = new Reference<Primitive>(object); |
| 622 | 642 |
| 623 accept(Visitor visitor) => visitor.visitGetField(this); | 643 accept(Visitor visitor) => visitor.visitGetField(this); |
| 624 | 644 |
| 625 @override | 645 @override |
| 626 bool get isSafeForElimination => objectIsNotNull; | 646 bool get isSafeForElimination => objectIsNotNull; |
| 647 | |
| 648 @override | |
| 649 bool get isSafeForReordering => objectIsNotNull && field.isFinal; | |
| 627 } | 650 } |
| 628 | 651 |
| 629 /// Reads the value of a static field or tears off a static method. | 652 /// Reads the value of a static field or tears off a static method. |
| 653 /// | |
| 654 /// Note that lazily initialized fields should be read using GetLazyStatic. | |
| 630 class GetStatic extends Primitive { | 655 class GetStatic extends Primitive { |
| 631 /// Can be [FieldElement] or [FunctionElement]. | 656 /// Can be [FieldElement] or [FunctionElement]. |
| 632 final Element element; | 657 final Element element; |
| 633 final SourceInformation sourceInformation; | 658 final SourceInformation sourceInformation; |
| 634 | 659 |
| 635 GetStatic(this.element, [this.sourceInformation]); | 660 GetStatic(this.element, [this.sourceInformation]); |
| 636 | 661 |
| 637 accept(Visitor visitor) => visitor.visitGetStatic(this); | 662 accept(Visitor visitor) => visitor.visitGetStatic(this); |
| 663 | |
| 664 @override | |
| 665 bool get isSafeForReordering { | |
| 666 return element is FunctionElement || element.isFinal; | |
| 667 } | |
| 638 } | 668 } |
| 639 | 669 |
| 640 /// Sets the value of a static field. | 670 /// Sets the value of a static field. |
| 641 class SetStatic extends Expression implements InteriorNode { | 671 class SetStatic extends Expression implements InteriorNode { |
| 642 final FieldElement element; | 672 final FieldElement element; |
| 643 final Reference<Primitive> value; | 673 final Reference<Primitive> value; |
| 644 Expression body; | 674 Expression body; |
| 645 final SourceInformation sourceInformation; | 675 final SourceInformation sourceInformation; |
| 646 | 676 |
| 647 SetStatic(this.element, Primitive value, [this.sourceInformation]) | 677 SetStatic(this.element, Primitive value, [this.sourceInformation]) |
| (...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1267 const RemovalVisitor(); | 1297 const RemovalVisitor(); |
| 1268 | 1298 |
| 1269 processReference(Reference reference) { | 1299 processReference(Reference reference) { |
| 1270 reference.unlink(); | 1300 reference.unlink(); |
| 1271 } | 1301 } |
| 1272 | 1302 |
| 1273 static void remove(Node node) { | 1303 static void remove(Node node) { |
| 1274 (const RemovalVisitor()).visit(node); | 1304 (const RemovalVisitor()).visit(node); |
| 1275 } | 1305 } |
| 1276 } | 1306 } |
| OLD | NEW |