// Copyright (c) 2011, 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.

// @dart = 2.10

import 'nodes.dart';

class HValidator extends HInstructionVisitor {
  bool isValid = true;
  HGraph graph;

  void visitGraph(HGraph visitee) {
    graph = visitee;
    visitDominatorTree(visitee);
  }

  void markInvalid(String reason) {
    print('Invalid: $reason');
    isValid = false;
  }

  // Note that during construction of the Ssa graph the basic blocks are
  // not required to be valid yet.
  @override
  void visitBasicBlock(HBasicBlock block) {
    currentBlock = block;
    if (!isValid) return; // Don't need to continue if we are already invalid.

    // Test that the last instruction is a branching instruction and that the
    // basic block contains the branch-target.
    if (block.first == null || block.last == null) {
      markInvalid("empty block");
    }
    if (block.last is! HControlFlow) {
      markInvalid("block ends with non-tail node.");
    }
    if (block.last is HIf && block.successors.length != 2) {
      markInvalid("If node without two successors");
    }
    if (block.last is HConditionalBranch && block.successors.length != 2) {
      markInvalid("Conditional node without two successors");
    }
    if (block.last is HLoopBranch) {
      // Assert that the block we inserted to avoid critical edges satisfies
      // our assumptions. That is, it must not contain any instructions
      // (although it may contain phi-updates).
      HBasicBlock avoidCriticalEdgeBlock = block.successors.last;
      if (avoidCriticalEdgeBlock.first is! HGoto) {
        markInvalid("Critical edge block contains instructions");
      }
    }
    if (block.last is HGoto && block.successors.length != 1) {
      markInvalid("Goto node with not exactly one successor");
    }
    if (block.last is HJump && block.successors.length != 1) {
      markInvalid("Break or continue node without one successor");
    }
    if ((block.last is HReturn || block.last is HThrow) &&
        (block.successors.length != 1 || !block.successors[0].isExitBlock())) {
      markInvalid("Return or throw node with > 1 successor "
          "or not going to exit-block");
    }
    if (block.last is HExit && !block.successors.isEmpty) {
      markInvalid("Exit block with successor");
    }

    if (block.successors.isEmpty && !block.isExitBlock()) {
      markInvalid("Non-exit block without successor");
    }

    // Check that successors ids are always higher than the current one.
    // TODO(floitsch): this is, of course, not true for back-branches.
    if (block.id == null) markInvalid("block without id");
    for (HBasicBlock successor in block.successors) {
      if (!isValid) break;
      if (successor.id == null) markInvalid("successor without id");
      if (successor.id <= block.id && !successor.isLoopHeader()) {
        markInvalid("successor with lower id, but not a loop-header");
      }
    }
    // Make sure we don't have a critical edge.
    if (isValid &&
        block.successors.length > 1 &&
        block.last is! HTry &&
        block.last is! HExitTry &&
        block.last is! HSwitch) {
      for (HBasicBlock successor in block.successors) {
        if (!isValid) break;
        if (successor.predecessors.length >= 2) {
          markInvalid("SSA graph contains critical edge.");
        }
      }
    }

    // Check that the entries in the dominated-list are sorted.
    int lastId = 0;
    for (HBasicBlock dominated in block.dominatedBlocks) {
      if (!isValid) break;
      if (!identical(dominated.dominator, block)) {
        markInvalid("dominated block not pointing back");
      }
      if (dominated.id == null || dominated.id <= lastId) {
        markInvalid("dominated.id == null or dominated has <= id");
      }
      lastId = dominated.id;
    }

    if (!isValid) return;
    block.forEachPhi(visitInstruction);

    // Check that the blocks of the parameters of a phi are dominating the
    // corresponding predecessor block. Note that a block dominates
    // itself.
    block.forEachPhi((HPhi phi) {
      assert(phi.inputs.length <= block.predecessors.length);
      for (int i = 0; i < phi.inputs.length; i++) {
        HInstruction input = phi.inputs[i];
        if (!input.block.dominates(block.predecessors[i])) {
          markInvalid("Definition does not dominate use");
        }
      }
    });

    // Check that the blocks of the inputs of an instruction dominate the
    // instruction's block.
    block.forEachInstruction((HInstruction instruction) {
      for (HInstruction input in instruction.inputs) {
        if (!input.block.dominates(block)) {
          markInvalid("Definition does not dominate use");
        }
      }
    });

    super.visitBasicBlock(block);
  }

  // Limit for the size of `inputs` and `usedBy` lists. We assume lists longer
  // than this are OK in order to avoid the O(N^2) validation getting out of
  // hand.
  //
  // Poster child: corelib_2/regexp/pcre_test.dart, which has a 7KLOC main().
  static const int kMaxValidatedInstructionListLength = 1000;

  /// Verifies [instruction] is contained in [instructions] [count] times.
  static bool checkInstructionCount(
      List<HInstruction> instructions, HInstruction instruction, int count) {
    if (instructions.length > kMaxValidatedInstructionListLength) return true;
    int result = 0;
    for (int i = 0; i < instructions.length; i++) {
      if (identical(instructions[i], instruction)) result++;
    }
    return result == count;
  }

  /// Returns true if the predicate returns true for every instruction in the
  /// list. The argument to [f] is an instruction with the count of how often
  /// it appeared in the list [instructions].
  static bool everyInstruction(
      List<HInstruction> instructions, bool Function(HInstruction, int) f) {
    if (instructions.length > kMaxValidatedInstructionListLength) return true;
    var copy = List<HInstruction>.from(instructions);
    // TODO(floitsch): there is currently no way to sort HInstructions before
    // we have assigned an ID. The loop is therefore O(n^2) for now.
    for (int i = 0; i < copy.length; i++) {
      var current = copy[i];
      if (current == null) continue;
      int count = 1;
      for (int j = i + 1; j < copy.length; j++) {
        if (identical(copy[j], current)) {
          copy[j] = null;
          count++;
        }
      }
      if (!f(current, count)) return false;
    }
    return true;
  }

  @override
  void visitInstruction(HInstruction instruction) {
    // Verifies that we are in the use list of our inputs.
    bool hasCorrectInputs() {
      bool inBasicBlock = instruction.isInBasicBlock();
      return everyInstruction(instruction.inputs, (input, count) {
        if (inBasicBlock) {
          return input.isInBasicBlock() &&
              checkInstructionCount(input.usedBy, instruction, count);
        } else {
          return checkInstructionCount(input.usedBy, instruction, 0);
        }
      });
    }

    // Verifies that all our uses have us in their inputs.
    bool hasCorrectUses() {
      if (!instruction.isInBasicBlock()) return true;
      return everyInstruction(instruction.usedBy, (use, count) {
        return use.isInBasicBlock() &&
            checkInstructionCount(use.inputs, instruction, count);
      });
    }

    if (!identical(instruction.block, currentBlock)) {
      markInvalid("Instruction in wrong block");
    }
    if (!hasCorrectInputs()) {
      markInvalid("Incorrect inputs");
    }
    if (!hasCorrectUses()) {
      markInvalid("Incorrect uses");
    }

    if (instruction is HLocalGet) {
      if (instruction.inputs.length != 1) {
        markInvalid('HLocalGet has one input');
      }
      HInstruction input = instruction.inputs.first;
      if (input is! HLocalValue) {
        markInvalid('Incorrect input ${input.runtimeType} to HLocalGet');
      }
    }
  }
}

/// Validate that the graph contains no unused phi nodes.
///
///     assert(NoUnusedPhiValidator.containsNoUnusedPhis(graph));
class NoUnusedPhiValidator extends HGraphVisitor {
  bool isValid = true;

  static bool containsNoUnusedPhis(HGraph graph) {
    final validator = NoUnusedPhiValidator();
    validator.visitDominatorTree(graph);
    return validator.isValid;
  }

  @override
  void visitBasicBlock(HBasicBlock block) {
    block.forEachPhi(visitPhi);
  }

  void visitPhi(HPhi phi) {
    if (phi.usedBy.isEmpty) {
      print('Unused $phi in B${phi.block.id}');
      isValid = false;
    }
  }
}
