/*
 * Copyright 2007 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.dev.jjs.impl;

import com.google.gwt.dev.jjs.InternalCompilerException;
import com.google.gwt.dev.jjs.ast.Context;
import com.google.gwt.dev.jjs.ast.JCastOperation;
import com.google.gwt.dev.jjs.ast.JDeclaredType;
import com.google.gwt.dev.jjs.ast.JExpression;
import com.google.gwt.dev.jjs.ast.JExpressionStatement;
import com.google.gwt.dev.jjs.ast.JLocalRef;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JMethodBody;
import com.google.gwt.dev.jjs.ast.JMethodCall;
import com.google.gwt.dev.jjs.ast.JModVisitor;
import com.google.gwt.dev.jjs.ast.JNewInstance;
import com.google.gwt.dev.jjs.ast.JParameter;
import com.google.gwt.dev.jjs.ast.JParameterRef;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.dev.jjs.ast.JReferenceType;
import com.google.gwt.dev.jjs.ast.JReturnStatement;
import com.google.gwt.dev.jjs.ast.JStatement;
import com.google.gwt.dev.jjs.ast.JThisRef;
import com.google.gwt.dev.jjs.ast.JType;
import com.google.gwt.dev.jjs.ast.JVisitor;
import com.google.gwt.dev.jjs.ast.js.JMultiExpression;
import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Inline methods that can be inlined. The current implementation limits the
 * methods that can be inlined to those that are composed of at most two
 * top-level expressions.
 * 
 * Future improvements will allow more complex methods to be inlined based on
 * the number of call sites, as well as adding support for more complex target
 * method expressions.
 */
public class MethodInliner {
  /**
   * Clones an expression, ensuring no local or this refs.
   */
  private static class CloneCalleeExpressionVisitor extends CloneExpressionVisitor {
    @Override
    public boolean visit(JLocalRef x, Context ctx) {
      throw new InternalCompilerException(
          "Unable to clone a local reference in a function being inlined");
    }

    @Override
    public boolean visit(JThisRef x, Context ctx) {
      throw new InternalCompilerException("Should not encounter a JThisRef "
          + "within a static method");
    }
  }

  /**
   * Method inlining visitor.
   */
  private class InliningVisitor extends JModVisitor {
    protected final Set<JMethod> modifiedMethods = new HashSet<JMethod>();

    /**
     * Resets with each new visitor, which is good since things that couldn't be
     * inlined before might become inlinable.
     */
    private final Set<JMethod> cannotInline = new HashSet<JMethod>();
    private JExpression ignoringReturnValueFor;

    @Override
    public void endVisit(JMethod x, Context ctx) {
      currentMethod = null;
    }

    @Override
    public void endVisit(JMethodCall x, Context ctx) {
      JMethod method = x.getTarget();

      if (currentMethod == method) {
        // Never try to inline a recursive call!
        return;
      }

      if (cannotInline.contains(method)) {
        return;
      }

      boolean possibleToInline = false;

      if (method.isStatic() && !method.isNative()) {
        JMethodBody body = (JMethodBody) method.getBody();
        List<JStatement> stmts = body.getStatements();

        if (method.getEnclosingType() != null
            && method.getEnclosingType().getMethods().get(0) == method && !stmts.isEmpty()) {
          // clinit() calls cannot be inlined unless they are empty
          possibleToInline = false;
        } else if (!body.getLocals().isEmpty()) {
          // methods with local variables cannot be inlined
          possibleToInline = false;
        } else {
          JMultiExpression multi = createMultiExpressionFromBody(body, ignoringReturnValueFor == x);
          if (multi != null) {
            possibleToInline = tryInlineExpression(x, ctx, multi);
          }
        }
      }

      // If it will never be possible to inline the method, add it to a
      // blacklist
      if (!possibleToInline) {
        cannotInline.add(method);
      }
    }

    @Override
    public void endVisit(JNewInstance x, Context ctx) {
      // Do not inline new operations.
    }

    @Override
    public boolean visit(JExpressionStatement x, Context ctx) {
      ignoringReturnValueFor = x.getExpr();
      return true;
    }

    @Override
    public boolean visit(JMethod x, Context ctx) {
      currentMethod = x;
      if (program.getStaticImpl(x) != null) {
        /*
         * Never inline a static impl into the calling instance method. We used
         * to allow this, and it required all kinds of special logic in the
         * optimizers to keep the AST sane. This was because it was possible to
         * tighten an instance call to its static impl after the static impl had
         * already been inlined, this meant any "flow" type optimizer would have
         * to fake artifical flow from the instance method to the static impl.
         * 
         * TODO: allow the inlining if we are the last remaining call site, and
         * prune the static impl? But it might tend to generate more code.
         */
        return false;
      }
      return true;
    }

    private JMethodCall createClinitCall(JMethodCall x) {
      JDeclaredType targetType = x.getTarget().getEnclosingType().getClinitTarget();
      if (!currentMethod.getEnclosingType().checkClinitTo(targetType)) {
        // Access from this class to the target class won't trigger a clinit
        return null;
      }
      if (program.isStaticImpl(x.getTarget())) {
        // No clinit needed; target is really an instance method.
        return null;
      }
      if (JProgram.isClinit(x.getTarget())) {
        // This is a clinit call, doesn't need another clinit
        return null;
      }

      JMethod clinit = targetType.getMethods().get(0);

      // If the clinit is a non-native, empty body we can optimize it out here
      if (!clinit.isNative() && (((JMethodBody) clinit.getBody())).getStatements().size() == 0) {
        return null;
      }

      return new JMethodCall(x.getSourceInfo(), null, clinit);
    }

    /**
     * Creates a multi expression for evaluating a method call instance and
     * possible clinit. This is a precursor for inlining the remainder of a
     * method.
     */
    private JMultiExpression createMultiExpressionForInstanceAndClinit(JMethodCall x) {
      JMultiExpression multi = new JMultiExpression(x.getSourceInfo());

      // Any instance expression goes first (this can happen even with statics).
      if (x.getInstance() != null) {
        multi.exprs.add(x.getInstance());
      }

      // If we need a clinit call, add it first
      JMethodCall clinit = createClinitCall(x);
      if (clinit != null) {
        multi.exprs.add(clinit);
      }
      return multi;
    }

    /**
     * Creates a JMultiExpression from a set of JExpressionStatements,
     * optionally terminated by a JReturnStatement. If the method doesn't match
     * this pattern, it returns <code>null</code>.
     * 
     * If a method has a non-void return statement and can be represented as a
     * multi-expression, the output of the multi-expression will be the return
     * expression of the method. If the method is void, the output of the
     * multi-expression should be considered undefined.
     */
    private JMultiExpression createMultiExpressionFromBody(JMethodBody body,
        boolean ignoringReturnValue) {
      JMultiExpression multi = new JMultiExpression(body.getSourceInfo());
      CloneCalleeExpressionVisitor cloner = new CloneCalleeExpressionVisitor();

      for (JStatement stmt : body.getStatements()) {
        if (stmt instanceof JExpressionStatement) {
          JExpressionStatement exprStmt = (JExpressionStatement) stmt;
          JExpression expr = exprStmt.getExpr();
          JExpression clone = cloner.cloneExpression(expr);
          multi.exprs.add(clone);
        } else if (stmt instanceof JReturnStatement) {
          JReturnStatement returnStatement = (JReturnStatement) stmt;
          JExpression expr = returnStatement.getExpr();
          if (expr != null) {
            if (!ignoringReturnValue || expr.hasSideEffects()) {
              JExpression clone = cloner.cloneExpression(expr);
              clone = maybeCast(clone, body.getMethod().getType());
              multi.exprs.add(clone);
            }
          }
          // We hit an unconditional return; no need to evaluate anything else.
          break;
        } else {
          // Any other kind of statement won't be inlinable.
          return null;
        }
      }

      return multi;
    }

    /**
     * Creates a multi expression for evaluating a method call instance,
     * possible clinit, and all arguments. This is a precursor for inlining the
     * remainder of a method that does not reference any parameters.
     */
    private JMultiExpression createMultiExpressionIncludingArgs(JMethodCall x) {
      JMultiExpression multi = createMultiExpressionForInstanceAndClinit(x);

      for (int i = 0, c = x.getArgs().size(); i < c; ++i) {
        JExpression arg = x.getArgs().get(i);
        ExpressionAnalyzer analyzer = new ExpressionAnalyzer();
        analyzer.accept(arg);

        if (analyzer.hasAssignment() || analyzer.canThrowException()) {
          multi.exprs.add(arg);
        }
      }
      return multi;
    }

    /**
     * Replace the current expression with a given multi-expression and mark the
     * method as modified. The dead-code elimination pass will optimize this if
     * necessary.
     */
    private void replaceWithMulti(Context ctx, JMultiExpression multi) {
      ctx.replaceMe(multi);
      modifiedMethods.add(currentMethod);
    }

    /**
     * Inline a call to an expression.
     */
    private boolean tryInlineExpression(JMethodCall x, Context ctx, JMultiExpression targetExpr) {
      /*
       * Limit inlined methods to multiexpressions of length 2 for now. This
       * handles the simple { return JVariableRef; } or { expression; return
       * something; } cases.
       * 
       * TODO: add an expression complexity analyzer.
       */
      if (targetExpr.exprs.size() > 2) {
        return false;
      }

      // Do not inline anything that modifies one of its params.
      ExpressionAnalyzer targetAnalyzer = new ExpressionAnalyzer();
      targetAnalyzer.accept(targetExpr);
      if (targetAnalyzer.hasAssignmentToParameter()) {
        return false;
      }

      // Make sure the expression we're about to inline doesn't include a call
      // to the target method!
      RecursionCheckVisitor recursionCheckVisitor = new RecursionCheckVisitor(x.getTarget());
      recursionCheckVisitor.accept(targetExpr);
      if (recursionCheckVisitor.isRecursive()) {
        return false;
      }

      /*
       * After this point, it's possible that the method might be inlinable at
       * some call sites, depending on its arguments. From here on return 'true'
       * as the method might be inlinable elsewhere.
       */

      /*
       * There are a different number of parameters than args - this is likely a
       * result of parameter pruning. Don't consider this call site a candidate.
       * 
       * TODO: would this be possible in the trivial delegation case?
       */
      if (x.getTarget().getParams().size() != x.getArgs().size()) {
        return true;
      }

      // Run the order check. This verifies that all the parameters are
      // referenced once and only once, not within a conditionally-executing
      // expression and before any tricky target expressions, such as:
      // - assignments to any variable
      // - expressions that throw exceptions
      // - field references

      /*
       * Ensure correct evaluation order or params relative to each other and to
       * other expressions.
       */
      OrderVisitor orderVisitor = new OrderVisitor(x.getTarget().getParams());
      orderVisitor.accept(targetExpr);

      /*
       * A method that doesn't touch any parameters is trivially inlinable (this
       * covers the empty method case)
       */
      if (orderVisitor.checkResults() == SideEffectCheck.NO_REFERENCES) {
        JMultiExpression multi = createMultiExpressionIncludingArgs(x);
        multi.exprs.add(targetExpr);
        replaceWithMulti(ctx, multi);
        return true;
      }

      /*
       * We can still inline in the case where all of the actual arguments are
       * "safe". They must have no side effects, and also have values which
       * could not be affected by the execution of any code within the callee.
       */
      if (orderVisitor.checkResults() == SideEffectCheck.FAILS) {
        for (JExpression arg : x.getArgs()) {
          ExpressionAnalyzer argAnalyzer = new ExpressionAnalyzer();
          argAnalyzer.accept(arg);

          if (argAnalyzer.hasAssignment() || argAnalyzer.accessesField()
              || argAnalyzer.createsObject() || argAnalyzer.canThrowException()) {

            /*
             * This argument evaluation could affect or be affected by the
             * callee so we cannot inline here.
             */
            return true;
          }
        }
      }

      // We're safe to inline.
      JMultiExpression multi = createMultiExpressionForInstanceAndClinit(x);

      // Replace all params in the target expression with the actual arguments.
      ParameterReplacer replacer = new ParameterReplacer(x);
      replacer.accept(targetExpr);

      multi.exprs.add(targetExpr);
      replaceWithMulti(ctx, multi);
      return true;
    }
  }

  /**
   * Verifies that all the parameters are referenced once and only once, not
   * within a conditionally-executing expression, and any before trouble some
   * expressions evaluate. Examples of troublesome expressions include:
   * 
   * <ul>
   * <li>assignments to any variable</li>
   * <li>expressions that throw exceptions</li>
   * <li>field references</li>
   * </ul>
   */
  private static class OrderVisitor extends ExpressionAnalyzer {
    private int currentIndex = 0;
    private final List<JParameter> parameters;
    private boolean succeeded = true;

    public OrderVisitor(List<JParameter> parameters) {
      this.parameters = parameters;
    }

    public SideEffectCheck checkResults() {
      if (succeeded && currentIndex == parameters.size()) {
        return SideEffectCheck.CORRECT_ORDER;
      }

      if (succeeded && currentIndex == 0) {
        return SideEffectCheck.NO_REFERENCES;
      }

      return SideEffectCheck.FAILS;
    }

    @Override
    public void endVisit(JParameterRef x, Context ctx) {
      JParameter param = x.getParameter();

      // If the expression has side-effects before a parameter reference, fail
      if (hasAssignment() || accessesField() || canThrowException()) {
        succeeded = false;
      }

      // If this parameter reference won't always execute, fail
      if (isInConditional()) {
        succeeded = false;
      }

      // Ensure this parameter is evaluated in the correct order relative to
      // other parameters.
      if (parameters.indexOf(param) == currentIndex) {
        currentIndex++;
      } else {
        succeeded = false;
      }

      super.endVisit(x, ctx);
    }
  }

  /**
   * Replace parameters inside an inlined expression with arguments to the
   * inlined method.
   */
  private class ParameterReplacer extends JModVisitor {
    private final JMethodCall methodCall;

    public ParameterReplacer(JMethodCall methodCall) {
      this.methodCall = methodCall;
    }

    @Override
    public void endVisit(JParameterRef x, Context ctx) {
      int paramIndex = methodCall.getTarget().getParams().indexOf(x.getParameter());
      assert paramIndex != -1;

      // Replace with a cloned call argument.
      CloneExpressionVisitor cloner = new CloneExpressionVisitor();
      JExpression arg = methodCall.getArgs().get(paramIndex);
      JExpression clone = cloner.cloneExpression(arg);

      clone = maybeCast(clone, x.getType());
      ctx.replaceMe(clone);
    }
  }

  private static class RecursionCheckVisitor extends JVisitor {
    private boolean isRecursive = false;
    private final JMethod method;

    public RecursionCheckVisitor(JMethod method) {
      this.method = method;
    }

    @Override
    public void endVisit(JMethodCall x, Context ctx) {
      if (x.getTarget() == method) {
        isRecursive = true;
      }
    }

    public boolean isRecursive() {
      return isRecursive;
    }
  }

  /**
   * Results of a side-effect and order check.
   */
  private enum SideEffectCheck {
    CORRECT_ORDER, FAILS, NO_REFERENCES
  }

  public static String NAME = MethodInliner.class.getSimpleName();

  public static OptimizerStats exec(JProgram program) {
    Event optimizeEvent = SpeedTracerLogger.start(CompilerEventType.OPTIMIZE, "optimizer", NAME);
    OptimizerStats stats = new MethodInliner(program).execImpl();
    optimizeEvent.end("didChange", "" + stats.didChange());
    return stats;
  }

  private JMethod currentMethod;

  private final JProgram program;

  private MethodInliner(JProgram program) {
    this.program = program;
  }

  private OptimizerStats execImpl() {
    OptimizerStats stats = new OptimizerStats(NAME);
    while (true) {
      InliningVisitor inliner = new InliningVisitor();
      inliner.accept(program);
      stats.recordModified(inliner.getNumMods());
      if (!inliner.didChange()) {
        break;
      }

      // Run a cleanup on the methods we just modified
      for (JMethod method : inliner.modifiedMethods) {
        OptimizerStats innerStats = DeadCodeElimination.exec(program, method);
        stats.recordModified(innerStats.getNumMods());
      }
    }
    return stats;
  }

  /**
   * Insert an implicit cast if the types differ; it might get optimized out
   * later, but in some cases it will force correct math evaluation.
   */
  private JExpression maybeCast(JExpression exp, JType targetType) {
    if (targetType instanceof JReferenceType) {
      assert exp.getType() instanceof JReferenceType;
      targetType = merge((JReferenceType) exp.getType(), (JReferenceType) targetType);
    }
    if (!program.typeOracle.canTriviallyCast(exp.getType(), targetType)) {
      exp = new JCastOperation(exp.getSourceInfo(), targetType, exp);
    }
    return exp;
  }

  private JReferenceType merge(JReferenceType source, JReferenceType target) {
    JReferenceType result;
    if (program.typeOracle.canTriviallyCast(source.getUnderlyingType(), target.getUnderlyingType())) {
      result = source;
    } else {
      result = target;
    }
    if ((!target.canBeNull())) {
      result = result.getNonNull();
    }
    return result;
  }
}
