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

Unified Diff: pkg/compiler/lib/src/cps_ir/use_field_initializers.dart

Issue 2246623002: Delete CPS IR (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/update_refinements.dart ('k') | pkg/compiler/lib/src/dart2js.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/cps_ir/use_field_initializers.dart
diff --git a/pkg/compiler/lib/src/cps_ir/use_field_initializers.dart b/pkg/compiler/lib/src/cps_ir/use_field_initializers.dart
deleted file mode 100644
index 601974277272c99940949c0800ddb052cdde4edf..0000000000000000000000000000000000000000
--- a/pkg/compiler/lib/src/cps_ir/use_field_initializers.dart
+++ /dev/null
@@ -1,220 +0,0 @@
-// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-library dart2js.cps_ir.use_field_initializers;
-
-import '../elements/elements.dart';
-import '../js_backend/js_backend.dart';
-import 'cps_ir_nodes.dart';
-import 'optimizers.dart';
-
-/// Eliminates [SetField] instructions when the value can instead be passed into
-/// the field initializer of a [CreateInstance] instruction.
-///
-/// This compensates for a somewhat common pattern where fields are initialized
-/// in the constructor body instead of using initializers. For example:
-///
-/// class Foo {
-/// var x, y;
-/// Foo(x, y) {
-/// this.x = x;
-/// this.y = y;
-/// }
-/// }
-///
-/// ==> (IR for Foo constructor)
-///
-/// foo = new D.Foo(null, null);
-/// foo.x = 'a';
-/// foo.y = 'b';
-///
-/// ==> (after this pass)
-///
-/// foo = new D.Foo('a', 'b');
-//
-// TODO(asgerf): Store forwarding and load elimination could most likely
-// handle this more generally.
-//
-class UseFieldInitializers extends BlockVisitor implements Pass {
- String get passName => 'Use field initializers';
-
- final JavaScriptBackend backend;
-
- final Set<CreateInstance> unescaped = new Set<CreateInstance>();
-
- /// Continuation bindings separating the current traversal position from an
- /// unescaped [CreateInstance]. When [CreateInstance] is sunk, these
- /// continuations must sink as well to ensure the object remains in scope
- /// inside the bound continuations.
- final List<LetCont> letConts = <LetCont>[];
-
- /// If non-null, the bindings in [letConts] should sink to immediately below
- /// this node.
- InteriorNode letContSinkTarget = null;
- EscapeVisitor escapeVisitor;
-
- UseFieldInitializers(this.backend);
-
- void rewrite(FunctionDefinition node) {
- escapeVisitor = new EscapeVisitor(this);
- BlockVisitor.traverseInPreOrder(node, this);
- }
-
- void escape(Reference ref) {
- Definition def = ref.definition;
- if (def is CreateInstance) {
- unescaped.remove(def);
- if (unescaped.isEmpty) {
- sinkLetConts();
- letConts.clear();
- }
- }
- }
-
- void visitContinuation(Continuation node) {
- endBasicBlock();
- }
-
- void visitLetHandler(LetHandler node) {
- endBasicBlock();
- }
-
- void visitInvokeContinuation(InvokeContinuation node) {
- endBasicBlock();
- }
-
- void visitBranch(Branch node) {
- endBasicBlock();
- }
-
- void visitRethrow(Rethrow node) {
- endBasicBlock();
- }
-
- void visitThrow(Throw node) {
- endBasicBlock();
- }
-
- void visitUnreachable(Unreachable node) {
- endBasicBlock();
- }
-
- void visitLetMutable(LetMutable node) {
- escape(node.valueRef);
- }
-
- void visitLetCont(LetCont node) {
- if (unescaped.isNotEmpty) {
- // Ensure we do not lift a LetCont if there is a sink target set above
- // the current node.
- sinkLetConts();
- letConts.add(node);
- }
- }
-
- void sinkLetConts() {
- if (letContSinkTarget != null) {
- for (LetCont letCont in letConts.reversed) {
- letCont
- ..remove()
- ..insertBelow(letContSinkTarget);
- }
- letContSinkTarget = null;
- }
- }
-
- void endBasicBlock() {
- sinkLetConts();
- letConts.clear();
- unescaped.clear();
- }
-
- void visitLetPrim(LetPrim node) {
- Primitive prim = node.primitive;
- if (prim is CreateInstance) {
- unescaped.add(prim);
- prim.argumentRefs.forEach(escape);
- return;
- }
- if (unescaped.isEmpty) return;
- if (prim is SetField) {
- escape(prim.valueRef);
- Primitive object = prim.object;
- if (object is CreateInstance && unescaped.contains(object)) {
- int index = getFieldIndex(object.classElement, prim.field);
- if (index == -1) {
- // This field is not initialized at creation time, so we cannot pull
- // set SetField into the CreateInstance instruction. We have to
- // leave the instruction here, and this counts as a use of the object.
- escape(prim.objectRef);
- } else {
- // Replace the field initializer with the new value. There are no uses
- // of the object before this, so the old value cannot have been seen.
- object.argumentRefs[index].changeTo(prim.value);
- prim.destroy();
- // The right-hand side might not be in scope at the CreateInstance.
- // Sink the creation down to this point.
- rebindCreateInstanceAt(object, node);
- letContSinkTarget = node;
- }
- }
- return;
- }
- if (prim is GetField) {
- // When reading the field of a newly created object, just use the initial
- // value and destroy the GetField. This can unblock the other optimization
- // since we remove a use of the object.
- Primitive object = prim.object;
- if (object is CreateInstance && unescaped.contains(object)) {
- int index = getFieldIndex(object.classElement, prim.field);
- if (index == -1) {
- escape(prim.objectRef);
- } else {
- prim.replaceUsesWith(object.argument(index));
- prim.destroy();
- node.remove();
- }
- }
- return;
- }
- escapeVisitor.visit(node.primitive);
- }
-
- void rebindCreateInstanceAt(CreateInstance prim, LetPrim newBinding) {
- removeBinding(prim);
- newBinding.primitive = prim;
- prim.parent = newBinding;
- }
-
- /// Returns the index of [field] in the canonical initialization order in
- /// [classElement], or -1 if the field is not initialized at creation time
- /// for that class.
- int getFieldIndex(ClassElement classElement, FieldElement field) {
- // There is no stored map from a field to its index in a given class, so we
- // have to iterate over all instance fields until we find it.
- int current = -1, index = -1;
- classElement.forEachInstanceField((host, currentField) {
- if (!backend.isNativeOrExtendsNative(host)) {
- ++current;
- if (currentField == field) {
- index = current;
- }
- }
- }, includeSuperAndInjectedMembers: true);
- return index;
- }
-
- void removeBinding(Primitive prim) {
- LetPrim node = prim.parent;
- node.remove();
- }
-}
-
-class EscapeVisitor extends DeepRecursiveVisitor {
- final UseFieldInitializers main;
- EscapeVisitor(this.main);
-
- processReference(Reference ref) {
- main.escape(ref);
- }
-}
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/update_refinements.dart ('k') | pkg/compiler/lib/src/dart2js.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698