// 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;
      } else {
        target = loopTarget[node.continuation];
      }
    } else if (node is Branch) {
      target = _markInnerLoop(loopTarget[node.trueContinuation],
          loopTarget[node.falseContinuation]);
    } 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;
  }
}
