Index: pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart |
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart |
index 561f8aca34ee99025a7b4e7f1be9ae977e73bd22..2b00eb34d184dfb5830ad4068e8287b8b51e65b5 100644 |
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart |
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart |
@@ -96,6 +96,10 @@ abstract class Primitive extends Definition<Primitive> { |
/// False must be returned for primitives that may throw, diverge, or have |
/// observable side-effects. |
bool get isSafeForElimination => true; |
+ |
+ /// True if time-of-evaluation is irrelevant for the given primitive, |
+ /// assuming its inputs are the same values. |
+ 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
|
} |
/// Operands to invocations and primitives are always variables. They point to |
@@ -266,6 +270,12 @@ class InvokeStatic extends Expression implements Invoke { |
: arguments = _referenceList(args), |
continuation = new Reference<Continuation>(cont); |
+ InvokeStatic.byReference(this.target, |
+ this.selector, |
+ this.arguments, |
+ this.continuation, |
+ [this.sourceInformation]); |
+ |
accept(Visitor visitor) => visitor.visitInvokeStatic(this); |
} |
@@ -299,6 +309,13 @@ class InvokeMethod extends Expression implements Invoke { |
this.arguments = _referenceList(arguments), |
this.continuation = new Reference<Continuation>(continuation); |
+ InvokeMethod.byReference(this.receiver, |
+ this.selector, |
+ this.mask, |
+ this.arguments, |
+ this.continuation, |
+ [this.sourceInformation]); |
+ |
accept(Visitor visitor) => visitor.visitInvokeMethod(this); |
} |
@@ -505,6 +522,9 @@ class GetMutableVariable extends Primitive { |
: this.variable = new Reference<MutableVariable>(variable); |
accept(Visitor visitor) => visitor.visitGetMutableVariable(this); |
+ |
+ @override |
+ bool get isSafeForReordering => false; |
} |
/// Assign a [MutableVariable]. |
@@ -624,9 +644,14 @@ class GetField extends Primitive { |
@override |
bool get isSafeForElimination => objectIsNotNull; |
+ |
+ @override |
+ bool get isSafeForReordering => objectIsNotNull && field.isFinal; |
} |
/// Reads the value of a static field or tears off a static method. |
+/// |
+/// Note that lazily initialized fields should be read using GetLazyStatic. |
class GetStatic extends Primitive { |
/// Can be [FieldElement] or [FunctionElement]. |
final Element element; |
@@ -635,6 +660,11 @@ class GetStatic extends Primitive { |
GetStatic(this.element, [this.sourceInformation]); |
accept(Visitor visitor) => visitor.visitGetStatic(this); |
+ |
+ @override |
+ bool get isSafeForReordering { |
+ return element is FunctionElement || element.isFinal; |
+ } |
} |
/// Sets the value of a static field. |