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

Unified Diff: pkg/compiler/lib/src/cps_ir/redundant_phi.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
Index: pkg/compiler/lib/src/cps_ir/redundant_phi.dart
diff --git a/pkg/compiler/lib/src/cps_ir/redundant_phi.dart b/pkg/compiler/lib/src/cps_ir/redundant_phi.dart
deleted file mode 100644
index 96e6431e950c0f72a5993f2516fc445e57a85067..0000000000000000000000000000000000000000
--- a/pkg/compiler/lib/src/cps_ir/redundant_phi.dart
+++ /dev/null
@@ -1,205 +0,0 @@
-// Copyright (c) 2014, 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.redundant_phi_elimination;
-
-import 'cps_ir_nodes.dart';
-import 'optimizers.dart';
-
-/// Eliminate redundant phis from the given [FunctionDefinition].
-///
-/// Phis in this case are [Continuations] together with corresponding
-/// [InvokeContinuation]s. A [Continuation] parameter at position i is redundant
-/// if for all [InvokeContinuation]s, the parameter at position i is identical
-/// (except for feedback). Redundant parameters are removed from the
-/// continuation signature, all invocations, and replaced within the
-/// continuation body.
-class RedundantPhiEliminator extends TrampolineRecursiveVisitor
- implements Pass {
- String get passName => 'Redundant phi elimination';
-
- final Set<Continuation> workSet = new Set<Continuation>();
-
- @override
- void rewrite(FunctionDefinition root) {
- // Traverse the tree once to build the work set.
- visit(root);
-
- // Process each continuation one-by-one.
- while (workSet.isNotEmpty) {
- Continuation cont = workSet.first;
- workSet.remove(cont);
-
- if (cont.isReturnContinuation) {
- continue; // Skip function return continuations.
- }
-
- _processContinuation(cont);
- }
- }
-
- /// Called for each continuation on the work set. Modifies the IR graph if
- /// [cont] is a candidate for redundant phi elimination.
- void _processContinuation(Continuation cont) {
- // Generate the list of all cont invocations. If cont is used in any other
- // context (i.e. as a continuation of InvokeMethod), it is not possible to
- // optimize.
- List<InvokeContinuation> invokes = <InvokeContinuation>[];
- for (Reference ref = cont.firstRef; ref != null; ref = ref.next) {
- Node parent = ref.parent;
- if (parent is InvokeContinuation && ref == parent.continuationRef) {
- invokes.add(parent);
- } else {
- return; // Can't optimize.
- }
- }
-
- if (invokes.isEmpty) {
- return; // Continuation is never invoked, can't optimize.
- }
-
- /// Returns the unique definition of parameter i if it exists and null
- /// otherwise. A definition is unique if it is the only value used to
- /// invoke the continuation, excluding feedback.
- Primitive uniqueDefinitionOf(int i) {
- Primitive value = null;
- for (InvokeContinuation invoke in invokes) {
- Primitive def = invoke.argument(i).effectiveDefinition;
-
- if (cont.parameters[i] == def) {
- // Invocation param == param in LetCont (i.e. a recursive call).
- continue;
- } else if (value == null) {
- value = def; // Set initial comparison value.
- } else if (value != def) {
- return null; // Differing invocation arguments.
- }
- }
-
- return value;
- }
-
- // If uniqueDefinition is in the body of the LetCont binding the
- // continuation, then we will drop the continuation binding to just inside
- // the binding of uniqueDefiniton. This is not safe if we drop the
- // continuation binding inside a LetHandler exception handler binding.
- LetCont letCont = cont.parent;
- bool safeForHandlers(Definition uniqueDefinition) {
- bool seenHandler = false;
- Node current = uniqueDefinition.parent;
- while (current != null) {
- if (current == letCont) return !seenHandler;
- seenHandler = seenHandler || current is LetHandler;
- current = current.parent;
- }
- // When uniqueDefinition is not in the body of the LetCont binding the
- // continuation, we will not move any code, so that is safe.
- return true;
- }
-
- // Check if individual parameters are always called with a unique
- // definition, and remove them if that is the case. During each iteration,
- // we read the current parameter/argument from index `src` and copy it
- // to index `dst`.
- int dst = 0;
- for (int src = 0; src < cont.parameters.length; src++) {
- // Is the current phi redundant?
- Primitive uniqueDefinition = uniqueDefinitionOf(src);
- if (uniqueDefinition == null || !safeForHandlers(uniqueDefinition)) {
- // Reorganize parameters and arguments in case of deletions.
- if (src != dst) {
- cont.parameters[dst] = cont.parameters[src];
- for (InvokeContinuation invoke in invokes) {
- invoke.argumentRefs[dst] = invoke.argumentRefs[src];
- }
- }
- dst++;
- continue;
- }
-
- Primitive oldDefinition = cont.parameters[src];
-
- // Add continuations of about-to-be modified invokes to worklist since
- // we might introduce new optimization opportunities.
- for (Reference ref = oldDefinition.firstRef;
- ref != null;
- ref = ref.next) {
- Node parent = ref.parent;
- if (parent is InvokeContinuation) {
- Continuation thatCont = parent.continuation;
- if (thatCont != cont) {
- workSet.add(thatCont);
- }
- }
- }
-
- // Replace individual parameters:
- // * In the continuation body, replace occurrence of param with value,
- // * and implicitly remove param from continuation signature and
- // invocations by not incrementing `dst`. References of removed
- // arguments are unlinked to keep definition usages up to date.
- oldDefinition.replaceUsesWith(uniqueDefinition);
- for (InvokeContinuation invoke in invokes) {
- invoke.argumentRefs[src].unlink();
- }
-
- // Finally, if the substituted definition is not in scope of the affected
- // continuation, move the continuation binding. This is safe to do since
- // the continuation is referenced only as the target in continuation
- // invokes, and all such invokes must be within the scope of
- // [uniqueDefinition]. Note that this is linear in the depth of
- // the binding of [uniqueDefinition].
- letCont = _makeUniqueBinding(cont);
- _moveIntoScopeOf(letCont, uniqueDefinition);
- }
-
- // Remove trailing items from parameter and argument lists.
- cont.parameters.length = dst;
- for (InvokeContinuation invoke in invokes) {
- invoke.argumentRefs.length = dst;
- }
- }
-
- void processLetCont(LetCont node) {
- node.continuations.forEach(workSet.add);
- }
-}
-
-/// Returns true, iff [letCont] is not scope of [definition].
-/// Linear in the depth of definition within the IR graph.
-bool _isInScopeOf(LetCont letCont, Definition definition) {
- for (Node node = definition.parent; node != null; node = node.parent) {
- if (node == letCont) {
- return false;
- }
- }
-
- return true;
-}
-
-/// Moves [letCont] below the binding of [definition] within the IR graph.
-/// Does nothing if [letCont] is already within the scope of [definition].
-/// Assumes that one argument is nested within the scope of the other
-/// when this method is called.
-void _moveIntoScopeOf(LetCont letCont, Definition definition) {
- if (_isInScopeOf(letCont, definition)) return;
-
- InteriorNode binding = definition.parent;
- letCont.remove();
- letCont.insertBelow(binding);
-}
-
-/// Ensures [continuation] has its own LetCont binding by creating
-/// a new LetCont below its current binding, if necessary.
-///
-/// Returns the LetCont that now binds [continuation].
-LetCont _makeUniqueBinding(Continuation continuation) {
- LetCont letCont = continuation.parent;
- if (letCont.continuations.length == 1) return letCont;
- letCont.continuations.remove(continuation);
- LetCont newBinding = new LetCont(continuation, null);
- continuation.parent = newBinding;
- newBinding.insertBelow(letCont);
- return newBinding;
-}
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/redundant_join.dart ('k') | pkg/compiler/lib/src/cps_ir/redundant_refinement.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698