| 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 3c735d1aeae6649b17f3e168186c96f59572605c..50349cf7768ed5ef93df549bfcf218fd94bba9e9 100644
|
| --- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
|
| +++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
|
| @@ -64,12 +64,10 @@ abstract class Definition<T extends Definition<T>> extends Node {
|
| }
|
| }
|
|
|
| -/// An expression that cannot throw or diverge and has no side-effects.
|
| -/// All primitives are named using the identity of the [Primitive] object.
|
| +/// A named value.
|
| ///
|
| -/// Primitives may allocate objects; this is not considered side-effect here.
|
| -///
|
| -/// Although primitives may not mutate state, they may depend on state.
|
| +/// The identity of the [Primitive] object is the name of the value.
|
| +/// The subclass describes how to compute the value.
|
| ///
|
| /// All primitives except [Parameter] must be bound by a [LetPrim].
|
| abstract class Primitive extends Definition<Primitive> {
|
| @@ -85,6 +83,13 @@ abstract class Primitive extends Definition<Primitive> {
|
| this.hint = hint;
|
| }
|
| }
|
| +
|
| + /// True if the primitive can be removed, assuming it has no uses
|
| + /// (this getter does not check if there are any uses).
|
| + ///
|
| + /// False must be returned for primitives that may throw, diverge, or have
|
| + /// observable side-effects.
|
| + bool get isSafeForElimination => true;
|
| }
|
|
|
| /// Operands to invocations and primitives are always variables. They point to
|
| @@ -607,14 +612,24 @@ class SetField extends Expression implements InteriorNode {
|
| }
|
|
|
| /// Directly reads from a field on a given object.
|
| +///
|
| +/// The [object] must either be `null` or an object that has [field].
|
| class GetField extends Primitive {
|
| final Reference<Primitive> object;
|
| FieldElement field;
|
|
|
| + /// True if the receiver is known not to be null.
|
| + // TODO(asgerf): This is a placeholder until we agree on how to track
|
| + // side effects.
|
| + bool objectIsNotNull = false;
|
| +
|
| GetField(Primitive object, this.field)
|
| : this.object = new Reference<Primitive>(object);
|
|
|
| accept(Visitor visitor) => visitor.visitGetField(this);
|
| +
|
| + @override
|
| + bool get isSafeForElimination => objectIsNotNull;
|
| }
|
|
|
| /// Reads the value of a static field or tears off a static method.
|
|
|