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

import 'dart:async' show EventSink;
import 'cps_ir_nodes.dart' as cps_ir;
import '../tracer.dart';

/**
 * If true, show LetCont expressions in output.
 */
const bool IR_TRACE_LET_CONT = false;

class IRTracer extends TracerUtil implements cps_ir.Visitor {
  EventSink<String> output;

  IRTracer(this.output);

  visit(cps_ir.Node node) => node.accept(this);

  void traceGraph(String name, cps_ir.FunctionDefinition node) {
    tag("cfg", () {
      printProperty("name", name);

      names = new Names();
      BlockCollector builder = new BlockCollector(names);
      builder.visit(node);

      for (Block block in builder.entries) {
        printBlock(block, entryPoint: node);
      }
      for (Block block in builder.cont2block.values) {
        printBlock(block);
      }
      names = null;
    });
  }

  // Temporary field used during tree walk
  Names names;

  visitFunctionDefinition(cps_ir.FunctionDefinition node) {
    unexpectedNode(node);
  }

  // Bodies and initializers are not visited.  They contain continuations which
  // are found by a BlockCollector, then those continuations are processed by
  // this visitor.
  unexpectedNode(cps_ir.Node node) {
    throw 'The IR tracer reached an unexpected IR instruction: $node';
  }

  int countUses(cps_ir.Definition definition) {
    int count = 0;
    cps_ir.Reference ref = definition.firstRef;
    while (ref != null) {
      ++count;
      ref = ref.next;
    }
    return count;
  }

  /// If [entryPoint] is given, this block is an entry point.
  printBlock(Block block, {cps_ir.FunctionDefinition entryPoint}) {
    tag("block", () {
      printProperty("name", block.name);
      printProperty("from_bci", -1);
      printProperty("to_bci", -1);
      printProperty("predecessors", block.pred.map((n) => n.name));
      printProperty("successors", block.succ.map((n) => n.name));
      printEmptyProperty("xhandlers");
      printEmptyProperty("flags");
      tag("states", () {
        tag("locals", () {
          printProperty("size", 0);
          printProperty("method", "None");
        });
      });
      tag("HIR", () {
        String formatParameter(cps_ir.Parameter param) {
          return '${names.name(param)} ${param.type}';
        }
        if (entryPoint != null) {
          String thisParam = entryPoint.receiverParameter != null
              ? formatParameter(entryPoint.receiverParameter)
              : 'no receiver';
          String interceptorParam = entryPoint.interceptorParameter != null
              ? formatParameter(entryPoint.interceptorParameter)
              : 'no interceptor';
          String params = entryPoint.parameters.map(formatParameter).join(', ');
          printStmt('x0', 'Entry ($interceptorParam) ($thisParam) ($params)');
        }
        String params = block.parameters.map(formatParameter).join(', ');
        printStmt('x0', 'Parameters ($params)');
        visit(block.body);
      });
    });
  }

  void printStmt(String resultVar, String contents) {
    int bci = 0;
    int uses = 0;
    addIndent();
    add("$bci $uses $resultVar $contents <|@\n");
  }

  visitLetPrim(cps_ir.LetPrim node) {
    String id = names.name(node.primitive);
    String primitive = visit(node.primitive);
    printStmt(id, "LetPrim $id = $primitive [type=${node.primitive.type}]");
    visit(node.body);
  }

  visitLetCont(cps_ir.LetCont node) {
    if (IR_TRACE_LET_CONT) {
      String dummy = names.name(node);

      String nameContinuation(cps_ir.Continuation cont) {
        String name = names.name(cont);
        return cont.isRecursive ? '$name*' : name;
      }

      String ids = node.continuations.map(nameContinuation).join(', ');
      printStmt(dummy, "LetCont $ids");
    }
    visit(node.body);
  }

  visitLetHandler(cps_ir.LetHandler node) {
    if (IR_TRACE_LET_CONT) {
      String dummy = names.name(node);
      String id = names.name(node.handler);
      printStmt(dummy, "LetHandler $id = <$id>");
    }
    visit(node.body);
  }

  visitLetMutable(cps_ir.LetMutable node) {
    String id = names.name(node.variable);
    printStmt(id, "LetMutable $id = ${formatReference(node.valueRef)}");
    visit(node.body);
  }

  visitInvokeStatic(cps_ir.InvokeStatic node) {
    String callName = node.selector.name;
    String args = node.argumentRefs.map(formatReference).join(', ');
    return "InvokeStatic $callName ($args)";
  }

  visitInvokeMethod(cps_ir.InvokeMethod node) {
    String receiver = formatReference(node.receiverRef);
    String callName = node.selector.name;
    String args = node.argumentRefs.map(formatReference).join(', ');
    return "InvokeMethod $receiver $callName ($args)";
  }

  visitInvokeMethodDirectly(cps_ir.InvokeMethodDirectly node) {
    String receiver = formatReference(node.receiverRef);
    String callName = node.selector.name;
    String args = node.argumentRefs.map(formatReference).join(', ');
    return "InvokeMethodDirectly $receiver $callName ($args)";
  }

  visitInvokeConstructor(cps_ir.InvokeConstructor node) {
    String className = node.target.enclosingClass.name;
    String callName;
    if (node.target.name.isEmpty) {
      callName = '${className}';
    } else {
      callName = '${className}.${node.target.name}';
    }
    String args = node.argumentRefs.map(formatReference).join(', ');
    return "InvokeConstructor $callName ($args)";
  }

  visitThrow(cps_ir.Throw node) {
    String dummy = names.name(node);
    String value = formatReference(node.valueRef);
    printStmt(dummy, "Throw $value");
  }

  visitRethrow(cps_ir.Rethrow node) {
    String dummy = names.name(node);
    printStmt(dummy, "Rethrow");
  }

  visitUnreachable(cps_ir.Unreachable node) {
    String dummy = names.name(node);
    printStmt(dummy, 'Unreachable');
  }

  visitLiteralList(cps_ir.LiteralList node) {
    String values = node.valueRefs.map(formatReference).join(', ');
    return "LiteralList ($values)";
  }

  visitTypeCast(cps_ir.TypeCast node) {
    String value = formatReference(node.valueRef);
    String args = node.typeArgumentRefs.map(formatReference).join(', ');
    return "TypeCast ($value ${node.dartType} ($args))";
  }

  visitInvokeContinuation(cps_ir.InvokeContinuation node) {
    String dummy = names.name(node);
    String kont = formatReference(node.continuationRef);
    String args = node.argumentRefs.map(formatReference).join(', ');
    printStmt(dummy, "InvokeContinuation $kont ($args)");
  }

  visitBranch(cps_ir.Branch node) {
    String dummy = names.name(node);
    String condition = formatReference(node.conditionRef);
    String trueCont = formatReference(node.trueContinuationRef);
    String falseCont = formatReference(node.falseContinuationRef);
    String strict = node.isStrictCheck ? "Strict" : "NonStrict";
    printStmt(dummy, "Branch $condition ($trueCont, $falseCont) $strict");
  }

  visitAwait(cps_ir.Await node) {
    String value = formatReference(node.inputRef);
    return 'Await $value';
  }

  visitYield(cps_ir.Yield node) {
    String name = node.hasStar ? 'YieldStar' : 'Yield';
    String value = formatReference(node.inputRef);
    return '$name $value';
  }

  visitSetMutable(cps_ir.SetMutable node) {
    String variable = names.name(node.variable);
    String value = formatReference(node.valueRef);
    return 'SetMutable $variable := $value';
  }

  String formatReference(cps_ir.Reference ref) {
    if (ref == null) return 'null';
    cps_ir.Definition target = ref.definition;
    if (target is cps_ir.Continuation && target.isReturnContinuation) {
      return "return"; // Do not generate a name for the return continuation
    } else {
      return names.name(ref.definition);
    }
  }

  visitConstant(cps_ir.Constant node) {
    return "Constant ${node.value.toStructuredString()}";
  }

  visitParameter(cps_ir.Parameter node) {
    return "Parameter ${names.name(node)}";
  }

  visitMutableVariable(cps_ir.MutableVariable node) {
    return "MutableVariable ${names.name(node)}";
  }

  visitContinuation(cps_ir.Continuation node) {
    return "Continuation ${names.name(node)}";
  }

  visitSetField(cps_ir.SetField node) {
    String object = formatReference(node.objectRef);
    String field = node.field.name;
    String value = formatReference(node.valueRef);
    return 'SetField $object.$field = $value';
  }

  visitGetField(cps_ir.GetField node) {
    String object = formatReference(node.objectRef);
    String field = node.field.name;
    String finalFlag = node.isFinal ? 'final' : 'non-final';
    return 'GetField $object.$field $finalFlag';
  }

  visitGetStatic(cps_ir.GetStatic node) {
    String element = node.element.name;
    String finalFlag = node.isFinal ? 'final' : 'non-final';
    return 'GetStatic $element $finalFlag';
  }

  visitSetStatic(cps_ir.SetStatic node) {
    String element = node.element.name;
    String value = formatReference(node.valueRef);
    return 'SetStatic $element = $value';
  }

  visitGetLazyStatic(cps_ir.GetLazyStatic node) {
    String element = node.element.name;
    String finalFlag = node.isFinal ? 'final' : 'non-final';
    return "GetLazyStatic $element $finalFlag";
  }

  visitCreateBox(cps_ir.CreateBox node) {
    return 'CreateBox';
  }

  visitCreateInstance(cps_ir.CreateInstance node) {
    String className = node.classElement.name;
    String arguments = node.argumentRefs.map(formatReference).join(', ');
    String typeInformation = formatReference(node.typeInformationRef);
    return 'CreateInstance $className ($arguments) <$typeInformation>';
  }

  visitInterceptor(cps_ir.Interceptor node) {
    return 'Interceptor(${formatReference(node.inputRef)}, '
        '${node.interceptedClasses})';
  }

  visitGetMutable(cps_ir.GetMutable node) {
    String variable = names.name(node.variable);
    return 'GetMutable $variable';
  }

  visitReadTypeVariable(cps_ir.ReadTypeVariable node) {
    return "ReadTypeVariable ${node.variable.element} "
        "${formatReference(node.targetRef)}";
  }

  visitReifyRuntimeType(cps_ir.ReifyRuntimeType node) {
    return "ReifyRuntimeType ${formatReference(node.valueRef)}";
  }

  visitTypeExpression(cps_ir.TypeExpression node) {
    return "TypeExpression ${node.kindAsString} ${node.dartType}"
        "${node.argumentRefs.map(formatReference).join(', ')}";
  }

  visitCreateInvocationMirror(cps_ir.CreateInvocationMirror node) {
    String args = node.argumentRefs.map(formatReference).join(', ');
    return "CreateInvocationMirror(${node.selector.name}, $args)";
  }

  visitTypeTest(cps_ir.TypeTest node) {
    String value = formatReference(node.valueRef);
    String args = node.typeArgumentRefs.map(formatReference).join(', ');
    return "TypeTest ($value ${node.dartType} ($args))";
  }

  visitTypeTestViaFlag(cps_ir.TypeTestViaFlag node) {
    String interceptor = formatReference(node.interceptorRef);
    return "TypeTestViaFlag ($interceptor ${node.dartType})";
  }

  visitApplyBuiltinOperator(cps_ir.ApplyBuiltinOperator node) {
    String operator = node.operator.toString();
    String args = node.argumentRefs.map(formatReference).join(', ');
    return 'ApplyBuiltinOperator $operator ($args)';
  }

  visitApplyBuiltinMethod(cps_ir.ApplyBuiltinMethod node) {
    String method = node.method.toString();
    String receiver = formatReference(node.receiverRef);
    String args = node.argumentRefs.map(formatReference).join(', ');
    return 'ApplyBuiltinMethod $method $receiver ($args)';
  }

  visitForeignCode(cps_ir.ForeignCode node) {
    String id = names.name(node);
    String arguments = node.argumentRefs.map(formatReference).join(', ');
    printStmt(
        id, "ForeignCode ${node.type} ${node.codeTemplate.source} $arguments");
  }

  visitGetLength(cps_ir.GetLength node) {
    String object = formatReference(node.objectRef);
    String finalFlag = node.isFinal ? 'final' : 'non-final';
    return 'GetLength $object $finalFlag';
  }

  visitGetIndex(cps_ir.GetIndex node) {
    String object = formatReference(node.objectRef);
    String index = formatReference(node.indexRef);
    return 'GetIndex $object $index';
  }

  visitSetIndex(cps_ir.SetIndex node) {
    String object = formatReference(node.objectRef);
    String index = formatReference(node.indexRef);
    String value = formatReference(node.valueRef);
    return 'SetIndex $object $index $value';
  }

  visitRefinement(cps_ir.Refinement node) {
    String value = formatReference(node.value);
    return 'Refinement $value ${node.refineType}';
  }

  visitBoundsCheck(cps_ir.BoundsCheck node) {
    String object = formatReference(node.objectRef);
    String index =
        node.indexRef == null ? 'no-index' : formatReference(node.indexRef);
    String length =
        node.lengthRef == null ? 'no-length' : formatReference(node.lengthRef);
    return 'BoundsCheck $object $index $length ${node.checkString}';
  }

  visitReceiverCheck(cps_ir.ReceiverCheck node) {
    String value = formatReference(node.valueRef);
    String condition = formatReference(node.conditionRef);
    return 'ReceiverCheck $value $condition ${node.selector} '
        '${node.flagString}';
  }
}

/**
 * Invents (and remembers) names for Continuations, Parameters, etc.
 * The names must match the conventions used by IR Hydra, e.g.
 * Continuations and Functions must have names of form B### since they
 * are visualized as basic blocks.
 */
class Names {
  final Map<Object, String> names = {};
  final Map<String, int> counters = {'r': 0, 'B': 0, 'v': 0, 'x': 0, 'c': 0};

  String prefix(x) {
    if (x is cps_ir.Parameter) return 'r';
    if (x is cps_ir.Continuation || x is cps_ir.FunctionDefinition) return 'B';
    if (x is cps_ir.Primitive) return 'v';
    if (x is cps_ir.MutableVariable) return 'c';
    return 'x';
  }

  String name(x) {
    String nam = names[x];
    if (nam == null) {
      String pref = prefix(x);
      int id = counters[pref]++;
      nam = names[x] = '${pref}${id}';
    }
    return nam;
  }
}

/**
 * A vertex in the graph visualization, used in place of basic blocks.
 */
class Block {
  String name;
  final List<cps_ir.Parameter> parameters;
  final cps_ir.Expression body;
  final List<Block> succ = <Block>[];
  final List<Block> pred = <Block>[];

  Block(this.name, this.parameters, this.body);

  void addEdgeTo(Block successor) {
    succ.add(successor);
    successor.pred.add(this);
  }
}

class BlockCollector implements cps_ir.Visitor {
  final Map<cps_ir.Continuation, Block> cont2block =
      <cps_ir.Continuation, Block>{};
  final Set<Block> entries = new Set<Block>();
  Block currentBlock;

  Names names;
  BlockCollector(this.names);

  Block getBlock(cps_ir.Continuation c) {
    Block block = cont2block[c];
    if (block == null) {
      block = new Block(names.name(c), c.parameters, c.body);
      cont2block[c] = block;
    }
    return block;
  }

  visit(cps_ir.Node node) => node.accept(this);

  visitFunctionDefinition(cps_ir.FunctionDefinition node) {
    currentBlock = new Block(names.name(node), [], node.body);
    entries.add(currentBlock);
    visit(node.body);
  }

  visitLetPrim(cps_ir.LetPrim exp) {
    visit(exp.body);
  }

  visitLetCont(cps_ir.LetCont exp) {
    exp.continuations.forEach(visit);
    visit(exp.body);
  }

  visitLetHandler(cps_ir.LetHandler exp) {
    visit(exp.handler);
    visit(exp.body);
  }

  visitLetMutable(cps_ir.LetMutable exp) {
    visit(exp.body);
  }

  void addEdgeToContinuation(cps_ir.Reference continuation) {
    cps_ir.Definition target = continuation.definition;
    if (target is cps_ir.Continuation && !target.isReturnContinuation) {
      currentBlock.addEdgeTo(getBlock(target));
    }
  }

  visitInvokeContinuation(cps_ir.InvokeContinuation exp) {
    addEdgeToContinuation(exp.continuationRef);
  }

  visitInvokeStatic(cps_ir.InvokeStatic node) {
    unexpectedNode(node);
  }

  visitInvokeMethod(cps_ir.InvokeMethod node) {
    unexpectedNode(node);
  }

  visitInvokeMethodDirectly(cps_ir.InvokeMethodDirectly node) {
    unexpectedNode(node);
  }

  visitInvokeConstructor(cps_ir.InvokeConstructor node) {
    unexpectedNode(node);
  }

  visitThrow(cps_ir.Throw exp) {}

  visitRethrow(cps_ir.Rethrow exp) {}

  visitUnreachable(cps_ir.Unreachable node) {}

  visitGetLazyStatic(cps_ir.GetLazyStatic node) {
    unexpectedNode(node);
  }

  visitBranch(cps_ir.Branch exp) {
    cps_ir.Continuation trueTarget = exp.trueContinuation;
    if (!trueTarget.isReturnContinuation) {
      currentBlock.addEdgeTo(getBlock(trueTarget));
    }
    cps_ir.Continuation falseTarget = exp.falseContinuation;
    if (!falseTarget.isReturnContinuation) {
      currentBlock.addEdgeTo(getBlock(falseTarget));
    }
  }

  visitTypeCast(cps_ir.TypeCast node) {
    unexpectedNode(node);
  }

  visitContinuation(cps_ir.Continuation c) {
    var old_node = currentBlock;
    currentBlock = getBlock(c);
    visit(c.body);
    currentBlock = old_node;
  }

  // Primitives and conditions are not visited when searching for blocks.
  unexpectedNode(cps_ir.Node node) {
    throw "The IR tracer's block collector reached an unexpected IR "
        "instruction: $node";
  }

  visitLiteralList(cps_ir.LiteralList node) {
    unexpectedNode(node);
  }

  visitConstant(cps_ir.Constant node) {
    unexpectedNode(node);
  }

  visitGetMutable(cps_ir.GetMutable node) {
    unexpectedNode(node);
  }

  visitParameter(cps_ir.Parameter node) {
    unexpectedNode(node);
  }

  visitMutableVariable(cps_ir.MutableVariable node) {
    unexpectedNode(node);
  }

  visitGetField(cps_ir.GetField node) {
    unexpectedNode(node);
  }

  visitGetStatic(cps_ir.GetStatic node) {
    unexpectedNode(node);
  }

  visitCreateBox(cps_ir.CreateBox node) {
    unexpectedNode(node);
  }

  visitCreateInstance(cps_ir.CreateInstance node) {
    unexpectedNode(node);
  }

  visitInterceptor(cps_ir.Interceptor node) {
    unexpectedNode(node);
  }

  visitReadTypeVariable(cps_ir.ReadTypeVariable node) {
    unexpectedNode(node);
  }

  visitReifyRuntimeType(cps_ir.ReifyRuntimeType node) {
    unexpectedNode(node);
  }

  visitTypeExpression(cps_ir.TypeExpression node) {
    unexpectedNode(node);
  }

  visitCreateInvocationMirror(cps_ir.CreateInvocationMirror node) {
    unexpectedNode(node);
  }

  visitTypeTest(cps_ir.TypeTest node) {
    unexpectedNode(node);
  }

  visitTypeTestViaFlag(cps_ir.TypeTestViaFlag node) {
    unexpectedNode(node);
  }

  visitApplyBuiltinOperator(cps_ir.ApplyBuiltinOperator node) {
    unexpectedNode(node);
  }

  visitApplyBuiltinMethod(cps_ir.ApplyBuiltinMethod node) {
    unexpectedNode(node);
  }

  visitGetLength(cps_ir.GetLength node) {
    unexpectedNode(node);
  }

  visitGetIndex(cps_ir.GetIndex node) {
    unexpectedNode(node);
  }

  visitSetIndex(cps_ir.SetIndex node) {
    unexpectedNode(node);
  }

  visitSetMutable(cps_ir.SetMutable node) {
    unexpectedNode(node);
  }

  visitSetField(cps_ir.SetField node) {
    unexpectedNode(node);
  }

  visitSetStatic(cps_ir.SetStatic node) {
    unexpectedNode(node);
  }

  visitForeignCode(cps_ir.ForeignCode node) {
    unexpectedNode(node);
  }

  visitAwait(cps_ir.Await node) {
    unexpectedNode(node);
  }

  visitYield(cps_ir.Yield node) {
    unexpectedNode(node);
  }

  visitRefinement(cps_ir.Refinement node) {
    unexpectedNode(node);
  }

  visitBoundsCheck(cps_ir.BoundsCheck node) {
    unexpectedNode(node);
  }

  visitReceiverCheck(cps_ir.ReceiverCheck node) {
    unexpectedNode(node);
  }
}
