// Copyright (c) 2015, 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.mutable_ssa;

import 'cps_ir_nodes.dart';
import 'optimizers.dart';

/// Determines which mutable variables should be rewritten to phi assignments
/// in this pass.
///
/// We do not rewrite variables that have an assignment inside a try block that
/// does not contain its declaration.
class MutableVariablePreanalysis extends TrampolineRecursiveVisitor {
  // Number of try blocks enclosing the current position.
  int currentDepth = 0;

  /// Number of try blocks enclosing the declaration of a given mutable
  /// variable.
  ///
  /// All mutable variables seen will be present in the map after the analysis.
  Map<MutableVariable, int> variableDepth = <MutableVariable, int>{};

  /// Variables with an assignment inside a try block that does not contain
  /// its declaration.
  Set<MutableVariable> hasAssignmentInTry = new Set<MutableVariable>();

  @override
  Expression traverseLetHandler(LetHandler node) {
    push(node.handler);
    ++currentDepth;
    pushAction(() => --currentDepth);
    return node.body;
  }

  void processLetMutable(LetMutable node) {
    variableDepth[node.variable] = currentDepth;
  }

  void processSetMutable(SetMutable node) {
    MutableVariable variable = node.variable;
    if (currentDepth > variableDepth[variable]) {
      hasAssignmentInTry.add(variable);
    }
  }

  /// True if there are no mutable variables or they are all assigned inside
  /// a try block. In this case, there is nothing to do and the pass should
  /// be skipped.
  bool get allMutablesAreAssignedInTryBlocks {
    return hasAssignmentInTry.length == variableDepth.length;
  }
}

/// Replaces mutable variables with continuation parameters, effectively
/// bringing them into SSA form.
///
/// This pass is intended to clean up mutable variables that were introduced
/// by an optimization in the type propagation pass.
///
/// This implementation potentially creates a lot of redundant and dead phi
/// parameters. These will be cleaned up by redundant phi elimination and
/// shrinking reductions.
///
/// Discussion:
/// For methods with a lot of mutable variables, creating all the spurious
/// parameters might be too expensive. If this is the case, we should
/// improve this pass to avoid most spurious parameters in practice.
class MutableVariableEliminator implements Pass {
  String get passName => 'Mutable variable elimination';

  /// Mutable variables currently in scope, in order of declaration.
  /// This list determines the order of the corresponding phi parameters.
  final List<MutableVariable> mutableVariables = <MutableVariable>[];

  /// Number of phi parameters added to the given continuation.
  final Map<Continuation, int> continuationPhiCount = <Continuation, int>{};

  /// Stack of yet unprocessed continuations interleaved with the
  /// mutable variables currently in scope.
  ///
  /// Continuations are processed when taken off the stack and mutable
  /// variables fall out of scope (i.e. removed from [mutableVariables]) when
  /// taken off the stack.
  final List<StackItem> stack = <StackItem>[];

  MutableVariablePreanalysis analysis;

  void rewrite(FunctionDefinition node) {
    analysis = new MutableVariablePreanalysis()..visit(node);
    if (analysis.allMutablesAreAssignedInTryBlocks) {
      // Skip the pass if there is nothing to do.
      return;
    }
    processBlock(node.body, <MutableVariable, Primitive>{});
    while (stack.isNotEmpty) {
      StackItem item = stack.removeLast();
      if (item is ContinuationItem) {
        processBlock(item.continuation.body, item.environment);
      } else {
        assert(item is VariableItem);
        mutableVariables.removeLast();
      }
    }
  }

  bool shouldRewrite(MutableVariable variable) {
    return !analysis.hasAssignmentInTry.contains(variable);
  }

  bool isJoinContinuation(Continuation cont) {
    return !cont.hasExactlyOneUse ||
           cont.firstRef.parent is InvokeContinuation;
  }

  /// If some useful source information is attached to exactly one of the
  /// two definitions, the information is copied onto the other.
  void mergeHints(MutableVariable variable, Primitive value) {
    if (variable.hint == null) {
      variable.hint = value.hint;
    } else if (value.hint == null) {
      value.hint = variable.hint;
    }
  }

  /// Processes a basic block, replacing mutable variable uses with direct
  /// references to their values.
  ///
  /// [environment] is the current value of each mutable variable. The map
  /// will be mutated during the processing.
  ///
  /// Continuations to be processed are put on the stack for later processing.
  void processBlock(Expression node,
                    Map<MutableVariable, Primitive> environment) {
    Expression next = node.next;
    for (; node is! TailExpression; node = next, next = node.next) {
      if (node is LetMutable && shouldRewrite(node.variable)) {
        // Put the new mutable variable on the stack while processing the body,
        // and pop it off again when done with the body.
        mutableVariables.add(node.variable);
        stack.add(new VariableItem());

        // Put the initial value into the environment.
        Primitive value = node.value;
        environment[node.variable] = value;

        // Preserve variable names.
        mergeHints(node.variable, value);

        // Remove the mutable variable binding.
        node.valueRef.unlink();
        node.remove();
      } else if (node is LetPrim && node.primitive is SetMutable) {
        SetMutable setter = node.primitive;
        MutableVariable variable = setter.variable;
        if (shouldRewrite(variable)) {
          // As above, update the environment, preserve variables and remove
          // the mutable variable assignment.
          environment[variable] = setter.value;
          mergeHints(variable, setter.value);
          setter.valueRef.unlink();
          node.remove();
        }
      } else if (node is LetPrim && node.primitive is GetMutable) {
        GetMutable getter = node.primitive;
        MutableVariable variable = getter.variable;
        if (shouldRewrite(variable)) {
          // Replace with the reaching definition from the environment.
          Primitive value = environment[variable];
          getter.replaceUsesWith(value);
          mergeHints(variable, value);
          node.remove();
        }
      } else if (node is LetCont) {
        // Create phi parameters for each join continuation bound here, and put
        // them on the stack for later processing.
        // Note that non-join continuations are handled at the use-site.
        for (Continuation cont in node.continuations) {
          if (!isJoinContinuation(cont)) continue;
          // Create a phi parameter for every mutable variable in scope.
          // At the same time, build the environment to use for processing
          // the continuation (mapping mutables to phi parameters).
          continuationPhiCount[cont] = mutableVariables.length;
          Map<MutableVariable, Primitive> environment =
              <MutableVariable, Primitive>{};
          for (MutableVariable variable in mutableVariables) {
            Parameter phi = new Parameter(variable.hint);
            phi.type = variable.type;
            cont.parameters.add(phi);
            phi.parent = cont;
            environment[variable] = phi;
          }
          stack.add(new ContinuationItem(cont, environment));
        }
      } else if (node is LetHandler) {
        // Process the catch block later and continue into the try block.
        // We can use the same environment object for the try and catch blocks.
        // The current environment bindings cannot change inside the try block
        // because we exclude all variables assigned inside a try block.
        // The environment might be extended with more bindings before we
        // analyze the catch block, but that's ok.
        stack.add(new ContinuationItem(node.handler, environment));
      }
    }

    // Analyze the terminal node.
    if (node is InvokeContinuation) {
      Continuation cont = node.continuation;
      if (cont.isReturnContinuation) return;
      // This is a call to a join continuation. Add arguments for the phi
      // parameters that were added to this continuation.
      int phiCount = continuationPhiCount[cont];
      for (int i = 0; i < phiCount; ++i) {
        Primitive value = environment[mutableVariables[i]];
        Reference<Primitive> arg = new Reference<Primitive>(value);
        node.argumentRefs.add(arg);
        arg.parent = node;
      }
    } else if (node is Branch) {
      // Enqueue both branches with the current environment.
      // Clone the environments once so the processing of one branch does not
      // mutate the environment needed to process the other branch.
      stack.add(new ContinuationItem(
          node.trueContinuation,
          new Map<MutableVariable, Primitive>.from(environment)));
      stack.add(new ContinuationItem(
          node.falseContinuation,
          environment));
    } else {
      assert(node is Throw || node is Unreachable);
    }
  }
}

abstract class StackItem {}

/// Represents a mutable variable that is in scope.
///
/// The topmost mutable variable falls out of scope when this item is
/// taken off the stack.
class VariableItem extends StackItem {}

/// Represents a yet unprocessed continuation together with the
/// environment in which to process it.
class ContinuationItem extends StackItem {
  final Continuation continuation;
  final Map<MutableVariable, Primitive> environment;

  ContinuationItem(this.continuation, this.environment);
}
