// 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.loop_hierarchy;

import 'cps_ir_nodes.dart';
import 'cps_fragment.dart';

/// Determines the effective nesting of loops.
///
/// The effective nesting of loops is different from the lexical nesting, since
/// recursive continuations can generally contain all the code following
/// after the loop in addition to the looping code itself.
///
/// For example, the 'else' branch below is not effectively part of the loop:
///
///   let rec kont x =
///     if (<loop condition>)
///       <loop body>
///       InvokeContinuation kont x'
///     else
///       <after loop>
///       return p.foo()
///
/// We use the term "loop" to mean recursive continuation.
/// The `null` value is used to represent a context not part of any loop.
class LoopHierarchy {
  /// Nesting depth of the given loop.
  Map<Continuation, int> loopDepth = <Continuation, int>{};

  /// The innermost loop (other than itself) that may be invoked recursively
  /// as a result of invoking the given continuation.
  Map<Continuation, Continuation> loopTarget = <Continuation, Continuation>{};

  /// Current nesting depth.
  int _currentDepth = 0;

  /// The loop target to use for missing code.  Used by [update].
  Continuation _exitLoop;

  /// Computes the loop hierarchy for the given function.
  ///
  /// Parent pointers must be computed for [node].
  LoopHierarchy(FunctionDefinition node) {
    _processBlock(node.body, null);
  }

  /// Returns the innermost loop which [cont] is effectively part of.
  Continuation getLoopHeader(Continuation cont) {
    return cont.isRecursive ? cont : loopTarget[cont];
  }

  /// Returns the innermost loop which the given continuation is part of, other
  /// than itself.
  Continuation getEnclosingLoop(Continuation cont) {
    return loopTarget[cont];
  }

  /// Marks the innermost loop as a subloop of the other loop.
  ///
  /// Returns the innermost loop.
  ///
  /// Both continuations, [c1] and [c2] may be null (i.e. no loop).
  ///
  /// A loop is said to be a subloop of an enclosing loop if it can invoke
  /// that loop recursively. This information is stored in [loopTarget].
  ///
  /// This method is only invoked with two distinct loops if there is a
  /// point that can reach a recursive invocation of both loops.
  /// This implies that one loop is nested in the other, because they must
  /// both be in scope at that point.
  Continuation _markInnerLoop(Continuation c1, Continuation c2) {
    assert(c1 == null || c1.isRecursive);
    assert(c2 == null || c2.isRecursive);
    if (c1 == null) return c2;
    if (c2 == null) return c1;
    if (c1 == c2) return c1;
    if (loopDepth[c1] > loopDepth[c2]) {
      loopTarget[c1] = _markInnerLoop(loopTarget[c1], c2);
      return c1;
    } else {
      loopTarget[c2] = _markInnerLoop(loopTarget[c2], c1);
      return c2;
    }
  }

  /// Analyzes the body of [cont] and returns the innermost loop
  /// that can be invoked recursively from [cont] (other than [cont] itself).
  ///
  /// [catchLoop] is the innermost loop that can be invoked recursively
  /// from the current exception handler.
  Continuation _processContinuation(Continuation cont, Continuation catchLoop) {
    if (cont.isRecursive) {
      ++_currentDepth;
      loopDepth[cont] = _currentDepth;
      Continuation target = _processBlock(cont.body, catchLoop);
      _markInnerLoop(loopTarget[cont], target);
      --_currentDepth;
    } else {
      loopTarget[cont] = _processBlock(cont.body, catchLoop);
    }
    return loopTarget[cont];
  }

  /// Analyzes a basic block and returns the innermost loop that
  /// can be invoked recursively from that block.
  Continuation _processBlock(Expression node, Continuation catchLoop) {
    for (; node != null && node is! TailExpression; node = node.next) {
      if (node is LetCont) {
        for (Continuation cont in node.continuations) {
          _processContinuation(cont, catchLoop);
        }
      } else if (node is LetHandler) {
        catchLoop = _processContinuation(node.handler, catchLoop);
      }
    }
    Continuation target;
    if (node is InvokeContinuation) {
      if (node.isRecursive) {
        target = node.continuation.definition;
      } else {
        target = loopTarget[node.continuation.definition];
      }
    } else if (node is Branch) {
      target = _markInnerLoop(
          loopTarget[node.trueContinuation.definition],
          loopTarget[node.falseContinuation.definition]);
    } else if (node == null) {
      // If the code ends abruptly, use the exit loop provided in [update].
      target = _exitLoop;
    } else {
      assert(node is Unreachable || node is Throw || node == null);
    }
    return _markInnerLoop(target, catchLoop);
  }

  /// Returns the the innermost loop that effectively encloses both
  /// c1 and c2 (or `null` if there is no such loop).
  Continuation lowestCommonAncestor(Continuation c1, Continuation c2) {
    int d1 = getDepth(c1), d2 = getDepth(c2);
    while (c1 != c2) {
      if (d1 <= d2) {
        c2 = getEnclosingLoop(c2);
        d2 = getDepth(c2);
      } else {
        c1 = getEnclosingLoop(c1);
        d1 = getDepth(c1);
      }
    }
    return c1;
  }

  /// Returns the lexical nesting depth of [loop].
  int getDepth(Continuation loop) {
    if (loop == null) return 0;
    return loopDepth[loop];
  }

  /// Sets the loop header for each continuation bound inside the given
  /// fragment.
  ///
  /// If the fragment is open, [exitLoop] denotes the loop header for
  /// the code that will occur after the fragment.
  ///
  /// [catchLoop] is the loop target for the catch clause of the try/catch
  /// surrounding the inserted fragment.
  void update(CpsFragment fragment,
              {Continuation exitLoop,
               Continuation catchLoop}) {
    if (fragment.isEmpty) return;
    _exitLoop = exitLoop;
    _currentDepth = getDepth(exitLoop);
    _processBlock(fragment.root, catchLoop);
    _exitLoop = null;
  }
}
